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