3 * Copyright 2009-2016, LabN Consulting, L.L.C.
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.
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.
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
20 #include "lib/zebra.h"
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"
30 #include "bgpd/bgpd.h"
31 #include "bgpd/bgp_attr.h"
32 #include "bgpd/bgp_route.h"
33 #include "bgpd/bgp_mplsvpn.h"
35 #include "bgpd/bgp_vty.h"
36 #include "bgpd/bgp_ecommunity.h"
37 #include "bgpd/rfapi/rfapi.h"
38 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
39 #include "bgpd/rfapi/rfapi_backend.h"
40 #include "bgpd/rfapi/rfapi_import.h"
41 #include "bgpd/rfapi/rfapi_private.h"
42 #include "bgpd/rfapi/rfapi_monitor.h"
43 #include "bgpd/rfapi/vnc_zebra.h"
44 #include "bgpd/rfapi/vnc_export_bgp.h"
45 #include "bgpd/rfapi/vnc_export_bgp_p.h"
46 #include "bgpd/rfapi/rfapi_vty.h"
47 #include "bgpd/rfapi/vnc_import_bgp.h"
48 #include "bgpd/rfapi/vnc_debug.h"
52 #undef BGP_VNC_DEBUG_MATCH_GROUP
55 DEFINE_MGROUP(RFAPI
, "rfapi")
56 DEFINE_MTYPE(RFAPI
, RFAPI_CFG
, "NVE Configuration")
57 DEFINE_MTYPE(RFAPI
, RFAPI_GROUP_CFG
, "NVE Group Configuration")
58 DEFINE_MTYPE(RFAPI
, RFAPI_L2_CFG
, "RFAPI L2 Group Configuration")
59 DEFINE_MTYPE(RFAPI
, RFAPI_RFP_GROUP_CFG
, "RFAPI RFP Group Configuration")
60 DEFINE_MTYPE(RFAPI
, RFAPI
, "RFAPI Generic")
61 DEFINE_MTYPE(RFAPI
, RFAPI_DESC
, "RFAPI Descriptor")
62 DEFINE_MTYPE(RFAPI
, RFAPI_IMPORTTABLE
, "RFAPI Import Table")
63 DEFINE_MTYPE(RFAPI
, RFAPI_MONITOR
, "RFAPI Monitor VPN")
64 DEFINE_MTYPE(RFAPI
, RFAPI_MONITOR_ENCAP
, "RFAPI Monitor Encap")
65 DEFINE_MTYPE(RFAPI
, RFAPI_NEXTHOP
, "RFAPI Next Hop")
66 DEFINE_MTYPE(RFAPI
, RFAPI_VN_OPTION
, "RFAPI VN Option")
67 DEFINE_MTYPE(RFAPI
, RFAPI_UN_OPTION
, "RFAPI UN Option")
68 DEFINE_MTYPE(RFAPI
, RFAPI_WITHDRAW
, "RFAPI Withdraw")
69 DEFINE_MTYPE(RFAPI
, RFAPI_RFG_NAME
, "RFAPI RFGName")
70 DEFINE_MTYPE(RFAPI
, RFAPI_ADB
, "RFAPI Advertisement Data")
71 DEFINE_MTYPE(RFAPI
, RFAPI_ETI
, "RFAPI Export Table Info")
72 DEFINE_MTYPE(RFAPI
, RFAPI_NVE_ADDR
, "RFAPI NVE Address")
73 DEFINE_MTYPE(RFAPI
, RFAPI_PREFIX_BAG
, "RFAPI Prefix Bag")
74 DEFINE_MTYPE(RFAPI
, RFAPI_IT_EXTRA
, "RFAPI IT Extra")
75 DEFINE_MTYPE(RFAPI
, RFAPI_INFO
, "RFAPI Info")
76 DEFINE_MTYPE(RFAPI
, RFAPI_ADDR
, "RFAPI Addr")
77 DEFINE_MTYPE(RFAPI
, RFAPI_UPDATED_RESPONSE_QUEUE
, "RFAPI Updated Rsp Queue")
78 DEFINE_MTYPE(RFAPI
, RFAPI_RECENT_DELETE
, "RFAPI Recently Deleted Route")
79 DEFINE_MTYPE(RFAPI
, RFAPI_L2ADDR_OPT
, "RFAPI L2 Address Option")
80 DEFINE_MTYPE(RFAPI
, RFAPI_AP
, "RFAPI Advertised Prefix")
81 DEFINE_MTYPE(RFAPI
, RFAPI_MONITOR_ETH
, "RFAPI Monitor Ethernet")
83 DEFINE_QOBJ_TYPE(rfapi_nve_group_cfg
)
84 DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg
)
85 /***********************************************************************
87 ***********************************************************************/
91 * compaitibility to old quagga_time call
92 * time_t value in terms of stabilised absolute time.
93 * replacement for POSIX time()
95 time_t rfapi_time(time_t *t
)
97 time_t clock
= bgp_clock();
103 void nve_group_to_nve_list(struct rfapi_nve_group_cfg
*rfg
, struct list
**nves
,
104 uint8_t family
) /* AF_INET, AF_INET6 */
106 struct listnode
*hln
;
107 struct rfapi_descriptor
*rfd
;
110 * loop over nves in this grp, add to list
112 for (ALL_LIST_ELEMENTS_RO(rfg
->nves
, hln
, rfd
)) {
113 if (rfd
->vn_addr
.addr_family
== family
) {
116 listnode_add(*nves
, rfd
);
122 struct rfapi_nve_group_cfg
*bgp_rfapi_cfg_match_group(struct rfapi_cfg
*hc
,
126 struct rfapi_nve_group_cfg
*rfg_vn
= NULL
;
127 struct rfapi_nve_group_cfg
*rfg_un
= NULL
;
129 struct route_table
*rt_vn
;
130 struct route_table
*rt_un
;
131 struct route_node
*rn_vn
;
132 struct route_node
*rn_un
;
134 struct rfapi_nve_group_cfg
*rfg
;
135 struct listnode
*node
, *nnode
;
137 switch (vn
->family
) {
139 rt_vn
= hc
->nve_groups_vn
[AFI_IP
];
142 rt_vn
= hc
->nve_groups_vn
[AFI_IP6
];
148 switch (un
->family
) {
150 rt_un
= hc
->nve_groups_un
[AFI_IP
];
153 rt_un
= hc
->nve_groups_un
[AFI_IP6
];
159 rn_vn
= route_node_match(rt_vn
, vn
); /* NB locks node */
161 rfg_vn
= rn_vn
->info
;
162 route_unlock_node(rn_vn
);
165 rn_un
= route_node_match(rt_un
, un
); /* NB locks node */
167 rfg_un
= rn_un
->info
;
168 route_unlock_node(rn_un
);
171 #if BGP_VNC_DEBUG_MATCH_GROUP
173 char buf
[PREFIX_STRLEN
];
175 prefix2str(vn
, buf
, sizeof(buf
));
176 vnc_zlog_debug_verbose("%s: vn prefix: %s", __func__
, buf
);
178 prefix2str(un
, buf
, sizeof(buf
));
179 vnc_zlog_debug_verbose("%s: un prefix: %s", __func__
, buf
);
181 vnc_zlog_debug_verbose(
182 "%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p",
183 __func__
, rn_vn
, rn_un
, rfg_vn
, rfg_un
);
188 if (rfg_un
== rfg_vn
) /* same group */
190 if (!rfg_un
) /* un doesn't match, return vn-matched grp */
192 if (!rfg_vn
) /* vn doesn't match, return un-matched grp */
196 * Two different nve groups match: the group configured earlier wins.
197 * For now, just walk the sequential list and pick the first one.
198 * If this approach is too slow, then store serial numbers in the
199 * nve group structures as they are defined and just compare
202 for (ALL_LIST_ELEMENTS(hc
->nve_groups_sequential
, node
, nnode
, rfg
)) {
203 if ((rfg
== rfg_un
) || (rfg
== rfg_vn
)) {
207 vnc_zlog_debug_verbose(
208 "%s: shouldn't happen, returning NULL when un and vn match",
210 return NULL
; /* shouldn't happen */
213 /*------------------------------------------
214 * rfapi_get_rfp_start_val
216 * Returns value passed to rfapi on rfp_start
219 * void * bgp structure
223 *------------------------------------------*/
224 void *rfapi_get_rfp_start_val(void *bgpv
)
226 struct bgp
*bgp
= bgpv
;
227 if (bgp
== NULL
|| bgp
->rfapi
== NULL
)
229 return bgp
->rfapi
->rfp
;
232 /*------------------------------------------
233 * bgp_rfapi_is_vnc_configured
235 * Returns if VNC is configured
238 * bgp NULL (=use default instance)
242 * return value: If VNC is configured for the bgpd instance
244 * EPERM Not Default instance (VNC operations not allowed)
245 * ENXIO VNC not configured
246 --------------------------------------------*/
247 int bgp_rfapi_is_vnc_configured(struct bgp
*bgp
)
250 bgp
= bgp_get_default();
252 if (bgp
&& bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
)
255 if (bgp
&& bgp
->rfapi_cfg
)
260 /***********************************************************************
261 * VNC Configuration/CLI
262 ***********************************************************************/
263 #define VNC_VTY_CONFIG_CHECK(bgp) \
265 switch (bgp_rfapi_is_vnc_configured(bgp)) { \
268 "VNC operations only permitted on default BGP instance.\n"); \
269 return CMD_WARNING_CONFIG_FAILED; \
272 vty_out(vty, "VNC not configured.\n"); \
273 return CMD_WARNING_CONFIG_FAILED; \
280 DEFUN (vnc_advertise_un_method
,
281 vnc_advertise_un_method_cmd
,
282 "vnc advertise-un-method encap-attr",
284 "Method of advertising UN addresses\n"
285 "Via Tunnel Encap attribute (in VPN SAFI)\n")
287 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
288 VNC_VTY_CONFIG_CHECK(bgp
);
290 if (!strncmp(argv
[2]->arg
, "encap-safi", 7)) {
291 bgp
->rfapi_cfg
->flags
|= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
;
293 bgp
->rfapi_cfg
->flags
&= ~BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
;
299 /*-------------------------------------------------------------------------
301 *-----------------------------------------------------------------------*/
304 DEFUN_NOSH (vnc_defaults
,
306 "vnc defaults", VNC_CONFIG_STR
"Configure default NVE group\n")
308 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
309 VNC_VTY_CONFIG_CHECK(bgp
);
310 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
) {
311 vty_out(vty
, "Malformed community-list value\n");
312 return CMD_WARNING_CONFIG_FAILED
;
314 vty
->node
= BGP_VNC_DEFAULTS_NODE
;
318 static int set_ecom_list(struct vty
*vty
, int argc
, struct cmd_token
**argv
,
319 struct ecommunity
**list
)
321 struct ecommunity
*ecom
= NULL
;
322 struct ecommunity
*ecomadd
;
324 for (; argc
; --argc
, ++argv
) {
326 ecomadd
= ecommunity_str2com(argv
[0]->arg
,
327 ECOMMUNITY_ROUTE_TARGET
, 0);
329 vty_out(vty
, "Malformed community-list value\n");
331 ecommunity_free(&ecom
);
332 return CMD_WARNING_CONFIG_FAILED
;
336 ecommunity_merge(ecom
, ecomadd
);
337 ecommunity_free(&ecomadd
);
344 ecommunity_free(&*list
);
351 DEFUN (vnc_defaults_rt_import
,
352 vnc_defaults_rt_import_cmd
,
353 "rt import RTLIST...",
354 "Specify default route targets\n"
356 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
358 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
359 return set_ecom_list(vty
, argc
- 2, argv
+ 2,
360 &bgp
->rfapi_cfg
->default_rt_import_list
);
363 DEFUN (vnc_defaults_rt_export
,
364 vnc_defaults_rt_export_cmd
,
365 "rt export RTLIST...",
366 "Configure default route targets\n"
368 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
370 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
371 return set_ecom_list(vty
, argc
- 2, argv
+ 2,
372 &bgp
->rfapi_cfg
->default_rt_export_list
);
375 DEFUN (vnc_defaults_rt_both
,
376 vnc_defaults_rt_both_cmd
,
378 "Configure default route targets\n"
379 "Export+import filters\n"
380 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
382 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
385 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2,
386 &bgp
->rfapi_cfg
->default_rt_import_list
);
387 if (rc
!= CMD_SUCCESS
)
389 return set_ecom_list(vty
, argc
- 2, argv
+ 2,
390 &bgp
->rfapi_cfg
->default_rt_export_list
);
393 DEFUN (vnc_defaults_rd
,
395 "rd ASN:NN_OR_IP-ADDRESS:NN",
396 "Specify default route distinguisher\n"
397 "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
399 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
401 struct prefix_rd prd
;
403 if (!strncmp(argv
[1]->arg
, "auto:vn:", 8)) {
405 * use AF_UNIX to designate automatically-assigned RD
406 * auto:vn:nn where nn is a 2-octet quantity
409 uint32_t value32
= strtoul(argv
[1]->arg
+ 8, &end
, 10);
410 uint16_t value
= value32
& 0xffff;
412 if (!argv
[1]->arg
[8] || *end
) {
413 vty_out(vty
, "%% Malformed rd\n");
414 return CMD_WARNING_CONFIG_FAILED
;
416 if (value32
> 0xffff) {
417 vty_out(vty
, "%% Malformed rd (must be less than %u\n",
419 return CMD_WARNING_CONFIG_FAILED
;
422 memset(&prd
, 0, sizeof(prd
));
423 prd
.family
= AF_UNIX
;
425 prd
.val
[0] = (RD_TYPE_IP
>> 8) & 0x0ff;
426 prd
.val
[1] = RD_TYPE_IP
& 0x0ff;
427 prd
.val
[6] = (value
>> 8) & 0x0ff;
428 prd
.val
[7] = value
& 0x0ff;
432 ret
= str2prefix_rd(argv
[1]->arg
, &prd
);
434 vty_out(vty
, "%% Malformed rd\n");
435 return CMD_WARNING_CONFIG_FAILED
;
439 bgp
->rfapi_cfg
->default_rd
= prd
;
443 DEFUN (vnc_defaults_l2rd
,
444 vnc_defaults_l2rd_cmd
,
445 "l2rd <(1-255)|auto-vn>",
446 "Specify default Local Nve ID value to use in RD for L2 routes\n"
447 "Fixed value 1-255\n"
448 "use the low-order octet of the NVE's VN address\n")
450 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
453 if (strmatch(argv
[1]->text
, "auto-vn")) {
457 unsigned long value_l
= strtoul(argv
[1]->arg
, &end
, 10);
459 value
= value_l
& 0xff;
460 if (!argv
[1]->arg
[0] || *end
) {
461 vty_out(vty
, "%% Malformed l2 nve ID \"%s\"\n",
463 return CMD_WARNING_CONFIG_FAILED
;
465 if ((value_l
< 1) || (value_l
> 0xff)) {
467 "%% Malformed l2 nve id (must be greater than 0 and less than %u\n",
469 return CMD_WARNING_CONFIG_FAILED
;
472 bgp
->rfapi_cfg
->flags
|= BGP_VNC_CONFIG_L2RD
;
473 bgp
->rfapi_cfg
->default_l2rd
= value
;
478 DEFUN (vnc_defaults_no_l2rd
,
479 vnc_defaults_no_l2rd_cmd
,
482 "Specify default Local Nve ID value to use in RD for L2 routes\n")
484 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
486 bgp
->rfapi_cfg
->default_l2rd
= 0;
487 bgp
->rfapi_cfg
->flags
&= ~BGP_VNC_CONFIG_L2RD
;
492 DEFUN (vnc_defaults_responselifetime
,
493 vnc_defaults_responselifetime_cmd
,
494 "response-lifetime <LIFETIME|infinite>",
495 "Specify default response lifetime\n"
496 "Response lifetime in seconds\n" "Infinite response lifetime\n")
498 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
500 struct rfapi
*h
= NULL
;
501 struct listnode
*hdnode
;
502 struct rfapi_descriptor
*rfd
;
506 return CMD_WARNING_CONFIG_FAILED
;
508 if (strmatch(argv
[1]->text
, "infinite")) {
509 rspint
= RFAPI_INFINITE_LIFETIME
;
511 rspint
= strtoul(argv
[1]->arg
, NULL
, 10);
512 if (rspint
> INT32_MAX
)
513 rspint
= INT32_MAX
; /* is really an int, not an unsigned
517 bgp
->rfapi_cfg
->default_response_lifetime
= rspint
;
519 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, hdnode
, rfd
))
521 && !(rfd
->rfg
->flags
& RFAPI_RFG_RESPONSE_LIFETIME
))
522 rfd
->response_lifetime
= rfd
->rfg
->response_lifetime
=
528 struct rfapi_nve_group_cfg
*
529 bgp_rfapi_cfg_match_byname(struct bgp
*bgp
, const char *name
,
530 rfapi_group_cfg_type_t type
) /* _MAX = any */
532 struct rfapi_nve_group_cfg
*rfg
;
533 struct listnode
*node
, *nnode
;
535 for (ALL_LIST_ELEMENTS(bgp
->rfapi_cfg
->nve_groups_sequential
, node
,
537 if ((type
== RFAPI_GROUP_CFG_MAX
|| type
== rfg
->type
)
538 && !strcmp(rfg
->name
, name
))
544 static struct rfapi_nve_group_cfg
*
545 rfapi_group_new(struct bgp
*bgp
, rfapi_group_cfg_type_t type
, const char *name
)
547 struct rfapi_nve_group_cfg
*rfg
;
549 rfg
= XCALLOC(MTYPE_RFAPI_GROUP_CFG
,
550 sizeof(struct rfapi_nve_group_cfg
));
553 rfg
->name
= strdup(name
);
554 /* add to tail of list */
555 listnode_add(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
);
557 rfg
->label
= MPLS_LABEL_NONE
;
558 QOBJ_REG(rfg
, rfapi_nve_group_cfg
);
563 static struct rfapi_l2_group_cfg
*rfapi_l2_group_lookup_byname(struct bgp
*bgp
,
566 struct rfapi_l2_group_cfg
*rfg
;
567 struct listnode
*node
, *nnode
;
569 if (bgp
->rfapi_cfg
->l2_groups
== NULL
) /* not the best place for this */
570 bgp
->rfapi_cfg
->l2_groups
= list_new();
572 for (ALL_LIST_ELEMENTS(bgp
->rfapi_cfg
->l2_groups
, node
, nnode
, rfg
)) {
573 if (!strcmp(rfg
->name
, name
))
579 static struct rfapi_l2_group_cfg
*rfapi_l2_group_new()
581 struct rfapi_l2_group_cfg
*rfg
;
583 rfg
= XCALLOC(MTYPE_RFAPI_L2_CFG
, sizeof(struct rfapi_l2_group_cfg
));
584 QOBJ_REG(rfg
, rfapi_l2_group_cfg
);
589 static void rfapi_l2_group_del(struct rfapi_l2_group_cfg
*rfg
)
592 XFREE(MTYPE_RFAPI_L2_CFG
, rfg
);
595 static int rfapi_str2route_type(const char *l3str
, const char *pstr
, afi_t
*afi
,
601 if (!strcmp(l3str
, "ipv4")) {
604 if (!strcmp(l3str
, "ipv6"))
610 if (!strcmp(pstr
, "connected"))
611 *type
= ZEBRA_ROUTE_CONNECT
;
612 if (!strcmp(pstr
, "kernel"))
613 *type
= ZEBRA_ROUTE_KERNEL
;
614 if (!strcmp(pstr
, "static"))
615 *type
= ZEBRA_ROUTE_STATIC
;
616 if (!strcmp(pstr
, "bgp"))
617 *type
= ZEBRA_ROUTE_BGP
;
618 if (!strcmp(pstr
, "bgp-direct"))
619 *type
= ZEBRA_ROUTE_BGP_DIRECT
;
620 if (!strcmp(pstr
, "bgp-direct-to-nve-groups"))
621 *type
= ZEBRA_ROUTE_BGP_DIRECT_EXT
;
623 if (!strcmp(pstr
, "rip")) {
625 *type
= ZEBRA_ROUTE_RIP
;
627 *type
= ZEBRA_ROUTE_RIPNG
;
630 if (!strcmp(pstr
, "ripng")) {
633 *type
= ZEBRA_ROUTE_RIPNG
;
636 if (!strcmp(pstr
, "ospf")) {
638 *type
= ZEBRA_ROUTE_OSPF
;
640 *type
= ZEBRA_ROUTE_OSPF6
;
643 if (!strcmp(pstr
, "ospf6")) {
646 *type
= ZEBRA_ROUTE_OSPF6
;
652 /*-------------------------------------------------------------------------
654 *-----------------------------------------------------------------------*/
656 #define VNC_REDIST_ENABLE(bgp, afi, type) \
659 case ZEBRA_ROUTE_BGP_DIRECT: \
660 vnc_import_bgp_redist_enable((bgp), (afi)); \
662 case ZEBRA_ROUTE_BGP_DIRECT_EXT: \
663 vnc_import_bgp_exterior_redist_enable((bgp), (afi)); \
666 vnc_redistribute_set((bgp), (afi), (type)); \
671 #define VNC_REDIST_DISABLE(bgp, afi, type) \
674 case ZEBRA_ROUTE_BGP_DIRECT: \
675 vnc_import_bgp_redist_disable((bgp), (afi)); \
677 case ZEBRA_ROUTE_BGP_DIRECT_EXT: \
678 vnc_import_bgp_exterior_redist_disable((bgp), (afi)); \
681 vnc_redistribute_unset((bgp), (afi), (type)); \
686 static uint8_t redist_was_enabled
[AFI_MAX
][ZEBRA_ROUTE_MAX
];
688 static void vnc_redistribute_prechange(struct bgp
*bgp
)
693 vnc_zlog_debug_verbose("%s: entry", __func__
);
694 memset(redist_was_enabled
, 0, sizeof(redist_was_enabled
));
697 * Look to see if we have any redistribution enabled. If so, flush
698 * the corresponding routes and turn off redistribution temporarily.
699 * We need to do it because the RD's used for the redistributed
700 * routes depend on the nve group.
702 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
703 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; ++type
) {
704 if (bgp
->rfapi_cfg
->redist
[afi
][type
]) {
705 redist_was_enabled
[afi
][type
] = 1;
706 VNC_REDIST_DISABLE(bgp
, afi
, type
);
710 vnc_zlog_debug_verbose("%s: return", __func__
);
713 static void vnc_redistribute_postchange(struct bgp
*bgp
)
718 vnc_zlog_debug_verbose("%s: entry", __func__
);
720 * If we turned off redistribution above, turn it back on. Doing so
721 * will tell zebra to resend the routes to us
723 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
724 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; ++type
) {
725 if (redist_was_enabled
[afi
][type
]) {
726 VNC_REDIST_ENABLE(bgp
, afi
, type
);
730 vnc_zlog_debug_verbose("%s: return", __func__
);
733 DEFUN (vnc_redistribute_rh_roo_localadmin
,
734 vnc_redistribute_rh_roo_localadmin_cmd
,
735 "vnc redistribute resolve-nve roo-ec-local-admin (0-65535)",
737 "Redistribute routes into VNC\n"
739 "Route Origin Extended Community Local Admin Field\n" "Field value\n")
741 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
745 VNC_VTY_CONFIG_CHECK(bgp
);
747 localadmin
= strtoul(argv
[4]->arg
, &endptr
, 0);
748 if (!argv
[4]->arg
[0] || *endptr
) {
749 vty_out(vty
, "%% Malformed value\n");
750 return CMD_WARNING_CONFIG_FAILED
;
753 if (localadmin
> 0xffff) {
754 vty_out(vty
, "%% Value out of range (0-%d)\n", 0xffff);
755 return CMD_WARNING_CONFIG_FAILED
;
758 if (bgp
->rfapi_cfg
->resolve_nve_roo_local_admin
== localadmin
)
761 if ((bgp
->rfapi_cfg
->flags
& BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS
)
762 == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE
) {
764 vnc_export_bgp_prechange(bgp
);
766 vnc_redistribute_prechange(bgp
);
768 bgp
->rfapi_cfg
->resolve_nve_roo_local_admin
= localadmin
;
770 if ((bgp
->rfapi_cfg
->flags
& BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS
)
771 == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE
) {
773 vnc_export_bgp_postchange(bgp
);
775 vnc_redistribute_postchange(bgp
);
781 DEFUN (vnc_redistribute_mode
,
782 vnc_redistribute_mode_cmd
,
783 "vnc redistribute mode <nve-group|plain|resolve-nve>",
785 "Redistribute routes into VNC\n"
786 "Redistribution mode\n"
787 "Based on redistribute nve-group\n"
788 "Unmodified\n" "Resolve each nexthop to connected NVEs\n")
790 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
791 vnc_redist_mode_t newmode
;
793 VNC_VTY_CONFIG_CHECK(bgp
);
795 switch (argv
[3]->arg
[0]) {
797 newmode
= VNC_REDIST_MODE_RFG
;
801 newmode
= VNC_REDIST_MODE_PLAIN
;
805 newmode
= VNC_REDIST_MODE_RESOLVE_NVE
;
809 vty_out(vty
, "unknown redistribute mode\n");
810 return CMD_WARNING_CONFIG_FAILED
;
813 if (newmode
!= bgp
->rfapi_cfg
->redist_mode
) {
814 vnc_redistribute_prechange(bgp
);
815 bgp
->rfapi_cfg
->redist_mode
= newmode
;
816 vnc_redistribute_postchange(bgp
);
822 DEFUN (vnc_redistribute_protocol
,
823 vnc_redistribute_protocol_cmd
,
824 "vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
826 "Redistribute routes into VNC\n"
830 "From BGP without Zebra\n"
831 "From BGP without Zebra, only to configured NVE groups\n"
832 "Connected interfaces\n"
833 "From kernel routes\n"
834 "From Open Shortest Path First (OSPF)\n"
835 "From Routing Information Protocol (RIP)\n" "From Static routes\n")
837 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
838 int type
= ZEBRA_ROUTE_MAX
; /* init to bogus value */
841 VNC_VTY_CONFIG_CHECK(bgp
);
843 if (rfapi_str2route_type(argv
[2]->arg
, argv
[3]->arg
, &afi
, &type
)) {
844 vty_out(vty
, "%% Invalid route type\n");
845 return CMD_WARNING_CONFIG_FAILED
;
848 if (type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
849 if (bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
) {
850 VNC_REDIST_DISABLE(bgp
, afi
,
851 type
); /* disabled view implicitly */
852 free(bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
);
853 bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
= NULL
;
855 bgp
->rfapi_cfg
->redist_bgp_exterior_view
= bgp
;
858 VNC_REDIST_ENABLE(bgp
, afi
, type
);
863 DEFUN (vnc_no_redistribute_protocol
,
864 vnc_no_redistribute_protocol_cmd
,
865 "no vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
868 "Redistribute from other protocol\n"
872 "From BGP without Zebra\n"
873 "From BGP without Zebra, only to configured NVE groups\n"
874 "Connected interfaces\n"
875 "From kernel routes\n"
876 "From Open Shortest Path First (OSPF)\n"
877 "From Routing Information Protocol (RIP)\n" "From Static routes\n")
879 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
883 VNC_VTY_CONFIG_CHECK(bgp
);
885 if (rfapi_str2route_type(argv
[3]->arg
, argv
[4]->arg
, &afi
, &type
)) {
886 vty_out(vty
, "%% Invalid route type\n");
887 return CMD_WARNING_CONFIG_FAILED
;
890 VNC_REDIST_DISABLE(bgp
, afi
, type
);
892 if (type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
893 if (bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
) {
894 free(bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
);
895 bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
= NULL
;
897 bgp
->rfapi_cfg
->redist_bgp_exterior_view
= NULL
;
903 DEFUN (vnc_redistribute_bgp_exterior
,
904 vnc_redistribute_bgp_exterior_cmd
,
905 "vnc redistribute <ipv4|ipv6> bgp-direct-to-nve-groups view NAME",
907 "Redistribute routes into VNC\n"
910 "From BGP without Zebra, only to configured NVE groups\n"
911 "From BGP view\n" "BGP view name\n")
913 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
917 VNC_VTY_CONFIG_CHECK(bgp
);
919 if (rfapi_str2route_type(argv
[2]->arg
, "bgp-direct-to-nve-groups", &afi
,
921 vty_out(vty
, "%% Invalid route type\n");
922 return CMD_WARNING_CONFIG_FAILED
;
925 if (bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
)
926 free(bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
);
927 bgp
->rfapi_cfg
->redist_bgp_exterior_view_name
= strdup(argv
[5]->arg
);
928 /* could be NULL if name is not defined yet */
929 bgp
->rfapi_cfg
->redist_bgp_exterior_view
=
930 bgp_lookup_by_name(argv
[5]->arg
);
932 VNC_REDIST_ENABLE(bgp
, afi
, type
);
937 DEFUN (vnc_redistribute_nvegroup
,
938 vnc_redistribute_nvegroup_cmd
,
939 "vnc redistribute nve-group NAME",
941 "Assign a NVE group to routes redistributed from another routing protocol\n"
942 "NVE group\n" "Group name\n")
944 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
945 VNC_VTY_CONFIG_CHECK(bgp
);
947 vnc_redistribute_prechange(bgp
);
950 * OK if nve group doesn't exist yet; we'll set the pointer
951 * when the group is defined later
953 bgp
->rfapi_cfg
->rfg_redist
= bgp_rfapi_cfg_match_byname(
954 bgp
, argv
[3]->arg
, RFAPI_GROUP_CFG_NVE
);
955 if (bgp
->rfapi_cfg
->rfg_redist_name
)
956 free(bgp
->rfapi_cfg
->rfg_redist_name
);
957 bgp
->rfapi_cfg
->rfg_redist_name
= strdup(argv
[3]->arg
);
959 vnc_redistribute_postchange(bgp
);
964 DEFUN (vnc_redistribute_no_nvegroup
,
965 vnc_redistribute_no_nvegroup_cmd
,
966 "no vnc redistribute nve-group",
969 "Redistribute from other protocol\n"
970 "Assign a NVE group to routes redistributed from another routing protocol\n")
972 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
974 VNC_VTY_CONFIG_CHECK(bgp
);
976 vnc_redistribute_prechange(bgp
);
978 bgp
->rfapi_cfg
->rfg_redist
= NULL
;
979 if (bgp
->rfapi_cfg
->rfg_redist_name
)
980 free(bgp
->rfapi_cfg
->rfg_redist_name
);
981 bgp
->rfapi_cfg
->rfg_redist_name
= NULL
;
983 vnc_redistribute_postchange(bgp
);
989 DEFUN (vnc_redistribute_lifetime
,
990 vnc_redistribute_lifetime_cmd
,
991 "vnc redistribute lifetime <LIFETIME|infinite>",
994 "Assign a lifetime to routes redistributed from another routing protocol\n"
995 "lifetime value (32 bit)\n"
996 "Allow lifetime to never expire\n")
998 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
999 VNC_VTY_CONFIG_CHECK(bgp
);
1001 vnc_redistribute_prechange(bgp
);
1003 if (strmatch(argv
[3]->text
, "infinite")) {
1004 bgp
->rfapi_cfg
->redist_lifetime
= RFAPI_INFINITE_LIFETIME
;
1006 bgp
->rfapi_cfg
->redist_lifetime
=
1007 strtoul(argv
[3]->arg
, NULL
, 10);
1010 vnc_redistribute_postchange(bgp
);
1015 /*-- redist policy, non-nvegroup start --*/
1017 DEFUN (vnc_redist_bgpdirect_no_prefixlist
,
1018 vnc_redist_bgpdirect_no_prefixlist_cmd
,
1019 "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list",
1022 "Redistribute from other protocol\n"
1023 "Redistribute from BGP directly\n"
1024 "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1026 "IPv6 routes\n" "Prefix-list for filtering redistributed routes\n")
1028 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1030 struct rfapi_cfg
*hc
;
1031 uint8_t route_type
= 0;
1033 VNC_VTY_CONFIG_CHECK(bgp
);
1034 hc
= bgp
->rfapi_cfg
;
1036 if (strmatch(argv
[3]->text
, "bgp-direct")) {
1037 route_type
= ZEBRA_ROUTE_BGP_DIRECT
;
1039 route_type
= ZEBRA_ROUTE_BGP_DIRECT_EXT
;
1042 if (strmatch(argv
[4]->text
, "ipv4")) {
1048 vnc_redistribute_prechange(bgp
);
1050 if (hc
->plist_redist_name
[route_type
][afi
])
1051 free(hc
->plist_redist_name
[route_type
][afi
]);
1052 hc
->plist_redist_name
[route_type
][afi
] = NULL
;
1053 hc
->plist_redist
[route_type
][afi
] = NULL
;
1055 vnc_redistribute_postchange(bgp
);
1060 DEFUN (vnc_redist_bgpdirect_prefixlist
,
1061 vnc_redist_bgpdirect_prefixlist_cmd
,
1062 "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list NAME",
1064 "Redistribute from other protocol\n"
1065 "Redistribute from BGP directly\n"
1066 "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1069 "Prefix-list for filtering redistributed routes\n"
1070 "prefix list name\n")
1072 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1073 struct rfapi_cfg
*hc
;
1075 uint8_t route_type
= 0;
1077 VNC_VTY_CONFIG_CHECK(bgp
);
1078 hc
= bgp
->rfapi_cfg
;
1080 if (strmatch(argv
[2]->text
, "bgp-direct")) {
1081 route_type
= ZEBRA_ROUTE_BGP_DIRECT
;
1083 route_type
= ZEBRA_ROUTE_BGP_DIRECT_EXT
;
1086 if (strmatch(argv
[3]->text
, "ipv4")) {
1092 vnc_redistribute_prechange(bgp
);
1094 if (hc
->plist_redist_name
[route_type
][afi
])
1095 free(hc
->plist_redist_name
[route_type
][afi
]);
1096 hc
->plist_redist_name
[route_type
][afi
] = strdup(argv
[5]->arg
);
1097 hc
->plist_redist
[route_type
][afi
] =
1098 prefix_list_lookup(afi
, argv
[5]->arg
);
1100 vnc_redistribute_postchange(bgp
);
1105 DEFUN (vnc_redist_bgpdirect_no_routemap
,
1106 vnc_redist_bgpdirect_no_routemap_cmd
,
1107 "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map",
1110 "Redistribute from other protocols\n"
1111 "Redistribute from BGP directly\n"
1112 "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1113 "Route-map for filtering redistributed routes\n")
1115 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1116 struct rfapi_cfg
*hc
;
1117 uint8_t route_type
= 0;
1119 VNC_VTY_CONFIG_CHECK(bgp
);
1120 hc
= bgp
->rfapi_cfg
;
1122 if (strmatch(argv
[3]->text
, "bgp-direct")) {
1123 route_type
= ZEBRA_ROUTE_BGP_DIRECT
;
1125 route_type
= ZEBRA_ROUTE_BGP_DIRECT_EXT
;
1128 vnc_redistribute_prechange(bgp
);
1130 if (hc
->routemap_redist_name
[route_type
])
1131 free(hc
->routemap_redist_name
[route_type
]);
1132 hc
->routemap_redist_name
[route_type
] = NULL
;
1133 hc
->routemap_redist
[route_type
] = NULL
;
1135 vnc_redistribute_postchange(bgp
);
1140 DEFUN (vnc_redist_bgpdirect_routemap
,
1141 vnc_redist_bgpdirect_routemap_cmd
,
1142 "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map NAME",
1144 "Redistribute from other protocols\n"
1145 "Redistribute from BGP directly\n"
1146 "Redistribute from BGP without Zebra, only to configured NVE groups\n"
1147 "Route-map for filtering exported routes\n" "route map name\n")
1149 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1150 struct rfapi_cfg
*hc
;
1151 uint8_t route_type
= 0;
1153 VNC_VTY_CONFIG_CHECK(bgp
);
1154 hc
= bgp
->rfapi_cfg
;
1156 if (strmatch(argv
[2]->text
, "bgp-direct")) {
1157 route_type
= ZEBRA_ROUTE_BGP_DIRECT
;
1159 route_type
= ZEBRA_ROUTE_BGP_DIRECT_EXT
;
1162 vnc_redistribute_prechange(bgp
);
1164 if (hc
->routemap_redist_name
[route_type
])
1165 free(hc
->routemap_redist_name
[route_type
]);
1166 hc
->routemap_redist_name
[route_type
] = strdup(argv
[4]->arg
);
1167 hc
->routemap_redist
[route_type
] =
1168 route_map_lookup_by_name(argv
[4]->arg
);
1170 vnc_redistribute_postchange(bgp
);
1175 /*-- redist policy, non-nvegroup end --*/
1177 /*-- redist policy, nvegroup start --*/
1179 DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist
,
1180 vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd
,
1181 "no redistribute bgp-direct <ipv4|ipv6> prefix-list",
1183 "Redistribute from other protocol\n"
1184 "Redistribute from BGP directly\n"
1187 "Prefix-list for filtering redistributed routes\n")
1189 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1190 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
)
1193 VNC_VTY_CONFIG_CHECK(bgp
);
1195 /* make sure it's still in list */
1196 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
1197 /* Not in list anymore */
1198 vty_out(vty
, "Current NVE group no longer exists\n");
1199 return CMD_WARNING_CONFIG_FAILED
;
1202 if (strmatch(argv
[3]->text
, "ipv4")) {
1208 vnc_redistribute_prechange(bgp
);
1210 if (rfg
->plist_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
1211 free(rfg
->plist_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
][afi
]);
1212 rfg
->plist_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
][afi
] = NULL
;
1213 rfg
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
] = NULL
;
1215 vnc_redistribute_postchange(bgp
);
1220 DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist
,
1221 vnc_nve_group_redist_bgpdirect_prefixlist_cmd
,
1222 "redistribute bgp-direct <ipv4|ipv6> prefix-list NAME",
1223 "Redistribute from other protocol\n"
1224 "Redistribute from BGP directly\n"
1227 "Prefix-list for filtering redistributed routes\n"
1228 "prefix list name\n")
1230 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1231 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
1234 VNC_VTY_CONFIG_CHECK(bgp
);
1236 /* make sure it's still in list */
1237 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
1238 /* Not in list anymore */
1239 vty_out(vty
, "Current NVE group no longer exists\n");
1240 return CMD_WARNING_CONFIG_FAILED
;
1243 if (strmatch(argv
[2]->text
, "ipv4")) {
1249 vnc_redistribute_prechange(bgp
);
1251 if (rfg
->plist_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
1252 free(rfg
->plist_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
][afi
]);
1253 rfg
->plist_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
][afi
] =
1254 strdup(argv
[4]->arg
);
1255 rfg
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
] =
1256 prefix_list_lookup(afi
, argv
[4]->arg
);
1258 vnc_redistribute_postchange(bgp
);
1263 DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap
,
1264 vnc_nve_group_redist_bgpdirect_no_routemap_cmd
,
1265 "no redistribute bgp-direct route-map",
1267 "Redistribute from other protocols\n"
1268 "Redistribute from BGP directly\n"
1269 "Route-map for filtering redistributed routes\n")
1271 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1272 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
1274 VNC_VTY_CONFIG_CHECK(bgp
);
1276 /* make sure it's still in list */
1277 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
1278 /* Not in list anymore */
1279 vty_out(vty
, "Current NVE group no longer exists\n");
1280 return CMD_WARNING_CONFIG_FAILED
;
1283 vnc_redistribute_prechange(bgp
);
1285 if (rfg
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
])
1286 free(rfg
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
]);
1287 rfg
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
] = NULL
;
1288 rfg
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
] = NULL
;
1290 vnc_redistribute_postchange(bgp
);
1295 DEFUN (vnc_nve_group_redist_bgpdirect_routemap
,
1296 vnc_nve_group_redist_bgpdirect_routemap_cmd
,
1297 "redistribute bgp-direct route-map NAME",
1298 "Redistribute from other protocols\n"
1299 "Redistribute from BGP directly\n"
1300 "Route-map for filtering exported routes\n" "route map name\n")
1302 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1303 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
1305 VNC_VTY_CONFIG_CHECK(bgp
);
1307 /* make sure it's still in list */
1308 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
1309 /* Not in list anymore */
1310 vty_out(vty
, "Current NVE group no longer exists\n");
1311 return CMD_WARNING_CONFIG_FAILED
;
1314 vnc_redistribute_prechange(bgp
);
1316 if (rfg
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
])
1317 free(rfg
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
]);
1318 rfg
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
] =
1319 strdup(argv
[3]->arg
);
1320 rfg
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
] =
1321 route_map_lookup_by_name(argv
[3]->arg
);
1323 vnc_redistribute_postchange(bgp
);
1328 /*-- redist policy, nvegroup end --*/
1330 /*-------------------------------------------------------------------------
1332 *-----------------------------------------------------------------------*/
1334 DEFUN (vnc_export_mode
,
1335 vnc_export_mode_cmd
,
1336 "vnc export <bgp|zebra> mode <group-nve|ce|none|registering-nve>",
1338 "Export to other protocols\n"
1340 "Export to Zebra (experimental)\n"
1341 "Select export mode\n"
1342 "Export routes with nve-group next-hops\n"
1343 "Export routes with NVE connected router next-hops\n"
1344 "Disable export\n" "Export routes with registering NVE as next-hop\n")
1346 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1347 uint32_t oldmode
= 0;
1348 uint32_t newmode
= 0;
1350 VNC_VTY_CONFIG_CHECK(bgp
);
1352 if (argv
[2]->arg
[0] == 'b') {
1353 oldmode
= bgp
->rfapi_cfg
->flags
1354 & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS
;
1355 switch (argv
[4]->arg
[0]) {
1357 newmode
= BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP
;
1360 newmode
= BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE
;
1366 newmode
= BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH
;
1369 vty_out(vty
, "Invalid mode specified\n");
1370 return CMD_WARNING_CONFIG_FAILED
;
1373 if (newmode
== oldmode
) {
1374 vty_out(vty
, "Mode unchanged\n");
1378 vnc_export_bgp_prechange(bgp
);
1380 bgp
->rfapi_cfg
->flags
&= ~BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS
;
1381 bgp
->rfapi_cfg
->flags
|= newmode
;
1383 vnc_export_bgp_postchange(bgp
);
1388 * export to zebra with RH mode is not yet implemented
1391 "Changing modes for zebra export not implemented yet\n");
1392 return CMD_WARNING_CONFIG_FAILED
;
1394 oldmode
= bgp
->rfapi_cfg
->flags
1395 & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS
;
1396 bgp
->rfapi_cfg
->flags
&= ~BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS
;
1397 switch (argv
[4]->arg
[0]) {
1399 if (oldmode
== BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH
) {
1402 bgp
->rfapi_cfg
->flags
|=
1403 BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP
;
1404 if (oldmode
!= BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP
) {
1409 if (oldmode
== BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH
) {
1412 if (oldmode
== BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP
) {
1417 if (oldmode
== BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP
) {
1420 bgp
->rfapi_cfg
->flags
|=
1421 BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH
;
1422 if (oldmode
!= BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH
) {
1427 vty_out(vty
, "Invalid mode\n");
1428 return CMD_WARNING_CONFIG_FAILED
;
1435 static struct rfapi_rfg_name
*rfgn_new()
1437 return XCALLOC(MTYPE_RFAPI_RFG_NAME
, sizeof(struct rfapi_rfg_name
));
1440 static void rfgn_free(struct rfapi_rfg_name
*rfgn
)
1442 XFREE(MTYPE_RFAPI_RFG_NAME
, rfgn
);
1445 DEFUN (vnc_export_nvegroup
,
1446 vnc_export_nvegroup_cmd
,
1447 "vnc export <bgp|zebra> group-nve group NAME",
1449 "Export to other protocols\n"
1451 "Export to Zebra (experimental)\n"
1452 "NVE group, used in 'group-nve' export mode\n"
1453 "NVE group\n" "Group name\n")
1455 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1456 struct rfapi_nve_group_cfg
*rfg_new
;
1458 VNC_VTY_CONFIG_CHECK(bgp
);
1460 rfg_new
= bgp_rfapi_cfg_match_byname(bgp
, argv
[5]->arg
,
1461 RFAPI_GROUP_CFG_NVE
);
1462 if (rfg_new
== NULL
) {
1463 rfg_new
= bgp_rfapi_cfg_match_byname(bgp
, argv
[5]->arg
,
1464 RFAPI_GROUP_CFG_VRF
);
1465 vnc_add_vrf_opener(bgp
, rfg_new
);
1468 if (rfg_new
== NULL
) {
1469 vty_out(vty
, "Can't find group named \"%s\".\n", argv
[5]->arg
);
1470 return CMD_WARNING_CONFIG_FAILED
;
1473 if (argv
[2]->arg
[0] == 'b') {
1475 struct listnode
*node
;
1476 struct rfapi_rfg_name
*rfgn
;
1479 * Set group for export to BGP Direct
1482 /* see if group is already included in export list */
1483 for (ALL_LIST_ELEMENTS_RO(
1484 bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
, node
,
1487 if (!strcmp(rfgn
->name
, argv
[5]->arg
)) {
1488 /* already in the list: we're done */
1494 rfgn
->name
= strdup(argv
[5]->arg
);
1495 rfgn
->rfg
= rfg_new
; /* OK if not set yet */
1497 listnode_add(bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
, rfgn
);
1499 vnc_zlog_debug_verbose("%s: testing rfg_new", __func__
);
1501 vnc_zlog_debug_verbose(
1502 "%s: testing bgp grp mode enabled", __func__
);
1503 if (VNC_EXPORT_BGP_GRP_ENABLED(bgp
->rfapi_cfg
))
1504 vnc_zlog_debug_verbose(
1505 "%s: calling vnc_direct_bgp_add_group",
1507 vnc_direct_bgp_add_group(bgp
, rfg_new
);
1512 struct listnode
*node
;
1513 struct rfapi_rfg_name
*rfgn
;
1516 * Set group for export to Zebra
1519 /* see if group is already included in export list */
1520 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
,
1523 if (!strcmp(rfgn
->name
, argv
[5]->arg
)) {
1524 /* already in the list: we're done */
1530 rfgn
->name
= strdup(argv
[5]->arg
);
1531 rfgn
->rfg
= rfg_new
; /* OK if not set yet */
1533 listnode_add(bgp
->rfapi_cfg
->rfg_export_zebra_l
, rfgn
);
1536 if (VNC_EXPORT_ZEBRA_GRP_ENABLED(bgp
->rfapi_cfg
))
1537 vnc_zebra_add_group(bgp
, rfg_new
);
1545 * This command applies to routes exported from VNC to BGP directly
1546 * without going though zebra
1548 DEFUN (vnc_no_export_nvegroup
,
1549 vnc_no_export_nvegroup_cmd
,
1550 "vnc export <bgp|zebra> group-nve no group NAME",
1552 "Export to other protocols\n"
1554 "Export to Zebra (experimental)\n"
1555 "NVE group, used in 'group-nve' export mode\n"
1556 "Disable export of VNC routes\n" "NVE group\n" "Group name\n")
1558 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1559 struct listnode
*node
, *nnode
;
1560 struct rfapi_rfg_name
*rfgn
;
1562 VNC_VTY_CONFIG_CHECK(bgp
);
1564 if (argv
[2]->arg
[0] == 'b') {
1565 for (ALL_LIST_ELEMENTS(bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
1566 node
, nnode
, rfgn
)) {
1568 if (rfgn
->name
&& !strcmp(rfgn
->name
, argv
[6]->arg
)) {
1569 vnc_zlog_debug_verbose("%s: matched \"%s\"",
1570 __func__
, rfgn
->name
);
1572 vnc_direct_bgp_del_group(bgp
,
1576 bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
1583 for (ALL_LIST_ELEMENTS(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
1586 vnc_zlog_debug_verbose("does rfg \"%s\" match?",
1588 if (rfgn
->name
&& !strcmp(rfgn
->name
, argv
[6]->arg
)) {
1590 vnc_zebra_del_group(bgp
, rfgn
->rfg
);
1593 bgp
->rfapi_cfg
->rfg_export_zebra_l
,
1603 DEFUN (vnc_nve_group_export_no_prefixlist
,
1604 vnc_nve_group_export_no_prefixlist_cmd
,
1605 "no export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
1607 "Export to other protocols\n"
1609 "Export to Zebra (experimental)\n"
1612 "Prefix-list for filtering exported routes\n" "prefix list name\n")
1614 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1615 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
1620 VNC_VTY_CONFIG_CHECK(bgp
);
1622 /* make sure it's still in list */
1623 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
1624 /* Not in list anymore */
1625 vty_out(vty
, "Current NVE group no longer exists\n");
1626 return CMD_WARNING_CONFIG_FAILED
;
1629 if (!argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1630 vty_out(vty
, "%% Malformed Address Family\n");
1631 return CMD_WARNING_CONFIG_FAILED
;
1634 if (argv
[idx
- 1]->text
[0] == 'z')
1636 idx
+= 2; /* skip afi and keyword */
1639 if (idx
== argc
|| strmatch(argv
[idx
]->arg
,
1640 rfg
->plist_export_bgp_name
[afi
])) {
1641 if (rfg
->plist_export_bgp_name
[afi
])
1642 free(rfg
->plist_export_bgp_name
[afi
]);
1643 rfg
->plist_export_bgp_name
[afi
] = NULL
;
1644 rfg
->plist_export_bgp
[afi
] = NULL
;
1646 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, afi
);
1650 || strmatch(argv
[idx
]->arg
,
1651 rfg
->plist_export_zebra_name
[afi
])) {
1652 if (rfg
->plist_export_zebra_name
[afi
])
1653 free(rfg
->plist_export_zebra_name
[afi
]);
1654 rfg
->plist_export_zebra_name
[afi
] = NULL
;
1655 rfg
->plist_export_zebra
[afi
] = NULL
;
1657 vnc_zebra_reexport_group_afi(bgp
, rfg
, afi
);
1663 ALIAS (vnc_nve_group_export_no_prefixlist
,
1664 vnc_vrf_policy_export_no_prefixlist_cmd
,
1665 "no export <ipv4|ipv6> prefix-list [NAME]",
1670 "Prefix-list for filtering exported routes\n" "prefix list name\n")
1672 DEFUN (vnc_nve_group_export_prefixlist
,
1673 vnc_nve_group_export_prefixlist_cmd
,
1674 "export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
1675 "Export to other protocols\n"
1677 "Export to Zebra (experimental)\n"
1680 "Prefix-list for filtering exported routes\n" "prefix list name\n")
1682 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1683 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
1688 VNC_VTY_CONFIG_CHECK(bgp
);
1690 /* make sure it's still in list */
1691 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
1692 /* Not in list anymore */
1693 vty_out(vty
, "Current NVE group no longer exists\n");
1694 return CMD_WARNING_CONFIG_FAILED
;
1697 if (!argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1698 vty_out(vty
, "%% Malformed Address Family\n");
1699 return CMD_WARNING_CONFIG_FAILED
;
1702 if (argv
[idx
- 1]->text
[0] == 'z')
1707 if (rfg
->plist_export_bgp_name
[afi
])
1708 free(rfg
->plist_export_bgp_name
[afi
]);
1709 rfg
->plist_export_bgp_name
[afi
] = strdup(argv
[idx
]->arg
);
1710 rfg
->plist_export_bgp
[afi
] =
1711 prefix_list_lookup(afi
, argv
[idx
]->arg
);
1713 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, afi
);
1716 if (rfg
->plist_export_zebra_name
[afi
])
1717 free(rfg
->plist_export_zebra_name
[afi
]);
1718 rfg
->plist_export_zebra_name
[afi
] = strdup(argv
[idx
]->arg
);
1719 rfg
->plist_export_zebra
[afi
] =
1720 prefix_list_lookup(afi
, argv
[idx
]->arg
);
1722 vnc_zebra_reexport_group_afi(bgp
, rfg
, afi
);
1727 ALIAS (vnc_nve_group_export_prefixlist
,
1728 vnc_vrf_policy_export_prefixlist_cmd
,
1729 "export <ipv4|ipv6> prefix-list NAME",
1733 "Prefix-list for filtering exported routes\n" "prefix list name\n")
1735 DEFUN (vnc_nve_group_export_no_routemap
,
1736 vnc_nve_group_export_no_routemap_cmd
,
1737 "no export <bgp|zebra> route-map [NAME]",
1739 "Export to other protocols\n"
1741 "Export to Zebra (experimental)\n"
1742 "Route-map for filtering exported routes\n" "route map name\n")
1744 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1745 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
1749 VNC_VTY_CONFIG_CHECK(bgp
);
1751 /* make sure it's still in list */
1752 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
1753 /* Not in list anymore */
1754 vty_out(vty
, "Current NVE group no longer exists\n");
1755 return CMD_WARNING_CONFIG_FAILED
;
1757 switch (argv
[idx
]->text
[0]) {
1764 default: /* route-map */
1770 if (idx
== argc
|| strmatch(argv
[idx
]->arg
,
1771 rfg
->routemap_export_bgp_name
)) {
1772 if (rfg
->routemap_export_bgp_name
)
1773 free(rfg
->routemap_export_bgp_name
);
1774 rfg
->routemap_export_bgp_name
= NULL
;
1775 rfg
->routemap_export_bgp
= NULL
;
1777 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, AFI_IP
);
1778 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, AFI_IP6
);
1781 if (idx
== argc
|| strmatch(argv
[idx
]->arg
,
1782 rfg
->routemap_export_zebra_name
)) {
1783 if (rfg
->routemap_export_zebra_name
)
1784 free(rfg
->routemap_export_zebra_name
);
1785 rfg
->routemap_export_zebra_name
= NULL
;
1786 rfg
->routemap_export_zebra
= NULL
;
1788 vnc_zebra_reexport_group_afi(bgp
, rfg
, AFI_IP
);
1789 vnc_zebra_reexport_group_afi(bgp
, rfg
, AFI_IP6
);
1795 ALIAS (vnc_nve_group_export_no_routemap
,
1796 vnc_vrf_policy_export_no_routemap_cmd
,
1797 "no export route-map [NAME]",
1800 "Route-map for filtering exported routes\n" "route map name\n")
1802 DEFUN (vnc_nve_group_export_routemap
,
1803 vnc_nve_group_export_routemap_cmd
,
1804 "export <bgp|zebra> route-map NAME",
1805 "Export to other protocols\n"
1807 "Export to Zebra (experimental)\n"
1808 "Route-map for filtering exported routes\n" "route map name\n")
1810 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1811 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
1815 VNC_VTY_CONFIG_CHECK(bgp
);
1817 /* make sure it's still in list */
1818 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
1819 /* Not in list anymore */
1820 vty_out(vty
, "Current NVE group no longer exists\n");
1821 return CMD_WARNING_CONFIG_FAILED
;
1824 if (argv
[1]->text
[0] == 'z')
1829 if (rfg
->routemap_export_bgp_name
)
1830 free(rfg
->routemap_export_bgp_name
);
1831 rfg
->routemap_export_bgp_name
= strdup(argv
[idx
]->arg
);
1832 rfg
->routemap_export_bgp
=
1833 route_map_lookup_by_name(argv
[idx
]->arg
);
1834 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, AFI_IP
);
1835 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, AFI_IP6
);
1837 if (rfg
->routemap_export_zebra_name
)
1838 free(rfg
->routemap_export_zebra_name
);
1839 rfg
->routemap_export_zebra_name
= strdup(argv
[idx
]->arg
);
1840 rfg
->routemap_export_zebra
=
1841 route_map_lookup_by_name(argv
[idx
]->arg
);
1842 vnc_zebra_reexport_group_afi(bgp
, rfg
, AFI_IP
);
1843 vnc_zebra_reexport_group_afi(bgp
, rfg
, AFI_IP6
);
1848 ALIAS (vnc_nve_group_export_routemap
,
1849 vnc_vrf_policy_export_routemap_cmd
,
1850 "export route-map NAME",
1852 "Route-map for filtering exported routes\n" "route map name\n")
1854 DEFUN (vnc_nve_export_no_prefixlist
,
1855 vnc_nve_export_no_prefixlist_cmd
,
1856 "no vnc export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
1859 "Export to other protocols\n"
1861 "Export to Zebra (experimental)\n"
1864 "Prefix-list for filtering exported routes\n" "Prefix list name\n")
1866 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1867 struct rfapi_cfg
*hc
;
1870 VNC_VTY_CONFIG_CHECK(bgp
);
1871 hc
= bgp
->rfapi_cfg
;
1873 if (strmatch(argv
[4]->text
, "ipv4")) {
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
]))
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
);
1890 if (((argc
> 6) && hc
->plist_export_zebra_name
[afi
]
1891 && strmatch(argv
[6]->text
,
1892 hc
->plist_export_zebra_name
[afi
]))
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); */
1904 DEFUN (vnc_nve_export_prefixlist
,
1905 vnc_nve_export_prefixlist_cmd
,
1906 "vnc export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
1908 "Export to other protocols\n"
1910 "Export to Zebra (experimental)\n"
1913 "Prefix-list for filtering exported routes\n" "Prefix list name\n")
1915 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1916 struct rfapi_cfg
*hc
;
1919 VNC_VTY_CONFIG_CHECK(bgp
);
1920 hc
= bgp
->rfapi_cfg
;
1922 if (strmatch(argv
[3]->text
, "ipv4")) {
1928 if (argv
[2]->arg
[0] == 'b') {
1929 if (hc
->plist_export_bgp_name
[afi
])
1930 free(hc
->plist_export_bgp_name
[afi
]);
1931 hc
->plist_export_bgp_name
[afi
] = strdup(argv
[5]->arg
);
1932 hc
->plist_export_bgp
[afi
] =
1933 prefix_list_lookup(afi
, argv
[5]->arg
);
1934 vnc_direct_bgp_reexport(bgp
, afi
);
1936 if (hc
->plist_export_zebra_name
[afi
])
1937 free(hc
->plist_export_zebra_name
[afi
]);
1938 hc
->plist_export_zebra_name
[afi
] = strdup(argv
[5]->arg
);
1939 hc
->plist_export_zebra
[afi
] =
1940 prefix_list_lookup(afi
, argv
[5]->arg
);
1941 /* TBD vnc_zebra_rh_reexport(bgp, afi); */
1946 DEFUN (vnc_nve_export_no_routemap
,
1947 vnc_nve_export_no_routemap_cmd
,
1948 "no vnc export <bgp|zebra> route-map [NAME]",
1951 "Export to other protocols\n"
1953 "Export to Zebra (experimental)\n"
1954 "Route-map for filtering exported routes\n" "Route map name\n")
1956 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1957 struct rfapi_cfg
*hc
;
1959 VNC_VTY_CONFIG_CHECK(bgp
);
1960 hc
= bgp
->rfapi_cfg
;
1962 if (argv
[3]->arg
[0] == 'b') {
1963 if (((argc
> 5) && hc
->routemap_export_bgp_name
1964 && strmatch(argv
[5]->text
, hc
->routemap_export_bgp_name
))
1967 free(hc
->routemap_export_bgp_name
);
1968 hc
->routemap_export_bgp_name
= NULL
;
1969 hc
->routemap_export_bgp
= NULL
;
1970 vnc_direct_bgp_reexport(bgp
, AFI_IP
);
1971 vnc_direct_bgp_reexport(bgp
, AFI_IP6
);
1974 if (((argc
> 5) && hc
->routemap_export_zebra_name
1975 && strmatch(argv
[5]->text
, hc
->routemap_export_zebra_name
))
1978 free(hc
->routemap_export_zebra_name
);
1979 hc
->routemap_export_zebra_name
= NULL
;
1980 hc
->routemap_export_zebra
= NULL
;
1981 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
1982 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
1988 DEFUN (vnc_nve_export_routemap
,
1989 vnc_nve_export_routemap_cmd
,
1990 "vnc export <bgp|zebra> route-map NAME",
1992 "Export to other protocols\n"
1994 "Export to Zebra (experimental)\n"
1995 "Route-map for filtering exported routes\n" "Route map name\n")
1997 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
1998 struct rfapi_cfg
*hc
;
2000 VNC_VTY_CONFIG_CHECK(bgp
);
2001 hc
= bgp
->rfapi_cfg
;
2003 if (argv
[2]->arg
[0] == 'b') {
2004 if (hc
->routemap_export_bgp_name
)
2005 free(hc
->routemap_export_bgp_name
);
2006 hc
->routemap_export_bgp_name
= strdup(argv
[4]->arg
);
2007 hc
->routemap_export_bgp
=
2008 route_map_lookup_by_name(argv
[4]->arg
);
2009 vnc_direct_bgp_reexport(bgp
, AFI_IP
);
2010 vnc_direct_bgp_reexport(bgp
, AFI_IP6
);
2012 if (hc
->routemap_export_zebra_name
)
2013 free(hc
->routemap_export_zebra_name
);
2014 hc
->routemap_export_zebra_name
= strdup(argv
[4]->arg
);
2015 hc
->routemap_export_zebra
=
2016 route_map_lookup_by_name(argv
[4]->arg
);
2017 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
2018 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
2025 * respond to changes in the global prefix list configuration
2027 void vnc_prefix_list_update(struct bgp
*bgp
)
2031 struct rfapi_nve_group_cfg
*rfg
;
2032 struct rfapi_cfg
*hc
;
2036 vnc_zlog_debug_verbose("%s: No BGP process is configured",
2041 if (!(hc
= bgp
->rfapi_cfg
)) {
2042 vnc_zlog_debug_verbose("%s: rfapi not configured", __func__
);
2046 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2048 * Loop over nve groups
2050 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->nve_groups_sequential
,
2053 if (rfg
->plist_export_bgp_name
[afi
]) {
2054 rfg
->plist_export_bgp
[afi
] = prefix_list_lookup(
2055 afi
, rfg
->plist_export_bgp_name
[afi
]);
2057 if (rfg
->plist_export_zebra_name
[afi
]) {
2058 rfg
->plist_export_zebra
2059 [afi
] = prefix_list_lookup(
2060 afi
, rfg
->plist_export_zebra_name
[afi
]);
2062 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; ++i
) {
2063 if (rfg
->plist_redist_name
[i
][afi
]) {
2065 [i
][afi
] = prefix_list_lookup(
2067 rfg
->plist_redist_name
[i
][afi
]);
2071 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, afi
);
2072 /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */
2078 if (hc
->plist_export_bgp_name
[afi
]) {
2079 hc
->plist_export_bgp
[afi
] = prefix_list_lookup(
2080 afi
, hc
->plist_export_bgp_name
[afi
]);
2082 if (hc
->plist_export_zebra_name
[afi
]) {
2083 hc
->plist_export_zebra
[afi
] = prefix_list_lookup(
2084 afi
, hc
->plist_export_zebra_name
[afi
]);
2087 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; ++i
) {
2088 if (hc
->plist_redist_name
[i
][afi
]) {
2089 hc
->plist_redist
[i
][afi
] = prefix_list_lookup(
2090 afi
, hc
->plist_redist_name
[i
][afi
]);
2095 vnc_direct_bgp_reexport(bgp
, AFI_IP
);
2096 vnc_direct_bgp_reexport(bgp
, AFI_IP6
);
2098 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
2099 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
2101 vnc_redistribute_prechange(bgp
);
2102 vnc_redistribute_postchange(bgp
);
2106 * respond to changes in the global route map configuration
2108 void vnc_routemap_update(struct bgp
*bgp
, const char *unused
)
2111 struct rfapi_nve_group_cfg
*rfg
;
2112 struct rfapi_cfg
*hc
;
2115 vnc_zlog_debug_verbose("%s(arg=%s)", __func__
, unused
);
2118 vnc_zlog_debug_verbose("%s: No BGP process is configured",
2123 if (!(hc
= bgp
->rfapi_cfg
)) {
2124 vnc_zlog_debug_verbose("%s: rfapi not configured", __func__
);
2129 * Loop over nve groups
2131 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->nve_groups_sequential
, n
,
2134 if (rfg
->routemap_export_bgp_name
) {
2135 rfg
->routemap_export_bgp
= route_map_lookup_by_name(
2136 rfg
->routemap_export_bgp_name
);
2138 if (rfg
->routemap_export_zebra_name
) {
2139 rfg
->routemap_export_bgp
= route_map_lookup_by_name(
2140 rfg
->routemap_export_zebra_name
);
2142 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; ++i
) {
2143 if (rfg
->routemap_redist_name
[i
]) {
2144 rfg
->routemap_redist
[i
] =
2145 route_map_lookup_by_name(
2146 rfg
->routemap_redist_name
[i
]);
2150 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, AFI_IP
);
2151 vnc_direct_bgp_reexport_group_afi(bgp
, rfg
, AFI_IP6
);
2152 /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */
2158 if (hc
->routemap_export_bgp_name
) {
2159 hc
->routemap_export_bgp
=
2160 route_map_lookup_by_name(hc
->routemap_export_bgp_name
);
2162 if (hc
->routemap_export_zebra_name
) {
2163 hc
->routemap_export_bgp
= route_map_lookup_by_name(
2164 hc
->routemap_export_zebra_name
);
2166 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; ++i
) {
2167 if (hc
->routemap_redist_name
[i
]) {
2168 hc
->routemap_redist
[i
] = route_map_lookup_by_name(
2169 hc
->routemap_redist_name
[i
]);
2173 vnc_direct_bgp_reexport(bgp
, AFI_IP
);
2174 vnc_direct_bgp_reexport(bgp
, AFI_IP6
);
2176 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
2177 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
2179 vnc_redistribute_prechange(bgp
);
2180 vnc_redistribute_postchange(bgp
);
2182 vnc_zlog_debug_verbose("%s done", __func__
);
2185 #if 0 /* superseded */
2186 static void vnc_routemap_event(route_map_event_t type
, /* ignored */
2187 const char *rmap_name
) /* ignored */
2189 struct listnode
*mnode
, *mnnode
;
2192 vnc_zlog_debug_verbose("%s(event type=%d)", __func__
, type
);
2193 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2196 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2197 vnc_routemap_update(bgp
, rmap_name
);
2199 vnc_zlog_debug_verbose("%s: done", __func__
);
2203 /*-------------------------------------------------------------------------
2205 *-----------------------------------------------------------------------*/
2208 DEFUN_NOSH (vnc_nve_group
,
2210 "vnc nve-group NAME",
2211 VNC_CONFIG_STR
"Configure a NVE group\n" "Group name\n")
2213 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2214 struct rfapi_nve_group_cfg
*rfg
;
2215 struct listnode
*node
, *nnode
;
2216 struct rfapi_rfg_name
*rfgn
;
2218 VNC_VTY_CONFIG_CHECK(bgp
);
2220 /* Search for name */
2221 rfg
= bgp_rfapi_cfg_match_byname(bgp
, argv
[2]->arg
,
2222 RFAPI_GROUP_CFG_NVE
);
2225 rfg
= rfapi_group_new(bgp
, RFAPI_GROUP_CFG_NVE
, argv
[2]->arg
);
2227 /* Error out of memory */
2228 vty_out(vty
, "Can't allocate memory for NVE group\n");
2229 return CMD_WARNING_CONFIG_FAILED
;
2232 /* Copy defaults from struct rfapi_cfg */
2233 rfg
->rd
= bgp
->rfapi_cfg
->default_rd
;
2234 if (bgp
->rfapi_cfg
->flags
& BGP_VNC_CONFIG_L2RD
) {
2235 rfg
->l2rd
= bgp
->rfapi_cfg
->default_l2rd
;
2236 rfg
->flags
|= RFAPI_RFG_L2RD
;
2238 rfg
->rd
= bgp
->rfapi_cfg
->default_rd
;
2239 rfg
->response_lifetime
=
2240 bgp
->rfapi_cfg
->default_response_lifetime
;
2242 if (bgp
->rfapi_cfg
->default_rt_export_list
) {
2243 rfg
->rt_export_list
= ecommunity_dup(
2244 bgp
->rfapi_cfg
->default_rt_export_list
);
2247 if (bgp
->rfapi_cfg
->default_rt_import_list
) {
2248 rfg
->rt_import_list
= ecommunity_dup(
2249 bgp
->rfapi_cfg
->default_rt_import_list
);
2250 rfg
->rfapi_import_table
= rfapiImportTableRefAdd(
2251 bgp
, rfg
->rt_import_list
, rfg
);
2255 * If a redist nve group was named but the group was not
2257 * make the linkage now
2259 if (!bgp
->rfapi_cfg
->rfg_redist
) {
2260 if (bgp
->rfapi_cfg
->rfg_redist_name
2261 && !strcmp(bgp
->rfapi_cfg
->rfg_redist_name
,
2264 vnc_redistribute_prechange(bgp
);
2265 bgp
->rfapi_cfg
->rfg_redist
= rfg
;
2266 vnc_redistribute_postchange(bgp
);
2271 * Same treatment for bgp-direct export group
2273 for (ALL_LIST_ELEMENTS(bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
2274 node
, nnode
, rfgn
)) {
2276 if (!strcmp(rfgn
->name
, rfg
->name
)) {
2278 vnc_direct_bgp_add_group(bgp
, rfg
);
2284 * Same treatment for zebra export group
2286 for (ALL_LIST_ELEMENTS(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
2289 vnc_zlog_debug_verbose(
2290 "%s: ezport zebra: checking if \"%s\" == \"%s\"",
2291 __func__
, rfgn
->name
, rfg
->name
);
2292 if (!strcmp(rfgn
->name
, rfg
->name
)) {
2294 vnc_zebra_add_group(bgp
, rfg
);
2301 * XXX subsequent calls will need to make sure this item is still
2302 * in the linked list and has the same name
2304 VTY_PUSH_CONTEXT_SUB(BGP_VNC_NVE_GROUP_NODE
, rfg
);
2309 static void bgp_rfapi_delete_nve_group(struct vty
*vty
, /* NULL = no output */
2311 struct rfapi_nve_group_cfg
*rfg
)
2313 struct list
*orphaned_nves
= NULL
;
2314 struct listnode
*node
, *nnode
;
2317 * If there are currently-open NVEs that belong to this group,
2318 * zero out their references to this group structure.
2321 struct rfapi_descriptor
*rfd
;
2322 orphaned_nves
= list_new();
2323 while ((rfd
= listnode_head(rfg
->nves
))) {
2325 listnode_delete(rfg
->nves
, rfd
);
2326 listnode_add(orphaned_nves
, rfd
);
2328 list_delete_and_null(&rfg
->nves
);
2333 if (rfg
->rfapi_import_table
)
2334 rfapiImportTableRefDelByIt(bgp
, rfg
->rfapi_import_table
);
2335 if (rfg
->rt_import_list
)
2336 ecommunity_free(&rfg
->rt_import_list
);
2337 if (rfg
->rt_export_list
)
2338 ecommunity_free(&rfg
->rt_export_list
);
2341 rfg
->vn_node
->info
= NULL
;
2342 route_unlock_node(rfg
->vn_node
); /* frees */
2345 rfg
->un_node
->info
= NULL
;
2346 route_unlock_node(rfg
->un_node
); /* frees */
2349 XFREE(MTYPE_RFAPI_RFP_GROUP_CFG
, rfg
->rfp_cfg
);
2350 listnode_delete(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
);
2353 XFREE(MTYPE_RFAPI_GROUP_CFG
, rfg
);
2356 * Attempt to reassign the orphaned nves to a new group. If
2357 * a NVE can not be reassigned, its rfd->rfg will remain NULL
2358 * and it will become a zombie until released by rfapi_close().
2360 if (orphaned_nves
) {
2361 struct rfapi_descriptor
*rfd
;
2363 for (ALL_LIST_ELEMENTS(orphaned_nves
, node
, nnode
, rfd
)) {
2365 * 1. rfapi_close() equivalent except:
2366 * a. don't free original descriptor
2367 * b. remember query list
2368 * c. remember advertised route list
2369 * 2. rfapi_open() equivalent except:
2370 * a. reuse original descriptor
2371 * 3. rfapi_register() on remembered advertised route
2373 * 4. rfapi_query on rememebred query list
2378 rc
= rfapi_reopen(rfd
, bgp
);
2381 list_delete_node(orphaned_nves
, node
);
2384 "WARNING: reassigned NVE vn=");
2385 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
2387 vty_out(vty
, " un=");
2388 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
2390 vty_out(vty
, " to new group \"%s\"\n",
2395 for (ALL_LIST_ELEMENTS_RO(orphaned_nves
, node
, rfd
)) {
2397 vty_out(vty
, "WARNING: orphaned NVE vn=");
2398 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
2400 vty_out(vty
, " un=");
2401 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
2405 list_delete_and_null(&orphaned_nves
);
2410 bgp_rfapi_delete_named_nve_group(struct vty
*vty
, /* NULL = no output */
2412 const char *rfg_name
, /* NULL = any */
2413 rfapi_group_cfg_type_t type
) /* _MAX = any */
2415 struct rfapi_nve_group_cfg
*rfg
= NULL
;
2416 struct listnode
*node
, *nnode
;
2417 struct rfapi_rfg_name
*rfgn
;
2419 /* Search for name */
2421 rfg
= bgp_rfapi_cfg_match_byname(bgp
, rfg_name
, type
);
2424 vty_out(vty
, "No NVE group named \"%s\"\n",
2426 return CMD_WARNING_CONFIG_FAILED
;
2431 * If this group is the redist nve group, unlink it
2433 if (rfg_name
== NULL
|| bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2434 vnc_redistribute_prechange(bgp
);
2435 bgp
->rfapi_cfg
->rfg_redist
= NULL
;
2436 vnc_redistribute_postchange(bgp
);
2441 * remove reference from bgp direct export list
2443 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
, node
,
2445 if (rfgn
->rfg
== rfg
) {
2447 /* remove exported routes from this group */
2448 vnc_direct_bgp_del_group(bgp
, rfg
);
2454 * remove reference from zebra export list
2456 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
2458 if (rfgn
->rfg
== rfg
) {
2460 /* remove exported routes from this group */
2461 vnc_zebra_del_group(bgp
, rfg
);
2467 clear_vnc_vrf_closer(rfg
);
2468 bgp_rfapi_delete_nve_group(vty
, bgp
, rfg
);
2469 } else /* must be delete all */
2470 for (ALL_LIST_ELEMENTS(bgp
->rfapi_cfg
->nve_groups_sequential
,
2471 node
, nnode
, rfg
)) {
2473 clear_vnc_vrf_closer(rfg
);
2474 bgp_rfapi_delete_nve_group(vty
, bgp
, rfg
);
2479 DEFUN (vnc_no_nve_group
,
2480 vnc_no_nve_group_cmd
,
2481 "no vnc nve-group NAME",
2484 "Configure a NVE group\n"
2487 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2489 return bgp_rfapi_delete_named_nve_group(vty
, bgp
, argv
[3]->arg
,
2490 RFAPI_GROUP_CFG_NVE
);
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"
2502 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2503 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
2506 struct route_table
*rt
;
2507 struct route_node
*rn
;
2508 int is_un_prefix
= 0;
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
;
2517 if (!str2prefix(argv
[2]->arg
, &p
)) {
2518 vty_out(vty
, "Malformed prefix \"%s\"\n", argv
[2]->arg
);
2519 return CMD_WARNING_CONFIG_FAILED
;
2522 afi
= family2afi(p
.family
);
2524 vty_out(vty
, "Unsupported address family\n");
2525 return CMD_WARNING_CONFIG_FAILED
;
2528 if (argv
[1]->arg
[0] == 'u') {
2529 rt
= bgp
->rfapi_cfg
->nve_groups_un
[afi
];
2532 rt
= bgp
->rfapi_cfg
->nve_groups_vn
[afi
];
2535 rn
= route_node_get(rt
, &p
); /* NB locks node */
2538 * There is already a group with this prefix
2540 route_unlock_node(rn
);
2541 if (rn
->info
!= rfg
) {
2543 * different group name: fail
2546 "nve group \"%s\" already has \"%s\" prefix %s\n",
2547 ((struct rfapi_nve_group_cfg
*)(rn
->info
))
2549 argv
[1]->arg
, argv
[2]->arg
);
2550 return CMD_WARNING_CONFIG_FAILED
;
2553 * same group name: it's already in the correct place
2554 * in the table, so we're done.
2556 * Implies rfg->(vn|un)_prefix is already correct.
2562 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2563 vnc_redistribute_prechange(bgp
);
2566 /* New prefix, new node */
2570 /* detach rfg from previous route table location */
2572 rfg
->un_node
->info
= NULL
;
2573 route_unlock_node(rfg
->un_node
); /* frees */
2575 rfg
->un_node
= rn
; /* back ref */
2580 /* detach rfg from previous route table location */
2582 rfg
->vn_node
->info
= NULL
;
2583 route_unlock_node(rfg
->vn_node
); /* frees */
2585 rfg
->vn_node
= rn
; /* back ref */
2592 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2593 vnc_redistribute_postchange(bgp
);
2599 DEFUN (vnc_nve_group_rt_import
,
2600 vnc_nve_group_rt_import_cmd
,
2601 "rt import RTLIST...",
2602 "Specify route targets\n"
2604 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
2606 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2607 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
2609 struct listnode
*node
;
2610 struct rfapi_rfg_name
*rfgn
;
2611 int is_export_bgp
= 0;
2612 int is_export_zebra
= 0;
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
;
2621 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2, &rfg
->rt_import_list
);
2622 if (rc
!= CMD_SUCCESS
)
2625 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
, node
,
2628 if (rfgn
->rfg
== rfg
) {
2635 vnc_direct_bgp_del_group(bgp
, rfg
);
2637 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
2640 if (rfgn
->rfg
== rfg
) {
2641 is_export_zebra
= 1;
2646 if (is_export_zebra
)
2647 vnc_zebra_del_group(bgp
, rfg
);
2650 * stop referencing old import table, now reference new one
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
);
2658 vnc_direct_bgp_add_group(bgp
, rfg
);
2660 if (is_export_zebra
)
2661 vnc_zebra_add_group(bgp
, rfg
);
2666 DEFUN (vnc_nve_group_rt_export
,
2667 vnc_nve_group_rt_export_cmd
,
2668 "rt export RTLIST...",
2669 "Specify route targets\n"
2671 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
2673 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2674 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
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
;
2684 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2685 vnc_redistribute_prechange(bgp
);
2688 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2, &rfg
->rt_export_list
);
2690 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2691 vnc_redistribute_postchange(bgp
);
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")
2704 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2705 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
2707 int is_export_bgp
= 0;
2708 int is_export_zebra
= 0;
2709 struct listnode
*node
;
2710 struct rfapi_rfg_name
*rfgn
;
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
;
2719 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2, &rfg
->rt_import_list
);
2720 if (rc
!= CMD_SUCCESS
)
2723 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
, node
,
2726 if (rfgn
->rfg
== rfg
) {
2733 vnc_direct_bgp_del_group(bgp
, rfg
);
2735 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
2738 if (rfgn
->rfg
== rfg
) {
2739 is_export_zebra
= 1;
2744 if (is_export_zebra
) {
2745 vnc_zlog_debug_verbose("%s: is_export_zebra", __func__
);
2746 vnc_zebra_del_group(bgp
, rfg
);
2750 * stop referencing old import table, now reference new one
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
);
2758 vnc_direct_bgp_add_group(bgp
, rfg
);
2760 if (is_export_zebra
)
2761 vnc_zebra_add_group(bgp
, rfg
);
2763 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2764 vnc_redistribute_prechange(bgp
);
2767 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2, &rfg
->rt_export_list
);
2769 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2770 vnc_redistribute_postchange(bgp
);
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")
2783 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2784 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
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
;
2793 if (strmatch(argv
[1]->text
, "auto:vn")) {
2797 unsigned long value_l
= strtoul(argv
[1]->arg
, &end
, 10);
2798 uint8_t value
= value_l
& 0xff;
2800 if (!argv
[1]->arg
[0] || *end
) {
2801 vty_out(vty
, "%% Malformed l2 nve ID \"%s\"\n",
2803 return CMD_WARNING_CONFIG_FAILED
;
2805 if ((value_l
< 1) || (value_l
> 0xff)) {
2807 "%% Malformed l2 nve id (must be greater than 0 and less than %u\n",
2809 return CMD_WARNING_CONFIG_FAILED
;
2814 rfg
->flags
|= RFAPI_RFG_L2RD
;
2819 DEFUN (vnc_nve_group_no_l2rd
,
2820 vnc_nve_group_no_l2rd_cmd
,
2823 "Specify default Local Nve ID value to use in RD for L2 routes\n")
2825 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2826 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
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
;
2836 rfg
->flags
&= ~RFAPI_RFG_L2RD
;
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")
2847 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2849 struct prefix_rd prd
;
2850 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
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
;
2859 if (!strncmp(argv
[1]->arg
, "auto:vn:", 8)) {
2861 * use AF_UNIX to designate automatically-assigned RD
2862 * auto:vn:nn where nn is a 2-octet quantity
2865 uint32_t value32
= strtoul(argv
[1]->arg
+ 8, &end
, 10);
2866 uint16_t value
= value32
& 0xffff;
2868 if (!argv
[1]->arg
[8] || *end
) {
2869 vty_out(vty
, "%% Malformed rd\n");
2870 return CMD_WARNING_CONFIG_FAILED
;
2872 if (value32
> 0xffff) {
2873 vty_out(vty
, "%% Malformed rd (must be less than %u\n",
2875 return CMD_WARNING_CONFIG_FAILED
;
2878 memset(&prd
, 0, sizeof(prd
));
2879 prd
.family
= AF_UNIX
;
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;
2888 ret
= str2prefix_rd(argv
[1]->arg
, &prd
);
2890 vty_out(vty
, "%% Malformed rd\n");
2891 return CMD_WARNING_CONFIG_FAILED
;
2895 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2896 vnc_redistribute_prechange(bgp
);
2901 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
2902 vnc_redistribute_postchange(bgp
);
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")
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
;
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
;
2926 if (strmatch(argv
[1]->text
, "infinite")) {
2927 rspint
= RFAPI_INFINITE_LIFETIME
;
2929 rspint
= strtoul(argv
[1]->arg
, NULL
, 10);
2932 rfg
->response_lifetime
= rspint
;
2933 rfg
->flags
|= RFAPI_RFG_RESPONSE_LIFETIME
;
2935 for (ALL_LIST_ELEMENTS_RO(rfg
->nves
, hdnode
, rfd
))
2936 rfd
->response_lifetime
= rspint
;
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.
2945 DEFUN_NOSH (exit_vnc
,
2948 "Exit VNC configuration mode\n")
2950 if (vty
->node
== BGP_VNC_DEFAULTS_NODE
2951 || vty
->node
== BGP_VNC_NVE_GROUP_NODE
2952 || vty
->node
== BGP_VNC_L2_GROUP_NODE
) {
2954 vty
->node
= BGP_NODE
;
2959 static struct cmd_node bgp_vnc_defaults_node
= {
2960 BGP_VNC_DEFAULTS_NODE
, "%s(config-router-vnc-defaults)# ", 1};
2962 static struct cmd_node bgp_vnc_nve_group_node
= {
2963 BGP_VNC_NVE_GROUP_NODE
, "%s(config-router-vnc-nve-group)# ", 1};
2965 /*-------------------------------------------------------------------------
2967 * Note there are two types of NVEs, one for VPNs one for RFP NVEs
2968 *-----------------------------------------------------------------------*/
2970 DEFUN_NOSH (vnc_vrf_policy
,
2973 "Configure a VRF policy group\n"
2976 struct rfapi_nve_group_cfg
*rfg
;
2977 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
2979 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
2981 "Can't configure vrf-policy within a BGP VRF instance\n");
2982 return CMD_WARNING_CONFIG_FAILED
;
2985 /* Search for name */
2986 rfg
= bgp_rfapi_cfg_match_byname(bgp
, argv
[1]->arg
,
2987 RFAPI_GROUP_CFG_VRF
);
2990 rfg
= rfapi_group_new(bgp
, RFAPI_GROUP_CFG_VRF
, argv
[1]->arg
);
2992 /* Error out of memory */
2993 vty_out(vty
, "Can't allocate memory for NVE group\n");
2994 return CMD_WARNING_CONFIG_FAILED
;
2998 * XXX subsequent calls will need to make sure this item is still
2999 * in the linked list and has the same name
3001 VTY_PUSH_CONTEXT_SUB(BGP_VRF_POLICY_NODE
, rfg
);
3006 DEFUN (vnc_no_vrf_policy
,
3007 vnc_no_vrf_policy_cmd
,
3008 "no vrf-policy NAME",
3010 "Remove a VRF policy group\n"
3013 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3015 /* silently return */
3016 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3019 return bgp_rfapi_delete_named_nve_group(vty
, bgp
, argv
[2]->arg
,
3020 RFAPI_GROUP_CFG_VRF
);
3023 DEFUN (vnc_vrf_policy_label
,
3024 vnc_vrf_policy_label_cmd
,
3025 "label (0-1048575)",
3026 "Default label value for VRF\n"
3027 "Label Value <0-1048575>\n")
3029 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
3032 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3034 /* make sure it's still in list */
3035 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
3036 /* Not in list anymore */
3037 vty_out(vty
, "Current NVE group no longer exists\n");
3038 return CMD_WARNING_CONFIG_FAILED
;
3041 label
= strtoul(argv
[1]->arg
, NULL
, 10);
3043 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3044 vnc_redistribute_prechange(bgp
);
3049 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3050 vnc_redistribute_postchange(bgp
);
3055 DEFUN (vnc_vrf_policy_no_label
,
3056 vnc_vrf_policy_no_label_cmd
,
3059 "Remove VRF default label\n")
3061 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
3062 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3064 /* make sure it's still in list */
3065 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
3066 /* Not in list anymore */
3067 vty_out(vty
, "Current VRF group no longer exists\n");
3068 return CMD_WARNING_CONFIG_FAILED
;
3071 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3072 vnc_redistribute_prechange(bgp
);
3075 rfg
->label
= MPLS_LABEL_NONE
;
3077 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3078 vnc_redistribute_postchange(bgp
);
3083 DEFUN (vnc_vrf_policy_nexthop
,
3084 vnc_vrf_policy_nexthop_cmd
,
3085 "nexthop <A.B.C.D|X:X::X:X|self>",
3086 "Specify next hop to use for VRF advertised prefixes\n"
3089 "Use configured router-id (default)\n")
3091 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
3094 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3096 /* make sure it's still in list */
3097 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
3098 /* Not in list anymore */
3099 vty_out(vty
, "Current VRF no longer exists\n");
3100 return CMD_WARNING_CONFIG_FAILED
;
3103 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3104 vnc_redistribute_prechange(bgp
);
3107 if (!str2prefix(argv
[1]->arg
, &p
) && p
.family
) {
3108 // vty_out (vty, "Nexthop set to self\n");
3109 SET_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
);
3110 memset(&rfg
->vn_prefix
, 0, sizeof(struct prefix
));
3112 UNSET_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
);
3117 /* TBD handle router-id/ nexthop changes when have advertised prefixes
3120 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3121 vnc_redistribute_postchange(bgp
);
3127 /* The RT code should be refactored/simplified with above... */
3128 DEFUN (vnc_vrf_policy_rt_import
,
3129 vnc_vrf_policy_rt_import_cmd
,
3130 "rt import RTLIST...",
3131 "Specify route targets\n"
3133 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3135 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
3136 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3138 struct listnode
*node
;
3139 struct rfapi_rfg_name
*rfgn
;
3140 int is_export_bgp
= 0;
3141 int is_export_zebra
= 0;
3143 /* make sure it's still in list */
3144 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
3145 /* Not in list anymore */
3146 vty_out(vty
, "Current NVE group no longer exists\n");
3147 return CMD_WARNING_CONFIG_FAILED
;
3150 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2, &rfg
->rt_import_list
);
3151 if (rc
!= CMD_SUCCESS
)
3154 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
, node
,
3157 if (rfgn
->rfg
== rfg
) {
3164 vnc_direct_bgp_del_group(bgp
, rfg
);
3166 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
3169 if (rfgn
->rfg
== rfg
) {
3170 is_export_zebra
= 1;
3175 if (is_export_zebra
)
3176 vnc_zebra_del_group(bgp
, rfg
);
3179 * stop referencing old import table, now reference new one
3181 if (rfg
->rfapi_import_table
)
3182 rfapiImportTableRefDelByIt(bgp
, rfg
->rfapi_import_table
);
3183 rfg
->rfapi_import_table
=
3184 rfapiImportTableRefAdd(bgp
, rfg
->rt_import_list
, rfg
);
3187 vnc_direct_bgp_add_group(bgp
, rfg
);
3189 if (is_export_zebra
)
3190 vnc_zebra_add_group(bgp
, rfg
);
3195 DEFUN (vnc_vrf_policy_rt_export
,
3196 vnc_vrf_policy_rt_export_cmd
,
3197 "rt export RTLIST...",
3198 "Specify route targets\n"
3200 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3202 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
3203 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3206 /* make sure it's still in list */
3207 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
3208 /* Not in list anymore */
3209 vty_out(vty
, "Current NVE group no longer exists\n");
3210 return CMD_WARNING_CONFIG_FAILED
;
3213 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3214 vnc_redistribute_prechange(bgp
);
3217 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2, &rfg
->rt_export_list
);
3219 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3220 vnc_redistribute_postchange(bgp
);
3226 DEFUN (vnc_vrf_policy_rt_both
,
3227 vnc_vrf_policy_rt_both_cmd
,
3228 "rt both RTLIST...",
3229 "Specify route targets\n"
3230 "Export+import filters\n"
3231 "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3233 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
3234 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3236 int is_export_bgp
= 0;
3237 int is_export_zebra
= 0;
3238 struct listnode
*node
;
3239 struct rfapi_rfg_name
*rfgn
;
3241 /* make sure it's still in list */
3242 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
3243 /* Not in list anymore */
3244 vty_out(vty
, "Current NVE group no longer exists\n");
3245 return CMD_WARNING_CONFIG_FAILED
;
3248 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2, &rfg
->rt_import_list
);
3249 if (rc
!= CMD_SUCCESS
)
3252 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
, node
,
3255 if (rfgn
->rfg
== rfg
) {
3262 vnc_direct_bgp_del_group(bgp
, rfg
);
3264 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
3267 if (rfgn
->rfg
== rfg
) {
3268 is_export_zebra
= 1;
3273 if (is_export_zebra
) {
3274 vnc_zlog_debug_verbose("%s: is_export_zebra", __func__
);
3275 vnc_zebra_del_group(bgp
, rfg
);
3279 * stop referencing old import table, now reference new one
3281 if (rfg
->rfapi_import_table
)
3282 rfapiImportTableRefDelByIt(bgp
, rfg
->rfapi_import_table
);
3283 rfg
->rfapi_import_table
=
3284 rfapiImportTableRefAdd(bgp
, rfg
->rt_import_list
, rfg
);
3287 vnc_direct_bgp_add_group(bgp
, rfg
);
3289 if (is_export_zebra
)
3290 vnc_zebra_add_group(bgp
, rfg
);
3292 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3293 vnc_redistribute_prechange(bgp
);
3296 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2, &rfg
->rt_export_list
);
3298 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3299 vnc_redistribute_postchange(bgp
);
3305 DEFUN (vnc_vrf_policy_rd
,
3306 vnc_vrf_policy_rd_cmd
,
3307 "rd ASN:NN_OR_IP-ADDRESS:NN",
3308 "Specify default VRF route distinguisher\n"
3309 "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:nh:<number> )\n")
3312 struct prefix_rd prd
;
3313 VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg
, rfg
);
3314 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3316 /* make sure it's still in list */
3317 if (!listnode_lookup(bgp
->rfapi_cfg
->nve_groups_sequential
, rfg
)) {
3318 /* Not in list anymore */
3319 vty_out(vty
, "Current NVE group no longer exists\n");
3320 return CMD_WARNING_CONFIG_FAILED
;
3323 if (!strncmp(argv
[1]->arg
, "auto:nh:", 8)) {
3325 * use AF_UNIX to designate automatically-assigned RD
3326 * auto:vn:nn where nn is a 2-octet quantity
3329 uint32_t value32
= strtoul(argv
[1]->arg
+ 8, &end
, 10);
3330 uint16_t value
= value32
& 0xffff;
3332 if (!*(argv
[1]->arg
+ 5) || *end
) {
3333 vty_out(vty
, "%% Malformed rd\n");
3334 return CMD_WARNING_CONFIG_FAILED
;
3336 if (value32
> 0xffff) {
3337 vty_out(vty
, "%% Malformed rd (must be less than %u\n",
3339 return CMD_WARNING_CONFIG_FAILED
;
3342 memset(&prd
, 0, sizeof(prd
));
3343 prd
.family
= AF_UNIX
;
3345 prd
.val
[0] = (RD_TYPE_IP
>> 8) & 0x0ff;
3346 prd
.val
[1] = RD_TYPE_IP
& 0x0ff;
3347 prd
.val
[6] = (value
>> 8) & 0x0ff;
3348 prd
.val
[7] = value
& 0x0ff;
3352 ret
= str2prefix_rd(argv
[1]->arg
, &prd
);
3354 vty_out(vty
, "%% Malformed rd\n");
3355 return CMD_WARNING_CONFIG_FAILED
;
3359 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3360 vnc_redistribute_prechange(bgp
);
3365 if (bgp
->rfapi_cfg
->rfg_redist
== rfg
) {
3366 vnc_redistribute_postchange(bgp
);
3371 DEFUN_NOSH (exit_vrf_policy
,
3372 exit_vrf_policy_cmd
,
3374 "Exit VRF policy configuration mode\n")
3376 if (vty
->node
== BGP_VRF_POLICY_NODE
) {
3377 vty
->node
= BGP_NODE
;
3382 static struct cmd_node bgp_vrf_policy_node
= {
3383 BGP_VRF_POLICY_NODE
, "%s(config-router-vrf-policy)# ", 1};
3385 /*-------------------------------------------------------------------------
3387 *-----------------------------------------------------------------------*/
3390 DEFUN_NOSH (vnc_l2_group
,
3392 "vnc l2-group NAME",
3393 VNC_CONFIG_STR
"Configure a L2 group\n" "Group name\n")
3395 struct rfapi_l2_group_cfg
*rfg
;
3396 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3397 VNC_VTY_CONFIG_CHECK(bgp
);
3399 /* Search for name */
3400 rfg
= rfapi_l2_group_lookup_byname(bgp
, argv
[2]->arg
);
3403 rfg
= rfapi_l2_group_new();
3405 /* Error out of memory */
3406 vty_out(vty
, "Can't allocate memory for L2 group\n");
3407 return CMD_WARNING_CONFIG_FAILED
;
3409 rfg
->name
= strdup(argv
[2]->arg
);
3410 /* add to tail of list */
3411 listnode_add(bgp
->rfapi_cfg
->l2_groups
, rfg
);
3415 * XXX subsequent calls will need to make sure this item is still
3416 * in the linked list and has the same name
3418 VTY_PUSH_CONTEXT_SUB(BGP_VNC_L2_GROUP_NODE
, rfg
);
3422 static void bgp_rfapi_delete_l2_group(struct vty
*vty
, /* NULL = no output */
3424 struct rfapi_l2_group_cfg
*rfg
)
3428 if (rfg
->rt_import_list
)
3429 ecommunity_free(&rfg
->rt_import_list
);
3430 if (rfg
->rt_export_list
)
3431 ecommunity_free(&rfg
->rt_export_list
);
3433 list_delete_and_null(&rfg
->labels
);
3435 XFREE(MTYPE_RFAPI_RFP_GROUP_CFG
, rfg
->rfp_cfg
);
3436 listnode_delete(bgp
->rfapi_cfg
->l2_groups
, rfg
);
3438 rfapi_l2_group_del(rfg
);
3442 bgp_rfapi_delete_named_l2_group(struct vty
*vty
, /* NULL = no output */
3444 const char *rfg_name
) /* NULL = any */
3446 struct rfapi_l2_group_cfg
*rfg
= NULL
;
3447 struct listnode
*node
, *nnode
;
3449 /* Search for name */
3451 rfg
= rfapi_l2_group_lookup_byname(bgp
, rfg_name
);
3454 vty_out(vty
, "No L2 group named \"%s\"\n",
3456 return CMD_WARNING_CONFIG_FAILED
;
3461 bgp_rfapi_delete_l2_group(vty
, bgp
, rfg
);
3462 else /* must be delete all */
3463 for (ALL_LIST_ELEMENTS(bgp
->rfapi_cfg
->l2_groups
, node
, nnode
,
3465 bgp_rfapi_delete_l2_group(vty
, bgp
, rfg
);
3469 DEFUN (vnc_no_l2_group
,
3470 vnc_no_l2_group_cmd
,
3471 "no vnc l2-group NAME",
3474 "Configure a L2 group\n"
3477 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3479 return bgp_rfapi_delete_named_l2_group(vty
, bgp
, argv
[3]->arg
);
3483 DEFUN (vnc_l2_group_lni
,
3484 vnc_l2_group_lni_cmd
,
3485 "logical-network-id (0-4294967295)",
3486 "Specify Logical Network ID associated with group\n"
3489 VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg
, rfg
);
3490 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3492 /* make sure it's still in list */
3493 if (!listnode_lookup(bgp
->rfapi_cfg
->l2_groups
, rfg
)) {
3494 /* Not in list anymore */
3495 vty_out(vty
, "Current L2 group no longer exists\n");
3496 return CMD_WARNING_CONFIG_FAILED
;
3499 rfg
->logical_net_id
= strtoul(argv
[1]->arg
, NULL
, 10);
3504 DEFUN (vnc_l2_group_labels
,
3505 vnc_l2_group_labels_cmd
,
3506 "labels LABELLIST...",
3507 "Specify label values associated with group\n"
3508 "Space separated list of label values <0-1048575>\n")
3510 VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg
, rfg
);
3511 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3514 /* make sure it's still in list */
3515 if (!listnode_lookup(bgp
->rfapi_cfg
->l2_groups
, rfg
)) {
3516 /* Not in list anymore */
3517 vty_out(vty
, "Current L2 group no longer exists\n");
3518 return CMD_WARNING_CONFIG_FAILED
;
3528 for (; argc
; --argc
, ++argv
) {
3530 label
= strtoul(argv
[0]->arg
, NULL
, 10);
3531 if (!listnode_lookup(ll
, (void *)(uintptr_t)label
))
3532 listnode_add(ll
, (void *)(uintptr_t)label
);
3538 DEFUN (vnc_l2_group_no_labels
,
3539 vnc_l2_group_no_labels_cmd
,
3540 "no labels LABELLIST...",
3542 "Specify label values associated with L2 group\n"
3543 "Space separated list of label values <0-1048575>\n")
3545 VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg
, rfg
);
3546 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3549 /* make sure it's still in list */
3550 if (!listnode_lookup(bgp
->rfapi_cfg
->l2_groups
, rfg
)) {
3551 /* Not in list anymore */
3552 vty_out(vty
, "Current L2 group no longer exists\n");
3553 return CMD_WARNING_CONFIG_FAILED
;
3558 vty_out(vty
, "Label no longer associated with group\n");
3559 return CMD_WARNING_CONFIG_FAILED
;
3564 for (; argc
; --argc
, ++argv
) {
3566 label
= strtoul(argv
[0]->arg
, NULL
, 10);
3567 listnode_delete(ll
, (void *)(uintptr_t)label
);
3573 DEFUN (vnc_l2_group_rt
,
3574 vnc_l2_group_rt_cmd
,
3575 "rt <both|export|import> ASN:NN_OR_IP-ADDRESS:NN",
3576 "Specify route targets\n"
3577 "Export+import filters\n"
3582 VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg
, rfg
);
3583 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
3584 int rc
= CMD_SUCCESS
;
3588 switch (argv
[1]->arg
[0]) {
3590 do_export
= 1; /* fall through */
3598 vty_out(vty
, "Unknown option, %s\n", argv
[1]->arg
);
3599 return CMD_ERR_NO_MATCH
;
3602 /* make sure it's still in list */
3603 if (!listnode_lookup(bgp
->rfapi_cfg
->l2_groups
, rfg
)) {
3604 /* Not in list anymore */
3605 vty_out(vty
, "Current L2 group no longer exists\n");
3606 return CMD_WARNING_CONFIG_FAILED
;
3610 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2,
3611 &rfg
->rt_import_list
);
3612 if (rc
== CMD_SUCCESS
&& do_export
)
3613 rc
= set_ecom_list(vty
, argc
- 2, argv
+ 2,
3614 &rfg
->rt_export_list
);
3619 static struct cmd_node bgp_vnc_l2_group_node
= {
3620 BGP_VNC_L2_GROUP_NODE
, "%s(config-router-vnc-l2-group)# ", 1};
3622 struct rfapi_l2_group_cfg
*
3623 bgp_rfapi_get_group_by_lni_label(struct bgp
*bgp
, uint32_t logical_net_id
,
3626 struct rfapi_l2_group_cfg
*rfg
;
3627 struct listnode
*node
;
3629 if (bgp
->rfapi_cfg
->l2_groups
== NULL
) /* not the best place for this */
3632 label
= label
& 0xfffff; /* label is 20 bits! */
3634 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->l2_groups
, node
, rfg
)) {
3635 if (rfg
->logical_net_id
== logical_net_id
) {
3636 struct listnode
*lnode
;
3638 for (ALL_LIST_ELEMENTS_RO(rfg
->labels
, lnode
, data
))
3639 if (((uint32_t)((uintptr_t)data
))
3640 == label
) { /* match! */
3648 struct list
*bgp_rfapi_get_labellist_by_lni_label(struct bgp
*bgp
,
3649 uint32_t logical_net_id
,
3652 struct rfapi_l2_group_cfg
*rfg
;
3653 rfg
= bgp_rfapi_get_group_by_lni_label(bgp
, logical_net_id
, label
);
3661 bgp_rfapi_get_ecommunity_by_lni_label(struct bgp
*bgp
, uint32_t is_import
,
3662 uint32_t logical_net_id
, uint32_t label
)
3664 struct rfapi_l2_group_cfg
*rfg
;
3665 rfg
= bgp_rfapi_get_group_by_lni_label(bgp
, logical_net_id
, label
);
3668 return rfg
->rt_import_list
;
3670 return rfg
->rt_export_list
;
3675 void bgp_rfapi_cfg_init(void)
3677 /* main bgpd code does not use this hook, but vnc does */
3678 /* superseded by bgp_route_map_process_update_cb() */
3679 /* bgp_route_map_event_hook_add(vnc_routemap_event); */
3681 install_node(&bgp_vnc_defaults_node
, NULL
);
3682 install_node(&bgp_vnc_nve_group_node
, NULL
);
3683 install_node(&bgp_vrf_policy_node
, NULL
);
3684 install_node(&bgp_vnc_l2_group_node
, NULL
);
3685 install_default(BGP_VRF_POLICY_NODE
);
3686 install_default(BGP_VNC_DEFAULTS_NODE
);
3687 install_default(BGP_VNC_NVE_GROUP_NODE
);
3688 install_default(BGP_VNC_L2_GROUP_NODE
);
3693 install_element(BGP_NODE
, &vnc_defaults_cmd
);
3694 install_element(BGP_NODE
, &vnc_nve_group_cmd
);
3695 install_element(BGP_NODE
, &vnc_no_nve_group_cmd
);
3696 install_element(BGP_NODE
, &vnc_vrf_policy_cmd
);
3697 install_element(BGP_NODE
, &vnc_no_vrf_policy_cmd
);
3698 install_element(BGP_NODE
, &vnc_l2_group_cmd
);
3699 install_element(BGP_NODE
, &vnc_no_l2_group_cmd
);
3700 install_element(BGP_NODE
, &vnc_advertise_un_method_cmd
);
3701 install_element(BGP_NODE
, &vnc_export_mode_cmd
);
3703 install_element(BGP_VNC_DEFAULTS_NODE
, &vnc_defaults_rt_import_cmd
);
3704 install_element(BGP_VNC_DEFAULTS_NODE
, &vnc_defaults_rt_export_cmd
);
3705 install_element(BGP_VNC_DEFAULTS_NODE
, &vnc_defaults_rt_both_cmd
);
3706 install_element(BGP_VNC_DEFAULTS_NODE
, &vnc_defaults_rd_cmd
);
3707 install_element(BGP_VNC_DEFAULTS_NODE
, &vnc_defaults_l2rd_cmd
);
3708 install_element(BGP_VNC_DEFAULTS_NODE
, &vnc_defaults_no_l2rd_cmd
);
3709 install_element(BGP_VNC_DEFAULTS_NODE
,
3710 &vnc_defaults_responselifetime_cmd
);
3711 install_element(BGP_VNC_DEFAULTS_NODE
, &exit_vnc_cmd
);
3713 install_element(BGP_NODE
, &vnc_redistribute_protocol_cmd
);
3714 install_element(BGP_NODE
, &vnc_no_redistribute_protocol_cmd
);
3715 install_element(BGP_NODE
, &vnc_redistribute_nvegroup_cmd
);
3716 install_element(BGP_NODE
, &vnc_redistribute_no_nvegroup_cmd
);
3717 install_element(BGP_NODE
, &vnc_redistribute_lifetime_cmd
);
3718 install_element(BGP_NODE
, &vnc_redistribute_rh_roo_localadmin_cmd
);
3719 install_element(BGP_NODE
, &vnc_redistribute_mode_cmd
);
3720 install_element(BGP_NODE
, &vnc_redistribute_bgp_exterior_cmd
);
3722 install_element(BGP_NODE
, &vnc_redist_bgpdirect_no_prefixlist_cmd
);
3723 install_element(BGP_NODE
, &vnc_redist_bgpdirect_prefixlist_cmd
);
3724 install_element(BGP_NODE
, &vnc_redist_bgpdirect_no_routemap_cmd
);
3725 install_element(BGP_NODE
, &vnc_redist_bgpdirect_routemap_cmd
);
3727 install_element(BGP_VNC_NVE_GROUP_NODE
,
3728 &vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd
);
3729 install_element(BGP_VNC_NVE_GROUP_NODE
,
3730 &vnc_nve_group_redist_bgpdirect_prefixlist_cmd
);
3731 install_element(BGP_VNC_NVE_GROUP_NODE
,
3732 &vnc_nve_group_redist_bgpdirect_no_routemap_cmd
);
3733 install_element(BGP_VNC_NVE_GROUP_NODE
,
3734 &vnc_nve_group_redist_bgpdirect_routemap_cmd
);
3736 install_element(BGP_NODE
, &vnc_export_nvegroup_cmd
);
3737 install_element(BGP_NODE
, &vnc_no_export_nvegroup_cmd
);
3738 install_element(BGP_NODE
, &vnc_nve_export_prefixlist_cmd
);
3739 install_element(BGP_NODE
, &vnc_nve_export_routemap_cmd
);
3740 install_element(BGP_NODE
, &vnc_nve_export_no_prefixlist_cmd
);
3741 install_element(BGP_NODE
, &vnc_nve_export_no_routemap_cmd
);
3743 install_element(BGP_VNC_NVE_GROUP_NODE
, &vnc_nve_group_l2rd_cmd
);
3744 install_element(BGP_VNC_NVE_GROUP_NODE
, &vnc_nve_group_no_l2rd_cmd
);
3745 install_element(BGP_VNC_NVE_GROUP_NODE
, &vnc_nve_group_prefix_cmd
);
3746 install_element(BGP_VNC_NVE_GROUP_NODE
, &vnc_nve_group_rt_import_cmd
);
3747 install_element(BGP_VNC_NVE_GROUP_NODE
, &vnc_nve_group_rt_export_cmd
);
3748 install_element(BGP_VNC_NVE_GROUP_NODE
, &vnc_nve_group_rt_both_cmd
);
3749 install_element(BGP_VNC_NVE_GROUP_NODE
, &vnc_nve_group_rd_cmd
);
3750 install_element(BGP_VNC_NVE_GROUP_NODE
,
3751 &vnc_nve_group_responselifetime_cmd
);
3752 install_element(BGP_VNC_NVE_GROUP_NODE
,
3753 &vnc_nve_group_export_prefixlist_cmd
);
3754 install_element(BGP_VNC_NVE_GROUP_NODE
,
3755 &vnc_nve_group_export_routemap_cmd
);
3756 install_element(BGP_VNC_NVE_GROUP_NODE
,
3757 &vnc_nve_group_export_no_prefixlist_cmd
);
3758 install_element(BGP_VNC_NVE_GROUP_NODE
,
3759 &vnc_nve_group_export_no_routemap_cmd
);
3760 install_element(BGP_VNC_NVE_GROUP_NODE
, &exit_vnc_cmd
);
3762 install_element(BGP_VRF_POLICY_NODE
, &vnc_vrf_policy_label_cmd
);
3763 install_element(BGP_VRF_POLICY_NODE
, &vnc_vrf_policy_no_label_cmd
);
3764 // Reenable to support VRF controller use case and testing
3765 install_element(BGP_VRF_POLICY_NODE
, &vnc_vrf_policy_nexthop_cmd
);
3766 install_element(BGP_VRF_POLICY_NODE
, &vnc_vrf_policy_rt_import_cmd
);
3767 install_element(BGP_VRF_POLICY_NODE
, &vnc_vrf_policy_rt_export_cmd
);
3768 install_element(BGP_VRF_POLICY_NODE
, &vnc_vrf_policy_rt_both_cmd
);
3769 install_element(BGP_VRF_POLICY_NODE
, &vnc_vrf_policy_rd_cmd
);
3770 install_element(BGP_VRF_POLICY_NODE
,
3771 &vnc_vrf_policy_export_prefixlist_cmd
);
3772 install_element(BGP_VRF_POLICY_NODE
,
3773 &vnc_vrf_policy_export_routemap_cmd
);
3774 install_element(BGP_VRF_POLICY_NODE
,
3775 &vnc_vrf_policy_export_no_prefixlist_cmd
);
3776 install_element(BGP_VRF_POLICY_NODE
,
3777 &vnc_vrf_policy_export_no_routemap_cmd
);
3778 install_element(BGP_VRF_POLICY_NODE
, &exit_vrf_policy_cmd
);
3780 install_element(BGP_VNC_L2_GROUP_NODE
, &vnc_l2_group_lni_cmd
);
3781 install_element(BGP_VNC_L2_GROUP_NODE
, &vnc_l2_group_labels_cmd
);
3782 install_element(BGP_VNC_L2_GROUP_NODE
, &vnc_l2_group_no_labels_cmd
);
3783 install_element(BGP_VNC_L2_GROUP_NODE
, &vnc_l2_group_rt_cmd
);
3784 install_element(BGP_VNC_L2_GROUP_NODE
, &exit_vnc_cmd
);
3787 struct rfapi_cfg
*bgp_rfapi_cfg_new(struct rfapi_rfp_cfg
*cfg
)
3789 struct rfapi_cfg
*h
;
3792 h
= (struct rfapi_cfg
*)XCALLOC(MTYPE_RFAPI_CFG
,
3793 sizeof(struct rfapi_cfg
));
3796 h
->nve_groups_sequential
= list_new();
3797 assert(h
->nve_groups_sequential
);
3798 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3799 h
->nve_groups_vn
[afi
] = route_table_init();
3800 h
->nve_groups_un
[afi
] = route_table_init();
3802 h
->default_response_lifetime
=
3803 BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT
;
3804 h
->rfg_export_direct_bgp_l
= list_new();
3805 h
->rfg_export_zebra_l
= list_new();
3806 h
->resolve_nve_roo_local_admin
=
3807 BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT
;
3809 SET_FLAG(h
->flags
, BGP_VNC_CONFIG_FLAGS_DEFAULT
);
3812 h
->rfp_cfg
.download_type
= RFAPI_RFP_DOWNLOAD_PARTIAL
;
3813 h
->rfp_cfg
.ftd_advertisement_interval
=
3814 RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL
;
3815 h
->rfp_cfg
.holddown_factor
=
3816 RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR
;
3817 h
->rfp_cfg
.use_updated_response
= 0;
3818 h
->rfp_cfg
.use_removes
= 0;
3820 h
->rfp_cfg
.download_type
= cfg
->download_type
;
3821 h
->rfp_cfg
.ftd_advertisement_interval
=
3822 cfg
->ftd_advertisement_interval
;
3823 h
->rfp_cfg
.holddown_factor
= cfg
->holddown_factor
;
3824 h
->rfp_cfg
.use_updated_response
= cfg
->use_updated_response
;
3825 h
->rfp_cfg
.use_removes
= cfg
->use_removes
;
3826 if (cfg
->use_updated_response
)
3827 h
->flags
&= ~BGP_VNC_CONFIG_CALLBACK_DISABLE
;
3829 h
->flags
|= BGP_VNC_CONFIG_CALLBACK_DISABLE
;
3830 if (cfg
->use_removes
)
3831 h
->flags
&= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE
;
3833 h
->flags
|= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE
;
3838 void bgp_rfapi_cfg_destroy(struct bgp
*bgp
, struct rfapi_cfg
*h
)
3844 bgp_rfapi_delete_named_nve_group(NULL
, bgp
, NULL
, RFAPI_GROUP_CFG_MAX
);
3845 bgp_rfapi_delete_named_l2_group(NULL
, bgp
, NULL
);
3846 if (h
->l2_groups
!= NULL
)
3847 list_delete_and_null(&h
->l2_groups
);
3848 list_delete_and_null(&h
->nve_groups_sequential
);
3849 list_delete_and_null(&h
->rfg_export_direct_bgp_l
);
3850 list_delete_and_null(&h
->rfg_export_zebra_l
);
3851 if (h
->default_rt_export_list
)
3852 ecommunity_free(&h
->default_rt_export_list
);
3853 if (h
->default_rt_import_list
)
3854 ecommunity_free(&h
->default_rt_import_list
);
3855 if (h
->default_rfp_cfg
)
3856 XFREE(MTYPE_RFAPI_RFP_GROUP_CFG
, h
->default_rfp_cfg
);
3857 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3858 route_table_finish(h
->nve_groups_vn
[afi
]);
3859 route_table_finish(h
->nve_groups_un
[afi
]);
3861 XFREE(MTYPE_RFAPI_CFG
, h
);
3864 int bgp_rfapi_cfg_write(struct vty
*vty
, struct bgp
*bgp
)
3866 struct listnode
*node
, *nnode
;
3867 struct rfapi_nve_group_cfg
*rfg
;
3868 struct rfapi_cfg
*hc
= bgp
->rfapi_cfg
;
3869 struct rfapi_rfg_name
*rfgn
;
3873 if (bgp
->rfapi
== NULL
|| hc
== NULL
)
3876 vty_out(vty
, "!\n");
3877 for (ALL_LIST_ELEMENTS(hc
->nve_groups_sequential
, node
, nnode
, rfg
))
3878 if (rfg
->type
== RFAPI_GROUP_CFG_VRF
) {
3880 vty_out(vty
, " vrf-policy %s\n", rfg
->name
);
3881 if (rfg
->label
<= MPLS_LABEL_MAX
) {
3882 vty_out(vty
, " label %u\n", rfg
->label
);
3884 if (CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
3885 vty_out(vty
, " nexthop self\n");
3888 if (rfg
->vn_prefix
.family
) {
3890 buf
[0] = buf
[BUFSIZ
- 1] = 0;
3891 inet_ntop(rfg
->vn_prefix
.family
,
3892 &rfg
->vn_prefix
.u
.prefix
, buf
,
3894 if (!buf
[0] || buf
[BUFSIZ
- 1]) {
3895 // vty_out (vty, "nexthop
3898 vty_out(vty
, " nexthop %s\n",
3904 if (rfg
->rd
.prefixlen
) {
3905 char buf
[RD_ADDRSTRLEN
];
3907 if (AF_UNIX
== rfg
->rd
.family
) {
3911 value
= ((rfg
->rd
.val
[6] << 8)
3913 | (rfg
->rd
.val
[7] & 0x0ff);
3915 vty_out(vty
, " rd auto:nh:%d\n",
3919 vty_out(vty
, " rd %s\n",
3920 prefix_rd2str(&rfg
->rd
, buf
,
3924 if (rfg
->rt_import_list
&& rfg
->rt_export_list
3925 && ecommunity_cmp(rfg
->rt_import_list
,
3926 rfg
->rt_export_list
)) {
3927 char *b
= ecommunity_ecom2str(
3928 rfg
->rt_import_list
,
3929 ECOMMUNITY_FORMAT_ROUTE_MAP
,
3930 ECOMMUNITY_ROUTE_TARGET
);
3931 vty_out(vty
, " rt both %s\n", b
);
3932 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
3934 if (rfg
->rt_import_list
) {
3935 char *b
= ecommunity_ecom2str(
3936 rfg
->rt_import_list
,
3937 ECOMMUNITY_FORMAT_ROUTE_MAP
,
3938 ECOMMUNITY_ROUTE_TARGET
);
3939 vty_out(vty
, " rt import %s\n", b
);
3940 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
3942 if (rfg
->rt_export_list
) {
3943 char *b
= ecommunity_ecom2str(
3944 rfg
->rt_export_list
,
3945 ECOMMUNITY_FORMAT_ROUTE_MAP
,
3946 ECOMMUNITY_ROUTE_TARGET
);
3947 vty_out(vty
, " rt export %s\n", b
);
3948 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
3953 * route filtering: prefix-lists and route-maps
3955 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
3957 const char *afistr
=
3958 (afi
== AFI_IP
) ? "ipv4" : "ipv6";
3960 if (rfg
->plist_export_bgp_name
[afi
]) {
3962 " export %s%s prefix-list %s\n",
3963 (rfg
->type
== RFAPI_GROUP_CFG_VRF
3967 rfg
->plist_export_bgp_name
3970 if (rfg
->plist_export_zebra_name
[afi
]) {
3972 " export %s%s prefix-list %s\n",
3973 (rfg
->type
== RFAPI_GROUP_CFG_VRF
3977 rfg
->plist_export_zebra_name
3981 * currently we only support redist plists for
3983 * If we later add plist support for
3984 * redistributing other
3985 * protocols, we'll need to loop over protocols
3988 if (rfg
->plist_redist_name
3989 [ZEBRA_ROUTE_BGP_DIRECT
][afi
]) {
3991 " redistribute bgp-direct %s prefix-list %s\n",
3993 rfg
->plist_redist_name
3994 [ZEBRA_ROUTE_BGP_DIRECT
]
3997 if (rfg
->plist_redist_name
3998 [ZEBRA_ROUTE_BGP_DIRECT_EXT
][afi
]) {
4000 " redistribute bgp-direct-to-nve-groups %s prefix-list %s\n",
4002 rfg
->plist_redist_name
4003 [ZEBRA_ROUTE_BGP_DIRECT_EXT
]
4008 if (rfg
->routemap_export_bgp_name
) {
4009 vty_out(vty
, " export %sroute-map %s\n",
4010 (rfg
->type
== RFAPI_GROUP_CFG_VRF
4013 rfg
->routemap_export_bgp_name
);
4015 if (rfg
->routemap_export_zebra_name
) {
4016 vty_out(vty
, " export %sroute-map %s\n",
4017 (rfg
->type
== RFAPI_GROUP_CFG_VRF
4020 rfg
->routemap_export_zebra_name
);
4022 if (rfg
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
]) {
4024 " redistribute bgp-direct route-map %s\n",
4025 rfg
->routemap_redist_name
4026 [ZEBRA_ROUTE_BGP_DIRECT
]);
4028 if (rfg
->routemap_redist_name
4029 [ZEBRA_ROUTE_BGP_DIRECT_EXT
]) {
4031 " redistribute bgp-direct-to-nve-groups route-map %s\n",
4032 rfg
->routemap_redist_name
4033 [ZEBRA_ROUTE_BGP_DIRECT_EXT
]);
4035 vty_out(vty
, " exit-vrf-policy\n");
4036 vty_out(vty
, "!\n");
4038 if (hc
->flags
& BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
) {
4039 vty_out(vty
, " vnc advertise-un-method encap-safi\n");
4043 { /* was based on listen ports */
4044 /* for now allow both old and new */
4045 if (bgp
->rfapi
->rfp_methods
.cfg_cb
)
4046 write
+= (bgp
->rfapi
->rfp_methods
.cfg_cb
)(
4047 vty
, bgp
->rfapi
->rfp
);
4050 vty_out(vty
, "!\n");
4052 if (hc
->l2_groups
) {
4053 struct rfapi_l2_group_cfg
*rfg
= NULL
;
4054 struct listnode
*gnode
;
4055 for (ALL_LIST_ELEMENTS_RO(hc
->l2_groups
, gnode
, rfg
)) {
4056 struct listnode
*lnode
;
4059 vty_out(vty
, " vnc l2-group %s\n", rfg
->name
);
4060 if (rfg
->logical_net_id
!= 0)
4062 " logical-network-id %u\n",
4063 rfg
->logical_net_id
);
4064 if (rfg
->labels
!= NULL
4065 && listhead(rfg
->labels
) != NULL
) {
4066 vty_out(vty
, " labels ");
4067 for (ALL_LIST_ELEMENTS_RO(rfg
->labels
,
4070 vty_out(vty
, "%hu ",
4078 if (rfg
->rt_import_list
&& rfg
->rt_export_list
4079 && ecommunity_cmp(rfg
->rt_import_list
,
4080 rfg
->rt_export_list
)) {
4081 char *b
= ecommunity_ecom2str(
4082 rfg
->rt_import_list
,
4083 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4084 ECOMMUNITY_ROUTE_TARGET
);
4085 vty_out(vty
, " rt both %s\n", b
);
4086 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4088 if (rfg
->rt_import_list
) {
4089 char *b
= ecommunity_ecom2str(
4090 rfg
->rt_import_list
,
4091 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4092 ECOMMUNITY_ROUTE_TARGET
);
4093 vty_out(vty
, " rt import %s\n",
4095 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4097 if (rfg
->rt_export_list
) {
4098 char *b
= ecommunity_ecom2str(
4099 rfg
->rt_export_list
,
4100 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4101 ECOMMUNITY_ROUTE_TARGET
);
4102 vty_out(vty
, " rt export %s\n",
4104 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4107 if (bgp
->rfapi
->rfp_methods
.cfg_group_cb
)
4108 write
+= (bgp
->rfapi
->rfp_methods
4110 vty
, bgp
->rfapi
->rfp
,
4111 RFAPI_RFP_CFG_GROUP_L2
,
4112 rfg
->name
, rfg
->rfp_cfg
);
4113 vty_out(vty
, " exit-vnc\n");
4114 vty_out(vty
, "!\n");
4118 if (hc
->default_rd
.prefixlen
4119 || hc
->default_response_lifetime
4120 != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT
4121 || hc
->default_rt_import_list
|| hc
->default_rt_export_list
4122 || hc
->nve_groups_sequential
->count
) {
4126 vty_out(vty
, " vnc defaults\n");
4128 if (hc
->default_rd
.prefixlen
) {
4129 char buf
[RD_ADDRSTRLEN
];
4131 if (AF_UNIX
== hc
->default_rd
.family
) {
4134 value
= ((hc
->default_rd
.val
[6] << 8)
4136 | (hc
->default_rd
.val
[7]
4139 vty_out(vty
, " rd auto:vn:%d\n",
4143 vty_out(vty
, " rd %s\n",
4144 prefix_rd2str(&hc
->default_rd
,
4148 if (hc
->default_response_lifetime
4149 != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT
) {
4150 vty_out(vty
, " response-lifetime ");
4151 if (hc
->default_response_lifetime
!= UINT32_MAX
)
4153 hc
->default_response_lifetime
);
4155 vty_out(vty
, "infinite");
4158 if (hc
->default_rt_import_list
4159 && hc
->default_rt_export_list
4160 && ecommunity_cmp(hc
->default_rt_import_list
,
4161 hc
->default_rt_export_list
)) {
4162 char *b
= ecommunity_ecom2str(
4163 hc
->default_rt_import_list
,
4164 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4165 ECOMMUNITY_ROUTE_TARGET
);
4166 vty_out(vty
, " rt both %s\n", b
);
4167 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4169 if (hc
->default_rt_import_list
) {
4170 char *b
= ecommunity_ecom2str(
4171 hc
->default_rt_import_list
,
4172 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4173 ECOMMUNITY_ROUTE_TARGET
);
4174 vty_out(vty
, " rt import %s\n", b
);
4175 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4177 if (hc
->default_rt_export_list
) {
4178 char *b
= ecommunity_ecom2str(
4179 hc
->default_rt_export_list
,
4180 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4181 ECOMMUNITY_ROUTE_TARGET
);
4182 vty_out(vty
, " rt export %s\n", b
);
4183 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4186 if (bgp
->rfapi
->rfp_methods
.cfg_group_cb
)
4187 write
+= (bgp
->rfapi
->rfp_methods
.cfg_group_cb
)(
4188 vty
, bgp
->rfapi
->rfp
,
4189 RFAPI_RFP_CFG_GROUP_DEFAULT
, NULL
,
4190 bgp
->rfapi_cfg
->default_rfp_cfg
);
4191 vty_out(vty
, " exit-vnc\n");
4192 vty_out(vty
, "!\n");
4195 for (ALL_LIST_ELEMENTS(hc
->nve_groups_sequential
, node
, nnode
,
4197 if (rfg
->type
== RFAPI_GROUP_CFG_NVE
) {
4199 vty_out(vty
, " vnc nve-group %s\n", rfg
->name
);
4201 if (rfg
->vn_prefix
.family
&& rfg
->vn_node
) {
4202 char buf
[PREFIX_STRLEN
];
4204 prefix2str(&rfg
->vn_prefix
, buf
,
4206 vty_out(vty
, " prefix %s %s\n", "vn",
4210 if (rfg
->un_prefix
.family
&& rfg
->un_node
) {
4211 char buf
[PREFIX_STRLEN
];
4213 prefix2str(&rfg
->un_prefix
, buf
,
4215 vty_out(vty
, " prefix %s %s\n", "un",
4220 if (rfg
->rd
.prefixlen
) {
4221 char buf
[RD_ADDRSTRLEN
];
4223 if (AF_UNIX
== rfg
->rd
.family
) {
4227 value
= ((rfg
->rd
.val
[6] << 8)
4237 vty_out(vty
, " rd %s\n",
4242 if (rfg
->flags
& RFAPI_RFG_RESPONSE_LIFETIME
) {
4243 vty_out(vty
, " response-lifetime ");
4244 if (rfg
->response_lifetime
4247 rfg
->response_lifetime
);
4249 vty_out(vty
, "infinite");
4253 if (rfg
->rt_import_list
&& rfg
->rt_export_list
4254 && ecommunity_cmp(rfg
->rt_import_list
,
4255 rfg
->rt_export_list
)) {
4256 char *b
= ecommunity_ecom2str(
4257 rfg
->rt_import_list
,
4258 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4259 ECOMMUNITY_ROUTE_TARGET
);
4260 vty_out(vty
, " rt both %s\n", b
);
4261 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4263 if (rfg
->rt_import_list
) {
4264 char *b
= ecommunity_ecom2str(
4265 rfg
->rt_import_list
,
4266 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4267 ECOMMUNITY_ROUTE_TARGET
);
4268 vty_out(vty
, " rt import %s\n",
4270 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4272 if (rfg
->rt_export_list
) {
4273 char *b
= ecommunity_ecom2str(
4274 rfg
->rt_export_list
,
4275 ECOMMUNITY_FORMAT_ROUTE_MAP
,
4276 ECOMMUNITY_ROUTE_TARGET
);
4277 vty_out(vty
, " rt export %s\n",
4279 XFREE(MTYPE_ECOMMUNITY_STR
, b
);
4284 * route filtering: prefix-lists and route-maps
4286 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
4288 const char *afistr
= (afi
== AFI_IP
)
4292 if (rfg
->plist_export_bgp_name
[afi
]) {
4294 " export bgp %s prefix-list %s\n",
4296 rfg
->plist_export_bgp_name
4299 if (rfg
->plist_export_zebra_name
[afi
]) {
4301 " export zebra %s prefix-list %s\n",
4303 rfg
->plist_export_zebra_name
4307 * currently we only support redist
4308 * plists for bgp-direct.
4309 * If we later add plist support for
4310 * redistributing other
4311 * protocols, we'll need to loop over
4314 if (rfg
->plist_redist_name
4315 [ZEBRA_ROUTE_BGP_DIRECT
]
4318 " redistribute bgp-direct %s prefix-list %s\n",
4320 rfg
->plist_redist_name
4321 [ZEBRA_ROUTE_BGP_DIRECT
]
4324 if (rfg
->plist_redist_name
4325 [ZEBRA_ROUTE_BGP_DIRECT_EXT
]
4328 " redistribute bgp-direct-to-nve-groups %s prefix-list %s\n",
4330 rfg
->plist_redist_name
4331 [ZEBRA_ROUTE_BGP_DIRECT_EXT
]
4336 if (rfg
->routemap_export_bgp_name
) {
4338 " export bgp route-map %s\n",
4339 rfg
->routemap_export_bgp_name
);
4341 if (rfg
->routemap_export_zebra_name
) {
4343 " export zebra route-map %s\n",
4344 rfg
->routemap_export_zebra_name
);
4346 if (rfg
->routemap_redist_name
4347 [ZEBRA_ROUTE_BGP_DIRECT
]) {
4349 " redistribute bgp-direct route-map %s\n",
4350 rfg
->routemap_redist_name
4351 [ZEBRA_ROUTE_BGP_DIRECT
]);
4353 if (rfg
->routemap_redist_name
4354 [ZEBRA_ROUTE_BGP_DIRECT_EXT
]) {
4356 " redistribute bgp-direct-to-nve-groups route-map %s\n",
4357 rfg
->routemap_redist_name
4358 [ZEBRA_ROUTE_BGP_DIRECT_EXT
]);
4360 if (bgp
->rfapi
->rfp_methods
.cfg_group_cb
)
4361 write
+= (bgp
->rfapi
->rfp_methods
4363 vty
, bgp
->rfapi
->rfp
,
4364 RFAPI_RFP_CFG_GROUP_NVE
,
4365 rfg
->name
, rfg
->rfp_cfg
);
4366 vty_out(vty
, " exit-vnc\n");
4367 vty_out(vty
, "!\n");
4369 } /* have listen ports */
4372 * route export to other protocols
4374 if (VNC_EXPORT_BGP_GRP_ENABLED(hc
)) {
4375 vty_out(vty
, " vnc export bgp mode group-nve\n");
4376 } else if (VNC_EXPORT_BGP_RH_ENABLED(hc
)) {
4377 vty_out(vty
, " vnc export bgp mode registering-nve\n");
4378 } else if (VNC_EXPORT_BGP_CE_ENABLED(hc
)) {
4379 vty_out(vty
, " vnc export bgp mode ce\n");
4382 if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc
)) {
4383 vty_out(vty
, " vnc export zebra mode group-nve\n");
4384 } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc
)) {
4385 vty_out(vty
, " vnc export zebra mode registering-nve\n");
4388 if (hc
->rfg_export_direct_bgp_l
) {
4389 for (ALL_LIST_ELEMENTS(hc
->rfg_export_direct_bgp_l
, node
, nnode
,
4392 vty_out(vty
, " vnc export bgp group-nve group %s\n",
4397 if (hc
->rfg_export_zebra_l
) {
4398 for (ALL_LIST_ELEMENTS(hc
->rfg_export_zebra_l
, node
, nnode
,
4401 vty_out(vty
, " vnc export zebra group-nve group %s\n",
4407 if (hc
->rfg_redist_name
) {
4408 vty_out(vty
, " vnc redistribute nve-group %s\n",
4409 hc
->rfg_redist_name
);
4411 if (hc
->redist_lifetime
) {
4412 vty_out(vty
, " vnc redistribute lifetime %d\n",
4413 hc
->redist_lifetime
);
4415 if (hc
->resolve_nve_roo_local_admin
4416 != BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT
) {
4419 " vnc redistribute resolve-nve roo-ec-local-admin %d\n",
4420 hc
->resolve_nve_roo_local_admin
);
4423 if (hc
->redist_mode
) /* ! default */
4427 switch (hc
->redist_mode
) {
4428 case VNC_REDIST_MODE_PLAIN
:
4431 case VNC_REDIST_MODE_RFG
:
4434 case VNC_REDIST_MODE_RESOLVE_NVE
:
4439 vty_out(vty
, " vnc redistribute mode %s\n", s
);
4444 * route filtering: prefix-lists and route-maps
4446 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
4448 const char *afistr
= (afi
== AFI_IP
) ? "ipv4" : "ipv6";
4450 if (hc
->plist_export_bgp_name
[afi
]) {
4451 vty_out(vty
, " vnc export bgp %s prefix-list %s\n",
4452 afistr
, hc
->plist_export_bgp_name
[afi
]);
4454 if (hc
->plist_export_zebra_name
[afi
]) {
4455 vty_out(vty
, " vnc export zebra %s prefix-list %s\n",
4456 afistr
, hc
->plist_export_zebra_name
[afi
]);
4458 if (hc
->plist_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
][afi
]) {
4460 " vnc redistribute bgp-direct %s prefix-list %s\n",
4462 hc
->plist_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
]
4467 if (hc
->routemap_export_bgp_name
) {
4468 vty_out(vty
, " vnc export bgp route-map %s\n",
4469 hc
->routemap_export_bgp_name
);
4471 if (hc
->routemap_export_zebra_name
) {
4472 vty_out(vty
, " vnc export zebra route-map %s\n",
4473 hc
->routemap_export_zebra_name
);
4475 if (hc
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
]) {
4476 vty_out(vty
, " vnc redistribute bgp-direct route-map %s\n",
4477 hc
->routemap_redist_name
[ZEBRA_ROUTE_BGP_DIRECT
]);
4480 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
4481 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; ++type
) {
4482 if (hc
->redist
[afi
][type
]) {
4483 if (type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
4484 && hc
->redist_bgp_exterior_view_name
) {
4486 " vnc redistribute %s %s view %s\n",
4487 ((afi
== AFI_IP
) ? "ipv4"
4489 zebra_route_string(type
),
4490 hc
->redist_bgp_exterior_view_name
);
4493 " vnc redistribute %s %s\n",
4494 ((afi
== AFI_IP
) ? "ipv4"
4496 zebra_route_string(type
));
4504 void bgp_rfapi_show_summary(struct bgp
*bgp
, struct vty
*vty
)
4506 struct rfapi_cfg
*hc
= bgp
->rfapi_cfg
;
4508 int type
, redist
= 0;
4513 vty_out(vty
, "%-39s %-19s %s\n", "VNC Advertise method:",
4514 (hc
->flags
& BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
4515 ? "Encapsulation SAFI"
4516 : "Tunnel Encap attribute"),
4517 ((hc
->flags
& BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
)
4518 == (BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
4519 & BGP_VNC_CONFIG_FLAGS_DEFAULT
)
4523 vty_out(vty
, "%-39s ", "Export from VNC:");
4525 * route export to other protocols
4527 if (VNC_EXPORT_BGP_GRP_ENABLED(hc
)) {
4529 vty_out(vty
, "ToBGP Groups={");
4530 if (hc
->rfg_export_direct_bgp_l
) {
4532 struct listnode
*node
, *nnode
;
4533 struct rfapi_rfg_name
*rfgn
;
4534 for (ALL_LIST_ELEMENTS(hc
->rfg_export_direct_bgp_l
,
4535 node
, nnode
, rfgn
)) {
4539 vty_out(vty
, "%s", rfgn
->name
);
4543 } else if (VNC_EXPORT_BGP_RH_ENABLED(hc
)) {
4545 vty_out(vty
, "ToBGP {Registering NVE}");
4546 /* note filters, route-maps not shown */
4547 } else if (VNC_EXPORT_BGP_CE_ENABLED(hc
)) {
4549 vty_out(vty
, "ToBGP {NVE connected router:%d}",
4550 hc
->resolve_nve_roo_local_admin
);
4551 /* note filters, route-maps not shown */
4554 if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc
)) {
4556 vty_out(vty
, "%sToZebra Groups={", (redist
== 1 ? "" : " "));
4557 if (hc
->rfg_export_direct_bgp_l
) {
4559 struct listnode
*node
, *nnode
;
4560 struct rfapi_rfg_name
*rfgn
;
4561 for (ALL_LIST_ELEMENTS(hc
->rfg_export_zebra_l
, node
,
4565 vty_out(vty
, "%s", rfgn
->name
);
4569 } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc
)) {
4571 vty_out(vty
, "%sToZebra {Registering NVE}",
4572 (redist
== 1 ? "" : " "));
4573 /* note filters, route-maps not shown */
4575 vty_out(vty
, "%-19s %s\n", (redist
? "" : "Off"),
4576 (redist
? "" : "(default)"));
4578 /* Redistribution */
4580 vty_out(vty
, "%-39s ", "Redistribution into VNC:");
4581 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
4582 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; ++type
) {
4583 if (hc
->redist
[afi
][type
]) {
4584 vty_out(vty
, "{%s,%s} ",
4585 ((afi
== AFI_IP
) ? "ipv4" : "ipv6"),
4586 zebra_route_string(type
));
4591 vty_out(vty
, "%-19s %s\n", (redist
? "" : "Off"),
4592 (redist
? "" : "(default)"));
4594 vty_out(vty
, "%-39s %3u%-16s %s\n",
4595 "RFP Registration Hold-Down Factor:",
4596 hc
->rfp_cfg
.holddown_factor
, "%",
4597 (hc
->rfp_cfg
.holddown_factor
4598 == RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR
4601 vty_out(vty
, "%-39s %-19s %s\n", "RFP Updated responses:",
4602 (hc
->rfp_cfg
.use_updated_response
== 0 ? "Off" : "On"),
4603 (hc
->rfp_cfg
.use_updated_response
== 0 ? "(default)" : ""));
4604 vty_out(vty
, "%-39s %-19s %s\n", "RFP Removal responses:",
4605 (hc
->rfp_cfg
.use_removes
== 0 ? "Off" : "On"),
4606 (hc
->rfp_cfg
.use_removes
== 0 ? "(default)" : ""));
4607 vty_out(vty
, "%-39s %-19s %s\n", "RFP Full table download:",
4608 (hc
->rfp_cfg
.download_type
== RFAPI_RFP_DOWNLOAD_FULL
? "On"
4610 (hc
->rfp_cfg
.download_type
== RFAPI_RFP_DOWNLOAD_PARTIAL
4613 sprintf(tmp
, "%u seconds", hc
->rfp_cfg
.ftd_advertisement_interval
);
4614 vty_out(vty
, "%-39s %-19s %s\n", " Advertisement Interval:", tmp
,
4615 (hc
->rfp_cfg
.ftd_advertisement_interval
4616 == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL
4619 vty_out(vty
, "%-39s %d seconds\n", "Default RFP response lifetime:",
4620 hc
->default_response_lifetime
);
4625 struct rfapi_cfg
*bgp_rfapi_get_config(struct bgp
*bgp
)
4627 struct rfapi_cfg
*hc
= NULL
;
4629 bgp
= bgp_get_default();
4631 hc
= bgp
->rfapi_cfg
;
4635 #endif /* ENABLE_BGP_VNC */