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