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