1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
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"
39 #include "bgpd/rfapi/rfapi_backend.h"
43 * Definitions and external declarations.
45 extern struct zclient
*zclient
;
47 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
48 int *index
, afi_t
*afi
)
51 if (argv_find(argv
, argc
, "vpnv4", index
)) {
55 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
63 uint32_t decode_label(mpls_label_t
*label_pnt
)
66 uint8_t *pnt
= (uint8_t *)label_pnt
;
68 l
= ((uint32_t)*pnt
++ << 12);
69 l
|= (uint32_t)*pnt
++ << 4;
70 l
|= (uint32_t)((*pnt
& 0xf0) >> 4);
74 void encode_label(mpls_label_t label
, mpls_label_t
*label_pnt
)
76 uint8_t *pnt
= (uint8_t *)label_pnt
;
79 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
) {
83 *pnt
++ = (label
>> 12) & 0xff;
84 *pnt
++ = (label
>> 4) & 0xff;
85 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
88 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
89 struct bgp_nlri
*packet
)
97 struct prefix_rd prd
= {0};
98 mpls_label_t label
= {0};
101 bool addpath_capable
;
106 prd
.family
= AF_UNSPEC
;
109 struct stream
*data
= stream_new(packet
->length
);
110 stream_put(data
, packet
->nlri
, packet
->length
);
115 addpath_capable
= bgp_addpath_encode_rx(peer
, afi
, safi
);
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
));
122 if (addpath_capable
) {
123 STREAM_GET(&addpath_id
, data
, BGP_ADDPATH_ID_LEN
);
124 addpath_id
= ntohl(addpath_id
);
127 if (STREAM_READABLE(data
) < 1) {
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
;
136 /* Fetch prefix length. */
137 STREAM_GETC(data
, prefixlen
);
138 p
.family
= afi2family(packet
->afi
);
139 psize
= PSIZE(prefixlen
);
141 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
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
;
150 /* sanity check against packet data */
151 if (STREAM_READABLE(data
) < psize
) {
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
;
160 /* sanity check against storage for the IP address portion */
161 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
164 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
166 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
168 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
172 /* Sanity check against max bitlen of the address family */
173 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
176 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
178 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
179 p
.family
, prefix_blen(&p
));
180 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
184 /* Copy label to prefix. */
185 if (STREAM_READABLE(data
) < BGP_LABEL_BYTES
) {
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
;
194 STREAM_GET(&label
, data
, BGP_LABEL_BYTES
);
195 bgp_set_valid_label(&label
);
197 /* Copy routing distinguisher to rd. */
198 if (STREAM_READABLE(data
) < 8) {
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
;
206 STREAM_GET(&prd
.val
, data
, 8);
208 /* Decode RD type. */
209 type
= decode_rd_type(prd
.val
);
213 decode_rd_as(&prd
.val
[2], &rd_as
);
217 decode_rd_as4(&prd
.val
[2], &rd_as
);
221 decode_rd_ip(&prd
.val
[2], &rd_ip
);
224 #ifdef ENABLE_BGP_VNC
225 case RD_TYPE_VNC_ETH
:
230 flog_err(EC_BGP_UPDATE_RCV
, "Unknown RD type %d", type
);
231 break; /* just report */
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
);
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
);
243 bgp_withdraw(peer
, &p
, addpath_id
, packet
->afi
,
244 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
245 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
248 /* Packet length consistency check. */
249 if (STREAM_READABLE(data
) != 0) {
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
;
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
;
270 #undef VPN_PREFIXLEN_MIN_BYTES
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."
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.
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
286 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
288 mpls_label_t label
= MPLS_LABEL_NONE
;
289 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
291 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
294 "%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
295 __func__
, bgp
->name_pretty
, afi2str(afi
));
300 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
301 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
305 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
306 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
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
;
317 * If zebra tells us vrf has become unconfigured, tell zebra not to
318 * use this label to forward to the vrf anymore
320 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
322 mpls_label_t label
= MPLS_LABEL_NONE
;
323 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
325 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
328 "%s: vrf_id not set, can't delete zebra vrf label",
335 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
336 bgp
->name_pretty
, bgp
->vrf_id
);
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
;
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."
348 void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp
*bgp
, afi_t afi
)
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
;
357 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
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
));
364 tovpn_sid
= bgp
->vpn_policy
[afi
].tovpn_sid
;
367 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__
,
368 bgp
->name_pretty
, afi2str(afi
));
373 zlog_debug("%s: vrf %s: afi %s: setting sid %pI6 for vrf id %d",
374 __func__
, bgp
->name_pretty
, afi2str(afi
), tovpn_sid
,
377 vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
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
);
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
;
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."
396 void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp
*bgp
)
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
;
405 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
408 "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
409 __func__
, bgp
->name_pretty
);
413 tovpn_sid
= bgp
->tovpn_sid
;
416 zlog_debug("%s: vrf %s: sid not set", __func__
,
422 zlog_debug("%s: vrf %s: setting sid %pI6 for vrf id %d",
423 __func__
, bgp
->name_pretty
, tovpn_sid
, bgp
->vrf_id
);
425 vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
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
);
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
;
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."
443 void vpn_leak_zebra_vrf_sid_update(struct bgp
*bgp
, afi_t afi
)
445 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
447 if (bgp
->vpn_policy
[afi
].tovpn_sid
)
448 return vpn_leak_zebra_vrf_sid_update_per_af(bgp
, afi
);
451 return vpn_leak_zebra_vrf_sid_update_per_vrf(bgp
);
454 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__
,
455 bgp
->name_pretty
, afi2str(afi
));
459 * If zebra tells us vrf has become unconfigured, tell zebra not to
460 * use this srv6-function to forward to the vrf anymore
462 void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp
*bgp
, afi_t afi
)
464 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
466 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
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
));
474 zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__
,
475 bgp
->name_pretty
, bgp
->vrf_id
);
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
);
485 * If zebra tells us vrf has become unconfigured, tell zebra not to
486 * use this srv6-function to forward to the vrf anymore
488 void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp
*bgp
)
490 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
492 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
495 "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
496 __func__
, bgp
->name_pretty
);
501 zlog_debug("%s: deleting sid for vrf %s (id=%d)", __func__
,
502 bgp
->name_pretty
, bgp
->vrf_id
);
504 zclient_send_localsid(zclient
, bgp
->tovpn_zebra_vrf_sid_last_sent
,
505 bgp
->vrf_id
, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
,
507 XFREE(MTYPE_BGP_SRV6_SID
, bgp
->tovpn_zebra_vrf_sid_last_sent
);
511 * If zebra tells us vrf has become unconfigured, tell zebra not to
512 * use this srv6-function to forward to the vrf anymore
514 void vpn_leak_zebra_vrf_sid_withdraw(struct bgp
*bgp
, afi_t afi
)
516 if (bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
)
517 vpn_leak_zebra_vrf_sid_withdraw_per_af(bgp
, afi
);
519 if (bgp
->tovpn_zebra_vrf_sid_last_sent
)
520 vpn_leak_zebra_vrf_sid_withdraw_per_vrf(bgp
);
523 int vpn_leak_label_callback(
528 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
529 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
532 zlog_debug("%s: label=%u, allocated=%d",
533 __func__
, label
, allocated
);
537 * previously-allocated label is now invalid
539 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
540 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
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
);
552 * New label allocation
554 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
557 * not currently configured for auto label, reject allocation
562 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
563 if (label
== vp
->tovpn_label
) {
564 /* already have same label, accept but do nothing */
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
,
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
);
584 static void sid_register(struct bgp
*bgp
, const struct in6_addr
*sid
,
585 const char *locator_name
)
587 struct bgp_srv6_function
*func
;
588 func
= XCALLOC(MTYPE_BGP_SRV6_FUNCTION
,
589 sizeof(struct bgp_srv6_function
));
591 snprintf(func
->locator_name
, sizeof(func
->locator_name
),
593 listnode_add(bgp
->srv6_functions
, func
);
596 static void sid_unregister(struct bgp
*bgp
, const struct in6_addr
*sid
)
598 struct listnode
*node
, *nnode
;
599 struct bgp_srv6_function
*func
;
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
);
608 static bool sid_exist(struct bgp
*bgp
, const struct in6_addr
*sid
)
610 struct listnode
*node
;
611 struct bgp_srv6_function
*func
;
613 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_functions
, node
, func
))
614 if (sid_same(&func
->sid
, sid
))
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.
624 * if index != 0: try to allocate as index-mode
625 * else: try to allocate as auto-mode
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
)
631 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
632 struct listnode
*node
;
633 struct srv6_locator_chunk
*chunk
;
634 bool alloced
= false;
637 uint8_t func_len
= 0, shift_len
= 0;
638 uint32_t index_max
= 0;
640 if (!bgp
|| !sid_locator_chunk
|| !sid
)
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
) {
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
);
654 index_max
= (1 << chunk
->function_bits_length
) - 1;
656 if (index
> index_max
) {
659 "%s: skipped SRv6 Locator chunk (%pFX): Function Length is too short to support specified index (%u)",
660 __func__
, &chunk
->prefix
, index
);
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
;
671 label
= index
<< shift_len
;
672 if (label
< MPLS_LABEL_UNRESERVED_MIN
) {
675 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
676 __func__
, &chunk
->prefix
,
681 transpose_sid(sid
, label
, offset
, func_len
);
682 if (sid_exist(bgp
, sid
))
688 for (uint32_t i
= 1; i
< index_max
; i
++) {
689 label
= i
<< shift_len
;
690 if (label
< MPLS_LABEL_UNRESERVED_MIN
) {
693 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
694 __func__
, &chunk
->prefix
,
698 transpose_sid(sid
, label
, offset
, func_len
);
699 if (sid_exist(bgp
, sid
))
709 sid_register(bgp
, sid
, bgp
->srv6_locator_name
);
713 void ensure_vrf_tovpn_sid_per_af(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
,
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;
723 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
724 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
726 /* skip when tovpn sid is already allocated on vrf instance */
727 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
)
731 * skip when bgp vpn instance ins't allocated
732 * or srv6 locator chunk isn't allocated
734 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
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
);
741 /* skip when VPN isn't configured on vrf-instance */
742 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
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.",
752 tovpn_sid_locator
= srv6_locator_chunk_alloc();
753 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
755 tovpn_sid_transpose_label
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
,
756 tovpn_sid_locator
, tovpn_sid
);
758 if (tovpn_sid_transpose_label
== 0) {
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
);
769 zlog_debug("%s: new sid %pI6 allocated for vrf %s: afi %s",
770 __func__
, tovpn_sid
, bgp_vrf
->name_pretty
,
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
;
779 void ensure_vrf_tovpn_sid_per_vrf(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
)
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;
788 zlog_debug("%s: try to allocate new SID for vrf %s", __func__
,
789 bgp_vrf
->name_pretty
);
791 /* skip when tovpn sid is already allocated on vrf instance */
792 if (bgp_vrf
->tovpn_sid
)
796 * skip when bgp vpn instance ins't allocated
797 * or srv6 locator chunk isn't allocated
799 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
802 tovpn_sid_index
= bgp_vrf
->tovpn_sid_index
;
803 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_TOVPN_SID_AUTO
);
805 /* skip when VPN isn't configured on vrf-instance */
806 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
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.",
816 tovpn_sid_locator
= srv6_locator_chunk_alloc();
817 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
819 tovpn_sid_transpose_label
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
,
820 tovpn_sid_locator
, tovpn_sid
);
822 if (tovpn_sid_transpose_label
== 0) {
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
);
832 zlog_debug("%s: new sid %pI6 allocated for vrf %s", __func__
,
833 tovpn_sid
, bgp_vrf
->name_pretty
);
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
;
840 void ensure_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
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
);
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
);
854 void delete_vrf_tovpn_sid_per_af(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
,
857 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
858 uint32_t tovpn_sid_index
= 0;
859 bool tovpn_sid_auto
= false;
862 zlog_debug("%s: try to remove SID for vrf %s: afi %s", __func__
,
863 bgp_vrf
->name_pretty
, afi2str(afi
));
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
);
869 /* skip when VPN is configured on vrf-instance */
870 if (tovpn_sid_index
!= 0 || tovpn_sid_auto
)
873 srv6_locator_chunk_free(&bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
);
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
);
879 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
= 0;
882 void delete_vrf_tovpn_sid_per_vrf(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
)
884 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
885 uint32_t tovpn_sid_index
= 0;
886 bool tovpn_sid_auto
= false;
889 zlog_debug("%s: try to remove SID for vrf %s", __func__
,
890 bgp_vrf
->name_pretty
);
892 tovpn_sid_index
= bgp_vrf
->tovpn_sid_index
;
894 CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VPN_POLICY_TOVPN_SID_AUTO
);
896 /* skip when VPN is configured on vrf-instance */
897 if (tovpn_sid_index
!= 0 || tovpn_sid_auto
)
900 srv6_locator_chunk_free(&bgp_vrf
->tovpn_sid_locator
);
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
);
906 bgp_vrf
->tovpn_sid_transpose_label
= 0;
909 void delete_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
911 delete_vrf_tovpn_sid_per_af(bgp_vpn
, bgp_vrf
, afi
);
912 delete_vrf_tovpn_sid_per_vrf(bgp_vpn
, bgp_vrf
);
916 * This function embeds upper `len` bits of `label` in `sid`,
917 * starting at offset `offset` as seen from the MSB of `sid`.
919 * e.g. Given that `label` is 0x12345 and `len` is 16,
920 * then `label` will be embedded in `sid` as follows:
923 * label: 0001 0002 0003 0004 0005
924 * sid: .... 0001 0002 0003 0004
930 * e.g. Given that `label` is 0x12345 and `len` is 8,
931 * `label` will be embedded in `sid` as follows:
934 * label: 0001 0002 0003 0004 0005
935 * sid: .... 0001 0002 0000 0000
941 void transpose_sid(struct in6_addr
*sid
, uint32_t label
, uint8_t offset
,
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);
952 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
964 if (n
!= bpi
->extra
->num_labels
)
967 for (i
= 0; i
< n
; ++i
) {
968 if (label
[i
] != bpi
->extra
->label
[i
])
975 * make encoded route labels match specified encoded label set
977 static void setlabels(struct bgp_path_info
*bpi
,
978 mpls_label_t
*label
, /* array of labels */
983 assert(num_labels
<= BGP_MAX_LABELS
);
987 bpi
->extra
->num_labels
= 0;
991 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
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
]);
1000 extra
->num_labels
= num_labels
;
1004 * make encoded route SIDs match specified encoded sid set
1006 static void setsids(struct bgp_path_info
*bpi
,
1007 struct in6_addr
*sid
,
1011 struct bgp_path_info_extra
*extra
;
1015 assert(num_sids
<= BGP_MAX_SIDS
);
1019 bpi
->extra
->num_sids
= 0;
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
;
1029 static void unsetsids(struct bgp_path_info
*bpi
)
1031 struct bgp_path_info_extra
*extra
;
1033 extra
= bgp_path_info_extra_get(bpi
);
1034 extra
->num_sids
= 0;
1035 memset(extra
->sid
, 0, sizeof(extra
->sid
));
1038 static bool leak_update_nexthop_valid(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
1039 struct attr
*new_attr
, afi_t afi
,
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
)
1046 struct bgp_path_info
*bpi_ultimate
;
1047 struct bgp
*bgp_nexthop
;
1050 bpi_ultimate
= bgp_get_imported_bpi_ultimate(source_bpi
);
1052 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
1053 bgp_nexthop
= bpi
->extra
->bgp_orig
;
1055 bgp_nexthop
= bgp_orig
;
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.
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
))
1068 * TBD do we need to do anything about the
1069 * 'connected' parameter?
1071 nh_valid
= bgp_find_or_add_nexthop(to_bgp
, bgp_nexthop
, afi
,
1072 safi
, bpi
, NULL
, 0, p
);
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
1079 if (to_bgp
->srv6_enabled
&&
1080 (!new_attr
->srv6_l3vpn
&& !new_attr
->srv6_vpn
)) {
1085 zlog_debug("%s: %pFX nexthop is %svalid (in %s)", __func__
, p
,
1086 (nh_valid
? "" : "not "), bgp_nexthop
->name_pretty
);
1092 * returns pointer to new bgp_path_info upon success
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
)
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 struct bgp_path_info
*parent
= source_bpi
;
1108 if (new_attr
->srv6_l3vpn
|| new_attr
->srv6_vpn
)
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
);
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.
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.
1136 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1137 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
1142 bool labelssame
= labels_same(bpi
, label
, num_labels
);
1144 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
1145 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
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
);
1155 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
1156 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
1158 bgp_attr_unintern(&new_attr
);
1161 "%s: ->%s: %pBD: Found route, no change",
1162 __func__
, to_bgp
->name_pretty
, bn
);
1166 /* If the RT was changed via extended communities as an
1167 * import/export list, we should withdraw implicitly the old
1169 * For instance, RT list was modified using route-maps:
1170 * route-map test permit 10
1171 * set extcommunity rt none
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
,
1183 bgp_path_info_delete(bn
, bpi
);
1187 /* attr is changed */
1188 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
1190 /* Rewrite BGP route information. */
1191 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1192 bgp_path_info_restore(bn
, bpi
);
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
);
1203 setlabels(bpi
, label
, num_labels
);
1209 if (new_attr
->srv6_l3vpn
) {
1210 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
1213 extra
= bgp_path_info_extra_get(bpi
);
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
,
1234 if (nexthop_self_flag
)
1235 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
1237 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1238 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ACCEPT_OWN
);
1240 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1241 source_bpi
, bpi
, bgp_orig
, p
,
1243 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
1245 bgp_path_info_unset_flag(bn
, bpi
, BGP_PATH_VALID
);
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
);
1253 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
1254 __func__
, to_bgp
->name_pretty
, bn
);
1259 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
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
);
1269 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
1270 to_bgp
->peer_self
, new_attr
, bn
);
1272 if (source_bpi
->peer
) {
1273 extra
= bgp_path_info_extra_get(new);
1274 extra
->peer_orig
= peer_lock(source_bpi
->peer
);
1277 if (nexthop_self_flag
)
1278 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
1280 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1281 bgp_path_info_set_flag(bn
, new, BGP_PATH_ACCEPT_OWN
);
1283 bgp_path_info_extra_get(new);
1289 if (new_attr
->srv6_l3vpn
) {
1290 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
1292 extra
= bgp_path_info_extra_get(new);
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
);
1310 setlabels(new, label
, num_labels
);
1312 new->extra
->parent
= bgp_path_info_lock(parent
);
1314 (struct bgp_dest
*)parent
->net
);
1316 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
1318 new->extra
->nexthop_orig
= *nexthop_orig
;
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
);
1324 bgp_path_info_unset_flag(bn
, new, BGP_PATH_VALID
);
1326 bgp_aggregate_increment(to_bgp
, p
, new, afi
, safi
);
1327 bgp_path_info_add(bn
, new);
1329 bgp_dest_unlock_node(bn
);
1330 bgp_process(to_bgp
, bn
, afi
, safi
);
1333 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
1334 to_bgp
->name_pretty
, bn
);
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 */
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
;
1352 struct bgp_dest
*bn
;
1353 const char *debugmsg
;
1354 int nexthop_self_flag
= 0;
1357 zlog_debug("%s: from vrf %s", __func__
, from_bgp
->name_pretty
);
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);
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
);
1374 zlog_debug("%s: can't get afi of prefix", __func__
);
1378 /* Is this route exportable into the VPN table? */
1379 if (!is_route_injectable_into_vpn(path_vrf
))
1382 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1384 zlog_debug("%s: %s skipping: %s", __func__
,
1385 from_bgp
->name
, debugmsg
);
1390 static_attr
= *path_vrf
->attr
;
1393 * route map handling
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
;
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
],
1405 if (RMAP_DENYMATCH
== ret
) {
1406 bgp_attr_flush(&static_attr
); /* free any added parts */
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
]
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);
1423 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1425 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1429 * Add the vpn-policy rt-list
1431 struct ecommunity
*old_ecom
;
1432 struct ecommunity
*new_ecom
;
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
);
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
);
1448 new_ecom
= ecommunity_dup(
1449 from_bgp
->vpn_policy
[afi
]
1450 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1452 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
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);
1459 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1461 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1464 community_strip_accept_own(&static_attr
);
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
;
1473 switch (nexthop
->family
) {
1475 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1477 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1479 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1480 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1484 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1485 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
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
)) {
1497 * For ipv4, copy to multiprotocol
1500 static_attr
.mp_nexthop_global_in
=
1501 static_attr
.nexthop
;
1502 static_attr
.mp_nexthop_len
=
1503 BGP_ATTR_NHLEN_IPV4
;
1505 * XXX Leave static_attr.nexthop
1509 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
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
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
;
1525 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1528 nexthop_self_flag
= 1;
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
);
1535 encode_label(label_val
, &label
);
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
;
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
;
1547 from_bgp
->vpn_policy
[afi
].tovpn_sid_transpose_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
=
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
;
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
));
1616 new_attr
= bgp_attr_intern(
1617 &static_attr
); /* hashed refcounted everything */
1618 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
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);
1624 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1625 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1628 /* Now new_attr is an allocated interned attr */
1630 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1631 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1633 struct bgp_path_info
*new_info
;
1636 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vrf
, &label
,
1637 1, from_bgp
, NULL
, nexthop_self_flag
, debug
);
1640 * Routes actually installed in the vpn RIB must also be
1641 * offered to all vrfs (because now they originate from
1644 * Acceptance into other vrfs depends on rt-lists.
1645 * Originating vrf will not accept the looped back route
1646 * because of loop checking.
1649 vpn_leak_to_vrf_update(from_bgp
, new_info
, NULL
);
1651 bgp_dest_unlock_node(bn
);
1654 void vpn_leak_from_vrf_withdraw(struct bgp
*to_bgp
, /* to */
1655 struct bgp
*from_bgp
, /* from */
1656 struct bgp_path_info
*path_vrf
) /* route */
1658 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1659 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1660 afi_t afi
= family2afi(p
->family
);
1661 safi_t safi
= SAFI_MPLS_VPN
;
1662 struct bgp_path_info
*bpi
;
1663 struct bgp_dest
*bn
;
1664 const char *debugmsg
;
1668 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1669 __func__
, from_bgp
->name_pretty
, path_vrf
->net
,
1670 path_vrf
->type
, path_vrf
->sub_type
);
1678 zlog_debug("%s: can't get afi of prefix", __func__
);
1682 /* Is this route exportable into the VPN table? */
1683 if (!is_route_injectable_into_vpn(path_vrf
))
1686 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1688 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1693 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1695 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1696 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1702 * match original bpi imported from
1704 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1705 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1711 /* withdraw from looped vrfs as well */
1712 vpn_leak_to_vrf_withdraw(bpi
);
1714 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1715 bgp_path_info_delete(bn
, bpi
);
1716 bgp_process(to_bgp
, bn
, afi
, safi
);
1718 bgp_dest_unlock_node(bn
);
1721 void vpn_leak_from_vrf_withdraw_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1724 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1725 struct bgp_dest
*pdest
;
1726 safi_t safi
= SAFI_MPLS_VPN
;
1729 * Walk vpn table, delete bpi with bgp_orig == from_bgp
1731 for (pdest
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); pdest
;
1732 pdest
= bgp_route_next(pdest
)) {
1734 struct bgp_table
*table
;
1735 struct bgp_dest
*bn
;
1736 struct bgp_path_info
*bpi
;
1738 /* This is the per-RD table of prefixes */
1739 table
= bgp_dest_get_bgp_table_info(pdest
);
1744 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1745 bpi
= bgp_dest_get_bgp_path_info(bn
);
1747 zlog_debug("%s: looking at prefix %pBD",
1751 for (; bpi
; bpi
= bpi
->next
) {
1753 zlog_debug("%s: type %d, sub_type %d",
1754 __func__
, bpi
->type
,
1756 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1760 if ((struct bgp
*)bpi
->extra
->bgp_orig
==
1764 zlog_debug("%s: deleting it",
1766 /* withdraw from leak-to vrfs as well */
1767 vpn_leak_to_vrf_withdraw(bpi
);
1768 bgp_aggregate_decrement(
1769 to_bgp
, bgp_dest_get_prefix(bn
),
1771 bgp_path_info_delete(bn
, bpi
);
1772 bgp_process(to_bgp
, bn
, afi
, safi
);
1779 void vpn_leak_from_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1782 struct bgp_dest
*bn
;
1783 struct bgp_path_info
*bpi
;
1784 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1787 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1788 from_bgp
->name_pretty
);
1790 for (bn
= bgp_table_top(from_bgp
->rib
[afi
][SAFI_UNICAST
]); bn
;
1791 bn
= bgp_route_next(bn
)) {
1794 zlog_debug("%s: node=%p", __func__
, bn
);
1796 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1800 "%s: calling vpn_leak_from_vrf_update",
1802 vpn_leak_from_vrf_update(to_bgp
, from_bgp
, bpi
);
1807 static struct bgp
*bgp_lookup_by_rd(struct bgp_path_info
*bpi
,
1808 struct prefix_rd
*rd
, afi_t afi
)
1810 struct listnode
*node
, *nnode
;
1816 /* If ACCEPT_OWN is not enabled for this path - return. */
1817 if (!CHECK_FLAG(bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1820 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
1821 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1824 if (!CHECK_FLAG(bgp
->vpn_policy
[afi
].flags
,
1825 BGP_VPN_POLICY_TOVPN_RD_SET
))
1828 /* Check if we have source VRF by RD value */
1829 if (memcmp(&bgp
->vpn_policy
[afi
].tovpn_rd
.val
, rd
->val
,
1830 ECOMMUNITY_SIZE
) == 0)
1837 static bool vpn_leak_to_vrf_update_onevrf(struct bgp
*to_bgp
, /* to */
1838 struct bgp
*from_bgp
, /* from */
1839 struct bgp_path_info
*path_vpn
,
1840 struct prefix_rd
*prd
)
1842 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1843 afi_t afi
= family2afi(p
->family
);
1845 struct attr static_attr
= {0};
1846 struct attr
*new_attr
= NULL
;
1847 struct bgp_dest
*bn
;
1848 safi_t safi
= SAFI_UNICAST
;
1849 const char *debugmsg
;
1850 struct prefix nexthop_orig
;
1851 mpls_label_t
*pLabels
= NULL
;
1852 uint32_t num_labels
= 0;
1853 int nexthop_self_flag
= 1;
1854 struct bgp_path_info
*bpi_ultimate
= NULL
;
1855 int origin_local
= 0;
1856 struct bgp
*src_vrf
;
1857 struct interface
*ifp
;
1858 char rd_buf
[RD_ADDRSTRLEN
];
1859 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1861 if (!vpn_leak_from_vpn_active(to_bgp
, afi
, &debugmsg
)) {
1864 "%s: from vpn (%s) to vrf (%s), skipping: %s",
1865 __func__
, from_bgp
->name_pretty
,
1866 to_bgp
->name_pretty
, debugmsg
);
1871 * For VRF-2-VRF route-leaking,
1872 * the source will be the originating VRF.
1874 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
1875 * get the source VRF (BGP) by looking at the RD.
1877 struct bgp
*src_bgp
= bgp_lookup_by_rd(path_vpn
, prd
, afi
);
1879 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1880 src_vrf
= path_vpn
->extra
->bgp_orig
;
1886 /* Check for intersection of route targets */
1887 if (!ecommunity_include(
1888 to_bgp
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1889 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1892 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
1893 from_bgp
->name_pretty
, to_bgp
->name_pretty
);
1899 prefix_rd2str(prd
, rd_buf
, sizeof(rd_buf
), to_bgp
->asnotation
);
1901 /* A route MUST NOT ever be accepted back into its source VRF, even if
1902 * it carries one or more RTs that match that VRF.
1904 if (CHECK_FLAG(path_vpn
->flags
, BGP_PATH_ACCEPT_OWN
) && prd
&&
1905 memcmp(&prd
->val
, &to_bgp
->vpn_policy
[afi
].tovpn_rd
.val
,
1906 ECOMMUNITY_SIZE
) == 0) {
1909 "%s: skipping import, match RD (%s) of src VRF (%s) and the prefix (%pFX)",
1910 __func__
, rd_buf
, to_bgp
->name_pretty
, p
);
1915 zlog_debug("%s: updating RD %s, %pFX to %s", __func__
, rd_buf
,
1916 p
, to_bgp
->name_pretty
);
1919 static_attr
= *path_vpn
->attr
;
1921 struct ecommunity
*old_ecom
;
1922 struct ecommunity
*new_ecom
;
1924 /* If doing VRF-to-VRF leaking, strip RTs. */
1925 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1926 if (old_ecom
&& CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1927 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1928 new_ecom
= ecommunity_dup(old_ecom
);
1929 ecommunity_strip_rts(new_ecom
);
1930 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1932 if (new_ecom
->size
== 0) {
1933 ecommunity_free(&new_ecom
);
1934 bgp_attr_set_ecommunity(&static_attr
, NULL
);
1937 if (!old_ecom
->refcnt
)
1938 ecommunity_free(&old_ecom
);
1941 community_strip_accept_own(&static_attr
);
1944 * Nexthop: stash and clear
1946 * Nexthop is valid in context of VPN core, but not in destination vrf.
1947 * Stash it for later label resolution by vrf ingress path and then
1948 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1950 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1952 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1953 nexthop_orig
.family
= nhfamily
;
1955 /* If the path has accept-own community and the source VRF
1956 * is valid, reset next-hop to self, to allow importing own
1957 * routes between different VRFs on the same node.
1958 * Set the nh ifindex to VRF's interface, not the real interface.
1959 * Let the kernel to decide with double lookup the real next-hop
1960 * interface when installing the route.
1963 subgroup_announce_reset_nhop(nhfamily
, &static_attr
);
1964 ifp
= if_get_vrf_loopback(src_vrf
->vrf_id
);
1966 static_attr
.nh_ifindex
= ifp
->ifindex
;
1972 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1973 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
1975 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1976 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1977 static_attr
.nexthop
.s_addr
=
1978 nexthop_orig
.u
.prefix4
.s_addr
;
1980 static_attr
.mp_nexthop_global_in
=
1981 path_vpn
->attr
->mp_nexthop_global_in
;
1982 static_attr
.mp_nexthop_len
=
1983 path_vpn
->attr
->mp_nexthop_len
;
1985 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1989 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1990 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
1992 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1993 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1994 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
2000 * route map handling
2002 if (to_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
2003 struct bgp_path_info info
;
2004 route_map_result_t ret
;
2006 memset(&info
, 0, sizeof(info
));
2007 info
.peer
= to_bgp
->peer_self
;
2008 info
.attr
= &static_attr
;
2009 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
2010 ret
= route_map_apply(to_bgp
->vpn_policy
[afi
]
2011 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
2013 if (RMAP_DENYMATCH
== ret
) {
2014 bgp_attr_flush(&static_attr
); /* free any added parts */
2017 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
2018 __func__
, to_bgp
->name_pretty
,
2019 to_bgp
->vpn_policy
[afi
]
2020 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
2025 * if route-map changed nexthop, don't nexthop-self on output
2027 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
2028 BATTR_RMAP_NEXTHOP_UNCHANGED
))
2029 nexthop_self_flag
= 0;
2032 new_attr
= bgp_attr_intern(&static_attr
);
2033 bgp_attr_flush(&static_attr
);
2035 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2038 * ensure labels are copied
2040 * However, there is a special case: if the route originated in
2041 * another local VRF (as opposed to arriving via VPN), then the
2042 * nexthop is reached by hairpinning through this router (me)
2043 * using IP forwarding only (no LSP). Therefore, the route
2044 * imported to the VRF should not have labels attached. Note
2045 * that nexthop tracking is also involved: eliminating the
2046 * labels for these routes enables the non-labeled nexthops
2047 * from the originating VRF to be considered valid for this route.
2049 if (!CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2050 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2051 /* work back to original route */
2052 bpi_ultimate
= bgp_get_imported_bpi_ultimate(path_vpn
);
2055 * if original route was unicast,
2056 * then it did not arrive over vpn
2058 if (bpi_ultimate
->net
) {
2059 struct bgp_table
*table
;
2061 table
= bgp_dest_table(bpi_ultimate
->net
);
2062 if (table
&& (table
->safi
== SAFI_UNICAST
))
2067 if (!origin_local
&& path_vpn
->extra
2068 && path_vpn
->extra
->num_labels
) {
2069 num_labels
= path_vpn
->extra
->num_labels
;
2070 if (num_labels
> BGP_MAX_LABELS
)
2071 num_labels
= BGP_MAX_LABELS
;
2072 pLabels
= path_vpn
->extra
->label
;
2077 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
2078 path_vpn
->net
, num_labels
);
2080 if (!leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
2081 num_labels
, src_vrf
, &nexthop_orig
, nexthop_self_flag
,
2083 bgp_dest_unlock_node(bn
);
2088 bool vpn_leak_to_vrf_update(struct bgp
*from_bgp
,
2089 struct bgp_path_info
*path_vpn
,
2090 struct prefix_rd
*prd
)
2092 struct listnode
*mnode
, *mnnode
;
2094 bool leak_success
= false;
2096 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2099 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2101 /* Loop over VRFs */
2102 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2104 if (!path_vpn
->extra
2105 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
2106 leak_success
|= vpn_leak_to_vrf_update_onevrf(
2107 bgp
, from_bgp
, path_vpn
, prd
);
2110 return leak_success
;
2113 void vpn_leak_to_vrf_withdraw(struct bgp_path_info
*path_vpn
)
2115 const struct prefix
*p
;
2117 safi_t safi
= SAFI_UNICAST
;
2119 struct listnode
*mnode
, *mnnode
;
2120 struct bgp_dest
*bn
;
2121 struct bgp_path_info
*bpi
;
2122 const char *debugmsg
;
2124 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2127 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
2128 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
2131 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2133 if (!path_vpn
->net
) {
2134 #ifdef ENABLE_BGP_VNC
2135 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2136 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
2137 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
2144 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
2149 p
= bgp_dest_get_prefix(path_vpn
->net
);
2150 afi
= family2afi(p
->family
);
2152 /* Loop over VRFs */
2153 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2154 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
2156 zlog_debug("%s: from %s, skipping: %s",
2157 __func__
, bgp
->name_pretty
,
2162 /* Check for intersection of route targets */
2163 if (!ecommunity_include(
2164 bgp
->vpn_policy
[afi
]
2165 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
2166 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
2172 zlog_debug("%s: withdrawing from vrf %s", __func__
,
2175 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2177 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2180 && (struct bgp_path_info
*)bpi
->extra
->parent
2188 zlog_debug("%s: deleting bpi %p", __func__
,
2190 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
2191 bgp_path_info_delete(bn
, bpi
);
2192 bgp_process(bgp
, bn
, afi
, safi
);
2194 bgp_dest_unlock_node(bn
);
2198 void vpn_leak_to_vrf_withdraw_all(struct bgp
*to_bgp
, afi_t afi
)
2200 struct bgp_dest
*bn
;
2201 struct bgp_path_info
*bpi
;
2202 safi_t safi
= SAFI_UNICAST
;
2203 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2206 zlog_debug("%s: entry", __func__
);
2208 * Walk vrf table, delete bpi with bgp_orig in a different vrf
2210 for (bn
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); bn
;
2211 bn
= bgp_route_next(bn
)) {
2213 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2215 if (bpi
->extra
&& bpi
->extra
->bgp_orig
!= to_bgp
&&
2216 bpi
->extra
->parent
&&
2217 is_pi_family_vpn(bpi
->extra
->parent
)) {
2220 bgp_aggregate_decrement(to_bgp
,
2221 bgp_dest_get_prefix(bn
),
2223 bgp_path_info_delete(bn
, bpi
);
2224 bgp_process(to_bgp
, bn
, afi
, safi
);
2230 void vpn_leak_to_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*vpn_from
,
2233 struct bgp_dest
*pdest
;
2234 safi_t safi
= SAFI_MPLS_VPN
;
2241 for (pdest
= bgp_table_top(vpn_from
->rib
[afi
][safi
]); pdest
;
2242 pdest
= bgp_route_next(pdest
)) {
2243 struct bgp_table
*table
;
2244 struct bgp_dest
*bn
;
2245 struct bgp_path_info
*bpi
;
2247 /* This is the per-RD table of prefixes */
2248 table
= bgp_dest_get_bgp_table_info(pdest
);
2253 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
2255 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2259 bpi
->extra
->bgp_orig
== to_bgp
)
2262 vpn_leak_to_vrf_update_onevrf(to_bgp
, vpn_from
,
2270 * This function is called for definition/deletion/change to a route-map
2272 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
2274 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2276 struct route_map
*rmap
;
2278 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2279 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2284 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
2286 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2288 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
2289 && !strcmp(rmap_name
,
2290 bgp
->vpn_policy
[afi
]
2291 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
2295 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2296 __func__
, rmap_name
, bgp
->as
,
2299 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2300 bgp_get_default(), bgp
);
2302 zlog_debug("%s: after vpn_leak_prechange",
2305 /* in case of definition/deletion */
2306 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
2309 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2310 bgp_get_default(), bgp
);
2313 zlog_debug("%s: after vpn_leak_postchange",
2317 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
2318 && !strcmp(rmap_name
,
2319 bgp
->vpn_policy
[afi
]
2320 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
2323 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
2324 __func__
, rmap_name
, bgp
->as
,
2328 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2329 bgp_get_default(), bgp
);
2331 /* in case of definition/deletion */
2332 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
2335 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2336 bgp_get_default(), bgp
);
2341 /* This API is used during router-id change, reflect VPNs
2342 * auto RD and RT values and readvertise routes to VPN table.
2344 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
2348 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
2349 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2351 const char *export_name
;
2352 char buf
[RD_ADDRSTRLEN
];
2353 struct bgp
*bgp_import
;
2354 struct listnode
*node
;
2355 struct ecommunity
*ecom
;
2356 enum vpn_policy_direction idir
, edir
;
2359 * Router-id change that is not explicitly configured
2360 * (a change from zebra, frr restart for example)
2361 * should not replace a configured vpn RD/RT.
2365 zlog_debug("%s: skipping non explicit router-id change",
2370 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2371 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2374 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
2375 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2376 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2378 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2379 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
2383 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
2384 afi
, bgp_get_default(), bgp
);
2386 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2387 __func__
, export_name
);
2389 /* Remove import RT from VRFs */
2390 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2391 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2392 export_vrf
, node
, vname
)) {
2393 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2394 bgp_import
= bgp_get_default();
2396 bgp_import
= bgp_lookup_by_name(vname
);
2401 bgp_import
->vpn_policy
[afi
]
2403 (struct ecommunity_val
*)ecom
->val
);
2406 /* New router-id derive auto RD and RT and export
2409 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
2410 &bgp
->vrf_prd_auto
);
2411 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
2412 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2413 sizeof(buf
), bgp
->asnotation
);
2415 /* free up pre-existing memory if any and allocate
2416 * the ecommunity attribute with new RD/RT
2418 if (bgp
->vpn_policy
[afi
].rtlist
[edir
])
2420 &bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2421 bgp
->vpn_policy
[afi
].rtlist
[edir
] = ecommunity_str2com(
2422 buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2424 /* Update import_vrf rt_list */
2425 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2426 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2427 export_vrf
, node
, vname
)) {
2428 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2429 bgp_import
= bgp_get_default();
2431 bgp_import
= bgp_lookup_by_name(vname
);
2434 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
2435 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2437 bgp_import
->vpn_policy
[afi
]
2438 .rtlist
[idir
], ecom
);
2440 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2441 = ecommunity_dup(ecom
);
2444 /* Update routes to VPN */
2445 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
2446 afi
, bgp_get_default(),
2449 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2450 __func__
, export_name
);
2455 void vpn_policy_routemap_event(const char *rmap_name
)
2457 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2458 struct listnode
*mnode
, *mnnode
;
2462 zlog_debug("%s: entry", __func__
);
2464 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2467 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2468 vpn_policy_routemap_update(bgp
, rmap_name
);
2471 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2472 afi_t afi
, safi_t safi
)
2474 const char *export_name
;
2475 enum vpn_policy_direction idir
, edir
;
2476 char *vname
, *tmp_name
;
2477 char buf
[RD_ADDRSTRLEN
];
2478 struct ecommunity
*ecom
;
2479 bool first_export
= false;
2481 struct listnode
*node
;
2482 bool is_inst_match
= false;
2484 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2485 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2486 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2488 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2489 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2492 * Cross-ref both VRFs. Also, note if this is the first time
2493 * any VRF is importing from "import_vrf".
2495 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2496 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2498 /* Check the import_vrf list of destination vrf for the source vrf name,
2501 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2503 if (strcmp(vname
, tmp_name
) == 0) {
2504 is_inst_match
= true;
2509 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2512 XFREE(MTYPE_TMP
, vname
);
2514 /* Check if the source vrf already exports to any vrf,
2515 * first time export requires to setup auto derived RD/RT values.
2516 * Add the destination vrf name to export vrf list if it is
2519 is_inst_match
= false;
2520 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2521 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2522 first_export
= true;
2524 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2526 if (strcmp(vname
, tmp_name
) == 0) {
2527 is_inst_match
= true;
2533 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2536 XFREE(MTYPE_TMP
, vname
);
2538 /* Update import RT for current VRF using export RT of the VRF we're
2539 * importing from. First though, make sure "import_vrf" has that
2543 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2544 &from_bgp
->vrf_prd_auto
);
2545 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2546 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2547 BGP_VPN_POLICY_TOVPN_RD_SET
);
2548 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2549 sizeof(buf
), from_bgp
->asnotation
);
2550 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2551 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2552 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2553 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2554 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2555 BGP_PREVENT_VRF_2_VRF_LEAK
;
2557 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2558 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2559 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2560 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2561 .rtlist
[idir
], ecom
);
2563 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2564 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2567 const char *from_name
;
2568 char *ecom1
, *ecom2
;
2570 from_name
= from_bgp
->name
? from_bgp
->name
:
2573 ecom1
= ecommunity_ecom2str(
2574 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2575 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2577 ecom2
= ecommunity_ecom2str(
2578 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2579 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2582 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2583 __func__
, from_name
, export_name
, first_export
, ecom1
,
2586 ecommunity_strfree(&ecom1
);
2587 ecommunity_strfree(&ecom2
);
2590 /* Does "import_vrf" first need to export its routes or that
2591 * is already done and we just need to import those routes
2592 * from the global table?
2595 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2597 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2600 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2601 afi_t afi
, safi_t safi
)
2603 const char *export_name
, *tmp_name
;
2604 enum vpn_policy_direction idir
, edir
;
2606 struct ecommunity
*ecom
= NULL
;
2607 struct listnode
*node
;
2610 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2611 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2612 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2613 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2615 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2616 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2618 /* Were we importing from "import_vrf"? */
2619 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2621 if (strcmp(vname
, tmp_name
) == 0)
2626 * We do not check in the cli if the passed in bgp
2627 * instance is actually imported into us before
2628 * we call this function. As such if we do not
2629 * find this in the import_vrf list than
2630 * we just need to return safely.
2636 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2638 /* Remove "import_vrf" from our import list. */
2639 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2640 XFREE(MTYPE_TMP
, vname
);
2642 /* Remove routes imported from "import_vrf". */
2643 /* TODO: In the current logic, we have to first remove all
2644 * imported routes and then (if needed) import back routes
2646 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2648 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2649 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2650 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2651 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2652 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2653 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2655 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2657 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2658 (struct ecommunity_val
*)ecom
->val
);
2659 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2664 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2665 * below is checking for NULL that export_vrf can be
2666 * NULL, consequently it is complaining( like a cabbage )
2667 * that we could dereference and crash in the listcount(..)
2669 * So make it happy, under protest, with liberty and justice
2672 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2674 /* Remove us from "import_vrf's" export list. If no other VRF
2675 * is importing from "import_vrf", cleanup appropriately.
2677 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2679 if (strcmp(vname
, export_name
) == 0)
2684 * If we have gotten to this point then the vname must
2685 * exist. If not, we are in a world of trouble and
2686 * have slag sitting around.
2688 * import_vrf and export_vrf must match in having
2689 * the in/out names as appropriate.
2690 * export_vrf list could have been cleaned up
2691 * as part of no router bgp source instnace.
2696 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2697 XFREE(MTYPE_TMP
, vname
);
2699 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2700 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2701 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2702 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2703 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2704 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2705 sizeof(struct prefix_rd
));
2706 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2707 BGP_VPN_POLICY_TOVPN_RD_SET
);
2708 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2713 /* For testing purpose, static route of MPLS-VPN. */
2714 DEFUN (vpnv4_network
,
2716 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2717 "Specify a network to announce via BGP\n"
2719 "Specify Route Distinguisher\n"
2720 "VPN Route Distinguisher\n"
2721 "VPN NLRI label (tag)\n"
2722 "VPN NLRI label (tag)\n"
2725 int idx_ipv4_prefixlen
= 1;
2726 int idx_ext_community
= 3;
2728 return bgp_static_set_safi(
2729 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2730 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
2731 NULL
, NULL
, NULL
, NULL
);
2734 DEFUN (vpnv4_network_route_map
,
2735 vpnv4_network_route_map_cmd
,
2736 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
2737 "Specify a network to announce via BGP\n"
2739 "Specify Route Distinguisher\n"
2740 "VPN Route Distinguisher\n"
2741 "VPN NLRI label (tag)\n"
2742 "VPN NLRI label (tag)\n"
2747 int idx_ipv4_prefixlen
= 1;
2748 int idx_ext_community
= 3;
2751 return bgp_static_set_safi(
2752 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2753 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2754 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2757 /* For testing purpose, static route of MPLS-VPN. */
2758 DEFUN (no_vpnv4_network
,
2759 no_vpnv4_network_cmd
,
2760 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2762 "Specify a network to announce via BGP\n"
2764 "Specify Route Distinguisher\n"
2765 "VPN Route Distinguisher\n"
2766 "VPN NLRI label (tag)\n"
2767 "VPN NLRI label (tag)\n"
2770 int idx_ipv4_prefixlen
= 2;
2771 int idx_ext_community
= 4;
2773 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
2774 argv
[idx_ipv4_prefixlen
]->arg
,
2775 argv
[idx_ext_community
]->arg
,
2776 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2779 DEFUN (vpnv6_network
,
2781 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
2782 "Specify a network to announce via BGP\n"
2783 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2784 "Specify Route Distinguisher\n"
2785 "VPN Route Distinguisher\n"
2786 "VPN NLRI label (tag)\n"
2787 "VPN NLRI label (tag)\n"
2792 int idx_ipv6_prefix
= 1;
2793 int idx_ext_community
= 3;
2797 return bgp_static_set_safi(
2798 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2799 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2800 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2802 return bgp_static_set_safi(
2803 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2804 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2805 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2808 /* For testing purpose, static route of MPLS-VPN. */
2809 DEFUN (no_vpnv6_network
,
2810 no_vpnv6_network_cmd
,
2811 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2813 "Specify a network to announce via BGP\n"
2814 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2815 "Specify Route Distinguisher\n"
2816 "VPN Route Distinguisher\n"
2817 "VPN NLRI label (tag)\n"
2818 "VPN NLRI label (tag)\n"
2821 int idx_ipv6_prefix
= 2;
2822 int idx_ext_community
= 4;
2824 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2825 argv
[idx_ipv6_prefix
]->arg
,
2826 argv
[idx_ext_community
]->arg
,
2827 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2830 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2831 enum bgp_show_type type
, void *output_arg
, int tags
,
2835 struct bgp_table
*table
;
2836 uint16_t show_flags
= 0;
2839 SET_FLAG(show_flags
, BGP_SHOW_OPT_JSON
);
2841 bgp
= bgp_get_default();
2844 vty_out(vty
, "No BGP process is configured\n");
2846 vty_out(vty
, "{}\n");
2849 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2850 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2851 output_arg
, show_flags
);
2854 DEFUN (show_bgp_ip_vpn_all_rd
,
2855 show_bgp_ip_vpn_all_rd_cmd
,
2856 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2860 "Display VPN NLRI specific information\n"
2861 "Display VPN NLRI specific information\n"
2862 "Display information for a route distinguisher\n"
2863 "VPN Route Distinguisher\n"
2864 "All VPN Route Distinguishers\n"
2868 struct prefix_rd prd
;
2872 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2873 /* Constrain search if user supplies RD && RD != "all" */
2874 if (argv_find(argv
, argc
, "rd", &idx
)
2875 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
2876 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2879 "%% Malformed Route Distinguisher\n");
2882 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2883 bgp_show_type_normal
, NULL
, 0,
2884 use_json(argc
, argv
));
2886 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2887 bgp_show_type_normal
, NULL
, 0,
2888 use_json(argc
, argv
));
2894 ALIAS(show_bgp_ip_vpn_all_rd
,
2895 show_bgp_ip_vpn_rd_cmd
,
2896 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2900 "Display VPN NLRI specific information\n"
2901 "Display information for a route distinguisher\n"
2902 "VPN Route Distinguisher\n"
2903 "All VPN Route Distinguishers\n"
2906 #ifdef KEEP_OLD_VPN_COMMANDS
2907 DEFUN (show_ip_bgp_vpn_rd
,
2908 show_ip_bgp_vpn_rd_cmd
,
2909 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2915 "Display information for a route distinguisher\n"
2916 "VPN Route Distinguisher\n"
2917 "All VPN Route Distinguishers\n")
2919 int idx_ext_community
= argc
- 1;
2921 struct prefix_rd prd
;
2925 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2926 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2927 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2928 bgp_show_type_normal
, NULL
, 0,
2930 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2932 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2935 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2941 DEFUN (show_ip_bgp_vpn_all
,
2942 show_ip_bgp_vpn_all_cmd
,
2943 "show [ip] bgp <vpnv4|vpnv6>",
2952 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2953 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2958 DEFUN (show_ip_bgp_vpn_all_tags
,
2959 show_ip_bgp_vpn_all_tags_cmd
,
2960 "show [ip] bgp <vpnv4|vpnv6> all tags",
2965 "Display information about all VPNv4/VPNV6 NLRIs\n"
2966 "Display BGP tags for prefixes\n")
2971 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2972 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2977 DEFUN (show_ip_bgp_vpn_rd_tags
,
2978 show_ip_bgp_vpn_rd_tags_cmd
,
2979 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2984 "Display information for a route distinguisher\n"
2985 "VPN Route Distinguisher\n"
2986 "All VPN Route Distinguishers\n"
2987 "Display BGP tags for prefixes\n")
2989 int idx_ext_community
= 5;
2991 struct prefix_rd prd
;
2995 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2996 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2997 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2998 bgp_show_type_normal
, NULL
, 1,
3000 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3002 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3005 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
3011 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
3012 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
3013 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
3018 "Display information about all VPNv4/VPNv6 NLRIs\n"
3019 "Detailed information on TCP and BGP neighbor connections\n"
3020 "Neighbor to display information about\n"
3021 "Display routes learned from neighbor\n"
3028 bool uj
= use_json(argc
, argv
);
3032 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3033 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3036 json_object
*json_no
= NULL
;
3037 json_no
= json_object_new_object();
3038 json_object_string_add(json_no
, "warning",
3039 "Malformed address");
3040 vty_out(vty
, "%s\n",
3041 json_object_to_json_string(json_no
));
3042 json_object_free(json_no
);
3044 vty_out(vty
, "Malformed address: %s\n",
3045 argv
[idx_ipv4
]->arg
);
3049 peer
= peer_lookup(NULL
, &su
);
3050 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3052 json_object
*json_no
= NULL
;
3053 json_no
= json_object_new_object();
3054 json_object_string_add(
3056 "No such neighbor or address family");
3057 vty_out(vty
, "%s\n",
3058 json_object_to_json_string(json_no
));
3059 json_object_free(json_no
);
3062 "%% No such neighbor or address family\n");
3066 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
3072 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
3073 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
3074 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
3079 "Display information for a route distinguisher\n"
3080 "VPN Route Distinguisher\n"
3081 "All VPN Route Distinguishers\n"
3082 "Detailed information on TCP and BGP neighbor connections\n"
3083 "Neighbor to display information about\n"
3084 "Display routes learned from neighbor\n"
3087 int idx_ext_community
= 5;
3092 struct prefix_rd prd
;
3093 bool prefix_rd_all
= false;
3094 bool uj
= use_json(argc
, argv
);
3098 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3099 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3100 prefix_rd_all
= true;
3102 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3105 json_object
*json_no
= NULL
;
3106 json_no
= json_object_new_object();
3107 json_object_string_add(
3109 "Malformed Route Distinguisher");
3110 vty_out(vty
, "%s\n",
3111 json_object_to_json_string(
3113 json_object_free(json_no
);
3116 "%% Malformed Route Distinguisher\n");
3121 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3124 json_object
*json_no
= NULL
;
3125 json_no
= json_object_new_object();
3126 json_object_string_add(json_no
, "warning",
3127 "Malformed address");
3128 vty_out(vty
, "%s\n",
3129 json_object_to_json_string(json_no
));
3130 json_object_free(json_no
);
3132 vty_out(vty
, "Malformed address: %s\n",
3133 argv
[idx_ext_community
]->arg
);
3137 peer
= peer_lookup(NULL
, &su
);
3138 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3140 json_object
*json_no
= NULL
;
3141 json_no
= json_object_new_object();
3142 json_object_string_add(
3144 "No such neighbor or address family");
3145 vty_out(vty
, "%s\n",
3146 json_object_to_json_string(json_no
));
3147 json_object_free(json_no
);
3150 "%% No such neighbor or address family\n");
3155 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3156 bgp_show_type_neighbor
, &su
, 0,
3159 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
3160 bgp_show_type_neighbor
, &su
, 0,
3166 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
3167 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
3168 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
3173 "Display information about all VPNv4/VPNv6 NLRIs\n"
3174 "Detailed information on TCP and BGP neighbor connections\n"
3175 "Neighbor to display information about\n"
3176 "Display the routes advertised to a BGP neighbor\n"
3183 bool uj
= use_json(argc
, argv
);
3187 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3188 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3191 json_object
*json_no
= NULL
;
3192 json_no
= json_object_new_object();
3193 json_object_string_add(json_no
, "warning",
3194 "Malformed address");
3195 vty_out(vty
, "%s\n",
3196 json_object_to_json_string(json_no
));
3197 json_object_free(json_no
);
3199 vty_out(vty
, "Malformed address: %s\n",
3200 argv
[idx_ipv4
]->arg
);
3203 peer
= peer_lookup(NULL
, &su
);
3204 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3206 json_object
*json_no
= NULL
;
3207 json_no
= json_object_new_object();
3208 json_object_string_add(
3210 "No such neighbor or address family");
3211 vty_out(vty
, "%s\n",
3212 json_object_to_json_string(json_no
));
3213 json_object_free(json_no
);
3216 "%% No such neighbor or address family\n");
3219 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3225 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
3226 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
3227 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
3232 "Display information for a route distinguisher\n"
3233 "VPN Route Distinguisher\n"
3234 "All VPN Route Distinguishers\n"
3235 "Detailed information on TCP and BGP neighbor connections\n"
3236 "Neighbor to display information about\n"
3237 "Display the routes advertised to a BGP neighbor\n"
3240 int idx_ext_community
= 5;
3244 struct prefix_rd prd
;
3246 bool uj
= use_json(argc
, argv
);
3250 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3251 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3254 json_object
*json_no
= NULL
;
3255 json_no
= json_object_new_object();
3256 json_object_string_add(json_no
, "warning",
3257 "Malformed address");
3258 vty_out(vty
, "%s\n",
3259 json_object_to_json_string(json_no
));
3260 json_object_free(json_no
);
3262 vty_out(vty
, "Malformed address: %s\n",
3263 argv
[idx_ext_community
]->arg
);
3266 peer
= peer_lookup(NULL
, &su
);
3267 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3269 json_object
*json_no
= NULL
;
3270 json_no
= json_object_new_object();
3271 json_object_string_add(
3273 "No such neighbor or address family");
3274 vty_out(vty
, "%s\n",
3275 json_object_to_json_string(json_no
));
3276 json_object_free(json_no
);
3279 "%% No such neighbor or address family\n");
3283 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3284 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3286 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3289 json_object
*json_no
= NULL
;
3290 json_no
= json_object_new_object();
3291 json_object_string_add(
3293 "Malformed Route Distinguisher");
3294 vty_out(vty
, "%s\n",
3295 json_object_to_json_string(json_no
));
3296 json_object_free(json_no
);
3299 "%% Malformed Route Distinguisher\n");
3303 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
3308 #endif /* KEEP_OLD_VPN_COMMANDS */
3310 void bgp_mplsvpn_init(void)
3312 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
3313 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
3314 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
3316 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
3317 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
3319 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
3320 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
3321 #ifdef KEEP_OLD_VPN_COMMANDS
3322 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
3323 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
3324 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
3325 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
3326 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
3327 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
3328 install_element(VIEW_NODE
,
3329 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
3330 install_element(VIEW_NODE
,
3331 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
3332 #endif /* KEEP_OLD_VPN_COMMANDS */
3335 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
3337 struct listnode
*mnode
, *mnnode
;
3341 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
3344 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
3345 struct ecommunity
*ec
;
3347 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3350 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
3352 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
3355 if (ecommunity_include(ec
, eckey
))
3362 * The purpose of this function is to process leaks that were deferred
3363 * from earlier per-vrf configuration due to not-yet-existing default
3364 * vrf, in other words, configuration such as:
3366 * router bgp MMM vrf FOO
3367 * address-family ipv4 unicast
3369 * exit-address-family
3374 * This function gets called when the default instance ("router bgp NNN")
3377 void vpn_leak_postchange_all(void)
3379 struct listnode
*next
;
3381 struct bgp
*bgp_default
= bgp_get_default();
3383 assert(bgp_default
);
3385 /* First, do any exporting from VRFs to the single VPN RIB */
3386 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3388 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3391 vpn_leak_postchange(
3392 BGP_VPN_POLICY_DIR_TOVPN
,
3397 vpn_leak_postchange(
3398 BGP_VPN_POLICY_DIR_TOVPN
,
3404 /* Now, do any importing to VRFs from the single VPN RIB */
3405 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3407 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3410 vpn_leak_postchange(
3411 BGP_VPN_POLICY_DIR_FROMVPN
,
3416 vpn_leak_postchange(
3417 BGP_VPN_POLICY_DIR_FROMVPN
,
3424 /* When a bgp vrf instance is unconfigured, remove its routes
3425 * from the VPN table and this vrf could be importing routes from other
3426 * bgp vrf instnaces, unimport them.
3427 * VRF X and VRF Y are exporting routes to each other.
3428 * When VRF X is deleted, unimport its routes from all target vrfs,
3429 * also VRF Y should unimport its routes from VRF X table.
3430 * This will ensure VPN table is cleaned up appropriately.
3432 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
3435 const char *tmp_name
;
3437 struct listnode
*node
, *next
;
3438 safi_t safi
= SAFI_UNICAST
;
3440 bool is_vrf_leak_bind
;
3443 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3446 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3447 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3449 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3451 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3452 /* vrf leak is for IPv4 and IPv6 Unicast only */
3453 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3456 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3457 if (from_bgp
== to_bgp
)
3460 /* Unimport and remove source vrf from the
3461 * other vrfs import list.
3463 struct vpn_policy
*to_vpolicy
;
3465 is_vrf_leak_bind
= false;
3466 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3467 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
3469 if (strcmp(vname
, tmp_name
) == 0) {
3470 is_vrf_leak_bind
= true;
3474 /* skip this bgp instance as there is no leak to this
3477 if (!is_vrf_leak_bind
)
3481 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3482 __func__
, from_bgp
->name_pretty
,
3483 to_bgp
->name_pretty
, afi2str(afi
),
3484 to_vpolicy
->import_vrf
->count
);
3486 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
3488 /* readd vrf name as unimport removes import vrf name
3489 * from the destination vrf's import list where the
3490 * `import vrf` configuration still exist.
3492 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
3493 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
3495 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
3496 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
3498 /* If to_bgp exports its routes to the bgp vrf
3499 * which is being deleted, un-import the
3500 * to_bgp routes from VPN.
3502 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3505 if (strcmp(vname
, tmp_name
) == 0) {
3506 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3516 /* When a router bgp is configured, there could be a bgp vrf
3517 * instance importing routes from this newly configured
3518 * bgp vrf instance. Export routes from configured
3520 * VRF Y has import from bgp vrf x,
3521 * when a bgp vrf x instance is created, export its routes
3522 * to VRF Y instance.
3524 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3527 const char *export_name
;
3529 struct listnode
*node
, *next
;
3530 struct ecommunity
*ecom
;
3531 enum vpn_policy_direction idir
, edir
;
3532 safi_t safi
= SAFI_UNICAST
;
3536 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3537 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3539 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3540 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3542 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3544 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3545 /* vrf leak is for IPv4 and IPv6 Unicast only */
3546 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3549 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3550 if (from_bgp
== to_bgp
)
3553 /* bgp instance has import list, check to see if newly
3554 * configured bgp instance is the list.
3556 struct vpn_policy
*to_vpolicy
;
3558 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3559 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3561 if (strcmp(vname
, export_name
) != 0)
3565 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3567 export_name
, to_bgp
->name_pretty
);
3569 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3570 /* remove import rt, it will be readded
3571 * as part of import from vrf.
3575 to_vpolicy
->rtlist
[idir
],
3576 (struct ecommunity_val
*)
3578 vrf_import_from_vrf(to_bgp
, from_bgp
,