]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
Merge pull request #12854 from opensourcerouting/fix/bgp_withdraw_attr_not_used
[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 }
1651
1652 void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, /* to */
1653 struct bgp *from_bgp, /* from */
1654 struct bgp_path_info *path_vrf) /* route */
1655 {
1656 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1657 const struct prefix *p = bgp_dest_get_prefix(path_vrf->net);
1658 afi_t afi = family2afi(p->family);
1659 safi_t safi = SAFI_MPLS_VPN;
1660 struct bgp_path_info *bpi;
1661 struct bgp_dest *bn;
1662 const char *debugmsg;
1663
1664 if (debug) {
1665 zlog_debug(
1666 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1667 __func__, from_bgp->name_pretty, path_vrf->net,
1668 path_vrf->type, path_vrf->sub_type);
1669 }
1670
1671 if (!to_bgp)
1672 return;
1673
1674 if (!afi) {
1675 if (debug)
1676 zlog_debug("%s: can't get afi of prefix", __func__);
1677 return;
1678 }
1679
1680 /* Is this route exportable into the VPN table? */
1681 if (!is_route_injectable_into_vpn(path_vrf))
1682 return;
1683
1684 if (!vpn_leak_to_vpn_active(from_bgp, afi, &debugmsg)) {
1685 if (debug)
1686 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1687 return;
1688 }
1689
1690 if (debug)
1691 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
1692
1693 bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p,
1694 &(from_bgp->vpn_policy[afi].tovpn_rd));
1695
1696 if (!bn)
1697 return;
1698 /*
1699 * vrf -> vpn
1700 * match original bpi imported from
1701 */
1702 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
1703 if (bpi->extra && bpi->extra->parent == path_vrf) {
1704 break;
1705 }
1706 }
1707
1708 if (bpi) {
1709 /* withdraw from looped vrfs as well */
1710 vpn_leak_to_vrf_withdraw(bpi);
1711
1712 bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi);
1713 bgp_path_info_delete(bn, bpi);
1714 bgp_process(to_bgp, bn, afi, safi);
1715 }
1716 bgp_dest_unlock_node(bn);
1717 }
1718
1719 void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp,
1720 afi_t afi)
1721 {
1722 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1723 struct bgp_dest *pdest;
1724 safi_t safi = SAFI_MPLS_VPN;
1725
1726 /*
1727 * Walk vpn table, delete bpi with bgp_orig == from_bgp
1728 */
1729 for (pdest = bgp_table_top(to_bgp->rib[afi][safi]); pdest;
1730 pdest = bgp_route_next(pdest)) {
1731
1732 struct bgp_table *table;
1733 struct bgp_dest *bn;
1734 struct bgp_path_info *bpi;
1735
1736 /* This is the per-RD table of prefixes */
1737 table = bgp_dest_get_bgp_table_info(pdest);
1738
1739 if (!table)
1740 continue;
1741
1742 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1743 bpi = bgp_dest_get_bgp_path_info(bn);
1744 if (debug && bpi) {
1745 zlog_debug("%s: looking at prefix %pBD",
1746 __func__, bn);
1747 }
1748
1749 for (; bpi; bpi = bpi->next) {
1750 if (debug)
1751 zlog_debug("%s: type %d, sub_type %d",
1752 __func__, bpi->type,
1753 bpi->sub_type);
1754 if (bpi->sub_type != BGP_ROUTE_IMPORTED)
1755 continue;
1756 if (!bpi->extra)
1757 continue;
1758 if ((struct bgp *)bpi->extra->bgp_orig ==
1759 from_bgp) {
1760 /* delete route */
1761 if (debug)
1762 zlog_debug("%s: deleting it",
1763 __func__);
1764 /* withdraw from leak-to vrfs as well */
1765 vpn_leak_to_vrf_withdraw(bpi);
1766 bgp_aggregate_decrement(
1767 to_bgp, bgp_dest_get_prefix(bn),
1768 bpi, afi, safi);
1769 bgp_path_info_delete(bn, bpi);
1770 bgp_process(to_bgp, bn, afi, safi);
1771 }
1772 }
1773 }
1774 }
1775 }
1776
1777 void vpn_leak_from_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
1778 afi_t afi)
1779 {
1780 struct bgp_dest *bn;
1781 struct bgp_path_info *bpi;
1782 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1783
1784 if (debug)
1785 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
1786 from_bgp->name_pretty);
1787
1788 for (bn = bgp_table_top(from_bgp->rib[afi][SAFI_UNICAST]); bn;
1789 bn = bgp_route_next(bn)) {
1790
1791 if (debug)
1792 zlog_debug("%s: node=%p", __func__, bn);
1793
1794 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
1795 bpi = bpi->next) {
1796 if (debug)
1797 zlog_debug(
1798 "%s: calling vpn_leak_from_vrf_update",
1799 __func__);
1800 vpn_leak_from_vrf_update(to_bgp, from_bgp, bpi);
1801 }
1802 }
1803 }
1804
1805 static struct bgp *bgp_lookup_by_rd(struct bgp_path_info *bpi,
1806 struct prefix_rd *rd, afi_t afi)
1807 {
1808 struct listnode *node, *nnode;
1809 struct bgp *bgp;
1810
1811 if (!rd)
1812 return NULL;
1813
1814 /* If ACCEPT_OWN is not enabled for this path - return. */
1815 if (!CHECK_FLAG(bpi->flags, BGP_PATH_ACCEPT_OWN))
1816 return NULL;
1817
1818 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
1819 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
1820 continue;
1821
1822 if (!CHECK_FLAG(bgp->vpn_policy[afi].flags,
1823 BGP_VPN_POLICY_TOVPN_RD_SET))
1824 continue;
1825
1826 /* Check if we have source VRF by RD value */
1827 if (memcmp(&bgp->vpn_policy[afi].tovpn_rd.val, rd->val,
1828 ECOMMUNITY_SIZE) == 0)
1829 return bgp;
1830 }
1831
1832 return NULL;
1833 }
1834
1835 static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
1836 struct bgp *from_bgp, /* from */
1837 struct bgp_path_info *path_vpn,
1838 struct prefix_rd *prd)
1839 {
1840 const struct prefix *p = bgp_dest_get_prefix(path_vpn->net);
1841 afi_t afi = family2afi(p->family);
1842
1843 struct attr static_attr = {0};
1844 struct attr *new_attr = NULL;
1845 struct bgp_dest *bn;
1846 safi_t safi = SAFI_UNICAST;
1847 const char *debugmsg;
1848 struct prefix nexthop_orig;
1849 mpls_label_t *pLabels = NULL;
1850 uint32_t num_labels = 0;
1851 int nexthop_self_flag = 1;
1852 struct bgp_path_info *bpi_ultimate = NULL;
1853 int origin_local = 0;
1854 struct bgp *src_vrf;
1855 struct interface *ifp;
1856 char rd_buf[RD_ADDRSTRLEN];
1857 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1858
1859 if (!vpn_leak_from_vpn_active(to_bgp, afi, &debugmsg)) {
1860 if (debug)
1861 zlog_debug(
1862 "%s: from vpn (%s) to vrf (%s), skipping: %s",
1863 __func__, from_bgp->name_pretty,
1864 to_bgp->name_pretty, debugmsg);
1865 return false;
1866 }
1867
1868 /*
1869 * For VRF-2-VRF route-leaking,
1870 * the source will be the originating VRF.
1871 *
1872 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
1873 * get the source VRF (BGP) by looking at the RD.
1874 */
1875 struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi);
1876
1877 if (path_vpn->extra && path_vpn->extra->bgp_orig)
1878 src_vrf = path_vpn->extra->bgp_orig;
1879 else if (src_bgp)
1880 src_vrf = src_bgp;
1881 else
1882 src_vrf = from_bgp;
1883
1884 /* Check for intersection of route targets */
1885 if (!ecommunity_include(
1886 to_bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1887 bgp_attr_get_ecommunity(path_vpn->attr))) {
1888 if (debug)
1889 zlog_debug(
1890 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
1891 from_bgp->name_pretty, to_bgp->name_pretty);
1892 return false;
1893 }
1894
1895 rd_buf[0] = '\0';
1896 if (debug && prd)
1897 prefix_rd2str(prd, rd_buf, sizeof(rd_buf), to_bgp->asnotation);
1898
1899 /* A route MUST NOT ever be accepted back into its source VRF, even if
1900 * it carries one or more RTs that match that VRF.
1901 */
1902 if (CHECK_FLAG(path_vpn->flags, BGP_PATH_ACCEPT_OWN) && prd &&
1903 memcmp(&prd->val, &to_bgp->vpn_policy[afi].tovpn_rd.val,
1904 ECOMMUNITY_SIZE) == 0) {
1905 if (debug)
1906 zlog_debug(
1907 "%s: skipping import, match RD (%s) of src VRF (%s) and the prefix (%pFX)",
1908 __func__, rd_buf, to_bgp->name_pretty, p);
1909 return false;
1910 }
1911
1912 if (debug)
1913 zlog_debug("%s: updating RD %s, %pFX to %s", __func__, rd_buf,
1914 p, to_bgp->name_pretty);
1915
1916 /* shallow copy */
1917 static_attr = *path_vpn->attr;
1918
1919 struct ecommunity *old_ecom;
1920 struct ecommunity *new_ecom;
1921
1922 /* If doing VRF-to-VRF leaking, strip RTs. */
1923 old_ecom = bgp_attr_get_ecommunity(&static_attr);
1924 if (old_ecom && CHECK_FLAG(to_bgp->af_flags[afi][safi],
1925 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1926 new_ecom = ecommunity_dup(old_ecom);
1927 ecommunity_strip_rts(new_ecom);
1928 bgp_attr_set_ecommunity(&static_attr, new_ecom);
1929
1930 if (new_ecom->size == 0) {
1931 ecommunity_free(&new_ecom);
1932 bgp_attr_set_ecommunity(&static_attr, NULL);
1933 }
1934
1935 if (!old_ecom->refcnt)
1936 ecommunity_free(&old_ecom);
1937 }
1938
1939 community_strip_accept_own(&static_attr);
1940
1941 /*
1942 * Nexthop: stash and clear
1943 *
1944 * Nexthop is valid in context of VPN core, but not in destination vrf.
1945 * Stash it for later label resolution by vrf ingress path and then
1946 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1947 */
1948 uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
1949
1950 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1951 nexthop_orig.family = nhfamily;
1952
1953 /* If the path has accept-own community and the source VRF
1954 * is valid, reset next-hop to self, to allow importing own
1955 * routes between different VRFs on the same node.
1956 * Set the nh ifindex to VRF's interface, not the real interface.
1957 * Let the kernel to decide with double lookup the real next-hop
1958 * interface when installing the route.
1959 */
1960 if (src_bgp) {
1961 subgroup_announce_reset_nhop(nhfamily, &static_attr);
1962 ifp = if_get_vrf_loopback(src_vrf->vrf_id);
1963 if (ifp)
1964 static_attr.nh_ifindex = ifp->ifindex;
1965 }
1966
1967 switch (nhfamily) {
1968 case AF_INET:
1969 /* save */
1970 nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
1971 nexthop_orig.prefixlen = IPV4_MAX_BITLEN;
1972
1973 if (CHECK_FLAG(to_bgp->af_flags[afi][safi],
1974 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1975 static_attr.nexthop.s_addr =
1976 nexthop_orig.u.prefix4.s_addr;
1977
1978 static_attr.mp_nexthop_global_in =
1979 path_vpn->attr->mp_nexthop_global_in;
1980 static_attr.mp_nexthop_len =
1981 path_vpn->attr->mp_nexthop_len;
1982 }
1983 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1984 break;
1985 case AF_INET6:
1986 /* save */
1987 nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
1988 nexthop_orig.prefixlen = IPV6_MAX_BITLEN;
1989
1990 if (CHECK_FLAG(to_bgp->af_flags[afi][safi],
1991 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1992 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
1993 }
1994 break;
1995 }
1996
1997 /*
1998 * route map handling
1999 */
2000 if (to_bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
2001 struct bgp_path_info info;
2002 route_map_result_t ret;
2003
2004 memset(&info, 0, sizeof(info));
2005 info.peer = to_bgp->peer_self;
2006 info.attr = &static_attr;
2007 info.extra = path_vpn->extra; /* Used for source-vrf filter */
2008 ret = route_map_apply(to_bgp->vpn_policy[afi]
2009 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
2010 p, &info);
2011 if (RMAP_DENYMATCH == ret) {
2012 bgp_attr_flush(&static_attr); /* free any added parts */
2013 if (debug)
2014 zlog_debug(
2015 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
2016 __func__, to_bgp->name_pretty,
2017 to_bgp->vpn_policy[afi]
2018 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
2019 ->name);
2020 return false;
2021 }
2022 /*
2023 * if route-map changed nexthop, don't nexthop-self on output
2024 */
2025 if (!CHECK_FLAG(static_attr.rmap_change_flags,
2026 BATTR_RMAP_NEXTHOP_UNCHANGED))
2027 nexthop_self_flag = 0;
2028 }
2029
2030 new_attr = bgp_attr_intern(&static_attr);
2031 bgp_attr_flush(&static_attr);
2032
2033 bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL);
2034
2035 /*
2036 * ensure labels are copied
2037 *
2038 * However, there is a special case: if the route originated in
2039 * another local VRF (as opposed to arriving via VPN), then the
2040 * nexthop is reached by hairpinning through this router (me)
2041 * using IP forwarding only (no LSP). Therefore, the route
2042 * imported to the VRF should not have labels attached. Note
2043 * that nexthop tracking is also involved: eliminating the
2044 * labels for these routes enables the non-labeled nexthops
2045 * from the originating VRF to be considered valid for this route.
2046 */
2047 if (!CHECK_FLAG(to_bgp->af_flags[afi][safi],
2048 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
2049 /* work back to original route */
2050 bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
2051
2052 /*
2053 * if original route was unicast,
2054 * then it did not arrive over vpn
2055 */
2056 if (bpi_ultimate->net) {
2057 struct bgp_table *table;
2058
2059 table = bgp_dest_table(bpi_ultimate->net);
2060 if (table && (table->safi == SAFI_UNICAST))
2061 origin_local = 1;
2062 }
2063
2064 /* copy labels */
2065 if (!origin_local && path_vpn->extra
2066 && path_vpn->extra->num_labels) {
2067 num_labels = path_vpn->extra->num_labels;
2068 if (num_labels > BGP_MAX_LABELS)
2069 num_labels = BGP_MAX_LABELS;
2070 pLabels = path_vpn->extra->label;
2071 }
2072 }
2073
2074 if (debug)
2075 zlog_debug("%s: pfx %pBD: num_labels %d", __func__,
2076 path_vpn->net, num_labels);
2077
2078 leak_update(to_bgp, bn, new_attr, afi, safi, path_vpn, pLabels,
2079 num_labels, src_vrf, &nexthop_orig, nexthop_self_flag,
2080 debug);
2081 return true;
2082 }
2083
2084 bool vpn_leak_to_vrf_update(struct bgp *from_bgp,
2085 struct bgp_path_info *path_vpn,
2086 struct prefix_rd *prd)
2087 {
2088 struct listnode *mnode, *mnnode;
2089 struct bgp *bgp;
2090 bool leak_success = false;
2091
2092 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2093
2094 if (debug)
2095 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
2096
2097 /* Loop over VRFs */
2098 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2099
2100 if (!path_vpn->extra
2101 || path_vpn->extra->bgp_orig != bgp) { /* no loop */
2102 leak_success |= vpn_leak_to_vrf_update_onevrf(
2103 bgp, from_bgp, path_vpn, prd);
2104 }
2105 }
2106 return leak_success;
2107 }
2108
2109 void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn)
2110 {
2111 const struct prefix *p;
2112 afi_t afi;
2113 safi_t safi = SAFI_UNICAST;
2114 struct bgp *bgp;
2115 struct listnode *mnode, *mnnode;
2116 struct bgp_dest *bn;
2117 struct bgp_path_info *bpi;
2118 const char *debugmsg;
2119
2120 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2121
2122 if (debug)
2123 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__,
2124 path_vpn->net, path_vpn->type, path_vpn->sub_type);
2125
2126 if (debug)
2127 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
2128
2129 if (!path_vpn->net) {
2130 #ifdef ENABLE_BGP_VNC
2131 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2132 if (path_vpn->type == ZEBRA_ROUTE_BGP
2133 && path_vpn->sub_type == BGP_ROUTE_RFP) {
2134
2135 return;
2136 }
2137 #endif
2138 if (debug)
2139 zlog_debug(
2140 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
2141 __func__);
2142 return;
2143 }
2144
2145 p = bgp_dest_get_prefix(path_vpn->net);
2146 afi = family2afi(p->family);
2147
2148 /* Loop over VRFs */
2149 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2150 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
2151 if (debug)
2152 zlog_debug("%s: from %s, skipping: %s",
2153 __func__, bgp->name_pretty,
2154 debugmsg);
2155 continue;
2156 }
2157
2158 /* Check for intersection of route targets */
2159 if (!ecommunity_include(
2160 bgp->vpn_policy[afi]
2161 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
2162 bgp_attr_get_ecommunity(path_vpn->attr))) {
2163
2164 continue;
2165 }
2166
2167 if (debug)
2168 zlog_debug("%s: withdrawing from vrf %s", __func__,
2169 bgp->name_pretty);
2170
2171 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
2172
2173 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2174 bpi = bpi->next) {
2175 if (bpi->extra
2176 && (struct bgp_path_info *)bpi->extra->parent
2177 == path_vpn) {
2178 break;
2179 }
2180 }
2181
2182 if (bpi) {
2183 if (debug)
2184 zlog_debug("%s: deleting bpi %p", __func__,
2185 bpi);
2186 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
2187 bgp_path_info_delete(bn, bpi);
2188 bgp_process(bgp, bn, afi, safi);
2189 }
2190 bgp_dest_unlock_node(bn);
2191 }
2192 }
2193
2194 void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi)
2195 {
2196 struct bgp_dest *bn;
2197 struct bgp_path_info *bpi;
2198 safi_t safi = SAFI_UNICAST;
2199 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
2200
2201 if (debug)
2202 zlog_debug("%s: entry", __func__);
2203 /*
2204 * Walk vrf table, delete bpi with bgp_orig in a different vrf
2205 */
2206 for (bn = bgp_table_top(to_bgp->rib[afi][safi]); bn;
2207 bn = bgp_route_next(bn)) {
2208
2209 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2210 bpi = bpi->next) {
2211 if (bpi->extra && bpi->extra->bgp_orig != to_bgp &&
2212 bpi->extra->parent &&
2213 is_pi_family_vpn(bpi->extra->parent)) {
2214
2215 /* delete route */
2216 bgp_aggregate_decrement(to_bgp,
2217 bgp_dest_get_prefix(bn),
2218 bpi, afi, safi);
2219 bgp_path_info_delete(bn, bpi);
2220 bgp_process(to_bgp, bn, afi, safi);
2221 }
2222 }
2223 }
2224 }
2225
2226 void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *vpn_from,
2227 afi_t afi)
2228 {
2229 struct bgp_dest *pdest;
2230 safi_t safi = SAFI_MPLS_VPN;
2231
2232 assert(vpn_from);
2233
2234 /*
2235 * Walk vpn table
2236 */
2237 for (pdest = bgp_table_top(vpn_from->rib[afi][safi]); pdest;
2238 pdest = bgp_route_next(pdest)) {
2239 struct bgp_table *table;
2240 struct bgp_dest *bn;
2241 struct bgp_path_info *bpi;
2242
2243 /* This is the per-RD table of prefixes */
2244 table = bgp_dest_get_bgp_table_info(pdest);
2245
2246 if (!table)
2247 continue;
2248
2249 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
2250
2251 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
2252 bpi = bpi->next) {
2253
2254 if (bpi->extra &&
2255 bpi->extra->bgp_orig == to_bgp)
2256 continue;
2257
2258 vpn_leak_to_vrf_update_onevrf(to_bgp, vpn_from,
2259 bpi, NULL);
2260 }
2261 }
2262 }
2263 }
2264
2265 /*
2266 * This function is called for definition/deletion/change to a route-map
2267 */
2268 static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
2269 {
2270 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2271 afi_t afi;
2272 struct route_map *rmap;
2273
2274 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
2275 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
2276
2277 return;
2278 }
2279
2280 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
2281
2282 for (afi = 0; afi < AFI_MAX; ++afi) {
2283
2284 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
2285 && !strcmp(rmap_name,
2286 bgp->vpn_policy[afi]
2287 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
2288
2289 if (debug)
2290 zlog_debug(
2291 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2292 __func__, rmap_name, bgp->as,
2293 afi2str(afi));
2294
2295 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
2296 bgp_get_default(), bgp);
2297 if (debug)
2298 zlog_debug("%s: after vpn_leak_prechange",
2299 __func__);
2300
2301 /* in case of definition/deletion */
2302 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
2303 rmap;
2304
2305 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
2306 bgp_get_default(), bgp);
2307
2308 if (debug)
2309 zlog_debug("%s: after vpn_leak_postchange",
2310 __func__);
2311 }
2312
2313 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
2314 && !strcmp(rmap_name,
2315 bgp->vpn_policy[afi]
2316 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
2317
2318 if (debug) {
2319 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
2320 __func__, rmap_name, bgp->as,
2321 afi2str(afi));
2322 }
2323
2324 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
2325 bgp_get_default(), bgp);
2326
2327 /* in case of definition/deletion */
2328 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
2329 rmap;
2330
2331 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
2332 bgp_get_default(), bgp);
2333 }
2334 }
2335 }
2336
2337 /* This API is used during router-id change, reflect VPNs
2338 * auto RD and RT values and readvertise routes to VPN table.
2339 */
2340 void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
2341 bool is_config)
2342 {
2343 afi_t afi;
2344 int debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF)
2345 | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2346 char *vname;
2347 const char *export_name;
2348 char buf[RD_ADDRSTRLEN];
2349 struct bgp *bgp_import;
2350 struct listnode *node;
2351 struct ecommunity *ecom;
2352 enum vpn_policy_direction idir, edir;
2353
2354 /*
2355 * Router-id change that is not explicitly configured
2356 * (a change from zebra, frr restart for example)
2357 * should not replace a configured vpn RD/RT.
2358 */
2359 if (!is_config) {
2360 if (debug)
2361 zlog_debug("%s: skipping non explicit router-id change",
2362 __func__);
2363 return;
2364 }
2365
2366 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
2367 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2368 return;
2369
2370 export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
2371 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2372 edir = BGP_VPN_POLICY_DIR_TOVPN;
2373
2374 for (afi = 0; afi < AFI_MAX; ++afi) {
2375 if (!vpn_leak_to_vpn_active(bgp, afi, NULL))
2376 continue;
2377
2378 if (withdraw) {
2379 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
2380 afi, bgp_get_default(), bgp);
2381 if (debug)
2382 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2383 __func__, export_name);
2384
2385 /* Remove import RT from VRFs */
2386 ecom = bgp->vpn_policy[afi].rtlist[edir];
2387 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
2388 export_vrf, node, vname)) {
2389 if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
2390 bgp_import = bgp_get_default();
2391 else
2392 bgp_import = bgp_lookup_by_name(vname);
2393 if (!bgp_import)
2394 continue;
2395
2396 ecommunity_del_val(
2397 bgp_import->vpn_policy[afi]
2398 .rtlist[idir],
2399 (struct ecommunity_val *)ecom->val);
2400 }
2401 } else {
2402 /* New router-id derive auto RD and RT and export
2403 * to VPN
2404 */
2405 form_auto_rd(bgp->router_id, bgp->vrf_rd_id,
2406 &bgp->vrf_prd_auto);
2407 bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
2408 prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
2409 sizeof(buf), bgp->asnotation);
2410
2411 /* free up pre-existing memory if any and allocate
2412 * the ecommunity attribute with new RD/RT
2413 */
2414 if (bgp->vpn_policy[afi].rtlist[edir])
2415 ecommunity_free(
2416 &bgp->vpn_policy[afi].rtlist[edir]);
2417 bgp->vpn_policy[afi].rtlist[edir] = ecommunity_str2com(
2418 buf, ECOMMUNITY_ROUTE_TARGET, 0);
2419
2420 /* Update import_vrf rt_list */
2421 ecom = bgp->vpn_policy[afi].rtlist[edir];
2422 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
2423 export_vrf, node, vname)) {
2424 if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
2425 bgp_import = bgp_get_default();
2426 else
2427 bgp_import = bgp_lookup_by_name(vname);
2428 if (!bgp_import)
2429 continue;
2430 if (bgp_import->vpn_policy[afi].rtlist[idir])
2431 bgp_import->vpn_policy[afi].rtlist[idir]
2432 = ecommunity_merge(
2433 bgp_import->vpn_policy[afi]
2434 .rtlist[idir], ecom);
2435 else
2436 bgp_import->vpn_policy[afi].rtlist[idir]
2437 = ecommunity_dup(ecom);
2438 }
2439
2440 /* Update routes to VPN */
2441 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
2442 afi, bgp_get_default(),
2443 bgp);
2444 if (debug)
2445 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2446 __func__, export_name);
2447 }
2448 }
2449 }
2450
2451 void vpn_policy_routemap_event(const char *rmap_name)
2452 {
2453 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
2454 struct listnode *mnode, *mnnode;
2455 struct bgp *bgp;
2456
2457 if (debug)
2458 zlog_debug("%s: entry", __func__);
2459
2460 if (bm->bgp == NULL) /* may be called during cleanup */
2461 return;
2462
2463 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
2464 vpn_policy_routemap_update(bgp, rmap_name);
2465 }
2466
2467 void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
2468 afi_t afi, safi_t safi)
2469 {
2470 const char *export_name;
2471 enum vpn_policy_direction idir, edir;
2472 char *vname, *tmp_name;
2473 char buf[RD_ADDRSTRLEN];
2474 struct ecommunity *ecom;
2475 bool first_export = false;
2476 int debug;
2477 struct listnode *node;
2478 bool is_inst_match = false;
2479
2480 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
2481 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2482 edir = BGP_VPN_POLICY_DIR_TOVPN;
2483
2484 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2485 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2486
2487 /*
2488 * Cross-ref both VRFs. Also, note if this is the first time
2489 * any VRF is importing from "import_vrf".
2490 */
2491 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
2492 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
2493
2494 /* Check the import_vrf list of destination vrf for the source vrf name,
2495 * insert otherwise.
2496 */
2497 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf,
2498 node, tmp_name)) {
2499 if (strcmp(vname, tmp_name) == 0) {
2500 is_inst_match = true;
2501 break;
2502 }
2503 }
2504 if (!is_inst_match)
2505 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
2506 vname);
2507 else
2508 XFREE(MTYPE_TMP, vname);
2509
2510 /* Check if the source vrf already exports to any vrf,
2511 * first time export requires to setup auto derived RD/RT values.
2512 * Add the destination vrf name to export vrf list if it is
2513 * not present.
2514 */
2515 is_inst_match = false;
2516 vname = XSTRDUP(MTYPE_TMP, export_name);
2517 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2518 first_export = true;
2519 } else {
2520 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
2521 node, tmp_name)) {
2522 if (strcmp(vname, tmp_name) == 0) {
2523 is_inst_match = true;
2524 break;
2525 }
2526 }
2527 }
2528 if (!is_inst_match)
2529 listnode_add(from_bgp->vpn_policy[afi].export_vrf,
2530 vname);
2531 else
2532 XFREE(MTYPE_TMP, vname);
2533
2534 /* Update import RT for current VRF using export RT of the VRF we're
2535 * importing from. First though, make sure "import_vrf" has that
2536 * set.
2537 */
2538 if (first_export) {
2539 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
2540 &from_bgp->vrf_prd_auto);
2541 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
2542 SET_FLAG(from_bgp->vpn_policy[afi].flags,
2543 BGP_VPN_POLICY_TOVPN_RD_SET);
2544 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd, buf,
2545 sizeof(buf), from_bgp->asnotation);
2546 from_bgp->vpn_policy[afi].rtlist[edir] =
2547 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
2548 SET_FLAG(from_bgp->af_flags[afi][safi],
2549 BGP_CONFIG_VRF_TO_VRF_EXPORT);
2550 from_bgp->vpn_policy[afi].tovpn_label =
2551 BGP_PREVENT_VRF_2_VRF_LEAK;
2552 }
2553 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2554 if (to_bgp->vpn_policy[afi].rtlist[idir])
2555 to_bgp->vpn_policy[afi].rtlist[idir] =
2556 ecommunity_merge(to_bgp->vpn_policy[afi]
2557 .rtlist[idir], ecom);
2558 else
2559 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
2560 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
2561
2562 if (debug) {
2563 const char *from_name;
2564 char *ecom1, *ecom2;
2565
2566 from_name = from_bgp->name ? from_bgp->name :
2567 VRF_DEFAULT_NAME;
2568
2569 ecom1 = ecommunity_ecom2str(
2570 to_bgp->vpn_policy[afi].rtlist[idir],
2571 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2572
2573 ecom2 = ecommunity_ecom2str(
2574 to_bgp->vpn_policy[afi].rtlist[edir],
2575 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
2576
2577 zlog_debug(
2578 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2579 __func__, from_name, export_name, first_export, ecom1,
2580 ecom2);
2581
2582 ecommunity_strfree(&ecom1);
2583 ecommunity_strfree(&ecom2);
2584 }
2585
2586 /* Does "import_vrf" first need to export its routes or that
2587 * is already done and we just need to import those routes
2588 * from the global table?
2589 */
2590 if (first_export)
2591 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
2592 else
2593 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
2594 }
2595
2596 void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
2597 afi_t afi, safi_t safi)
2598 {
2599 const char *export_name, *tmp_name;
2600 enum vpn_policy_direction idir, edir;
2601 char *vname;
2602 struct ecommunity *ecom = NULL;
2603 struct listnode *node;
2604 int debug;
2605
2606 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
2607 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
2608 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2609 edir = BGP_VPN_POLICY_DIR_TOVPN;
2610
2611 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2612 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2613
2614 /* Were we importing from "import_vrf"? */
2615 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
2616 vname)) {
2617 if (strcmp(vname, tmp_name) == 0)
2618 break;
2619 }
2620
2621 /*
2622 * We do not check in the cli if the passed in bgp
2623 * instance is actually imported into us before
2624 * we call this function. As such if we do not
2625 * find this in the import_vrf list than
2626 * we just need to return safely.
2627 */
2628 if (!vname)
2629 return;
2630
2631 if (debug)
2632 zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
2633
2634 /* Remove "import_vrf" from our import list. */
2635 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
2636 XFREE(MTYPE_TMP, vname);
2637
2638 /* Remove routes imported from "import_vrf". */
2639 /* TODO: In the current logic, we have to first remove all
2640 * imported routes and then (if needed) import back routes
2641 */
2642 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
2643
2644 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
2645 if (!to_bgp->vpn_policy[afi].rmap[idir])
2646 UNSET_FLAG(to_bgp->af_flags[afi][safi],
2647 BGP_CONFIG_VRF_TO_VRF_IMPORT);
2648 if (to_bgp->vpn_policy[afi].rtlist[idir])
2649 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
2650 } else {
2651 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2652 if (ecom)
2653 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
2654 (struct ecommunity_val *)ecom->val);
2655 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
2656 }
2657
2658 /*
2659 * What?
2660 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2661 * below is checking for NULL that export_vrf can be
2662 * NULL, consequently it is complaining( like a cabbage )
2663 * that we could dereference and crash in the listcount(..)
2664 * check below.
2665 * So make it happy, under protest, with liberty and justice
2666 * for all.
2667 */
2668 assert(from_bgp->vpn_policy[afi].export_vrf);
2669
2670 /* Remove us from "import_vrf's" export list. If no other VRF
2671 * is importing from "import_vrf", cleanup appropriately.
2672 */
2673 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
2674 node, vname)) {
2675 if (strcmp(vname, export_name) == 0)
2676 break;
2677 }
2678
2679 /*
2680 * If we have gotten to this point then the vname must
2681 * exist. If not, we are in a world of trouble and
2682 * have slag sitting around.
2683 *
2684 * import_vrf and export_vrf must match in having
2685 * the in/out names as appropriate.
2686 * export_vrf list could have been cleaned up
2687 * as part of no router bgp source instnace.
2688 */
2689 if (!vname)
2690 return;
2691
2692 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
2693 XFREE(MTYPE_TMP, vname);
2694
2695 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
2696 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
2697 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
2698 UNSET_FLAG(from_bgp->af_flags[afi][safi],
2699 BGP_CONFIG_VRF_TO_VRF_EXPORT);
2700 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
2701 sizeof(struct prefix_rd));
2702 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
2703 BGP_VPN_POLICY_TOVPN_RD_SET);
2704 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
2705
2706 }
2707 }
2708
2709 /* For testing purpose, static route of MPLS-VPN. */
2710 DEFUN (vpnv4_network,
2711 vpnv4_network_cmd,
2712 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2713 "Specify a network to announce via BGP\n"
2714 "IPv4 prefix\n"
2715 "Specify Route Distinguisher\n"
2716 "VPN Route Distinguisher\n"
2717 "VPN NLRI label (tag)\n"
2718 "VPN NLRI label (tag)\n"
2719 "Label value\n")
2720 {
2721 int idx_ipv4_prefixlen = 1;
2722 int idx_ext_community = 3;
2723 int idx_label = 5;
2724 return bgp_static_set_safi(
2725 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
2726 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
2727 NULL, NULL, NULL, NULL);
2728 }
2729
2730 DEFUN (vpnv4_network_route_map,
2731 vpnv4_network_route_map_cmd,
2732 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
2733 "Specify a network to announce via BGP\n"
2734 "IPv4 prefix\n"
2735 "Specify Route Distinguisher\n"
2736 "VPN Route Distinguisher\n"
2737 "VPN NLRI label (tag)\n"
2738 "VPN NLRI label (tag)\n"
2739 "Label value\n"
2740 "route map\n"
2741 "route map name\n")
2742 {
2743 int idx_ipv4_prefixlen = 1;
2744 int idx_ext_community = 3;
2745 int idx_label = 5;
2746 int idx_word_2 = 7;
2747 return bgp_static_set_safi(
2748 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
2749 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2750 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
2751 }
2752
2753 /* For testing purpose, static route of MPLS-VPN. */
2754 DEFUN (no_vpnv4_network,
2755 no_vpnv4_network_cmd,
2756 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2757 NO_STR
2758 "Specify a network to announce via BGP\n"
2759 "IPv4 prefix\n"
2760 "Specify Route Distinguisher\n"
2761 "VPN Route Distinguisher\n"
2762 "VPN NLRI label (tag)\n"
2763 "VPN NLRI label (tag)\n"
2764 "Label value\n")
2765 {
2766 int idx_ipv4_prefixlen = 2;
2767 int idx_ext_community = 4;
2768 int idx_label = 6;
2769 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
2770 argv[idx_ipv4_prefixlen]->arg,
2771 argv[idx_ext_community]->arg,
2772 argv[idx_label]->arg, 0, NULL, NULL, NULL);
2773 }
2774
2775 DEFUN (vpnv6_network,
2776 vpnv6_network_cmd,
2777 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
2778 "Specify a network to announce via BGP\n"
2779 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2780 "Specify Route Distinguisher\n"
2781 "VPN Route Distinguisher\n"
2782 "VPN NLRI label (tag)\n"
2783 "VPN NLRI label (tag)\n"
2784 "Label value\n"
2785 "route map\n"
2786 "route map name\n")
2787 {
2788 int idx_ipv6_prefix = 1;
2789 int idx_ext_community = 3;
2790 int idx_label = 5;
2791 int idx_word_2 = 7;
2792 if (argc == 8)
2793 return bgp_static_set_safi(
2794 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
2795 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2796 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
2797 else
2798 return bgp_static_set_safi(
2799 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
2800 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2801 NULL, 0, NULL, NULL, NULL, NULL);
2802 }
2803
2804 /* For testing purpose, static route of MPLS-VPN. */
2805 DEFUN (no_vpnv6_network,
2806 no_vpnv6_network_cmd,
2807 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2808 NO_STR
2809 "Specify a network to announce via BGP\n"
2810 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2811 "Specify Route Distinguisher\n"
2812 "VPN Route Distinguisher\n"
2813 "VPN NLRI label (tag)\n"
2814 "VPN NLRI label (tag)\n"
2815 "Label value\n")
2816 {
2817 int idx_ipv6_prefix = 2;
2818 int idx_ext_community = 4;
2819 int idx_label = 6;
2820 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
2821 argv[idx_ipv6_prefix]->arg,
2822 argv[idx_ext_community]->arg,
2823 argv[idx_label]->arg, 0, NULL, NULL, NULL);
2824 }
2825
2826 int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
2827 enum bgp_show_type type, void *output_arg, int tags,
2828 bool use_json)
2829 {
2830 struct bgp *bgp;
2831 struct bgp_table *table;
2832 uint16_t show_flags = 0;
2833
2834 if (use_json)
2835 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
2836
2837 bgp = bgp_get_default();
2838 if (bgp == NULL) {
2839 if (!use_json)
2840 vty_out(vty, "No BGP process is configured\n");
2841 else
2842 vty_out(vty, "{}\n");
2843 return CMD_WARNING;
2844 }
2845 table = bgp->rib[afi][SAFI_MPLS_VPN];
2846 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
2847 output_arg, show_flags);
2848 }
2849
2850 DEFUN (show_bgp_ip_vpn_all_rd,
2851 show_bgp_ip_vpn_all_rd_cmd,
2852 "show bgp "BGP_AFI_CMD_STR" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2853 SHOW_STR
2854 BGP_STR
2855 BGP_VPNVX_HELP_STR
2856 "Display VPN NLRI specific information\n"
2857 "Display VPN NLRI specific information\n"
2858 "Display information for a route distinguisher\n"
2859 "VPN Route Distinguisher\n"
2860 "All VPN Route Distinguishers\n"
2861 JSON_STR)
2862 {
2863 int ret;
2864 struct prefix_rd prd;
2865 afi_t afi;
2866 int idx = 0;
2867
2868 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
2869 /* Constrain search if user supplies RD && RD != "all" */
2870 if (argv_find(argv, argc, "rd", &idx)
2871 && strcmp(argv[idx + 1]->arg, "all")) {
2872 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
2873 if (!ret) {
2874 vty_out(vty,
2875 "%% Malformed Route Distinguisher\n");
2876 return CMD_WARNING;
2877 }
2878 return bgp_show_mpls_vpn(vty, afi, &prd,
2879 bgp_show_type_normal, NULL, 0,
2880 use_json(argc, argv));
2881 } else {
2882 return bgp_show_mpls_vpn(vty, afi, NULL,
2883 bgp_show_type_normal, NULL, 0,
2884 use_json(argc, argv));
2885 }
2886 }
2887 return CMD_SUCCESS;
2888 }
2889
2890 ALIAS(show_bgp_ip_vpn_all_rd,
2891 show_bgp_ip_vpn_rd_cmd,
2892 "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2893 SHOW_STR
2894 BGP_STR
2895 BGP_VPNVX_HELP_STR
2896 "Display VPN NLRI specific information\n"
2897 "Display information for a route distinguisher\n"
2898 "VPN Route Distinguisher\n"
2899 "All VPN Route Distinguishers\n"
2900 JSON_STR)
2901
2902 #ifdef KEEP_OLD_VPN_COMMANDS
2903 DEFUN (show_ip_bgp_vpn_rd,
2904 show_ip_bgp_vpn_rd_cmd,
2905 "show ip bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2906 SHOW_STR
2907 IP_STR
2908 BGP_STR
2909 BGP_AFI_HELP_STR
2910 BGP_AF_MODIFIER_STR
2911 "Display information for a route distinguisher\n"
2912 "VPN Route Distinguisher\n"
2913 "All VPN Route Distinguishers\n")
2914 {
2915 int idx_ext_community = argc - 1;
2916 int ret;
2917 struct prefix_rd prd;
2918 afi_t afi;
2919 int idx = 0;
2920
2921 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2922 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2923 return bgp_show_mpls_vpn(vty, afi, NULL,
2924 bgp_show_type_normal, NULL, 0,
2925 0);
2926 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2927 if (!ret) {
2928 vty_out(vty, "%% Malformed Route Distinguisher\n");
2929 return CMD_WARNING;
2930 }
2931 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2932 NULL, 0, 0);
2933 }
2934 return CMD_SUCCESS;
2935 }
2936
2937 DEFUN (show_ip_bgp_vpn_all,
2938 show_ip_bgp_vpn_all_cmd,
2939 "show [ip] bgp <vpnv4|vpnv6>",
2940 SHOW_STR
2941 IP_STR
2942 BGP_STR
2943 BGP_VPNVX_HELP_STR)
2944 {
2945 afi_t afi;
2946 int idx = 0;
2947
2948 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2949 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2950 NULL, 0, 0);
2951 return CMD_SUCCESS;
2952 }
2953
2954 DEFUN (show_ip_bgp_vpn_all_tags,
2955 show_ip_bgp_vpn_all_tags_cmd,
2956 "show [ip] bgp <vpnv4|vpnv6> all tags",
2957 SHOW_STR
2958 IP_STR
2959 BGP_STR
2960 BGP_VPNVX_HELP_STR
2961 "Display information about all VPNv4/VPNV6 NLRIs\n"
2962 "Display BGP tags for prefixes\n")
2963 {
2964 afi_t afi;
2965 int idx = 0;
2966
2967 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2968 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2969 NULL, 1, 0);
2970 return CMD_SUCCESS;
2971 }
2972
2973 DEFUN (show_ip_bgp_vpn_rd_tags,
2974 show_ip_bgp_vpn_rd_tags_cmd,
2975 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2976 SHOW_STR
2977 IP_STR
2978 BGP_STR
2979 BGP_VPNVX_HELP_STR
2980 "Display information for a route distinguisher\n"
2981 "VPN Route Distinguisher\n"
2982 "All VPN Route Distinguishers\n"
2983 "Display BGP tags for prefixes\n")
2984 {
2985 int idx_ext_community = 5;
2986 int ret;
2987 struct prefix_rd prd;
2988 afi_t afi;
2989 int idx = 0;
2990
2991 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2992 if (!strcmp(argv[idx_ext_community]->arg, "all"))
2993 return bgp_show_mpls_vpn(vty, afi, NULL,
2994 bgp_show_type_normal, NULL, 1,
2995 0);
2996 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2997 if (!ret) {
2998 vty_out(vty, "%% Malformed Route Distinguisher\n");
2999 return CMD_WARNING;
3000 }
3001 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
3002 NULL, 1, 0);
3003 }
3004 return CMD_SUCCESS;
3005 }
3006
3007 DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
3008 show_ip_bgp_vpn_all_neighbor_routes_cmd,
3009 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
3010 SHOW_STR
3011 IP_STR
3012 BGP_STR
3013 BGP_VPNVX_HELP_STR
3014 "Display information about all VPNv4/VPNv6 NLRIs\n"
3015 "Detailed information on TCP and BGP neighbor connections\n"
3016 "Neighbor to display information about\n"
3017 "Display routes learned from neighbor\n"
3018 JSON_STR)
3019 {
3020 int idx_ipv4 = 6;
3021 union sockunion su;
3022 struct peer *peer;
3023 int ret;
3024 bool uj = use_json(argc, argv);
3025 afi_t afi;
3026 int idx = 0;
3027
3028 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3029 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3030 if (ret < 0) {
3031 if (uj) {
3032 json_object *json_no = NULL;
3033 json_no = json_object_new_object();
3034 json_object_string_add(json_no, "warning",
3035 "Malformed address");
3036 vty_out(vty, "%s\n",
3037 json_object_to_json_string(json_no));
3038 json_object_free(json_no);
3039 } else
3040 vty_out(vty, "Malformed address: %s\n",
3041 argv[idx_ipv4]->arg);
3042 return CMD_WARNING;
3043 }
3044
3045 peer = peer_lookup(NULL, &su);
3046 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3047 if (uj) {
3048 json_object *json_no = NULL;
3049 json_no = json_object_new_object();
3050 json_object_string_add(
3051 json_no, "warning",
3052 "No such neighbor or address family");
3053 vty_out(vty, "%s\n",
3054 json_object_to_json_string(json_no));
3055 json_object_free(json_no);
3056 } else
3057 vty_out(vty,
3058 "%% No such neighbor or address family\n");
3059 return CMD_WARNING;
3060 }
3061
3062 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
3063 &su, 0, uj);
3064 }
3065 return CMD_SUCCESS;
3066 }
3067
3068 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
3069 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
3070 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
3071 SHOW_STR
3072 IP_STR
3073 BGP_STR
3074 BGP_VPNVX_HELP_STR
3075 "Display information for a route distinguisher\n"
3076 "VPN Route Distinguisher\n"
3077 "All VPN Route Distinguishers\n"
3078 "Detailed information on TCP and BGP neighbor connections\n"
3079 "Neighbor to display information about\n"
3080 "Display routes learned from neighbor\n"
3081 JSON_STR)
3082 {
3083 int idx_ext_community = 5;
3084 int idx_ipv4 = 7;
3085 int ret;
3086 union sockunion su;
3087 struct peer *peer;
3088 struct prefix_rd prd;
3089 bool prefix_rd_all = false;
3090 bool uj = use_json(argc, argv);
3091 afi_t afi;
3092 int idx = 0;
3093
3094 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3095 if (!strcmp(argv[idx_ext_community]->arg, "all"))
3096 prefix_rd_all = true;
3097 else {
3098 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3099 if (!ret) {
3100 if (uj) {
3101 json_object *json_no = NULL;
3102 json_no = json_object_new_object();
3103 json_object_string_add(
3104 json_no, "warning",
3105 "Malformed Route Distinguisher");
3106 vty_out(vty, "%s\n",
3107 json_object_to_json_string(
3108 json_no));
3109 json_object_free(json_no);
3110 } else
3111 vty_out(vty,
3112 "%% Malformed Route Distinguisher\n");
3113 return CMD_WARNING;
3114 }
3115 }
3116
3117 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3118 if (ret < 0) {
3119 if (uj) {
3120 json_object *json_no = NULL;
3121 json_no = json_object_new_object();
3122 json_object_string_add(json_no, "warning",
3123 "Malformed address");
3124 vty_out(vty, "%s\n",
3125 json_object_to_json_string(json_no));
3126 json_object_free(json_no);
3127 } else
3128 vty_out(vty, "Malformed address: %s\n",
3129 argv[idx_ext_community]->arg);
3130 return CMD_WARNING;
3131 }
3132
3133 peer = peer_lookup(NULL, &su);
3134 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3135 if (uj) {
3136 json_object *json_no = NULL;
3137 json_no = json_object_new_object();
3138 json_object_string_add(
3139 json_no, "warning",
3140 "No such neighbor or address family");
3141 vty_out(vty, "%s\n",
3142 json_object_to_json_string(json_no));
3143 json_object_free(json_no);
3144 } else
3145 vty_out(vty,
3146 "%% No such neighbor or address family\n");
3147 return CMD_WARNING;
3148 }
3149
3150 if (prefix_rd_all)
3151 return bgp_show_mpls_vpn(vty, afi, NULL,
3152 bgp_show_type_neighbor, &su, 0,
3153 uj);
3154 else
3155 return bgp_show_mpls_vpn(vty, afi, &prd,
3156 bgp_show_type_neighbor, &su, 0,
3157 uj);
3158 }
3159 return CMD_SUCCESS;
3160 }
3161
3162 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
3163 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
3164 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
3165 SHOW_STR
3166 IP_STR
3167 BGP_STR
3168 BGP_VPNVX_HELP_STR
3169 "Display information about all VPNv4/VPNv6 NLRIs\n"
3170 "Detailed information on TCP and BGP neighbor connections\n"
3171 "Neighbor to display information about\n"
3172 "Display the routes advertised to a BGP neighbor\n"
3173 JSON_STR)
3174 {
3175 int idx_ipv4 = 6;
3176 int ret;
3177 struct peer *peer;
3178 union sockunion su;
3179 bool uj = use_json(argc, argv);
3180 afi_t afi;
3181 int idx = 0;
3182
3183 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3184 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3185 if (ret < 0) {
3186 if (uj) {
3187 json_object *json_no = NULL;
3188 json_no = json_object_new_object();
3189 json_object_string_add(json_no, "warning",
3190 "Malformed address");
3191 vty_out(vty, "%s\n",
3192 json_object_to_json_string(json_no));
3193 json_object_free(json_no);
3194 } else
3195 vty_out(vty, "Malformed address: %s\n",
3196 argv[idx_ipv4]->arg);
3197 return CMD_WARNING;
3198 }
3199 peer = peer_lookup(NULL, &su);
3200 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3201 if (uj) {
3202 json_object *json_no = NULL;
3203 json_no = json_object_new_object();
3204 json_object_string_add(
3205 json_no, "warning",
3206 "No such neighbor or address family");
3207 vty_out(vty, "%s\n",
3208 json_object_to_json_string(json_no));
3209 json_object_free(json_no);
3210 } else
3211 vty_out(vty,
3212 "%% No such neighbor or address family\n");
3213 return CMD_WARNING;
3214 }
3215 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
3216 SAFI_MPLS_VPN, uj);
3217 }
3218 return CMD_SUCCESS;
3219 }
3220
3221 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
3222 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
3223 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
3224 SHOW_STR
3225 IP_STR
3226 BGP_STR
3227 BGP_VPNVX_HELP_STR
3228 "Display information for a route distinguisher\n"
3229 "VPN Route Distinguisher\n"
3230 "All VPN Route Distinguishers\n"
3231 "Detailed information on TCP and BGP neighbor connections\n"
3232 "Neighbor to display information about\n"
3233 "Display the routes advertised to a BGP neighbor\n"
3234 JSON_STR)
3235 {
3236 int idx_ext_community = 5;
3237 int idx_ipv4 = 7;
3238 int ret;
3239 struct peer *peer;
3240 struct prefix_rd prd;
3241 union sockunion su;
3242 bool uj = use_json(argc, argv);
3243 afi_t afi;
3244 int idx = 0;
3245
3246 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
3247 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
3248 if (ret < 0) {
3249 if (uj) {
3250 json_object *json_no = NULL;
3251 json_no = json_object_new_object();
3252 json_object_string_add(json_no, "warning",
3253 "Malformed address");
3254 vty_out(vty, "%s\n",
3255 json_object_to_json_string(json_no));
3256 json_object_free(json_no);
3257 } else
3258 vty_out(vty, "Malformed address: %s\n",
3259 argv[idx_ext_community]->arg);
3260 return CMD_WARNING;
3261 }
3262 peer = peer_lookup(NULL, &su);
3263 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
3264 if (uj) {
3265 json_object *json_no = NULL;
3266 json_no = json_object_new_object();
3267 json_object_string_add(
3268 json_no, "warning",
3269 "No such neighbor or address family");
3270 vty_out(vty, "%s\n",
3271 json_object_to_json_string(json_no));
3272 json_object_free(json_no);
3273 } else
3274 vty_out(vty,
3275 "%% No such neighbor or address family\n");
3276 return CMD_WARNING;
3277 }
3278
3279 if (!strcmp(argv[idx_ext_community]->arg, "all"))
3280 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
3281 SAFI_MPLS_VPN, uj);
3282 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
3283 if (!ret) {
3284 if (uj) {
3285 json_object *json_no = NULL;
3286 json_no = json_object_new_object();
3287 json_object_string_add(
3288 json_no, "warning",
3289 "Malformed Route Distinguisher");
3290 vty_out(vty, "%s\n",
3291 json_object_to_json_string(json_no));
3292 json_object_free(json_no);
3293 } else
3294 vty_out(vty,
3295 "%% Malformed Route Distinguisher\n");
3296 return CMD_WARNING;
3297 }
3298
3299 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
3300 SAFI_MPLS_VPN, uj);
3301 }
3302 return CMD_SUCCESS;
3303 }
3304 #endif /* KEEP_OLD_VPN_COMMANDS */
3305
3306 void bgp_mplsvpn_init(void)
3307 {
3308 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
3309 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
3310 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
3311
3312 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
3313 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
3314
3315 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
3316 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
3317 #ifdef KEEP_OLD_VPN_COMMANDS
3318 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
3319 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
3320 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
3321 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
3322 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
3323 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
3324 install_element(VIEW_NODE,
3325 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
3326 install_element(VIEW_NODE,
3327 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
3328 #endif /* KEEP_OLD_VPN_COMMANDS */
3329 }
3330
3331 vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
3332 {
3333 struct listnode *mnode, *mnnode;
3334 struct bgp *bgp;
3335 afi_t afi = AFI_IP;
3336
3337 if (eckey->unit_size == IPV6_ECOMMUNITY_SIZE)
3338 afi = AFI_IP6;
3339
3340 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
3341 struct ecommunity *ec;
3342
3343 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3344 continue;
3345
3346 ec = bgp->vpn_policy[afi].import_redirect_rtlist;
3347
3348 if (ec && eckey->unit_size != ec->unit_size)
3349 continue;
3350
3351 if (ecommunity_include(ec, eckey))
3352 return bgp->vrf_id;
3353 }
3354 return VRF_UNKNOWN;
3355 }
3356
3357 /*
3358 * The purpose of this function is to process leaks that were deferred
3359 * from earlier per-vrf configuration due to not-yet-existing default
3360 * vrf, in other words, configuration such as:
3361 *
3362 * router bgp MMM vrf FOO
3363 * address-family ipv4 unicast
3364 * rd vpn export 1:1
3365 * exit-address-family
3366 *
3367 * router bgp NNN
3368 * ...
3369 *
3370 * This function gets called when the default instance ("router bgp NNN")
3371 * is created.
3372 */
3373 void vpn_leak_postchange_all(void)
3374 {
3375 struct listnode *next;
3376 struct bgp *bgp;
3377 struct bgp *bgp_default = bgp_get_default();
3378
3379 assert(bgp_default);
3380
3381 /* First, do any exporting from VRFs to the single VPN RIB */
3382 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
3383
3384 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3385 continue;
3386
3387 vpn_leak_postchange(
3388 BGP_VPN_POLICY_DIR_TOVPN,
3389 AFI_IP,
3390 bgp_default,
3391 bgp);
3392
3393 vpn_leak_postchange(
3394 BGP_VPN_POLICY_DIR_TOVPN,
3395 AFI_IP6,
3396 bgp_default,
3397 bgp);
3398 }
3399
3400 /* Now, do any importing to VRFs from the single VPN RIB */
3401 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
3402
3403 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3404 continue;
3405
3406 vpn_leak_postchange(
3407 BGP_VPN_POLICY_DIR_FROMVPN,
3408 AFI_IP,
3409 bgp_default,
3410 bgp);
3411
3412 vpn_leak_postchange(
3413 BGP_VPN_POLICY_DIR_FROMVPN,
3414 AFI_IP6,
3415 bgp_default,
3416 bgp);
3417 }
3418 }
3419
3420 /* When a bgp vrf instance is unconfigured, remove its routes
3421 * from the VPN table and this vrf could be importing routes from other
3422 * bgp vrf instnaces, unimport them.
3423 * VRF X and VRF Y are exporting routes to each other.
3424 * When VRF X is deleted, unimport its routes from all target vrfs,
3425 * also VRF Y should unimport its routes from VRF X table.
3426 * This will ensure VPN table is cleaned up appropriately.
3427 */
3428 void bgp_vpn_leak_unimport(struct bgp *from_bgp)
3429 {
3430 struct bgp *to_bgp;
3431 const char *tmp_name;
3432 char *vname;
3433 struct listnode *node, *next;
3434 safi_t safi = SAFI_UNICAST;
3435 afi_t afi;
3436 bool is_vrf_leak_bind;
3437 int debug;
3438
3439 if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3440 return;
3441
3442 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3443 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3444
3445 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
3446
3447 for (afi = 0; afi < AFI_MAX; ++afi) {
3448 /* vrf leak is for IPv4 and IPv6 Unicast only */
3449 if (afi != AFI_IP && afi != AFI_IP6)
3450 continue;
3451
3452 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3453 if (from_bgp == to_bgp)
3454 continue;
3455
3456 /* Unimport and remove source vrf from the
3457 * other vrfs import list.
3458 */
3459 struct vpn_policy *to_vpolicy;
3460
3461 is_vrf_leak_bind = false;
3462 to_vpolicy = &(to_bgp->vpn_policy[afi]);
3463 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf, node,
3464 vname)) {
3465 if (strcmp(vname, tmp_name) == 0) {
3466 is_vrf_leak_bind = true;
3467 break;
3468 }
3469 }
3470 /* skip this bgp instance as there is no leak to this
3471 * vrf instance.
3472 */
3473 if (!is_vrf_leak_bind)
3474 continue;
3475
3476 if (debug)
3477 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3478 __func__, from_bgp->name_pretty,
3479 to_bgp->name_pretty, afi2str(afi),
3480 to_vpolicy->import_vrf->count);
3481
3482 vrf_unimport_from_vrf(to_bgp, from_bgp, afi, safi);
3483
3484 /* readd vrf name as unimport removes import vrf name
3485 * from the destination vrf's import list where the
3486 * `import vrf` configuration still exist.
3487 */
3488 vname = XSTRDUP(MTYPE_TMP, tmp_name);
3489 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
3490 vname);
3491 SET_FLAG(to_bgp->af_flags[afi][safi],
3492 BGP_CONFIG_VRF_TO_VRF_IMPORT);
3493
3494 /* If to_bgp exports its routes to the bgp vrf
3495 * which is being deleted, un-import the
3496 * to_bgp routes from VPN.
3497 */
3498 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi]
3499 .export_vrf, node,
3500 vname)) {
3501 if (strcmp(vname, tmp_name) == 0) {
3502 vrf_unimport_from_vrf(from_bgp, to_bgp,
3503 afi, safi);
3504 break;
3505 }
3506 }
3507 }
3508 }
3509 return;
3510 }
3511
3512 /* When a router bgp is configured, there could be a bgp vrf
3513 * instance importing routes from this newly configured
3514 * bgp vrf instance. Export routes from configured
3515 * bgp vrf to VPN.
3516 * VRF Y has import from bgp vrf x,
3517 * when a bgp vrf x instance is created, export its routes
3518 * to VRF Y instance.
3519 */
3520 void bgp_vpn_leak_export(struct bgp *from_bgp)
3521 {
3522 afi_t afi;
3523 const char *export_name;
3524 char *vname;
3525 struct listnode *node, *next;
3526 struct ecommunity *ecom;
3527 enum vpn_policy_direction idir, edir;
3528 safi_t safi = SAFI_UNICAST;
3529 struct bgp *to_bgp;
3530 int debug;
3531
3532 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
3533 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
3534
3535 idir = BGP_VPN_POLICY_DIR_FROMVPN;
3536 edir = BGP_VPN_POLICY_DIR_TOVPN;
3537
3538 export_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
3539
3540 for (afi = 0; afi < AFI_MAX; ++afi) {
3541 /* vrf leak is for IPv4 and IPv6 Unicast only */
3542 if (afi != AFI_IP && afi != AFI_IP6)
3543 continue;
3544
3545 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
3546 if (from_bgp == to_bgp)
3547 continue;
3548
3549 /* bgp instance has import list, check to see if newly
3550 * configured bgp instance is the list.
3551 */
3552 struct vpn_policy *to_vpolicy;
3553
3554 to_vpolicy = &(to_bgp->vpn_policy[afi]);
3555 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
3556 node, vname)) {
3557 if (strcmp(vname, export_name) != 0)
3558 continue;
3559
3560 if (debug)
3561 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3562 __func__,
3563 export_name, to_bgp->name_pretty);
3564
3565 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
3566 /* remove import rt, it will be readded
3567 * as part of import from vrf.
3568 */
3569 if (ecom)
3570 ecommunity_del_val(
3571 to_vpolicy->rtlist[idir],
3572 (struct ecommunity_val *)
3573 ecom->val);
3574 vrf_import_from_vrf(to_bgp, from_bgp,
3575 afi, safi);
3576 break;
3577
3578 }
3579 }
3580 }
3581 }