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