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