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