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, unless MPLS allocation per nexthop is
1120 * performed. In the default case nexthop tracking does not apply,
1121 * if those routes are subsequently imported to other RIBs within
1122 * BGP, the leaked routes do not carry the original
1123 * BGP_ROUTE_REDISTRIBUTE sub_type. Therefore, in order to determine
1124 * if the route we are currently leaking should have nexthop
1125 * tracking, we must find the ultimate parent so we can check its
1128 * As of now, source_bpi may at most be a second-generation route
1129 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
1130 * Using a loop here supports more complex intra-bgp import-export
1131 * schemes that could be implemented in the future.
1138 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1139 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
1144 bool labelssame
= labels_same(bpi
, label
, num_labels
);
1146 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
1147 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
1150 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
1151 __func__
, to_bgp
->name_pretty
,
1152 source_bpi
->flags
, bpi
->flags
, p
);
1157 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
1158 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
1160 bgp_attr_unintern(&new_attr
);
1163 "%s: ->%s: %pBD: Found route, no change",
1164 __func__
, to_bgp
->name_pretty
, bn
);
1168 /* If the RT was changed via extended communities as an
1169 * import/export list, we should withdraw implicitly the old
1171 * For instance, RT list was modified using route-maps:
1172 * route-map test permit 10
1173 * set extcommunity rt none
1175 if (CHECK_FLAG(bpi
->attr
->flag
,
1176 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) &&
1177 CHECK_FLAG(new_attr
->flag
,
1178 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
1179 if (!ecommunity_cmp(
1180 bgp_attr_get_ecommunity(bpi
->attr
),
1181 bgp_attr_get_ecommunity(new_attr
))) {
1182 vpn_leak_to_vrf_withdraw(bpi
);
1183 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
,
1185 bgp_path_info_delete(bn
, bpi
);
1189 /* attr is changed */
1190 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
1192 /* Rewrite BGP route information. */
1193 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1194 bgp_path_info_restore(bn
, bpi
);
1196 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1197 bgp_attr_unintern(&bpi
->attr
);
1198 bpi
->attr
= new_attr
;
1199 bpi
->uptime
= monotime(NULL
);
1205 setlabels(bpi
, label
, num_labels
);
1211 if (new_attr
->srv6_l3vpn
) {
1212 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
1215 extra
= bgp_path_info_extra_get(bpi
);
1217 extra
->sid
[0].loc_block_len
=
1218 new_attr
->srv6_l3vpn
->loc_block_len
;
1219 extra
->sid
[0].loc_node_len
=
1220 new_attr
->srv6_l3vpn
->loc_node_len
;
1221 extra
->sid
[0].func_len
=
1222 new_attr
->srv6_l3vpn
->func_len
;
1223 extra
->sid
[0].arg_len
=
1224 new_attr
->srv6_l3vpn
->arg_len
;
1225 extra
->sid
[0].transposition_len
=
1226 new_attr
->srv6_l3vpn
->transposition_len
;
1227 extra
->sid
[0].transposition_offset
=
1228 new_attr
->srv6_l3vpn
1229 ->transposition_offset
;
1230 } else if (new_attr
->srv6_vpn
)
1231 setsids(bpi
, &new_attr
->srv6_vpn
->sid
,
1236 if (nexthop_self_flag
)
1237 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
1239 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1240 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ACCEPT_OWN
);
1242 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1243 source_bpi
, bpi
, bgp_orig
, p
,
1245 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
1247 bgp_path_info_unset_flag(bn
, bpi
, BGP_PATH_VALID
);
1249 /* Process change. */
1250 bgp_aggregate_increment(to_bgp
, p
, bpi
, afi
, safi
);
1251 bgp_process(to_bgp
, bn
, afi
, safi
);
1252 bgp_dest_unlock_node(bn
);
1255 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
1256 __func__
, to_bgp
->name_pretty
, bn
);
1261 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
1264 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
1265 __func__
, to_bgp
->name_pretty
,
1266 source_bpi
->flags
, p
);
1271 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
1272 to_bgp
->peer_self
, new_attr
, bn
);
1274 if (source_bpi
->peer
) {
1275 extra
= bgp_path_info_extra_get(new);
1276 extra
->peer_orig
= peer_lock(source_bpi
->peer
);
1279 if (nexthop_self_flag
)
1280 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
1282 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1283 bgp_path_info_set_flag(bn
, new, BGP_PATH_ACCEPT_OWN
);
1285 bgp_path_info_extra_get(new);
1291 if (new_attr
->srv6_l3vpn
) {
1292 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
1294 extra
= bgp_path_info_extra_get(new);
1296 extra
->sid
[0].loc_block_len
=
1297 new_attr
->srv6_l3vpn
->loc_block_len
;
1298 extra
->sid
[0].loc_node_len
=
1299 new_attr
->srv6_l3vpn
->loc_node_len
;
1300 extra
->sid
[0].func_len
= new_attr
->srv6_l3vpn
->func_len
;
1301 extra
->sid
[0].arg_len
= new_attr
->srv6_l3vpn
->arg_len
;
1302 extra
->sid
[0].transposition_len
=
1303 new_attr
->srv6_l3vpn
->transposition_len
;
1304 extra
->sid
[0].transposition_offset
=
1305 new_attr
->srv6_l3vpn
->transposition_offset
;
1306 } else if (new_attr
->srv6_vpn
)
1307 setsids(new, &new_attr
->srv6_vpn
->sid
, num_sids
);
1312 setlabels(new, label
, num_labels
);
1314 new->extra
->parent
= bgp_path_info_lock(parent
);
1316 (struct bgp_dest
*)parent
->net
);
1318 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
1320 new->extra
->nexthop_orig
= *nexthop_orig
;
1322 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1323 source_bpi
, new, bgp_orig
, p
, debug
))
1324 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
1326 bgp_path_info_unset_flag(bn
, new, BGP_PATH_VALID
);
1328 bgp_aggregate_increment(to_bgp
, p
, new, afi
, safi
);
1329 bgp_path_info_add(bn
, new);
1331 bgp_dest_unlock_node(bn
);
1332 bgp_process(to_bgp
, bn
, afi
, safi
);
1335 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
1336 to_bgp
->name_pretty
, bn
);
1341 void bgp_mplsvpn_path_nh_label_unlink(struct bgp_path_info
*pi
)
1343 struct bgp_label_per_nexthop_cache
*blnc
;
1348 blnc
= pi
->label_nexthop_cache
;
1353 LIST_REMOVE(pi
, label_nh_thread
);
1354 pi
->label_nexthop_cache
->path_count
--;
1355 pi
->label_nexthop_cache
= NULL
;
1357 if (LIST_EMPTY(&(blnc
->paths
)))
1358 bgp_label_per_nexthop_free(blnc
);
1361 /* Called upon reception of a ZAPI Message from zebra, about
1362 * a new available label.
1364 static int bgp_mplsvpn_get_label_per_nexthop_cb(mpls_label_t label
,
1365 void *context
, bool allocated
)
1367 struct bgp_label_per_nexthop_cache
*blnc
= context
;
1368 mpls_label_t old_label
;
1369 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
1370 struct bgp_path_info
*pi
;
1371 struct bgp_table
*table
;
1373 old_label
= blnc
->label
;
1376 zlog_debug("%s: label=%u, allocated=%d, nexthop=%pFX", __func__
,
1377 label
, allocated
, &blnc
->nexthop
);
1379 /* update the entry with the new label */
1380 blnc
->label
= label
;
1383 * previously-allocated label is now invalid
1384 * eg: zebra deallocated the labels and notifies it
1386 blnc
->label
= MPLS_INVALID_LABEL
;
1388 if (old_label
== blnc
->label
)
1389 return 0; /* no change */
1392 if (blnc
->label
!= MPLS_INVALID_LABEL
)
1393 bgp_zebra_send_nexthop_label(
1394 ZEBRA_MPLS_LABELS_ADD
, blnc
->label
, blnc
->nh
->ifindex
,
1395 blnc
->nh
->vrf_id
, ZEBRA_LSP_BGP
, &blnc
->nexthop
);
1397 LIST_FOREACH (pi
, &(blnc
->paths
), label_nh_thread
) {
1400 table
= bgp_dest_table(pi
->net
);
1403 vpn_leak_from_vrf_update(blnc
->to_bgp
, table
->bgp
, pi
);
1409 /* Get a per label nexthop value:
1410 * - Find and return a per label nexthop from the cache
1411 * - else allocate a new per label nexthop cache entry and request a
1412 * label to zebra. Return MPLS_INVALID_LABEL
1414 static mpls_label_t
_vpn_leak_from_vrf_get_per_nexthop_label(
1415 struct bgp_path_info
*pi
, struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1416 afi_t afi
, safi_t safi
)
1418 struct bgp_nexthop_cache
*bnc
= pi
->nexthop
;
1419 struct bgp_label_per_nexthop_cache
*blnc
;
1420 struct bgp_label_per_nexthop_cache_head
*tree
;
1421 struct prefix
*nh_pfx
= NULL
;
1422 struct prefix nh_gate
= {0};
1424 /* extract the nexthop from the BNC nexthop cache */
1425 switch (bnc
->nexthop
->type
) {
1426 case NEXTHOP_TYPE_IPV4
:
1427 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1428 /* the nexthop is recursive */
1429 nh_gate
.family
= AF_INET
;
1430 nh_gate
.prefixlen
= IPV4_MAX_BITLEN
;
1431 IPV4_ADDR_COPY(&nh_gate
.u
.prefix4
, &bnc
->nexthop
->gate
.ipv4
);
1434 case NEXTHOP_TYPE_IPV6
:
1435 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1436 /* the nexthop is recursive */
1437 nh_gate
.family
= AF_INET6
;
1438 nh_gate
.prefixlen
= IPV6_MAX_BITLEN
;
1439 IPV6_ADDR_COPY(&nh_gate
.u
.prefix6
, &bnc
->nexthop
->gate
.ipv6
);
1442 case NEXTHOP_TYPE_IFINDEX
:
1443 /* the nexthop is direcly connected */
1444 nh_pfx
= &bnc
->prefix
;
1446 case NEXTHOP_TYPE_BLACKHOLE
:
1447 assert(!"Blackhole nexthop. Already checked by the caller.");
1450 /* find or allocate a nexthop label cache entry */
1451 tree
= &from_bgp
->mpls_labels_per_nexthop
[family2afi(nh_pfx
->family
)];
1452 blnc
= bgp_label_per_nexthop_find(tree
, nh_pfx
);
1454 blnc
= bgp_label_per_nexthop_new(tree
, nh_pfx
);
1455 blnc
->to_bgp
= to_bgp
;
1456 /* request a label to zebra for this nexthop
1457 * the response from zebra will trigger the callback
1459 bgp_lp_get(LP_TYPE_NEXTHOP
, blnc
,
1460 bgp_mplsvpn_get_label_per_nexthop_cb
);
1463 if (pi
->label_nexthop_cache
== blnc
)
1467 /* Unlink from any existing nexthop cache. Free the entry if unused.
1469 bgp_mplsvpn_path_nh_label_unlink(pi
);
1471 /* updates NHT pi list reference */
1472 LIST_INSERT_HEAD(&(blnc
->paths
), pi
, label_nh_thread
);
1473 pi
->label_nexthop_cache
= blnc
;
1474 pi
->label_nexthop_cache
->path_count
++;
1475 blnc
->last_update
= monotime(NULL
);
1478 /* then add or update the selected nexthop */
1480 blnc
->nh
= nexthop_dup(bnc
->nexthop
, NULL
);
1481 else if (!nexthop_same(bnc
->nexthop
, blnc
->nh
)) {
1482 nexthop_free(blnc
->nh
);
1483 blnc
->nh
= nexthop_dup(bnc
->nexthop
, NULL
);
1484 if (blnc
->label
!= MPLS_INVALID_LABEL
) {
1485 bgp_zebra_send_nexthop_label(
1486 ZEBRA_MPLS_LABELS_REPLACE
, blnc
->label
,
1487 bnc
->nexthop
->ifindex
, bnc
->nexthop
->vrf_id
,
1488 ZEBRA_LSP_BGP
, &blnc
->nexthop
);
1495 /* Filter out all the cases where a per nexthop label is not possible:
1496 * - return an invalid label when the nexthop is invalid
1497 * - return the per VRF label when the per nexthop label is not supported
1498 * Otherwise, find or request a per label nexthop.
1500 static mpls_label_t
vpn_leak_from_vrf_get_per_nexthop_label(
1501 afi_t afi
, safi_t safi
, struct bgp_path_info
*pi
, struct bgp
*from_bgp
,
1504 struct bgp_path_info
*bpi_ultimate
= bgp_get_imported_bpi_ultimate(pi
);
1505 struct bgp
*bgp_nexthop
= NULL
;
1508 bool is_bgp_static_route
;
1510 is_bgp_static_route
= bpi_ultimate
->sub_type
== BGP_ROUTE_STATIC
&&
1511 bpi_ultimate
->type
== ZEBRA_ROUTE_BGP
;
1513 if (is_bgp_static_route
== false && afi
== AFI_IP
&&
1514 CHECK_FLAG(pi
->attr
->flag
, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) &&
1515 (pi
->attr
->nexthop
.s_addr
== INADDR_ANY
||
1516 !ipv4_unicast_valid(&pi
->attr
->nexthop
))) {
1517 /* IPv4 nexthop in standard BGP encoding format.
1518 * Format of address is not valid (not any, not unicast).
1519 * Fallback to the per VRF label.
1521 bgp_mplsvpn_path_nh_label_unlink(pi
);
1522 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1525 if (is_bgp_static_route
== false && afi
== AFI_IP
&&
1526 pi
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV4
&&
1527 (pi
->attr
->mp_nexthop_global_in
.s_addr
== INADDR_ANY
||
1528 !ipv4_unicast_valid(&pi
->attr
->mp_nexthop_global_in
))) {
1529 /* IPv4 nexthop is in MP-BGP encoding format.
1530 * Format of address is not valid (not any, not unicast).
1531 * Fallback to the per VRF label.
1533 bgp_mplsvpn_path_nh_label_unlink(pi
);
1534 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1537 if (is_bgp_static_route
== false && afi
== AFI_IP6
&&
1538 (pi
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
||
1539 pi
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) &&
1540 (IN6_IS_ADDR_UNSPECIFIED(&pi
->attr
->mp_nexthop_global
) ||
1541 IN6_IS_ADDR_LOOPBACK(&pi
->attr
->mp_nexthop_global
) ||
1542 IN6_IS_ADDR_MULTICAST(&pi
->attr
->mp_nexthop_global
))) {
1543 /* IPv6 nexthop is in MP-BGP encoding format.
1544 * Format of address is not valid
1545 * Fallback to the per VRF label.
1547 bgp_mplsvpn_path_nh_label_unlink(pi
);
1548 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1551 /* Check the next-hop reachability.
1552 * Get the bgp instance where the bgp_path_info originates.
1554 if (pi
->extra
&& pi
->extra
->bgp_orig
)
1555 bgp_nexthop
= pi
->extra
->bgp_orig
;
1557 bgp_nexthop
= from_bgp
;
1559 nh_afi
= BGP_ATTR_NH_AFI(afi
, pi
->attr
);
1560 nh_valid
= bgp_find_or_add_nexthop(from_bgp
, bgp_nexthop
, nh_afi
, safi
,
1563 if (!nh_valid
&& is_bgp_static_route
&&
1564 !CHECK_FLAG(from_bgp
->flags
, BGP_FLAG_IMPORT_CHECK
)) {
1565 /* "network" prefixes not routable, but since 'no bgp network
1566 * import-check' is configured, they are always valid in the BGP
1567 * table. Fallback to the per-vrf label
1569 bgp_mplsvpn_path_nh_label_unlink(pi
);
1570 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1573 if (!nh_valid
|| !pi
->nexthop
|| pi
->nexthop
->nexthop_num
== 0 ||
1574 !pi
->nexthop
->nexthop
) {
1575 /* invalid next-hop:
1576 * do not send the per-vrf label
1577 * otherwise, when the next-hop becomes valid,
1578 * we will have 2 BGP updates:
1579 * - one with the per-vrf label
1580 * - the second with the per-nexthop label
1582 bgp_mplsvpn_path_nh_label_unlink(pi
);
1583 return MPLS_INVALID_LABEL
;
1586 if (pi
->nexthop
->nexthop_num
> 1 ||
1587 pi
->nexthop
->nexthop
->type
== NEXTHOP_TYPE_BLACKHOLE
) {
1588 /* Blackhole or ECMP routes
1589 * is not compatible with per-nexthop label.
1590 * Fallback to per-vrf label.
1592 bgp_mplsvpn_path_nh_label_unlink(pi
);
1593 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1596 return _vpn_leak_from_vrf_get_per_nexthop_label(pi
, to_bgp
, from_bgp
,
1600 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1601 void vpn_leak_from_vrf_update(struct bgp
*to_bgp
, /* to */
1602 struct bgp
*from_bgp
, /* from */
1603 struct bgp_path_info
*path_vrf
) /* route */
1605 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1606 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1607 afi_t afi
= family2afi(p
->family
);
1608 struct attr static_attr
= {0};
1609 struct attr
*new_attr
= NULL
;
1610 safi_t safi
= SAFI_MPLS_VPN
;
1611 mpls_label_t label_val
;
1613 struct bgp_dest
*bn
;
1614 const char *debugmsg
;
1615 int nexthop_self_flag
= 0;
1618 zlog_debug("%s: from vrf %s", __func__
, from_bgp
->name_pretty
);
1620 if (debug
&& bgp_attr_get_ecommunity(path_vrf
->attr
)) {
1621 char *s
= ecommunity_ecom2str(
1622 bgp_attr_get_ecommunity(path_vrf
->attr
),
1623 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1625 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
1626 from_bgp
->name
, path_vrf
->type
, s
);
1627 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1635 zlog_debug("%s: can't get afi of prefix", __func__
);
1639 /* Is this route exportable into the VPN table? */
1640 if (!is_route_injectable_into_vpn(path_vrf
))
1643 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1645 zlog_debug("%s: %s skipping: %s", __func__
,
1646 from_bgp
->name
, debugmsg
);
1651 static_attr
= *path_vrf
->attr
;
1654 * route map handling
1656 if (from_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1657 struct bgp_path_info info
;
1658 route_map_result_t ret
;
1660 memset(&info
, 0, sizeof(info
));
1661 info
.peer
= to_bgp
->peer_self
;
1662 info
.attr
= &static_attr
;
1663 ret
= route_map_apply(from_bgp
->vpn_policy
[afi
]
1664 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1666 if (RMAP_DENYMATCH
== ret
) {
1667 bgp_attr_flush(&static_attr
); /* free any added parts */
1670 "%s: vrf %s route map \"%s\" says DENY, returning",
1671 __func__
, from_bgp
->name_pretty
,
1672 from_bgp
->vpn_policy
[afi
]
1673 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
1679 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1680 char *s
= ecommunity_ecom2str(
1681 bgp_attr_get_ecommunity(&static_attr
),
1682 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1684 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1686 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1690 * Add the vpn-policy rt-list
1692 struct ecommunity
*old_ecom
;
1693 struct ecommunity
*new_ecom
;
1695 /* Export with the 'from' instance's export RTs. */
1696 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1697 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1699 new_ecom
= ecommunity_dup(old_ecom
);
1700 if (CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1701 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1702 ecommunity_strip_rts(new_ecom
);
1703 new_ecom
= ecommunity_merge(
1704 new_ecom
, from_bgp
->vpn_policy
[afi
]
1705 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1706 if (!old_ecom
->refcnt
)
1707 ecommunity_free(&old_ecom
);
1709 new_ecom
= ecommunity_dup(
1710 from_bgp
->vpn_policy
[afi
]
1711 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1713 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1715 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1716 char *s
= ecommunity_ecom2str(
1717 bgp_attr_get_ecommunity(&static_attr
),
1718 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1720 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1722 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1725 community_strip_accept_own(&static_attr
);
1728 /* if policy nexthop not set, use 0 */
1729 if (CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1730 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1731 struct prefix
*nexthop
=
1732 &from_bgp
->vpn_policy
[afi
].tovpn_nexthop
;
1734 switch (nexthop
->family
) {
1736 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1738 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1740 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1741 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1745 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1746 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1753 if (!CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1754 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1755 if (afi
== AFI_IP
&&
1756 !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1758 * For ipv4, copy to multiprotocol
1761 static_attr
.mp_nexthop_global_in
=
1762 static_attr
.nexthop
;
1763 static_attr
.mp_nexthop_len
=
1764 BGP_ATTR_NHLEN_IPV4
;
1766 * XXX Leave static_attr.nexthop
1770 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1773 /* Update based on next-hop family to account for
1774 * RFC 5549 (BGP unnumbered) scenario. Note that
1775 * specific action is only needed for the case of
1776 * IPv4 nexthops as the attr has been copied
1780 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1781 static_attr
.mp_nexthop_global_in
.s_addr
=
1782 static_attr
.nexthop
.s_addr
;
1783 static_attr
.mp_nexthop_len
=
1784 BGP_ATTR_NHLEN_IPV4
;
1786 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1789 nexthop_self_flag
= 1;
1792 if (CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1793 BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP
))
1794 /* per nexthop label mode */
1795 label_val
= vpn_leak_from_vrf_get_per_nexthop_label(
1796 afi
, safi
, path_vrf
, from_bgp
, to_bgp
);
1798 /* per VRF label mode */
1799 label_val
= from_bgp
->vpn_policy
[afi
].tovpn_label
;
1801 if (label_val
== MPLS_INVALID_LABEL
&&
1802 CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1803 BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP
)) {
1804 /* no valid label for the moment
1805 * when the 'bgp_mplsvpn_get_label_per_nexthop_cb' callback gets
1806 * a valid label value, it will call the current function again.
1810 "%s: %s skipping: waiting for a valid per-label nexthop.",
1811 __func__
, from_bgp
->name_pretty
);
1814 if (label_val
== MPLS_LABEL_NONE
)
1815 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1817 encode_label(label_val
, &label
);
1819 /* Set originator ID to "me" */
1820 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1821 static_attr
.originator_id
= to_bgp
->router_id
;
1823 /* Set SID for SRv6 VPN */
1824 if (from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
) {
1825 struct srv6_locator_chunk
*locator
=
1826 from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
;
1828 from_bgp
->vpn_policy
[afi
].tovpn_sid_transpose_label
,
1830 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1831 sizeof(struct bgp_attr_srv6_l3vpn
));
1832 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1833 static_attr
.srv6_l3vpn
->endpoint_behavior
=
1835 ? (CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1836 ? SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID
1837 : SRV6_ENDPOINT_BEHAVIOR_END_DT4
)
1838 : (CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1839 ? SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID
1840 : SRV6_ENDPOINT_BEHAVIOR_END_DT6
);
1841 static_attr
.srv6_l3vpn
->loc_block_len
=
1842 from_bgp
->vpn_policy
[afi
]
1843 .tovpn_sid_locator
->block_bits_length
;
1844 static_attr
.srv6_l3vpn
->loc_node_len
=
1845 from_bgp
->vpn_policy
[afi
]
1846 .tovpn_sid_locator
->node_bits_length
;
1847 static_attr
.srv6_l3vpn
->func_len
=
1848 from_bgp
->vpn_policy
[afi
]
1849 .tovpn_sid_locator
->function_bits_length
;
1850 static_attr
.srv6_l3vpn
->arg_len
=
1851 from_bgp
->vpn_policy
[afi
]
1852 .tovpn_sid_locator
->argument_bits_length
;
1853 static_attr
.srv6_l3vpn
->transposition_len
=
1854 from_bgp
->vpn_policy
[afi
]
1855 .tovpn_sid_locator
->function_bits_length
;
1856 static_attr
.srv6_l3vpn
->transposition_offset
=
1857 from_bgp
->vpn_policy
[afi
]
1858 .tovpn_sid_locator
->block_bits_length
+
1859 from_bgp
->vpn_policy
[afi
]
1860 .tovpn_sid_locator
->node_bits_length
;
1862 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1863 &from_bgp
->vpn_policy
[afi
]
1864 .tovpn_sid_locator
->prefix
.prefix
,
1865 sizeof(struct in6_addr
));
1866 } else if (from_bgp
->tovpn_sid_locator
) {
1867 struct srv6_locator_chunk
*locator
=
1868 from_bgp
->tovpn_sid_locator
;
1869 encode_label(from_bgp
->tovpn_sid_transpose_label
, &label
);
1870 static_attr
.srv6_l3vpn
=
1871 XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1872 sizeof(struct bgp_attr_srv6_l3vpn
));
1873 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1874 static_attr
.srv6_l3vpn
->endpoint_behavior
=
1875 CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1876 ? SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID
1877 : SRV6_ENDPOINT_BEHAVIOR_END_DT46
;
1878 static_attr
.srv6_l3vpn
->loc_block_len
=
1879 from_bgp
->tovpn_sid_locator
->block_bits_length
;
1880 static_attr
.srv6_l3vpn
->loc_node_len
=
1881 from_bgp
->tovpn_sid_locator
->node_bits_length
;
1882 static_attr
.srv6_l3vpn
->func_len
=
1883 from_bgp
->tovpn_sid_locator
->function_bits_length
;
1884 static_attr
.srv6_l3vpn
->arg_len
=
1885 from_bgp
->tovpn_sid_locator
->argument_bits_length
;
1886 static_attr
.srv6_l3vpn
->transposition_len
=
1887 from_bgp
->tovpn_sid_locator
->function_bits_length
;
1888 static_attr
.srv6_l3vpn
->transposition_offset
=
1889 from_bgp
->tovpn_sid_locator
->block_bits_length
+
1890 from_bgp
->tovpn_sid_locator
->node_bits_length
;
1891 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1892 &from_bgp
->tovpn_sid_locator
->prefix
.prefix
,
1893 sizeof(struct in6_addr
));
1897 new_attr
= bgp_attr_intern(
1898 &static_attr
); /* hashed refcounted everything */
1899 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1901 if (debug
&& bgp_attr_get_ecommunity(new_attr
)) {
1902 char *s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr
),
1903 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1905 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1906 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1909 /* Now new_attr is an allocated interned attr */
1911 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1912 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1914 struct bgp_path_info
*new_info
;
1917 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vrf
, &label
,
1918 1, from_bgp
, NULL
, nexthop_self_flag
, debug
);
1921 * Routes actually installed in the vpn RIB must also be
1922 * offered to all vrfs (because now they originate from
1925 * Acceptance into other vrfs depends on rt-lists.
1926 * Originating vrf will not accept the looped back route
1927 * because of loop checking.
1930 vpn_leak_to_vrf_update(from_bgp
, new_info
, NULL
);
1932 bgp_dest_unlock_node(bn
);
1935 void vpn_leak_from_vrf_withdraw(struct bgp
*to_bgp
, /* to */
1936 struct bgp
*from_bgp
, /* from */
1937 struct bgp_path_info
*path_vrf
) /* route */
1939 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1940 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1941 afi_t afi
= family2afi(p
->family
);
1942 safi_t safi
= SAFI_MPLS_VPN
;
1943 struct bgp_path_info
*bpi
;
1944 struct bgp_dest
*bn
;
1945 const char *debugmsg
;
1949 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1950 __func__
, from_bgp
->name_pretty
, path_vrf
->net
,
1951 path_vrf
->type
, path_vrf
->sub_type
);
1959 zlog_debug("%s: can't get afi of prefix", __func__
);
1963 /* Is this route exportable into the VPN table? */
1964 if (!is_route_injectable_into_vpn(path_vrf
))
1967 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1969 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1974 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1976 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1977 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1983 * match original bpi imported from
1985 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1986 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1992 /* withdraw from looped vrfs as well */
1993 vpn_leak_to_vrf_withdraw(bpi
);
1995 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1996 bgp_path_info_delete(bn
, bpi
);
1997 bgp_process(to_bgp
, bn
, afi
, safi
);
1999 bgp_dest_unlock_node(bn
);
2002 void vpn_leak_from_vrf_withdraw_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2005 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
2006 struct bgp_dest
*pdest
;
2007 safi_t safi
= SAFI_MPLS_VPN
;
2010 * Walk vpn table, delete bpi with bgp_orig == from_bgp
2012 for (pdest
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); pdest
;
2013 pdest
= bgp_route_next(pdest
)) {
2015 struct bgp_table
*table
;
2016 struct bgp_dest
*bn
;
2017 struct bgp_path_info
*bpi
;
2019 /* This is the per-RD table of prefixes */
2020 table
= bgp_dest_get_bgp_table_info(pdest
);
2025 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
2026 bpi
= bgp_dest_get_bgp_path_info(bn
);
2028 zlog_debug("%s: looking at prefix %pBD",
2032 for (; bpi
; bpi
= bpi
->next
) {
2034 zlog_debug("%s: type %d, sub_type %d",
2035 __func__
, bpi
->type
,
2037 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
2041 if ((struct bgp
*)bpi
->extra
->bgp_orig
==
2045 zlog_debug("%s: deleting it",
2047 /* withdraw from leak-to vrfs as well */
2048 vpn_leak_to_vrf_withdraw(bpi
);
2049 bgp_aggregate_decrement(
2050 to_bgp
, bgp_dest_get_prefix(bn
),
2052 bgp_path_info_delete(bn
, bpi
);
2053 bgp_process(to_bgp
, bn
, afi
, safi
);
2054 bgp_mplsvpn_path_nh_label_unlink(
2055 bpi
->extra
->parent
);
2062 void vpn_leak_from_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2065 struct bgp_dest
*bn
;
2066 struct bgp_path_info
*bpi
;
2067 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
2070 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
2071 from_bgp
->name_pretty
);
2073 for (bn
= bgp_table_top(from_bgp
->rib
[afi
][SAFI_UNICAST
]); bn
;
2074 bn
= bgp_route_next(bn
)) {
2077 zlog_debug("%s: node=%p", __func__
, bn
);
2079 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2083 "%s: calling vpn_leak_from_vrf_update",
2085 vpn_leak_from_vrf_update(to_bgp
, from_bgp
, bpi
);
2090 static struct bgp
*bgp_lookup_by_rd(struct bgp_path_info
*bpi
,
2091 struct prefix_rd
*rd
, afi_t afi
)
2093 struct listnode
*node
, *nnode
;
2099 /* If ACCEPT_OWN is not enabled for this path - return. */
2100 if (!CHECK_FLAG(bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
2103 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
2104 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2107 if (!CHECK_FLAG(bgp
->vpn_policy
[afi
].flags
,
2108 BGP_VPN_POLICY_TOVPN_RD_SET
))
2111 /* Check if we have source VRF by RD value */
2112 if (memcmp(&bgp
->vpn_policy
[afi
].tovpn_rd
.val
, rd
->val
,
2113 ECOMMUNITY_SIZE
) == 0)
2120 static bool vpn_leak_to_vrf_update_onevrf(struct bgp
*to_bgp
, /* to */
2121 struct bgp
*from_bgp
, /* from */
2122 struct bgp_path_info
*path_vpn
,
2123 struct prefix_rd
*prd
)
2125 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
2126 afi_t afi
= family2afi(p
->family
);
2128 struct attr static_attr
= {0};
2129 struct attr
*new_attr
= NULL
;
2130 struct bgp_dest
*bn
;
2131 safi_t safi
= SAFI_UNICAST
;
2132 const char *debugmsg
;
2133 struct prefix nexthop_orig
;
2134 mpls_label_t
*pLabels
= NULL
;
2135 uint32_t num_labels
= 0;
2136 int nexthop_self_flag
= 1;
2137 struct bgp_path_info
*bpi_ultimate
= NULL
;
2138 int origin_local
= 0;
2139 struct bgp
*src_vrf
;
2140 struct interface
*ifp
;
2141 char rd_buf
[RD_ADDRSTRLEN
];
2142 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2144 if (!vpn_leak_from_vpn_active(to_bgp
, afi
, &debugmsg
)) {
2147 "%s: from vpn (%s) to vrf (%s), skipping: %s",
2148 __func__
, from_bgp
->name_pretty
,
2149 to_bgp
->name_pretty
, debugmsg
);
2154 * For VRF-2-VRF route-leaking,
2155 * the source will be the originating VRF.
2157 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
2158 * get the source VRF (BGP) by looking at the RD.
2160 struct bgp
*src_bgp
= bgp_lookup_by_rd(path_vpn
, prd
, afi
);
2162 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
2163 src_vrf
= path_vpn
->extra
->bgp_orig
;
2169 /* Check for intersection of route targets */
2170 if (!ecommunity_include(
2171 to_bgp
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
2172 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
2175 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
2176 from_bgp
->name_pretty
, to_bgp
->name_pretty
);
2182 prefix_rd2str(prd
, rd_buf
, sizeof(rd_buf
), to_bgp
->asnotation
);
2184 /* A route MUST NOT ever be accepted back into its source VRF, even if
2185 * it carries one or more RTs that match that VRF.
2187 if (CHECK_FLAG(path_vpn
->flags
, BGP_PATH_ACCEPT_OWN
) && prd
&&
2188 memcmp(&prd
->val
, &to_bgp
->vpn_policy
[afi
].tovpn_rd
.val
,
2189 ECOMMUNITY_SIZE
) == 0) {
2192 "%s: skipping import, match RD (%s) of src VRF (%s) and the prefix (%pFX)",
2193 __func__
, rd_buf
, to_bgp
->name_pretty
, p
);
2198 zlog_debug("%s: updating RD %s, %pFX to %s", __func__
, rd_buf
,
2199 p
, to_bgp
->name_pretty
);
2202 static_attr
= *path_vpn
->attr
;
2204 struct ecommunity
*old_ecom
;
2205 struct ecommunity
*new_ecom
;
2207 /* If doing VRF-to-VRF leaking, strip RTs. */
2208 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
2209 if (old_ecom
&& CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2210 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2211 new_ecom
= ecommunity_dup(old_ecom
);
2212 ecommunity_strip_rts(new_ecom
);
2213 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
2215 if (new_ecom
->size
== 0) {
2216 ecommunity_free(&new_ecom
);
2217 bgp_attr_set_ecommunity(&static_attr
, NULL
);
2220 if (!old_ecom
->refcnt
)
2221 ecommunity_free(&old_ecom
);
2224 community_strip_accept_own(&static_attr
);
2227 * Nexthop: stash and clear
2229 * Nexthop is valid in context of VPN core, but not in destination vrf.
2230 * Stash it for later label resolution by vrf ingress path and then
2231 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
2233 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
2235 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
2236 nexthop_orig
.family
= nhfamily
;
2238 /* If the path has accept-own community and the source VRF
2239 * is valid, reset next-hop to self, to allow importing own
2240 * routes between different VRFs on the same node.
2241 * Set the nh ifindex to VRF's interface, not the real interface.
2242 * Let the kernel to decide with double lookup the real next-hop
2243 * interface when installing the route.
2246 subgroup_announce_reset_nhop(nhfamily
, &static_attr
);
2247 ifp
= if_get_vrf_loopback(src_vrf
->vrf_id
);
2249 static_attr
.nh_ifindex
= ifp
->ifindex
;
2255 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
2256 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
2258 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2259 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2260 static_attr
.nexthop
.s_addr
=
2261 nexthop_orig
.u
.prefix4
.s_addr
;
2263 static_attr
.mp_nexthop_global_in
=
2264 path_vpn
->attr
->mp_nexthop_global_in
;
2265 static_attr
.mp_nexthop_len
=
2266 path_vpn
->attr
->mp_nexthop_len
;
2268 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
2272 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
2273 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
2275 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2276 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2277 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
2283 * route map handling
2285 if (to_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
2286 struct bgp_path_info info
;
2287 route_map_result_t ret
;
2289 memset(&info
, 0, sizeof(info
));
2290 info
.peer
= to_bgp
->peer_self
;
2291 info
.attr
= &static_attr
;
2292 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
2293 ret
= route_map_apply(to_bgp
->vpn_policy
[afi
]
2294 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
2296 if (RMAP_DENYMATCH
== ret
) {
2297 bgp_attr_flush(&static_attr
); /* free any added parts */
2300 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
2301 __func__
, to_bgp
->name_pretty
,
2302 to_bgp
->vpn_policy
[afi
]
2303 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
2308 * if route-map changed nexthop, don't nexthop-self on output
2310 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
2311 BATTR_RMAP_NEXTHOP_UNCHANGED
))
2312 nexthop_self_flag
= 0;
2315 new_attr
= bgp_attr_intern(&static_attr
);
2316 bgp_attr_flush(&static_attr
);
2318 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2321 * ensure labels are copied
2323 * However, there is a special case: if the route originated in
2324 * another local VRF (as opposed to arriving via VPN), then the
2325 * nexthop is reached by hairpinning through this router (me)
2326 * using IP forwarding only (no LSP). Therefore, the route
2327 * imported to the VRF should not have labels attached. Note
2328 * that nexthop tracking is also involved: eliminating the
2329 * labels for these routes enables the non-labeled nexthops
2330 * from the originating VRF to be considered valid for this route.
2332 if (!CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2333 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2334 /* work back to original route */
2335 bpi_ultimate
= bgp_get_imported_bpi_ultimate(path_vpn
);
2338 * if original route was unicast,
2339 * then it did not arrive over vpn
2341 if (bpi_ultimate
->net
) {
2342 struct bgp_table
*table
;
2344 table
= bgp_dest_table(bpi_ultimate
->net
);
2345 if (table
&& (table
->safi
== SAFI_UNICAST
))
2350 if (!origin_local
&& path_vpn
->extra
2351 && path_vpn
->extra
->num_labels
) {
2352 num_labels
= path_vpn
->extra
->num_labels
;
2353 if (num_labels
> BGP_MAX_LABELS
)
2354 num_labels
= BGP_MAX_LABELS
;
2355 pLabels
= path_vpn
->extra
->label
;
2360 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
2361 path_vpn
->net
, num_labels
);
2363 if (!leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
2364 num_labels
, src_vrf
, &nexthop_orig
, nexthop_self_flag
,
2366 bgp_dest_unlock_node(bn
);
2371 bool vpn_leak_to_vrf_update(struct bgp
*from_bgp
,
2372 struct bgp_path_info
*path_vpn
,
2373 struct prefix_rd
*prd
)
2375 struct listnode
*mnode
, *mnnode
;
2377 bool leak_success
= false;
2379 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2382 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2384 /* Loop over VRFs */
2385 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2387 if (!path_vpn
->extra
2388 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
2389 leak_success
|= vpn_leak_to_vrf_update_onevrf(
2390 bgp
, from_bgp
, path_vpn
, prd
);
2393 return leak_success
;
2396 void vpn_leak_to_vrf_withdraw(struct bgp_path_info
*path_vpn
)
2398 const struct prefix
*p
;
2400 safi_t safi
= SAFI_UNICAST
;
2402 struct listnode
*mnode
, *mnnode
;
2403 struct bgp_dest
*bn
;
2404 struct bgp_path_info
*bpi
;
2405 const char *debugmsg
;
2407 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2410 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
2411 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
2414 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2416 if (!path_vpn
->net
) {
2417 #ifdef ENABLE_BGP_VNC
2418 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2419 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
2420 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
2427 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
2432 p
= bgp_dest_get_prefix(path_vpn
->net
);
2433 afi
= family2afi(p
->family
);
2435 /* Loop over VRFs */
2436 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2437 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
2439 zlog_debug("%s: from %s, skipping: %s",
2440 __func__
, bgp
->name_pretty
,
2445 /* Check for intersection of route targets */
2446 if (!ecommunity_include(
2447 bgp
->vpn_policy
[afi
]
2448 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
2449 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
2455 zlog_debug("%s: withdrawing from vrf %s", __func__
,
2458 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2460 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2463 && (struct bgp_path_info
*)bpi
->extra
->parent
2471 zlog_debug("%s: deleting bpi %p", __func__
,
2473 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
2474 bgp_path_info_delete(bn
, bpi
);
2475 bgp_process(bgp
, bn
, afi
, safi
);
2477 bgp_dest_unlock_node(bn
);
2481 void vpn_leak_to_vrf_withdraw_all(struct bgp
*to_bgp
, afi_t afi
)
2483 struct bgp_dest
*bn
;
2484 struct bgp_path_info
*bpi
;
2485 safi_t safi
= SAFI_UNICAST
;
2486 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2489 zlog_debug("%s: entry", __func__
);
2491 * Walk vrf table, delete bpi with bgp_orig in a different vrf
2493 for (bn
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); bn
;
2494 bn
= bgp_route_next(bn
)) {
2496 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2498 if (bpi
->extra
&& bpi
->extra
->bgp_orig
!= to_bgp
&&
2499 bpi
->extra
->parent
&&
2500 is_pi_family_vpn(bpi
->extra
->parent
)) {
2503 bgp_aggregate_decrement(to_bgp
,
2504 bgp_dest_get_prefix(bn
),
2506 bgp_path_info_delete(bn
, bpi
);
2507 bgp_process(to_bgp
, bn
, afi
, safi
);
2513 void vpn_leak_to_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*vpn_from
,
2516 struct bgp_dest
*pdest
;
2517 safi_t safi
= SAFI_MPLS_VPN
;
2524 for (pdest
= bgp_table_top(vpn_from
->rib
[afi
][safi
]); pdest
;
2525 pdest
= bgp_route_next(pdest
)) {
2526 struct bgp_table
*table
;
2527 struct bgp_dest
*bn
;
2528 struct bgp_path_info
*bpi
;
2530 /* This is the per-RD table of prefixes */
2531 table
= bgp_dest_get_bgp_table_info(pdest
);
2536 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
2538 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2542 bpi
->extra
->bgp_orig
== to_bgp
)
2545 vpn_leak_to_vrf_update_onevrf(to_bgp
, vpn_from
,
2553 * This function is called for definition/deletion/change to a route-map
2555 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
2557 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2559 struct route_map
*rmap
;
2561 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2562 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2567 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
2569 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2571 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
2572 && !strcmp(rmap_name
,
2573 bgp
->vpn_policy
[afi
]
2574 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
2578 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2579 __func__
, rmap_name
, bgp
->as
,
2582 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2583 bgp_get_default(), bgp
);
2585 zlog_debug("%s: after vpn_leak_prechange",
2588 /* in case of definition/deletion */
2589 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
2592 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2593 bgp_get_default(), bgp
);
2596 zlog_debug("%s: after vpn_leak_postchange",
2600 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
2601 && !strcmp(rmap_name
,
2602 bgp
->vpn_policy
[afi
]
2603 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
2606 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
2607 __func__
, rmap_name
, bgp
->as
,
2611 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2612 bgp_get_default(), bgp
);
2614 /* in case of definition/deletion */
2615 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
2618 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2619 bgp_get_default(), bgp
);
2624 /* This API is used during router-id change, reflect VPNs
2625 * auto RD and RT values and readvertise routes to VPN table.
2627 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
2631 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
2632 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2634 const char *export_name
;
2635 char buf
[RD_ADDRSTRLEN
];
2636 struct bgp
*bgp_import
;
2637 struct listnode
*node
;
2638 struct ecommunity
*ecom
;
2639 enum vpn_policy_direction idir
, edir
;
2642 * Router-id change that is not explicitly configured
2643 * (a change from zebra, frr restart for example)
2644 * should not replace a configured vpn RD/RT.
2648 zlog_debug("%s: skipping non explicit router-id change",
2653 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2654 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2657 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
2658 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2659 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2661 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2662 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
2666 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
2667 afi
, bgp_get_default(), bgp
);
2669 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2670 __func__
, export_name
);
2672 /* Remove import RT from VRFs */
2673 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2674 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2675 export_vrf
, node
, vname
)) {
2676 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2677 bgp_import
= bgp_get_default();
2679 bgp_import
= bgp_lookup_by_name(vname
);
2684 bgp_import
->vpn_policy
[afi
]
2686 (struct ecommunity_val
*)ecom
->val
);
2689 /* New router-id derive auto RD and RT and export
2692 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
2693 &bgp
->vrf_prd_auto
);
2694 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
2695 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2696 sizeof(buf
), bgp
->asnotation
);
2698 /* free up pre-existing memory if any and allocate
2699 * the ecommunity attribute with new RD/RT
2701 if (bgp
->vpn_policy
[afi
].rtlist
[edir
])
2703 &bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2704 bgp
->vpn_policy
[afi
].rtlist
[edir
] = ecommunity_str2com(
2705 buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2707 /* Update import_vrf rt_list */
2708 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2709 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2710 export_vrf
, node
, vname
)) {
2711 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2712 bgp_import
= bgp_get_default();
2714 bgp_import
= bgp_lookup_by_name(vname
);
2717 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
2718 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2720 bgp_import
->vpn_policy
[afi
]
2721 .rtlist
[idir
], ecom
);
2723 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2724 = ecommunity_dup(ecom
);
2727 /* Update routes to VPN */
2728 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
2729 afi
, bgp_get_default(),
2732 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2733 __func__
, export_name
);
2738 void vpn_policy_routemap_event(const char *rmap_name
)
2740 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2741 struct listnode
*mnode
, *mnnode
;
2745 zlog_debug("%s: entry", __func__
);
2747 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2750 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2751 vpn_policy_routemap_update(bgp
, rmap_name
);
2754 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2755 afi_t afi
, safi_t safi
)
2757 const char *export_name
;
2758 enum vpn_policy_direction idir
, edir
;
2759 char *vname
, *tmp_name
;
2760 char buf
[RD_ADDRSTRLEN
];
2761 struct ecommunity
*ecom
;
2762 bool first_export
= false;
2764 struct listnode
*node
;
2765 bool is_inst_match
= false;
2767 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2768 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2769 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2771 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2772 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2775 * Cross-ref both VRFs. Also, note if this is the first time
2776 * any VRF is importing from "import_vrf".
2778 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2779 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2781 /* Check the import_vrf list of destination vrf for the source vrf name,
2784 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2786 if (strcmp(vname
, tmp_name
) == 0) {
2787 is_inst_match
= true;
2792 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2795 XFREE(MTYPE_TMP
, vname
);
2797 /* Check if the source vrf already exports to any vrf,
2798 * first time export requires to setup auto derived RD/RT values.
2799 * Add the destination vrf name to export vrf list if it is
2802 is_inst_match
= false;
2803 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2804 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2805 first_export
= true;
2807 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2809 if (strcmp(vname
, tmp_name
) == 0) {
2810 is_inst_match
= true;
2816 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2819 XFREE(MTYPE_TMP
, vname
);
2821 /* Update import RT for current VRF using export RT of the VRF we're
2822 * importing from. First though, make sure "import_vrf" has that
2826 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2827 &from_bgp
->vrf_prd_auto
);
2828 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2829 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2830 BGP_VPN_POLICY_TOVPN_RD_SET
);
2831 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2832 sizeof(buf
), from_bgp
->asnotation
);
2833 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2834 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2835 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2836 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2837 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2838 BGP_PREVENT_VRF_2_VRF_LEAK
;
2840 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2841 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2842 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2843 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2844 .rtlist
[idir
], ecom
);
2846 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2847 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2850 const char *from_name
;
2851 char *ecom1
, *ecom2
;
2853 from_name
= from_bgp
->name
? from_bgp
->name
:
2856 ecom1
= ecommunity_ecom2str(
2857 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2858 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2860 ecom2
= ecommunity_ecom2str(
2861 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2862 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2865 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2866 __func__
, from_name
, export_name
, first_export
, ecom1
,
2869 ecommunity_strfree(&ecom1
);
2870 ecommunity_strfree(&ecom2
);
2873 /* Does "import_vrf" first need to export its routes or that
2874 * is already done and we just need to import those routes
2875 * from the global table?
2878 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2880 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2883 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2884 afi_t afi
, safi_t safi
)
2886 const char *export_name
, *tmp_name
;
2887 enum vpn_policy_direction idir
, edir
;
2889 struct ecommunity
*ecom
= NULL
;
2890 struct listnode
*node
;
2893 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2894 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2895 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2896 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2898 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2899 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2901 /* Were we importing from "import_vrf"? */
2902 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2904 if (strcmp(vname
, tmp_name
) == 0)
2909 * We do not check in the cli if the passed in bgp
2910 * instance is actually imported into us before
2911 * we call this function. As such if we do not
2912 * find this in the import_vrf list than
2913 * we just need to return safely.
2919 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2921 /* Remove "import_vrf" from our import list. */
2922 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2923 XFREE(MTYPE_TMP
, vname
);
2925 /* Remove routes imported from "import_vrf". */
2926 /* TODO: In the current logic, we have to first remove all
2927 * imported routes and then (if needed) import back routes
2929 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2931 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2932 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2933 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2934 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2935 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2936 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2938 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2940 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2941 (struct ecommunity_val
*)ecom
->val
);
2942 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2947 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2948 * below is checking for NULL that export_vrf can be
2949 * NULL, consequently it is complaining( like a cabbage )
2950 * that we could dereference and crash in the listcount(..)
2952 * So make it happy, under protest, with liberty and justice
2955 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2957 /* Remove us from "import_vrf's" export list. If no other VRF
2958 * is importing from "import_vrf", cleanup appropriately.
2960 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2962 if (strcmp(vname
, export_name
) == 0)
2967 * If we have gotten to this point then the vname must
2968 * exist. If not, we are in a world of trouble and
2969 * have slag sitting around.
2971 * import_vrf and export_vrf must match in having
2972 * the in/out names as appropriate.
2973 * export_vrf list could have been cleaned up
2974 * as part of no router bgp source instnace.
2979 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2980 XFREE(MTYPE_TMP
, vname
);
2982 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2983 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2984 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2985 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2986 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2987 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2988 sizeof(struct prefix_rd
));
2989 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2990 BGP_VPN_POLICY_TOVPN_RD_SET
);
2991 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2996 /* For testing purpose, static route of MPLS-VPN. */
2997 DEFUN (vpnv4_network
,
2999 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
3000 "Specify a network to announce via BGP\n"
3002 "Specify Route Distinguisher\n"
3003 "VPN Route Distinguisher\n"
3004 "VPN NLRI label (tag)\n"
3005 "VPN NLRI label (tag)\n"
3008 int idx_ipv4_prefixlen
= 1;
3009 int idx_ext_community
= 3;
3011 return bgp_static_set_safi(
3012 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
3013 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
3014 NULL
, NULL
, NULL
, NULL
);
3017 DEFUN (vpnv4_network_route_map
,
3018 vpnv4_network_route_map_cmd
,
3019 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
3020 "Specify a network to announce via BGP\n"
3022 "Specify Route Distinguisher\n"
3023 "VPN Route Distinguisher\n"
3024 "VPN NLRI label (tag)\n"
3025 "VPN NLRI label (tag)\n"
3030 int idx_ipv4_prefixlen
= 1;
3031 int idx_ext_community
= 3;
3034 return bgp_static_set_safi(
3035 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
3036 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
3037 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
3040 /* For testing purpose, static route of MPLS-VPN. */
3041 DEFUN (no_vpnv4_network
,
3042 no_vpnv4_network_cmd
,
3043 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
3045 "Specify a network to announce via BGP\n"
3047 "Specify Route Distinguisher\n"
3048 "VPN Route Distinguisher\n"
3049 "VPN NLRI label (tag)\n"
3050 "VPN NLRI label (tag)\n"
3053 int idx_ipv4_prefixlen
= 2;
3054 int idx_ext_community
= 4;
3056 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
3057 argv
[idx_ipv4_prefixlen
]->arg
,
3058 argv
[idx_ext_community
]->arg
,
3059 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
3062 DEFUN (vpnv6_network
,
3064 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
3065 "Specify a network to announce via BGP\n"
3066 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
3067 "Specify Route Distinguisher\n"
3068 "VPN Route Distinguisher\n"
3069 "VPN NLRI label (tag)\n"
3070 "VPN NLRI label (tag)\n"
3075 int idx_ipv6_prefix
= 1;
3076 int idx_ext_community
= 3;
3080 return bgp_static_set_safi(
3081 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
3082 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
3083 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
3085 return bgp_static_set_safi(
3086 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
3087 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
3088 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
3091 /* For testing purpose, static route of MPLS-VPN. */
3092 DEFUN (no_vpnv6_network
,
3093 no_vpnv6_network_cmd
,
3094 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
3096 "Specify a network to announce via BGP\n"
3097 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
3098 "Specify Route Distinguisher\n"
3099 "VPN Route Distinguisher\n"
3100 "VPN NLRI label (tag)\n"
3101 "VPN NLRI label (tag)\n"
3104 int idx_ipv6_prefix
= 2;
3105 int idx_ext_community
= 4;
3107 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
3108 argv
[idx_ipv6_prefix
]->arg
,
3109 argv
[idx_ext_community
]->arg
,
3110 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
3113 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
3114 enum bgp_show_type type
, void *output_arg
, int tags
,
3118 struct bgp_table
*table
;
3119 uint16_t show_flags
= 0;
3122 SET_FLAG(show_flags
, BGP_SHOW_OPT_JSON
);
3124 bgp
= bgp_get_default();
3127 vty_out(vty
, "No BGP process is configured\n");
3129 vty_out(vty
, "{}\n");
3132 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
3133 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
3134 output_arg
, show_flags
);
3137 DEFUN (show_bgp_ip_vpn_all_rd
,
3138 show_bgp_ip_vpn_all_rd_cmd
,
3139 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
3143 "Display VPN NLRI specific information\n"
3144 "Display VPN NLRI specific information\n"
3145 "Display information for a route distinguisher\n"
3146 "VPN Route Distinguisher\n"
3147 "All VPN Route Distinguishers\n"
3151 struct prefix_rd prd
;
3155 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
3156 /* Constrain search if user supplies RD && RD != "all" */
3157 if (argv_find(argv
, argc
, "rd", &idx
)
3158 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
3159 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
3162 "%% Malformed Route Distinguisher\n");
3165 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
3166 bgp_show_type_normal
, NULL
, 0,
3167 use_json(argc
, argv
));
3169 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3170 bgp_show_type_normal
, NULL
, 0,
3171 use_json(argc
, argv
));
3177 ALIAS(show_bgp_ip_vpn_all_rd
,
3178 show_bgp_ip_vpn_rd_cmd
,
3179 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
3183 "Display VPN NLRI specific information\n"
3184 "Display information for a route distinguisher\n"
3185 "VPN Route Distinguisher\n"
3186 "All VPN Route Distinguishers\n"
3189 #ifdef KEEP_OLD_VPN_COMMANDS
3190 DEFUN (show_ip_bgp_vpn_rd
,
3191 show_ip_bgp_vpn_rd_cmd
,
3192 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
3198 "Display information for a route distinguisher\n"
3199 "VPN Route Distinguisher\n"
3200 "All VPN Route Distinguishers\n")
3202 int idx_ext_community
= argc
- 1;
3204 struct prefix_rd prd
;
3208 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3209 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3210 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3211 bgp_show_type_normal
, NULL
, 0,
3213 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3215 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3218 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
3224 DEFUN (show_ip_bgp_vpn_all
,
3225 show_ip_bgp_vpn_all_cmd
,
3226 "show [ip] bgp <vpnv4|vpnv6>",
3235 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
3236 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
3241 DEFUN (show_ip_bgp_vpn_all_tags
,
3242 show_ip_bgp_vpn_all_tags_cmd
,
3243 "show [ip] bgp <vpnv4|vpnv6> all tags",
3248 "Display information about all VPNv4/VPNV6 NLRIs\n"
3249 "Display BGP tags for prefixes\n")
3254 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
3255 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
3260 DEFUN (show_ip_bgp_vpn_rd_tags
,
3261 show_ip_bgp_vpn_rd_tags_cmd
,
3262 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
3267 "Display information for a route distinguisher\n"
3268 "VPN Route Distinguisher\n"
3269 "All VPN Route Distinguishers\n"
3270 "Display BGP tags for prefixes\n")
3272 int idx_ext_community
= 5;
3274 struct prefix_rd prd
;
3278 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3279 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3280 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3281 bgp_show_type_normal
, NULL
, 1,
3283 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3285 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3288 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
3294 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
3295 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
3296 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
3301 "Display information about all VPNv4/VPNv6 NLRIs\n"
3302 "Detailed information on TCP and BGP neighbor connections\n"
3303 "Neighbor to display information about\n"
3304 "Display routes learned from neighbor\n"
3311 bool uj
= use_json(argc
, argv
);
3315 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3316 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3319 json_object
*json_no
= NULL
;
3320 json_no
= json_object_new_object();
3321 json_object_string_add(json_no
, "warning",
3322 "Malformed address");
3323 vty_out(vty
, "%s\n",
3324 json_object_to_json_string(json_no
));
3325 json_object_free(json_no
);
3327 vty_out(vty
, "Malformed address: %s\n",
3328 argv
[idx_ipv4
]->arg
);
3332 peer
= peer_lookup(NULL
, &su
);
3333 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3335 json_object
*json_no
= NULL
;
3336 json_no
= json_object_new_object();
3337 json_object_string_add(
3339 "No such neighbor or address family");
3340 vty_out(vty
, "%s\n",
3341 json_object_to_json_string(json_no
));
3342 json_object_free(json_no
);
3345 "%% No such neighbor or address family\n");
3349 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
3355 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
3356 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
3357 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
3362 "Display information for a route distinguisher\n"
3363 "VPN Route Distinguisher\n"
3364 "All VPN Route Distinguishers\n"
3365 "Detailed information on TCP and BGP neighbor connections\n"
3366 "Neighbor to display information about\n"
3367 "Display routes learned from neighbor\n"
3370 int idx_ext_community
= 5;
3375 struct prefix_rd prd
;
3376 bool prefix_rd_all
= false;
3377 bool uj
= use_json(argc
, argv
);
3381 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3382 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3383 prefix_rd_all
= true;
3385 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3388 json_object
*json_no
= NULL
;
3389 json_no
= json_object_new_object();
3390 json_object_string_add(
3392 "Malformed Route Distinguisher");
3393 vty_out(vty
, "%s\n",
3394 json_object_to_json_string(
3396 json_object_free(json_no
);
3399 "%% Malformed Route Distinguisher\n");
3404 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3407 json_object
*json_no
= NULL
;
3408 json_no
= json_object_new_object();
3409 json_object_string_add(json_no
, "warning",
3410 "Malformed address");
3411 vty_out(vty
, "%s\n",
3412 json_object_to_json_string(json_no
));
3413 json_object_free(json_no
);
3415 vty_out(vty
, "Malformed address: %s\n",
3416 argv
[idx_ext_community
]->arg
);
3420 peer
= peer_lookup(NULL
, &su
);
3421 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3423 json_object
*json_no
= NULL
;
3424 json_no
= json_object_new_object();
3425 json_object_string_add(
3427 "No such neighbor or address family");
3428 vty_out(vty
, "%s\n",
3429 json_object_to_json_string(json_no
));
3430 json_object_free(json_no
);
3433 "%% No such neighbor or address family\n");
3438 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3439 bgp_show_type_neighbor
, &su
, 0,
3442 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
3443 bgp_show_type_neighbor
, &su
, 0,
3449 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
3450 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
3451 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
3456 "Display information about all VPNv4/VPNv6 NLRIs\n"
3457 "Detailed information on TCP and BGP neighbor connections\n"
3458 "Neighbor to display information about\n"
3459 "Display the routes advertised to a BGP neighbor\n"
3466 bool uj
= use_json(argc
, argv
);
3470 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3471 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3474 json_object
*json_no
= NULL
;
3475 json_no
= json_object_new_object();
3476 json_object_string_add(json_no
, "warning",
3477 "Malformed address");
3478 vty_out(vty
, "%s\n",
3479 json_object_to_json_string(json_no
));
3480 json_object_free(json_no
);
3482 vty_out(vty
, "Malformed address: %s\n",
3483 argv
[idx_ipv4
]->arg
);
3486 peer
= peer_lookup(NULL
, &su
);
3487 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3489 json_object
*json_no
= NULL
;
3490 json_no
= json_object_new_object();
3491 json_object_string_add(
3493 "No such neighbor or address family");
3494 vty_out(vty
, "%s\n",
3495 json_object_to_json_string(json_no
));
3496 json_object_free(json_no
);
3499 "%% No such neighbor or address family\n");
3502 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3508 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
3509 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
3510 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
3515 "Display information for a route distinguisher\n"
3516 "VPN Route Distinguisher\n"
3517 "All VPN Route Distinguishers\n"
3518 "Detailed information on TCP and BGP neighbor connections\n"
3519 "Neighbor to display information about\n"
3520 "Display the routes advertised to a BGP neighbor\n"
3523 int idx_ext_community
= 5;
3527 struct prefix_rd prd
;
3529 bool uj
= use_json(argc
, argv
);
3533 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3534 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3537 json_object
*json_no
= NULL
;
3538 json_no
= json_object_new_object();
3539 json_object_string_add(json_no
, "warning",
3540 "Malformed address");
3541 vty_out(vty
, "%s\n",
3542 json_object_to_json_string(json_no
));
3543 json_object_free(json_no
);
3545 vty_out(vty
, "Malformed address: %s\n",
3546 argv
[idx_ext_community
]->arg
);
3549 peer
= peer_lookup(NULL
, &su
);
3550 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3552 json_object
*json_no
= NULL
;
3553 json_no
= json_object_new_object();
3554 json_object_string_add(
3556 "No such neighbor or address family");
3557 vty_out(vty
, "%s\n",
3558 json_object_to_json_string(json_no
));
3559 json_object_free(json_no
);
3562 "%% No such neighbor or address family\n");
3566 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3567 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3569 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3572 json_object
*json_no
= NULL
;
3573 json_no
= json_object_new_object();
3574 json_object_string_add(
3576 "Malformed Route Distinguisher");
3577 vty_out(vty
, "%s\n",
3578 json_object_to_json_string(json_no
));
3579 json_object_free(json_no
);
3582 "%% Malformed Route Distinguisher\n");
3586 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
3591 #endif /* KEEP_OLD_VPN_COMMANDS */
3593 void bgp_mplsvpn_init(void)
3595 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
3596 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
3597 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
3599 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
3600 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
3602 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
3603 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
3604 #ifdef KEEP_OLD_VPN_COMMANDS
3605 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
3606 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
3607 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
3608 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
3609 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
3610 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
3611 install_element(VIEW_NODE
,
3612 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
3613 install_element(VIEW_NODE
,
3614 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
3615 #endif /* KEEP_OLD_VPN_COMMANDS */
3618 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
3620 struct listnode
*mnode
, *mnnode
;
3624 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
3627 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
3628 struct ecommunity
*ec
;
3630 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3633 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
3635 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
3638 if (ecommunity_include(ec
, eckey
))
3645 * The purpose of this function is to process leaks that were deferred
3646 * from earlier per-vrf configuration due to not-yet-existing default
3647 * vrf, in other words, configuration such as:
3649 * router bgp MMM vrf FOO
3650 * address-family ipv4 unicast
3652 * exit-address-family
3657 * This function gets called when the default instance ("router bgp NNN")
3660 void vpn_leak_postchange_all(void)
3662 struct listnode
*next
;
3664 struct bgp
*bgp_default
= bgp_get_default();
3666 assert(bgp_default
);
3668 /* First, do any exporting from VRFs to the single VPN RIB */
3669 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3671 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3674 vpn_leak_postchange(
3675 BGP_VPN_POLICY_DIR_TOVPN
,
3680 vpn_leak_postchange(
3681 BGP_VPN_POLICY_DIR_TOVPN
,
3687 /* Now, do any importing to VRFs from the single VPN RIB */
3688 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3690 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3693 vpn_leak_postchange(
3694 BGP_VPN_POLICY_DIR_FROMVPN
,
3699 vpn_leak_postchange(
3700 BGP_VPN_POLICY_DIR_FROMVPN
,
3707 /* When a bgp vrf instance is unconfigured, remove its routes
3708 * from the VPN table and this vrf could be importing routes from other
3709 * bgp vrf instnaces, unimport them.
3710 * VRF X and VRF Y are exporting routes to each other.
3711 * When VRF X is deleted, unimport its routes from all target vrfs,
3712 * also VRF Y should unimport its routes from VRF X table.
3713 * This will ensure VPN table is cleaned up appropriately.
3715 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
3718 const char *tmp_name
;
3720 struct listnode
*node
, *next
;
3721 safi_t safi
= SAFI_UNICAST
;
3723 bool is_vrf_leak_bind
;
3726 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3729 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3730 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3732 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3734 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3735 /* vrf leak is for IPv4 and IPv6 Unicast only */
3736 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3739 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3740 if (from_bgp
== to_bgp
)
3743 /* Unimport and remove source vrf from the
3744 * other vrfs import list.
3746 struct vpn_policy
*to_vpolicy
;
3748 is_vrf_leak_bind
= false;
3749 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3750 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
3752 if (strcmp(vname
, tmp_name
) == 0) {
3753 is_vrf_leak_bind
= true;
3757 /* skip this bgp instance as there is no leak to this
3760 if (!is_vrf_leak_bind
)
3764 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3765 __func__
, from_bgp
->name_pretty
,
3766 to_bgp
->name_pretty
, afi2str(afi
),
3767 to_vpolicy
->import_vrf
->count
);
3769 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
3771 /* readd vrf name as unimport removes import vrf name
3772 * from the destination vrf's import list where the
3773 * `import vrf` configuration still exist.
3775 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
3776 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
3778 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
3779 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
3781 /* If to_bgp exports its routes to the bgp vrf
3782 * which is being deleted, un-import the
3783 * to_bgp routes from VPN.
3785 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3788 if (strcmp(vname
, tmp_name
) == 0) {
3789 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3799 /* When a router bgp is configured, there could be a bgp vrf
3800 * instance importing routes from this newly configured
3801 * bgp vrf instance. Export routes from configured
3803 * VRF Y has import from bgp vrf x,
3804 * when a bgp vrf x instance is created, export its routes
3805 * to VRF Y instance.
3807 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3810 const char *export_name
;
3812 struct listnode
*node
, *next
;
3813 struct ecommunity
*ecom
;
3814 enum vpn_policy_direction idir
, edir
;
3815 safi_t safi
= SAFI_UNICAST
;
3819 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3820 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3822 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3823 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3825 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3827 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3828 /* vrf leak is for IPv4 and IPv6 Unicast only */
3829 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3832 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3833 if (from_bgp
== to_bgp
)
3836 /* bgp instance has import list, check to see if newly
3837 * configured bgp instance is the list.
3839 struct vpn_policy
*to_vpolicy
;
3841 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3842 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3844 if (strcmp(vname
, export_name
) != 0)
3848 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3850 export_name
, to_bgp
->name_pretty
);
3852 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3853 /* remove import rt, it will be readded
3854 * as part of import from vrf.
3858 to_vpolicy
->rtlist
[idir
],
3859 (struct ecommunity_val
*)
3861 vrf_import_from_vrf(to_bgp
, from_bgp
,