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