]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_routemap_nb_config.c
Merge pull request #8364 from stipmonster/master
[mirror_frr.git] / zebra / zebra_routemap_nb_config.c
1 #include <zebra.h>
2
3 #include "lib/command.h"
4 #include "lib/log.h"
5 #include "lib/northbound.h"
6 #include "lib/routemap.h"
7 #include "zebra/rib.h"
8 #include "zebra/zebra_routemap_nb.h"
9
10 /*
11 * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length
12 */
13 int
14 lib_route_map_entry_match_condition_rmap_match_condition_ipv4_prefix_length_modify(
15 struct nb_cb_modify_args *args)
16 {
17 struct routemap_hook_context *rhc;
18 const char *length;
19 int rv;
20 const char *condition;
21
22 switch (args->event) {
23 case NB_EV_VALIDATE:
24 case NB_EV_PREPARE:
25 case NB_EV_ABORT:
26 return NB_OK;
27 case NB_EV_APPLY:
28 /* Add configuration. */
29 rhc = nb_running_get_entry(args->dnode, NULL, true);
30 length = yang_dnode_get_string(args->dnode, NULL);
31 condition = yang_dnode_get_string(args->dnode,
32 "../../frr-route-map:condition");
33
34 if (IS_MATCH_IPv4_PREFIX_LEN(condition))
35 rhc->rhc_rule = "ip address prefix-len";
36 else if (IS_MATCH_IPv4_NH_PREFIX_LEN(condition))
37 rhc->rhc_rule = "ip next-hop prefix-len";
38
39 rhc->rhc_mhook = generic_match_delete;
40 rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
41
42 rv = generic_match_add(rhc->rhc_rmi, rhc->rhc_rule,
43 length, RMAP_EVENT_MATCH_ADDED,
44 args->errmsg, args->errmsg_len);
45 if (rv != CMD_SUCCESS) {
46 rhc->rhc_mhook = NULL;
47 return NB_ERR_INCONSISTENCY;
48 }
49 }
50
51 return NB_OK;
52 }
53
54 int
55 lib_route_map_entry_match_condition_rmap_match_condition_ipv4_prefix_length_destroy(
56 struct nb_cb_destroy_args *args)
57 {
58 switch (args->event) {
59 case NB_EV_VALIDATE:
60 case NB_EV_PREPARE:
61 case NB_EV_ABORT:
62 break;
63 case NB_EV_APPLY:
64 return lib_route_map_entry_match_destroy(args);
65 }
66
67 return NB_OK;
68 }
69
70 /*
71 * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-zebra-route-map:ipv6-prefix-length
72 */
73 int
74 lib_route_map_entry_match_condition_rmap_match_condition_ipv6_prefix_length_modify(
75 struct nb_cb_modify_args *args)
76 {
77 struct routemap_hook_context *rhc;
78 const char *length;
79 int rv;
80
81 switch (args->event) {
82 case NB_EV_VALIDATE:
83 case NB_EV_PREPARE:
84 case NB_EV_ABORT:
85 return NB_OK;
86 case NB_EV_APPLY:
87 /* Add configuration. */
88 rhc = nb_running_get_entry(args->dnode, NULL, true);
89 length = yang_dnode_get_string(args->dnode, NULL);
90
91 /* Set destroy information. */
92 rhc->rhc_mhook = generic_match_delete;
93 rhc->rhc_rule = "ipv6 address prefix-len";
94 rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
95
96 rv = generic_match_add(rhc->rhc_rmi, "ipv6 address prefix-len",
97 length, RMAP_EVENT_MATCH_ADDED,
98 args->errmsg, args->errmsg_len);
99 if (rv != CMD_SUCCESS) {
100 rhc->rhc_mhook = NULL;
101 return NB_ERR_INCONSISTENCY;
102 }
103 }
104
105 return NB_OK;
106 }
107
108 int
109 lib_route_map_entry_match_condition_rmap_match_condition_ipv6_prefix_length_destroy(
110 struct nb_cb_destroy_args *args)
111 {
112 switch (args->event) {
113 case NB_EV_VALIDATE:
114 case NB_EV_PREPARE:
115 case NB_EV_ABORT:
116 break;
117 case NB_EV_APPLY:
118 return lib_route_map_entry_match_destroy(args);
119 }
120
121 return NB_OK;
122
123 }
124
125 /*
126 * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-zebra-route-map:source-instance
127 */
128 int
129 lib_route_map_entry_match_condition_rmap_match_condition_source_instance_modify(
130 struct nb_cb_modify_args *args)
131 {
132 struct routemap_hook_context *rhc;
133 const char *type;
134 int rv;
135
136 switch (args->event) {
137 case NB_EV_VALIDATE:
138 case NB_EV_PREPARE:
139 case NB_EV_ABORT:
140 break;
141 case NB_EV_APPLY:
142 /* Add configuration. */
143 rhc = nb_running_get_entry(args->dnode, NULL, true);
144 type = yang_dnode_get_string(args->dnode, NULL);
145
146 /* Set destroy information. */
147 rhc->rhc_mhook = generic_match_delete;
148 rhc->rhc_rule = "source-instance";
149 rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
150
151 rv = generic_match_add(rhc->rhc_rmi, "source-instance",
152 type, RMAP_EVENT_MATCH_ADDED,
153 args->errmsg, args->errmsg_len);
154 if (rv != CMD_SUCCESS) {
155 rhc->rhc_mhook = NULL;
156 return NB_ERR_INCONSISTENCY;
157 }
158 }
159
160 return NB_OK;
161 }
162
163 int
164 lib_route_map_entry_match_condition_rmap_match_condition_source_instance_destroy(
165 struct nb_cb_destroy_args *args)
166 {
167 switch (args->event) {
168 case NB_EV_VALIDATE:
169 case NB_EV_PREPARE:
170 case NB_EV_ABORT:
171 break;
172 case NB_EV_APPLY:
173 return lib_route_map_entry_match_destroy(args);
174 }
175
176 return NB_OK;
177 }
178
179 /*
180 * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-zebra-route-map:source-protocol
181 */
182 int
183 lib_route_map_entry_match_condition_rmap_match_condition_source_protocol_modify(
184 struct nb_cb_modify_args *args)
185 {
186 struct routemap_hook_context *rhc;
187 const char *type;
188 int rv;
189
190 switch (args->event) {
191 case NB_EV_VALIDATE:
192 type = yang_dnode_get_string(args->dnode, NULL);
193 if (proto_name2num(type) == -1) {
194 zlog_warn("%s: invalid protocol: %s", __func__, type);
195 return NB_ERR_VALIDATION;
196 }
197 return NB_OK;
198 case NB_EV_PREPARE:
199 case NB_EV_ABORT:
200 return NB_OK;
201 case NB_EV_APPLY:
202 /* NOTHING */
203 break;
204 }
205
206 /* Add configuration. */
207 rhc = nb_running_get_entry(args->dnode, NULL, true);
208 type = yang_dnode_get_string(args->dnode, NULL);
209
210 /* Set destroy information. */
211 rhc->rhc_mhook = generic_match_delete;
212 rhc->rhc_rule = "source-protocol";
213 rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
214
215 rv = generic_match_add(rhc->rhc_rmi, "source-protocol", type,
216 RMAP_EVENT_MATCH_ADDED,
217 args->errmsg, args->errmsg_len);
218 if (rv != CMD_SUCCESS) {
219 rhc->rhc_mhook = NULL;
220 return NB_ERR_INCONSISTENCY;
221 }
222
223 return NB_OK;
224 }
225
226 int
227 lib_route_map_entry_match_condition_rmap_match_condition_source_protocol_destroy(
228 struct nb_cb_destroy_args *args)
229 {
230 switch (args->event) {
231 case NB_EV_VALIDATE:
232 case NB_EV_PREPARE:
233 case NB_EV_ABORT:
234 break;
235 case NB_EV_APPLY:
236 return lib_route_map_entry_match_destroy(args);
237 }
238
239 return NB_OK;
240 }
241
242 /*
243 * XPath: /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-zebra-route-map:ipv4-src-address
244 */
245 int
246 lib_route_map_entry_set_action_rmap_set_action_ipv4_src_address_modify(
247 struct nb_cb_modify_args *args)
248 {
249 struct routemap_hook_context *rhc;
250 struct interface *pif = NULL;
251 const char *source;
252 struct vrf *vrf;
253 struct prefix p;
254 int rv;
255
256 switch (args->event) {
257 case NB_EV_VALIDATE:
258 memset(&p, 0, sizeof(p));
259 yang_dnode_get_ipv4p(&p, args->dnode, NULL);
260 if (zebra_check_addr(&p) == 0) {
261 zlog_warn("%s: invalid IPv4 address: %s", __func__,
262 yang_dnode_get_string(args->dnode, NULL));
263 return NB_ERR_VALIDATION;
264 }
265
266 RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) {
267 pif = if_lookup_exact_address(&p.u.prefix4, AF_INET,
268 vrf->vrf_id);
269 if (pif != NULL)
270 break;
271 }
272 if (pif == NULL) {
273 zlog_warn("%s: is not a local address: %s", __func__,
274 yang_dnode_get_string(args->dnode, NULL));
275 return NB_ERR_VALIDATION;
276 }
277 return NB_OK;
278 case NB_EV_PREPARE:
279 case NB_EV_ABORT:
280 return NB_OK;
281 case NB_EV_APPLY:
282 /* NOTHING */
283 break;
284 }
285
286 /* Add configuration. */
287 rhc = nb_running_get_entry(args->dnode, NULL, true);
288 source = yang_dnode_get_string(args->dnode, NULL);
289
290 /* Set destroy information. */
291 rhc->rhc_shook = generic_set_delete;
292 rhc->rhc_rule = "src";
293
294 rv = generic_set_add(rhc->rhc_rmi, "src", source,
295 args->errmsg, args->errmsg_len);
296 if (rv != CMD_SUCCESS) {
297 rhc->rhc_shook = NULL;
298 return NB_ERR_INCONSISTENCY;
299 }
300
301 return NB_OK;
302 }
303
304 int
305 lib_route_map_entry_set_action_rmap_set_action_ipv4_src_address_destroy(
306 struct nb_cb_destroy_args *args)
307 {
308 switch (args->event) {
309 case NB_EV_VALIDATE:
310 case NB_EV_PREPARE:
311 case NB_EV_ABORT:
312 break;
313 case NB_EV_APPLY:
314 return lib_route_map_entry_set_destroy(args);
315 }
316
317 return NB_OK;
318 }
319
320 /*
321 * XPath: /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-zebra-route-map:ipv6-src-address
322 */
323 int
324 lib_route_map_entry_set_action_rmap_set_action_ipv6_src_address_modify(
325 struct nb_cb_modify_args *args)
326 {
327 struct routemap_hook_context *rhc;
328 struct interface *pif = NULL;
329 const char *source;
330 struct vrf *vrf;
331 struct prefix p;
332 int rv;
333
334 switch (args->event) {
335 case NB_EV_VALIDATE:
336 memset(&p, 0, sizeof(p));
337 yang_dnode_get_ipv6p(&p, args->dnode, NULL);
338 if (zebra_check_addr(&p) == 0) {
339 zlog_warn("%s: invalid IPv6 address: %s", __func__,
340 yang_dnode_get_string(args->dnode, NULL));
341 return NB_ERR_VALIDATION;
342 }
343
344 RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) {
345 pif = if_lookup_exact_address(&p.u.prefix6, AF_INET6,
346 vrf->vrf_id);
347 if (pif != NULL)
348 break;
349 }
350 if (pif == NULL) {
351 zlog_warn("%s: is not a local address: %s", __func__,
352 yang_dnode_get_string(args->dnode, NULL));
353 return NB_ERR_VALIDATION;
354 }
355 return NB_OK;
356 case NB_EV_PREPARE:
357 case NB_EV_ABORT:
358 return NB_OK;
359 case NB_EV_APPLY:
360 /* NOTHING */
361 break;
362 }
363
364 /* Add configuration. */
365 rhc = nb_running_get_entry(args->dnode, NULL, true);
366 source = yang_dnode_get_string(args->dnode, NULL);
367
368 /* Set destroy information. */
369 rhc->rhc_shook = generic_set_delete;
370 rhc->rhc_rule = "src";
371
372 rv = generic_set_add(rhc->rhc_rmi, "src", source,
373 args->errmsg, args->errmsg_len);
374 if (rv != CMD_SUCCESS) {
375 rhc->rhc_shook = NULL;
376 return NB_ERR_INCONSISTENCY;
377 }
378
379 return NB_OK;
380 }
381
382 int
383 lib_route_map_entry_set_action_rmap_set_action_ipv6_src_address_destroy(
384 struct nb_cb_destroy_args *args)
385 {
386 switch (args->event) {
387 case NB_EV_VALIDATE:
388 case NB_EV_PREPARE:
389 case NB_EV_ABORT:
390 break;
391 case NB_EV_APPLY:
392 return lib_route_map_entry_set_destroy(args);
393 }
394
395 return NB_OK;
396 }