1 /*
2  *
3   ***** BEGIN LICENSE BLOCK *****
4 
5   Copyright (C) 2009-2019 Olof Hagsand
6   Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
7 
8   This file is part of CLIXON.
9 
10   Licensed under the Apache License, Version 2.0 (the "License");
11   you may not use this file except in compliance with the License.
12   You may obtain a copy of the License at
13 
14     http://www.apache.org/licenses/LICENSE-2.0
15 
16   Unless required by applicable law or agreed to in writing, software
17   distributed under the License is distributed on an "AS IS" BASIS,
18   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   See the License for the specific language governing permissions and
20   limitations under the License.
21 
22   Alternatively, the contents of this file may be used under the terms of
23   the GNU General Public License Version 3 or later (the "GPL"),
24   in which case the provisions of the GPL are applicable instead
25   of those above. If you wish to allow use of your version of this file only
26   under the terms of the GPL, and not to allow others to
27   use your version of this file under the terms of Apache License version 2,
28   indicate your decision by deleting the provisions above and replace them with
29   the  notice and other provisions required by the GPL. If you do not delete
30   the provisions above, a recipient may use your version of this file under
31   the terms of any one of the Apache License version 2 or the GPL.
32 
33   ***** END LICENSE BLOCK *****
34 
35  * Yang functions
36  * @see https://tools.ietf.org/html/rfc6020 YANG 1.0
37  * @see https://tools.ietf.org/html/rfc7950 YANG 1.1
38  */
39 
40 #ifndef _CLIXON_YANG_H_
41 #define _CLIXON_YANG_H_
42 
43 /*
44  * Clixon-specific cligen variable (cv) flags
45  * CLIgen flags defined are in the range 0x01 -0x0f
46  * An application can use any flags above that
47  * @see cv_flag
48  */
49 #define V_UNSET	  0x10	/* Used by XML code to denote a value is not default */
50 
51 /*
52  * Yang flags used in
53  */
54 #define YANG_FLAG_MARK  0x01  /* (Dynamic) marker for dynamic algorithms, eg expand and DAG */
55 #define YANG_FLAG_TMP   0x02  /* (Dynamic) marker for dynamic algorithms, eg DAG detection */
56 #ifdef XML_EXPLICIT_INDEX
57 #define YANG_FLAG_INDEX 0x04  /* This yang node under list is (extra) index. --> you can access
58 			       * list elements using this index with binary search */
59 #endif
60 
61 /*
62  * Types
63  */
64 /*! YANG keywords from RFC6020.
65  * See also keywords generated by yacc/bison in clicon_yang_parse.tab.h, but they start with K_
66  * instead of Y_
67  * Wanted to unify these (K_ and Y_) but gave up for several reasons:
68  * - Dont want to expose a generated yacc file to the API
69  * - Cant use the symbols in this file because yacc needs token definitions
70  * - Use 0 as no keyword --> therefore start enumeration with 1.
71  */
72 enum rfc_6020{
73     Y_ACTION = 1,
74     Y_ANYDATA,
75     Y_ANYXML,
76     Y_ARGUMENT,
77     Y_AUGMENT,
78     Y_BASE,
79     Y_BELONGS_TO,
80     Y_BIT,
81     Y_CASE,
82     Y_CHOICE,          /* 10 */
83     Y_CONFIG,
84     Y_CONTACT,
85     Y_CONTAINER,
86     Y_DEFAULT,
87     Y_DESCRIPTION,
88     Y_DEVIATE,
89     Y_DEVIATION,
90     Y_ENUM,
91     Y_ERROR_APP_TAG,
92     Y_ERROR_MESSAGE,   /* 20 */
93     Y_EXTENSION,
94     Y_FEATURE,
95     Y_FRACTION_DIGITS,
96     Y_GROUPING,
97     Y_IDENTITY,
98     Y_IF_FEATURE,
99     Y_IMPORT,
100     Y_INCLUDE,
101     Y_INPUT,
102     Y_KEY,             /* 30 */
103     Y_LEAF,
104     Y_LEAF_LIST,
105     Y_LENGTH,
106     Y_LIST,
107     Y_MANDATORY,
108     Y_MAX_ELEMENTS,
109     Y_MIN_ELEMENTS,
110     Y_MODIFIER,
111     Y_MODULE,
112     Y_MUST,             /* 40 */
113     Y_NAMESPACE,
114     Y_NOTIFICATION,
115     Y_ORDERED_BY,
116     Y_ORGANIZATION,
117     Y_OUTPUT,
118     Y_PATH,
119     Y_PATTERN,
120     Y_POSITION,
121     Y_PREFIX,
122     Y_PRESENCE,         /* 50 */
123     Y_RANGE,
124     Y_REFERENCE,
125     Y_REFINE,
126     Y_REQUIRE_INSTANCE,
127     Y_REVISION,
128     Y_REVISION_DATE,
129     Y_RPC,
130     Y_STATUS,
131     Y_SUBMODULE,
132     Y_TYPE,            /* 60 */
133     Y_TYPEDEF,
134     Y_UNIQUE,
135     Y_UNITS,
136     Y_UNKNOWN,
137     Y_USES,
138     Y_VALUE,
139     Y_WHEN,
140     Y_YANG_VERSION,
141     Y_YIN_ELEMENT,
142     Y_SPEC  /* XXX: NOTE NOT YANG STATEMENT, reserved for top level spec */
143 };
144 
145 /* Type used to group yang nodes used in some functions
146  * See RFC7950 Sec 3
147  */
148 enum yang_class{
149     YC_NONE,            /* Someting else,... */
150     YC_DATANODE,        /* See yang_datanode() */
151     YC_DATADEFINITION,  /* See yang_datadefinition() */
152     YC_SCHEMANODE       /* See yang_schemanode() */
153 };
154 typedef enum yang_class yang_class;
155 
156 struct xml;
157 
158 typedef struct yang_stmt yang_stmt; /* Defined in clixon_yang_internal */
159 
160 /*! Yang apply function worker
161  * @param[in]  yn   yang node
162  * @param[in]  arg  Argument
163  * @retval    -1    Error, abort
164  * @retval     0    OK, continue with next
165  * @retval     n    OK, abort traversal and return to caller with "n"
166  */
167 typedef int (yang_applyfn_t)(yang_stmt *ys, void *arg);
168 
169 
170 /* Yang data definition statement
171  * See RFC 7950 Sec 3:
172  *   o  data definition statement: A statement that defines new data
173  *      nodes.  One of "container", "leaf", "leaf-list", "list", "choice",
174  *      "case", "augment", "uses", "anydata", and "anyxml".
175  */
176 #define yang_datadefinition(y) (yang_datanode(y) || yang_keyword_get(y) == Y_CHOICE || yang_keyword_get(y) == Y_CASE || yang_keyword_get(y) == Y_AUGMENT || yang_keyword_get(y) == Y_USES)
177 
178 /* Yang schema node .
179  * See RFC 7950 Sec 3:
180  *    o  schema node: A node in the schema tree.  One of action, container,
181  *       leaf, leaf-list, list, choice, case, rpc, input, output,
182  *       notification, anydata, and anyxml.
183  */
184 #define yang_schemanode(y) (yang_datanode(y) || yang_keyword_get(y) == Y_RPC || yang_keyword_get(y) == Y_CHOICE || yang_keyword_get(y) == Y_CASE || yang_keyword_get(y) == Y_INPUT || yang_keyword_get(y) == Y_OUTPUT || yang_keyword_get(y) == Y_NOTIFICATION)
185 
186 /*
187  * Prototypes
188  */
189 /* Access functions */
190 int        yang_len_get(yang_stmt *ys);
191 yang_stmt *yang_child_i(yang_stmt *ys, int i);
192 
193 yang_stmt *yang_parent_get(yang_stmt *ys);
194 enum rfc_6020 yang_keyword_get(yang_stmt *ys);
195 char      *yang_argument_get(yang_stmt *ys);
196 int        yang_argument_set(yang_stmt *ys, char *arg);
197 
198 cg_var    *yang_cv_get(yang_stmt *ys);
199 cvec      *yang_cvec_get(yang_stmt *ys);
200 int        yang_cvec_set(yang_stmt *ys, cvec *cvv);
201 uint16_t   yang_flag_get(yang_stmt *ys, uint16_t flag);
202 int        yang_flag_set(yang_stmt *ys, uint16_t flag);
203 int        yang_flag_reset(yang_stmt *ys, uint16_t flag);
204 char      *yang_when_xpath_get(yang_stmt *ys);
205 int        yang_when_xpath_set(yang_stmt *ys, char *xpath);
206 cvec      *yang_when_nsc_get(yang_stmt *ys);
207 int        yang_when_nsc_set(yang_stmt *ys, cvec *nsc);
208 
209 /* Other functions */
210 yang_stmt *yspec_new(void);
211 yang_stmt *ys_new(enum rfc_6020 keyw);
212 yang_stmt *ys_prune(yang_stmt *yp, int i);
213 
214 int        ys_free(yang_stmt *ys);
215 int        yspec_free(yang_stmt *yspec);
216 int        ys_cp(yang_stmt *nw, yang_stmt *old);
217 yang_stmt *ys_dup(yang_stmt *old);
218 int        yn_insert(yang_stmt *ys_parent, yang_stmt *ys_child);
219 yang_stmt *yn_each(yang_stmt *yn, yang_stmt *ys);
220 char      *yang_key2str(int keyword);
221 int        ys_module_by_xml(yang_stmt *ysp, struct xml *xt, yang_stmt **ymodp);
222 yang_stmt *ys_module(yang_stmt *ys);
223 int        ys_real_module(yang_stmt *ys, yang_stmt **ymod);
224 yang_stmt *ys_spec(yang_stmt *ys);
225 yang_stmt *yang_find(yang_stmt *yn, int keyword, const char *argument);
226 int        yang_match(yang_stmt *yn, int keyword, char *argument);
227 yang_stmt *yang_find_datanode(yang_stmt *yn, char *argument);
228 yang_stmt *yang_find_schemanode(yang_stmt *yn, char *argument);
229 char      *yang_find_myprefix(yang_stmt *ys);
230 char      *yang_find_mynamespace(yang_stmt *ys);
231 int        yang_find_prefix_by_namespace(yang_stmt *ys, char *ns, char **prefix);
232 yang_stmt *yang_myroot(yang_stmt *ys);
233 yang_stmt *yang_choice(yang_stmt *y);
234 int        yang_order(yang_stmt *y);
235 int        yang_print_cb(FILE *f, yang_stmt *yn, clicon_output_cb *fn);
236 int        yang_print(FILE *f, yang_stmt *yn);
237 int        yang_print_cbuf(cbuf *cb, yang_stmt *yn, int marginal);
238 int        if_feature(yang_stmt *yspec, char *module, char *feature);
239 int        ys_populate(yang_stmt *ys, void *arg);
240 int        ys_populate2(yang_stmt *ys, void *arg);
241 int        yang_apply(yang_stmt *yn, enum rfc_6020 key, yang_applyfn_t fn,
242 		      void *arg);
243 int        yang_datanode(yang_stmt *ys);
244 int        yang_abs_schema_nodeid(yang_stmt *ys, char *schema_nodeid, yang_stmt **yres);
245 int        yang_desc_schema_nodeid(yang_stmt *yn, char *schema_nodeid, yang_stmt **yres);
246 int        yang_mandatory(yang_stmt *ys);
247 int        yang_config(yang_stmt *ys);
248 int        yang_config_ancestor(yang_stmt *ys);
249 int        yang_features(clicon_handle h, yang_stmt *yt);
250 cvec      *yang_arg2cvec(yang_stmt *ys, char *delimi);
251 int        yang_container_cli_hide(yang_stmt *ys, int gt);
252 int        yang_key_match(yang_stmt *yn, char *name);
253 
254 int        yang_type_cache_regexp_set(yang_stmt *ytype, int rxmode, cvec *regexps);
255 int        yang_type_cache_get(yang_stmt *ytype, yang_stmt **resolved, int *options,
256 		   cvec **cvv, cvec *patterns, int *rxmode, cvec *regexps, uint8_t *fraction);
257 int        yang_type_cache_set(yang_stmt *ys, yang_stmt *resolved, int options, cvec *cvv,
258 			       cvec *patterns, uint8_t fraction);
259 yang_stmt *yang_anydata_add(yang_stmt *yp, char *name);
260 
261 
262 #endif  /* _CLIXON_YANG_H_ */
263