]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
pimd: Option to get IGMP groups and sources for a particular interface
[mirror_frr.git] / bgpd / bgp_mplsvpn.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* MPLS-VPN
3 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4 */
5
6 #include <zebra.h>
7
8 #include "command.h"
9 #include "prefix.h"
10 #include "log.h"
11 #include "memory.h"
12 #include "stream.h"
13 #include "queue.h"
14 #include "filter.h"
15 #include "mpls.h"
16 #include "json.h"
17 #include "zclient.h"
18
19 #include "bgpd/bgpd.h"
20 #include "bgpd/bgp_debug.h"
21 #include "bgpd/bgp_errors.h"
22 #include "bgpd/bgp_table.h"
23 #include "bgpd/bgp_route.h"
24 #include "bgpd/bgp_attr.h"
25 #include "bgpd/bgp_label.h"
26 #include "bgpd/bgp_mplsvpn.h"
27 #include "bgpd/bgp_packet.h"
28 #include "bgpd/bgp_vty.h"
29 #include "bgpd/bgp_vpn.h"
30 #include "bgpd/bgp_community.h"
31 #include "bgpd/bgp_ecommunity.h"
32 #include "bgpd/bgp_zebra.h"
33 #include "bgpd/bgp_nexthop.h"
34 #include "bgpd/bgp_nht.h"
35 #include "bgpd/bgp_evpn.h"
36 #include "bgpd/bgp_memory.h"
37
38 #ifdef ENABLE_BGP_VNC
39 #include "bgpd/rfapi/rfapi_backend.h"
40 #endif
41
42 /*
43 * Definitions and external declarations.
44 */
45 extern struct zclient *zclient;
46
47 extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
48 int *index, afi_t *afi)
49 {
50 int ret = 0;
51 if (argv_find(argv, argc, "vpnv4", index)) {
52 ret = 1;
53 if (afi)
54 *afi = AFI_IP;
55 } else if (argv_find(argv, argc, "vpnv6", index)) {
56 ret = 1;
57 if (afi)
58 *afi = AFI_IP6;
59 }
60 return ret;
61 }
62
63 uint32_t decode_label(mpls_label_t *label_pnt)
64 {
65 uint32_t l;
66 uint8_t *pnt = (uint8_t *)label_pnt;
67
68 l = ((uint32_t)*pnt++ << 12);
69 l |= (uint32_t)*pnt++ << 4;
70 l |= (uint32_t)((*pnt & 0xf0) >> 4);
71 return l;
72 }
73
74 void encode_label(mpls_label_t label, mpls_label_t *label_pnt)
75 {
76 uint8_t *pnt = (uint8_t *)label_pnt;
77 if (pnt == NULL)
78 return;
79 if (label == BGP_PREVENT_VRF_2_VRF_LEAK) {
80 *label_pnt = label;
81 return;
82 }
83 *pnt++ = (label >> 12) & 0xff;
84 *pnt++ = (label >> 4) & 0xff;
85 *pnt++ = ((label << 4) + 1) & 0xff; /* S=1 */
86 }
87
88 int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
89 struct bgp_nlri *packet)
90 {
91 struct prefix p;
92 uint8_t psize = 0;
93 uint8_t prefixlen;
94 uint16_t type;
95 struct rd_as rd_as;
96 struct rd_ip rd_ip;
97 struct prefix_rd prd = {0};
98 mpls_label_t label = {0};
99 afi_t afi;
100 safi_t safi;
101 bool addpath_capable;
102 uint32_t addpath_id;
103 int ret = 0;
104
105 /* Make prefix_rd */
106 prd.family = AF_UNSPEC;
107 prd.prefixlen = 64;
108
109 struct stream *data = stream_new(packet->length);
110 stream_put(data, packet->nlri, packet->length);
111 afi = packet->afi;
112 safi = packet->safi;
113 addpath_id = 0;
114
115 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
116
117 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
118 while (STREAM_READABLE(data) > 0) {
119 /* Clear prefix structure. */
120 memset(&p, 0, sizeof(p));
121
122 if (addpath_capable) {
123 STREAM_GET(&addpath_id, data, BGP_ADDPATH_ID_LEN);
124 addpath_id = ntohl(addpath_id);
125 }
126
127 if (STREAM_READABLE(data) < 1) {
128 flog_err(
129 EC_BGP_UPDATE_RCV,
130 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no prefix length)",
131 peer->host, packet->length);
132 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
133 goto done;
134 }
135
136 /* Fetch prefix length. */
137 STREAM_GETC(data, prefixlen);
138 p.family = afi2family(packet->afi);
139 psize = PSIZE(prefixlen);
140
141 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
142 flog_err(
143 EC_BGP_UPDATE_RCV,
144 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
145 peer->host, prefixlen);
146 ret = BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
147 goto done;
148 }
149
150 /* sanity check against packet data */
151 if (STREAM_READABLE(data) < psize) {
152 flog_err(
153 EC_BGP_UPDATE_RCV,
154 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
155 peer->host, prefixlen, packet->length);
156 ret = BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
157 goto done;
158 }
159
160 /* sanity check against storage for the IP address portion */
161 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
162 flog_err(
163 EC_BGP_UPDATE_RCV,
164 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
165 peer->host,
166 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
167 sizeof(p.u));
168 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
169 goto done;
170 }
171
172 /* Sanity check against max bitlen of the address family */
173 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
174 flog_err(
175 EC_BGP_UPDATE_RCV,
176 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
177 peer->host,
178 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
179 p.family, prefix_blen(&p));
180 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
181 goto done;
182 }
183
184 /* Copy label to prefix. */
185 if (STREAM_READABLE(data) < BGP_LABEL_BYTES) {
186 flog_err(
187 EC_BGP_UPDATE_RCV,
188 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no label)",
189 peer->host, packet->length);
190 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
191 goto done;
192 }
193
194 STREAM_GET(&label, data, BGP_LABEL_BYTES);
195 bgp_set_valid_label(&label);
196
197 /* Copy routing distinguisher to rd. */
198 if (STREAM_READABLE(data) < 8) {
199 flog_err(
200 EC_BGP_UPDATE_RCV,
201 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no RD)",
202 peer->host, packet->length);
203 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
204 goto done;
205 }
206 STREAM_GET(&prd.val, data, 8);
207
208 /* Decode RD type. */
209 type = decode_rd_type(prd.val);
210
211 switch (type) {
212 case RD_TYPE_AS:
213 decode_rd_as(&prd.val[2], &rd_as);
214 break;
215
216 case RD_TYPE_AS4:
217 decode_rd_as4(&prd.val[2], &rd_as);
218 break;
219
220 case RD_TYPE_IP:
221 decode_rd_ip(&prd.val[2], &rd_ip);
222 break;
223
224 #ifdef ENABLE_BGP_VNC
225 case RD_TYPE_VNC_ETH:
226 break;
227 #endif
228
229 default:
230 flog_err(EC_BGP_UPDATE_RCV, "Unknown RD type %d", type);
231 break; /* just report */
232 }
233
234 /* exclude label & RD */
235 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8;
236 STREAM_GET(p.u.val, data, psize - VPN_PREFIXLEN_MIN_BYTES);
237
238 if (attr) {
239 bgp_update(peer, &p, addpath_id, attr, packet->afi,
240 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
241 BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
242 } else {
243 bgp_withdraw(peer, &p, addpath_id, packet->afi,
244 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
245 BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
246 }
247 }
248 /* Packet length consistency check. */
249 if (STREAM_READABLE(data) != 0) {
250 flog_err(
251 EC_BGP_UPDATE_RCV,
252 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
253 peer->host, STREAM_READABLE(data));
254 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
255 }
256
257 goto done;
258
259 stream_failure:
260 flog_err(
261 EC_BGP_UPDATE_RCV,
262 "%s [Error] Update packet error / VPN (NLRI of size %u - length error)",
263 peer->host, packet->length);
264 ret = BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
265
266 done:
267 stream_free(data);
268 return ret;
269
270 #undef VPN_PREFIXLEN_MIN_BYTES
271 }
272
273 /*
274 * This function informs zebra of the label this vrf sets on routes
275 * leaked to VPN. Zebra should install this label in the kernel with
276 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
277 *
278 * Sending this vrf-label association is qualified by a) whether vrf->vpn
279 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
280 * are set) and b) whether vpn-policy label is set.
281 *
282 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
283 * for this vrf, which zebra interprets to mean "delete this vrf-label
284 * association."
285 */
286 void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
287 {
288 mpls_label_t label = MPLS_LABEL_NONE;
289 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
290
291 if (bgp->vrf_id == VRF_UNKNOWN) {
292 if (debug) {
293 zlog_debug(
294 "%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
295 __func__, bgp->name_pretty, afi2str(afi));
296 }
297 return;
298 }
299
300 if (vpn_leak_to_vpn_active(bgp, afi, NULL)) {
301 label = bgp->vpn_policy[afi].tovpn_label;
302 }
303
304 if (debug) {
305 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
306 __func__, bgp->name_pretty, afi2str(afi), label,
307 bgp->vrf_id);
308 }
309
310 if (label == BGP_PREVENT_VRF_2_VRF_LEAK)
311 label = MPLS_LABEL_NONE;
312 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
313 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
314 }
315
316 /*
317 * If zebra tells us vrf has become unconfigured, tell zebra not to
318 * use this label to forward to the vrf anymore
319 */
320 void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi)
321 {
322 mpls_label_t label = MPLS_LABEL_NONE;
323 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
324
325 if (bgp->vrf_id == VRF_UNKNOWN) {
326 if (debug) {
327 zlog_debug(
328 "%s: vrf_id not set, can't delete zebra vrf label",
329 __func__);
330 }
331 return;
332 }
333
334 if (debug) {
335 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__,
336 bgp->name_pretty, bgp->vrf_id);
337 }
338
339 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
340 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
341 }
342
343 /*
344 * This function informs zebra of the srv6-function this vrf sets on routes
345 * leaked to VPN. Zebra should install this srv6-function in the kernel with
346 * an action of "End.DT4/6's IP FIB to route the PDU."
347 */
348 void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi)
349 {
350 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
351 enum seg6local_action_t act;
352 struct seg6local_context ctx = {};
353 struct in6_addr *tovpn_sid = NULL;
354 struct in6_addr *tovpn_sid_ls = NULL;
355 struct vrf *vrf;
356
357 if (bgp->vrf_id == VRF_UNKNOWN) {
358 if (debug)
359 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
360 __func__, bgp->name_pretty, afi2str(afi));
361 return;
362 }
363
364 tovpn_sid = bgp->vpn_policy[afi].tovpn_sid;
365 if (!tovpn_sid) {
366 if (debug)
367 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__,
368 bgp->name_pretty, afi2str(afi));
369 return;
370 }
371
372 if (debug)
373 zlog_debug("%s: vrf %s: afi %s: setting sid %pI6 for vrf id %d",
374 __func__, bgp->name_pretty, afi2str(afi), tovpn_sid,
375 bgp->vrf_id);
376
377 vrf = vrf_lookup_by_id(bgp->vrf_id);
378 if (!vrf)
379 return;
380
381 ctx.table = vrf->data.l.table_id;
382 act = afi == AFI_IP ? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
383 : ZEBRA_SEG6_LOCAL_ACTION_END_DT6;
384 zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
385
386 tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
387 *tovpn_sid_ls = *tovpn_sid;
388 bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent = tovpn_sid_ls;
389 }
390
391 /*
392 * This function informs zebra of the srv6-function this vrf sets on routes
393 * leaked to VPN. Zebra should install this srv6-function in the kernel with
394 * an action of "End.DT46's IP FIB to route the PDU."
395 */
396 void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp)
397 {
398 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
399 enum seg6local_action_t act;
400 struct seg6local_context ctx = {};
401 struct in6_addr *tovpn_sid = NULL;
402 struct in6_addr *tovpn_sid_ls = NULL;
403 struct vrf *vrf;
404
405 if (bgp->vrf_id == VRF_UNKNOWN) {
406 if (debug)
407 zlog_debug(
408 "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
409 __func__, bgp->name_pretty);
410 return;
411 }
412
413 tovpn_sid = bgp->tovpn_sid;
414 if (!tovpn_sid) {
415 if (debug)
416 zlog_debug("%s: vrf %s: sid not set", __func__,
417 bgp->name_pretty);
418 return;
419 }
420
421 if (debug)
422 zlog_debug("%s: vrf %s: setting sid %pI6 for vrf id %d",
423 __func__, bgp->name_pretty, tovpn_sid, bgp->vrf_id);
424
425 vrf = vrf_lookup_by_id(bgp->vrf_id);
426 if (!vrf)
427 return;
428
429 ctx.table = vrf->data.l.table_id;
430 act = ZEBRA_SEG6_LOCAL_ACTION_END_DT46;
431 zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
432
433 tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
434 *tovpn_sid_ls = *tovpn_sid;
435 bgp->tovpn_zebra_vrf_sid_last_sent = tovpn_sid_ls;
436 }
437
438 /*
439 * This function informs zebra of the srv6-function this vrf sets on routes
440 * leaked to VPN. Zebra should install this srv6-function in the kernel with
441 * an action of "End.DT4/6/46's IP FIB to route the PDU."
442 */
443 void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi)
444 {
445 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
446
447 if (bgp->vpn_policy[afi].tovpn_sid)
448 return vpn_leak_zebra_vrf_sid_update_per_af(bgp, afi);
449
450 if (bgp->tovpn_sid)
451 return vpn_leak_zebra_vrf_sid_update_per_vrf(bgp);
452
453 if (debug)
454 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__,
455 bgp->name_pretty, afi2str(afi));
456 }
457
458 /*
459 * If zebra tells us vrf has become unconfigured, tell zebra not to
460 * use this srv6-function to forward to the vrf anymore
461 */
462 void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi)
463 {
464 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
465
466 if (bgp->vrf_id == VRF_UNKNOWN) {
467 if (debug)
468 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
469 __func__, bgp->name_pretty, afi2str(afi));
470 return;
471 }
472
473 if (debug)
474 zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__,
475 bgp->name_pretty, bgp->vrf_id);
476
477 zclient_send_localsid(zclient,
478 bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent,
479 bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC, NULL);
480 XFREE(MTYPE_BGP_SRV6_SID,
481 bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent);
482 }
483
484 /*
485 * If zebra tells us vrf has become unconfigured, tell zebra not to
486 * use this srv6-function to forward to the vrf anymore
487 */
488 void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp)
489 {
490 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
491
492 if (bgp->vrf_id == VRF_UNKNOWN) {
493 if (debug)
494 zlog_debug(
495 "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
496 __func__, bgp->name_pretty);
497 return;
498 }
499
500 if (debug)
501 zlog_debug("%s: deleting sid for vrf %s (id=%d)", __func__,
502 bgp->name_pretty, bgp->vrf_id);
503
504 zclient_send_localsid(zclient, bgp->tovpn_zebra_vrf_sid_last_sent,
505 bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC,
506 NULL);
507 XFREE(MTYPE_BGP_SRV6_SID, bgp->tovpn_zebra_vrf_sid_last_sent);
508 }
509
510 /*
511 * If zebra tells us vrf has become unconfigured, tell zebra not to
512 * use this srv6-function to forward to the vrf anymore
513 */
514 void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi)
515 {
516 if (bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent)
517 vpn_leak_zebra_vrf_sid_withdraw_per_af(bgp, afi);
518
519 if (bgp->tovpn_zebra_vrf_sid_last_sent)
520 vpn_leak_zebra_vrf_sid_withdraw_per_vrf(bgp);
521 }
522
523 int vpn_leak_label_callback(
524 mpls_label_t label,
525 void *labelid,
526 bool allocated)
527 {
528 struct vpn_policy *vp = (struct vpn_policy *)labelid;
529 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
530
531 if (debug)
532 zlog_debug("%s: label=%u, allocated=%d",
533 __func__, label, allocated);
534
535 if (!allocated) {
536 /*
537 * previously-allocated label is now invalid
538 */
539 if (CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
540 (vp->tovpn_label != MPLS_LABEL_NONE)) {
541
542 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
543 vp->afi, bgp_get_default(), vp->bgp);
544 vp->tovpn_label = MPLS_LABEL_NONE;
545 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
546 vp->afi, bgp_get_default(), vp->bgp);
547 }
548 return 0;
549 }
550
551 /*
552 * New label allocation
553 */
554 if (!CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
555
556 /*
557 * not currently configured for auto label, reject allocation
558 */
559 return -1;
560 }
561
562 if (vp->tovpn_label != MPLS_LABEL_NONE) {
563 if (label == vp->tovpn_label) {
564 /* already have same label, accept but do nothing */
565 return 0;
566 }
567 /* Shouldn't happen: different label allocation */
568 flog_err(EC_BGP_LABEL,
569 "%s: %s had label %u but got new assignment %u",
570 __func__, vp->bgp->name_pretty, vp->tovpn_label,
571 label);
572 /* use new one */
573 }
574
575 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
576 vp->afi, bgp_get_default(), vp->bgp);
577 vp->tovpn_label = label;
578 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
579 vp->afi, bgp_get_default(), vp->bgp);
580
581 return 0;
582 }
583
584 static void sid_register(struct bgp *bgp, const struct in6_addr *sid,
585 const char *locator_name)
586 {
587 struct bgp_srv6_function *func;
588 func = XCALLOC(MTYPE_BGP_SRV6_FUNCTION,
589 sizeof(struct bgp_srv6_function));
590 func->sid = *sid;
591 snprintf(func->locator_name, sizeof(func->locator_name),
592 "%s", locator_name);
593 listnode_add(bgp->srv6_functions, func);
594 }
595
596 static void sid_unregister(struct bgp *bgp, const struct in6_addr *sid)
597 {
598 struct listnode *node, *nnode;
599 struct bgp_srv6_function *func;
600
601 for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func))
602 if (sid_same(&func->sid, sid)) {
603 listnode_delete(bgp->srv6_functions, func);
604 XFREE(MTYPE_BGP_SRV6_FUNCTION, func);
605 }
606 }
607
608 static bool sid_exist(struct bgp *bgp, const struct in6_addr *sid)
609 {
610 struct listnode *node;
611 struct bgp_srv6_function *func;
612
613 for (ALL_LIST_ELEMENTS_RO(bgp->srv6_functions, node, func))
614 if (sid_same(&func->sid, sid))
615 return true;
616 return false;
617 }
618
619 /*
620 * This function generates a new SID based on bgp->srv6_locator_chunks and
621 * index. The locator and generated SID are stored in arguments sid_locator
622 * and sid, respectively.
623 *
624 * if index != 0: try to allocate as index-mode
625 * else: try to allocate as auto-mode
626 */
627 static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
628 struct srv6_locator_chunk *sid_locator_chunk,
629 struct in6_addr *sid)
630 {
631 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
632 struct listnode *node;
633 struct srv6_locator_chunk *chunk;
634 bool alloced = false;
635 int label = 0;
636 uint8_t offset = 0;
637 uint8_t func_len = 0, shift_len = 0;
638 uint32_t index_max = 0;
639
640 if (!bgp || !sid_locator_chunk || !sid)
641 return false;
642
643 for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
644 if (chunk->function_bits_length >
645 BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH) {
646 if (debug)
647 zlog_debug(
648 "%s: invalid SRv6 Locator chunk (%pFX): Function Length must be less or equal to %d",
649 __func__, &chunk->prefix,
650 BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH);
651 continue;
652 }
653
654 index_max = (1 << chunk->function_bits_length) - 1;
655
656 if (index > index_max) {
657 if (debug)
658 zlog_debug(
659 "%s: skipped SRv6 Locator chunk (%pFX): Function Length is too short to support specified index (%u)",
660 __func__, &chunk->prefix, index);
661 continue;
662 }
663
664 *sid = chunk->prefix.prefix;
665 *sid_locator_chunk = *chunk;
666 offset = chunk->block_bits_length + chunk->node_bits_length;
667 func_len = chunk->function_bits_length;
668 shift_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH - func_len;
669
670 if (index != 0) {
671 label = index << shift_len;
672 if (label < MPLS_LABEL_UNRESERVED_MIN) {
673 if (debug)
674 zlog_debug(
675 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
676 __func__, &chunk->prefix,
677 label);
678 continue;
679 }
680
681 transpose_sid(sid, label, offset, func_len);
682 if (sid_exist(bgp, sid))
683 continue;
684 alloced = true;
685 break;
686 }
687
688 for (uint32_t i = 1; i < index_max; i++) {
689 label = i << shift_len;
690 if (label < MPLS_LABEL_UNRESERVED_MIN) {
691 if (debug)
692 zlog_debug(
693 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
694 __func__, &chunk->prefix,
695 label);
696 continue;
697 }
698 transpose_sid(sid, label, offset, func_len);
699 if (sid_exist(bgp, sid))
700 continue;
701 alloced = true;
702 break;
703 }
704 }
705
706 if (!alloced)
707 return 0;
708
709 sid_register(bgp, sid, bgp->srv6_locator_name);
710 return label;
711 }
712
713 void ensure_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
714 afi_t afi)
715 {
716 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
717 struct srv6_locator_chunk *tovpn_sid_locator;
718 struct in6_addr *tovpn_sid;
719 uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
720 bool tovpn_sid_auto = false;
721
722 if (debug)
723 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
724 __func__, bgp_vrf->name_pretty, afi2str(afi));
725
726 /* skip when tovpn sid is already allocated on vrf instance */
727 if (bgp_vrf->vpn_policy[afi].tovpn_sid)
728 return;
729
730 /*
731 * skip when bgp vpn instance ins't allocated
732 * or srv6 locator chunk isn't allocated
733 */
734 if (!bgp_vpn || !bgp_vpn->srv6_locator_chunks)
735 return;
736
737 tovpn_sid_index = bgp_vrf->vpn_policy[afi].tovpn_sid_index;
738 tovpn_sid_auto = CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
739 BGP_VPN_POLICY_TOVPN_SID_AUTO);
740
741 /* skip when VPN isn't configured on vrf-instance */
742 if (tovpn_sid_index == 0 && !tovpn_sid_auto)
743 return;
744
745 /* check invalid case both configured index and auto */
746 if (tovpn_sid_index != 0 && tovpn_sid_auto) {
747 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
748 __func__);
749 return;
750 }
751
752 tovpn_sid_locator = srv6_locator_chunk_alloc();
753 tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
754
755 tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index,
756 tovpn_sid_locator, tovpn_sid);
757
758 if (tovpn_sid_transpose_label == 0) {
759 if (debug)
760 zlog_debug(
761 "%s: not allocated new sid for vrf %s: afi %s",
762 __func__, bgp_vrf->name_pretty, afi2str(afi));
763 srv6_locator_chunk_free(&tovpn_sid_locator);
764 XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid);
765 return;
766 }
767
768 if (debug)
769 zlog_debug("%s: new sid %pI6 allocated for vrf %s: afi %s",
770 __func__, tovpn_sid, bgp_vrf->name_pretty,
771 afi2str(afi));
772
773 bgp_vrf->vpn_policy[afi].tovpn_sid = tovpn_sid;
774 bgp_vrf->vpn_policy[afi].tovpn_sid_locator = tovpn_sid_locator;
775 bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label =
776 tovpn_sid_transpose_label;
777 }
778
779 void ensure_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
780 {
781 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
782 struct srv6_locator_chunk *tovpn_sid_locator;
783 struct in6_addr *tovpn_sid;
784 uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
785 bool tovpn_sid_auto = false;
786
787 if (debug)
788 zlog_debug("%s: try to allocate new SID for vrf %s", __func__,
789 bgp_vrf->name_pretty);
790
791 /* skip when tovpn sid is already allocated on vrf instance */
792 if (bgp_vrf->tovpn_sid)
793 return;
794
795 /*
796 * skip when bgp vpn instance ins't allocated
797 * or srv6 locator chunk isn't allocated
798 */
799 if (!bgp_vpn || !bgp_vpn->srv6_locator_chunks)
800 return;
801
802 tovpn_sid_index = bgp_vrf->tovpn_sid_index;
803 tovpn_sid_auto = CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_AUTO);
804
805 /* skip when VPN isn't configured on vrf-instance */
806 if (tovpn_sid_index == 0 && !tovpn_sid_auto)
807 return;
808
809 /* check invalid case both configured index and auto */
810 if (tovpn_sid_index != 0 && tovpn_sid_auto) {
811 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
812 __func__);
813 return;
814 }
815
816 tovpn_sid_locator = srv6_locator_chunk_alloc();
817 tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
818
819 tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index,
820 tovpn_sid_locator, tovpn_sid);
821
822 if (tovpn_sid_transpose_label == 0) {
823 if (debug)
824 zlog_debug("%s: not allocated new sid for vrf %s",
825 __func__, bgp_vrf->name_pretty);
826 srv6_locator_chunk_free(&tovpn_sid_locator);
827 XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid);
828 return;
829 }
830
831 if (debug)
832 zlog_debug("%s: new sid %pI6 allocated for vrf %s", __func__,
833 tovpn_sid, bgp_vrf->name_pretty);
834
835 bgp_vrf->tovpn_sid = tovpn_sid;
836 bgp_vrf->tovpn_sid_locator = tovpn_sid_locator;
837 bgp_vrf->tovpn_sid_transpose_label = tovpn_sid_transpose_label;
838 }
839
840 void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
841 {
842 /* per-af sid */
843 if (bgp_vrf->vpn_policy[afi].tovpn_sid_index != 0 ||
844 CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
845 BGP_VPN_POLICY_TOVPN_SID_AUTO))
846 return ensure_vrf_tovpn_sid_per_af(bgp_vpn, bgp_vrf, afi);
847
848 /* per-vrf sid */
849 if (bgp_vrf->tovpn_sid_index != 0 ||
850 CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_AUTO))
851 return ensure_vrf_tovpn_sid_per_vrf(bgp_vpn, bgp_vrf);
852 }
853
854 void delete_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
855 afi_t afi)
856 {
857 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
858 uint32_t tovpn_sid_index = 0;
859 bool tovpn_sid_auto = false;
860
861 if (debug)
862 zlog_debug("%s: try to remove SID for vrf %s: afi %s", __func__,
863 bgp_vrf->name_pretty, afi2str(afi));
864
865 tovpn_sid_index = bgp_vrf->vpn_policy[afi].tovpn_sid_index;
866 tovpn_sid_auto = CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
867 BGP_VPN_POLICY_TOVPN_SID_AUTO);
868
869 /* skip when VPN is configured on vrf-instance */
870 if (tovpn_sid_index != 0 || tovpn_sid_auto)
871 return;
872
873 srv6_locator_chunk_free(&bgp_vrf->vpn_policy[afi].tovpn_sid_locator);
874
875 if (bgp_vrf->vpn_policy[afi].tovpn_sid) {
876 sid_unregister(bgp_vpn, bgp_vrf->vpn_policy[afi].tovpn_sid);
877 XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->vpn_policy[afi].tovpn_sid);
878 }
879 bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label = 0;
880 }
881
882 void delete_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
883 {
884 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
885 uint32_t tovpn_sid_index = 0;
886 bool tovpn_sid_auto = false;
887
888 if (debug)
889 zlog_debug("%s: try to remove SID for vrf %s", __func__,
890 bgp_vrf->name_pretty);
891
892 tovpn_sid_index = bgp_vrf->tovpn_sid_index;
893 tovpn_sid_auto =
894 CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VPN_POLICY_TOVPN_SID_AUTO);
895
896 /* skip when VPN is configured on vrf-instance */
897 if (tovpn_sid_index != 0 || tovpn_sid_auto)
898 return;
899
900 srv6_locator_chunk_free(&bgp_vrf->tovpn_sid_locator);
901
902 if (bgp_vrf->tovpn_sid) {
903 sid_unregister(bgp_vpn, bgp_vrf->tovpn_sid);
904 XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->tovpn_sid);
905 }
906 bgp_vrf->tovpn_sid_transpose_label = 0;
907 }
908
909 void delete_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
910 {
911 delete_vrf_tovpn_sid_per_af(bgp_vpn, bgp_vrf, afi);
912 delete_vrf_tovpn_sid_per_vrf(bgp_vpn, bgp_vrf);
913 }
914
915 /*
916 * This function embeds upper `len` bits of `label` in `sid`,
917 * starting at offset `offset` as seen from the MSB of `sid`.
918 *
919 * e.g. Given that `label` is 0x12345 and `len` is 16,
920 * then `label` will be embedded in `sid` as follows:
921 *
922 * <---- len ----->
923 * label: 0001 0002 0003 0004 0005
924 * sid: .... 0001 0002 0003 0004
925 * <---- len ----->
926 * ^
927 * |
928 * offset from MSB
929 *
930 * e.g. Given that `label` is 0x12345 and `len` is 8,
931 * `label` will be embedded in `sid` as follows:
932 *
933 * <- len ->
934 * label: 0001 0002 0003 0004 0005
935 * sid: .... 0001 0002 0000 0000
936 * <- len ->
937 * ^
938 * |
939 * offset from MSB
940 */
941 void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
942 uint8_t len)
943 {
944 for (uint8_t idx = 0; idx < len; idx++) {
945 uint8_t tidx = offset + idx;
946 sid->s6_addr[tidx / 8] &= ~(0x1 << (7 - tidx % 8));
947 if (label >> (19 - idx) & 0x1)
948 sid->s6_addr[tidx / 8] |= 0x1 << (7 - tidx % 8);
949 }
950 }
951
952 static bool labels_same(struct bgp_path_info *bpi, mpls_label_t *label,
953 uint32_t n)
954 {
955 uint32_t i;
956
957 if (!bpi->extra) {
958 if (!n)
959 return true;
960 else
961 return false;
962 }
963
964 if (n != bpi->extra->num_labels)
965 return false;
966
967 for (i = 0; i < n; ++i) {
968 if (label[i] != bpi->extra->label[i])
969 return false;
970 }
971 return true;
972 }
973
974 /*
975 * make encoded route labels match specified encoded label set
976 */
977 static void setlabels(struct bgp_path_info *bpi,
978 mpls_label_t *label, /* array of labels */
979 uint32_t num_labels)
980 {
981 if (num_labels)
982 assert(label);
983 assert(num_labels <= BGP_MAX_LABELS);
984
985 if (!num_labels) {
986 if (bpi->extra)
987 bpi->extra->num_labels = 0;
988 return;
989 }
990
991 struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi);
992 uint32_t i;
993
994 for (i = 0; i < num_labels; ++i) {
995 extra->label[i] = label[i];
996 if (!bgp_is_valid_label(&label[i])) {
997 bgp_set_valid_label(&extra->label[i]);
998 }
999 }
1000 extra->num_labels = num_labels;
1001 }
1002
1003 /*
1004 * make encoded route SIDs match specified encoded sid set
1005 */
1006 static void setsids(struct bgp_path_info *bpi,
1007 struct in6_addr *sid,
1008 uint32_t num_sids)
1009 {
1010 uint32_t i;
1011 struct bgp_path_info_extra *extra;
1012
1013 if (num_sids)
1014 assert(sid);
1015 assert(num_sids <= BGP_MAX_SIDS);
1016
1017 if (!num_sids) {
1018 if (bpi->extra)
1019 bpi->extra->num_sids = 0;
1020 return;
1021 }
1022
1023 extra = bgp_path_info_extra_get(bpi);
1024 for (i = 0; i < num_sids; i++)
1025 memcpy(&extra->sid[i].sid, &sid[i], sizeof(struct in6_addr));
1026 extra->num_sids = num_sids;
1027 }
1028
1029 static void unsetsids(struct bgp_path_info *bpi)
1030 {
1031 struct bgp_path_info_extra *extra;
1032
1033 extra = bgp_path_info_extra_get(bpi);
1034 extra->num_sids = 0;
1035 memset(extra->sid, 0, sizeof(extra->sid));
1036 }
1037
1038 static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,
1039 struct attr *new_attr, afi_t afi,
1040 safi_t safi,
1041 struct bgp_path_info *source_bpi,
1042 struct bgp_path_info *bpi,
1043 struct bgp *bgp_orig,
1044 const struct prefix *p, int debug)
1045 {
1046 struct bgp_path_info *bpi_ultimate;
1047 struct bgp *bgp_nexthop;
1048 bool nh_valid;
1049
1050 bpi_ultimate = bgp_get_imported_bpi_ultimate(source_bpi);
1051
1052 if (bpi->extra && bpi->extra->bgp_orig)
1053 bgp_nexthop = bpi->extra->bgp_orig;
1054 else
1055 bgp_nexthop = bgp_orig;
1056
1057 /*
1058 * No nexthop tracking for redistributed routes, for
1059 * EVPN-imported routes that get leaked, or for routes
1060 * leaked between VRFs with accept-own community.
1061 */
1062 if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE ||
1063 is_pi_family_evpn(bpi_ultimate) ||
1064 CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_ACCEPT_OWN))
1065 nh_valid = true;
1066 else
1067 /*
1068 * TBD do we need to do anything about the
1069 * 'connected' parameter?
1070 */
1071 nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, afi,
1072 safi, bpi, NULL, 0, p);
1073
1074 /*
1075 * If you are using SRv6 VPN instead of MPLS, it need to check
1076 * the SID allocation. If the sid is not allocated, the rib
1077 * will be invalid.
1078 */
1079 if (to_bgp->srv6_enabled &&
1080 (!new_attr->srv6_l3vpn && !new_attr->srv6_vpn)) {
1081 nh_valid = false;
1082 }
1083
1084 if (debug)
1085 zlog_debug("%s: %pFX nexthop is %svalid (in %s)", __func__, p,
1086 (nh_valid ? "" : "not "), bgp_nexthop->name_pretty);
1087
1088 return nh_valid;
1089 }
1090
1091 /*
1092 * returns pointer to new bgp_path_info upon success
1093 */
1094 static struct bgp_path_info *
1095 leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
1096 struct attr *new_attr, /* already interned */
1097 afi_t afi, safi_t safi, struct bgp_path_info *source_bpi,
1098 mpls_label_t *label, uint32_t num_labels, struct bgp *bgp_orig,
1099 struct prefix *nexthop_orig, int nexthop_self_flag, int debug)
1100 {
1101 const struct prefix *p = bgp_dest_get_prefix(bn);
1102 struct bgp_path_info *bpi;
1103 struct bgp_path_info *new;
1104 struct bgp_path_info_extra *extra;
1105 uint32_t num_sids = 0;
1106 void *parent = source_bpi;
1107
1108 if (new_attr->srv6_l3vpn || new_attr->srv6_vpn)
1109 num_sids = 1;
1110
1111 if (debug)
1112 zlog_debug(
1113 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
1114 __func__, to_bgp->name_pretty, bn, source_bpi->type,
1115 source_bpi->sub_type);
1116
1117 /*
1118 * Routes that are redistributed into BGP from zebra do not get
1119 * nexthop tracking. However, if those routes are subsequently
1120 * imported to other RIBs within BGP, the leaked routes do not
1121 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
1122 * in order to determine if the route we are currently leaking
1123 * should have nexthop tracking, we must find the ultimate
1124 * parent so we can check its sub_type.
1125 *
1126 * As of now, source_bpi may at most be a second-generation route
1127 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
1128 * Using a loop here supports more complex intra-bgp import-export
1129 * schemes that could be implemented in the future.
1130 *
1131 */
1132
1133 /*
1134 * match parent
1135 */
1136 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
1137 if (bpi->extra && bpi->extra->parent == parent)
1138 break;
1139 }
1140
1141 if (bpi) {
1142 bool labelssame = labels_same(bpi, label, num_labels);
1143
1144 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)
1145 && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
1146 if (debug) {
1147 zlog_debug(
1148 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
1149 __func__, to_bgp->name_pretty,
1150 source_bpi->flags, bpi->flags, p);
1151 }
1152 return NULL;
1153 }
1154
1155 if (attrhash_cmp(bpi->attr, new_attr) && labelssame
1156 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
1157
1158 bgp_attr_unintern(&new_attr);
1159 if (debug)
1160 zlog_debug(
1161 "%s: ->%s: %pBD: Found route, no change",
1162 __func__, to_bgp->name_pretty, bn);
1163 return NULL;
1164 }
1165
1166 /* If the RT was changed via extended communities as an
1167 * import/export list, we should withdraw implicitly the old
1168 * path from VRFs.
1169 * For instance, RT list was modified using route-maps:
1170 * route-map test permit 10
1171 * set extcommunity rt none
1172 */
1173 if (CHECK_FLAG(bpi->attr->flag,
1174 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
1175 CHECK_FLAG(new_attr->flag,
1176 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
1177 if (!ecommunity_cmp(
1178 bgp_attr_get_ecommunity(bpi->attr),
1179 bgp_attr_get_ecommunity(new_attr))) {
1180 vpn_leak_to_vrf_withdraw(bpi);
1181 bgp_aggregate_decrement(to_bgp, p, bpi, afi,
1182 safi);
1183 bgp_path_info_delete(bn, bpi);
1184 }
1185 }
1186
1187 /* attr is changed */
1188 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
1189
1190 /* Rewrite BGP route information. */
1191 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
1192 bgp_path_info_restore(bn, bpi);
1193 else
1194 bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi);
1195 bgp_attr_unintern(&bpi->attr);
1196 bpi->attr = new_attr;
1197 bpi->uptime = monotime(NULL);
1198
1199 /*
1200 * rewrite labels
1201 */
1202 if (!labelssame)
1203 setlabels(bpi, label, num_labels);
1204
1205 /*
1206 * rewrite sid
1207 */
1208 if (num_sids) {
1209 if (new_attr->srv6_l3vpn) {
1210 setsids(bpi, &new_attr->srv6_l3vpn->sid,
1211 num_sids);
1212
1213 extra = bgp_path_info_extra_get(bpi);
1214
1215 extra->sid[0].loc_block_len =
1216 new_attr->srv6_l3vpn->loc_block_len;
1217 extra->sid[0].loc_node_len =
1218 new_attr->srv6_l3vpn->loc_node_len;
1219 extra->sid[0].func_len =
1220 new_attr->srv6_l3vpn->func_len;
1221 extra->sid[0].arg_len =
1222 new_attr->srv6_l3vpn->arg_len;
1223 extra->sid[0].transposition_len =
1224 new_attr->srv6_l3vpn->transposition_len;
1225 extra->sid[0].transposition_offset =
1226 new_attr->srv6_l3vpn
1227 ->transposition_offset;
1228 } else if (new_attr->srv6_vpn)
1229 setsids(bpi, &new_attr->srv6_vpn->sid,
1230 num_sids);
1231 } else
1232 unsetsids(bpi);
1233
1234 if (nexthop_self_flag)
1235 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
1236
1237 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN))
1238 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ACCEPT_OWN);
1239
1240 if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi,
1241 source_bpi, bpi, bgp_orig, p,
1242 debug))
1243 bgp_path_info_set_flag(bn, bpi, BGP_PATH_VALID);
1244 else
1245 bgp_path_info_unset_flag(bn, bpi, BGP_PATH_VALID);
1246
1247 /* Process change. */
1248 bgp_aggregate_increment(to_bgp, p, bpi, afi, safi);
1249 bgp_process(to_bgp, bn, afi, safi);
1250 bgp_dest_unlock_node(bn);
1251
1252 if (debug)
1253 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
1254 __func__, to_bgp->name_pretty, bn);
1255
1256 return bpi;
1257 }
1258
1259 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)) {
1260 if (debug) {
1261 zlog_debug(
1262 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
1263 __func__, to_bgp->name_pretty,
1264 source_bpi->flags, p);
1265 }
1266 return NULL;
1267 }
1268
1269 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
1270 to_bgp->peer_self, new_attr, bn);
1271
1272 if (source_bpi->peer) {
1273 extra = bgp_path_info_extra_get(new);
1274 extra->peer_orig = peer_lock(source_bpi->peer);
1275 }
1276
1277 if (nexthop_self_flag)
1278 bgp_path_info_set_flag(bn, new, BGP_PATH_ANNC_NH_SELF);
1279
1280 if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN))
1281 bgp_path_info_set_flag(bn, new, BGP_PATH_ACCEPT_OWN);
1282
1283 bgp_path_info_extra_get(new);
1284
1285 /*
1286 * rewrite sid
1287 */
1288 if (num_sids) {
1289 if (new_attr->srv6_l3vpn) {
1290 setsids(new, &new_attr->srv6_l3vpn->sid, num_sids);
1291
1292 extra = bgp_path_info_extra_get(new);
1293
1294 extra->sid[0].loc_block_len =
1295 new_attr->srv6_l3vpn->loc_block_len;
1296 extra->sid[0].loc_node_len =
1297 new_attr->srv6_l3vpn->loc_node_len;
1298 extra->sid[0].func_len = new_attr->srv6_l3vpn->func_len;
1299 extra->sid[0].arg_len = new_attr->srv6_l3vpn->arg_len;
1300 extra->sid[0].transposition_len =
1301 new_attr->srv6_l3vpn->transposition_len;
1302 extra->sid[0].transposition_offset =
1303 new_attr->srv6_l3vpn->transposition_offset;
1304 } else if (new_attr->srv6_vpn)
1305 setsids(new, &new_attr->srv6_vpn->sid, num_sids);
1306 } else
1307 unsetsids(new);
1308
1309 if (num_labels)
1310 setlabels(new, label, num_labels);
1311
1312 new->extra->parent = bgp_path_info_lock(parent);
1313 bgp_dest_lock_node(
1314 (struct bgp_dest *)((struct bgp_path_info *)parent)->net);
1315 if (bgp_orig)
1316 new->extra->bgp_orig = bgp_lock(bgp_orig);
1317 if (nexthop_orig)
1318 new->extra->nexthop_orig = *nexthop_orig;
1319
1320 if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi,
1321 source_bpi, new, bgp_orig, p, debug))
1322 bgp_path_info_set_flag(bn, new, BGP_PATH_VALID);
1323 else
1324 bgp_path_info_unset_flag(bn, new, BGP_PATH_VALID);
1325
1326 bgp_aggregate_increment(to_bgp, p, new, afi, safi);
1327 bgp_path_info_add(bn, new);
1328
1329 bgp_dest_unlock_node(bn);
1330 bgp_process(to_bgp, bn, afi, safi);
1331
1332 if (debug)
1333 zlog_debug("%s: ->%s: %pBD: Added new route", __func__,
1334 to_bgp->name_pretty, bn);
1335
1336 return new;
1337 }
1338
1339 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1340 void vpn_leak_from_vrf_update(struct bgp *to_bgp, /* to */
1341 struct bgp *from_bgp, /* from */
1342 struct bgp_path_info *path_vrf) /* route */
1343 {
1344 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1345 const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
1346 afi_t afi = family2afi(p->family);
1347 struct attr static_attr = {0};
1348 struct attr *new_attr = NULL;
1349 safi_t safi = SAFI_MPLS_VPN;
1350 mpls_label_t label_val;
1351 mpls_label_t label;
1352 struct bgp_dest *bn;
1353 const char *debugmsg;
1354 int nexthop_self_flag = 0;
1355
1356 if (debug)
1357 zlog_debug("%s: from vrf %s", __func__, from_bgp->name_pretty);
1358
1359 if (debug && bgp_attr_get_ecommunity(path_vrf->attr)) {
1360 char *s = ecommunity_ecom2str(
1361 bgp_attr_get_ecommunity(path_vrf->attr),
1362 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1363
1364 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__,
1365 from_bgp->name, path_vrf->type, s);
1366 XFREE(MTYPE_ECOMMUNITY_STR, s);
1367 }
1368
1369 if (!to_bgp)
1370 return;
1371
1372 if (!afi) {
1373 if (debug)
1374 zlog_debug("%s: can't get afi of prefix", __func__);
1375 return;
1376 }
1377
1378 /* Is this route exportable into the VPN table? */
1379 if (!is_route_injectable_into_vpn(path_vrf))
1380 return;
1381
1382 if (!vpn_leak_to_vpn_active(from_bgp, afi, &debugmsg)) {
1383 if (debug)
1384 zlog_debug("%s: %s skipping: %s", __func__,
1385 from_bgp->name, debugmsg);
1386 return;
1387 }
1388
1389 /* shallow copy */
1390 static_attr = *path_vrf->attr;
1391
1392 /*
1393 * route map handling
1394 */
1395 if (from_bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
1396 struct bgp_path_info info;
1397 route_map_result_t ret;
1398
1399 memset(&info, 0, sizeof(info));
1400 info.peer = to_bgp->peer_self;
1401 info.attr = &static_attr;
1402 ret = route_map_apply(from_bgp->vpn_policy[afi]
1403 .rmap[BGP_VPN_POLICY_DIR_TOVPN],
1404 p, &info);
1405 if (RMAP_DENYMATCH == ret) {
1406 bgp_attr_flush(&static_attr); /* free any added parts */
1407 if (debug)
1408 zlog_debug(
1409 "%s: vrf %s route map \"%s\" says DENY, returning",
1410 __func__, from_bgp->name_pretty,
1411 from_bgp->vpn_policy[afi]
1412 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
1413 ->name);
1414 return;
1415 }
1416 }
1417
1418 if (debug && bgp_attr_get_ecommunity(&static_attr)) {
1419 char *s = ecommunity_ecom2str(
1420 bgp_attr_get_ecommunity(&static_attr),
1421 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1422
1423 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1424 __func__, s);
1425 XFREE(MTYPE_ECOMMUNITY_STR, s);
1426 }
1427
1428 /*
1429 * Add the vpn-policy rt-list
1430 */
1431 struct ecommunity *old_ecom;
1432 struct ecommunity *new_ecom;
1433
1434 /* Export with the 'from' instance's export RTs. */
1435 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1436 old_ecom = bgp_attr_get_ecommunity(&static_attr);
1437 if (old_ecom) {
1438 new_ecom = ecommunity_dup(old_ecom);
1439 if (CHECK_FLAG(from_bgp->af_flags[afi][SAFI_UNICAST],
1440 BGP_CONFIG_VRF_TO_VRF_EXPORT))
1441 ecommunity_strip_rts(new_ecom);
1442 new_ecom = ecommunity_merge(
1443 new_ecom, from_bgp->vpn_policy[afi]
1444 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
1445 if (!old_ecom->refcnt)
1446 ecommunity_free(&old_ecom);
1447 } else {
1448 new_ecom = ecommunity_dup(
1449 from_bgp->vpn_policy[afi]
1450 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
1451 }
1452 bgp_attr_set_ecommunity(&static_attr, new_ecom);
1453
1454 if (debug && bgp_attr_get_ecommunity(&static_attr)) {
1455 char *s = ecommunity_ecom2str(
1456 bgp_attr_get_ecommunity(&static_attr),
1457 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1458
1459 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1460 __func__, s);
1461 XFREE(MTYPE_ECOMMUNITY_STR, s);
1462 }
1463
1464 community_strip_accept_own(&static_attr);
1465
1466 /* Nexthop */
1467 /* if policy nexthop not set, use 0 */
1468 if (CHECK_FLAG(from_bgp->vpn_policy[afi].flags,
1469 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
1470 struct prefix *nexthop =
1471 &from_bgp->vpn_policy[afi].tovpn_nexthop;
1472
1473 switch (nexthop->family) {
1474 case AF_INET:
1475 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1476 */
1477 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
1478
1479 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
1480 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1481 break;
1482
1483 case AF_INET6:
1484 static_attr.mp_nexthop_global = nexthop->u.prefix6;
1485 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
1486 break;
1487
1488 default:
1489 assert(0);
1490 }
1491 } else {
1492 if (!CHECK_FLAG(from_bgp->af_flags[afi][SAFI_UNICAST],
1493 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
1494 if (afi == AFI_IP &&
1495 !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
1496 /*
1497 * For ipv4, copy to multiprotocol
1498 * nexthop field
1499 */
1500 static_attr.mp_nexthop_global_in =
1501 static_attr.nexthop;
1502 static_attr.mp_nexthop_len =
1503 BGP_ATTR_NHLEN_IPV4;
1504 /*
1505 * XXX Leave static_attr.nexthop
1506 * intact for NHT
1507 */
1508 static_attr.flag &=
1509 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1510 }
1511 } else {
1512 /* Update based on next-hop family to account for
1513 * RFC 5549 (BGP unnumbered) scenario. Note that
1514 * specific action is only needed for the case of
1515 * IPv4 nexthops as the attr has been copied
1516 * otherwise.
1517 */
1518 if (afi == AFI_IP
1519 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
1520 static_attr.mp_nexthop_global_in.s_addr =
1521 static_attr.nexthop.s_addr;
1522 static_attr.mp_nexthop_len =
1523 BGP_ATTR_NHLEN_IPV4;
1524 static_attr.flag |=
1525 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1526 }
1527 }
1528 nexthop_self_flag = 1;
1529 }
1530
1531 label_val = from_bgp->vpn_policy[afi].tovpn_label;
1532 if (label_val == MPLS_LABEL_NONE) {
1533 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
1534 } else {
1535 encode_label(label_val, &label);
1536 }
1537
1538 /* Set originator ID to "me" */
1539 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
1540 static_attr.originator_id = to_bgp->router_id;
1541
1542 /* Set SID for SRv6 VPN */
1543 if (from_bgp->vpn_policy[afi].tovpn_sid_locator) {
1544 struct srv6_locator_chunk *locator =
1545 from_bgp->vpn_policy[afi].tovpn_sid_locator;
1546 encode_label(
1547 from_bgp->vpn_policy[afi].tovpn_sid_transpose_label,
1548 &label);
1549 static_attr.srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
1550 sizeof(struct bgp_attr_srv6_l3vpn));
1551 static_attr.srv6_l3vpn->sid_flags = 0x00;
1552 static_attr.srv6_l3vpn->endpoint_behavior =
1553 afi == AFI_IP
1554 ? (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1555 ? SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID
1556 : SRV6_ENDPOINT_BEHAVIOR_END_DT4)
1557 : (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1558 ? SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID
1559 : SRV6_ENDPOINT_BEHAVIOR_END_DT6);
1560 static_attr.srv6_l3vpn->loc_block_len =
1561 from_bgp->vpn_policy[afi]
1562 .tovpn_sid_locator->block_bits_length;
1563 static_attr.srv6_l3vpn->loc_node_len =
1564 from_bgp->vpn_policy[afi]
1565 .tovpn_sid_locator->node_bits_length;
1566 static_attr.srv6_l3vpn->func_len =
1567 from_bgp->vpn_policy[afi]
1568 .tovpn_sid_locator->function_bits_length;
1569 static_attr.srv6_l3vpn->arg_len =
1570 from_bgp->vpn_policy[afi]
1571 .tovpn_sid_locator->argument_bits_length;
1572 static_attr.srv6_l3vpn->transposition_len =
1573 from_bgp->vpn_policy[afi]
1574 .tovpn_sid_locator->function_bits_length;
1575 static_attr.srv6_l3vpn->transposition_offset =
1576 from_bgp->vpn_policy[afi]
1577 .tovpn_sid_locator->block_bits_length +
1578 from_bgp->vpn_policy[afi]
1579 .tovpn_sid_locator->node_bits_length;
1580 ;
1581 memcpy(&static_attr.srv6_l3vpn->sid,
1582 &from_bgp->vpn_policy[afi]
1583 .tovpn_sid_locator->prefix.prefix,
1584 sizeof(struct in6_addr));
1585 } else if (from_bgp->tovpn_sid_locator) {
1586 struct srv6_locator_chunk *locator =
1587 from_bgp->tovpn_sid_locator;
1588 encode_label(from_bgp->tovpn_sid_transpose_label, &label);
1589 static_attr.srv6_l3vpn =
1590 XCALLOC(MTYPE_BGP_SRV6_L3VPN,
1591 sizeof(struct bgp_attr_srv6_l3vpn));
1592 static_attr.srv6_l3vpn->sid_flags = 0x00;
1593 static_attr.srv6_l3vpn->endpoint_behavior =
1594 CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
1595 ? SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID
1596 : SRV6_ENDPOINT_BEHAVIOR_END_DT46;
1597 static_attr.srv6_l3vpn->loc_block_len =
1598 from_bgp->tovpn_sid_locator->block_bits_length;
1599 static_attr.srv6_l3vpn->loc_node_len =
1600 from_bgp->tovpn_sid_locator->node_bits_length;
1601 static_attr.srv6_l3vpn->func_len =
1602 from_bgp->tovpn_sid_locator->function_bits_length;
1603 static_attr.srv6_l3vpn->arg_len =
1604 from_bgp->tovpn_sid_locator->argument_bits_length;
1605 static_attr.srv6_l3vpn->transposition_len =
1606 from_bgp->tovpn_sid_locator->function_bits_length;
1607 static_attr.srv6_l3vpn->transposition_offset =
1608 from_bgp->tovpn_sid_locator->block_bits_length +
1609 from_bgp->tovpn_sid_locator->node_bits_length;
1610 memcpy(&static_attr.srv6_l3vpn->sid,
1611 &from_bgp->tovpn_sid_locator->prefix.prefix,
1612 sizeof(struct in6_addr));
1613 }
1614
1615
1616 new_attr = bgp_attr_intern(
1617 &static_attr); /* hashed refcounted everything */
1618 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
1619
1620 if (debug && bgp_attr_get_ecommunity(new_attr)) {
1621 char *s = ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr),
1622 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1623
1624 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
1625 XFREE(MTYPE_ECOMMUNITY_STR, s);
1626 }
1627
1628 /* Now new_attr is an allocated interned attr */
1629
1630 bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p,
1631 &(from_bgp->vpn_policy[afi].tovpn_rd));
1632
1633 struct bgp_path_info *new_info;
1634
1635 new_info =
1636 leak_update(to_bgp, bn, new_attr, afi, safi, path_vrf, &label,
1637 1, from_bgp, NULL, nexthop_self_flag, debug);
1638
1639 /*
1640 * Routes actually installed in the vpn RIB must also be
1641 * offered to all vrfs (because now they originate from
1642 * the vpn RIB).
1643 *
1644 * Acceptance into other vrfs depends on rt-lists.
1645 * Originating vrf will not accept the looped back route
1646 * because of loop checking.
1647 */
1648 if (new_info)
1649 vpn_leak_to_vrf_update(from_bgp, new_info, NULL);
1650 else
1651 bgp_dest_unlock_node(bn);
1652 }
1653
1654 void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, /* to */
1655 struct bgp *from_bgp, /* from */
1656 struct bgp_path_info *path_vrf) /* route */
1657 {
1658 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1659 const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
1660 afi_t afi = family2afi(p->family);
1661 safi_t safi = SAFI_MPLS_VPN;
1662 struct bgp_path_info *bpi;
1663 struct bgp_dest *bn;
1664 const char *debugmsg;
1665
1666 if (debug) {
1667 zlog_debug(
1668 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1669 __func__, from_bgp->name_pretty, path_vrf->net,
1670 path_vrf->type, path_vrf->sub_type);
1671 }
1672
1673 if (!to_bgp)
1674 return;
1675
1676 if (!afi) {
1677 if (debug)
1678 zlog_debug("%s: can't get afi of prefix", __func__);
1679 return;
1680 }
1681
1682 /* Is this route exportable into the VPN table? */
1683 if (!is_route_injectable_into_vpn(path_vrf))
1684 return;
1685
1686 if (!vpn_leak_to_vpn_active(from_bgp, afi, &debugmsg)) {
1687 if (debug)
1688 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1689 return;
1690 }
1691
1692 if (debug)
1693 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
1694
1695 bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p,
1696 &(from_bgp->vpn_policy[afi].tovpn_rd));
1697
1698 if (!bn)
1699 return;
1700 /*
1701 * vrf -> vpn
1702 * match original bpi imported from
1703 */
1704 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
1705 if (bpi->extra && bpi->extra->parent == path_vrf) {
1706 break;
1707 }
1708 }
1709
1710 if (bpi) {
1711 /* withdraw from looped vrfs as well */
1712 vpn_leak_to_vrf_withdraw(bpi);
1713
1714 bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi);
1715 bgp_path_info_delete(bn, bpi);
1716 bgp_process(to_bgp, bn, afi, safi);
1717 }
1718 bgp_dest_unlock_node(bn);
1719 }
1720
1721 void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp,
1722 afi_t afi)
1723 {
1724 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1725 struct bgp_dest *pdest;
1726 safi_t safi = SAFI_MPLS_VPN;
1727
1728 /*
1729 * Walk vpn table, delete bpi with bgp_orig == from_bgp
1730 */
1731 for (pdest = bgp_table_top(to_bgp->rib[afi][safi]); pdest;
1732 pdest = bgp_route_next(pdest)) {
1733
1734 struct bgp_table *table;
1735 struct bgp_dest *bn;
1736 struct bgp_path_info *bpi;
1737
1738 /* This is the per-RD table of prefixes */
1739 table = bgp_dest_get_bgp_table_info(pdest);
1740
1741 if (!table)
1742 continue;
1743
1744 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1745 bpi = bgp_dest_get_bgp_path_info(bn);
1746 if (debug && bpi) {
1747 zlog_debug("%s: looking at prefix %pBD",
1748 __func__, bn);
1749 }
1750
1751 for (; bpi; bpi = bpi->next) {
1752 if (debug)
1753 zlog_debug("%s: type %d, sub_type %d",
1754 __func__, bpi->type,
1755 bpi->sub_type);
1756 if (bpi->sub_type != BGP_ROUTE_IMPORTED)
1757 continue;
1758 if (!bpi->extra)
1759 continue;
1760 if ((struct bgp *)bpi->extra->bgp_orig ==
1761 from_bgp) {
1762 /* delete route */
1763 if (debug)
1764 zlog_debug("%s: deleting it",
1765 __func__);
1766 /* withdraw from leak-to vrfs as well */
1767 vpn_leak_to_vrf_withdraw(bpi);
1768 bgp_aggregate_decrement(
1769 to_bgp, bgp_dest_get_prefix(bn),
1770 bpi, afi, safi);
1771 bgp_path_info_delete(bn, bpi);
1772 bgp_process(to_bgp, bn, afi, safi);
1773 }
1774 }
1775 }
1776 }
1777 }
1778
1779 void vpn_leak_from_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
1780 afi_t afi)
1781 {
1782 struct bgp_dest *bn;
1783 struct bgp_path_info *bpi;
1784 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1785
1786 if (debug)
1787 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
1788 from_bgp->name_pretty);
1789
1790 for (bn = bgp_table_top(from_bgp->rib[afi][SAFI_UNICAST]); bn;
1791 bn = bgp_route_next(bn)) {
1792
1793 if (debug)
1794 zlog_debug("%s: node=%p", __func__, bn);
1795
1796 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
1797 bpi = bpi->next) {
1798 if (debug)
1799 zlog_debug(
1800 "%s: calling vpn_leak_from_vrf_update",
1801 __func__);
1802 vpn_leak_from_vrf_update(to_bgp, from_bgp, bpi);
1803 }
1804 }
1805 }
1806
1807 static struct bgp *bgp_lookup_by_rd(struct bgp_path_info *bpi,
1808 struct prefix_rd *rd, afi_t afi)
1809 {
1810 struct listnode *node, *nnode;
1811 struct bgp *bgp;
1812
1813 if (!rd)
1814 return NULL;
1815
1816 /* If ACCEPT_OWN is not enabled for this path - return. */
1817 if (!CHECK_FLAG(bpi->flags, BGP_PATH_ACCEPT_OWN))
1818 return NULL;
1819
1820 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
1821 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
1822 continue;
1823
1824 if (!CHECK_FLAG(bgp->vpn_policy[afi].flags,
1825 BGP_VPN_POLICY_TOVPN_RD_SET))
1826 continue;
1827
1828 /* Check if we have source VRF by RD value */
1829 if (memcmp(&bgp->vpn_policy[afi].tovpn_rd.val, rd->val,
1830 ECOMMUNITY_SIZE) == 0)
1831 return bgp;
1832 }
1833
1834 return NULL;
1835 }
1836
1837 static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
1838 struct bgp *from_bgp, /* from */
1839 struct bgp_path_info *path_vpn,
1840 struct prefix_rd *prd)
1841 {
1842 const struct prefix *p = bgp_dest_get_prefix(path_vpn->net);
1843 afi_t afi = family2afi(p->family);
1844
1845 struct attr static_attr = {0};
1846 struct attr *new_attr = NULL;
1847 struct bgp_dest *bn;
1848 safi_t safi = SAFI_UNICAST;
1849 const char *debugmsg;
1850 struct prefix nexthop_orig;
1851 mpls_label_t *pLabels = NULL;
1852 uint32_t num_labels = 0;
1853 int nexthop_self_flag = 1;
1854 struct bgp_path_info *bpi_ultimate = NULL;
1855 int origin_local = 0;
1856 struct bgp *src_vrf;
1857 struct interface *ifp;
1858 char rd_buf[RD_ADDRSTRLEN];
1859 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1860
1861 if (!vpn_leak_from_vpn_active(to_bgp, afi, &debugmsg)) {
1862 if (debug)
1863 zlog_debug(
1864 "%s: from vpn (%s) to vrf (%s), skipping: %s",
1865 __func__, from_bgp->name_pretty,
1866 to_bgp->name_pretty, debugmsg);
1867 return false;
1868 }
1869
1870 /*
1871 * For VRF-2-VRF route-leaking,
1872 * the source will be the originating VRF.
1873 *
1874 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
1875 * get the source VRF (BGP) by looking at the RD.
1876 */
1877 struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi);
1878
1879 if (path_vpn->extra && path_vpn->extra->bgp_orig)
1880 src_vrf = path_vpn->extra->bgp_orig;
1881 else if (src_bgp)
1882 src_vrf = src_bgp;
1883 else
1884 src_vrf = from_bgp;
1885
1886 /* Check for intersection of route targets */
1887 if (!ecommunity_include(
1888 to_bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1889 bgp_attr_get_ecommunity(path_vpn->attr))) {
1890 if (debug)
1891 zlog_debug(
1892 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
1893 from_bgp->name_pretty, to_bgp->name_pretty);
1894 return false;
1895 }
1896
1897 rd_buf[0] = '\0';
1898 if (debug && prd)
1899 prefix_rd2str(prd, rd_buf, sizeof(rd_buf), to_bgp->asnotation);
1900
1901 /* A route MUST NOT ever be accepted back into its source VRF, even if
1902 * it carries one or more RTs that match that VRF.
1903 */
1904 if (CHECK_FLAG(path_vpn->flags, BGP_PATH_ACCEPT_OWN) && prd &&
1905 memcmp(&prd->val, &to_bgp->vpn_policy[afi].tovpn_rd.val,
1906 ECOMMUNITY_SIZE) == 0) {
1907 if (debug)
1908 zlog_debug(
1909 "%s: skipping import, match RD (%s) of src VRF (%s) and the prefix (%pFX)",
1910 __func__, rd_buf, to_bgp->name_pretty, p);
1911 return false;
1912 }
1913
1914 if (debug)
1915 zlog_debug("%s: updating RD %s, %pFX to %s", __func__, rd_buf,
1916 p, to_bgp->name_pretty);
1917
1918 /* shallow copy */
1919 static_attr = *path_vpn->attr;
1920
1921 struct ecommunity *old_ecom;
1922 struct ecommunity *new_ecom;
1923
1924 /* If doing VRF-to-VRF leaking, strip RTs. */
1925 old_ecom = bgp_attr_get_ecommunity(&static_attr);
1926 if (old_ecom && CHECK_FLAG(to_bgp->af_flags[afi][safi],
1927 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1928 new_ecom = ecommunity_dup(old_ecom);
1929 ecommunity_strip_rts(new_ecom);
1930 bgp_attr_set_ecommunity(&static_attr, new_ecom);
1931
1932 if (new_ecom->size == 0) {
1933 ecommunity_free(&new_ecom);
1934 bgp_attr_set_ecommunity(&static_attr, NULL);
1935 }
1936
1937 if (!old_ecom->refcnt)
1938 ecommunity_free(&old_ecom);
1939 }
1940
1941 community_strip_accept_own(&static_attr);
1942
1943 /*
1944 * Nexthop: stash and clear
1945 *
1946 * Nexthop is valid in context of VPN core, but not in destination vrf.
1947 * Stash it for later label resolution by vrf ingress path and then
1948 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1949 */
1950 uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
1951
1952 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1953 nexthop_orig.family = nhfamily;
1954
1955 /* If the path has accept-own community and the source VRF
1956 * is valid, reset next-hop to self, to allow importing own
1957 * routes between different VRFs on the same node.
1958 * Set the nh ifindex to VRF's interface, not the real interface.
1959 * Let the kernel to decide with double lookup the real next-hop
1960 * interface when installing the route.
1961 */
1962 if (src_bgp) {
1963 subgroup_announce_reset_nhop(nhfamily, &static_attr);
1964 ifp = if_get_vrf_loopback(src_vrf->vrf_id);
1965 if (ifp)
1966 static_attr.nh_ifindex = ifp->ifindex;
1967 }
1968
1969 switch (nhfamily) {
1970 case AF_INET:
1971 /* save */
1972 nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
1973 nexthop_orig.prefixlen = IPV4_MAX_BITLEN;
1974
1975 if (CHECK_FLAG(to_bgp->af_flags[afi][safi],
1976 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1977 static_attr.nexthop.s_addr =
1978 nexthop_orig.u.prefix4.s_addr;
1979
1980 static_attr.mp_nexthop_global_in =
1981 path_vpn->attr->mp_nexthop_global_in;
1982 static_attr.mp_nexthop_len =
1983 path_vpn->attr->mp_nexthop_len;
1984 }
1985 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1986 break;
1987 case AF_INET6:
1988 /* save */
1989 nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
1990 nexthop_orig.prefixlen = IPV6_MAX_BITLEN;
1991
1992 if (CHECK_FLAG(to_bgp->af_flags[afi][safi],
1993 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1994 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
1995 }
1996 break;
1997 }
1998
1999 /*
2000 * route map handling
2001 */
2002 if (to_bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
2003 struct bgp_path_info info;
2004 route_map_result_t ret;
2005
2006 memset(&info, 0, sizeof(info));
2007 info.peer = to_bgp->peer_self;
2008 info.attr = &static_attr;
2009 info.extra = path_vpn->extra; /* Used for source-vrf filter */
2010 ret = route_map_apply(to_bgp->vpn_policy[afi]
2011 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
2012 p, &info);
2013 if (RMAP_DENYMATCH == ret) {
2014 bgp_attr_flush(&static_attr); /* free any added parts */
2015 if (debug)
2016 zlog_debug(
2017 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
2018 __func__, to_bgp->name_pretty,
2019 to_bgp->vpn_policy[afi]
2020 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
2021 ->name);
2022 return false;
2023 }
2024 /*
2025 * if route-map changed nexthop, don't nexthop-self on output
2026 */
2027 if (!CHECK_FLAG(static_attr.rmap_change_flags,
2028 BATTR_RMAP_NEXTHOP_UNCHANGED))
2029 nexthop_self_flag = 0;
2030 }
2031
2032 new_attr = bgp_attr_intern(&static_attr);
2033 bgp_attr_flush(&static_attr);
2034
2035 bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL);
2036
2037 /*
2038 * ensure labels are copied
2039 *
2040 * However, there is a special case: if the route originated in
2041 * another local VRF (as opposed to arriving via VPN), then the
2042 * nexthop is reached by hairpinning through this router (me)
2043 * using IP forwarding only (no LSP). Therefore, the route
2044 * imported to the VRF should not have labels attached. Note
2045 * that nexthop tracking is also involved: eliminating the
2046 * labels for these routes enables the non-labeled nexthops
2047 * from the originating VRF to be considered valid for this route.
2048 */
2049 if (!CHECK_FLAG(to_bgp->af_flags[afi][safi],
2050 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
2051 /* work back to original route */
2052 bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
2053
2054 /*
2055 * if original route was unicast,
2056 * then it did not arrive over vpn
2057 */
2058 if (bpi_ultimate->net) {
2059 struct bgp_table *table;
2060
2061 table = bgp_dest_table(bpi_ultimate->net);
2062 if (table && (table->safi == SAFI_UNICAST))
2063 origin_local = 1;
2064 }
2065
2066 /* copy labels */
2067 if (!origin_local && path_vpn->extra
2068 && path_vpn->extra->num_labels) {
2069 num_labels = path_vpn->extra->num_labels;
2070 if (num_labels > BGP_MAX_LABELS)
2071 num_labels = BGP_MAX_LABELS;
2072 pLabels = path_vpn->extra->label;
2073 }
2074 }
2075
2076 if (debug)
2077 zlog_debug("%s: pfx %pBD: num_labels %d", __func__,
2078 path_vpn->net, num_labels);
2079
2080 if (!leak_update(to_bgp, bn, new_attr, afi, safi, path_vpn, pLabels,
2081 num_labels, src_vrf, &nexthop_orig, nexthop_self_flag,
2082 debug))
2083 bgp_dest_unlock_node(bn);
2084
2085 return true;
2086 }
2087
2088 bool vpn_leak_to_vrf_update(struct bgp *from_bgp,
2089 struct bgp_path_info *path_vpn,
2090 struct prefix_rd *prd)
2091 {
2092 struct listnode *mnode, *mnnode;
2093 struct bgp *bgp;
2094 bool leak_success = false;
2095
2096 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2097
2098 if (debug)
2099 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
2100
2101 /* Loop over VRFs */
2102 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2103
2104 if (!path_vpn->extra
2105 || path_vpn->extra->bgp_orig != bgp) { /* no loop */
2106 leak_success |= vpn_leak_to_vrf_update_onevrf(
2107 bgp, from_bgp, path_vpn, prd);
2108 }
2109 }
2110 return leak_success;
2111 }
2112
2113 void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn)
2114 {
2115 const struct prefix *p;
2116 afi_t afi;
2117 safi_t safi = SAFI_UNICAST;
2118 struct bgp *bgp;
2119 struct listnode *mnode, *mnnode;
2120 struct bgp_dest *bn;
2121 struct bgp_path_info *bpi;
2122 const char *debugmsg;
2123
2124 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2125
2126 if (debug)
2127 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__,
2128 path_vpn->net, path_vpn->type, path_vpn->sub_type);
2129
2130 if (debug)
2131 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
2132
2133 if (!path_vpn->net) {
2134 #ifdef ENABLE_BGP_VNC
2135 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2136 if (path_vpn->type == ZEBRA_ROUTE_BGP
2137 && path_vpn->sub_type == BGP_ROUTE_RFP) {
2138
2139 return;
2140 }
2141 #endif
2142 if (debug)
2143 zlog_debug(
2144 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
2145 __func__);
2146 return;
2147 }
2148
2149 p = bgp_dest_get_prefix(path_vpn->net);
2150 afi = family2afi(p->family);
2151
2152 /* Loop over VRFs */
2153 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2154 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
2155 if (debug)
2156 zlog_debug("%s: from %s, skipping: %s",
2157 __func__, bgp->name_pretty,
2158 debugmsg);
2159 continue;
2160 }
2161
2162 /* Check for intersection of route targets */
2163 if (!ecommunity_include(
2164 bgp->vpn_policy[afi]
2165 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
2166 bgp_attr_get_ecommunity(path_vpn->attr))) {
2167
2168 continue;
2169 }
2170
2171 if (debug)
2172 zlog_debug("%s: withdrawing from vrf %s", __func__,
2173 bgp->name_pretty);
2174
2175 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
2176
2177 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2178 bpi = bpi->next) {
2179 if (bpi->extra
2180 && (struct bgp_path_info *)bpi->extra->parent
2181 == path_vpn) {
2182 break;
2183 }
2184 }
2185
2186 if (bpi) {
2187 if (debug)
2188 zlog_debug("%s: deleting bpi %p", __func__,
2189 bpi);
2190 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
2191 bgp_path_info_delete(bn, bpi);
2192 bgp_process(bgp, bn, afi, safi);
2193 }
2194 bgp_dest_unlock_node(bn);
2195 }
2196 }
2197
2198 void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi)
2199 {
2200 struct bgp_dest *bn;
2201 struct bgp_path_info *bpi;
2202 safi_t safi = SAFI_UNICAST;
2203 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2204
2205 if (debug)
2206 zlog_debug("%s: entry", __func__);
2207 /*
2208 * Walk vrf table, delete bpi with bgp_orig in a different vrf
2209 */
2210 for (bn = bgp_table_top(to_bgp->rib[afi][safi]); bn;
2211 bn = bgp_route_next(bn)) {
2212
2213 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2214 bpi = bpi->next) {
2215 if (bpi->extra && bpi->extra->bgp_orig != to_bgp &&
2216 bpi->extra->parent &&
2217 is_pi_family_vpn(bpi->extra->parent)) {
2218
2219 /* delete route */
2220 bgp_aggregate_decrement(to_bgp,
2221 bgp_dest_get_prefix(bn),
2222 bpi, afi, safi);
2223 bgp_path_info_delete(bn, bpi);
2224 bgp_process(to_bgp, bn, afi, safi);
2225 }
2226 }
2227 }
2228 }
2229
2230 void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *vpn_from,
2231 afi_t afi)
2232 {
2233 struct bgp_dest *pdest;
2234 safi_t safi = SAFI_MPLS_VPN;
2235
2236 assert(vpn_from);
2237
2238 /*
2239 * Walk vpn table
2240 */
2241 for (pdest = bgp_table_top(vpn_from->rib[afi][safi]); pdest;
2242 pdest = bgp_route_next(pdest)) {
2243 struct bgp_table *table;
2244 struct bgp_dest *bn;
2245 struct bgp_path_info *bpi;
2246
2247 /* This is the per-RD table of prefixes */
2248 table = bgp_dest_get_bgp_table_info(pdest);
2249
2250 if (!table)
2251 continue;
2252
2253 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
2254
2255 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2256 bpi = bpi->next) {
2257
2258 if (bpi->extra &&
2259 bpi->extra->bgp_orig == to_bgp)
2260 continue;
2261
2262 vpn_leak_to_vrf_update_onevrf(to_bgp, vpn_from,
2263 bpi, NULL);
2264 }
2265 }
2266 }
2267 }
2268
2269 /*
2270 * This function is called for definition/deletion/change to a route-map
2271 */
2272 static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
2273 {
2274 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2275 afi_t afi;
2276 struct route_map *rmap;
2277
2278 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
2279 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
2280
2281 return;
2282 }
2283
2284 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
2285
2286 for (afi = 0; afi < AFI_MAX; ++afi) {
2287
2288 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
2289 && !strcmp(rmap_name,
2290 bgp->vpn_policy[afi]
2291 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
2292
2293 if (debug)
2294 zlog_debug(
2295 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2296 __func__, rmap_name, bgp->as,
2297 afi2str(afi));
2298
2299 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
2300 bgp_get_default(), bgp);
2301 if (debug)
2302 zlog_debug("%s: after vpn_leak_prechange",
2303 __func__);
2304
2305 /* in case of definition/deletion */
2306 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
2307 rmap;
2308
2309 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
2310 bgp_get_default(), bgp);
2311
2312 if (debug)
2313 zlog_debug("%s: after vpn_leak_postchange",
2314 __func__);
2315 }
2316
2317 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
2318 && !strcmp(rmap_name,
2319 bgp->vpn_policy[afi]
2320 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
2321
2322 if (debug) {
2323 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
2324 __func__, rmap_name, bgp->as,
2325 afi2str(afi));
2326 }
2327
2328 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
2329 bgp_get_default(), bgp);
2330
2331 /* in case of definition/deletion */
2332 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
2333 rmap;
2334
2335 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
2336 bgp_get_default(), bgp);
2337 }
2338 }
2339 }
2340
2341 /* This API is used during router-id change, reflect VPNs
2342 * auto RD and RT values and readvertise routes to VPN table.
2343 */
2344 void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
2345 bool is_config)
2346 {
2347 afi_t afi;
2348 int debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF)
2349 | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2350 char *vname;
2351 const char *export_name;
2352 char buf[RD_ADDRSTRLEN];
2353 struct bgp *bgp_import;
2354 struct listnode *node;
2355 struct ecommunity *ecom;
2356 enum vpn_policy_direction idir, edir;
2357
2358 /*
2359 * Router-id change that is not explicitly configured
2360 * (a change from zebra, frr restart for example)
2361 * should not replace a configured vpn RD/RT.
2362 */
2363 if (!is_config) {
2364 if (debug)
2365 zlog_debug("%s: skipping non explicit router-id change",
2366 __func__);
2367 return;
2368 }
2369
2370 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
2371 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2372 return;
2373
2374 export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
2375 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2376 edir = BGP_VPN_POLICY_DIR_TOVPN;
2377
2378 for (afi = 0; afi < AFI_MAX; ++afi) {
2379 if (!vpn_leak_to_vpn_active(bgp, afi, NULL))
2380 continue;
2381
2382 if (withdraw) {
2383 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
2384 afi, bgp_get_default(), bgp);
2385 if (debug)
2386 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2387 __func__, export_name);
2388
2389 /* Remove import RT from VRFs */
2390 ecom = bgp->vpn_policy[afi].rtlist[edir];
2391 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
2392 export_vrf, node, vname)) {
2393 if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
2394 bgp_import = bgp_get_default();
2395 else
2396 bgp_import = bgp_lookup_by_name(vname);
2397 if (!bgp_import)
2398 continue;
2399
2400 ecommunity_del_val(
2401 bgp_import->vpn_policy[afi]
2402 .rtlist[idir],
2403 (struct ecommunity_val *)ecom->val);
2404 }
2405 } else {
2406 /* New router-id derive auto RD and RT and export
2407 * to VPN
2408 */
2409 form_auto_rd(bgp->router_id, bgp->vrf_rd_id,
2410 &bgp->vrf_prd_auto);
2411 bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
2412 prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
2413 sizeof(buf), bgp->asnotation);
2414
2415 /* free up pre-existing memory if any and allocate
2416 * the ecommunity attribute with new RD/RT
2417 */
2418 if (bgp->vpn_policy[afi].rtlist[edir])
2419 ecommunity_free(
2420 &bgp->vpn_policy[afi].rtlist[edir]);
2421 bgp->vpn_policy[afi].rtlist[edir] = ecommunity_str2com(
2422 buf, ECOMMUNITY_ROUTE_TARGET, 0);
2423
2424 /* Update import_vrf rt_list */
2425 ecom = bgp->vpn_policy[afi].rtlist[edir];
2426 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
2427 export_vrf, node, vname)) {
2428 if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
2429 bgp_import = bgp_get_default();
2430 else
2431 bgp_import = bgp_lookup_by_name(vname);
2432 if (!bgp_import)
2433 continue;
2434 if (bgp_import->vpn_policy[afi].rtlist[idir])
2435 bgp_import->vpn_policy[afi].rtlist[idir]
2436 = ecommunity_merge(
2437 bgp_import->vpn_policy[afi]
2438 .rtlist[idir], ecom);
2439 else
2440 bgp_import->vpn_policy[afi].rtlist[idir]
2441 = ecommunity_dup(ecom);
2442 }
2443
2444 /* Update routes to VPN */
2445 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
2446 afi, bgp_get_default(),
2447 bgp);
2448 if (debug)
2449 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2450 __func__, export_name);
2451 }
2452 }
2453 }
2454
2455 void vpn_policy_routemap_event(const char *rmap_name)
2456 {
2457 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2458 struct listnode *mnode, *mnnode;
2459 struct bgp *bgp;
2460
2461 if (debug)
2462 zlog_debug("%s: entry", __func__);
2463
2464 if (bm->bgp == NULL) /* may be called during cleanup */
2465 return;
2466
2467 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
2468 vpn_policy_routemap_update(bgp, rmap_name);
2469 }
2470
2471 void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
2472 afi_t afi, safi_t safi)
2473 {
2474 const char *export_name;
2475 enum vpn_policy_direction idir, edir;
2476 char *vname, *tmp_name;
2477 char buf[RD_ADDRSTRLEN];
2478 struct ecommunity *ecom;
2479 bool first_export = false;
2480 int debug;
2481 struct listnode *node;
2482 bool is_inst_match = false;
2483
2484 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
2485 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2486 edir = BGP_VPN_POLICY_DIR_TOVPN;
2487
2488 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2489 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2490
2491 /*
2492 * Cross-ref both VRFs. Also, note if this is the first time
2493 * any VRF is importing from "import_vrf".
2494 */
2495 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
2496 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
2497
2498 /* Check the import_vrf list of destination vrf for the source vrf name,
2499 * insert otherwise.
2500 */
2501 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf,
2502 node, tmp_name)) {
2503 if (strcmp(vname, tmp_name) == 0) {
2504 is_inst_match = true;
2505 break;
2506 }
2507 }
2508 if (!is_inst_match)
2509 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
2510 vname);
2511 else
2512 XFREE(MTYPE_TMP, vname);
2513
2514 /* Check if the source vrf already exports to any vrf,
2515 * first time export requires to setup auto derived RD/RT values.
2516 * Add the destination vrf name to export vrf list if it is
2517 * not present.
2518 */
2519 is_inst_match = false;
2520 vname = XSTRDUP(MTYPE_TMP, export_name);
2521 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2522 first_export = true;
2523 } else {
2524 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
2525 node, tmp_name)) {
2526 if (strcmp(vname, tmp_name) == 0) {
2527 is_inst_match = true;
2528 break;
2529 }
2530 }
2531 }
2532 if (!is_inst_match)
2533 listnode_add(from_bgp->vpn_policy[afi].export_vrf,
2534 vname);
2535 else
2536 XFREE(MTYPE_TMP, vname);
2537
2538 /* Update import RT for current VRF using export RT of the VRF we're
2539 * importing from. First though, make sure "import_vrf" has that
2540 * set.
2541 */
2542 if (first_export) {
2543 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
2544 &from_bgp->vrf_prd_auto);
2545 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
2546 SET_FLAG(from_bgp->vpn_policy[afi].flags,
2547 BGP_VPN_POLICY_TOVPN_RD_SET);
2548 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd, buf,
2549 sizeof(buf), from_bgp->asnotation);
2550 from_bgp->vpn_policy[afi].rtlist[edir] =
2551 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
2552 SET_FLAG(from_bgp->af_flags[afi][safi],
2553 BGP_CONFIG_VRF_TO_VRF_EXPORT);
2554 from_bgp->vpn_policy[afi].tovpn_label =
2555 BGP_PREVENT_VRF_2_VRF_LEAK;
2556 }
2557 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2558 if (to_bgp->vpn_policy[afi].rtlist[idir])
2559 to_bgp->vpn_policy[afi].rtlist[idir] =
2560 ecommunity_merge(to_bgp->vpn_policy[afi]
2561 .rtlist[idir], ecom);
2562 else
2563 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
2564 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
2565
2566 if (debug) {
2567 const char *from_name;
2568 char *ecom1, *ecom2;
2569
2570 from_name = from_bgp->name ? from_bgp->name :
2571 VRF_DEFAULT_NAME;
2572
2573 ecom1 = ecommunity_ecom2str(
2574 to_bgp->vpn_policy[afi].rtlist[idir],
2575 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2576
2577 ecom2 = ecommunity_ecom2str(
2578 to_bgp->vpn_policy[afi].rtlist[edir],
2579 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2580
2581 zlog_debug(
2582 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2583 __func__, from_name, export_name, first_export, ecom1,
2584 ecom2);
2585
2586 ecommunity_strfree(&ecom1);
2587 ecommunity_strfree(&ecom2);
2588 }
2589
2590 /* Does "import_vrf" first need to export its routes or that
2591 * is already done and we just need to import those routes
2592 * from the global table?
2593 */
2594 if (first_export)
2595 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
2596 else
2597 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
2598 }
2599
2600 void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
2601 afi_t afi, safi_t safi)
2602 {
2603 const char *export_name, *tmp_name;
2604 enum vpn_policy_direction idir, edir;
2605 char *vname;
2606 struct ecommunity *ecom = NULL;
2607 struct listnode *node;
2608 int debug;
2609
2610 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
2611 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
2612 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2613 edir = BGP_VPN_POLICY_DIR_TOVPN;
2614
2615 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2616 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2617
2618 /* Were we importing from "import_vrf"? */
2619 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
2620 vname)) {
2621 if (strcmp(vname, tmp_name) == 0)
2622 break;
2623 }
2624
2625 /*
2626 * We do not check in the cli if the passed in bgp
2627 * instance is actually imported into us before
2628 * we call this function. As such if we do not
2629 * find this in the import_vrf list than
2630 * we just need to return safely.
2631 */
2632 if (!vname)
2633 return;
2634
2635 if (debug)
2636 zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
2637
2638 /* Remove "import_vrf" from our import list. */
2639 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
2640 XFREE(MTYPE_TMP, vname);
2641
2642 /* Remove routes imported from "import_vrf". */
2643 /* TODO: In the current logic, we have to first remove all
2644 * imported routes and then (if needed) import back routes
2645 */
2646 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
2647
2648 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
2649 if (!to_bgp->vpn_policy[afi].rmap[idir])
2650 UNSET_FLAG(to_bgp->af_flags[afi][safi],
2651 BGP_CONFIG_VRF_TO_VRF_IMPORT);
2652 if (to_bgp->vpn_policy[afi].rtlist[idir])
2653 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
2654 } else {
2655 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2656 if (ecom)
2657 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
2658 (struct ecommunity_val *)ecom->val);
2659 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
2660 }
2661
2662 /*
2663 * What?
2664 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2665 * below is checking for NULL that export_vrf can be
2666 * NULL, consequently it is complaining( like a cabbage )
2667 * that we could dereference and crash in the listcount(..)
2668 * check below.
2669 * So make it happy, under protest, with liberty and justice
2670 * for all.
2671 */
2672 assert(from_bgp->vpn_policy[afi].export_vrf);
2673
2674 /* Remove us from "import_vrf's" export list. If no other VRF
2675 * is importing from "import_vrf", cleanup appropriately.
2676 */
2677 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
2678 node, vname)) {
2679 if (strcmp(vname, export_name) == 0)
2680 break;
2681 }
2682
2683 /*
2684 * If we have gotten to this point then the vname must
2685 * exist. If not, we are in a world of trouble and
2686 * have slag sitting around.
2687 *
2688 * import_vrf and export_vrf must match in having
2689 * the in/out names as appropriate.
2690 * export_vrf list could have been cleaned up
2691 * as part of no router bgp source instnace.
2692 */
2693 if (!vname)
2694 return;
2695
2696 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
2697 XFREE(MTYPE_TMP, vname);
2698
2699 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2700 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
2701 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
2702 UNSET_FLAG(from_bgp->af_flags[afi][safi],
2703 BGP_CONFIG_VRF_TO_VRF_EXPORT);
2704 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
2705 sizeof(struct prefix_rd));
2706 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
2707 BGP_VPN_POLICY_TOVPN_RD_SET);
2708 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
2709
2710 }
2711 }
2712
2713 /* For testing purpose, static route of MPLS-VPN. */
2714 DEFUN (vpnv4_network,
2715 vpnv4_network_cmd,
2716 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2717 "Specify a network to announce via BGP\n"
2718 "IPv4 prefix\n"
2719 "Specify Route Distinguisher\n"
2720 "VPN Route Distinguisher\n"
2721 "VPN NLRI label (tag)\n"
2722 "VPN NLRI label (tag)\n"
2723 "Label value\n")
2724 {
2725 int idx_ipv4_prefixlen = 1;
2726 int idx_ext_community = 3;
2727 int idx_label = 5;
2728 return bgp_static_set_safi(
2729 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
2730 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
2731 NULL, NULL, NULL, NULL);
2732 }
2733
2734 DEFUN (vpnv4_network_route_map,
2735 vpnv4_network_route_map_cmd,
2736 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
2737 "Specify a network to announce via BGP\n"
2738 "IPv4 prefix\n"
2739 "Specify Route Distinguisher\n"
2740 "VPN Route Distinguisher\n"
2741 "VPN NLRI label (tag)\n"
2742 "VPN NLRI label (tag)\n"
2743 "Label value\n"
2744 "route map\n"
2745 "route map name\n")
2746 {
2747 int idx_ipv4_prefixlen = 1;
2748 int idx_ext_community = 3;
2749 int idx_label = 5;
2750 int idx_word_2 = 7;
2751 return bgp_static_set_safi(
2752 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
2753 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2754 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
2755 }
2756
2757 /* For testing purpose, static route of MPLS-VPN. */
2758 DEFUN (no_vpnv4_network,
2759 no_vpnv4_network_cmd,
2760 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2761 NO_STR
2762 "Specify a network to announce via BGP\n"
2763 "IPv4 prefix\n"
2764 "Specify Route Distinguisher\n"
2765 "VPN Route Distinguisher\n"
2766 "VPN NLRI label (tag)\n"
2767 "VPN NLRI label (tag)\n"
2768 "Label value\n")
2769 {
2770 int idx_ipv4_prefixlen = 2;
2771 int idx_ext_community = 4;
2772 int idx_label = 6;
2773 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
2774 argv[idx_ipv4_prefixlen]->arg,
2775 argv[idx_ext_community]->arg,
2776 argv[idx_label]->arg, 0, NULL, NULL, NULL);
2777 }
2778
2779 DEFUN (vpnv6_network,
2780 vpnv6_network_cmd,
2781 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
2782 "Specify a network to announce via BGP\n"
2783 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2784 "Specify Route Distinguisher\n"
2785 "VPN Route Distinguisher\n"
2786 "VPN NLRI label (tag)\n"
2787 "VPN NLRI label (tag)\n"
2788 "Label value\n"
2789 "route map\n"
2790 "route map name\n")
2791 {
2792 int idx_ipv6_prefix = 1;
2793 int idx_ext_community = 3;
2794 int idx_label = 5;
2795 int idx_word_2 = 7;
2796 if (argc == 8)
2797 return bgp_static_set_safi(
2798 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
2799 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2800 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
2801 else
2802 return bgp_static_set_safi(
2803 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
2804 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2805 NULL, 0, NULL, NULL, NULL, NULL);
2806 }
2807
2808 /* For testing purpose, static route of MPLS-VPN. */
2809 DEFUN (no_vpnv6_network,
2810 no_vpnv6_network_cmd,
2811 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2812 NO_STR
2813 "Specify a network to announce via BGP\n"
2814 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2815 "Specify Route Distinguisher\n"
2816 "VPN Route Distinguisher\n"
2817 "VPN NLRI label (tag)\n"
2818 "VPN NLRI label (tag)\n"
2819 "Label value\n")
2820 {
2821 int idx_ipv6_prefix = 2;
2822 int idx_ext_community = 4;
2823 int idx_label = 6;
2824 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
2825 argv[idx_ipv6_prefix]->arg,
2826 argv[idx_ext_community]->arg,
2827 argv[idx_label]->arg, 0, NULL, NULL, NULL);
2828 }
2829
2830 int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
2831 enum bgp_show_type type, void *output_arg, int tags,
2832 bool use_json)
2833 {
2834 struct bgp *bgp;
2835 struct bgp_table *table;
2836 uint16_t show_flags = 0;
2837
2838 if (use_json)
2839 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
2840
2841 bgp = bgp_get_default();
2842 if (bgp == NULL) {
2843 if (!use_json)
2844 vty_out(vty, "No BGP process is configured\n");
2845 else
2846 vty_out(vty, "{}\n");
2847 return CMD_WARNING;
2848 }
2849 table = bgp->rib[afi][SAFI_MPLS_VPN];
2850 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
2851 output_arg, show_flags);
2852 }
2853
2854 DEFUN (show_bgp_ip_vpn_all_rd,
2855 show_bgp_ip_vpn_all_rd_cmd,
2856 "show bgp "BGP_AFI_CMD_STR" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2857 SHOW_STR
2858 BGP_STR
2859 BGP_VPNVX_HELP_STR
2860 "Display VPN NLRI specific information\n"
2861 "Display VPN NLRI specific information\n"
2862 "Display information for a route distinguisher\n"
2863 "VPN Route Distinguisher\n"
2864 "All VPN Route Distinguishers\n"
2865 JSON_STR)
2866 {
2867 int ret;
2868 struct prefix_rd prd;
2869 afi_t afi;
2870 int idx = 0;
2871
2872 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
2873 /* Constrain search if user supplies RD && RD != "all" */
2874 if (argv_find(argv, argc, "rd", &idx)
2875 && strcmp(argv[idx + 1]->arg, "all")) {
2876 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
2877 if (!ret) {
2878 vty_out(vty,
2879 "%% Malformed Route Distinguisher\n");
2880 return CMD_WARNING;
2881 }
2882 return bgp_show_mpls_vpn(vty, afi, &prd,
2883 bgp_show_type_normal, NULL, 0,
2884 use_json(argc, argv));
2885 } else {
2886 return bgp_show_mpls_vpn(vty, afi, NULL,
2887 bgp_show_type_normal, NULL, 0,
2888 use_json(argc, argv));
2889 }
2890 }
2891 return CMD_SUCCESS;
2892 }
2893
2894 ALIAS(show_bgp_ip_vpn_all_rd,
2895 show_bgp_ip_vpn_rd_cmd,
2896 "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2897 SHOW_STR
2898 BGP_STR
2899 BGP_VPNVX_HELP_STR
2900 "Display VPN NLRI specific information\n"
2901 "Display information for a route distinguisher\n"
2902 "VPN Route Distinguisher\n"
2903 "All VPN Route Distinguishers\n"
2904 JSON_STR)
2905
2906 #ifdef KEEP_OLD_VPN_COMMANDS
2907 DEFUN (show_ip_bgp_vpn_rd,
2908 show_ip_bgp_vpn_rd_cmd,
2909 "show ip bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2910 SHOW_STR
2911 IP_STR
2912 BGP_STR
2913 BGP_AFI_HELP_STR
2914 BGP_AF_MODIFIER_STR
2915 "Display information for a route distinguisher\n"
2916 "VPN Route Distinguisher\n"
2917 "All VPN Route Distinguishers\n")
2918 {
2919 int idx_ext_community = argc - 1;
2920 int ret;
2921 struct prefix_rd prd;
2922 afi_t afi;
2923 int idx = 0;
2924
2925 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2926 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2927 return bgp_show_mpls_vpn(vty, afi, NULL,
2928 bgp_show_type_normal, NULL, 0,
2929 0);
2930 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2931 if (!ret) {
2932 vty_out(vty, "%% Malformed Route Distinguisher\n");
2933 return CMD_WARNING;
2934 }
2935 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2936 NULL, 0, 0);
2937 }
2938 return CMD_SUCCESS;
2939 }
2940
2941 DEFUN (show_ip_bgp_vpn_all,
2942 show_ip_bgp_vpn_all_cmd,
2943 "show [ip] bgp <vpnv4|vpnv6>",
2944 SHOW_STR
2945 IP_STR
2946 BGP_STR
2947 BGP_VPNVX_HELP_STR)
2948 {
2949 afi_t afi;
2950 int idx = 0;
2951
2952 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2953 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2954 NULL, 0, 0);
2955 return CMD_SUCCESS;
2956 }
2957
2958 DEFUN (show_ip_bgp_vpn_all_tags,
2959 show_ip_bgp_vpn_all_tags_cmd,
2960 "show [ip] bgp <vpnv4|vpnv6> all tags",
2961 SHOW_STR
2962 IP_STR
2963 BGP_STR
2964 BGP_VPNVX_HELP_STR
2965 "Display information about all VPNv4/VPNV6 NLRIs\n"
2966 "Display BGP tags for prefixes\n")
2967 {
2968 afi_t afi;
2969 int idx = 0;
2970
2971 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2972 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2973 NULL, 1, 0);
2974 return CMD_SUCCESS;
2975 }
2976
2977 DEFUN (show_ip_bgp_vpn_rd_tags,
2978 show_ip_bgp_vpn_rd_tags_cmd,
2979 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2980 SHOW_STR
2981 IP_STR
2982 BGP_STR
2983 BGP_VPNVX_HELP_STR
2984 "Display information for a route distinguisher\n"
2985 "VPN Route Distinguisher\n"
2986 "All VPN Route Distinguishers\n"
2987 "Display BGP tags for prefixes\n")
2988 {
2989 int idx_ext_community = 5;
2990 int ret;
2991 struct prefix_rd prd;
2992 afi_t afi;
2993 int idx = 0;
2994
2995 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2996 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2997 return bgp_show_mpls_vpn(vty, afi, NULL,
2998 bgp_show_type_normal, NULL, 1,
2999 0);
3000 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3001 if (!ret) {
3002 vty_out(vty, "%% Malformed Route Distinguisher\n");
3003 return CMD_WARNING;
3004 }
3005 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
3006 NULL, 1, 0);
3007 }
3008 return CMD_SUCCESS;
3009 }
3010
3011 DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
3012 show_ip_bgp_vpn_all_neighbor_routes_cmd,
3013 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
3014 SHOW_STR
3015 IP_STR
3016 BGP_STR
3017 BGP_VPNVX_HELP_STR
3018 "Display information about all VPNv4/VPNv6 NLRIs\n"
3019 "Detailed information on TCP and BGP neighbor connections\n"
3020 "Neighbor to display information about\n"
3021 "Display routes learned from neighbor\n"
3022 JSON_STR)
3023 {
3024 int idx_ipv4 = 6;
3025 union sockunion su;
3026 struct peer *peer;
3027 int ret;
3028 bool uj = use_json(argc, argv);
3029 afi_t afi;
3030 int idx = 0;
3031
3032 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3033 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3034 if (ret < 0) {
3035 if (uj) {
3036 json_object *json_no = NULL;
3037 json_no = json_object_new_object();
3038 json_object_string_add(json_no, "warning",
3039 "Malformed address");
3040 vty_out(vty, "%s\n",
3041 json_object_to_json_string(json_no));
3042 json_object_free(json_no);
3043 } else
3044 vty_out(vty, "Malformed address: %s\n",
3045 argv[idx_ipv4]->arg);
3046 return CMD_WARNING;
3047 }
3048
3049 peer = peer_lookup(NULL, &su);
3050 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3051 if (uj) {
3052 json_object *json_no = NULL;
3053 json_no = json_object_new_object();
3054 json_object_string_add(
3055 json_no, "warning",
3056 "No such neighbor or address family");
3057 vty_out(vty, "%s\n",
3058 json_object_to_json_string(json_no));
3059 json_object_free(json_no);
3060 } else
3061 vty_out(vty,
3062 "%% No such neighbor or address family\n");
3063 return CMD_WARNING;
3064 }
3065
3066 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
3067 &su, 0, uj);
3068 }
3069 return CMD_SUCCESS;
3070 }
3071
3072 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
3073 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
3074 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
3075 SHOW_STR
3076 IP_STR
3077 BGP_STR
3078 BGP_VPNVX_HELP_STR
3079 "Display information for a route distinguisher\n"
3080 "VPN Route Distinguisher\n"
3081 "All VPN Route Distinguishers\n"
3082 "Detailed information on TCP and BGP neighbor connections\n"
3083 "Neighbor to display information about\n"
3084 "Display routes learned from neighbor\n"
3085 JSON_STR)
3086 {
3087 int idx_ext_community = 5;
3088 int idx_ipv4 = 7;
3089 int ret;
3090 union sockunion su;
3091 struct peer *peer;
3092 struct prefix_rd prd;
3093 bool prefix_rd_all = false;
3094 bool uj = use_json(argc, argv);
3095 afi_t afi;
3096 int idx = 0;
3097
3098 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3099 if (!strcmp(argv[idx_ext_community]->arg, "all"))
3100 prefix_rd_all = true;
3101 else {
3102 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3103 if (!ret) {
3104 if (uj) {
3105 json_object *json_no = NULL;
3106 json_no = json_object_new_object();
3107 json_object_string_add(
3108 json_no, "warning",
3109 "Malformed Route Distinguisher");
3110 vty_out(vty, "%s\n",
3111 json_object_to_json_string(
3112 json_no));
3113 json_object_free(json_no);
3114 } else
3115 vty_out(vty,
3116 "%% Malformed Route Distinguisher\n");
3117 return CMD_WARNING;
3118 }
3119 }
3120
3121 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3122 if (ret < 0) {
3123 if (uj) {
3124 json_object *json_no = NULL;
3125 json_no = json_object_new_object();
3126 json_object_string_add(json_no, "warning",
3127 "Malformed address");
3128 vty_out(vty, "%s\n",
3129 json_object_to_json_string(json_no));
3130 json_object_free(json_no);
3131 } else
3132 vty_out(vty, "Malformed address: %s\n",
3133 argv[idx_ext_community]->arg);
3134 return CMD_WARNING;
3135 }
3136
3137 peer = peer_lookup(NULL, &su);
3138 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3139 if (uj) {
3140 json_object *json_no = NULL;
3141 json_no = json_object_new_object();
3142 json_object_string_add(
3143 json_no, "warning",
3144 "No such neighbor or address family");
3145 vty_out(vty, "%s\n",
3146 json_object_to_json_string(json_no));
3147 json_object_free(json_no);
3148 } else
3149 vty_out(vty,
3150 "%% No such neighbor or address family\n");
3151 return CMD_WARNING;
3152 }
3153
3154 if (prefix_rd_all)
3155 return bgp_show_mpls_vpn(vty, afi, NULL,
3156 bgp_show_type_neighbor, &su, 0,
3157 uj);
3158 else
3159 return bgp_show_mpls_vpn(vty, afi, &prd,
3160 bgp_show_type_neighbor, &su, 0,
3161 uj);
3162 }
3163 return CMD_SUCCESS;
3164 }
3165
3166 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
3167 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
3168 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
3169 SHOW_STR
3170 IP_STR
3171 BGP_STR
3172 BGP_VPNVX_HELP_STR
3173 "Display information about all VPNv4/VPNv6 NLRIs\n"
3174 "Detailed information on TCP and BGP neighbor connections\n"
3175 "Neighbor to display information about\n"
3176 "Display the routes advertised to a BGP neighbor\n"
3177 JSON_STR)
3178 {
3179 int idx_ipv4 = 6;
3180 int ret;
3181 struct peer *peer;
3182 union sockunion su;
3183 bool uj = use_json(argc, argv);
3184 afi_t afi;
3185 int idx = 0;
3186
3187 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3188 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3189 if (ret < 0) {
3190 if (uj) {
3191 json_object *json_no = NULL;
3192 json_no = json_object_new_object();
3193 json_object_string_add(json_no, "warning",
3194 "Malformed address");
3195 vty_out(vty, "%s\n",
3196 json_object_to_json_string(json_no));
3197 json_object_free(json_no);
3198 } else
3199 vty_out(vty, "Malformed address: %s\n",
3200 argv[idx_ipv4]->arg);
3201 return CMD_WARNING;
3202 }
3203 peer = peer_lookup(NULL, &su);
3204 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3205 if (uj) {
3206 json_object *json_no = NULL;
3207 json_no = json_object_new_object();
3208 json_object_string_add(
3209 json_no, "warning",
3210 "No such neighbor or address family");
3211 vty_out(vty, "%s\n",
3212 json_object_to_json_string(json_no));
3213 json_object_free(json_no);
3214 } else
3215 vty_out(vty,
3216 "%% No such neighbor or address family\n");
3217 return CMD_WARNING;
3218 }
3219 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
3220 SAFI_MPLS_VPN, uj);
3221 }
3222 return CMD_SUCCESS;
3223 }
3224
3225 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
3226 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
3227 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
3228 SHOW_STR
3229 IP_STR
3230 BGP_STR
3231 BGP_VPNVX_HELP_STR
3232 "Display information for a route distinguisher\n"
3233 "VPN Route Distinguisher\n"
3234 "All VPN Route Distinguishers\n"
3235 "Detailed information on TCP and BGP neighbor connections\n"
3236 "Neighbor to display information about\n"
3237 "Display the routes advertised to a BGP neighbor\n"
3238 JSON_STR)
3239 {
3240 int idx_ext_community = 5;
3241 int idx_ipv4 = 7;
3242 int ret;
3243 struct peer *peer;
3244 struct prefix_rd prd;
3245 union sockunion su;
3246 bool uj = use_json(argc, argv);
3247 afi_t afi;
3248 int idx = 0;
3249
3250 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3251 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3252 if (ret < 0) {
3253 if (uj) {
3254 json_object *json_no = NULL;
3255 json_no = json_object_new_object();
3256 json_object_string_add(json_no, "warning",
3257 "Malformed address");
3258 vty_out(vty, "%s\n",
3259 json_object_to_json_string(json_no));
3260 json_object_free(json_no);
3261 } else
3262 vty_out(vty, "Malformed address: %s\n",
3263 argv[idx_ext_community]->arg);
3264 return CMD_WARNING;
3265 }
3266 peer = peer_lookup(NULL, &su);
3267 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3268 if (uj) {
3269 json_object *json_no = NULL;
3270 json_no = json_object_new_object();
3271 json_object_string_add(
3272 json_no, "warning",
3273 "No such neighbor or address family");
3274 vty_out(vty, "%s\n",
3275 json_object_to_json_string(json_no));
3276 json_object_free(json_no);
3277 } else
3278 vty_out(vty,
3279 "%% No such neighbor or address family\n");
3280 return CMD_WARNING;
3281 }
3282
3283 if (!strcmp(argv[idx_ext_community]->arg, "all"))
3284 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
3285 SAFI_MPLS_VPN, uj);
3286 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3287 if (!ret) {
3288 if (uj) {
3289 json_object *json_no = NULL;
3290 json_no = json_object_new_object();
3291 json_object_string_add(
3292 json_no, "warning",
3293 "Malformed Route Distinguisher");
3294 vty_out(vty, "%s\n",
3295 json_object_to_json_string(json_no));
3296 json_object_free(json_no);
3297 } else
3298 vty_out(vty,
3299 "%% Malformed Route Distinguisher\n");
3300 return CMD_WARNING;
3301 }
3302
3303 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
3304 SAFI_MPLS_VPN, uj);
3305 }
3306 return CMD_SUCCESS;
3307 }
3308 #endif /* KEEP_OLD_VPN_COMMANDS */
3309
3310 void bgp_mplsvpn_init(void)
3311 {
3312 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
3313 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
3314 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
3315
3316 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
3317 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
3318
3319 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
3320 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
3321 #ifdef KEEP_OLD_VPN_COMMANDS
3322 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
3323 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
3324 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
3325 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
3326 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
3327 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
3328 install_element(VIEW_NODE,
3329 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
3330 install_element(VIEW_NODE,
3331 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
3332 #endif /* KEEP_OLD_VPN_COMMANDS */
3333 }
3334
3335 vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
3336 {
3337 struct listnode *mnode, *mnnode;
3338 struct bgp *bgp;
3339 afi_t afi = AFI_IP;
3340
3341 if (eckey->unit_size == IPV6_ECOMMUNITY_SIZE)
3342 afi = AFI_IP6;
3343
3344 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
3345 struct ecommunity *ec;
3346
3347 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3348 continue;
3349
3350 ec = bgp->vpn_policy[afi].import_redirect_rtlist;
3351
3352 if (ec && eckey->unit_size != ec->unit_size)
3353 continue;
3354
3355 if (ecommunity_include(ec, eckey))
3356 return bgp->vrf_id;
3357 }
3358 return VRF_UNKNOWN;
3359 }
3360
3361 /*
3362 * The purpose of this function is to process leaks that were deferred
3363 * from earlier per-vrf configuration due to not-yet-existing default
3364 * vrf, in other words, configuration such as:
3365 *
3366 * router bgp MMM vrf FOO
3367 * address-family ipv4 unicast
3368 * rd vpn export 1:1
3369 * exit-address-family
3370 *
3371 * router bgp NNN
3372 * ...
3373 *
3374 * This function gets called when the default instance ("router bgp NNN")
3375 * is created.
3376 */
3377 void vpn_leak_postchange_all(void)
3378 {
3379 struct listnode *next;
3380 struct bgp *bgp;
3381 struct bgp *bgp_default = bgp_get_default();
3382
3383 assert(bgp_default);
3384
3385 /* First, do any exporting from VRFs to the single VPN RIB */
3386 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
3387
3388 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3389 continue;
3390
3391 vpn_leak_postchange(
3392 BGP_VPN_POLICY_DIR_TOVPN,
3393 AFI_IP,
3394 bgp_default,
3395 bgp);
3396
3397 vpn_leak_postchange(
3398 BGP_VPN_POLICY_DIR_TOVPN,
3399 AFI_IP6,
3400 bgp_default,
3401 bgp);
3402 }
3403
3404 /* Now, do any importing to VRFs from the single VPN RIB */
3405 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
3406
3407 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3408 continue;
3409
3410 vpn_leak_postchange(
3411 BGP_VPN_POLICY_DIR_FROMVPN,
3412 AFI_IP,
3413 bgp_default,
3414 bgp);
3415
3416 vpn_leak_postchange(
3417 BGP_VPN_POLICY_DIR_FROMVPN,
3418 AFI_IP6,
3419 bgp_default,
3420 bgp);
3421 }
3422 }
3423
3424 /* When a bgp vrf instance is unconfigured, remove its routes
3425 * from the VPN table and this vrf could be importing routes from other
3426 * bgp vrf instnaces, unimport them.
3427 * VRF X and VRF Y are exporting routes to each other.
3428 * When VRF X is deleted, unimport its routes from all target vrfs,
3429 * also VRF Y should unimport its routes from VRF X table.
3430 * This will ensure VPN table is cleaned up appropriately.
3431 */
3432 void bgp_vpn_leak_unimport(struct bgp *from_bgp)
3433 {
3434 struct bgp *to_bgp;
3435 const char *tmp_name;
3436 char *vname;
3437 struct listnode *node, *next;
3438 safi_t safi = SAFI_UNICAST;
3439 afi_t afi;
3440 bool is_vrf_leak_bind;
3441 int debug;
3442
3443 if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3444 return;
3445
3446 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3447 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3448
3449 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
3450
3451 for (afi = 0; afi < AFI_MAX; ++afi) {
3452 /* vrf leak is for IPv4 and IPv6 Unicast only */
3453 if (afi != AFI_IP && afi != AFI_IP6)
3454 continue;
3455
3456 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3457 if (from_bgp == to_bgp)
3458 continue;
3459
3460 /* Unimport and remove source vrf from the
3461 * other vrfs import list.
3462 */
3463 struct vpn_policy *to_vpolicy;
3464
3465 is_vrf_leak_bind = false;
3466 to_vpolicy = &(to_bgp->vpn_policy[afi]);
3467 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf, node,
3468 vname)) {
3469 if (strcmp(vname, tmp_name) == 0) {
3470 is_vrf_leak_bind = true;
3471 break;
3472 }
3473 }
3474 /* skip this bgp instance as there is no leak to this
3475 * vrf instance.
3476 */
3477 if (!is_vrf_leak_bind)
3478 continue;
3479
3480 if (debug)
3481 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3482 __func__, from_bgp->name_pretty,
3483 to_bgp->name_pretty, afi2str(afi),
3484 to_vpolicy->import_vrf->count);
3485
3486 vrf_unimport_from_vrf(to_bgp, from_bgp, afi, safi);
3487
3488 /* readd vrf name as unimport removes import vrf name
3489 * from the destination vrf's import list where the
3490 * `import vrf` configuration still exist.
3491 */
3492 vname = XSTRDUP(MTYPE_TMP, tmp_name);
3493 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
3494 vname);
3495 SET_FLAG(to_bgp->af_flags[afi][safi],
3496 BGP_CONFIG_VRF_TO_VRF_IMPORT);
3497
3498 /* If to_bgp exports its routes to the bgp vrf
3499 * which is being deleted, un-import the
3500 * to_bgp routes from VPN.
3501 */
3502 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi]
3503 .export_vrf, node,
3504 vname)) {
3505 if (strcmp(vname, tmp_name) == 0) {
3506 vrf_unimport_from_vrf(from_bgp, to_bgp,
3507 afi, safi);
3508 break;
3509 }
3510 }
3511 }
3512 }
3513 return;
3514 }
3515
3516 /* When a router bgp is configured, there could be a bgp vrf
3517 * instance importing routes from this newly configured
3518 * bgp vrf instance. Export routes from configured
3519 * bgp vrf to VPN.
3520 * VRF Y has import from bgp vrf x,
3521 * when a bgp vrf x instance is created, export its routes
3522 * to VRF Y instance.
3523 */
3524 void bgp_vpn_leak_export(struct bgp *from_bgp)
3525 {
3526 afi_t afi;
3527 const char *export_name;
3528 char *vname;
3529 struct listnode *node, *next;
3530 struct ecommunity *ecom;
3531 enum vpn_policy_direction idir, edir;
3532 safi_t safi = SAFI_UNICAST;
3533 struct bgp *to_bgp;
3534 int debug;
3535
3536 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3537 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3538
3539 idir = BGP_VPN_POLICY_DIR_FROMVPN;
3540 edir = BGP_VPN_POLICY_DIR_TOVPN;
3541
3542 export_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
3543
3544 for (afi = 0; afi < AFI_MAX; ++afi) {
3545 /* vrf leak is for IPv4 and IPv6 Unicast only */
3546 if (afi != AFI_IP && afi != AFI_IP6)
3547 continue;
3548
3549 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3550 if (from_bgp == to_bgp)
3551 continue;
3552
3553 /* bgp instance has import list, check to see if newly
3554 * configured bgp instance is the list.
3555 */
3556 struct vpn_policy *to_vpolicy;
3557
3558 to_vpolicy = &(to_bgp->vpn_policy[afi]);
3559 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
3560 node, vname)) {
3561 if (strcmp(vname, export_name) != 0)
3562 continue;
3563
3564 if (debug)
3565 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3566 __func__,
3567 export_name, to_bgp->name_pretty);
3568
3569 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
3570 /* remove import rt, it will be readded
3571 * as part of import from vrf.
3572 */
3573 if (ecom)
3574 ecommunity_del_val(
3575 to_vpolicy->rtlist[idir],
3576 (struct ecommunity_val *)
3577 ecom->val);
3578 vrf_import_from_vrf(to_bgp, from_bgp,
3579 afi, safi);
3580 break;
3581
3582 }
3583 }
3584 }
3585 }