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