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