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