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