]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/rfapi/bgp_rfapi_cfg.c
Merge pull request #12854 from opensourcerouting/fix/bgp_withdraw_attr_not_used
[mirror_frr.git] / bgpd / rfapi / bgp_rfapi_cfg.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 *
4 * Copyright 2009-2016, LabN Consulting, L.L.C.
5 *
6 */
7 #include "lib/zebra.h"
8
9 #include "lib/command.h"
10 #include "lib/prefix.h"
11 #include "lib/memory.h"
12 #include "lib/linklist.h"
13 #include "lib/agg_table.h"
14 #include "lib/plist.h"
15 #include "lib/routemap.h"
16
17 #include "bgpd/bgpd.h"
18 #include "bgpd/bgp_attr.h"
19 #include "bgpd/bgp_route.h"
20 #include "bgpd/bgp_mplsvpn.h"
21
22 #include "bgpd/bgp_vty.h"
23 #include "bgpd/bgp_ecommunity.h"
24 #include "bgpd/rfapi/rfapi.h"
25 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
26 #include "bgpd/rfapi/rfapi_backend.h"
27 #include "bgpd/rfapi/rfapi_import.h"
28 #include "bgpd/rfapi/rfapi_private.h"
29 #include "bgpd/rfapi/rfapi_monitor.h"
30 #include "bgpd/rfapi/vnc_zebra.h"
31 #include "bgpd/rfapi/vnc_export_bgp.h"
32 #include "bgpd/rfapi/vnc_export_bgp_p.h"
33 #include "bgpd/rfapi/rfapi_vty.h"
34 #include "bgpd/rfapi/vnc_import_bgp.h"
35 #include "bgpd/rfapi/vnc_debug.h"
36
37 #ifdef ENABLE_BGP_VNC
38
39 #undef BGP_VNC_DEBUG_MATCH_GROUP
40
41
42 DEFINE_MGROUP(RFAPI, "rfapi");
43 DEFINE_MTYPE(RFAPI, RFAPI_CFG, "NVE Configuration");
44 DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG, "NVE Group Configuration");
45 DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG, "RFAPI L2 Group Configuration");
46 DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG, "RFAPI RFP Group Configuration");
47 DEFINE_MTYPE(RFAPI, RFAPI, "RFAPI Generic");
48 DEFINE_MTYPE(RFAPI, RFAPI_DESC, "RFAPI Descriptor");
49 DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE, "RFAPI Import Table");
50 DEFINE_MTYPE(RFAPI, RFAPI_MONITOR, "RFAPI Monitor VPN");
51 DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP, "RFAPI Monitor Encap");
52 DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP, "RFAPI Next Hop");
53 DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION, "RFAPI VN Option");
54 DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION, "RFAPI UN Option");
55 DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW, "RFAPI Withdraw");
56 DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME, "RFAPI RFGName");
57 DEFINE_MTYPE(RFAPI, RFAPI_ADB, "RFAPI Advertisement Data");
58 DEFINE_MTYPE(RFAPI, RFAPI_ETI, "RFAPI Export Table Info");
59 DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR, "RFAPI NVE Address");
60 DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG, "RFAPI Prefix Bag");
61 DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA, "RFAPI IT Extra");
62 DEFINE_MTYPE(RFAPI, RFAPI_INFO, "RFAPI Info");
63 DEFINE_MTYPE(RFAPI, RFAPI_ADDR, "RFAPI Addr");
64 DEFINE_MTYPE(RFAPI, RFAPI_UPDATED_RESPONSE_QUEUE, "RFAPI Updated Rsp Queue");
65 DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE, "RFAPI Recently Deleted Route");
66 DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT, "RFAPI L2 Address Option");
67 DEFINE_MTYPE(RFAPI, RFAPI_AP, "RFAPI Advertised Prefix");
68 DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH, "RFAPI Monitor Ethernet");
69
70 DEFINE_QOBJ_TYPE(rfapi_nve_group_cfg);
71 DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg);
72 /***********************************************************************
73 * RFAPI Support
74 ***********************************************************************/
75
76
77 /*
78 * compaitibility to old quagga_time call
79 * time_t value in terms of stabilised absolute time.
80 * replacement for POSIX time()
81 */
82 time_t rfapi_time(time_t *t)
83 {
84 time_t clock = monotime(NULL);
85 if (t)
86 *t = clock;
87 return clock;
88 }
89
90 void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg, struct list **nves,
91 uint8_t family) /* AF_INET, AF_INET6 */
92 {
93 struct listnode *hln;
94 struct rfapi_descriptor *rfd;
95
96 /*
97 * loop over nves in this grp, add to list
98 */
99 for (ALL_LIST_ELEMENTS_RO(rfg->nves, hln, rfd)) {
100 if (rfd->vn_addr.addr_family == family) {
101 if (!*nves)
102 *nves = list_new();
103 listnode_add(*nves, rfd);
104 }
105 }
106 }
107
108
109 struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
110 struct prefix *vn,
111 struct prefix *un)
112 {
113 struct rfapi_nve_group_cfg *rfg_vn = NULL;
114 struct rfapi_nve_group_cfg *rfg_un = NULL;
115
116 struct agg_table *rt_vn;
117 struct agg_table *rt_un;
118 struct agg_node *rn_vn;
119 struct agg_node *rn_un;
120
121 struct rfapi_nve_group_cfg *rfg;
122 struct listnode *node, *nnode;
123
124 switch (vn->family) {
125 case AF_INET:
126 rt_vn = hc->nve_groups_vn[AFI_IP];
127 break;
128 case AF_INET6:
129 rt_vn = hc->nve_groups_vn[AFI_IP6];
130 break;
131 default:
132 return NULL;
133 }
134
135 switch (un->family) {
136 case AF_INET:
137 rt_un = hc->nve_groups_un[AFI_IP];
138 break;
139 case AF_INET6:
140 rt_un = hc->nve_groups_un[AFI_IP6];
141 break;
142 default:
143 return NULL;
144 }
145
146 rn_vn = agg_node_match(rt_vn, vn); /* NB locks node */
147 if (rn_vn) {
148 rfg_vn = rn_vn->info;
149 agg_unlock_node(rn_vn);
150 }
151
152 rn_un = agg_node_match(rt_un, un); /* NB locks node */
153 if (rn_un) {
154 rfg_un = rn_un->info;
155 agg_unlock_node(rn_un);
156 }
157
158 #ifdef BGP_VNC_DEBUG_MATCH_GROUP
159 {
160 vnc_zlog_debug_verbose("%s: vn prefix: %pFX", __func__, vn);
161 vnc_zlog_debug_verbose("%s: un prefix: %pFX", __func__, un);
162 vnc_zlog_debug_verbose(
163 "%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p",
164 __func__, rn_vn, rn_un, rfg_vn, rfg_un);
165 }
166 #endif
167
168
169 if (rfg_un == rfg_vn) /* same group */
170 return rfg_un;
171 if (!rfg_un) /* un doesn't match, return vn-matched grp */
172 return rfg_vn;
173 if (!rfg_vn) /* vn doesn't match, return un-matched grp */
174 return rfg_un;
175
176 /*
177 * Two different nve groups match: the group configured earlier wins.
178 * For now, just walk the sequential list and pick the first one.
179 * If this approach is too slow, then store serial numbers in the
180 * nve group structures as they are defined and just compare
181 * serial numbers.
182 */
183 for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg)) {
184 if ((rfg == rfg_un) || (rfg == rfg_vn)) {
185 return rfg;
186 }
187 }
188 vnc_zlog_debug_verbose(
189 "%s: shouldn't happen, returning NULL when un and vn match",
190 __func__);
191 return NULL; /* shouldn't happen */
192 }
193
194 /*------------------------------------------
195 * rfapi_get_rfp_start_val
196 *
197 * Returns value passed to rfapi on rfp_start
198 *
199 * input:
200 * void * bgp structure
201 *
202 * returns:
203 * void *
204 *------------------------------------------*/
205 void *rfapi_get_rfp_start_val(void *bgpv)
206 {
207 struct bgp *bgp = bgpv;
208 if (bgp == NULL || bgp->rfapi == NULL)
209 return NULL;
210 return bgp->rfapi->rfp;
211 }
212
213 /*------------------------------------------
214 * bgp_rfapi_is_vnc_configured
215 *
216 * Returns if VNC is configured
217 *
218 * input:
219 * bgp NULL (=use default instance)
220 *
221 * output:
222 *
223 * return value: If VNC is configured for the bgpd instance
224 * 0 Success
225 * EPERM Not Default instance (VNC operations not allowed)
226 * ENXIO VNC not configured
227 --------------------------------------------*/
228 int bgp_rfapi_is_vnc_configured(struct bgp *bgp)
229 {
230 if (bgp == NULL)
231 bgp = bgp_get_default();
232
233 if (bgp && bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)
234 return EPERM;
235
236 if (bgp && bgp->rfapi_cfg)
237 return 0;
238 return ENXIO;
239 }
240
241 /***********************************************************************
242 * VNC Configuration/CLI
243 ***********************************************************************/
244 #define VNC_VTY_CONFIG_CHECK(bgp) \
245 { \
246 switch (bgp_rfapi_is_vnc_configured(bgp)) { \
247 case EPERM: \
248 vty_out(vty, \
249 "VNC operations only permitted on default BGP instance.\n"); \
250 return CMD_WARNING_CONFIG_FAILED; \
251 break; \
252 case ENXIO: \
253 vty_out(vty, "VNC not configured.\n"); \
254 return CMD_WARNING_CONFIG_FAILED; \
255 break; \
256 default: \
257 break; \
258 } \
259 }
260
261 DEFUN (vnc_advertise_un_method,
262 vnc_advertise_un_method_cmd,
263 "vnc advertise-un-method encap-attr",
264 VNC_CONFIG_STR
265 "Method of advertising UN addresses\n"
266 "Via Tunnel Encap attribute (in VPN SAFI)\n")
267 {
268 VTY_DECLVAR_CONTEXT(bgp, bgp);
269 VNC_VTY_CONFIG_CHECK(bgp);
270
271 if (!strncmp(argv[2]->arg, "encap-safi", 7)) {
272 bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP;
273 } else {
274 bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP;
275 }
276
277 return CMD_SUCCESS;
278 }
279
280 /*-------------------------------------------------------------------------
281 * RFG defaults
282 *-----------------------------------------------------------------------*/
283
284
285 DEFUN_NOSH (vnc_defaults,
286 vnc_defaults_cmd,
287 "vnc defaults", VNC_CONFIG_STR "Configure default NVE group\n")
288 {
289 VTY_DECLVAR_CONTEXT(bgp, bgp);
290 VNC_VTY_CONFIG_CHECK(bgp);
291 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
292 vty_out(vty, "Malformed community-list value\n");
293 return CMD_WARNING_CONFIG_FAILED;
294 }
295 vty->node = BGP_VNC_DEFAULTS_NODE;
296 return CMD_SUCCESS;
297 }
298
299 static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv,
300 struct ecommunity **list)
301 {
302 struct ecommunity *ecom = NULL;
303 struct ecommunity *ecomadd;
304
305 for (; argc; --argc, ++argv) {
306
307 ecomadd = ecommunity_str2com(argv[0]->arg,
308 ECOMMUNITY_ROUTE_TARGET, 0);
309 if (!ecomadd) {
310 vty_out(vty, "Malformed community-list value\n");
311 if (ecom)
312 ecommunity_free(&ecom);
313 return CMD_WARNING_CONFIG_FAILED;
314 }
315
316 if (ecom) {
317 ecommunity_merge(ecom, ecomadd);
318 ecommunity_free(&ecomadd);
319 } else {
320 ecom = ecomadd;
321 }
322 }
323
324 if (*list) {
325 ecommunity_free(&*list);
326 }
327 *list = ecom;
328
329 return CMD_SUCCESS;
330 }
331
332 DEFUN (vnc_defaults_rt_import,
333 vnc_defaults_rt_import_cmd,
334 "rt import RTLIST...",
335 "Specify default route targets\n"
336 "Import filter\n"
337 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
338 {
339 VTY_DECLVAR_CONTEXT(bgp, bgp);
340 return set_ecom_list(vty, argc - 2, argv + 2,
341 &bgp->rfapi_cfg->default_rt_import_list);
342 }
343
344 DEFUN (vnc_defaults_rt_export,
345 vnc_defaults_rt_export_cmd,
346 "rt export RTLIST...",
347 "Configure default route targets\n"
348 "Export filter\n"
349 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
350 {
351 VTY_DECLVAR_CONTEXT(bgp, bgp);
352 return set_ecom_list(vty, argc - 2, argv + 2,
353 &bgp->rfapi_cfg->default_rt_export_list);
354 }
355
356 DEFUN (vnc_defaults_rt_both,
357 vnc_defaults_rt_both_cmd,
358 "rt both RTLIST...",
359 "Configure default route targets\n"
360 "Export+import filters\n"
361 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
362 {
363 VTY_DECLVAR_CONTEXT(bgp, bgp);
364 int rc;
365
366 rc = set_ecom_list(vty, argc - 2, argv + 2,
367 &bgp->rfapi_cfg->default_rt_import_list);
368 if (rc != CMD_SUCCESS)
369 return rc;
370 return set_ecom_list(vty, argc - 2, argv + 2,
371 &bgp->rfapi_cfg->default_rt_export_list);
372 }
373
374 DEFUN (vnc_defaults_rd,
375 vnc_defaults_rd_cmd,
376 "rd ASN:NN_OR_IP-ADDRESS:NN",
377 "Specify default route distinguisher\n"
378 "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
379 {
380 VTY_DECLVAR_CONTEXT(bgp, bgp);
381 int ret;
382 struct prefix_rd prd;
383
384 if (!strncmp(argv[1]->arg, "auto:vn:", 8)) {
385 /*
386 * use AF_UNIX to designate automatically-assigned RD
387 * auto:vn:nn where nn is a 2-octet quantity
388 */
389 char *end = NULL;
390 uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
391 uint16_t value = value32 & 0xffff;
392
393 if (!argv[1]->arg[8] || *end) {
394 vty_out(vty, "%% Malformed rd\n");
395 return CMD_WARNING_CONFIG_FAILED;
396 }
397 if (value32 > 0xffff) {
398 vty_out(vty, "%% Malformed rd (must be less than %u\n",
399 0x0ffff);
400 return CMD_WARNING_CONFIG_FAILED;
401 }
402
403 memset(&prd, 0, sizeof(prd));
404 prd.family = AF_UNIX;
405 prd.prefixlen = 64;
406 prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
407 prd.val[1] = RD_TYPE_IP & 0x0ff;
408 prd.val[6] = (value >> 8) & 0x0ff;
409 prd.val[7] = value & 0x0ff;
410
411 } else {
412
413 /* TODO: save RD format */
414 ret = str2prefix_rd(argv[1]->arg, &prd);
415 if (!ret) {
416 vty_out(vty, "%% Malformed rd\n");
417 return CMD_WARNING_CONFIG_FAILED;
418 }
419 }
420
421 bgp->rfapi_cfg->default_rd = prd;
422 return CMD_SUCCESS;
423 }
424
425 DEFUN (vnc_defaults_l2rd,
426 vnc_defaults_l2rd_cmd,
427 "l2rd <(1-255)|auto-vn>",
428 "Specify default Local Nve ID value to use in RD for L2 routes\n"
429 "Fixed value 1-255\n"
430 "use the low-order octet of the NVE's VN address\n")
431 {
432 VTY_DECLVAR_CONTEXT(bgp, bgp);
433 uint8_t value = 0;
434
435 if (strmatch(argv[1]->text, "auto-vn")) {
436 value = 0;
437 } else {
438 char *end = NULL;
439 unsigned long value_l = strtoul(argv[1]->arg, &end, 10);
440
441 value = value_l & 0xff;
442 if (!argv[1]->arg[0] || *end) {
443 vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n",
444 argv[1]->arg);
445 return CMD_WARNING_CONFIG_FAILED;
446 }
447 if ((value_l < 1) || (value_l > 0xff)) {
448 vty_out(vty,
449 "%% Malformed l2 nve id (must be greater than 0 and less than %u\n",
450 0x100);
451 return CMD_WARNING_CONFIG_FAILED;
452 }
453 }
454 bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_L2RD;
455 bgp->rfapi_cfg->default_l2rd = value;
456
457 return CMD_SUCCESS;
458 }
459
460 DEFUN (vnc_defaults_no_l2rd,
461 vnc_defaults_no_l2rd_cmd,
462 "no l2rd",
463 NO_STR
464 "Specify default Local Nve ID value to use in RD for L2 routes\n")
465 {
466 VTY_DECLVAR_CONTEXT(bgp, bgp);
467
468 bgp->rfapi_cfg->default_l2rd = 0;
469 bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_L2RD;
470
471 return CMD_SUCCESS;
472 }
473
474 DEFUN (vnc_defaults_responselifetime,
475 vnc_defaults_responselifetime_cmd,
476 "response-lifetime <LIFETIME|infinite>",
477 "Specify default response lifetime\n"
478 "Response lifetime in seconds\n" "Infinite response lifetime\n")
479 {
480 VTY_DECLVAR_CONTEXT(bgp, bgp);
481 uint32_t rspint;
482 struct rfapi *h = NULL;
483 struct listnode *hdnode;
484 struct rfapi_descriptor *rfd;
485
486 h = bgp->rfapi;
487 if (!h)
488 return CMD_WARNING_CONFIG_FAILED;
489
490 if (strmatch(argv[1]->text, "infinite")) {
491 rspint = RFAPI_INFINITE_LIFETIME;
492 } else {
493 rspint = strtoul(argv[1]->arg, NULL, 10);
494 if (rspint > INT32_MAX)
495 rspint = INT32_MAX; /* is really an int, not an unsigned
496 int */
497 }
498
499 bgp->rfapi_cfg->default_response_lifetime = rspint;
500
501 for (ALL_LIST_ELEMENTS_RO(&h->descriptors, hdnode, rfd))
502 if (rfd->rfg
503 && !(rfd->rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME))
504 rfd->response_lifetime = rfd->rfg->response_lifetime =
505 rspint;
506
507 return CMD_SUCCESS;
508 }
509
510 struct rfapi_nve_group_cfg *
511 bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name,
512 rfapi_group_cfg_type_t type) /* _MAX = any */
513 {
514 struct rfapi_nve_group_cfg *rfg;
515 struct listnode *node, *nnode;
516
517 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, node,
518 nnode, rfg)) {
519 if ((type == RFAPI_GROUP_CFG_MAX || type == rfg->type)
520 && !strcmp(rfg->name, name))
521 return rfg;
522 }
523 return NULL;
524 }
525
526 static struct rfapi_nve_group_cfg *
527 rfapi_group_new(struct bgp *bgp, rfapi_group_cfg_type_t type, const char *name)
528 {
529 struct rfapi_nve_group_cfg *rfg;
530
531 rfg = XCALLOC(MTYPE_RFAPI_GROUP_CFG,
532 sizeof(struct rfapi_nve_group_cfg));
533 rfg->type = type;
534 rfg->name = strdup(name);
535 /* add to tail of list */
536 listnode_add(bgp->rfapi_cfg->nve_groups_sequential, rfg);
537 rfg->label = MPLS_LABEL_NONE;
538
539 QOBJ_REG(rfg, rfapi_nve_group_cfg);
540
541 return rfg;
542 }
543
544 static struct rfapi_l2_group_cfg *rfapi_l2_group_lookup_byname(struct bgp *bgp,
545 const char *name)
546 {
547 struct rfapi_l2_group_cfg *rfg;
548 struct listnode *node, *nnode;
549
550 if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */
551 bgp->rfapi_cfg->l2_groups = list_new();
552
553 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) {
554 if (!strcmp(rfg->name, name))
555 return rfg;
556 }
557 return NULL;
558 }
559
560 static struct rfapi_l2_group_cfg *rfapi_l2_group_new(void)
561 {
562 struct rfapi_l2_group_cfg *rfg;
563
564 rfg = XCALLOC(MTYPE_RFAPI_L2_CFG, sizeof(struct rfapi_l2_group_cfg));
565 QOBJ_REG(rfg, rfapi_l2_group_cfg);
566
567 return rfg;
568 }
569
570 static void rfapi_l2_group_del(struct rfapi_l2_group_cfg *rfg)
571 {
572 QOBJ_UNREG(rfg);
573 XFREE(MTYPE_RFAPI_L2_CFG, rfg);
574 }
575
576 static int rfapi_str2route_type(const char *l3str, const char *pstr, afi_t *afi,
577 int *type)
578 {
579 if (!l3str || !pstr)
580 return EINVAL;
581
582 if (!strcmp(l3str, "ipv4")) {
583 *afi = AFI_IP;
584 } else {
585 if (!strcmp(l3str, "ipv6"))
586 *afi = AFI_IP6;
587 else
588 return ENOENT;
589 }
590
591 if (!strcmp(pstr, "connected"))
592 *type = ZEBRA_ROUTE_CONNECT;
593 if (!strcmp(pstr, "kernel"))
594 *type = ZEBRA_ROUTE_KERNEL;
595 if (!strcmp(pstr, "static"))
596 *type = ZEBRA_ROUTE_STATIC;
597 if (!strcmp(pstr, "bgp"))
598 *type = ZEBRA_ROUTE_BGP;
599 if (!strcmp(pstr, "bgp-direct"))
600 *type = ZEBRA_ROUTE_BGP_DIRECT;
601 if (!strcmp(pstr, "bgp-direct-to-nve-groups"))
602 *type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
603
604 if (!strcmp(pstr, "rip")) {
605 if (*afi == AFI_IP)
606 *type = ZEBRA_ROUTE_RIP;
607 else
608 *type = ZEBRA_ROUTE_RIPNG;
609 }
610
611 if (!strcmp(pstr, "ripng")) {
612 if (*afi == AFI_IP)
613 return EAFNOSUPPORT;
614 *type = ZEBRA_ROUTE_RIPNG;
615 }
616
617 if (!strcmp(pstr, "ospf")) {
618 if (*afi == AFI_IP)
619 *type = ZEBRA_ROUTE_OSPF;
620 else
621 *type = ZEBRA_ROUTE_OSPF6;
622 }
623
624 if (!strcmp(pstr, "ospf6")) {
625 if (*afi == AFI_IP)
626 return EAFNOSUPPORT;
627 *type = ZEBRA_ROUTE_OSPF6;
628 }
629
630 return 0;
631 }
632
633 /*-------------------------------------------------------------------------
634 * redistribute
635 *-----------------------------------------------------------------------*/
636
637 #define VNC_REDIST_ENABLE(bgp, afi, type) \
638 do { \
639 switch (type) { \
640 case ZEBRA_ROUTE_BGP_DIRECT: \
641 vnc_import_bgp_redist_enable((bgp), (afi)); \
642 break; \
643 case ZEBRA_ROUTE_BGP_DIRECT_EXT: \
644 vnc_import_bgp_exterior_redist_enable((bgp), (afi)); \
645 break; \
646 default: \
647 if ((type) < ZEBRA_ROUTE_MAX) \
648 vnc_redistribute_set((bgp), (afi), (type)); \
649 break; \
650 } \
651 } while (0)
652
653 #define VNC_REDIST_DISABLE(bgp, afi, type) \
654 do { \
655 switch (type) { \
656 case ZEBRA_ROUTE_BGP_DIRECT: \
657 vnc_import_bgp_redist_disable((bgp), (afi)); \
658 break; \
659 case ZEBRA_ROUTE_BGP_DIRECT_EXT: \
660 vnc_import_bgp_exterior_redist_disable((bgp), (afi)); \
661 break; \
662 default: \
663 if ((type) < ZEBRA_ROUTE_MAX) \
664 vnc_redistribute_unset((bgp), (afi), (type)); \
665 break; \
666 } \
667 } while (0)
668
669 static uint8_t redist_was_enabled[AFI_MAX][ZEBRA_ROUTE_MAX];
670
671 static void vnc_redistribute_prechange(struct bgp *bgp)
672 {
673 afi_t afi;
674 int type;
675
676 vnc_zlog_debug_verbose("%s: entry", __func__);
677 memset(redist_was_enabled, 0, sizeof(redist_was_enabled));
678
679 /*
680 * Look to see if we have any redistribution enabled. If so, flush
681 * the corresponding routes and turn off redistribution temporarily.
682 * We need to do it because the RD's used for the redistributed
683 * routes depend on the nve group.
684 */
685 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
686 for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
687 if (bgp->rfapi_cfg->redist[afi][type]) {
688 redist_was_enabled[afi][type] = 1;
689 VNC_REDIST_DISABLE(bgp, afi, type);
690 }
691 }
692 }
693 vnc_zlog_debug_verbose("%s: return", __func__);
694 }
695
696 static void vnc_redistribute_postchange(struct bgp *bgp)
697 {
698 afi_t afi;
699 int type;
700
701 vnc_zlog_debug_verbose("%s: entry", __func__);
702 /*
703 * If we turned off redistribution above, turn it back on. Doing so
704 * will tell zebra to resend the routes to us
705 */
706 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
707 for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
708 if (redist_was_enabled[afi][type]) {
709 VNC_REDIST_ENABLE(bgp, afi, type);
710 }
711 }
712 }
713 vnc_zlog_debug_verbose("%s: return", __func__);
714 }
715
716 DEFUN (vnc_redistribute_rh_roo_localadmin,
717 vnc_redistribute_rh_roo_localadmin_cmd,
718 "vnc redistribute resolve-nve roo-ec-local-admin (0-65535)",
719 VNC_CONFIG_STR
720 "Redistribute routes into VNC\n"
721 "Resolve-NVE mode\n"
722 "Route Origin Extended Community Local Admin Field\n" "Field value\n")
723 {
724 VTY_DECLVAR_CONTEXT(bgp, bgp);
725 uint32_t localadmin;
726 char *endptr;
727
728 VNC_VTY_CONFIG_CHECK(bgp);
729
730 localadmin = strtoul(argv[4]->arg, &endptr, 0);
731 if (!argv[4]->arg[0] || *endptr) {
732 vty_out(vty, "%% Malformed value\n");
733 return CMD_WARNING_CONFIG_FAILED;
734 }
735
736 if (localadmin > 0xffff) {
737 vty_out(vty, "%% Value out of range (0-%d)\n", 0xffff);
738 return CMD_WARNING_CONFIG_FAILED;
739 }
740
741 if (bgp->rfapi_cfg->resolve_nve_roo_local_admin == localadmin)
742 return CMD_SUCCESS;
743
744 if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)
745 == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) {
746
747 vnc_export_bgp_prechange(bgp);
748 }
749 vnc_redistribute_prechange(bgp);
750
751 bgp->rfapi_cfg->resolve_nve_roo_local_admin = localadmin;
752
753 if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)
754 == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) {
755
756 vnc_export_bgp_postchange(bgp);
757 }
758 vnc_redistribute_postchange(bgp);
759
760 return CMD_SUCCESS;
761 }
762
763
764 DEFUN (vnc_redistribute_mode,
765 vnc_redistribute_mode_cmd,
766 "vnc redistribute mode <nve-group|plain|resolve-nve>",
767 VNC_CONFIG_STR
768 "Redistribute routes into VNC\n"
769 "Redistribution mode\n"
770 "Based on redistribute nve-group\n"
771 "Unmodified\n" "Resolve each nexthop to connected NVEs\n")
772 {
773 VTY_DECLVAR_CONTEXT(bgp, bgp);
774 vnc_redist_mode_t newmode;
775
776 VNC_VTY_CONFIG_CHECK(bgp);
777
778 switch (argv[3]->arg[0]) {
779 case 'n':
780 newmode = VNC_REDIST_MODE_RFG;
781 break;
782
783 case 'p':
784 newmode = VNC_REDIST_MODE_PLAIN;
785 break;
786
787 case 'r':
788 newmode = VNC_REDIST_MODE_RESOLVE_NVE;
789 break;
790
791 default:
792 vty_out(vty, "unknown redistribute mode\n");
793 return CMD_WARNING_CONFIG_FAILED;
794 }
795
796 if (newmode != bgp->rfapi_cfg->redist_mode) {
797 vnc_redistribute_prechange(bgp);
798 bgp->rfapi_cfg->redist_mode = newmode;
799 vnc_redistribute_postchange(bgp);
800 }
801
802 return CMD_SUCCESS;
803 }
804
805 DEFUN (vnc_redistribute_protocol,
806 vnc_redistribute_protocol_cmd,
807 "vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
808 VNC_CONFIG_STR
809 "Redistribute routes into VNC\n"
810 "IPv4 routes\n"
811 "IPv6 routes\n"
812 "From BGP\n"
813 "From BGP without Zebra\n"
814 "From BGP without Zebra, only to configured NVE groups\n"
815 "Connected interfaces\n"
816 "From kernel routes\n"
817 "From Open Shortest Path First (OSPF)\n"
818 "From Routing Information Protocol (RIP)\n" "From Static routes\n")
819 {
820 VTY_DECLVAR_CONTEXT(bgp, bgp);
821 int type = ZEBRA_ROUTE_MAX; /* init to bogus value */
822 afi_t afi;
823
824 VNC_VTY_CONFIG_CHECK(bgp);
825
826 if (rfapi_str2route_type(argv[2]->arg, argv[3]->arg, &afi, &type)) {
827 vty_out(vty, "%% Invalid route type\n");
828 return CMD_WARNING_CONFIG_FAILED;
829 }
830
831 if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
832 if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) {
833 VNC_REDIST_DISABLE(bgp, afi,
834 type); /* disabled view implicitly */
835 free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
836 bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL;
837 }
838 bgp->rfapi_cfg->redist_bgp_exterior_view = bgp;
839 }
840
841 VNC_REDIST_ENABLE(bgp, afi, type);
842
843 return CMD_SUCCESS;
844 }
845
846 DEFUN (vnc_no_redistribute_protocol,
847 vnc_no_redistribute_protocol_cmd,
848 "no vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
849 NO_STR
850 VNC_CONFIG_STR
851 "Redistribute from other protocol\n"
852 "IPv4 routes\n"
853 "IPv6 routes\n"
854 "From BGP\n"
855 "From BGP without Zebra\n"
856 "From BGP without Zebra, only to configured NVE groups\n"
857 "Connected interfaces\n"
858 "From kernel routes\n"
859 "From Open Shortest Path First (OSPF)\n"
860 "From Routing Information Protocol (RIP)\n" "From Static routes\n")
861 {
862 VTY_DECLVAR_CONTEXT(bgp, bgp);
863 int type;
864 afi_t afi;
865
866 VNC_VTY_CONFIG_CHECK(bgp);
867
868 if (rfapi_str2route_type(argv[3]->arg, argv[4]->arg, &afi, &type)) {
869 vty_out(vty, "%% Invalid route type\n");
870 return CMD_WARNING_CONFIG_FAILED;
871 }
872
873 VNC_REDIST_DISABLE(bgp, afi, type);
874
875 if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
876 if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) {
877 free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
878 bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL;
879 }
880 bgp->rfapi_cfg->redist_bgp_exterior_view = NULL;
881 }
882
883 return CMD_SUCCESS;
884 }
885
886 DEFUN (vnc_redistribute_bgp_exterior,
887 vnc_redistribute_bgp_exterior_cmd,
888 "vnc redistribute <ipv4|ipv6> bgp-direct-to-nve-groups view NAME",
889 VNC_CONFIG_STR
890 "Redistribute routes into VNC\n"
891 "IPv4 routes\n"
892 "IPv6 routes\n"
893 "From BGP without Zebra, only to configured NVE groups\n"
894 "From BGP view\n" "BGP view name\n")
895 {
896 VTY_DECLVAR_CONTEXT(bgp, bgp);
897 int type;
898 afi_t afi;
899
900 VNC_VTY_CONFIG_CHECK(bgp);
901
902 if (rfapi_str2route_type(argv[2]->arg, "bgp-direct-to-nve-groups", &afi,
903 &type)) {
904 vty_out(vty, "%% Invalid route type\n");
905 return CMD_WARNING_CONFIG_FAILED;
906 }
907
908 if (bgp->rfapi_cfg->redist_bgp_exterior_view_name)
909 free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
910 bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup(argv[5]->arg);
911 /* could be NULL if name is not defined yet */
912 bgp->rfapi_cfg->redist_bgp_exterior_view =
913 bgp_lookup_by_name(argv[5]->arg);
914
915 VNC_REDIST_ENABLE(bgp, afi, type);
916
917 return CMD_SUCCESS;
918 }
919
920 DEFUN (vnc_redistribute_nvegroup,
921 vnc_redistribute_nvegroup_cmd,
922 "vnc redistribute nve-group NAME",
923 VNC_CONFIG_STR
924 "Assign a NVE group to routes redistributed from another routing protocol\n"
925 "NVE group\n" "Group name\n")
926 {
927 VTY_DECLVAR_CONTEXT(bgp, bgp);
928 VNC_VTY_CONFIG_CHECK(bgp);
929
930 vnc_redistribute_prechange(bgp);
931
932 /*
933 * OK if nve group doesn't exist yet; we'll set the pointer
934 * when the group is defined later
935 */
936 bgp->rfapi_cfg->rfg_redist = bgp_rfapi_cfg_match_byname(
937 bgp, argv[3]->arg, RFAPI_GROUP_CFG_NVE);
938 if (bgp->rfapi_cfg->rfg_redist_name)
939 free(bgp->rfapi_cfg->rfg_redist_name);
940 bgp->rfapi_cfg->rfg_redist_name = strdup(argv[3]->arg);
941
942 vnc_redistribute_postchange(bgp);
943
944 return CMD_SUCCESS;
945 }
946
947 DEFUN (vnc_redistribute_no_nvegroup,
948 vnc_redistribute_no_nvegroup_cmd,
949 "no vnc redistribute nve-group",
950 NO_STR
951 VNC_CONFIG_STR
952 "Redistribute from other protocol\n"
953 "Assign a NVE group to routes redistributed from another routing protocol\n")
954 {
955 VTY_DECLVAR_CONTEXT(bgp, bgp);
956
957 VNC_VTY_CONFIG_CHECK(bgp);
958
959 vnc_redistribute_prechange(bgp);
960
961 bgp->rfapi_cfg->rfg_redist = NULL;
962 if (bgp->rfapi_cfg->rfg_redist_name)
963 free(bgp->rfapi_cfg->rfg_redist_name);
964 bgp->rfapi_cfg->rfg_redist_name = NULL;
965
966 vnc_redistribute_postchange(bgp);
967
968 return CMD_SUCCESS;
969 }
970
971
972 DEFUN (vnc_redistribute_lifetime,
973 vnc_redistribute_lifetime_cmd,
974 "vnc redistribute lifetime <LIFETIME|infinite>",
975 VNC_CONFIG_STR
976 "Redistribute\n"
977 "Assign a lifetime to routes redistributed from another routing protocol\n"
978 "lifetime value (32 bit)\n"
979 "Allow lifetime to never expire\n")
980 {
981 VTY_DECLVAR_CONTEXT(bgp, bgp);
982 VNC_VTY_CONFIG_CHECK(bgp);
983
984 vnc_redistribute_prechange(bgp);
985
986 if (strmatch(argv[3]->text, "infinite")) {
987 bgp->rfapi_cfg->redist_lifetime = RFAPI_INFINITE_LIFETIME;
988 } else {
989 bgp->rfapi_cfg->redist_lifetime =
990 strtoul(argv[3]->arg, NULL, 10);
991 }
992
993 vnc_redistribute_postchange(bgp);
994
995 return CMD_SUCCESS;
996 }
997
998 /*-- redist policy, non-nvegroup start --*/
999
1000 DEFUN (vnc_redist_bgpdirect_no_prefixlist,
1001 vnc_redist_bgpdirect_no_prefixlist_cmd,
1002 "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list",
1003 NO_STR
1004 VNC_CONFIG_STR
1005 "Redistribute from other protocol\n"
1006 "Redistribute from BGP directly\n"
1007 "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1008 "IPv4 routes\n"
1009 "IPv6 routes\n" "Prefix-list for filtering redistributed routes\n")
1010 {
1011 VTY_DECLVAR_CONTEXT(bgp, bgp);
1012 afi_t afi;
1013 struct rfapi_cfg *hc;
1014 uint8_t route_type = 0;
1015
1016 VNC_VTY_CONFIG_CHECK(bgp);
1017 hc = bgp->rfapi_cfg;
1018
1019 if (strmatch(argv[3]->text, "bgp-direct")) {
1020 route_type = ZEBRA_ROUTE_BGP_DIRECT;
1021 } else {
1022 route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
1023 }
1024
1025 if (strmatch(argv[4]->text, "ipv4")) {
1026 afi = AFI_IP;
1027 } else {
1028 afi = AFI_IP6;
1029 }
1030
1031 vnc_redistribute_prechange(bgp);
1032
1033 if (hc->plist_redist_name[route_type][afi])
1034 free(hc->plist_redist_name[route_type][afi]);
1035 hc->plist_redist_name[route_type][afi] = NULL;
1036 hc->plist_redist[route_type][afi] = NULL;
1037
1038 vnc_redistribute_postchange(bgp);
1039
1040 return CMD_SUCCESS;
1041 }
1042
1043 DEFUN (vnc_redist_bgpdirect_prefixlist,
1044 vnc_redist_bgpdirect_prefixlist_cmd,
1045 "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list NAME",
1046 VNC_CONFIG_STR
1047 "Redistribute from other protocol\n"
1048 "Redistribute from BGP directly\n"
1049 "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1050 "IPv4 routes\n"
1051 "IPv6 routes\n"
1052 "Prefix-list for filtering redistributed routes\n"
1053 "prefix list name\n")
1054 {
1055 VTY_DECLVAR_CONTEXT(bgp, bgp);
1056 struct rfapi_cfg *hc;
1057 afi_t afi;
1058 uint8_t route_type = 0;
1059
1060 VNC_VTY_CONFIG_CHECK(bgp);
1061 hc = bgp->rfapi_cfg;
1062
1063 if (strmatch(argv[2]->text, "bgp-direct")) {
1064 route_type = ZEBRA_ROUTE_BGP_DIRECT;
1065 } else {
1066 route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
1067 }
1068
1069 if (strmatch(argv[3]->text, "ipv4")) {
1070 afi = AFI_IP;
1071 } else {
1072 afi = AFI_IP6;
1073 }
1074
1075 vnc_redistribute_prechange(bgp);
1076
1077 if (hc->plist_redist_name[route_type][afi])
1078 free(hc->plist_redist_name[route_type][afi]);
1079 hc->plist_redist_name[route_type][afi] = strdup(argv[5]->arg);
1080 hc->plist_redist[route_type][afi] =
1081 prefix_list_lookup(afi, argv[5]->arg);
1082
1083 vnc_redistribute_postchange(bgp);
1084
1085 return CMD_SUCCESS;
1086 }
1087
1088 DEFUN (vnc_redist_bgpdirect_no_routemap,
1089 vnc_redist_bgpdirect_no_routemap_cmd,
1090 "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map",
1091 NO_STR
1092 VNC_CONFIG_STR
1093 "Redistribute from other protocols\n"
1094 "Redistribute from BGP directly\n"
1095 "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1096 "Route-map for filtering redistributed routes\n")
1097 {
1098 VTY_DECLVAR_CONTEXT(bgp, bgp);
1099 struct rfapi_cfg *hc;
1100 uint8_t route_type = 0;
1101
1102 VNC_VTY_CONFIG_CHECK(bgp);
1103 hc = bgp->rfapi_cfg;
1104
1105 if (strmatch(argv[3]->text, "bgp-direct")) {
1106 route_type = ZEBRA_ROUTE_BGP_DIRECT;
1107 } else {
1108 route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
1109 }
1110
1111 vnc_redistribute_prechange(bgp);
1112
1113 if (hc->routemap_redist_name[route_type])
1114 free(hc->routemap_redist_name[route_type]);
1115 hc->routemap_redist_name[route_type] = NULL;
1116 hc->routemap_redist[route_type] = NULL;
1117
1118 vnc_redistribute_postchange(bgp);
1119
1120 return CMD_SUCCESS;
1121 }
1122
1123 DEFUN (vnc_redist_bgpdirect_routemap,
1124 vnc_redist_bgpdirect_routemap_cmd,
1125 "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map NAME",
1126 VNC_CONFIG_STR
1127 "Redistribute from other protocols\n"
1128 "Redistribute from BGP directly\n"
1129 "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1130 "Route-map for filtering exported routes\n" "route map name\n")
1131 {
1132 VTY_DECLVAR_CONTEXT(bgp, bgp);
1133 struct rfapi_cfg *hc;
1134 uint8_t route_type = 0;
1135
1136 VNC_VTY_CONFIG_CHECK(bgp);
1137 hc = bgp->rfapi_cfg;
1138
1139 if (strmatch(argv[2]->text, "bgp-direct")) {
1140 route_type = ZEBRA_ROUTE_BGP_DIRECT;
1141 } else {
1142 route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
1143 }
1144
1145 vnc_redistribute_prechange(bgp);
1146
1147 if (hc->routemap_redist_name[route_type])
1148 free(hc->routemap_redist_name[route_type]);
1149
1150 /* If the old route map config overwrite with new
1151 * route map config , old routemap counter have to be
1152 * reduced.
1153 */
1154 route_map_counter_decrement(hc->routemap_redist[route_type]);
1155 hc->routemap_redist_name[route_type] = strdup(argv[4]->arg);
1156 hc->routemap_redist[route_type] =
1157 route_map_lookup_by_name(argv[4]->arg);
1158 route_map_counter_increment(hc->routemap_redist[route_type]);
1159
1160 vnc_redistribute_postchange(bgp);
1161
1162 return CMD_SUCCESS;
1163 }
1164
1165 /*-- redist policy, non-nvegroup end --*/
1166
1167 /*-- redist policy, nvegroup start --*/
1168
1169 DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist,
1170 vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd,
1171 "no redistribute bgp-direct <ipv4|ipv6> prefix-list",
1172 NO_STR
1173 "Redistribute from other protocol\n"
1174 "Redistribute from BGP directly\n"
1175 "IPv4 routes\n"
1176 "IPv6 routes\n"
1177 "Prefix-list for filtering redistributed routes\n")
1178 {
1179 VTY_DECLVAR_CONTEXT(bgp, bgp);
1180 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg)
1181 afi_t afi;
1182
1183 VNC_VTY_CONFIG_CHECK(bgp);
1184
1185 /* make sure it's still in list */
1186 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1187 /* Not in list anymore */
1188 vty_out(vty, "Current NVE group no longer exists\n");
1189 return CMD_WARNING_CONFIG_FAILED;
1190 }
1191
1192 if (strmatch(argv[3]->text, "ipv4")) {
1193 afi = AFI_IP;
1194 } else {
1195 afi = AFI_IP6;
1196 }
1197
1198 vnc_redistribute_prechange(bgp);
1199
1200 if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi])
1201 free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]);
1202 rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL;
1203 rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL;
1204
1205 vnc_redistribute_postchange(bgp);
1206
1207 return CMD_SUCCESS;
1208 }
1209
1210 DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist,
1211 vnc_nve_group_redist_bgpdirect_prefixlist_cmd,
1212 "redistribute bgp-direct <ipv4|ipv6> prefix-list NAME",
1213 "Redistribute from other protocol\n"
1214 "Redistribute from BGP directly\n"
1215 "IPv4 routes\n"
1216 "IPv6 routes\n"
1217 "Prefix-list for filtering redistributed routes\n"
1218 "prefix list name\n")
1219 {
1220 VTY_DECLVAR_CONTEXT(bgp, bgp);
1221 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1222 afi_t afi;
1223
1224 VNC_VTY_CONFIG_CHECK(bgp);
1225
1226 /* make sure it's still in list */
1227 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1228 /* Not in list anymore */
1229 vty_out(vty, "Current NVE group no longer exists\n");
1230 return CMD_WARNING_CONFIG_FAILED;
1231 }
1232
1233 if (strmatch(argv[2]->text, "ipv4")) {
1234 afi = AFI_IP;
1235 } else {
1236 afi = AFI_IP6;
1237 }
1238
1239 vnc_redistribute_prechange(bgp);
1240
1241 if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi])
1242 free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]);
1243 rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] =
1244 strdup(argv[4]->arg);
1245 rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] =
1246 prefix_list_lookup(afi, argv[4]->arg);
1247
1248 vnc_redistribute_postchange(bgp);
1249
1250 return CMD_SUCCESS;
1251 }
1252
1253 DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap,
1254 vnc_nve_group_redist_bgpdirect_no_routemap_cmd,
1255 "no redistribute bgp-direct route-map",
1256 NO_STR
1257 "Redistribute from other protocols\n"
1258 "Redistribute from BGP directly\n"
1259 "Route-map for filtering redistributed routes\n")
1260 {
1261 VTY_DECLVAR_CONTEXT(bgp, bgp);
1262 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1263
1264 VNC_VTY_CONFIG_CHECK(bgp);
1265
1266 /* make sure it's still in list */
1267 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1268 /* Not in list anymore */
1269 vty_out(vty, "Current NVE group no longer exists\n");
1270 return CMD_WARNING_CONFIG_FAILED;
1271 }
1272
1273 vnc_redistribute_prechange(bgp);
1274
1275 if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT])
1276 free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
1277 route_map_counter_decrement(
1278 rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
1279 rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = NULL;
1280 rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = NULL;
1281
1282 vnc_redistribute_postchange(bgp);
1283
1284 return CMD_SUCCESS;
1285 }
1286
1287 DEFUN (vnc_nve_group_redist_bgpdirect_routemap,
1288 vnc_nve_group_redist_bgpdirect_routemap_cmd,
1289 "redistribute bgp-direct route-map NAME",
1290 "Redistribute from other protocols\n"
1291 "Redistribute from BGP directly\n"
1292 "Route-map for filtering exported routes\n" "route map name\n")
1293 {
1294 VTY_DECLVAR_CONTEXT(bgp, bgp);
1295 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1296
1297 VNC_VTY_CONFIG_CHECK(bgp);
1298
1299 /* make sure it's still in list */
1300 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1301 /* Not in list anymore */
1302 vty_out(vty, "Current NVE group no longer exists\n");
1303 return CMD_WARNING_CONFIG_FAILED;
1304 }
1305
1306 vnc_redistribute_prechange(bgp);
1307
1308 if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT])
1309 free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
1310 route_map_counter_decrement(
1311 rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
1312 rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] =
1313 strdup(argv[3]->arg);
1314 rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] =
1315 route_map_lookup_by_name(argv[3]->arg);
1316 route_map_counter_increment(
1317 rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
1318
1319 vnc_redistribute_postchange(bgp);
1320
1321 return CMD_SUCCESS;
1322 }
1323
1324 /*-- redist policy, nvegroup end --*/
1325
1326 /*-------------------------------------------------------------------------
1327 * export
1328 *-----------------------------------------------------------------------*/
1329
1330 DEFUN (vnc_export_mode,
1331 vnc_export_mode_cmd,
1332 "vnc export <bgp|zebra> mode <group-nve|ce|none|registering-nve>",
1333 VNC_CONFIG_STR
1334 "Export to other protocols\n"
1335 "Export to BGP\n"
1336 "Export to Zebra (experimental)\n"
1337 "Select export mode\n"
1338 "Export routes with nve-group next-hops\n"
1339 "Export routes with NVE connected router next-hops\n"
1340 "Disable export\n" "Export routes with registering NVE as next-hop\n")
1341 {
1342 VTY_DECLVAR_CONTEXT(bgp, bgp);
1343 uint32_t oldmode = 0;
1344 uint32_t newmode = 0;
1345
1346 VNC_VTY_CONFIG_CHECK(bgp);
1347
1348 if (argv[2]->arg[0] == 'b') {
1349 oldmode = bgp->rfapi_cfg->flags
1350 & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS;
1351 switch (argv[4]->arg[0]) {
1352 case 'g':
1353 newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP;
1354 break;
1355 case 'c':
1356 newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE;
1357 break;
1358 case 'n':
1359 newmode = 0;
1360 break;
1361 case 'r':
1362 newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH;
1363 break;
1364 default:
1365 vty_out(vty, "Invalid mode specified\n");
1366 return CMD_WARNING_CONFIG_FAILED;
1367 }
1368
1369 if (newmode == oldmode) {
1370 vty_out(vty, "Mode unchanged\n");
1371 return CMD_SUCCESS;
1372 }
1373
1374 vnc_export_bgp_prechange(bgp);
1375
1376 bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS;
1377 bgp->rfapi_cfg->flags |= newmode;
1378
1379 vnc_export_bgp_postchange(bgp);
1380
1381
1382 } else {
1383 /*
1384 * export to zebra with RH mode is not yet implemented
1385 */
1386 vty_out(vty,
1387 "Changing modes for zebra export not implemented yet\n");
1388 return CMD_WARNING_CONFIG_FAILED;
1389 }
1390
1391 return CMD_SUCCESS;
1392 }
1393
1394 static struct rfapi_rfg_name *rfgn_new(void)
1395 {
1396 return XCALLOC(MTYPE_RFAPI_RFG_NAME, sizeof(struct rfapi_rfg_name));
1397 }
1398
1399 static void rfgn_free(struct rfapi_rfg_name *rfgn)
1400 {
1401 XFREE(MTYPE_RFAPI_RFG_NAME, rfgn);
1402 }
1403
1404 DEFUN (vnc_export_nvegroup,
1405 vnc_export_nvegroup_cmd,
1406 "vnc export <bgp|zebra> group-nve group NAME",
1407 VNC_CONFIG_STR
1408 "Export to other protocols\n"
1409 "Export to BGP\n"
1410 "Export to Zebra (experimental)\n"
1411 "NVE group, used in 'group-nve' export mode\n"
1412 "NVE group\n" "Group name\n")
1413 {
1414 VTY_DECLVAR_CONTEXT(bgp, bgp);
1415 struct rfapi_nve_group_cfg *rfg_new;
1416
1417 VNC_VTY_CONFIG_CHECK(bgp);
1418
1419 rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg,
1420 RFAPI_GROUP_CFG_NVE);
1421 if (rfg_new == NULL) {
1422 rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg,
1423 RFAPI_GROUP_CFG_VRF);
1424 if (rfg_new)
1425 vnc_add_vrf_opener(bgp, rfg_new);
1426 }
1427
1428 if (rfg_new == NULL) {
1429 vty_out(vty, "Can't find group named \"%s\".\n", argv[5]->arg);
1430 return CMD_WARNING_CONFIG_FAILED;
1431 }
1432
1433 if (argv[2]->arg[0] == 'b') {
1434
1435 struct listnode *node;
1436 struct rfapi_rfg_name *rfgn;
1437
1438 /*
1439 * Set group for export to BGP Direct
1440 */
1441
1442 /* see if group is already included in export list */
1443 for (ALL_LIST_ELEMENTS_RO(
1444 bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
1445 rfgn)) {
1446
1447 if (!strcmp(rfgn->name, argv[5]->arg)) {
1448 /* already in the list: we're done */
1449 return CMD_SUCCESS;
1450 }
1451 }
1452
1453 rfgn = rfgn_new();
1454 rfgn->name = strdup(argv[5]->arg);
1455 rfgn->rfg = rfg_new; /* OK if not set yet */
1456
1457 listnode_add(bgp->rfapi_cfg->rfg_export_direct_bgp_l, rfgn);
1458
1459 vnc_zlog_debug_verbose("%s: testing rfg_new", __func__);
1460 if (rfg_new) {
1461 vnc_zlog_debug_verbose(
1462 "%s: testing bgp grp mode enabled", __func__);
1463 if (VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg))
1464 vnc_zlog_debug_verbose(
1465 "%s: calling vnc_direct_bgp_add_group",
1466 __func__);
1467 vnc_direct_bgp_add_group(bgp, rfg_new);
1468 }
1469
1470 } else {
1471
1472 struct listnode *node;
1473 struct rfapi_rfg_name *rfgn;
1474
1475 /*
1476 * Set group for export to Zebra
1477 */
1478
1479 /* see if group is already included in export list */
1480 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l,
1481 node, rfgn)) {
1482
1483 if (!strcmp(rfgn->name, argv[5]->arg)) {
1484 /* already in the list: we're done */
1485 return CMD_SUCCESS;
1486 }
1487 }
1488
1489 rfgn = rfgn_new();
1490 rfgn->name = strdup(argv[5]->arg);
1491 rfgn->rfg = rfg_new; /* OK if not set yet */
1492
1493 listnode_add(bgp->rfapi_cfg->rfg_export_zebra_l, rfgn);
1494
1495 if (rfg_new) {
1496 if (VNC_EXPORT_ZEBRA_GRP_ENABLED(bgp->rfapi_cfg))
1497 vnc_zebra_add_group(bgp, rfg_new);
1498 }
1499 }
1500
1501 return CMD_SUCCESS;
1502 }
1503
1504 /*
1505 * This command applies to routes exported from VNC to BGP directly
1506 * without going though zebra
1507 */
1508 DEFUN (vnc_no_export_nvegroup,
1509 vnc_no_export_nvegroup_cmd,
1510 "vnc export <bgp|zebra> group-nve no group NAME",
1511 VNC_CONFIG_STR
1512 "Export to other protocols\n"
1513 "Export to BGP\n"
1514 "Export to Zebra (experimental)\n"
1515 "NVE group, used in 'group-nve' export mode\n"
1516 "Disable export of VNC routes\n" "NVE group\n" "Group name\n")
1517 {
1518 VTY_DECLVAR_CONTEXT(bgp, bgp);
1519 struct listnode *node, *nnode;
1520 struct rfapi_rfg_name *rfgn;
1521
1522 VNC_VTY_CONFIG_CHECK(bgp);
1523
1524 if (argv[2]->arg[0] == 'b') {
1525 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l,
1526 node, nnode, rfgn)) {
1527
1528 if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) {
1529 vnc_zlog_debug_verbose("%s: matched \"%s\"",
1530 __func__, rfgn->name);
1531 if (rfgn->rfg)
1532 vnc_direct_bgp_del_group(bgp,
1533 rfgn->rfg);
1534 free(rfgn->name);
1535 list_delete_node(
1536 bgp->rfapi_cfg->rfg_export_direct_bgp_l,
1537 node);
1538 rfgn_free(rfgn);
1539 break;
1540 }
1541 }
1542 } else {
1543 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node,
1544 nnode, rfgn)) {
1545
1546 vnc_zlog_debug_verbose("does rfg \"%s\" match?",
1547 rfgn->name);
1548 if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) {
1549 if (rfgn->rfg)
1550 vnc_zebra_del_group(bgp, rfgn->rfg);
1551 free(rfgn->name);
1552 list_delete_node(
1553 bgp->rfapi_cfg->rfg_export_zebra_l,
1554 node);
1555 rfgn_free(rfgn);
1556 break;
1557 }
1558 }
1559 }
1560 return CMD_SUCCESS;
1561 }
1562
1563 DEFUN (vnc_nve_group_export_no_prefixlist,
1564 vnc_nve_group_export_no_prefixlist_cmd,
1565 "no export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
1566 NO_STR
1567 "Export to other protocols\n"
1568 "Export to BGP\n"
1569 "Export to Zebra (experimental)\n"
1570 "IPv4 routes\n"
1571 "IPv6 routes\n"
1572 "Prefix-list for filtering exported routes\n" "prefix list name\n")
1573 {
1574 VTY_DECLVAR_CONTEXT(bgp, bgp);
1575 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1576 int idx = 0;
1577 int is_bgp = 1;
1578 afi_t afi;
1579
1580 VNC_VTY_CONFIG_CHECK(bgp);
1581
1582 /* make sure it's still in list */
1583 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1584 /* Not in list anymore */
1585 vty_out(vty, "Current NVE group no longer exists\n");
1586 return CMD_WARNING_CONFIG_FAILED;
1587 }
1588
1589 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
1590 vty_out(vty, "%% Malformed Address Family\n");
1591 return CMD_WARNING_CONFIG_FAILED;
1592 }
1593
1594 if (argv[idx - 1]->text[0] == 'z')
1595 is_bgp = 0;
1596 idx += 2; /* skip afi and keyword */
1597
1598 if (is_bgp) {
1599 if (idx == argc
1600 || (rfg->plist_export_bgp_name[afi]
1601 && strmatch(argv[idx]->arg,
1602 rfg->plist_export_bgp_name[afi]))) {
1603 if (rfg->plist_export_bgp_name[afi])
1604 free(rfg->plist_export_bgp_name[afi]);
1605 rfg->plist_export_bgp_name[afi] = NULL;
1606 rfg->plist_export_bgp[afi] = NULL;
1607
1608 vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
1609 }
1610 } else {
1611 if (idx == argc
1612 || (rfg->plist_export_zebra_name[afi]
1613 && strmatch(argv[idx]->arg,
1614 rfg->plist_export_zebra_name[afi]))) {
1615 if (rfg->plist_export_zebra_name[afi])
1616 free(rfg->plist_export_zebra_name[afi]);
1617 rfg->plist_export_zebra_name[afi] = NULL;
1618 rfg->plist_export_zebra[afi] = NULL;
1619
1620 vnc_zebra_reexport_group_afi(bgp, rfg, afi);
1621 }
1622 }
1623 return CMD_SUCCESS;
1624 }
1625
1626 ALIAS (vnc_nve_group_export_no_prefixlist,
1627 vnc_vrf_policy_export_no_prefixlist_cmd,
1628 "no export <ipv4|ipv6> prefix-list [NAME]",
1629 NO_STR
1630 "Export to VRF\n"
1631 "IPv4 routes\n"
1632 "IPv6 routes\n"
1633 "Prefix-list for filtering exported routes\n" "prefix list name\n")
1634
1635 DEFUN (vnc_nve_group_export_prefixlist,
1636 vnc_nve_group_export_prefixlist_cmd,
1637 "export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
1638 "Export to other protocols\n"
1639 "Export to BGP\n"
1640 "Export to Zebra (experimental)\n"
1641 "IPv4 routes\n"
1642 "IPv6 routes\n"
1643 "Prefix-list for filtering exported routes\n" "prefix list name\n")
1644 {
1645 VTY_DECLVAR_CONTEXT(bgp, bgp);
1646 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1647 int idx = 0;
1648 int is_bgp = 1;
1649 afi_t afi;
1650
1651 VNC_VTY_CONFIG_CHECK(bgp);
1652
1653 /* make sure it's still in list */
1654 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1655 /* Not in list anymore */
1656 vty_out(vty, "Current NVE group no longer exists\n");
1657 return CMD_WARNING_CONFIG_FAILED;
1658 }
1659
1660 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
1661 vty_out(vty, "%% Malformed Address Family\n");
1662 return CMD_WARNING_CONFIG_FAILED;
1663 }
1664
1665 if (argv[idx - 1]->text[0] == 'z')
1666 is_bgp = 0;
1667 idx = argc - 1;
1668
1669 if (is_bgp) {
1670 if (rfg->plist_export_bgp_name[afi])
1671 free(rfg->plist_export_bgp_name[afi]);
1672 rfg->plist_export_bgp_name[afi] = strdup(argv[idx]->arg);
1673 rfg->plist_export_bgp[afi] =
1674 prefix_list_lookup(afi, argv[idx]->arg);
1675
1676 vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
1677
1678 } else {
1679 if (rfg->plist_export_zebra_name[afi])
1680 free(rfg->plist_export_zebra_name[afi]);
1681 rfg->plist_export_zebra_name[afi] = strdup(argv[idx]->arg);
1682 rfg->plist_export_zebra[afi] =
1683 prefix_list_lookup(afi, argv[idx]->arg);
1684
1685 vnc_zebra_reexport_group_afi(bgp, rfg, afi);
1686 }
1687 return CMD_SUCCESS;
1688 }
1689
1690 ALIAS (vnc_nve_group_export_prefixlist,
1691 vnc_vrf_policy_export_prefixlist_cmd,
1692 "export <ipv4|ipv6> prefix-list NAME",
1693 "Export to VRF\n"
1694 "IPv4 routes\n"
1695 "IPv6 routes\n"
1696 "Prefix-list for filtering exported routes\n" "prefix list name\n")
1697
1698 DEFUN (vnc_nve_group_export_no_routemap,
1699 vnc_nve_group_export_no_routemap_cmd,
1700 "no export <bgp|zebra> route-map [NAME]",
1701 NO_STR
1702 "Export to other protocols\n"
1703 "Export to BGP\n"
1704 "Export to Zebra (experimental)\n"
1705 "Route-map for filtering exported routes\n" "route map name\n")
1706 {
1707 VTY_DECLVAR_CONTEXT(bgp, bgp);
1708 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1709 int idx = 2;
1710 int is_bgp = 1;
1711
1712 VNC_VTY_CONFIG_CHECK(bgp);
1713
1714 /* make sure it's still in list */
1715 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1716 /* Not in list anymore */
1717 vty_out(vty, "Current NVE group no longer exists\n");
1718 return CMD_WARNING_CONFIG_FAILED;
1719 }
1720 switch (argv[idx]->text[0]) {
1721 case 'z':
1722 is_bgp = 0;
1723 /* fall thru */
1724 case 'b':
1725 idx += 2;
1726 break;
1727 default: /* route-map */
1728 idx++;
1729 break;
1730 }
1731
1732 if (is_bgp) {
1733 if (idx == argc
1734 || (rfg->routemap_export_bgp_name
1735 && strmatch(argv[idx]->arg,
1736 rfg->routemap_export_bgp_name))) {
1737 if (rfg->routemap_export_bgp_name)
1738 free(rfg->routemap_export_bgp_name);
1739 route_map_counter_decrement(rfg->routemap_export_bgp);
1740 rfg->routemap_export_bgp_name = NULL;
1741 rfg->routemap_export_bgp = NULL;
1742
1743 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
1744 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
1745 }
1746 } else {
1747 if (idx == argc
1748 || (rfg->routemap_export_zebra_name
1749 && strmatch(argv[idx]->arg,
1750 rfg->routemap_export_zebra_name))) {
1751 if (rfg->routemap_export_zebra_name)
1752 free(rfg->routemap_export_zebra_name);
1753 route_map_counter_decrement(rfg->routemap_export_zebra);
1754 rfg->routemap_export_zebra_name = NULL;
1755 rfg->routemap_export_zebra = NULL;
1756
1757 vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP);
1758 vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6);
1759 }
1760 }
1761 return CMD_SUCCESS;
1762 }
1763
1764 ALIAS (vnc_nve_group_export_no_routemap,
1765 vnc_vrf_policy_export_no_routemap_cmd,
1766 "no export route-map [NAME]",
1767 NO_STR
1768 "Export to VRF\n"
1769 "Route-map for filtering exported routes\n" "route map name\n")
1770
1771 DEFUN (vnc_nve_group_export_routemap,
1772 vnc_nve_group_export_routemap_cmd,
1773 "export <bgp|zebra> route-map NAME",
1774 "Export to other protocols\n"
1775 "Export to BGP\n"
1776 "Export to Zebra (experimental)\n"
1777 "Route-map for filtering exported routes\n" "route map name\n")
1778 {
1779 VTY_DECLVAR_CONTEXT(bgp, bgp);
1780 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
1781 int idx = 0;
1782 int is_bgp = 1;
1783
1784 VNC_VTY_CONFIG_CHECK(bgp);
1785
1786 /* make sure it's still in list */
1787 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
1788 /* Not in list anymore */
1789 vty_out(vty, "Current NVE group no longer exists\n");
1790 return CMD_WARNING_CONFIG_FAILED;
1791 }
1792
1793 if (argv[1]->text[0] == 'z')
1794 is_bgp = 0;
1795 idx = argc - 1;
1796
1797 if (is_bgp) {
1798 if (rfg->routemap_export_bgp_name)
1799 free(rfg->routemap_export_bgp_name);
1800 route_map_counter_decrement(rfg->routemap_export_bgp);
1801 rfg->routemap_export_bgp_name = strdup(argv[idx]->arg);
1802 rfg->routemap_export_bgp =
1803 route_map_lookup_by_name(argv[idx]->arg);
1804 route_map_counter_increment(rfg->routemap_export_bgp);
1805 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
1806 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
1807 } else {
1808 if (rfg->routemap_export_zebra_name)
1809 free(rfg->routemap_export_zebra_name);
1810 route_map_counter_decrement(rfg->routemap_export_zebra);
1811 rfg->routemap_export_zebra_name = strdup(argv[idx]->arg);
1812 rfg->routemap_export_zebra =
1813 route_map_lookup_by_name(argv[idx]->arg);
1814 route_map_counter_increment(rfg->routemap_export_zebra);
1815 vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP);
1816 vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6);
1817 }
1818 return CMD_SUCCESS;
1819 }
1820
1821 ALIAS (vnc_nve_group_export_routemap,
1822 vnc_vrf_policy_export_routemap_cmd,
1823 "export route-map NAME",
1824 "Export to VRF\n"
1825 "Route-map for filtering exported routes\n" "route map name\n")
1826
1827 DEFUN (vnc_nve_export_no_prefixlist,
1828 vnc_nve_export_no_prefixlist_cmd,
1829 "no vnc export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
1830 NO_STR
1831 VNC_CONFIG_STR
1832 "Export to other protocols\n"
1833 "Export to BGP\n"
1834 "Export to Zebra (experimental)\n"
1835 "IPv4 prefixes\n"
1836 "IPv6 prefixes\n"
1837 "Prefix-list for filtering exported routes\n" "Prefix list name\n")
1838 {
1839 VTY_DECLVAR_CONTEXT(bgp, bgp);
1840 struct rfapi_cfg *hc;
1841 afi_t afi;
1842
1843 VNC_VTY_CONFIG_CHECK(bgp);
1844 hc = bgp->rfapi_cfg;
1845
1846 if (strmatch(argv[4]->text, "ipv4")) {
1847 afi = AFI_IP;
1848 } else {
1849 afi = AFI_IP6;
1850 }
1851
1852 if (argv[3]->arg[0] == 'b') {
1853 if (((argc > 6) && hc->plist_export_bgp_name[afi]
1854 && strmatch(argv[6]->text, hc->plist_export_bgp_name[afi]))
1855 || (argc <= 6)) {
1856
1857 free(hc->plist_export_bgp_name[afi]);
1858 hc->plist_export_bgp_name[afi] = NULL;
1859 hc->plist_export_bgp[afi] = NULL;
1860 vnc_direct_bgp_reexport(bgp, afi);
1861 }
1862 } else {
1863 if (((argc > 6) && hc->plist_export_zebra_name[afi]
1864 && strmatch(argv[6]->text,
1865 hc->plist_export_zebra_name[afi]))
1866 || (argc <= 6)) {
1867
1868 free(hc->plist_export_zebra_name[afi]);
1869 hc->plist_export_zebra_name[afi] = NULL;
1870 hc->plist_export_zebra[afi] = NULL;
1871 /* TBD vnc_zebra_rh_reexport(bgp, afi); */
1872 }
1873 }
1874 return CMD_SUCCESS;
1875 }
1876
1877 DEFUN (vnc_nve_export_prefixlist,
1878 vnc_nve_export_prefixlist_cmd,
1879 "vnc export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
1880 VNC_CONFIG_STR
1881 "Export to other protocols\n"
1882 "Export to BGP\n"
1883 "Export to Zebra (experimental)\n"
1884 "IPv4 prefixes\n"
1885 "IPv6 prefixes\n"
1886 "Prefix-list for filtering exported routes\n" "Prefix list name\n")
1887 {
1888 VTY_DECLVAR_CONTEXT(bgp, bgp);
1889 struct rfapi_cfg *hc;
1890 afi_t afi;
1891
1892 VNC_VTY_CONFIG_CHECK(bgp);
1893 hc = bgp->rfapi_cfg;
1894
1895 if (strmatch(argv[3]->text, "ipv4")) {
1896 afi = AFI_IP;
1897 } else {
1898 afi = AFI_IP6;
1899 }
1900
1901 if (argv[2]->arg[0] == 'b') {
1902 if (hc->plist_export_bgp_name[afi])
1903 free(hc->plist_export_bgp_name[afi]);
1904 hc->plist_export_bgp_name[afi] = strdup(argv[5]->arg);
1905 hc->plist_export_bgp[afi] =
1906 prefix_list_lookup(afi, argv[5]->arg);
1907 vnc_direct_bgp_reexport(bgp, afi);
1908 } else {
1909 if (hc->plist_export_zebra_name[afi])
1910 free(hc->plist_export_zebra_name[afi]);
1911 hc->plist_export_zebra_name[afi] = strdup(argv[5]->arg);
1912 hc->plist_export_zebra[afi] =
1913 prefix_list_lookup(afi, argv[5]->arg);
1914 /* TBD vnc_zebra_rh_reexport(bgp, afi); */
1915 }
1916 return CMD_SUCCESS;
1917 }
1918
1919 DEFUN (vnc_nve_export_no_routemap,
1920 vnc_nve_export_no_routemap_cmd,
1921 "no vnc export <bgp|zebra> route-map [NAME]",
1922 NO_STR
1923 VNC_CONFIG_STR
1924 "Export to other protocols\n"
1925 "Export to BGP\n"
1926 "Export to Zebra (experimental)\n"
1927 "Route-map for filtering exported routes\n" "Route map name\n")
1928 {
1929 VTY_DECLVAR_CONTEXT(bgp, bgp);
1930 struct rfapi_cfg *hc;
1931
1932 VNC_VTY_CONFIG_CHECK(bgp);
1933 hc = bgp->rfapi_cfg;
1934
1935 if (argv[3]->arg[0] == 'b') {
1936 if (((argc > 5) && hc->routemap_export_bgp_name
1937 && strmatch(argv[5]->text, hc->routemap_export_bgp_name))
1938 || (argc <= 5)) {
1939
1940 free(hc->routemap_export_bgp_name);
1941 route_map_counter_decrement(hc->routemap_export_bgp);
1942 hc->routemap_export_bgp_name = NULL;
1943 hc->routemap_export_bgp = NULL;
1944 vnc_direct_bgp_reexport(bgp, AFI_IP);
1945 vnc_direct_bgp_reexport(bgp, AFI_IP6);
1946 }
1947 } else {
1948 if (((argc > 5) && hc->routemap_export_zebra_name
1949 && strmatch(argv[5]->text, hc->routemap_export_zebra_name))
1950 || (argc <= 5)) {
1951
1952 free(hc->routemap_export_zebra_name);
1953 route_map_counter_decrement(hc->routemap_export_zebra);
1954 hc->routemap_export_zebra_name = NULL;
1955 hc->routemap_export_zebra = NULL;
1956 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
1957 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
1958 }
1959 }
1960 return CMD_SUCCESS;
1961 }
1962
1963 DEFUN (vnc_nve_export_routemap,
1964 vnc_nve_export_routemap_cmd,
1965 "vnc export <bgp|zebra> route-map NAME",
1966 VNC_CONFIG_STR
1967 "Export to other protocols\n"
1968 "Export to BGP\n"
1969 "Export to Zebra (experimental)\n"
1970 "Route-map for filtering exported routes\n" "Route map name\n")
1971 {
1972 VTY_DECLVAR_CONTEXT(bgp, bgp);
1973 struct rfapi_cfg *hc;
1974
1975 VNC_VTY_CONFIG_CHECK(bgp);
1976 hc = bgp->rfapi_cfg;
1977
1978 if (argv[2]->arg[0] == 'b') {
1979 if (hc->routemap_export_bgp_name)
1980 free(hc->routemap_export_bgp_name);
1981 route_map_counter_decrement(hc->routemap_export_bgp);
1982 hc->routemap_export_bgp_name = strdup(argv[4]->arg);
1983 hc->routemap_export_bgp =
1984 route_map_lookup_by_name(argv[4]->arg);
1985 route_map_counter_increment(hc->routemap_export_bgp);
1986 vnc_direct_bgp_reexport(bgp, AFI_IP);
1987 vnc_direct_bgp_reexport(bgp, AFI_IP6);
1988 } else {
1989 if (hc->routemap_export_zebra_name)
1990 free(hc->routemap_export_zebra_name);
1991 route_map_counter_decrement(hc->routemap_export_zebra);
1992 hc->routemap_export_zebra_name = strdup(argv[4]->arg);
1993 hc->routemap_export_zebra =
1994 route_map_lookup_by_name(argv[4]->arg);
1995 route_map_counter_increment(hc->routemap_export_zebra);
1996 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
1997 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
1998 }
1999 return CMD_SUCCESS;
2000 }
2001
2002
2003 /*
2004 * respond to changes in the global prefix list configuration
2005 */
2006 void vnc_prefix_list_update(struct bgp *bgp)
2007 {
2008 afi_t afi;
2009 struct listnode *n;
2010 struct rfapi_nve_group_cfg *rfg;
2011 struct rfapi_cfg *hc;
2012 int i;
2013
2014 if (!bgp) {
2015 vnc_zlog_debug_verbose("%s: No BGP process is configured",
2016 __func__);
2017 return;
2018 }
2019
2020 if (!(hc = bgp->rfapi_cfg)) {
2021 vnc_zlog_debug_verbose("%s: rfapi not configured", __func__);
2022 return;
2023 }
2024
2025 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2026 /*
2027 * Loop over nve groups
2028 */
2029 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential,
2030 n, rfg)) {
2031
2032 if (rfg->plist_export_bgp_name[afi]) {
2033 rfg->plist_export_bgp[afi] = prefix_list_lookup(
2034 afi, rfg->plist_export_bgp_name[afi]);
2035 }
2036 if (rfg->plist_export_zebra_name[afi]) {
2037 rfg->plist_export_zebra
2038 [afi] = prefix_list_lookup(
2039 afi, rfg->plist_export_zebra_name[afi]);
2040 }
2041 for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
2042 if (rfg->plist_redist_name[i][afi]) {
2043 rfg->plist_redist
2044 [i][afi] = prefix_list_lookup(
2045 afi,
2046 rfg->plist_redist_name[i][afi]);
2047 }
2048 }
2049
2050 vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
2051 /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */
2052 }
2053
2054 /*
2055 * RH config, too
2056 */
2057 if (hc->plist_export_bgp_name[afi]) {
2058 hc->plist_export_bgp[afi] = prefix_list_lookup(
2059 afi, hc->plist_export_bgp_name[afi]);
2060 }
2061 if (hc->plist_export_zebra_name[afi]) {
2062 hc->plist_export_zebra[afi] = prefix_list_lookup(
2063 afi, hc->plist_export_zebra_name[afi]);
2064 }
2065
2066 for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
2067 if (hc->plist_redist_name[i][afi]) {
2068 hc->plist_redist[i][afi] = prefix_list_lookup(
2069 afi, hc->plist_redist_name[i][afi]);
2070 }
2071 }
2072 }
2073
2074 vnc_direct_bgp_reexport(bgp, AFI_IP);
2075 vnc_direct_bgp_reexport(bgp, AFI_IP6);
2076
2077 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
2078 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
2079
2080 vnc_redistribute_prechange(bgp);
2081 vnc_redistribute_postchange(bgp);
2082 }
2083
2084 /*
2085 * respond to changes in the global route map configuration
2086 */
2087 void vnc_routemap_update(struct bgp *bgp, const char *unused)
2088 {
2089 struct listnode *n;
2090 struct rfapi_nve_group_cfg *rfg;
2091 struct rfapi_cfg *hc;
2092 int i;
2093 struct route_map *old = NULL;
2094
2095 vnc_zlog_debug_verbose("%s(arg=%s)", __func__, unused);
2096
2097 if (!bgp) {
2098 vnc_zlog_debug_verbose("%s: No BGP process is configured",
2099 __func__);
2100 return;
2101 }
2102
2103 if (!(hc = bgp->rfapi_cfg)) {
2104 vnc_zlog_debug_verbose("%s: rfapi not configured", __func__);
2105 return;
2106 }
2107
2108 /*
2109 * Loop over nve groups
2110 */
2111 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, n,
2112 rfg)) {
2113
2114 if (rfg->routemap_export_bgp_name) {
2115 old = rfg->routemap_export_bgp;
2116 rfg->routemap_export_bgp = route_map_lookup_by_name(
2117 rfg->routemap_export_bgp_name);
2118 /* old is NULL. i.e Route map creation event.
2119 * So update applied_counter.
2120 * If Old is not NULL, i.e It may be routemap
2121 * updation or deletion.
2122 * So no need to update the counter.
2123 */
2124 if (!old)
2125 route_map_counter_increment(
2126 rfg->routemap_export_bgp);
2127 }
2128 if (rfg->routemap_export_zebra_name) {
2129 old = rfg->routemap_export_bgp;
2130 rfg->routemap_export_bgp = route_map_lookup_by_name(
2131 rfg->routemap_export_zebra_name);
2132 if (!old)
2133 route_map_counter_increment(
2134 rfg->routemap_export_bgp);
2135 }
2136 for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
2137 if (rfg->routemap_redist_name[i]) {
2138 old = rfg->routemap_redist[i];
2139 rfg->routemap_redist[i] =
2140 route_map_lookup_by_name(
2141 rfg->routemap_redist_name[i]);
2142 if (!old)
2143 route_map_counter_increment(
2144 rfg->routemap_redist[i]);
2145 }
2146 }
2147
2148 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
2149 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
2150 /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */
2151 }
2152
2153 /*
2154 * RH config, too
2155 */
2156 if (hc->routemap_export_bgp_name) {
2157 old = hc->routemap_export_bgp;
2158 hc->routemap_export_bgp =
2159 route_map_lookup_by_name(hc->routemap_export_bgp_name);
2160 if (!old)
2161 route_map_counter_increment(hc->routemap_export_bgp);
2162 }
2163 if (hc->routemap_export_zebra_name) {
2164 old = hc->routemap_export_bgp;
2165 hc->routemap_export_bgp = route_map_lookup_by_name(
2166 hc->routemap_export_zebra_name);
2167 if (!old)
2168 route_map_counter_increment(hc->routemap_export_bgp);
2169 }
2170 for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
2171 if (hc->routemap_redist_name[i]) {
2172 old = hc->routemap_redist[i];
2173 hc->routemap_redist[i] = route_map_lookup_by_name(
2174 hc->routemap_redist_name[i]);
2175 if (!old)
2176 route_map_counter_increment(
2177 hc->routemap_redist[i]);
2178 }
2179 }
2180
2181 vnc_direct_bgp_reexport(bgp, AFI_IP);
2182 vnc_direct_bgp_reexport(bgp, AFI_IP6);
2183
2184 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
2185 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
2186
2187 vnc_redistribute_prechange(bgp);
2188 vnc_redistribute_postchange(bgp);
2189
2190 vnc_zlog_debug_verbose("%s done", __func__);
2191 }
2192
2193 /*-------------------------------------------------------------------------
2194 * nve-group
2195 *-----------------------------------------------------------------------*/
2196
2197
2198 DEFUN_NOSH (vnc_nve_group,
2199 vnc_nve_group_cmd,
2200 "vnc nve-group NAME",
2201 VNC_CONFIG_STR "Configure a NVE group\n" "Group name\n")
2202 {
2203 VTY_DECLVAR_CONTEXT(bgp, bgp);
2204 struct rfapi_nve_group_cfg *rfg;
2205 struct listnode *node, *nnode;
2206 struct rfapi_rfg_name *rfgn;
2207
2208 VNC_VTY_CONFIG_CHECK(bgp);
2209
2210 /* Search for name */
2211 rfg = bgp_rfapi_cfg_match_byname(bgp, argv[2]->arg,
2212 RFAPI_GROUP_CFG_NVE);
2213
2214 if (!rfg) {
2215 rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_NVE, argv[2]->arg);
2216 if (!rfg) {
2217 /* Error out of memory */
2218 vty_out(vty, "Can't allocate memory for NVE group\n");
2219 return CMD_WARNING_CONFIG_FAILED;
2220 }
2221
2222 /* Copy defaults from struct rfapi_cfg */
2223 rfg->rd = bgp->rfapi_cfg->default_rd;
2224 if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_L2RD) {
2225 rfg->l2rd = bgp->rfapi_cfg->default_l2rd;
2226 rfg->flags |= RFAPI_RFG_L2RD;
2227 }
2228 rfg->rd = bgp->rfapi_cfg->default_rd;
2229 rfg->response_lifetime =
2230 bgp->rfapi_cfg->default_response_lifetime;
2231
2232 if (bgp->rfapi_cfg->default_rt_export_list) {
2233 rfg->rt_export_list = ecommunity_dup(
2234 bgp->rfapi_cfg->default_rt_export_list);
2235 }
2236
2237 if (bgp->rfapi_cfg->default_rt_import_list) {
2238 rfg->rt_import_list = ecommunity_dup(
2239 bgp->rfapi_cfg->default_rt_import_list);
2240 rfg->rfapi_import_table = rfapiImportTableRefAdd(
2241 bgp, rfg->rt_import_list, rfg);
2242 }
2243
2244 /*
2245 * If a redist nve group was named but the group was not
2246 * defined,
2247 * make the linkage now
2248 */
2249 if (!bgp->rfapi_cfg->rfg_redist) {
2250 if (bgp->rfapi_cfg->rfg_redist_name
2251 && !strcmp(bgp->rfapi_cfg->rfg_redist_name,
2252 rfg->name)) {
2253
2254 vnc_redistribute_prechange(bgp);
2255 bgp->rfapi_cfg->rfg_redist = rfg;
2256 vnc_redistribute_postchange(bgp);
2257 }
2258 }
2259
2260 /*
2261 * Same treatment for bgp-direct export group
2262 */
2263 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l,
2264 node, nnode, rfgn)) {
2265
2266 if (!strcmp(rfgn->name, rfg->name)) {
2267 rfgn->rfg = rfg;
2268 vnc_direct_bgp_add_group(bgp, rfg);
2269 break;
2270 }
2271 }
2272
2273 /*
2274 * Same treatment for zebra export group
2275 */
2276 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node,
2277 nnode, rfgn)) {
2278
2279 vnc_zlog_debug_verbose(
2280 "%s: ezport zebra: checking if \"%s\" == \"%s\"",
2281 __func__, rfgn->name, rfg->name);
2282 if (!strcmp(rfgn->name, rfg->name)) {
2283 rfgn->rfg = rfg;
2284 vnc_zebra_add_group(bgp, rfg);
2285 break;
2286 }
2287 }
2288 }
2289
2290 /*
2291 * XXX subsequent calls will need to make sure this item is still
2292 * in the linked list and has the same name
2293 */
2294 VTY_PUSH_CONTEXT_SUB(BGP_VNC_NVE_GROUP_NODE, rfg);
2295
2296 return CMD_SUCCESS;
2297 }
2298
2299 static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */
2300 struct bgp *bgp,
2301 struct rfapi_nve_group_cfg *rfg)
2302 {
2303 struct list *orphaned_nves = NULL;
2304 struct listnode *node, *nnode;
2305
2306 /*
2307 * If there are currently-open NVEs that belong to this group,
2308 * zero out their references to this group structure.
2309 */
2310 if (rfg->nves) {
2311 struct rfapi_descriptor *rfd;
2312 orphaned_nves = list_new();
2313 while ((rfd = listnode_head(rfg->nves))) {
2314 rfd->rfg = NULL;
2315 listnode_delete(rfg->nves, rfd);
2316 listnode_add(orphaned_nves, rfd);
2317 }
2318 list_delete(&rfg->nves);
2319 }
2320
2321 /* delete it */
2322 free(rfg->name);
2323 if (rfg->rfapi_import_table)
2324 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
2325 if (rfg->rt_import_list)
2326 ecommunity_free(&rfg->rt_import_list);
2327 if (rfg->rt_export_list)
2328 ecommunity_free(&rfg->rt_export_list);
2329
2330 if (rfg->vn_node) {
2331 rfg->vn_node->info = NULL;
2332 agg_unlock_node(rfg->vn_node); /* frees */
2333 }
2334 if (rfg->un_node) {
2335 rfg->un_node->info = NULL;
2336 agg_unlock_node(rfg->un_node); /* frees */
2337 }
2338 if (rfg->rfp_cfg)
2339 XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
2340 listnode_delete(bgp->rfapi_cfg->nve_groups_sequential, rfg);
2341
2342 QOBJ_UNREG(rfg);
2343 XFREE(MTYPE_RFAPI_GROUP_CFG, rfg);
2344
2345 /*
2346 * Attempt to reassign the orphaned nves to a new group. If
2347 * a NVE can not be reassigned, its rfd->rfg will remain NULL
2348 * and it will become a zombie until released by rfapi_close().
2349 */
2350 if (orphaned_nves) {
2351 struct rfapi_descriptor *rfd;
2352
2353 for (ALL_LIST_ELEMENTS(orphaned_nves, node, nnode, rfd)) {
2354 /*
2355 * 1. rfapi_close() equivalent except:
2356 * a. don't free original descriptor
2357 * b. remember query list
2358 * c. remember advertised route list
2359 * 2. rfapi_open() equivalent except:
2360 * a. reuse original descriptor
2361 * 3. rfapi_register() on remembered advertised route
2362 * list
2363 * 4. rfapi_query on rememebred query list
2364 */
2365
2366 int rc;
2367
2368 rc = rfapi_reopen(rfd, bgp);
2369
2370 if (!rc) {
2371 list_delete_node(orphaned_nves, node);
2372 if (vty)
2373 vty_out(vty,
2374 "WARNING: reassigned NVE vn=");
2375 rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
2376 if (vty)
2377 vty_out(vty, " un=");
2378 rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
2379 if (vty)
2380 vty_out(vty, " to new group \"%s\"\n",
2381 rfd->rfg->name);
2382 }
2383 }
2384
2385 for (ALL_LIST_ELEMENTS_RO(orphaned_nves, node, rfd)) {
2386 if (vty)
2387 vty_out(vty, "WARNING: orphaned NVE vn=");
2388 rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
2389 if (vty)
2390 vty_out(vty, " un=");
2391 rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
2392 if (vty)
2393 vty_out(vty, "\n");
2394 }
2395 list_delete(&orphaned_nves);
2396 }
2397 }
2398
2399 static int
2400 bgp_rfapi_delete_named_nve_group(struct vty *vty, /* NULL = no output */
2401 struct bgp *bgp,
2402 const char *rfg_name, /* NULL = any */
2403 rfapi_group_cfg_type_t type) /* _MAX = any */
2404 {
2405 struct rfapi_nve_group_cfg *rfg = NULL;
2406 struct listnode *node, *nnode;
2407 struct rfapi_rfg_name *rfgn;
2408
2409 /* Search for name */
2410 if (rfg_name) {
2411 rfg = bgp_rfapi_cfg_match_byname(bgp, rfg_name, type);
2412 if (!rfg) {
2413 if (vty)
2414 vty_out(vty, "No NVE group named \"%s\"\n",
2415 rfg_name);
2416 return CMD_WARNING_CONFIG_FAILED;
2417 }
2418 }
2419
2420 /*
2421 * If this group is the redist nve group, unlink it
2422 */
2423 if (rfg_name == NULL || bgp->rfapi_cfg->rfg_redist == rfg) {
2424 vnc_redistribute_prechange(bgp);
2425 bgp->rfapi_cfg->rfg_redist = NULL;
2426 vnc_redistribute_postchange(bgp);
2427 }
2428
2429
2430 /*
2431 * remove reference from bgp direct export list
2432 */
2433 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
2434 rfgn)) {
2435 if (rfgn->rfg == rfg) {
2436 rfgn->rfg = NULL;
2437 /* remove exported routes from this group */
2438 vnc_direct_bgp_del_group(bgp, rfg);
2439 break;
2440 }
2441 }
2442
2443 /*
2444 * remove reference from zebra export list
2445 */
2446 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
2447 rfgn)) {
2448 if (rfgn->rfg == rfg) {
2449 rfgn->rfg = NULL;
2450 /* remove exported routes from this group */
2451 vnc_zebra_del_group(bgp, rfg);
2452 break;
2453 }
2454 }
2455 if (rfg) {
2456 if (rfg->rfd)
2457 clear_vnc_vrf_closer(rfg);
2458 bgp_rfapi_delete_nve_group(vty, bgp, rfg);
2459 } else /* must be delete all */
2460 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential,
2461 node, nnode, rfg)) {
2462 if (rfg->rfd)
2463 clear_vnc_vrf_closer(rfg);
2464 bgp_rfapi_delete_nve_group(vty, bgp, rfg);
2465 }
2466 return CMD_SUCCESS;
2467 }
2468
2469 DEFUN (vnc_no_nve_group,
2470 vnc_no_nve_group_cmd,
2471 "no vnc nve-group NAME",
2472 NO_STR
2473 VNC_CONFIG_STR
2474 "Configure a NVE group\n"
2475 "Group name\n")
2476 {
2477 VTY_DECLVAR_CONTEXT(bgp, bgp);
2478
2479 return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[3]->arg,
2480 RFAPI_GROUP_CFG_NVE);
2481 }
2482
2483 DEFUN (vnc_nve_group_prefix,
2484 vnc_nve_group_prefix_cmd,
2485 "prefix <vn|un> <A.B.C.D/M|X:X::X:X/M>",
2486 "Specify prefixes matching NVE VN or UN interfaces\n"
2487 "VN prefix\n"
2488 "UN prefix\n"
2489 "IPv4 prefix\n"
2490 "IPv6 prefix\n")
2491 {
2492 VTY_DECLVAR_CONTEXT(bgp, bgp);
2493 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2494 struct prefix p;
2495 afi_t afi;
2496 struct agg_table *rt;
2497 struct agg_node *rn;
2498 int is_un_prefix = 0;
2499
2500 /* make sure it's still in list */
2501 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2502 /* Not in list anymore */
2503 vty_out(vty, "Current NVE group no longer exists\n");
2504 return CMD_WARNING_CONFIG_FAILED;
2505 }
2506
2507 if (!str2prefix(argv[2]->arg, &p)) {
2508 vty_out(vty, "Malformed prefix \"%s\"\n", argv[2]->arg);
2509 return CMD_WARNING_CONFIG_FAILED;
2510 }
2511
2512 afi = family2afi(p.family);
2513 if (!afi) {
2514 vty_out(vty, "Unsupported address family\n");
2515 return CMD_WARNING_CONFIG_FAILED;
2516 }
2517
2518 if (argv[1]->arg[0] == 'u') {
2519 rt = bgp->rfapi_cfg->nve_groups_un[afi];
2520 is_un_prefix = 1;
2521 } else {
2522 rt = bgp->rfapi_cfg->nve_groups_vn[afi];
2523 }
2524
2525 rn = agg_node_get(rt, &p); /* NB locks node */
2526 if (rn->info) {
2527 /*
2528 * There is already a group with this prefix
2529 */
2530 agg_unlock_node(rn);
2531 if (rn->info != rfg) {
2532 /*
2533 * different group name: fail
2534 */
2535 vty_out(vty,
2536 "nve group \"%s\" already has \"%s\" prefix %s\n",
2537 ((struct rfapi_nve_group_cfg *)(rn->info))
2538 ->name,
2539 argv[1]->arg, argv[2]->arg);
2540 return CMD_WARNING_CONFIG_FAILED;
2541 } else {
2542 /*
2543 * same group name: it's already in the correct place
2544 * in the table, so we're done.
2545 *
2546 * Implies rfg->(vn|un)_prefix is already correct.
2547 */
2548 return CMD_SUCCESS;
2549 }
2550 }
2551
2552 if (bgp->rfapi_cfg->rfg_redist == rfg) {
2553 vnc_redistribute_prechange(bgp);
2554 }
2555
2556 /* New prefix, new node */
2557
2558 if (is_un_prefix) {
2559
2560 /* detach rfg from previous route table location */
2561 if (rfg->un_node) {
2562 rfg->un_node->info = NULL;
2563 agg_unlock_node(rfg->un_node); /* frees */
2564 }
2565 rfg->un_node = rn; /* back ref */
2566 rfg->un_prefix = p;
2567
2568 } else {
2569
2570 /* detach rfg from previous route table location */
2571 if (rfg->vn_node) {
2572 rfg->vn_node->info = NULL;
2573 agg_unlock_node(rfg->vn_node); /* frees */
2574 }
2575 rfg->vn_node = rn; /* back ref */
2576 rfg->vn_prefix = p;
2577 }
2578
2579 /* attach */
2580 rn->info = rfg;
2581
2582 if (bgp->rfapi_cfg->rfg_redist == rfg) {
2583 vnc_redistribute_postchange(bgp);
2584 }
2585
2586 return CMD_SUCCESS;
2587 }
2588
2589 DEFUN (vnc_nve_group_rt_import,
2590 vnc_nve_group_rt_import_cmd,
2591 "rt import RTLIST...",
2592 "Specify route targets\n"
2593 "Import filter\n"
2594 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
2595 {
2596 VTY_DECLVAR_CONTEXT(bgp, bgp);
2597 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2598 int rc;
2599 struct listnode *node;
2600 struct rfapi_rfg_name *rfgn;
2601 int is_export_bgp = 0;
2602 int is_export_zebra = 0;
2603
2604 /* make sure it's still in list */
2605 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2606 /* Not in list anymore */
2607 vty_out(vty, "Current NVE group no longer exists\n");
2608 return CMD_WARNING_CONFIG_FAILED;
2609 }
2610
2611 rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
2612 if (rc != CMD_SUCCESS)
2613 return rc;
2614
2615 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
2616 rfgn)) {
2617
2618 if (rfgn->rfg == rfg) {
2619 is_export_bgp = 1;
2620 break;
2621 }
2622 }
2623
2624 if (is_export_bgp)
2625 vnc_direct_bgp_del_group(bgp, rfg);
2626
2627 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
2628 rfgn)) {
2629
2630 if (rfgn->rfg == rfg) {
2631 is_export_zebra = 1;
2632 break;
2633 }
2634 }
2635
2636 if (is_export_zebra)
2637 vnc_zebra_del_group(bgp, rfg);
2638
2639 /*
2640 * stop referencing old import table, now reference new one
2641 */
2642 if (rfg->rfapi_import_table)
2643 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
2644 rfg->rfapi_import_table =
2645 rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
2646
2647 if (is_export_bgp)
2648 vnc_direct_bgp_add_group(bgp, rfg);
2649
2650 if (is_export_zebra)
2651 vnc_zebra_add_group(bgp, rfg);
2652
2653 return CMD_SUCCESS;
2654 }
2655
2656 DEFUN (vnc_nve_group_rt_export,
2657 vnc_nve_group_rt_export_cmd,
2658 "rt export RTLIST...",
2659 "Specify route targets\n"
2660 "Export filter\n"
2661 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
2662 {
2663 VTY_DECLVAR_CONTEXT(bgp, bgp);
2664 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2665 int rc;
2666
2667 /* make sure it's still in list */
2668 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2669 /* Not in list anymore */
2670 vty_out(vty, "Current NVE group no longer exists\n");
2671 return CMD_WARNING_CONFIG_FAILED;
2672 }
2673
2674 if (bgp->rfapi_cfg->rfg_redist == rfg) {
2675 vnc_redistribute_prechange(bgp);
2676 }
2677
2678 rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
2679
2680 if (bgp->rfapi_cfg->rfg_redist == rfg) {
2681 vnc_redistribute_postchange(bgp);
2682 }
2683
2684 return rc;
2685 }
2686
2687 DEFUN (vnc_nve_group_rt_both,
2688 vnc_nve_group_rt_both_cmd,
2689 "rt both RTLIST...",
2690 "Specify route targets\n"
2691 "Export+import filters\n"
2692 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
2693 {
2694 VTY_DECLVAR_CONTEXT(bgp, bgp);
2695 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2696 int rc;
2697 int is_export_bgp = 0;
2698 int is_export_zebra = 0;
2699 struct listnode *node;
2700 struct rfapi_rfg_name *rfgn;
2701
2702 /* make sure it's still in list */
2703 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2704 /* Not in list anymore */
2705 vty_out(vty, "Current NVE group no longer exists\n");
2706 return CMD_WARNING_CONFIG_FAILED;
2707 }
2708
2709 rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
2710 if (rc != CMD_SUCCESS)
2711 return rc;
2712
2713 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
2714 rfgn)) {
2715
2716 if (rfgn->rfg == rfg) {
2717 is_export_bgp = 1;
2718 break;
2719 }
2720 }
2721
2722 if (is_export_bgp)
2723 vnc_direct_bgp_del_group(bgp, rfg);
2724
2725 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
2726 rfgn)) {
2727
2728 if (rfgn->rfg == rfg) {
2729 is_export_zebra = 1;
2730 break;
2731 }
2732 }
2733
2734 if (is_export_zebra) {
2735 vnc_zlog_debug_verbose("%s: is_export_zebra", __func__);
2736 vnc_zebra_del_group(bgp, rfg);
2737 }
2738
2739 /*
2740 * stop referencing old import table, now reference new one
2741 */
2742 if (rfg->rfapi_import_table)
2743 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
2744 rfg->rfapi_import_table =
2745 rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
2746
2747 if (is_export_bgp)
2748 vnc_direct_bgp_add_group(bgp, rfg);
2749
2750 if (is_export_zebra)
2751 vnc_zebra_add_group(bgp, rfg);
2752
2753 if (bgp->rfapi_cfg->rfg_redist == rfg) {
2754 vnc_redistribute_prechange(bgp);
2755 }
2756
2757 rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
2758
2759 if (bgp->rfapi_cfg->rfg_redist == rfg) {
2760 vnc_redistribute_postchange(bgp);
2761 }
2762
2763 return rc;
2764 }
2765
2766 DEFUN (vnc_nve_group_l2rd,
2767 vnc_nve_group_l2rd_cmd,
2768 "l2rd <(1-255)|auto-vn>",
2769 "Specify default Local Nve ID value to use in RD for L2 routes\n"
2770 "Fixed value 1-255\n"
2771 "use the low-order octet of the NVE's VN address\n")
2772 {
2773 VTY_DECLVAR_CONTEXT(bgp, bgp);
2774 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2775
2776 /* make sure it's still in list */
2777 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2778 /* Not in list anymore */
2779 vty_out(vty, "Current NVE group no longer exists\n");
2780 return CMD_WARNING_CONFIG_FAILED;
2781 }
2782
2783 if (strmatch(argv[1]->text, "auto:vn")) {
2784 rfg->l2rd = 0;
2785 } else {
2786 char *end = NULL;
2787 unsigned long value_l = strtoul(argv[1]->arg, &end, 10);
2788 uint8_t value = value_l & 0xff;
2789
2790 if (!argv[1]->arg[0] || *end) {
2791 vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n",
2792 argv[1]->arg);
2793 return CMD_WARNING_CONFIG_FAILED;
2794 }
2795 if ((value_l < 1) || (value_l > 0xff)) {
2796 vty_out(vty,
2797 "%% Malformed l2 nve id (must be greater than 0 and less than %u\n",
2798 0x100);
2799 return CMD_WARNING_CONFIG_FAILED;
2800 }
2801
2802 rfg->l2rd = value;
2803 }
2804 rfg->flags |= RFAPI_RFG_L2RD;
2805
2806 return CMD_SUCCESS;
2807 }
2808
2809 DEFUN (vnc_nve_group_no_l2rd,
2810 vnc_nve_group_no_l2rd_cmd,
2811 "no l2rd",
2812 NO_STR
2813 "Specify default Local Nve ID value to use in RD for L2 routes\n")
2814 {
2815 VTY_DECLVAR_CONTEXT(bgp, bgp);
2816 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2817
2818 /* make sure it's still in list */
2819 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2820 /* Not in list anymore */
2821 vty_out(vty, "Current NVE group no longer exists\n");
2822 return CMD_WARNING_CONFIG_FAILED;
2823 }
2824
2825 rfg->l2rd = 0;
2826 rfg->flags &= ~RFAPI_RFG_L2RD;
2827
2828 return CMD_SUCCESS;
2829 }
2830
2831 DEFUN (vnc_nve_group_rd,
2832 vnc_nve_group_rd_cmd,
2833 "rd ASN:NN_OR_IP-ADDRESS:NN",
2834 "Specify route distinguisher\n"
2835 "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
2836 {
2837 VTY_DECLVAR_CONTEXT(bgp, bgp);
2838 int ret;
2839 struct prefix_rd prd;
2840 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2841
2842 /* make sure it's still in list */
2843 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2844 /* Not in list anymore */
2845 vty_out(vty, "Current NVE group no longer exists\n");
2846 return CMD_WARNING_CONFIG_FAILED;
2847 }
2848
2849 if (!strncmp(argv[1]->arg, "auto:vn:", 8)) {
2850 /*
2851 * use AF_UNIX to designate automatically-assigned RD
2852 * auto:vn:nn where nn is a 2-octet quantity
2853 */
2854 char *end = NULL;
2855 uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
2856 uint16_t value = value32 & 0xffff;
2857
2858 if (!argv[1]->arg[8] || *end) {
2859 vty_out(vty, "%% Malformed rd\n");
2860 return CMD_WARNING_CONFIG_FAILED;
2861 }
2862 if (value32 > 0xffff) {
2863 vty_out(vty, "%% Malformed rd (must be less than %u\n",
2864 0x0ffff);
2865 return CMD_WARNING_CONFIG_FAILED;
2866 }
2867
2868 memset(&prd, 0, sizeof(prd));
2869 prd.family = AF_UNIX;
2870 prd.prefixlen = 64;
2871 prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
2872 prd.val[1] = RD_TYPE_IP & 0x0ff;
2873 prd.val[6] = (value >> 8) & 0x0ff;
2874 prd.val[7] = value & 0x0ff;
2875
2876 } else {
2877
2878 /* TODO: save RD format */
2879 ret = str2prefix_rd(argv[1]->arg, &prd);
2880 if (!ret) {
2881 vty_out(vty, "%% Malformed rd\n");
2882 return CMD_WARNING_CONFIG_FAILED;
2883 }
2884 }
2885
2886 if (bgp->rfapi_cfg->rfg_redist == rfg) {
2887 vnc_redistribute_prechange(bgp);
2888 }
2889
2890 rfg->rd = prd;
2891
2892 if (bgp->rfapi_cfg->rfg_redist == rfg) {
2893 vnc_redistribute_postchange(bgp);
2894 }
2895 return CMD_SUCCESS;
2896 }
2897
2898 DEFUN (vnc_nve_group_responselifetime,
2899 vnc_nve_group_responselifetime_cmd,
2900 "response-lifetime <LIFETIME|infinite>",
2901 "Specify response lifetime\n"
2902 "Response lifetime in seconds\n" "Infinite response lifetime\n")
2903 {
2904 VTY_DECLVAR_CONTEXT(bgp, bgp);
2905 unsigned int rspint;
2906 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
2907 struct rfapi_descriptor *rfd;
2908 struct listnode *hdnode;
2909
2910 /* make sure it's still in list */
2911 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
2912 /* Not in list anymore */
2913 vty_out(vty, "Current NVE group no longer exists\n");
2914 return CMD_WARNING_CONFIG_FAILED;
2915 }
2916
2917 if (strmatch(argv[1]->text, "infinite")) {
2918 rspint = RFAPI_INFINITE_LIFETIME;
2919 } else {
2920 rspint = strtoul(argv[1]->arg, NULL, 10);
2921 }
2922
2923 rfg->response_lifetime = rspint;
2924 rfg->flags |= RFAPI_RFG_RESPONSE_LIFETIME;
2925 if (rfg->nves)
2926 for (ALL_LIST_ELEMENTS_RO(rfg->nves, hdnode, rfd))
2927 rfd->response_lifetime = rspint;
2928 return CMD_SUCCESS;
2929 }
2930
2931 /*
2932 * Sigh. This command, like exit-address-family, is a hack to deal
2933 * with the lack of rigorous level control in the command handler.
2934 * TBD fix command handler.
2935 */
2936 DEFUN_NOSH (exit_vnc,
2937 exit_vnc_cmd,
2938 "exit-vnc",
2939 "Exit VNC configuration mode\n")
2940 {
2941 if (vty->node == BGP_VNC_DEFAULTS_NODE
2942 || vty->node == BGP_VNC_NVE_GROUP_NODE
2943 || vty->node == BGP_VNC_L2_GROUP_NODE) {
2944
2945 vty->node = BGP_NODE;
2946 }
2947 return CMD_SUCCESS;
2948 }
2949
2950 static struct cmd_node bgp_vnc_defaults_node = {
2951 .name = "bgp vnc defaults",
2952 .node = BGP_VNC_DEFAULTS_NODE,
2953 .parent_node = BGP_NODE,
2954 .prompt = "%s(config-router-vnc-defaults)# ",
2955 };
2956
2957 static struct cmd_node bgp_vnc_nve_group_node = {
2958 .name = "bgp vnc nve",
2959 .node = BGP_VNC_NVE_GROUP_NODE,
2960 .parent_node = BGP_NODE,
2961 .prompt = "%s(config-router-vnc-nve-group)# ",
2962 };
2963
2964 /*-------------------------------------------------------------------------
2965 * VNC nve-group
2966 * Note there are two types of NVEs, one for VPNs one for RFP NVEs
2967 *-----------------------------------------------------------------------*/
2968
2969 DEFUN_NOSH (vnc_vrf_policy,
2970 vnc_vrf_policy_cmd,
2971 "vrf-policy NAME",
2972 "Configure a VRF policy group\n"
2973 "VRF name\n")
2974 {
2975 struct rfapi_nve_group_cfg *rfg;
2976 VTY_DECLVAR_CONTEXT(bgp, bgp);
2977
2978 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
2979 vty_out(vty,
2980 "Can't configure vrf-policy within a BGP VRF instance\n");
2981 return CMD_WARNING_CONFIG_FAILED;
2982 }
2983
2984 /* Search for name */
2985 rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg,
2986 RFAPI_GROUP_CFG_VRF);
2987
2988 if (!rfg) {
2989 rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_VRF, argv[1]->arg);
2990 if (!rfg) {
2991 /* Error out of memory */
2992 vty_out(vty, "Can't allocate memory for NVE group\n");
2993 return CMD_WARNING_CONFIG_FAILED;
2994 }
2995 }
2996 /*
2997 * XXX subsequent calls will need to make sure this item is still
2998 * in the linked list and has the same name
2999 */
3000 VTY_PUSH_CONTEXT_SUB(BGP_VRF_POLICY_NODE, rfg);
3001
3002 return CMD_SUCCESS;
3003 }
3004
3005 DEFUN (vnc_no_vrf_policy,
3006 vnc_no_vrf_policy_cmd,
3007 "no vrf-policy NAME",
3008 NO_STR
3009 "Remove a VRF policy group\n"
3010 "VRF name\n")
3011 {
3012 VTY_DECLVAR_CONTEXT(bgp, bgp);
3013
3014 /* silently return */
3015 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3016 return CMD_SUCCESS;
3017
3018 return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[2]->arg,
3019 RFAPI_GROUP_CFG_VRF);
3020 }
3021
3022 DEFUN (vnc_vrf_policy_label,
3023 vnc_vrf_policy_label_cmd,
3024 "label (0-1048575)",
3025 "Default label value for VRF\n"
3026 "Label Value <0-1048575>\n")
3027 {
3028 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3029
3030 uint32_t label;
3031 VTY_DECLVAR_CONTEXT(bgp, bgp);
3032
3033 /* make sure it's still in list */
3034 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3035 /* Not in list anymore */
3036 vty_out(vty, "Current NVE group no longer exists\n");
3037 return CMD_WARNING_CONFIG_FAILED;
3038 }
3039
3040 label = strtoul(argv[1]->arg, NULL, 10);
3041
3042 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3043 vnc_redistribute_prechange(bgp);
3044 }
3045
3046 rfg->label = label;
3047
3048 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3049 vnc_redistribute_postchange(bgp);
3050 }
3051 return CMD_SUCCESS;
3052 }
3053
3054 DEFUN (vnc_vrf_policy_no_label,
3055 vnc_vrf_policy_no_label_cmd,
3056 "no label",
3057 NO_STR
3058 "Remove VRF default label\n")
3059 {
3060 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3061 VTY_DECLVAR_CONTEXT(bgp, bgp);
3062
3063 /* make sure it's still in list */
3064 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3065 /* Not in list anymore */
3066 vty_out(vty, "Current VRF group no longer exists\n");
3067 return CMD_WARNING_CONFIG_FAILED;
3068 }
3069
3070 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3071 vnc_redistribute_prechange(bgp);
3072 }
3073
3074 rfg->label = MPLS_LABEL_NONE;
3075
3076 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3077 vnc_redistribute_postchange(bgp);
3078 }
3079 return CMD_SUCCESS;
3080 }
3081
3082 DEFUN (vnc_vrf_policy_nexthop,
3083 vnc_vrf_policy_nexthop_cmd,
3084 "nexthop <A.B.C.D|X:X::X:X|self>",
3085 "Specify next hop to use for VRF advertised prefixes\n"
3086 "IPv4 prefix\n"
3087 "IPv6 prefix\n"
3088 "Use configured router-id (default)\n")
3089 {
3090 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3091 struct prefix p;
3092
3093 VTY_DECLVAR_CONTEXT(bgp, bgp);
3094
3095 /* make sure it's still in list */
3096 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3097 /* Not in list anymore */
3098 vty_out(vty, "Current VRF no longer exists\n");
3099 return CMD_WARNING_CONFIG_FAILED;
3100 }
3101
3102 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3103 vnc_redistribute_prechange(bgp);
3104 }
3105
3106 if (!str2prefix(argv[1]->arg, &p) && p.family) {
3107 // vty_out (vty, "Nexthop set to self\n");
3108 SET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF);
3109 memset(&rfg->vn_prefix, 0, sizeof(struct prefix));
3110 } else {
3111 UNSET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF);
3112 rfg->vn_prefix = p;
3113 rfg->un_prefix = p;
3114 }
3115
3116 /* TBD handle router-id/ nexthop changes when have advertised prefixes
3117 */
3118
3119 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3120 vnc_redistribute_postchange(bgp);
3121 }
3122
3123 return CMD_SUCCESS;
3124 }
3125
3126 /* The RT code should be refactored/simplified with above... */
3127 DEFUN (vnc_vrf_policy_rt_import,
3128 vnc_vrf_policy_rt_import_cmd,
3129 "rt import RTLIST...",
3130 "Specify route targets\n"
3131 "Import filter\n"
3132 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3133 {
3134 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3135 VTY_DECLVAR_CONTEXT(bgp, bgp);
3136 int rc;
3137 struct listnode *node;
3138 struct rfapi_rfg_name *rfgn;
3139 int is_export_bgp = 0;
3140 int is_export_zebra = 0;
3141
3142 /* make sure it's still in list */
3143 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3144 /* Not in list anymore */
3145 vty_out(vty, "Current NVE group no longer exists\n");
3146 return CMD_WARNING_CONFIG_FAILED;
3147 }
3148
3149 rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
3150 if (rc != CMD_SUCCESS)
3151 return rc;
3152
3153 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
3154 rfgn)) {
3155
3156 if (rfgn->rfg == rfg) {
3157 is_export_bgp = 1;
3158 break;
3159 }
3160 }
3161
3162 if (is_export_bgp)
3163 vnc_direct_bgp_del_group(bgp, rfg);
3164
3165 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
3166 rfgn)) {
3167
3168 if (rfgn->rfg == rfg) {
3169 is_export_zebra = 1;
3170 break;
3171 }
3172 }
3173
3174 if (is_export_zebra)
3175 vnc_zebra_del_group(bgp, rfg);
3176
3177 /*
3178 * stop referencing old import table, now reference new one
3179 */
3180 if (rfg->rfapi_import_table)
3181 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
3182 rfg->rfapi_import_table =
3183 rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
3184
3185 if (is_export_bgp)
3186 vnc_direct_bgp_add_group(bgp, rfg);
3187
3188 if (is_export_zebra)
3189 vnc_zebra_add_group(bgp, rfg);
3190
3191 return CMD_SUCCESS;
3192 }
3193
3194 DEFUN (vnc_vrf_policy_rt_export,
3195 vnc_vrf_policy_rt_export_cmd,
3196 "rt export RTLIST...",
3197 "Specify route targets\n"
3198 "Export filter\n"
3199 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3200 {
3201 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3202 VTY_DECLVAR_CONTEXT(bgp, bgp);
3203 int rc;
3204
3205 /* make sure it's still in list */
3206 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3207 /* Not in list anymore */
3208 vty_out(vty, "Current NVE group no longer exists\n");
3209 return CMD_WARNING_CONFIG_FAILED;
3210 }
3211
3212 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3213 vnc_redistribute_prechange(bgp);
3214 }
3215
3216 rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
3217
3218 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3219 vnc_redistribute_postchange(bgp);
3220 }
3221
3222 return rc;
3223 }
3224
3225 DEFUN (vnc_vrf_policy_rt_both,
3226 vnc_vrf_policy_rt_both_cmd,
3227 "rt both RTLIST...",
3228 "Specify route targets\n"
3229 "Export+import filters\n"
3230 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3231 {
3232 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3233 VTY_DECLVAR_CONTEXT(bgp, bgp);
3234 int rc;
3235 int is_export_bgp = 0;
3236 int is_export_zebra = 0;
3237 struct listnode *node;
3238 struct rfapi_rfg_name *rfgn;
3239
3240 /* make sure it's still in list */
3241 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3242 /* Not in list anymore */
3243 vty_out(vty, "Current NVE group no longer exists\n");
3244 return CMD_WARNING_CONFIG_FAILED;
3245 }
3246
3247 rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
3248 if (rc != CMD_SUCCESS)
3249 return rc;
3250
3251 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
3252 rfgn)) {
3253
3254 if (rfgn->rfg == rfg) {
3255 is_export_bgp = 1;
3256 break;
3257 }
3258 }
3259
3260 if (is_export_bgp)
3261 vnc_direct_bgp_del_group(bgp, rfg);
3262
3263 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
3264 rfgn)) {
3265
3266 if (rfgn->rfg == rfg) {
3267 is_export_zebra = 1;
3268 break;
3269 }
3270 }
3271
3272 if (is_export_zebra) {
3273 vnc_zlog_debug_verbose("%s: is_export_zebra", __func__);
3274 vnc_zebra_del_group(bgp, rfg);
3275 }
3276
3277 /*
3278 * stop referencing old import table, now reference new one
3279 */
3280 if (rfg->rfapi_import_table)
3281 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
3282 rfg->rfapi_import_table =
3283 rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
3284
3285 if (is_export_bgp)
3286 vnc_direct_bgp_add_group(bgp, rfg);
3287
3288 if (is_export_zebra)
3289 vnc_zebra_add_group(bgp, rfg);
3290
3291 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3292 vnc_redistribute_prechange(bgp);
3293 }
3294
3295 rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
3296
3297 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3298 vnc_redistribute_postchange(bgp);
3299 }
3300
3301 return rc;
3302 }
3303
3304 DEFUN (vnc_vrf_policy_rd,
3305 vnc_vrf_policy_rd_cmd,
3306 "rd ASN:NN_OR_IP-ADDRESS:NN",
3307 "Specify default VRF route distinguisher\n"
3308 "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:nh:<number> )\n")
3309 {
3310 int ret;
3311 struct prefix_rd prd;
3312 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
3313 VTY_DECLVAR_CONTEXT(bgp, bgp);
3314
3315 /* make sure it's still in list */
3316 if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
3317 /* Not in list anymore */
3318 vty_out(vty, "Current NVE group no longer exists\n");
3319 return CMD_WARNING_CONFIG_FAILED;
3320 }
3321
3322 if (!strncmp(argv[1]->arg, "auto:nh:", 8)) {
3323 /*
3324 * use AF_UNIX to designate automatically-assigned RD
3325 * auto:vn:nn where nn is a 2-octet quantity
3326 */
3327 char *end = NULL;
3328 uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
3329 uint16_t value = value32 & 0xffff;
3330
3331 if (!*(argv[1]->arg + 5) || *end) {
3332 vty_out(vty, "%% Malformed rd\n");
3333 return CMD_WARNING_CONFIG_FAILED;
3334 }
3335 if (value32 > 0xffff) {
3336 vty_out(vty, "%% Malformed rd (must be less than %u\n",
3337 0x0ffff);
3338 return CMD_WARNING_CONFIG_FAILED;
3339 }
3340
3341 memset(&prd, 0, sizeof(prd));
3342 prd.family = AF_UNIX;
3343 prd.prefixlen = 64;
3344 prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
3345 prd.val[1] = RD_TYPE_IP & 0x0ff;
3346 prd.val[6] = (value >> 8) & 0x0ff;
3347 prd.val[7] = value & 0x0ff;
3348
3349 } else {
3350
3351 /* TODO: save RD format */
3352 ret = str2prefix_rd(argv[1]->arg, &prd);
3353 if (!ret) {
3354 vty_out(vty, "%% Malformed rd\n");
3355 return CMD_WARNING_CONFIG_FAILED;
3356 }
3357 }
3358
3359 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3360 vnc_redistribute_prechange(bgp);
3361 }
3362
3363 rfg->rd = prd;
3364
3365 if (bgp->rfapi_cfg->rfg_redist == rfg) {
3366 vnc_redistribute_postchange(bgp);
3367 }
3368 return CMD_SUCCESS;
3369 }
3370
3371 DEFUN_NOSH (exit_vrf_policy,
3372 exit_vrf_policy_cmd,
3373 "exit-vrf-policy",
3374 "Exit VRF policy configuration mode\n")
3375 {
3376 if (vty->node == BGP_VRF_POLICY_NODE) {
3377 vty->node = BGP_NODE;
3378 }
3379 return CMD_SUCCESS;
3380 }
3381
3382 static struct cmd_node bgp_vrf_policy_node = {
3383 .name = "bgp vrf policy",
3384 .node = BGP_VRF_POLICY_NODE,
3385 .parent_node = BGP_NODE,
3386 .prompt = "%s(config-router-vrf-policy)# ",
3387 };
3388
3389 /*-------------------------------------------------------------------------
3390 * vnc-l2-group
3391 *-----------------------------------------------------------------------*/
3392
3393
3394 DEFUN_NOSH (vnc_l2_group,
3395 vnc_l2_group_cmd,
3396 "vnc l2-group NAME",
3397 VNC_CONFIG_STR "Configure a L2 group\n" "Group name\n")
3398 {
3399 struct rfapi_l2_group_cfg *rfg;
3400 VTY_DECLVAR_CONTEXT(bgp, bgp);
3401 VNC_VTY_CONFIG_CHECK(bgp);
3402
3403 /* Search for name */
3404 rfg = rfapi_l2_group_lookup_byname(bgp, argv[2]->arg);
3405
3406 if (!rfg) {
3407 rfg = rfapi_l2_group_new();
3408 if (!rfg) {
3409 /* Error out of memory */
3410 vty_out(vty, "Can't allocate memory for L2 group\n");
3411 return CMD_WARNING_CONFIG_FAILED;
3412 }
3413 rfg->name = strdup(argv[2]->arg);
3414 /* add to tail of list */
3415 listnode_add(bgp->rfapi_cfg->l2_groups, rfg);
3416 }
3417
3418 /*
3419 * XXX subsequent calls will need to make sure this item is still
3420 * in the linked list and has the same name
3421 */
3422 VTY_PUSH_CONTEXT_SUB(BGP_VNC_L2_GROUP_NODE, rfg);
3423 return CMD_SUCCESS;
3424 }
3425
3426 static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */
3427 struct bgp *bgp,
3428 struct rfapi_l2_group_cfg *rfg)
3429 {
3430 /* delete it */
3431 free(rfg->name);
3432 if (rfg->rt_import_list)
3433 ecommunity_free(&rfg->rt_import_list);
3434 if (rfg->rt_export_list)
3435 ecommunity_free(&rfg->rt_export_list);
3436 if (rfg->labels)
3437 list_delete(&rfg->labels);
3438 XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
3439 listnode_delete(bgp->rfapi_cfg->l2_groups, rfg);
3440
3441 rfapi_l2_group_del(rfg);
3442 }
3443
3444 static int
3445 bgp_rfapi_delete_named_l2_group(struct vty *vty, /* NULL = no output */
3446 struct bgp *bgp,
3447 const char *rfg_name) /* NULL = any */
3448 {
3449 struct rfapi_l2_group_cfg *rfg = NULL;
3450 struct listnode *node, *nnode;
3451
3452 /* Search for name */
3453 if (rfg_name) {
3454 rfg = rfapi_l2_group_lookup_byname(bgp, rfg_name);
3455 if (!rfg) {
3456 if (vty)
3457 vty_out(vty, "No L2 group named \"%s\"\n",
3458 rfg_name);
3459 return CMD_WARNING_CONFIG_FAILED;
3460 }
3461 }
3462
3463 if (rfg)
3464 bgp_rfapi_delete_l2_group(vty, bgp, rfg);
3465 else /* must be delete all */
3466 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode,
3467 rfg))
3468 bgp_rfapi_delete_l2_group(vty, bgp, rfg);
3469 return CMD_SUCCESS;
3470 }
3471
3472 DEFUN (vnc_no_l2_group,
3473 vnc_no_l2_group_cmd,
3474 "no vnc l2-group NAME",
3475 NO_STR
3476 VNC_CONFIG_STR
3477 "Configure a L2 group\n"
3478 "Group name\n")
3479 {
3480 VTY_DECLVAR_CONTEXT(bgp, bgp);
3481
3482 return bgp_rfapi_delete_named_l2_group(vty, bgp, argv[3]->arg);
3483 }
3484
3485
3486 DEFUN (vnc_l2_group_lni,
3487 vnc_l2_group_lni_cmd,
3488 "logical-network-id (0-4294967295)",
3489 "Specify Logical Network ID associated with group\n"
3490 "value\n")
3491 {
3492 VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
3493 VTY_DECLVAR_CONTEXT(bgp, bgp);
3494
3495 /* make sure it's still in list */
3496 if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
3497 /* Not in list anymore */
3498 vty_out(vty, "Current L2 group no longer exists\n");
3499 return CMD_WARNING_CONFIG_FAILED;
3500 }
3501
3502 rfg->logical_net_id = strtoul(argv[1]->arg, NULL, 10);
3503
3504 return CMD_SUCCESS;
3505 }
3506
3507 DEFUN (vnc_l2_group_labels,
3508 vnc_l2_group_labels_cmd,
3509 "labels (0-1048575)...",
3510 "Specify label values associated with group\n"
3511 "Space separated list of label values <0-1048575>\n")
3512 {
3513 VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
3514 VTY_DECLVAR_CONTEXT(bgp, bgp);
3515 struct list *ll;
3516
3517 /* make sure it's still in list */
3518 if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
3519 /* Not in list anymore */
3520 vty_out(vty, "Current L2 group no longer exists\n");
3521 return CMD_WARNING_CONFIG_FAILED;
3522 }
3523
3524 ll = rfg->labels;
3525 if (ll == NULL) {
3526 ll = list_new();
3527 rfg->labels = ll;
3528 }
3529 argc--;
3530 argv++;
3531 for (; argc; --argc, ++argv) {
3532 uint32_t label;
3533 label = strtoul(argv[0]->arg, NULL, 10);
3534 if (!listnode_lookup(ll, (void *)(uintptr_t)label))
3535 listnode_add(ll, (void *)(uintptr_t)label);
3536 }
3537
3538 return CMD_SUCCESS;
3539 }
3540
3541 DEFUN (vnc_l2_group_no_labels,
3542 vnc_l2_group_no_labels_cmd,
3543 "no labels (0-1048575)...",
3544 NO_STR
3545 "Specify label values associated with L2 group\n"
3546 "Space separated list of label values <0-1048575>\n")
3547 {
3548 VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
3549 VTY_DECLVAR_CONTEXT(bgp, bgp);
3550 struct list *ll;
3551
3552 /* make sure it's still in list */
3553 if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
3554 /* Not in list anymore */
3555 vty_out(vty, "Current L2 group no longer exists\n");
3556 return CMD_WARNING_CONFIG_FAILED;
3557 }
3558
3559 ll = rfg->labels;
3560 if (ll == NULL) {
3561 vty_out(vty, "Label no longer associated with group\n");
3562 return CMD_WARNING_CONFIG_FAILED;
3563 }
3564
3565 argc -= 2;
3566 argv += 2;
3567 for (; argc; --argc, ++argv) {
3568 uint32_t label;
3569 label = strtoul(argv[0]->arg, NULL, 10);
3570 listnode_delete(ll, (void *)(uintptr_t)label);
3571 }
3572
3573 return CMD_SUCCESS;
3574 }
3575
3576 DEFUN (vnc_l2_group_rt,
3577 vnc_l2_group_rt_cmd,
3578 "rt <both|export|import> ASN:NN_OR_IP-ADDRESS:NN",
3579 "Specify route targets\n"
3580 "Export+import filters\n"
3581 "Export filters\n"
3582 "Import filters\n"
3583 "A route target\n")
3584 {
3585 VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
3586 VTY_DECLVAR_CONTEXT(bgp, bgp);
3587 int rc = CMD_SUCCESS;
3588 int do_import = 0;
3589 int do_export = 0;
3590
3591 switch (argv[1]->arg[0]) {
3592 case 'b':
3593 do_export = 1; /* fall through */
3594 case 'i':
3595 do_import = 1;
3596 break;
3597 case 'e':
3598 do_export = 1;
3599 break;
3600 default:
3601 vty_out(vty, "Unknown option, %s\n", argv[1]->arg);
3602 return CMD_ERR_NO_MATCH;
3603 }
3604
3605 /* make sure it's still in list */
3606 if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
3607 /* Not in list anymore */
3608 vty_out(vty, "Current L2 group no longer exists\n");
3609 return CMD_WARNING_CONFIG_FAILED;
3610 }
3611
3612 if (do_import)
3613 rc = set_ecom_list(vty, argc - 2, argv + 2,
3614 &rfg->rt_import_list);
3615 if (rc == CMD_SUCCESS && do_export)
3616 rc = set_ecom_list(vty, argc - 2, argv + 2,
3617 &rfg->rt_export_list);
3618 return rc;
3619 }
3620
3621
3622 static struct cmd_node bgp_vnc_l2_group_node = {
3623 .name = "bgp vnc l2",
3624 .node = BGP_VNC_L2_GROUP_NODE,
3625 .parent_node = BGP_NODE,
3626 .prompt = "%s(config-router-vnc-l2-group)# ",
3627 };
3628
3629 struct rfapi_l2_group_cfg *
3630 bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id,
3631 uint32_t label)
3632 {
3633 struct rfapi_l2_group_cfg *rfg;
3634 struct listnode *node;
3635
3636 if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */
3637 return NULL;
3638
3639 label = label & 0xfffff; /* label is 20 bits! */
3640
3641 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->l2_groups, node, rfg)) {
3642 if (rfg->logical_net_id == logical_net_id) {
3643 struct listnode *lnode;
3644 void *data;
3645 for (ALL_LIST_ELEMENTS_RO(rfg->labels, lnode, data))
3646 if (((uint32_t)((uintptr_t)data))
3647 == label) { /* match! */
3648 return rfg;
3649 }
3650 }
3651 }
3652 return NULL;
3653 }
3654
3655 struct list *bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp,
3656 uint32_t logical_net_id,
3657 uint32_t label)
3658 {
3659 struct rfapi_l2_group_cfg *rfg;
3660 rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label);
3661 if (rfg) {
3662 return rfg->labels;
3663 }
3664 return NULL;
3665 }
3666
3667 struct ecommunity *
3668 bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import,
3669 uint32_t logical_net_id, uint32_t label)
3670 {
3671 struct rfapi_l2_group_cfg *rfg;
3672 rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label);
3673 if (rfg) {
3674 if (is_import)
3675 return rfg->rt_import_list;
3676 else
3677 return rfg->rt_export_list;
3678 }
3679 return NULL;
3680 }
3681
3682 void bgp_rfapi_cfg_init(void)
3683 {
3684 install_node(&bgp_vnc_defaults_node);
3685 install_node(&bgp_vnc_nve_group_node);
3686 install_node(&bgp_vrf_policy_node);
3687 install_node(&bgp_vnc_l2_group_node);
3688 install_default(BGP_VRF_POLICY_NODE);
3689 install_default(BGP_VNC_DEFAULTS_NODE);
3690 install_default(BGP_VNC_NVE_GROUP_NODE);
3691 install_default(BGP_VNC_L2_GROUP_NODE);
3692
3693 /*
3694 * Add commands
3695 */
3696 install_element(BGP_NODE, &vnc_defaults_cmd);
3697 install_element(BGP_NODE, &vnc_nve_group_cmd);
3698 install_element(BGP_NODE, &vnc_no_nve_group_cmd);
3699 install_element(BGP_NODE, &vnc_vrf_policy_cmd);
3700 install_element(BGP_NODE, &vnc_no_vrf_policy_cmd);
3701 install_element(BGP_NODE, &vnc_l2_group_cmd);
3702 install_element(BGP_NODE, &vnc_no_l2_group_cmd);
3703 install_element(BGP_NODE, &vnc_advertise_un_method_cmd);
3704 install_element(BGP_NODE, &vnc_export_mode_cmd);
3705
3706 install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_import_cmd);
3707 install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_export_cmd);
3708 install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_both_cmd);
3709 install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rd_cmd);
3710 install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_l2rd_cmd);
3711 install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_no_l2rd_cmd);
3712 install_element(BGP_VNC_DEFAULTS_NODE,
3713 &vnc_defaults_responselifetime_cmd);
3714 install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_cmd);
3715
3716 install_element(BGP_NODE, &vnc_redistribute_protocol_cmd);
3717 install_element(BGP_NODE, &vnc_no_redistribute_protocol_cmd);
3718 install_element(BGP_NODE, &vnc_redistribute_nvegroup_cmd);
3719 install_element(BGP_NODE, &vnc_redistribute_no_nvegroup_cmd);
3720 install_element(BGP_NODE, &vnc_redistribute_lifetime_cmd);
3721 install_element(BGP_NODE, &vnc_redistribute_rh_roo_localadmin_cmd);
3722 install_element(BGP_NODE, &vnc_redistribute_mode_cmd);
3723 install_element(BGP_NODE, &vnc_redistribute_bgp_exterior_cmd);
3724
3725 install_element(BGP_NODE, &vnc_redist_bgpdirect_no_prefixlist_cmd);
3726 install_element(BGP_NODE, &vnc_redist_bgpdirect_prefixlist_cmd);
3727 install_element(BGP_NODE, &vnc_redist_bgpdirect_no_routemap_cmd);
3728 install_element(BGP_NODE, &vnc_redist_bgpdirect_routemap_cmd);
3729
3730 install_element(BGP_VNC_NVE_GROUP_NODE,
3731 &vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd);
3732 install_element(BGP_VNC_NVE_GROUP_NODE,
3733 &vnc_nve_group_redist_bgpdirect_prefixlist_cmd);
3734 install_element(BGP_VNC_NVE_GROUP_NODE,
3735 &vnc_nve_group_redist_bgpdirect_no_routemap_cmd);
3736 install_element(BGP_VNC_NVE_GROUP_NODE,
3737 &vnc_nve_group_redist_bgpdirect_routemap_cmd);
3738
3739 install_element(BGP_NODE, &vnc_export_nvegroup_cmd);
3740 install_element(BGP_NODE, &vnc_no_export_nvegroup_cmd);
3741 install_element(BGP_NODE, &vnc_nve_export_prefixlist_cmd);
3742 install_element(BGP_NODE, &vnc_nve_export_routemap_cmd);
3743 install_element(BGP_NODE, &vnc_nve_export_no_prefixlist_cmd);
3744 install_element(BGP_NODE, &vnc_nve_export_no_routemap_cmd);
3745
3746 install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_l2rd_cmd);
3747 install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_no_l2rd_cmd);
3748 install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_prefix_cmd);
3749 install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_import_cmd);
3750 install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_export_cmd);
3751 install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_both_cmd);
3752 install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rd_cmd);
3753 install_element(BGP_VNC_NVE_GROUP_NODE,
3754 &vnc_nve_group_responselifetime_cmd);
3755 install_element(BGP_VNC_NVE_GROUP_NODE,
3756 &vnc_nve_group_export_prefixlist_cmd);
3757 install_element(BGP_VNC_NVE_GROUP_NODE,
3758 &vnc_nve_group_export_routemap_cmd);
3759 install_element(BGP_VNC_NVE_GROUP_NODE,
3760 &vnc_nve_group_export_no_prefixlist_cmd);
3761 install_element(BGP_VNC_NVE_GROUP_NODE,
3762 &vnc_nve_group_export_no_routemap_cmd);
3763 install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_cmd);
3764
3765 install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_label_cmd);
3766 install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_no_label_cmd);
3767 // Reenable to support VRF controller use case and testing
3768 install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_nexthop_cmd);
3769 install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_import_cmd);
3770 install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_export_cmd);
3771 install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_both_cmd);
3772 install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rd_cmd);
3773 install_element(BGP_VRF_POLICY_NODE,
3774 &vnc_vrf_policy_export_prefixlist_cmd);
3775 install_element(BGP_VRF_POLICY_NODE,
3776 &vnc_vrf_policy_export_routemap_cmd);
3777 install_element(BGP_VRF_POLICY_NODE,
3778 &vnc_vrf_policy_export_no_prefixlist_cmd);
3779 install_element(BGP_VRF_POLICY_NODE,
3780 &vnc_vrf_policy_export_no_routemap_cmd);
3781 install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd);
3782
3783 install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_lni_cmd);
3784 install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_labels_cmd);
3785 install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_no_labels_cmd);
3786 install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_rt_cmd);
3787 install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_cmd);
3788 }
3789
3790 struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
3791 {
3792 struct rfapi_cfg *h;
3793 afi_t afi;
3794
3795 h = XCALLOC(MTYPE_RFAPI_CFG, sizeof(struct rfapi_cfg));
3796 assert(h);
3797
3798 h->nve_groups_sequential = list_new();
3799 assert(h->nve_groups_sequential);
3800 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3801 h->nve_groups_vn[afi] = agg_table_init();
3802 h->nve_groups_un[afi] = agg_table_init();
3803 }
3804 h->default_response_lifetime =
3805 BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;
3806 h->rfg_export_direct_bgp_l = list_new();
3807 h->rfg_export_zebra_l = list_new();
3808 h->resolve_nve_roo_local_admin =
3809 BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT;
3810
3811 SET_FLAG(h->flags, BGP_VNC_CONFIG_FLAGS_DEFAULT);
3812
3813 if (cfg == NULL) {
3814 h->rfp_cfg.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL;
3815 h->rfp_cfg.ftd_advertisement_interval =
3816 RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL;
3817 h->rfp_cfg.holddown_factor =
3818 RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR;
3819 h->rfp_cfg.use_updated_response = 0;
3820 h->rfp_cfg.use_removes = 0;
3821 } else {
3822 h->rfp_cfg.download_type = cfg->download_type;
3823 h->rfp_cfg.ftd_advertisement_interval =
3824 cfg->ftd_advertisement_interval;
3825 h->rfp_cfg.holddown_factor = cfg->holddown_factor;
3826 h->rfp_cfg.use_updated_response = cfg->use_updated_response;
3827 h->rfp_cfg.use_removes = cfg->use_removes;
3828 if (cfg->use_updated_response)
3829 h->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE;
3830 else
3831 h->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE;
3832 if (cfg->use_removes)
3833 h->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;
3834 else
3835 h->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;
3836 }
3837 return h;
3838 }
3839
3840 static void bgp_rfapi_rfgn_list_delete(void *data)
3841 {
3842 struct rfapi_rfg_name *rfgn = data;
3843 free(rfgn->name);
3844 rfgn_free(rfgn);
3845 }
3846
3847 void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
3848 {
3849 afi_t afi;
3850 if (h == NULL)
3851 return;
3852
3853 bgp_rfapi_delete_named_nve_group(NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX);
3854 bgp_rfapi_delete_named_l2_group(NULL, bgp, NULL);
3855 if (h->l2_groups != NULL)
3856 list_delete(&h->l2_groups);
3857 list_delete(&h->nve_groups_sequential);
3858
3859 h->rfg_export_direct_bgp_l->del = bgp_rfapi_rfgn_list_delete;
3860 list_delete(&h->rfg_export_direct_bgp_l);
3861
3862 h->rfg_export_zebra_l->del = bgp_rfapi_rfgn_list_delete;
3863 list_delete(&h->rfg_export_zebra_l);
3864
3865 if (h->default_rt_export_list)
3866 ecommunity_free(&h->default_rt_export_list);
3867 if (h->default_rt_import_list)
3868 ecommunity_free(&h->default_rt_import_list);
3869 XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg);
3870 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3871 agg_table_finish(h->nve_groups_vn[afi]);
3872 agg_table_finish(h->nve_groups_un[afi]);
3873 }
3874 XFREE(MTYPE_RFAPI_CFG, h);
3875 }
3876
3877 int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
3878 {
3879 struct listnode *node, *nnode;
3880 struct rfapi_nve_group_cfg *rfg;
3881 struct rfapi_cfg *hc = bgp->rfapi_cfg;
3882 struct rfapi_rfg_name *rfgn;
3883 int write = 0;
3884 afi_t afi;
3885 int type;
3886 if (bgp->rfapi == NULL || hc == NULL)
3887 return write;
3888
3889 vty_out(vty, "!\n");
3890 for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg))
3891 if (rfg->type == RFAPI_GROUP_CFG_VRF) {
3892 ++write;
3893 vty_out(vty, " vrf-policy %s\n", rfg->name);
3894 if (rfg->label <= MPLS_LABEL_MAX) {
3895 vty_out(vty, " label %u\n", rfg->label);
3896 }
3897 if (CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) {
3898 vty_out(vty, " nexthop self\n");
3899
3900 } else {
3901 if (rfg->vn_prefix.family) {
3902 char buf[BUFSIZ];
3903 buf[0] = buf[BUFSIZ - 1] = 0;
3904 inet_ntop(rfg->vn_prefix.family,
3905 &rfg->vn_prefix.u.prefix, buf,
3906 sizeof(buf));
3907 if (!buf[0] || buf[BUFSIZ - 1]) {
3908 // vty_out (vty, "nexthop
3909 // self\n");
3910 } else {
3911 vty_out(vty, " nexthop %s\n",
3912 buf);
3913 }
3914 }
3915 }
3916
3917 if (rfg->rd.prefixlen) {
3918 if (AF_UNIX == rfg->rd.family) {
3919
3920 uint16_t value = 0;
3921
3922 value = ((rfg->rd.val[6] << 8)
3923 & 0x0ff00)
3924 | (rfg->rd.val[7] & 0x0ff);
3925
3926 vty_out(vty, " rd auto:nh:%d\n",
3927 value);
3928
3929 } else
3930 vty_out(vty, " rd %pRDP\n", &rfg->rd);
3931 }
3932
3933 if (rfg->rt_import_list && rfg->rt_export_list
3934 && ecommunity_cmp(rfg->rt_import_list,
3935 rfg->rt_export_list)) {
3936 char *b = ecommunity_ecom2str(
3937 rfg->rt_import_list,
3938 ECOMMUNITY_FORMAT_ROUTE_MAP,
3939 ECOMMUNITY_ROUTE_TARGET);
3940 vty_out(vty, " rt both %s\n", b);
3941 XFREE(MTYPE_ECOMMUNITY_STR, b);
3942 } else {
3943 if (rfg->rt_import_list) {
3944 char *b = ecommunity_ecom2str(
3945 rfg->rt_import_list,
3946 ECOMMUNITY_FORMAT_ROUTE_MAP,
3947 ECOMMUNITY_ROUTE_TARGET);
3948 vty_out(vty, " rt import %s\n", b);
3949 XFREE(MTYPE_ECOMMUNITY_STR, b);
3950 }
3951 if (rfg->rt_export_list) {
3952 char *b = ecommunity_ecom2str(
3953 rfg->rt_export_list,
3954 ECOMMUNITY_FORMAT_ROUTE_MAP,
3955 ECOMMUNITY_ROUTE_TARGET);
3956 vty_out(vty, " rt export %s\n", b);
3957 XFREE(MTYPE_ECOMMUNITY_STR, b);
3958 }
3959 }
3960
3961 /*
3962 * route filtering: prefix-lists and route-maps
3963 */
3964 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
3965
3966 const char *afistr =
3967 (afi == AFI_IP) ? "ipv4" : "ipv6";
3968
3969 if (rfg->plist_export_bgp_name[afi]) {
3970 vty_out(vty,
3971 " export %s%s prefix-list %s\n",
3972 (rfg->type == RFAPI_GROUP_CFG_VRF
3973 ? ""
3974 : "bgp "),
3975 afistr,
3976 rfg->plist_export_bgp_name
3977 [afi]);
3978 }
3979 if (rfg->plist_export_zebra_name[afi]) {
3980 vty_out(vty,
3981 " export %s%s prefix-list %s\n",
3982 (rfg->type == RFAPI_GROUP_CFG_VRF
3983 ? ""
3984 : "zebra "),
3985 afistr,
3986 rfg->plist_export_zebra_name
3987 [afi]);
3988 }
3989 /*
3990 * currently we only support redist plists for
3991 * bgp-direct.
3992 * If we later add plist support for
3993 * redistributing other
3994 * protocols, we'll need to loop over protocols
3995 * here
3996 */
3997 if (rfg->plist_redist_name
3998 [ZEBRA_ROUTE_BGP_DIRECT][afi]) {
3999 vty_out(vty,
4000 " redistribute bgp-direct %s prefix-list %s\n",
4001 afistr,
4002 rfg->plist_redist_name
4003 [ZEBRA_ROUTE_BGP_DIRECT]
4004 [afi]);
4005 }
4006 if (rfg->plist_redist_name
4007 [ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) {
4008 vty_out(vty,
4009 " redistribute bgp-direct-to-nve-groups %s prefix-list %s\n",
4010 afistr,
4011 rfg->plist_redist_name
4012 [ZEBRA_ROUTE_BGP_DIRECT_EXT]
4013 [afi]);
4014 }
4015 }
4016
4017 if (rfg->routemap_export_bgp_name) {
4018 vty_out(vty, " export %sroute-map %s\n",
4019 (rfg->type == RFAPI_GROUP_CFG_VRF
4020 ? ""
4021 : "bgp "),
4022 rfg->routemap_export_bgp_name);
4023 }
4024 if (rfg->routemap_export_zebra_name) {
4025 vty_out(vty, " export %sroute-map %s\n",
4026 (rfg->type == RFAPI_GROUP_CFG_VRF
4027 ? ""
4028 : "zebra "),
4029 rfg->routemap_export_zebra_name);
4030 }
4031 if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) {
4032 vty_out(vty,
4033 " redistribute bgp-direct route-map %s\n",
4034 rfg->routemap_redist_name
4035 [ZEBRA_ROUTE_BGP_DIRECT]);
4036 }
4037 if (rfg->routemap_redist_name
4038 [ZEBRA_ROUTE_BGP_DIRECT_EXT]) {
4039 vty_out(vty,
4040 " redistribute bgp-direct-to-nve-groups route-map %s\n",
4041 rfg->routemap_redist_name
4042 [ZEBRA_ROUTE_BGP_DIRECT_EXT]);
4043 }
4044 vty_out(vty, " exit-vrf-policy\n");
4045 vty_out(vty, "!\n");
4046 }
4047 if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) {
4048 vty_out(vty, " vnc advertise-un-method encap-safi\n");
4049 write++;
4050 }
4051
4052 { /* was based on listen ports */
4053 /* for now allow both old and new */
4054 if (bgp->rfapi->rfp_methods.cfg_cb)
4055 write += (bgp->rfapi->rfp_methods.cfg_cb)(
4056 vty, bgp->rfapi->rfp);
4057
4058 if (write)
4059 vty_out(vty, "!\n");
4060
4061 if (hc->l2_groups) {
4062 struct rfapi_l2_group_cfg *rfgc = NULL;
4063 struct listnode *gnode;
4064 for (ALL_LIST_ELEMENTS_RO(hc->l2_groups, gnode, rfgc)) {
4065 struct listnode *lnode;
4066 void *data;
4067 ++write;
4068 vty_out(vty, " vnc l2-group %s\n", rfgc->name);
4069 if (rfgc->logical_net_id != 0)
4070 vty_out(vty,
4071 " logical-network-id %u\n",
4072 rfgc->logical_net_id);
4073 if (rfgc->labels != NULL
4074 && listhead(rfgc->labels) != NULL) {
4075 vty_out(vty, " labels ");
4076 for (ALL_LIST_ELEMENTS_RO(rfgc->labels,
4077 lnode,
4078 data)) {
4079 vty_out(vty, "%hu ",
4080 (uint16_t)(
4081 (uintptr_t)
4082 data));
4083 }
4084 vty_out(vty, "\n");
4085 }
4086
4087 if (rfgc->rt_import_list && rfgc->rt_export_list
4088 && ecommunity_cmp(rfgc->rt_import_list,
4089 rfgc->rt_export_list)) {
4090 char *b = ecommunity_ecom2str(
4091 rfgc->rt_import_list,
4092 ECOMMUNITY_FORMAT_ROUTE_MAP,
4093 ECOMMUNITY_ROUTE_TARGET);
4094 vty_out(vty, " rt both %s\n", b);
4095 XFREE(MTYPE_ECOMMUNITY_STR, b);
4096 } else {
4097 if (rfgc->rt_import_list) {
4098 char *b = ecommunity_ecom2str(
4099 rfgc->rt_import_list,
4100 ECOMMUNITY_FORMAT_ROUTE_MAP,
4101 ECOMMUNITY_ROUTE_TARGET);
4102 vty_out(vty, " rt import %s\n",
4103 b);
4104 XFREE(MTYPE_ECOMMUNITY_STR, b);
4105 }
4106 if (rfgc->rt_export_list) {
4107 char *b = ecommunity_ecom2str(
4108 rfgc->rt_export_list,
4109 ECOMMUNITY_FORMAT_ROUTE_MAP,
4110 ECOMMUNITY_ROUTE_TARGET);
4111 vty_out(vty, " rt export %s\n",
4112 b);
4113 XFREE(MTYPE_ECOMMUNITY_STR, b);
4114 }
4115 }
4116 if (bgp->rfapi->rfp_methods.cfg_group_cb)
4117 write += (bgp->rfapi->rfp_methods
4118 .cfg_group_cb)(
4119 vty, bgp->rfapi->rfp,
4120 RFAPI_RFP_CFG_GROUP_L2,
4121 rfgc->name, rfgc->rfp_cfg);
4122 vty_out(vty, " exit-vnc\n");
4123 vty_out(vty, "!\n");
4124 }
4125 }
4126
4127 if (hc->default_rd.prefixlen
4128 || hc->default_response_lifetime
4129 != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT
4130 || hc->default_rt_import_list || hc->default_rt_export_list
4131 || hc->nve_groups_sequential->count) {
4132
4133
4134 ++write;
4135 vty_out(vty, " vnc defaults\n");
4136
4137 if (hc->default_rd.prefixlen) {
4138 if (AF_UNIX == hc->default_rd.family) {
4139 uint16_t value = 0;
4140
4141 value = ((hc->default_rd.val[6] << 8)
4142 & 0x0ff00)
4143 | (hc->default_rd.val[7]
4144 & 0x0ff);
4145
4146 vty_out(vty, " rd auto:vn:%d\n",
4147 value);
4148
4149 } else
4150 vty_out(vty, " rd %pRDP\n",
4151 &hc->default_rd);
4152 }
4153 if (hc->default_response_lifetime
4154 != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT) {
4155 vty_out(vty, " response-lifetime ");
4156 if (hc->default_response_lifetime != UINT32_MAX)
4157 vty_out(vty, "%d",
4158 hc->default_response_lifetime);
4159 else
4160 vty_out(vty, "infinite");
4161 vty_out(vty, "\n");
4162 }
4163 if (hc->default_rt_import_list
4164 && hc->default_rt_export_list
4165 && ecommunity_cmp(hc->default_rt_import_list,
4166 hc->default_rt_export_list)) {
4167 char *b = ecommunity_ecom2str(
4168 hc->default_rt_import_list,
4169 ECOMMUNITY_FORMAT_ROUTE_MAP,
4170 ECOMMUNITY_ROUTE_TARGET);
4171 vty_out(vty, " rt both %s\n", b);
4172 XFREE(MTYPE_ECOMMUNITY_STR, b);
4173 } else {
4174 if (hc->default_rt_import_list) {
4175 char *b = ecommunity_ecom2str(
4176 hc->default_rt_import_list,
4177 ECOMMUNITY_FORMAT_ROUTE_MAP,
4178 ECOMMUNITY_ROUTE_TARGET);
4179 vty_out(vty, " rt import %s\n", b);
4180 XFREE(MTYPE_ECOMMUNITY_STR, b);
4181 }
4182 if (hc->default_rt_export_list) {
4183 char *b = ecommunity_ecom2str(
4184 hc->default_rt_export_list,
4185 ECOMMUNITY_FORMAT_ROUTE_MAP,
4186 ECOMMUNITY_ROUTE_TARGET);
4187 vty_out(vty, " rt export %s\n", b);
4188 XFREE(MTYPE_ECOMMUNITY_STR, b);
4189 }
4190 }
4191 if (bgp->rfapi->rfp_methods.cfg_group_cb)
4192 write += (bgp->rfapi->rfp_methods.cfg_group_cb)(
4193 vty, bgp->rfapi->rfp,
4194 RFAPI_RFP_CFG_GROUP_DEFAULT, NULL,
4195 bgp->rfapi_cfg->default_rfp_cfg);
4196 vty_out(vty, " exit-vnc\n");
4197 vty_out(vty, "!\n");
4198 }
4199
4200 for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode,
4201 rfg))
4202 if (rfg->type == RFAPI_GROUP_CFG_NVE) {
4203 ++write;
4204 vty_out(vty, " vnc nve-group %s\n", rfg->name);
4205
4206 if (rfg->vn_prefix.family && rfg->vn_node)
4207 vty_out(vty, " prefix %s %pFX\n", "vn",
4208 &rfg->vn_prefix);
4209
4210 if (rfg->un_prefix.family && rfg->un_node)
4211 vty_out(vty, " prefix %s %pFX\n", "un",
4212 &rfg->un_prefix);
4213
4214
4215 if (rfg->rd.prefixlen) {
4216 if (AF_UNIX == rfg->rd.family) {
4217
4218 uint16_t value = 0;
4219
4220 value = ((rfg->rd.val[6] << 8)
4221 & 0x0ff00)
4222 | (rfg->rd.val[7]
4223 & 0x0ff);
4224
4225 vty_out(vty,
4226 " rd auto:vn:%d\n",
4227 value);
4228
4229 } else
4230 vty_out(vty, " rd %pRDP\n",
4231 &rfg->rd);
4232 }
4233 if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) {
4234 vty_out(vty, " response-lifetime ");
4235 if (rfg->response_lifetime
4236 != UINT32_MAX)
4237 vty_out(vty, "%d",
4238 rfg->response_lifetime);
4239 else
4240 vty_out(vty, "infinite");
4241 vty_out(vty, "\n");
4242 }
4243
4244 if (rfg->rt_import_list && rfg->rt_export_list
4245 && ecommunity_cmp(rfg->rt_import_list,
4246 rfg->rt_export_list)) {
4247 char *b = ecommunity_ecom2str(
4248 rfg->rt_import_list,
4249 ECOMMUNITY_FORMAT_ROUTE_MAP,
4250 ECOMMUNITY_ROUTE_TARGET);
4251 vty_out(vty, " rt both %s\n", b);
4252 XFREE(MTYPE_ECOMMUNITY_STR, b);
4253 } else {
4254 if (rfg->rt_import_list) {
4255 char *b = ecommunity_ecom2str(
4256 rfg->rt_import_list,
4257 ECOMMUNITY_FORMAT_ROUTE_MAP,
4258 ECOMMUNITY_ROUTE_TARGET);
4259 vty_out(vty, " rt import %s\n",
4260 b);
4261 XFREE(MTYPE_ECOMMUNITY_STR, b);
4262 }
4263 if (rfg->rt_export_list) {
4264 char *b = ecommunity_ecom2str(
4265 rfg->rt_export_list,
4266 ECOMMUNITY_FORMAT_ROUTE_MAP,
4267 ECOMMUNITY_ROUTE_TARGET);
4268 vty_out(vty, " rt export %s\n",
4269 b);
4270 XFREE(MTYPE_ECOMMUNITY_STR, b);
4271 }
4272 }
4273
4274 /*
4275 * route filtering: prefix-lists and route-maps
4276 */
4277 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4278
4279 const char *afistr = (afi == AFI_IP)
4280 ? "ipv4"
4281 : "ipv6";
4282
4283 if (rfg->plist_export_bgp_name[afi]) {
4284 vty_out(vty,
4285 " export bgp %s prefix-list %s\n",
4286 afistr,
4287 rfg->plist_export_bgp_name
4288 [afi]);
4289 }
4290 if (rfg->plist_export_zebra_name[afi]) {
4291 vty_out(vty,
4292 " export zebra %s prefix-list %s\n",
4293 afistr,
4294 rfg->plist_export_zebra_name
4295 [afi]);
4296 }
4297 /*
4298 * currently we only support redist
4299 * plists for bgp-direct.
4300 * If we later add plist support for
4301 * redistributing other
4302 * protocols, we'll need to loop over
4303 * protocols here
4304 */
4305 if (rfg->plist_redist_name
4306 [ZEBRA_ROUTE_BGP_DIRECT]
4307 [afi]) {
4308 vty_out(vty,
4309 " redistribute bgp-direct %s prefix-list %s\n",
4310 afistr,
4311 rfg->plist_redist_name
4312 [ZEBRA_ROUTE_BGP_DIRECT]
4313 [afi]);
4314 }
4315 if (rfg->plist_redist_name
4316 [ZEBRA_ROUTE_BGP_DIRECT_EXT]
4317 [afi]) {
4318 vty_out(vty,
4319 " redistribute bgp-direct-to-nve-groups %s prefix-list %s\n",
4320 afistr,
4321 rfg->plist_redist_name
4322 [ZEBRA_ROUTE_BGP_DIRECT_EXT]
4323 [afi]);
4324 }
4325 }
4326
4327 if (rfg->routemap_export_bgp_name) {
4328 vty_out(vty,
4329 " export bgp route-map %s\n",
4330 rfg->routemap_export_bgp_name);
4331 }
4332 if (rfg->routemap_export_zebra_name) {
4333 vty_out(vty,
4334 " export zebra route-map %s\n",
4335 rfg->routemap_export_zebra_name);
4336 }
4337 if (rfg->routemap_redist_name
4338 [ZEBRA_ROUTE_BGP_DIRECT]) {
4339 vty_out(vty,
4340 " redistribute bgp-direct route-map %s\n",
4341 rfg->routemap_redist_name
4342 [ZEBRA_ROUTE_BGP_DIRECT]);
4343 }
4344 if (rfg->routemap_redist_name
4345 [ZEBRA_ROUTE_BGP_DIRECT_EXT]) {
4346 vty_out(vty,
4347 " redistribute bgp-direct-to-nve-groups route-map %s\n",
4348 rfg->routemap_redist_name
4349 [ZEBRA_ROUTE_BGP_DIRECT_EXT]);
4350 }
4351 if (bgp->rfapi->rfp_methods.cfg_group_cb)
4352 write += (bgp->rfapi->rfp_methods
4353 .cfg_group_cb)(
4354 vty, bgp->rfapi->rfp,
4355 RFAPI_RFP_CFG_GROUP_NVE,
4356 rfg->name, rfg->rfp_cfg);
4357 vty_out(vty, " exit-vnc\n");
4358 vty_out(vty, "!\n");
4359 }
4360 } /* have listen ports */
4361
4362 /*
4363 * route export to other protocols
4364 */
4365 if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) {
4366 vty_out(vty, " vnc export bgp mode group-nve\n");
4367 } else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) {
4368 vty_out(vty, " vnc export bgp mode registering-nve\n");
4369 } else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) {
4370 vty_out(vty, " vnc export bgp mode ce\n");
4371 }
4372
4373 if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) {
4374 vty_out(vty, " vnc export zebra mode group-nve\n");
4375 } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) {
4376 vty_out(vty, " vnc export zebra mode registering-nve\n");
4377 }
4378
4379 if (hc->rfg_export_direct_bgp_l) {
4380 for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l, node, nnode,
4381 rfgn)) {
4382
4383 vty_out(vty, " vnc export bgp group-nve group %s\n",
4384 rfgn->name);
4385 }
4386 }
4387
4388 if (hc->rfg_export_zebra_l) {
4389 for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node, nnode,
4390 rfgn)) {
4391
4392 vty_out(vty, " vnc export zebra group-nve group %s\n",
4393 rfgn->name);
4394 }
4395 }
4396
4397
4398 if (hc->rfg_redist_name) {
4399 vty_out(vty, " vnc redistribute nve-group %s\n",
4400 hc->rfg_redist_name);
4401 }
4402 if (hc->redist_lifetime) {
4403 vty_out(vty, " vnc redistribute lifetime %d\n",
4404 hc->redist_lifetime);
4405 }
4406 if (hc->resolve_nve_roo_local_admin
4407 != BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT) {
4408
4409 vty_out(vty,
4410 " vnc redistribute resolve-nve roo-ec-local-admin %d\n",
4411 hc->resolve_nve_roo_local_admin);
4412 }
4413
4414 if (hc->redist_mode) /* ! default */
4415 {
4416 const char *s = "";
4417
4418 switch (hc->redist_mode) {
4419 case VNC_REDIST_MODE_PLAIN:
4420 s = "plain";
4421 break;
4422 case VNC_REDIST_MODE_RFG:
4423 s = "nve-group";
4424 break;
4425 case VNC_REDIST_MODE_RESOLVE_NVE:
4426 s = "resolve-nve";
4427 break;
4428 }
4429 if (s) {
4430 vty_out(vty, " vnc redistribute mode %s\n", s);
4431 }
4432 }
4433
4434 /*
4435 * route filtering: prefix-lists and route-maps
4436 */
4437 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4438
4439 const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6";
4440
4441 if (hc->plist_export_bgp_name[afi]) {
4442 vty_out(vty, " vnc export bgp %s prefix-list %s\n",
4443 afistr, hc->plist_export_bgp_name[afi]);
4444 }
4445 if (hc->plist_export_zebra_name[afi]) {
4446 vty_out(vty, " vnc export zebra %s prefix-list %s\n",
4447 afistr, hc->plist_export_zebra_name[afi]);
4448 }
4449 if (hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) {
4450 vty_out(vty,
4451 " vnc redistribute bgp-direct %s prefix-list %s\n",
4452 afistr,
4453 hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT]
4454 [afi]);
4455 }
4456 }
4457
4458 if (hc->routemap_export_bgp_name) {
4459 vty_out(vty, " vnc export bgp route-map %s\n",
4460 hc->routemap_export_bgp_name);
4461 }
4462 if (hc->routemap_export_zebra_name) {
4463 vty_out(vty, " vnc export zebra route-map %s\n",
4464 hc->routemap_export_zebra_name);
4465 }
4466 if (hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) {
4467 vty_out(vty, " vnc redistribute bgp-direct route-map %s\n",
4468 hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
4469 }
4470
4471 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4472 for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
4473 if (hc->redist[afi][type]) {
4474 if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT
4475 && hc->redist_bgp_exterior_view_name) {
4476 vty_out(vty,
4477 " vnc redistribute %s %s view %s\n",
4478 ((afi == AFI_IP) ? "ipv4"
4479 : "ipv6"),
4480 zebra_route_string(type),
4481 hc->redist_bgp_exterior_view_name);
4482 } else {
4483 vty_out(vty,
4484 " vnc redistribute %s %s\n",
4485 ((afi == AFI_IP) ? "ipv4"
4486 : "ipv6"),
4487 zebra_route_string(type));
4488 }
4489 }
4490 }
4491 }
4492 return write;
4493 }
4494
4495 void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty)
4496 {
4497 struct rfapi_cfg *hc = bgp->rfapi_cfg;
4498 afi_t afi;
4499 int type, redist = 0;
4500 char tmp[40];
4501 if (hc == NULL)
4502 return;
4503
4504 vty_out(vty, "%-39s %-19s %s\n", "VNC Advertise method:",
4505 (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
4506 ? "Encapsulation SAFI"
4507 : "Tunnel Encap attribute"),
4508 ((hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)
4509 == (BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
4510 & BGP_VNC_CONFIG_FLAGS_DEFAULT)
4511 ? "(default)"
4512 : ""));
4513 /* export */
4514 vty_out(vty, "%-39s ", "Export from VNC:");
4515 /*
4516 * route export to other protocols
4517 */
4518 if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) {
4519 redist++;
4520 vty_out(vty, "ToBGP Groups={");
4521 if (hc->rfg_export_direct_bgp_l) {
4522 int cnt = 0;
4523 struct listnode *node, *nnode;
4524 struct rfapi_rfg_name *rfgn;
4525 for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l,
4526 node, nnode, rfgn)) {
4527 if (cnt++ != 0)
4528 vty_out(vty, ",");
4529
4530 vty_out(vty, "%s", rfgn->name);
4531 }
4532 }
4533 vty_out(vty, "}");
4534 } else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) {
4535 redist++;
4536 vty_out(vty, "ToBGP {Registering NVE}");
4537 /* note filters, route-maps not shown */
4538 } else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) {
4539 redist++;
4540 vty_out(vty, "ToBGP {NVE connected router:%d}",
4541 hc->resolve_nve_roo_local_admin);
4542 /* note filters, route-maps not shown */
4543 }
4544
4545 if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) {
4546 redist++;
4547 vty_out(vty, "%sToZebra Groups={", (redist == 1 ? "" : " "));
4548 if (hc->rfg_export_zebra_l) {
4549 int cnt = 0;
4550 struct listnode *node, *nnode;
4551 struct rfapi_rfg_name *rfgn;
4552 for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node,
4553 nnode, rfgn)) {
4554 if (cnt++ != 0)
4555 vty_out(vty, ",");
4556 vty_out(vty, "%s", rfgn->name);
4557 }
4558 }
4559 vty_out(vty, "}");
4560 } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) {
4561 redist++;
4562 vty_out(vty, "%sToZebra {Registering NVE}",
4563 (redist == 1 ? "" : " "));
4564 /* note filters, route-maps not shown */
4565 }
4566 vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"),
4567 (redist ? "" : "(default)"));
4568
4569 /* Redistribution */
4570 redist = 0;
4571 vty_out(vty, "%-39s ", "Redistribution into VNC:");
4572 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4573 for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
4574 if (hc->redist[afi][type]) {
4575 vty_out(vty, "{%s,%s} ",
4576 ((afi == AFI_IP) ? "ipv4" : "ipv6"),
4577 zebra_route_string(type));
4578 redist++;
4579 }
4580 }
4581 }
4582 vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"),
4583 (redist ? "" : "(default)"));
4584
4585 vty_out(vty, "%-39s %3u%-16s %s\n",
4586 "RFP Registration Hold-Down Factor:",
4587 hc->rfp_cfg.holddown_factor, "%",
4588 (hc->rfp_cfg.holddown_factor
4589 == RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR
4590 ? "(default)"
4591 : ""));
4592 vty_out(vty, "%-39s %-19s %s\n", "RFP Updated responses:",
4593 (hc->rfp_cfg.use_updated_response == 0 ? "Off" : "On"),
4594 (hc->rfp_cfg.use_updated_response == 0 ? "(default)" : ""));
4595 vty_out(vty, "%-39s %-19s %s\n", "RFP Removal responses:",
4596 (hc->rfp_cfg.use_removes == 0 ? "Off" : "On"),
4597 (hc->rfp_cfg.use_removes == 0 ? "(default)" : ""));
4598 vty_out(vty, "%-39s %-19s %s\n", "RFP Full table download:",
4599 (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL ? "On"
4600 : "Off"),
4601 (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL
4602 ? "(default)"
4603 : ""));
4604 snprintf(tmp, sizeof(tmp), "%u seconds",
4605 hc->rfp_cfg.ftd_advertisement_interval);
4606 vty_out(vty, "%-39s %-19s %s\n", " Advertisement Interval:", tmp,
4607 (hc->rfp_cfg.ftd_advertisement_interval
4608 == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL
4609 ? "(default)"
4610 : ""));
4611 vty_out(vty, "%-39s %d seconds\n", "Default RFP response lifetime:",
4612 hc->default_response_lifetime);
4613 vty_out(vty, "\n");
4614 return;
4615 }
4616
4617 struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp)
4618 {
4619 struct rfapi_cfg *hc = NULL;
4620 if (bgp == NULL)
4621 bgp = bgp_get_default();
4622 if (bgp != NULL)
4623 hc = bgp->rfapi_cfg;
4624 return hc;
4625 }
4626
4627 #endif /* ENABLE_BGP_VNC */