clixon_yang_cardinality files added
This commit is contained in:
parent
a8f0aad411
commit
4303406957
2 changed files with 288 additions and 0 deletions
246
lib/src/clixon_yang_cardinality.c
Normal file
246
lib/src/clixon_yang_cardinality.c
Normal file
|
|
@ -0,0 +1,246 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||||
|
|
||||||
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
* Yang cardinality functions according to RFC 7950
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "clixon_config.h" /* generated by config & autoconf */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#define __USE_GNU /* strverscmp */
|
||||||
|
#include <string.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
/* cligen */
|
||||||
|
#include <cligen/cligen.h>
|
||||||
|
|
||||||
|
/* clicon */
|
||||||
|
#include "clixon_queue.h"
|
||||||
|
#include "clixon_hash.h"
|
||||||
|
#include "clixon_handle.h"
|
||||||
|
#include "clixon_err.h"
|
||||||
|
#include "clixon_yang.h"
|
||||||
|
#include "clixon_yang_cardinality.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
/* Encode cardinality according to RFC 7950
|
||||||
|
* Example:
|
||||||
|
* 7.20.3.1. The deviation's Substatements
|
||||||
|
*
|
||||||
|
* +--------------+----------+-------------+
|
||||||
|
* | substatement | section | cardinality |
|
||||||
|
* +--------------+----------+-------------+
|
||||||
|
* | description | 7.21.3 | 0..1 |
|
||||||
|
* | deviate | 7.20.3.2 | 1..n |
|
||||||
|
* | reference | 7.21.4 | 0..1 |
|
||||||
|
* +--------------+----------+-------------+
|
||||||
|
* The cardinalities are (and how many time they occur)
|
||||||
|
* 0..1 149 See ycardmap_01
|
||||||
|
* 1..n, 1
|
||||||
|
* 0..n 176 (no restrictions)
|
||||||
|
* 1 10
|
||||||
|
*/
|
||||||
|
struct ycard{
|
||||||
|
enum rfc_6020 yc_parent;
|
||||||
|
enum rfc_6020 yc_child;
|
||||||
|
int yc_min;
|
||||||
|
int yc_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables
|
||||||
|
*/
|
||||||
|
/* Yang statements cardinality map
|
||||||
|
* The cardinalities are (and how many time they occur)
|
||||||
|
* 1..n, 1
|
||||||
|
* 1 10
|
||||||
|
* 0..1 149
|
||||||
|
* 0..n 176 (no restrictions)
|
||||||
|
* @note assume array is ordered wrt parent
|
||||||
|
* @note yang-version is optional in RFC6020 but mandatory in RFC7950, if not given, it defaults to 1.
|
||||||
|
*/
|
||||||
|
#define NMAX 1000000 /* Just a large number */
|
||||||
|
static const struct ycard yclist[] = {
|
||||||
|
{Y_MODULE, Y_ANYDATA, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_ANYXML, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_AUGMENT, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_CHOICE, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_CONTACT, 0, 1},
|
||||||
|
{Y_MODULE, Y_CONTAINER, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_DESCRIPTION, 0, 1},
|
||||||
|
{Y_MODULE, Y_DEVIATION, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_EXTENSION, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_FEATURE, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_GROUPING, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_IDENTITY, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_IMPORT, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_INCLUDE, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_LEAF, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_LEAF_LIST, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_LIST, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_NAMESPACE, 1, 1},
|
||||||
|
{Y_MODULE, Y_NOTIFICATION, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_ORGANIZATION, 0, 1},
|
||||||
|
{Y_MODULE, Y_PREFIX, 1, 1},
|
||||||
|
{Y_MODULE, Y_REFERENCE, 0, 1},
|
||||||
|
{Y_MODULE, Y_REVISION, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_RPC, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_TYPEDEF, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_USES, 0, NMAX},
|
||||||
|
{Y_MODULE, Y_YANG_VERSION, 0, 1},
|
||||||
|
{0,}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! Find yang parent and child combination in yang cardinality table
|
||||||
|
* @param[in] parent Parent Yang spec
|
||||||
|
* @param[in] child Child yang spec if -1 first
|
||||||
|
* @param[in] yc Yang cardinality map
|
||||||
|
* @param[in] p If set, quit as soon as parents dont match
|
||||||
|
* @retval NULL Not found
|
||||||
|
* @retval yp Found
|
||||||
|
*/
|
||||||
|
static const struct ycard *
|
||||||
|
ycard_find(enum rfc_6020 parent,
|
||||||
|
enum rfc_6020 child,
|
||||||
|
const struct ycard *yclist,
|
||||||
|
int p)
|
||||||
|
|
||||||
|
{
|
||||||
|
const struct ycard *yc;
|
||||||
|
|
||||||
|
for (yc = &yclist[0]; (int)yc->yc_parent; yc++){
|
||||||
|
if (yc->yc_parent == parent){
|
||||||
|
if (!child || yc->yc_child == child)
|
||||||
|
return yc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (p)
|
||||||
|
return NULL; /* premature quit */
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Check cardinality, ie if each yang node has the expected nr of children
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] yt Yang statement
|
||||||
|
* @param[in] modname Name of module (for debug message)
|
||||||
|
* 1) For all children, if neither in 0..n, 0..1, 1 or 1..n ->ERROR
|
||||||
|
* 2) For all in 1 and 1..n list, if 0 such children ->ERROR
|
||||||
|
* 3) For all in 0..1 and 1 list, if >1 such children ->ERROR
|
||||||
|
* 4) Recurse
|
||||||
|
* @note always accept UNKNOWN (due to extension)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
yang_cardinality(clicon_handle h,
|
||||||
|
yang_stmt *yt,
|
||||||
|
char *modname)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
yang_stmt *ys = NULL;
|
||||||
|
int pk;
|
||||||
|
int ck;
|
||||||
|
int i;
|
||||||
|
int nr;
|
||||||
|
const struct ycard *ycplist; /* ycard parent table*/
|
||||||
|
const struct ycard *yc;
|
||||||
|
|
||||||
|
pk = yt->ys_keyword;
|
||||||
|
/* 0) Find parent sub-parts of cardinality vector */
|
||||||
|
ycplist = ycard_find(pk, 0, yclist, 0);
|
||||||
|
/* 1) For all children, if neither in 0..n, 0..1, 1 or 1..n ->ERROR */
|
||||||
|
i = 0;
|
||||||
|
while (i<yt->ys_len){
|
||||||
|
ys = yt->ys_stmt[i++];
|
||||||
|
ck = ys->ys_keyword;
|
||||||
|
if (ck == Y_UNKNOWN) /* special case */
|
||||||
|
continue;
|
||||||
|
if ((yc = ycard_find(pk, ck, ycplist, 1)) == NULL){
|
||||||
|
clicon_err(OE_YANG, 0, "%s: \"%s\" is child of \"%s\", but should not be",
|
||||||
|
modname, yang_key2str(ck), yang_key2str(pk));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 2) For all in 1 and 1..n list, if 0 such children ->ERROR */
|
||||||
|
for (yc = &ycplist[0]; (int)yc->yc_parent == pk; yc++){
|
||||||
|
if (yc->yc_min &&
|
||||||
|
yang_find((yang_node*)yt, yc->yc_child, NULL) == NULL){
|
||||||
|
clicon_err(OE_YANG, 0, "%s: \"%s\" is missing but is mandatory child of \"%s\"",
|
||||||
|
modname, yang_key2str(yc->yc_child), yang_key2str(pk));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 3) For all in 0..1 and 1 list, if >1 such children ->ERROR */
|
||||||
|
for (yc = &ycplist[0]; (int)yc->yc_parent == pk; yc++){
|
||||||
|
if (yc->yc_max<NMAX &&
|
||||||
|
(nr = yang_match((yang_node*)yt, yc->yc_child, NULL)) > yc->yc_max){
|
||||||
|
clicon_err(OE_YANG, 0, "%s: \"%s\" has %d children of type \"%s\", but only %d allowed",
|
||||||
|
modname,
|
||||||
|
yang_key2str(pk),
|
||||||
|
nr,
|
||||||
|
yang_key2str(yc->yc_child),
|
||||||
|
yc->yc_max);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0) { /* Notyet */
|
||||||
|
/* 4) Recurse */
|
||||||
|
i = 0;
|
||||||
|
while (i<yt->ys_len){ /* Note, children may be removed */
|
||||||
|
ys = yt->ys_stmt[i++];
|
||||||
|
if (yang_cardinality(h, ys, modname) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
42
lib/src/clixon_yang_cardinality.h
Normal file
42
lib/src/clixon_yang_cardinality.h
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||||
|
|
||||||
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
* Yang cardinality functions according to RFC 7950
|
||||||
|
*/
|
||||||
|
#ifndef _CLIXON_YANG_CARDINALITY_H_
|
||||||
|
#define _CLIXON_YANG_CARDINALITY_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes
|
||||||
|
*/
|
||||||
|
int yang_cardinality(clicon_handle h, yang_stmt *yt, char *modname);
|
||||||
|
|
||||||
|
#endif /* _CLIXON_YANG_CARDINALITY_H_ */
|
||||||
Loading…
Add table
Add a link
Reference in a new issue