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