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