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