]> git.proxmox.com Git - mirror_frr.git/blame - lib/filter_nb.c
yang: fix cisco access list network information
[mirror_frr.git] / lib / filter_nb.c
CommitLineData
4470143b
RZ
1/*
2 * FRR filter northbound implementation.
3 *
4 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
5 * Rafael Zalamena
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23#include "zebra.h"
24
4470143b
RZ
25#include "lib/northbound.h"
26#include "lib/prefix.h"
8bc38cbd 27#include "lib/printfrr.h"
4470143b
RZ
28
29#include "lib/filter.h"
30#include "lib/plist.h"
31#include "lib/plist_int.h"
1eb17c77 32#include "lib/routemap.h"
4470143b 33
fb8884f3
RZ
34/* Helper function. */
35static in_addr_t
36ipv4_network_addr(in_addr_t hostaddr, int masklen)
37{
38 struct in_addr mask;
39
40 masklen2ip(masklen, &mask);
41 return hostaddr & mask.s_addr;
42}
43
1eb17c77
K
44static void acl_notify_route_map(struct access_list *acl, int route_map_event)
45{
46 switch (route_map_event) {
47 case RMAP_EVENT_FILTER_ADDED:
48 if (acl->master->add_hook)
49 (*acl->master->add_hook)(acl);
50 break;
51 case RMAP_EVENT_FILTER_DELETED:
52 if (acl->master->delete_hook)
53 (*acl->master->delete_hook)(acl);
54 break;
55 }
56
57 route_map_notify_dependencies(acl->name, route_map_event);
58}
59
8bc38cbd 60static enum nb_error prefix_list_length_validate(struct nb_cb_modify_args *args)
4362a768 61{
8bc38cbd 62 int type = yang_dnode_get_enum(args->dnode, "../../type");
4362a768
RZ
63 const char *xpath_le = NULL, *xpath_ge = NULL;
64 struct prefix p;
65 uint8_t le, ge;
66
be96651c 67 if (type == YPLT_IPV4) {
8bc38cbd 68 yang_dnode_get_prefix(&p, args->dnode, "../ipv4-prefix");
4362a768
RZ
69 xpath_le = "../ipv4-prefix-length-lesser-or-equal";
70 xpath_ge = "../ipv4-prefix-length-greater-or-equal";
71 } else {
8bc38cbd 72 yang_dnode_get_prefix(&p, args->dnode, "../ipv6-prefix");
4362a768
RZ
73 xpath_le = "../ipv6-prefix-length-lesser-or-equal";
74 xpath_ge = "../ipv6-prefix-length-greater-or-equal";
75 }
76
77 /*
78 * Check rule:
79 * prefix length <= le.
80 */
8bc38cbd
RZ
81 if (yang_dnode_exists(args->dnode, xpath_le)) {
82 le = yang_dnode_get_uint8(args->dnode, xpath_le);
4362a768
RZ
83 if (p.prefixlen > le)
84 goto log_and_fail;
4362a768
RZ
85 }
86
87 /*
88 * Check rule:
89 * prefix length < ge.
90 */
8bc38cbd
RZ
91 if (yang_dnode_exists(args->dnode, xpath_ge)) {
92 ge = yang_dnode_get_uint8(args->dnode, xpath_ge);
4362a768
RZ
93 if (p.prefixlen >= ge)
94 goto log_and_fail;
95 }
96
97 /*
98 * Check rule:
99 * ge <= le.
100 */
8bc38cbd
RZ
101 if (yang_dnode_exists(args->dnode, xpath_le)
102 && yang_dnode_exists(args->dnode, xpath_ge)) {
103 le = yang_dnode_get_uint8(args->dnode, xpath_le);
104 ge = yang_dnode_get_uint8(args->dnode, xpath_ge);
4362a768
RZ
105 if (ge > le)
106 goto log_and_fail;
107 }
108
109 return NB_OK;
110
8bc38cbd
RZ
111log_and_fail:
112 snprintfrr(
113 args->errmsg, args->errmsg_len,
114 "Invalid prefix range for %pFX: Make sure that mask length < ge <= le",
115 &p);
4362a768
RZ
116 return NB_ERR_VALIDATION;
117}
118
81b50422
RZ
119/**
120 * Sets prefix list entry to blank value.
121 *
122 * \param[out] ple prefix list entry to modify.
123 */
124static void prefix_list_entry_set_empty(struct prefix_list_entry *ple)
125{
126 ple->any = false;
127 memset(&ple->prefix, 0, sizeof(ple->prefix));
128 ple->ge = 0;
129 ple->le = 0;
130}
131
0ed507dd
RZ
132/**
133 * Unsets the cisco style rule for addresses so it becomes disabled (the
134 * equivalent of setting: `0.0.0.0/32`).
135 *
136 * \param addr address part.
137 * \param mask mask part.
138 */
139static void cisco_unset_addr_mask(struct in_addr *addr, struct in_addr *mask)
140{
141 addr->s_addr = INADDR_ANY;
142 mask->s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
143}
144
4470143b 145/*
375d157f 146 * XPath: /frr-filter:lib/access-list
4470143b 147 */
375d157f 148static int lib_access_list_create(struct nb_cb_create_args *args)
4470143b 149{
375d157f 150 struct access_list *acl = NULL;
4470143b 151 const char *acl_name;
375d157f 152 int type;
4470143b 153
fb8884f3 154 if (args->event != NB_EV_APPLY)
4470143b
RZ
155 return NB_OK;
156
375d157f
RZ
157 type = yang_dnode_get_enum(args->dnode, "./type");
158 acl_name = yang_dnode_get_string(args->dnode, "./name");
159
160 switch (type) {
161 case YALT_IPV4:
162 acl = access_list_get(AFI_IP, acl_name);
163 break;
164 case YALT_IPV6:
165 acl = access_list_get(AFI_IP6, acl_name);
166 break;
167 case YALT_MAC:
168 acl = access_list_get(AFI_L2VPN, acl_name);
169 break;
170 }
171
fb8884f3 172 nb_running_set_entry(args->dnode, acl);
4470143b
RZ
173
174 return NB_OK;
175}
176
375d157f 177static int lib_access_list_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
178{
179 struct access_master *am;
180 struct access_list *acl;
181
fb8884f3 182 if (args->event != NB_EV_APPLY)
4470143b
RZ
183 return NB_OK;
184
fb8884f3 185 acl = nb_running_unset_entry(args->dnode);
4470143b
RZ
186 am = acl->master;
187 if (am->delete_hook)
188 am->delete_hook(acl);
189
190 access_list_delete(acl);
191
192 return NB_OK;
193}
194
195/*
375d157f 196 * XPath: /frr-filter:lib/access-list/remark
4470143b 197 */
375d157f 198static int lib_access_list_remark_modify(struct nb_cb_modify_args *args)
4470143b
RZ
199{
200 struct access_list *acl;
201 const char *remark;
202
fb8884f3 203 if (args->event != NB_EV_APPLY)
4470143b
RZ
204 return NB_OK;
205
fb8884f3 206 acl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
207 if (acl->remark)
208 XFREE(MTYPE_TMP, acl->remark);
209
fb8884f3 210 remark = yang_dnode_get_string(args->dnode, NULL);
4470143b
RZ
211 acl->remark = XSTRDUP(MTYPE_TMP, remark);
212
213 return NB_OK;
214}
215
fb8884f3 216static int
375d157f 217lib_access_list_remark_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
218{
219 struct access_list *acl;
220
fb8884f3 221 if (args->event != NB_EV_APPLY)
4470143b
RZ
222 return NB_OK;
223
fb8884f3 224 acl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
225 if (acl->remark)
226 XFREE(MTYPE_TMP, acl->remark);
227
4470143b
RZ
228 return NB_OK;
229}
230
375d157f 231
4470143b 232/*
375d157f 233 * XPath: /frr-filter:lib/access-list/entry
4470143b 234 */
375d157f 235static int lib_access_list_entry_create(struct nb_cb_create_args *args)
4470143b 236{
4470143b
RZ
237 struct access_list *acl;
238 struct filter *f;
4470143b 239
fb8884f3 240 if (args->event != NB_EV_APPLY)
4470143b
RZ
241 return NB_OK;
242
4470143b 243 f = filter_new();
fb8884f3 244 f->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
4470143b 245
fb8884f3 246 acl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
247 f->acl = acl;
248 access_list_filter_add(acl, f);
fb8884f3 249 nb_running_set_entry(args->dnode, f);
4470143b
RZ
250
251 return NB_OK;
252}
253
375d157f 254static int lib_access_list_entry_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
255{
256 struct access_list *acl;
257 struct filter *f;
258
fb8884f3 259 if (args->event != NB_EV_APPLY)
4470143b
RZ
260 return NB_OK;
261
fb8884f3 262 f = nb_running_unset_entry(args->dnode);
4470143b
RZ
263 acl = f->acl;
264 access_list_filter_delete(acl, f);
265
266 return NB_OK;
267}
268
269/*
375d157f 270 * XPath: /frr-filter:lib/access-list/entry/action
4470143b
RZ
271 */
272static int
375d157f 273lib_access_list_entry_action_modify(struct nb_cb_modify_args *args)
4470143b
RZ
274{
275 const char *filter_type;
276 struct filter *f;
277
fb8884f3 278 if (args->event != NB_EV_APPLY)
4470143b
RZ
279 return NB_OK;
280
fb8884f3
RZ
281 f = nb_running_get_entry(args->dnode, NULL, true);
282 filter_type = yang_dnode_get_string(args->dnode, NULL);
4470143b
RZ
283 if (strcmp(filter_type, "permit") == 0)
284 f->type = FILTER_PERMIT;
285 else
286 f->type = FILTER_DENY;
287
1eb17c77
K
288 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
289
4470143b
RZ
290 return NB_OK;
291}
292
293/*
375d157f 294 * XPath: /frr-filter:lib/access-list/entry/ipv4-prefix
4470143b
RZ
295 */
296static int
375d157f 297lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
4470143b 298{
375d157f 299 struct filter_zebra *fz;
4470143b
RZ
300 struct filter *f;
301
fb8884f3 302 if (args->event != NB_EV_APPLY)
4470143b
RZ
303 return NB_OK;
304
fb8884f3 305 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
306 f->cisco = 0;
307 fz = &f->u.zfilter;
308 yang_dnode_get_prefix(&fz->prefix, args->dnode, NULL);
4470143b 309
1eb17c77
K
310 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
311
4470143b
RZ
312 return NB_OK;
313}
314
315static int
375d157f 316lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
4470143b 317{
375d157f 318 struct filter_zebra *fz;
4470143b
RZ
319 struct filter *f;
320
fb8884f3 321 if (args->event != NB_EV_APPLY)
4470143b
RZ
322 return NB_OK;
323
fb8884f3 324 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
325 fz = &f->u.zfilter;
326 memset(&fz->prefix, 0, sizeof(fz->prefix));
4470143b 327
1eb17c77
K
328 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
329
4470143b
RZ
330 return NB_OK;
331}
332
333/*
375d157f 334 * XPath: /frr-filter:lib/access-list/entry/ipv4-exact-match
4470143b
RZ
335 */
336static int
375d157f 337lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args *args)
4470143b 338{
375d157f 339 struct filter_zebra *fz;
4470143b 340 struct filter *f;
4470143b 341
fb8884f3 342 if (args->event != NB_EV_APPLY)
4470143b
RZ
343 return NB_OK;
344
fb8884f3 345 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
346 fz = &f->u.zfilter;
347 fz->exact = yang_dnode_get_bool(args->dnode, NULL);
4470143b 348
1eb17c77
K
349 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
350
4470143b
RZ
351 return NB_OK;
352}
353
354static int
375d157f 355lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args *args)
4470143b 356{
375d157f 357 struct filter_zebra *fz;
4470143b
RZ
358 struct filter *f;
359
fb8884f3 360 if (args->event != NB_EV_APPLY)
4470143b
RZ
361 return NB_OK;
362
fb8884f3 363 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
364 fz = &f->u.zfilter;
365 fz->exact = 0;
4470143b 366
1eb17c77
K
367 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
368
4470143b
RZ
369 return NB_OK;
370}
371
372/*
375d157f 373 * XPath: /frr-filter:lib/access-list/entry/host
4470143b 374 */
fb8884f3 375static int
375d157f 376lib_access_list_entry_host_modify(struct nb_cb_modify_args *args)
4470143b
RZ
377{
378 struct filter_cisco *fc;
379 struct filter *f;
380
fb8884f3 381 if (args->event != NB_EV_APPLY)
4470143b
RZ
382 return NB_OK;
383
fb8884f3 384 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f 385 f->cisco = 1;
4470143b 386 fc = &f->u.cfilter;
375d157f 387 yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
0ed507dd 388 fc->addr_mask.s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
4470143b 389
1eb17c77
K
390 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
391
4470143b
RZ
392 return NB_OK;
393}
394
395static int
375d157f 396lib_access_list_entry_host_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
397{
398 struct filter_cisco *fc;
399 struct filter *f;
400
fb8884f3 401 if (args->event != NB_EV_APPLY)
4470143b
RZ
402 return NB_OK;
403
fb8884f3 404 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b 405 fc = &f->u.cfilter;
0ed507dd 406 cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
4470143b 407
1eb17c77
K
408 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
409
4470143b
RZ
410 return NB_OK;
411}
412
413/*
375d157f 414 * XPath: /frr-filter:lib/access-list/entry/network
4470143b 415 */
375d157f
RZ
416static int
417lib_access_list_entry_network_modify(struct nb_cb_modify_args *args)
4470143b
RZ
418{
419 struct filter_cisco *fc;
420 struct filter *f;
375d157f 421 struct prefix p;
4470143b 422
fb8884f3 423 if (args->event != NB_EV_APPLY)
4470143b
RZ
424 return NB_OK;
425
fb8884f3 426 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f 427 f->cisco = 1;
4470143b 428 fc = &f->u.cfilter;
375d157f
RZ
429 yang_dnode_get_prefix(&p, args->dnode, NULL);
430 fc->addr.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen);
431 masklen2ip(p.prefixlen, &fc->addr_mask);
0ed507dd 432 fc->addr_mask.s_addr = ~fc->addr_mask.s_addr;
4470143b 433
1eb17c77
K
434 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
435
4470143b
RZ
436 return NB_OK;
437}
438
375d157f
RZ
439static int
440lib_access_list_entry_network_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
441{
442 struct filter_cisco *fc;
443 struct filter *f;
444
fb8884f3 445 if (args->event != NB_EV_APPLY)
4470143b
RZ
446 return NB_OK;
447
fb8884f3 448 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b 449 fc = &f->u.cfilter;
0ed507dd 450 cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
4470143b 451
1eb17c77
K
452 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
453
4470143b
RZ
454 return NB_OK;
455}
456
457/*
375d157f 458 * XPath: /frr-filter:lib/access-list/entry/source-any
4470143b 459 */
375d157f
RZ
460static int
461lib_access_list_entry_source_any_create(struct nb_cb_create_args *args)
4470143b
RZ
462{
463 struct filter_cisco *fc;
464 struct filter *f;
4470143b 465
fb8884f3 466 if (args->event != NB_EV_APPLY)
4470143b
RZ
467 return NB_OK;
468
fb8884f3 469 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f 470 f->cisco = 1;
4470143b 471 fc = &f->u.cfilter;
375d157f 472 fc->addr.s_addr = INADDR_ANY;
0ed507dd 473 fc->addr_mask.s_addr = CISCO_BIN_ANY_WILDCARD_MASK;
4470143b 474
1eb17c77
K
475 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
476
4470143b
RZ
477 return NB_OK;
478}
479
375d157f
RZ
480static int
481lib_access_list_entry_source_any_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
482{
483 struct filter_cisco *fc;
484 struct filter *f;
485
fb8884f3 486 if (args->event != NB_EV_APPLY)
4470143b
RZ
487 return NB_OK;
488
fb8884f3 489 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b 490 fc = &f->u.cfilter;
0ed507dd 491 cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
4470143b 492
1eb17c77
K
493 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
494
4470143b
RZ
495 return NB_OK;
496}
497
498/*
375d157f 499 * XPath: /frr-filter:lib/access-list/entry/destination-host
4470143b 500 */
375d157f
RZ
501static int lib_access_list_entry_destination_host_modify(
502 struct nb_cb_modify_args *args)
4470143b
RZ
503{
504 struct filter_cisco *fc;
505 struct filter *f;
506
fb8884f3 507 if (args->event != NB_EV_APPLY)
4470143b
RZ
508 return NB_OK;
509
fb8884f3 510 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b 511 fc = &f->u.cfilter;
375d157f
RZ
512 fc->extended = 1;
513 yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
0ed507dd 514 fc->mask_mask.s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
4470143b 515
1eb17c77
K
516 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
517
4470143b
RZ
518 return NB_OK;
519}
520
375d157f 521static int lib_access_list_entry_destination_host_destroy(
fb8884f3 522 struct nb_cb_destroy_args *args)
4470143b
RZ
523{
524 struct filter_cisco *fc;
525 struct filter *f;
526
fb8884f3 527 if (args->event != NB_EV_APPLY)
4470143b
RZ
528 return NB_OK;
529
fb8884f3 530 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b 531 fc = &f->u.cfilter;
375d157f 532 fc->extended = 0;
0ed507dd 533 cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
4470143b 534
1eb17c77
K
535 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
536
4470143b
RZ
537 return NB_OK;
538}
539
540/*
375d157f 541 * XPath: /frr-filter:lib/access-list/entry/destination-network
4470143b 542 */
375d157f
RZ
543static int lib_access_list_entry_destination_network_modify(
544 struct nb_cb_modify_args *args)
4470143b 545{
375d157f 546 struct filter_cisco *fc;
4470143b 547 struct filter *f;
375d157f 548 struct prefix p;
4470143b 549
fb8884f3 550 if (args->event != NB_EV_APPLY)
4470143b
RZ
551 return NB_OK;
552
fb8884f3 553 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
554 fc = &f->u.cfilter;
555 fc->extended = 1;
556 yang_dnode_get_prefix(&p, args->dnode, NULL);
557 fc->mask.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen);
558 masklen2ip(p.prefixlen, &fc->mask_mask);
0ed507dd 559 fc->mask_mask.s_addr = ~fc->mask_mask.s_addr;
4470143b 560
1eb17c77
K
561 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
562
4470143b
RZ
563 return NB_OK;
564}
565
375d157f
RZ
566static int lib_access_list_entry_destination_network_destroy(
567 struct nb_cb_destroy_args *args)
4470143b 568{
375d157f 569 struct filter_cisco *fc;
4470143b
RZ
570 struct filter *f;
571
fb8884f3 572 if (args->event != NB_EV_APPLY)
4470143b
RZ
573 return NB_OK;
574
fb8884f3 575 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
576 fc = &f->u.cfilter;
577 fc->extended = 0;
0ed507dd 578 cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
4470143b 579
1eb17c77
K
580 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
581
4470143b
RZ
582 return NB_OK;
583}
584
585/*
375d157f 586 * XPath: /frr-filter:lib/access-list/entry/destination-any
4470143b 587 */
375d157f
RZ
588static int lib_access_list_entry_destination_any_create(
589 struct nb_cb_create_args *args)
4470143b 590{
375d157f 591 struct filter_cisco *fc;
4470143b
RZ
592 struct filter *f;
593
fb8884f3 594 if (args->event != NB_EV_APPLY)
4470143b
RZ
595 return NB_OK;
596
fb8884f3 597 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
598 fc = &f->u.cfilter;
599 fc->extended = 1;
600 fc->mask.s_addr = INADDR_ANY;
0ed507dd 601 fc->mask_mask.s_addr = CISCO_BIN_ANY_WILDCARD_MASK;
4470143b 602
1eb17c77
K
603 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
604
4470143b
RZ
605 return NB_OK;
606}
607
375d157f
RZ
608static int lib_access_list_entry_destination_any_destroy(
609 struct nb_cb_destroy_args *args)
4470143b 610{
375d157f 611 struct filter_cisco *fc;
4470143b
RZ
612 struct filter *f;
613
fb8884f3 614 if (args->event != NB_EV_APPLY)
4470143b
RZ
615 return NB_OK;
616
fb8884f3 617 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
618 fc = &f->u.cfilter;
619 fc->extended = 0;
0ed507dd 620 cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
4470143b 621
1eb17c77
K
622 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
623
4470143b
RZ
624 return NB_OK;
625}
626
4470143b
RZ
627/*
628 * XPath: /frr-filter:lib/access-list/entry/any
629 */
fb8884f3 630static int lib_access_list_entry_any_create(struct nb_cb_create_args *args)
4470143b
RZ
631{
632 struct filter_zebra *fz;
633 struct filter *f;
634 int type;
635
fb8884f3 636 if (args->event != NB_EV_APPLY)
4470143b
RZ
637 return NB_OK;
638
fb8884f3 639 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f 640 f->cisco = 0;
4470143b
RZ
641 fz = &f->u.zfilter;
642 memset(&fz->prefix, 0, sizeof(fz->prefix));
643
fb8884f3 644 type = yang_dnode_get_enum(args->dnode, "../../type");
4470143b 645 switch (type) {
be96651c 646 case YALT_IPV4:
4470143b
RZ
647 fz->prefix.family = AF_INET;
648 break;
be96651c 649 case YALT_IPV6:
4470143b
RZ
650 fz->prefix.family = AF_INET6;
651 break;
be96651c 652 case YALT_MAC:
4470143b
RZ
653 fz->prefix.family = AF_ETHERNET;
654 break;
655 }
656
1eb17c77
K
657 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
658
4470143b
RZ
659 return NB_OK;
660}
661
fb8884f3 662static int lib_access_list_entry_any_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
663{
664 struct filter_zebra *fz;
665 struct filter *f;
666
fb8884f3 667 if (args->event != NB_EV_APPLY)
4470143b
RZ
668 return NB_OK;
669
fb8884f3 670 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
671 fz = &f->u.zfilter;
672 fz->prefix.family = 0;
673
1eb17c77
K
674 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
675
4470143b
RZ
676 return NB_OK;
677}
678
679/*
680 * XPath: /frr-filter:lib/prefix-list
681 */
fb8884f3 682static int lib_prefix_list_create(struct nb_cb_create_args *args)
4470143b 683{
ff94358e 684 struct prefix_list *pl = NULL;
4470143b
RZ
685 const char *name;
686 int type;
687
fb8884f3 688 if (args->event != NB_EV_APPLY)
4470143b
RZ
689 return NB_OK;
690
fb8884f3
RZ
691 type = yang_dnode_get_enum(args->dnode, "./type");
692 name = yang_dnode_get_string(args->dnode, "./name");
4470143b
RZ
693 switch (type) {
694 case 0: /* ipv4 */
695 pl = prefix_list_get(AFI_IP, 0, name);
696 break;
697 case 1: /* ipv6 */
698 pl = prefix_list_get(AFI_IP6, 0, name);
699 break;
700 }
701
fb8884f3 702 nb_running_set_entry(args->dnode, pl);
4470143b
RZ
703
704 return NB_OK;
705}
706
fb8884f3 707static int lib_prefix_list_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
708{
709 struct prefix_list *pl;
710
fb8884f3 711 if (args->event != NB_EV_APPLY)
4470143b
RZ
712 return NB_OK;
713
fb8884f3 714 pl = nb_running_unset_entry(args->dnode);
4470143b
RZ
715 prefix_list_delete(pl);
716
717 return NB_OK;
718}
719
720/*
cc82bcc1 721 * XPath: /frr-filter:lib/prefix-list/remark
4470143b 722 */
cc82bcc1 723static int lib_prefix_list_remark_modify(struct nb_cb_modify_args *args)
4470143b
RZ
724{
725 struct prefix_list *pl;
726 const char *remark;
727
fb8884f3 728 if (args->event != NB_EV_APPLY)
4470143b
RZ
729 return NB_OK;
730
fb8884f3 731 pl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
732 if (pl->desc)
733 XFREE(MTYPE_TMP, pl->desc);
734
fb8884f3 735 remark = yang_dnode_get_string(args->dnode, NULL);
4470143b
RZ
736 pl->desc = XSTRDUP(MTYPE_TMP, remark);
737
738 return NB_OK;
739}
740
cc82bcc1 741static int lib_prefix_list_remark_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
742{
743 struct prefix_list *pl;
744
fb8884f3 745 if (args->event != NB_EV_APPLY)
4470143b
RZ
746 return NB_OK;
747
fb8884f3 748 pl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
749 if (pl->desc)
750 XFREE(MTYPE_TMP, pl->desc);
751
4470143b
RZ
752 return NB_OK;
753}
754
755/*
756 * XPath: /frr-filter:lib/prefix-list/entry
757 */
fb8884f3 758static int lib_prefix_list_entry_create(struct nb_cb_create_args *args)
4470143b
RZ
759{
760 struct prefix_list_entry *ple;
761 struct prefix_list *pl;
4470143b 762
fb8884f3 763 if (args->event != NB_EV_APPLY)
4470143b
RZ
764 return NB_OK;
765
fb8884f3 766 pl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
767 ple = prefix_list_entry_new();
768 ple->pl = pl;
cc82bcc1 769 ple->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
81b50422 770 prefix_list_entry_set_empty(ple);
a7b28218 771 nb_running_set_entry(args->dnode, ple);
4470143b
RZ
772
773 return NB_OK;
774}
775
fb8884f3 776static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
777{
778 struct prefix_list_entry *ple;
779
fb8884f3 780 if (args->event != NB_EV_APPLY)
4470143b
RZ
781 return NB_OK;
782
fb8884f3 783 ple = nb_running_unset_entry(args->dnode);
a7b28218 784 if (ple->installed)
81b50422 785 prefix_list_entry_delete2(ple);
a7b28218
RZ
786 else
787 prefix_list_entry_free(ple);
4470143b
RZ
788
789 return NB_OK;
790}
791
792/*
793 * XPath: /frr-filter:lib/prefix-list/entry/action
794 */
fb8884f3 795static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args *args)
4470143b
RZ
796{
797 struct prefix_list_entry *ple;
be96651c 798 int action_type;
4470143b 799
fb8884f3 800 if (args->event != NB_EV_APPLY)
4470143b
RZ
801 return NB_OK;
802
fb8884f3 803 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
804
805 /* Start prefix entry update procedure. */
806 prefix_list_entry_update_start(ple);
807
be96651c
RZ
808 action_type = yang_dnode_get_enum(args->dnode, NULL);
809 if (action_type == YPLA_PERMIT)
4470143b
RZ
810 ple->type = PREFIX_PERMIT;
811 else
812 ple->type = PREFIX_DENY;
813
a7b28218
RZ
814 /* Finish prefix entry update procedure. */
815 prefix_list_entry_update_finish(ple);
816
4470143b
RZ
817 return NB_OK;
818}
819
820/*
821 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix
822 */
823static int
fb8884f3 824lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
4470143b
RZ
825{
826 struct prefix_list_entry *ple;
cf4472c4
RZ
827 struct prefix p;
828
829 if (args->event == NB_EV_VALIDATE) {
830 /*
831 * TODO: validate prefix_entry_dup_check() passes.
832 *
833 * This needs to be implemented using YANG lyd_node
834 * navigation, because the `priv` data structures are not
835 * available at `NB_EV_VALIDATE` phase. An easier
836 * alternative would be mark `ipvx-prefix` as unique
837 * (see RFC 7950, Section 7.8.3. The list "unique" Statement).
838 */
839 return NB_OK;
840 }
4470143b 841
fb8884f3 842 if (args->event != NB_EV_APPLY)
4470143b
RZ
843 return NB_OK;
844
fb8884f3 845 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
846
847 /* Start prefix entry update procedure. */
848 prefix_list_entry_update_start(ple);
849
fb8884f3 850 yang_dnode_get_prefix(&ple->prefix, args->dnode, NULL);
4470143b 851
cf4472c4
RZ
852 /* Apply mask and correct original address if necessary. */
853 prefix_copy(&p, &ple->prefix);
854 apply_mask(&p);
855 if (!prefix_same(&ple->prefix, &p)) {
856 zlog_info("%s: bad network %pFX correcting it to %pFX",
857 __func__, &ple->prefix, &p);
858 prefix_copy(&ple->prefix, &p);
859 }
860
861
a7b28218
RZ
862 /* Finish prefix entry update procedure. */
863 prefix_list_entry_update_finish(ple);
864
4470143b
RZ
865 return NB_OK;
866}
867
868static int
fb8884f3 869lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
870{
871 struct prefix_list_entry *ple;
872
fb8884f3 873 if (args->event != NB_EV_APPLY)
4470143b
RZ
874 return NB_OK;
875
fb8884f3 876 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
877
878 /* Start prefix entry update procedure. */
879 prefix_list_entry_update_start(ple);
880
4470143b 881 memset(&ple->prefix, 0, sizeof(ple->prefix));
4470143b 882
a7b28218
RZ
883 /* Finish prefix entry update procedure. */
884 prefix_list_entry_update_finish(ple);
885
4470143b
RZ
886 return NB_OK;
887}
888
889/*
890 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal
891 */
892static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
fb8884f3 893 struct nb_cb_modify_args *args)
4470143b
RZ
894{
895 struct prefix_list_entry *ple;
896
4362a768 897 if (args->event == NB_EV_VALIDATE &&
8bc38cbd 898 prefix_list_length_validate(args) != NB_OK)
4362a768
RZ
899 return NB_ERR_VALIDATION;
900
fb8884f3 901 if (args->event != NB_EV_APPLY)
4470143b
RZ
902 return NB_OK;
903
fb8884f3 904 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
905
906 /* Start prefix entry update procedure. */
907 prefix_list_entry_update_start(ple);
908
fb8884f3 909 ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
4470143b 910
a7b28218
RZ
911 /* Finish prefix entry update procedure. */
912 prefix_list_entry_update_finish(ple);
913
4470143b
RZ
914 return NB_OK;
915}
916
917static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
fb8884f3 918 struct nb_cb_destroy_args *args)
4470143b
RZ
919{
920 struct prefix_list_entry *ple;
921
fb8884f3 922 if (args->event != NB_EV_APPLY)
4470143b
RZ
923 return NB_OK;
924
fb8884f3 925 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
926
927 /* Start prefix entry update procedure. */
928 prefix_list_entry_update_start(ple);
929
4470143b
RZ
930 ple->ge = 0;
931
a7b28218
RZ
932 /* Finish prefix entry update procedure. */
933 prefix_list_entry_update_finish(ple);
934
4470143b
RZ
935 return NB_OK;
936}
937
938/*
939 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal
940 */
941static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
fb8884f3 942 struct nb_cb_modify_args *args)
4470143b
RZ
943{
944 struct prefix_list_entry *ple;
945
4362a768 946 if (args->event == NB_EV_VALIDATE &&
8bc38cbd 947 prefix_list_length_validate(args) != NB_OK)
4362a768
RZ
948 return NB_ERR_VALIDATION;
949
fb8884f3 950 if (args->event != NB_EV_APPLY)
4470143b
RZ
951 return NB_OK;
952
fb8884f3 953 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
954
955 /* Start prefix entry update procedure. */
956 prefix_list_entry_update_start(ple);
957
fb8884f3 958 ple->le = yang_dnode_get_uint8(args->dnode, NULL);
4470143b 959
a7b28218
RZ
960 /* Finish prefix entry update procedure. */
961 prefix_list_entry_update_finish(ple);
962
4470143b
RZ
963 return NB_OK;
964}
965
966static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
fb8884f3 967 struct nb_cb_destroy_args *args)
4470143b
RZ
968{
969 struct prefix_list_entry *ple;
970
fb8884f3 971 if (args->event != NB_EV_APPLY)
4470143b
RZ
972 return NB_OK;
973
fb8884f3 974 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
975
976 /* Start prefix entry update procedure. */
977 prefix_list_entry_update_start(ple);
978
4470143b
RZ
979 ple->le = 0;
980
a7b28218
RZ
981 /* Finish prefix entry update procedure. */
982 prefix_list_entry_update_finish(ple);
983
4470143b
RZ
984 return NB_OK;
985}
986
4470143b
RZ
987/*
988 * XPath: /frr-filter:lib/prefix-list/entry/any
989 */
fb8884f3 990static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
4470143b
RZ
991{
992 struct prefix_list_entry *ple;
81b50422 993 int type;
4470143b 994
fb8884f3 995 if (args->event != NB_EV_APPLY)
4470143b
RZ
996 return NB_OK;
997
fb8884f3 998 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
999
1000 /* Start prefix entry update procedure. */
1001 prefix_list_entry_update_start(ple);
1002
81b50422
RZ
1003 ple->any = true;
1004
1005 /* Fill prefix struct from scratch. */
4470143b 1006 memset(&ple->prefix, 0, sizeof(ple->prefix));
81b50422
RZ
1007
1008 type = yang_dnode_get_enum(args->dnode, "../../type");
1009 switch (type) {
be96651c 1010 case YPLT_IPV4:
81b50422
RZ
1011 ple->prefix.family = AF_INET;
1012 ple->ge = 0;
1013 ple->le = IPV4_MAX_BITLEN;
1014 break;
be96651c 1015 case YPLT_IPV6:
81b50422
RZ
1016 ple->prefix.family = AF_INET6;
1017 ple->ge = 0;
1018 ple->le = IPV6_MAX_BITLEN;
1019 break;
1020 }
4470143b 1021
a7b28218
RZ
1022 /* Finish prefix entry update procedure. */
1023 prefix_list_entry_update_finish(ple);
1024
4470143b
RZ
1025 return NB_OK;
1026}
1027
fb8884f3 1028static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
1029{
1030 struct prefix_list_entry *ple;
1031
fb8884f3 1032 if (args->event != NB_EV_APPLY)
4470143b
RZ
1033 return NB_OK;
1034
fb8884f3 1035 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1036
1037 /* Start prefix entry update procedure. */
1038 prefix_list_entry_update_start(ple);
1039
81b50422 1040 prefix_list_entry_set_empty(ple);
4470143b 1041
a7b28218
RZ
1042 /* Finish prefix entry update procedure. */
1043 prefix_list_entry_update_finish(ple);
1044
4470143b
RZ
1045 return NB_OK;
1046}
1047
1048/* clang-format off */
1049const struct frr_yang_module_info frr_filter_info = {
1050 .name = "frr-filter",
1051 .nodes = {
1052 {
375d157f 1053 .xpath = "/frr-filter:lib/access-list",
4470143b 1054 .cbs = {
375d157f
RZ
1055 .create = lib_access_list_create,
1056 .destroy = lib_access_list_destroy,
4470143b
RZ
1057 }
1058 },
1059 {
375d157f 1060 .xpath = "/frr-filter:lib/access-list/remark",
4470143b 1061 .cbs = {
375d157f
RZ
1062 .modify = lib_access_list_remark_modify,
1063 .destroy = lib_access_list_remark_destroy,
1064 .cli_show = access_list_remark_show,
4470143b
RZ
1065 }
1066 },
1067 {
375d157f 1068 .xpath = "/frr-filter:lib/access-list/entry",
4470143b 1069 .cbs = {
375d157f
RZ
1070 .create = lib_access_list_entry_create,
1071 .destroy = lib_access_list_entry_destroy,
1072 .cli_show = access_list_show,
4470143b
RZ
1073 }
1074 },
1075 {
375d157f 1076 .xpath = "/frr-filter:lib/access-list/entry/action",
4470143b 1077 .cbs = {
375d157f 1078 .modify = lib_access_list_entry_action_modify,
4470143b
RZ
1079 }
1080 },
1081 {
375d157f 1082 .xpath = "/frr-filter:lib/access-list/entry/ipv4-prefix",
4470143b 1083 .cbs = {
375d157f
RZ
1084 .modify = lib_access_list_entry_ipv4_prefix_modify,
1085 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
4470143b
RZ
1086 }
1087 },
1088 {
375d157f 1089 .xpath = "/frr-filter:lib/access-list/entry/ipv4-exact-match",
4470143b 1090 .cbs = {
375d157f
RZ
1091 .modify = lib_access_list_entry_ipv4_exact_match_modify,
1092 .destroy = lib_access_list_entry_ipv4_exact_match_destroy,
4470143b
RZ
1093 }
1094 },
1095 {
375d157f 1096 .xpath = "/frr-filter:lib/access-list/entry/host",
4470143b 1097 .cbs = {
375d157f
RZ
1098 .modify = lib_access_list_entry_host_modify,
1099 .destroy = lib_access_list_entry_host_destroy,
4470143b
RZ
1100 }
1101 },
1102 {
375d157f 1103 .xpath = "/frr-filter:lib/access-list/entry/network",
4470143b 1104 .cbs = {
375d157f
RZ
1105 .modify = lib_access_list_entry_network_modify,
1106 .destroy = lib_access_list_entry_network_destroy,
4470143b
RZ
1107 }
1108 },
1109 {
375d157f 1110 .xpath = "/frr-filter:lib/access-list/entry/source-any",
4470143b 1111 .cbs = {
375d157f
RZ
1112 .create = lib_access_list_entry_source_any_create,
1113 .destroy = lib_access_list_entry_source_any_destroy,
4470143b
RZ
1114 }
1115 },
1116 {
375d157f 1117 .xpath = "/frr-filter:lib/access-list/entry/destination-host",
4470143b 1118 .cbs = {
375d157f
RZ
1119 .modify = lib_access_list_entry_destination_host_modify,
1120 .destroy = lib_access_list_entry_destination_host_destroy,
4470143b
RZ
1121 }
1122 },
1123 {
375d157f 1124 .xpath = "/frr-filter:lib/access-list/entry/destination-network",
4470143b 1125 .cbs = {
375d157f
RZ
1126 .modify = lib_access_list_entry_destination_network_modify,
1127 .destroy = lib_access_list_entry_destination_network_destroy,
4470143b
RZ
1128 }
1129 },
1130 {
375d157f 1131 .xpath = "/frr-filter:lib/access-list/entry/destination-any",
4470143b 1132 .cbs = {
375d157f
RZ
1133 .create = lib_access_list_entry_destination_any_create,
1134 .destroy = lib_access_list_entry_destination_any_destroy,
4470143b
RZ
1135 }
1136 },
1137 {
1138 .xpath = "/frr-filter:lib/access-list/entry/ipv6-prefix",
1139 .cbs = {
a247b2b7
RZ
1140 .modify = lib_access_list_entry_ipv4_prefix_modify,
1141 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
4470143b
RZ
1142 }
1143 },
1144 {
1145 .xpath = "/frr-filter:lib/access-list/entry/ipv6-exact-match",
1146 .cbs = {
a247b2b7
RZ
1147 .modify = lib_access_list_entry_ipv4_exact_match_modify,
1148 .destroy = lib_access_list_entry_ipv4_exact_match_destroy,
4470143b
RZ
1149 }
1150 },
1151 {
1152 .xpath = "/frr-filter:lib/access-list/entry/mac",
1153 .cbs = {
a247b2b7
RZ
1154 .modify = lib_access_list_entry_ipv4_prefix_modify,
1155 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
4470143b
RZ
1156 }
1157 },
1158 {
1159 .xpath = "/frr-filter:lib/access-list/entry/any",
1160 .cbs = {
1161 .create = lib_access_list_entry_any_create,
1162 .destroy = lib_access_list_entry_any_destroy,
1163 }
1164 },
1165 {
1166 .xpath = "/frr-filter:lib/prefix-list",
1167 .cbs = {
1168 .create = lib_prefix_list_create,
1169 .destroy = lib_prefix_list_destroy,
1170 }
1171 },
1172 {
cc82bcc1 1173 .xpath = "/frr-filter:lib/prefix-list/remark",
4470143b 1174 .cbs = {
cc82bcc1
RZ
1175 .modify = lib_prefix_list_remark_modify,
1176 .destroy = lib_prefix_list_remark_destroy,
1d3c4b66 1177 .cli_show = prefix_list_remark_show,
4470143b
RZ
1178 }
1179 },
1180 {
1181 .xpath = "/frr-filter:lib/prefix-list/entry",
1182 .cbs = {
1183 .create = lib_prefix_list_entry_create,
1184 .destroy = lib_prefix_list_entry_destroy,
1d3c4b66 1185 .cli_show = prefix_list_show,
4470143b
RZ
1186 }
1187 },
1188 {
1189 .xpath = "/frr-filter:lib/prefix-list/entry/action",
1190 .cbs = {
1191 .modify = lib_prefix_list_entry_action_modify,
1192 }
1193 },
1194 {
1195 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix",
1196 .cbs = {
1197 .modify = lib_prefix_list_entry_ipv4_prefix_modify,
1198 .destroy = lib_prefix_list_entry_ipv4_prefix_destroy,
1199 }
1200 },
1201 {
1202 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal",
1203 .cbs = {
1204 .modify = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify,
1205 .destroy = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy,
1206 }
1207 },
1208 {
1209 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal",
1210 .cbs = {
1211 .modify = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify,
1212 .destroy = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy,
1213 }
1214 },
1215 {
1216 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix",
1217 .cbs = {
a247b2b7
RZ
1218 .modify = lib_prefix_list_entry_ipv4_prefix_modify,
1219 .destroy = lib_prefix_list_entry_ipv4_prefix_destroy,
4470143b
RZ
1220 }
1221 },
1222 {
1223 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal",
1224 .cbs = {
a247b2b7
RZ
1225 .modify = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify,
1226 .destroy = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy,
4470143b
RZ
1227 }
1228 },
1229 {
1230 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal",
1231 .cbs = {
a247b2b7
RZ
1232 .modify = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify,
1233 .destroy = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy,
4470143b
RZ
1234 }
1235 },
1236 {
1237 .xpath = "/frr-filter:lib/prefix-list/entry/any",
1238 .cbs = {
1239 .create = lib_prefix_list_entry_any_create,
1240 .destroy = lib_prefix_list_entry_any_destroy,
1241 }
1242 },
1243 {
1244 .xpath = NULL,
1245 },
1246 }
1247};