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
);
1477 /* then add or update the selected nexthop */
1479 blnc
->nh
= nexthop_dup(bnc
->nexthop
, NULL
);
1480 else if (!nexthop_same(bnc
->nexthop
, blnc
->nh
)) {
1481 nexthop_free(blnc
->nh
);
1482 blnc
->nh
= nexthop_dup(bnc
->nexthop
, NULL
);
1483 if (blnc
->label
!= MPLS_INVALID_LABEL
) {
1484 bgp_zebra_send_nexthop_label(
1485 ZEBRA_MPLS_LABELS_REPLACE
, blnc
->label
,
1486 bnc
->nexthop
->ifindex
, bnc
->nexthop
->vrf_id
,
1487 ZEBRA_LSP_BGP
, &blnc
->nexthop
);
1494 /* Filter out all the cases where a per nexthop label is not possible:
1495 * - return an invalid label when the nexthop is invalid
1496 * - return the per VRF label when the per nexthop label is not supported
1497 * Otherwise, find or request a per label nexthop.
1499 static mpls_label_t
vpn_leak_from_vrf_get_per_nexthop_label(
1500 afi_t afi
, safi_t safi
, struct bgp_path_info
*pi
, struct bgp
*from_bgp
,
1503 struct bgp_path_info
*bpi_ultimate
= bgp_get_imported_bpi_ultimate(pi
);
1504 struct bgp
*bgp_nexthop
= NULL
;
1507 bool is_bgp_static_route
;
1509 is_bgp_static_route
= bpi_ultimate
->sub_type
== BGP_ROUTE_STATIC
&&
1510 bpi_ultimate
->type
== ZEBRA_ROUTE_BGP
;
1512 if (is_bgp_static_route
== false && afi
== AFI_IP
&&
1513 CHECK_FLAG(pi
->attr
->flag
, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) &&
1514 (pi
->attr
->nexthop
.s_addr
== INADDR_ANY
||
1515 !ipv4_unicast_valid(&pi
->attr
->nexthop
))) {
1516 /* IPv4 nexthop in standard BGP encoding format.
1517 * Format of address is not valid (not any, not unicast).
1518 * Fallback to the per VRF label.
1520 bgp_mplsvpn_path_nh_label_unlink(pi
);
1521 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1524 if (is_bgp_static_route
== false && afi
== AFI_IP
&&
1525 pi
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV4
&&
1526 (pi
->attr
->mp_nexthop_global_in
.s_addr
== INADDR_ANY
||
1527 !ipv4_unicast_valid(&pi
->attr
->mp_nexthop_global_in
))) {
1528 /* IPv4 nexthop is in MP-BGP encoding format.
1529 * Format of address is not valid (not any, not unicast).
1530 * Fallback to the per VRF label.
1532 bgp_mplsvpn_path_nh_label_unlink(pi
);
1533 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1536 if (is_bgp_static_route
== false && afi
== AFI_IP6
&&
1537 (pi
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
||
1538 pi
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) &&
1539 (IN6_IS_ADDR_UNSPECIFIED(&pi
->attr
->mp_nexthop_global
) ||
1540 IN6_IS_ADDR_LOOPBACK(&pi
->attr
->mp_nexthop_global
) ||
1541 IN6_IS_ADDR_MULTICAST(&pi
->attr
->mp_nexthop_global
))) {
1542 /* IPv6 nexthop is in MP-BGP encoding format.
1543 * Format of address is not valid
1544 * Fallback to the per VRF label.
1546 bgp_mplsvpn_path_nh_label_unlink(pi
);
1547 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1550 /* Check the next-hop reachability.
1551 * Get the bgp instance where the bgp_path_info originates.
1553 if (pi
->extra
&& pi
->extra
->bgp_orig
)
1554 bgp_nexthop
= pi
->extra
->bgp_orig
;
1556 bgp_nexthop
= from_bgp
;
1558 nh_afi
= BGP_ATTR_NH_AFI(afi
, pi
->attr
);
1559 nh_valid
= bgp_find_or_add_nexthop(from_bgp
, bgp_nexthop
, nh_afi
, safi
,
1562 if (!nh_valid
&& is_bgp_static_route
&&
1563 !CHECK_FLAG(from_bgp
->flags
, BGP_FLAG_IMPORT_CHECK
)) {
1564 /* "network" prefixes not routable, but since 'no bgp network
1565 * import-check' is configured, they are always valid in the BGP
1566 * table. Fallback to the per-vrf label
1568 bgp_mplsvpn_path_nh_label_unlink(pi
);
1569 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1572 if (!nh_valid
|| !pi
->nexthop
|| pi
->nexthop
->nexthop_num
== 0 ||
1573 !pi
->nexthop
->nexthop
) {
1574 /* invalid next-hop:
1575 * do not send the per-vrf label
1576 * otherwise, when the next-hop becomes valid,
1577 * we will have 2 BGP updates:
1578 * - one with the per-vrf label
1579 * - the second with the per-nexthop label
1581 bgp_mplsvpn_path_nh_label_unlink(pi
);
1582 return MPLS_INVALID_LABEL
;
1585 if (pi
->nexthop
->nexthop_num
> 1 ||
1586 pi
->nexthop
->nexthop
->type
== NEXTHOP_TYPE_BLACKHOLE
) {
1587 /* Blackhole or ECMP routes
1588 * is not compatible with per-nexthop label.
1589 * Fallback to per-vrf label.
1591 bgp_mplsvpn_path_nh_label_unlink(pi
);
1592 return from_bgp
->vpn_policy
[afi
].tovpn_label
;
1595 return _vpn_leak_from_vrf_get_per_nexthop_label(pi
, to_bgp
, from_bgp
,
1599 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1600 void vpn_leak_from_vrf_update(struct bgp
*to_bgp
, /* to */
1601 struct bgp
*from_bgp
, /* from */
1602 struct bgp_path_info
*path_vrf
) /* route */
1604 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1605 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1606 afi_t afi
= family2afi(p
->family
);
1607 struct attr static_attr
= {0};
1608 struct attr
*new_attr
= NULL
;
1609 safi_t safi
= SAFI_MPLS_VPN
;
1610 mpls_label_t label_val
;
1612 struct bgp_dest
*bn
;
1613 const char *debugmsg
;
1614 int nexthop_self_flag
= 0;
1617 zlog_debug("%s: from vrf %s", __func__
, from_bgp
->name_pretty
);
1619 if (debug
&& bgp_attr_get_ecommunity(path_vrf
->attr
)) {
1620 char *s
= ecommunity_ecom2str(
1621 bgp_attr_get_ecommunity(path_vrf
->attr
),
1622 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1624 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
1625 from_bgp
->name
, path_vrf
->type
, s
);
1626 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1634 zlog_debug("%s: can't get afi of prefix", __func__
);
1638 /* Is this route exportable into the VPN table? */
1639 if (!is_route_injectable_into_vpn(path_vrf
))
1642 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1644 zlog_debug("%s: %s skipping: %s", __func__
,
1645 from_bgp
->name
, debugmsg
);
1650 static_attr
= *path_vrf
->attr
;
1653 * route map handling
1655 if (from_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1656 struct bgp_path_info info
;
1657 route_map_result_t ret
;
1659 memset(&info
, 0, sizeof(info
));
1660 info
.peer
= to_bgp
->peer_self
;
1661 info
.attr
= &static_attr
;
1662 ret
= route_map_apply(from_bgp
->vpn_policy
[afi
]
1663 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1665 if (RMAP_DENYMATCH
== ret
) {
1666 bgp_attr_flush(&static_attr
); /* free any added parts */
1669 "%s: vrf %s route map \"%s\" says DENY, returning",
1670 __func__
, from_bgp
->name_pretty
,
1671 from_bgp
->vpn_policy
[afi
]
1672 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
1678 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1679 char *s
= ecommunity_ecom2str(
1680 bgp_attr_get_ecommunity(&static_attr
),
1681 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1683 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1685 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1689 * Add the vpn-policy rt-list
1691 struct ecommunity
*old_ecom
;
1692 struct ecommunity
*new_ecom
;
1694 /* Export with the 'from' instance's export RTs. */
1695 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1696 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1698 new_ecom
= ecommunity_dup(old_ecom
);
1699 if (CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1700 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1701 ecommunity_strip_rts(new_ecom
);
1702 new_ecom
= ecommunity_merge(
1703 new_ecom
, from_bgp
->vpn_policy
[afi
]
1704 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1705 if (!old_ecom
->refcnt
)
1706 ecommunity_free(&old_ecom
);
1708 new_ecom
= ecommunity_dup(
1709 from_bgp
->vpn_policy
[afi
]
1710 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1712 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1714 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1715 char *s
= ecommunity_ecom2str(
1716 bgp_attr_get_ecommunity(&static_attr
),
1717 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1719 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1721 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1724 community_strip_accept_own(&static_attr
);
1727 /* if policy nexthop not set, use 0 */
1728 if (CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1729 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1730 struct prefix
*nexthop
=
1731 &from_bgp
->vpn_policy
[afi
].tovpn_nexthop
;
1733 switch (nexthop
->family
) {
1735 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1737 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1739 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1740 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1744 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1745 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1752 if (!CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1753 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1754 if (afi
== AFI_IP
&&
1755 !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1757 * For ipv4, copy to multiprotocol
1760 static_attr
.mp_nexthop_global_in
=
1761 static_attr
.nexthop
;
1762 static_attr
.mp_nexthop_len
=
1763 BGP_ATTR_NHLEN_IPV4
;
1765 * XXX Leave static_attr.nexthop
1769 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1772 /* Update based on next-hop family to account for
1773 * RFC 5549 (BGP unnumbered) scenario. Note that
1774 * specific action is only needed for the case of
1775 * IPv4 nexthops as the attr has been copied
1779 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1780 static_attr
.mp_nexthop_global_in
.s_addr
=
1781 static_attr
.nexthop
.s_addr
;
1782 static_attr
.mp_nexthop_len
=
1783 BGP_ATTR_NHLEN_IPV4
;
1785 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1788 nexthop_self_flag
= 1;
1791 if (CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1792 BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP
))
1793 /* per nexthop label mode */
1794 label_val
= vpn_leak_from_vrf_get_per_nexthop_label(
1795 afi
, safi
, path_vrf
, from_bgp
, to_bgp
);
1797 /* per VRF label mode */
1798 label_val
= from_bgp
->vpn_policy
[afi
].tovpn_label
;
1800 if (label_val
== MPLS_INVALID_LABEL
&&
1801 CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1802 BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP
)) {
1803 /* no valid label for the moment
1804 * when the 'bgp_mplsvpn_get_label_per_nexthop_cb' callback gets
1805 * a valid label value, it will call the current function again.
1809 "%s: %s skipping: waiting for a valid per-label nexthop.",
1810 __func__
, from_bgp
->name_pretty
);
1813 if (label_val
== MPLS_LABEL_NONE
)
1814 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1816 encode_label(label_val
, &label
);
1818 /* Set originator ID to "me" */
1819 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1820 static_attr
.originator_id
= to_bgp
->router_id
;
1822 /* Set SID for SRv6 VPN */
1823 if (from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
) {
1824 struct srv6_locator_chunk
*locator
=
1825 from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
;
1827 from_bgp
->vpn_policy
[afi
].tovpn_sid_transpose_label
,
1829 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1830 sizeof(struct bgp_attr_srv6_l3vpn
));
1831 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1832 static_attr
.srv6_l3vpn
->endpoint_behavior
=
1834 ? (CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1835 ? SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID
1836 : SRV6_ENDPOINT_BEHAVIOR_END_DT4
)
1837 : (CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1838 ? SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID
1839 : SRV6_ENDPOINT_BEHAVIOR_END_DT6
);
1840 static_attr
.srv6_l3vpn
->loc_block_len
=
1841 from_bgp
->vpn_policy
[afi
]
1842 .tovpn_sid_locator
->block_bits_length
;
1843 static_attr
.srv6_l3vpn
->loc_node_len
=
1844 from_bgp
->vpn_policy
[afi
]
1845 .tovpn_sid_locator
->node_bits_length
;
1846 static_attr
.srv6_l3vpn
->func_len
=
1847 from_bgp
->vpn_policy
[afi
]
1848 .tovpn_sid_locator
->function_bits_length
;
1849 static_attr
.srv6_l3vpn
->arg_len
=
1850 from_bgp
->vpn_policy
[afi
]
1851 .tovpn_sid_locator
->argument_bits_length
;
1852 static_attr
.srv6_l3vpn
->transposition_len
=
1853 from_bgp
->vpn_policy
[afi
]
1854 .tovpn_sid_locator
->function_bits_length
;
1855 static_attr
.srv6_l3vpn
->transposition_offset
=
1856 from_bgp
->vpn_policy
[afi
]
1857 .tovpn_sid_locator
->block_bits_length
+
1858 from_bgp
->vpn_policy
[afi
]
1859 .tovpn_sid_locator
->node_bits_length
;
1861 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1862 &from_bgp
->vpn_policy
[afi
]
1863 .tovpn_sid_locator
->prefix
.prefix
,
1864 sizeof(struct in6_addr
));
1865 } else if (from_bgp
->tovpn_sid_locator
) {
1866 struct srv6_locator_chunk
*locator
=
1867 from_bgp
->tovpn_sid_locator
;
1868 encode_label(from_bgp
->tovpn_sid_transpose_label
, &label
);
1869 static_attr
.srv6_l3vpn
=
1870 XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1871 sizeof(struct bgp_attr_srv6_l3vpn
));
1872 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1873 static_attr
.srv6_l3vpn
->endpoint_behavior
=
1874 CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1875 ? SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID
1876 : SRV6_ENDPOINT_BEHAVIOR_END_DT46
;
1877 static_attr
.srv6_l3vpn
->loc_block_len
=
1878 from_bgp
->tovpn_sid_locator
->block_bits_length
;
1879 static_attr
.srv6_l3vpn
->loc_node_len
=
1880 from_bgp
->tovpn_sid_locator
->node_bits_length
;
1881 static_attr
.srv6_l3vpn
->func_len
=
1882 from_bgp
->tovpn_sid_locator
->function_bits_length
;
1883 static_attr
.srv6_l3vpn
->arg_len
=
1884 from_bgp
->tovpn_sid_locator
->argument_bits_length
;
1885 static_attr
.srv6_l3vpn
->transposition_len
=
1886 from_bgp
->tovpn_sid_locator
->function_bits_length
;
1887 static_attr
.srv6_l3vpn
->transposition_offset
=
1888 from_bgp
->tovpn_sid_locator
->block_bits_length
+
1889 from_bgp
->tovpn_sid_locator
->node_bits_length
;
1890 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1891 &from_bgp
->tovpn_sid_locator
->prefix
.prefix
,
1892 sizeof(struct in6_addr
));
1896 new_attr
= bgp_attr_intern(
1897 &static_attr
); /* hashed refcounted everything */
1898 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1900 if (debug
&& bgp_attr_get_ecommunity(new_attr
)) {
1901 char *s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr
),
1902 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1904 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1905 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1908 /* Now new_attr is an allocated interned attr */
1910 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1911 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1913 struct bgp_path_info
*new_info
;
1916 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vrf
, &label
,
1917 1, from_bgp
, NULL
, nexthop_self_flag
, debug
);
1920 * Routes actually installed in the vpn RIB must also be
1921 * offered to all vrfs (because now they originate from
1924 * Acceptance into other vrfs depends on rt-lists.
1925 * Originating vrf will not accept the looped back route
1926 * because of loop checking.
1929 vpn_leak_to_vrf_update(from_bgp
, new_info
, NULL
);
1931 bgp_dest_unlock_node(bn
);
1934 void vpn_leak_from_vrf_withdraw(struct bgp
*to_bgp
, /* to */
1935 struct bgp
*from_bgp
, /* from */
1936 struct bgp_path_info
*path_vrf
) /* route */
1938 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1939 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1940 afi_t afi
= family2afi(p
->family
);
1941 safi_t safi
= SAFI_MPLS_VPN
;
1942 struct bgp_path_info
*bpi
;
1943 struct bgp_dest
*bn
;
1944 const char *debugmsg
;
1948 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1949 __func__
, from_bgp
->name_pretty
, path_vrf
->net
,
1950 path_vrf
->type
, path_vrf
->sub_type
);
1958 zlog_debug("%s: can't get afi of prefix", __func__
);
1962 /* Is this route exportable into the VPN table? */
1963 if (!is_route_injectable_into_vpn(path_vrf
))
1966 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1968 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1973 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1975 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1976 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1982 * match original bpi imported from
1984 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1985 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1991 /* withdraw from looped vrfs as well */
1992 vpn_leak_to_vrf_withdraw(bpi
);
1994 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1995 bgp_path_info_delete(bn
, bpi
);
1996 bgp_process(to_bgp
, bn
, afi
, safi
);
1998 bgp_dest_unlock_node(bn
);
2001 void vpn_leak_from_vrf_withdraw_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2004 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
2005 struct bgp_dest
*pdest
;
2006 safi_t safi
= SAFI_MPLS_VPN
;
2009 * Walk vpn table, delete bpi with bgp_orig == from_bgp
2011 for (pdest
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); pdest
;
2012 pdest
= bgp_route_next(pdest
)) {
2014 struct bgp_table
*table
;
2015 struct bgp_dest
*bn
;
2016 struct bgp_path_info
*bpi
;
2018 /* This is the per-RD table of prefixes */
2019 table
= bgp_dest_get_bgp_table_info(pdest
);
2024 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
2025 bpi
= bgp_dest_get_bgp_path_info(bn
);
2027 zlog_debug("%s: looking at prefix %pBD",
2031 for (; bpi
; bpi
= bpi
->next
) {
2033 zlog_debug("%s: type %d, sub_type %d",
2034 __func__
, bpi
->type
,
2036 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
2040 if ((struct bgp
*)bpi
->extra
->bgp_orig
==
2044 zlog_debug("%s: deleting it",
2046 /* withdraw from leak-to vrfs as well */
2047 vpn_leak_to_vrf_withdraw(bpi
);
2048 bgp_aggregate_decrement(
2049 to_bgp
, bgp_dest_get_prefix(bn
),
2051 bgp_path_info_delete(bn
, bpi
);
2052 bgp_process(to_bgp
, bn
, afi
, safi
);
2053 bgp_mplsvpn_path_nh_label_unlink(
2054 bpi
->extra
->parent
);
2061 void vpn_leak_from_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2064 struct bgp_dest
*bn
;
2065 struct bgp_path_info
*bpi
;
2066 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
2069 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
2070 from_bgp
->name_pretty
);
2072 for (bn
= bgp_table_top(from_bgp
->rib
[afi
][SAFI_UNICAST
]); bn
;
2073 bn
= bgp_route_next(bn
)) {
2076 zlog_debug("%s: node=%p", __func__
, bn
);
2078 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2082 "%s: calling vpn_leak_from_vrf_update",
2084 vpn_leak_from_vrf_update(to_bgp
, from_bgp
, bpi
);
2089 static struct bgp
*bgp_lookup_by_rd(struct bgp_path_info
*bpi
,
2090 struct prefix_rd
*rd
, afi_t afi
)
2092 struct listnode
*node
, *nnode
;
2098 /* If ACCEPT_OWN is not enabled for this path - return. */
2099 if (!CHECK_FLAG(bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
2102 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
2103 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2106 if (!CHECK_FLAG(bgp
->vpn_policy
[afi
].flags
,
2107 BGP_VPN_POLICY_TOVPN_RD_SET
))
2110 /* Check if we have source VRF by RD value */
2111 if (memcmp(&bgp
->vpn_policy
[afi
].tovpn_rd
.val
, rd
->val
,
2112 ECOMMUNITY_SIZE
) == 0)
2119 static bool vpn_leak_to_vrf_update_onevrf(struct bgp
*to_bgp
, /* to */
2120 struct bgp
*from_bgp
, /* from */
2121 struct bgp_path_info
*path_vpn
,
2122 struct prefix_rd
*prd
)
2124 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
2125 afi_t afi
= family2afi(p
->family
);
2127 struct attr static_attr
= {0};
2128 struct attr
*new_attr
= NULL
;
2129 struct bgp_dest
*bn
;
2130 safi_t safi
= SAFI_UNICAST
;
2131 const char *debugmsg
;
2132 struct prefix nexthop_orig
;
2133 mpls_label_t
*pLabels
= NULL
;
2134 uint32_t num_labels
= 0;
2135 int nexthop_self_flag
= 1;
2136 struct bgp_path_info
*bpi_ultimate
= NULL
;
2137 int origin_local
= 0;
2138 struct bgp
*src_vrf
;
2139 struct interface
*ifp
;
2140 char rd_buf
[RD_ADDRSTRLEN
];
2141 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2143 if (!vpn_leak_from_vpn_active(to_bgp
, afi
, &debugmsg
)) {
2146 "%s: from vpn (%s) to vrf (%s), skipping: %s",
2147 __func__
, from_bgp
->name_pretty
,
2148 to_bgp
->name_pretty
, debugmsg
);
2153 * For VRF-2-VRF route-leaking,
2154 * the source will be the originating VRF.
2156 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
2157 * get the source VRF (BGP) by looking at the RD.
2159 struct bgp
*src_bgp
= bgp_lookup_by_rd(path_vpn
, prd
, afi
);
2161 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
2162 src_vrf
= path_vpn
->extra
->bgp_orig
;
2168 /* Check for intersection of route targets */
2169 if (!ecommunity_include(
2170 to_bgp
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
2171 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
2174 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
2175 from_bgp
->name_pretty
, to_bgp
->name_pretty
);
2181 prefix_rd2str(prd
, rd_buf
, sizeof(rd_buf
), to_bgp
->asnotation
);
2183 /* A route MUST NOT ever be accepted back into its source VRF, even if
2184 * it carries one or more RTs that match that VRF.
2186 if (CHECK_FLAG(path_vpn
->flags
, BGP_PATH_ACCEPT_OWN
) && prd
&&
2187 memcmp(&prd
->val
, &to_bgp
->vpn_policy
[afi
].tovpn_rd
.val
,
2188 ECOMMUNITY_SIZE
) == 0) {
2191 "%s: skipping import, match RD (%s) of src VRF (%s) and the prefix (%pFX)",
2192 __func__
, rd_buf
, to_bgp
->name_pretty
, p
);
2197 zlog_debug("%s: updating RD %s, %pFX to %s", __func__
, rd_buf
,
2198 p
, to_bgp
->name_pretty
);
2201 static_attr
= *path_vpn
->attr
;
2203 struct ecommunity
*old_ecom
;
2204 struct ecommunity
*new_ecom
;
2206 /* If doing VRF-to-VRF leaking, strip RTs. */
2207 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
2208 if (old_ecom
&& CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2209 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2210 new_ecom
= ecommunity_dup(old_ecom
);
2211 ecommunity_strip_rts(new_ecom
);
2212 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
2214 if (new_ecom
->size
== 0) {
2215 ecommunity_free(&new_ecom
);
2216 bgp_attr_set_ecommunity(&static_attr
, NULL
);
2219 if (!old_ecom
->refcnt
)
2220 ecommunity_free(&old_ecom
);
2223 community_strip_accept_own(&static_attr
);
2226 * Nexthop: stash and clear
2228 * Nexthop is valid in context of VPN core, but not in destination vrf.
2229 * Stash it for later label resolution by vrf ingress path and then
2230 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
2232 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
2234 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
2235 nexthop_orig
.family
= nhfamily
;
2237 /* If the path has accept-own community and the source VRF
2238 * is valid, reset next-hop to self, to allow importing own
2239 * routes between different VRFs on the same node.
2240 * Set the nh ifindex to VRF's interface, not the real interface.
2241 * Let the kernel to decide with double lookup the real next-hop
2242 * interface when installing the route.
2245 subgroup_announce_reset_nhop(nhfamily
, &static_attr
);
2246 ifp
= if_get_vrf_loopback(src_vrf
->vrf_id
);
2248 static_attr
.nh_ifindex
= ifp
->ifindex
;
2254 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
2255 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
2257 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2258 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2259 static_attr
.nexthop
.s_addr
=
2260 nexthop_orig
.u
.prefix4
.s_addr
;
2262 static_attr
.mp_nexthop_global_in
=
2263 path_vpn
->attr
->mp_nexthop_global_in
;
2264 static_attr
.mp_nexthop_len
=
2265 path_vpn
->attr
->mp_nexthop_len
;
2267 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
2271 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
2272 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
2274 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2275 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2276 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
2282 * route map handling
2284 if (to_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
2285 struct bgp_path_info info
;
2286 route_map_result_t ret
;
2288 memset(&info
, 0, sizeof(info
));
2289 info
.peer
= to_bgp
->peer_self
;
2290 info
.attr
= &static_attr
;
2291 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
2292 ret
= route_map_apply(to_bgp
->vpn_policy
[afi
]
2293 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
2295 if (RMAP_DENYMATCH
== ret
) {
2296 bgp_attr_flush(&static_attr
); /* free any added parts */
2299 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
2300 __func__
, to_bgp
->name_pretty
,
2301 to_bgp
->vpn_policy
[afi
]
2302 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
2307 * if route-map changed nexthop, don't nexthop-self on output
2309 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
2310 BATTR_RMAP_NEXTHOP_UNCHANGED
))
2311 nexthop_self_flag
= 0;
2314 new_attr
= bgp_attr_intern(&static_attr
);
2315 bgp_attr_flush(&static_attr
);
2317 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2320 * ensure labels are copied
2322 * However, there is a special case: if the route originated in
2323 * another local VRF (as opposed to arriving via VPN), then the
2324 * nexthop is reached by hairpinning through this router (me)
2325 * using IP forwarding only (no LSP). Therefore, the route
2326 * imported to the VRF should not have labels attached. Note
2327 * that nexthop tracking is also involved: eliminating the
2328 * labels for these routes enables the non-labeled nexthops
2329 * from the originating VRF to be considered valid for this route.
2331 if (!CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2332 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2333 /* work back to original route */
2334 bpi_ultimate
= bgp_get_imported_bpi_ultimate(path_vpn
);
2337 * if original route was unicast,
2338 * then it did not arrive over vpn
2340 if (bpi_ultimate
->net
) {
2341 struct bgp_table
*table
;
2343 table
= bgp_dest_table(bpi_ultimate
->net
);
2344 if (table
&& (table
->safi
== SAFI_UNICAST
))
2349 if (!origin_local
&& path_vpn
->extra
2350 && path_vpn
->extra
->num_labels
) {
2351 num_labels
= path_vpn
->extra
->num_labels
;
2352 if (num_labels
> BGP_MAX_LABELS
)
2353 num_labels
= BGP_MAX_LABELS
;
2354 pLabels
= path_vpn
->extra
->label
;
2359 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
2360 path_vpn
->net
, num_labels
);
2362 if (!leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
2363 num_labels
, src_vrf
, &nexthop_orig
, nexthop_self_flag
,
2365 bgp_dest_unlock_node(bn
);
2370 bool vpn_leak_to_vrf_update(struct bgp
*from_bgp
,
2371 struct bgp_path_info
*path_vpn
,
2372 struct prefix_rd
*prd
)
2374 struct listnode
*mnode
, *mnnode
;
2376 bool leak_success
= false;
2378 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2381 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2383 /* Loop over VRFs */
2384 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2386 if (!path_vpn
->extra
2387 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
2388 leak_success
|= vpn_leak_to_vrf_update_onevrf(
2389 bgp
, from_bgp
, path_vpn
, prd
);
2392 return leak_success
;
2395 void vpn_leak_to_vrf_withdraw(struct bgp_path_info
*path_vpn
)
2397 const struct prefix
*p
;
2399 safi_t safi
= SAFI_UNICAST
;
2401 struct listnode
*mnode
, *mnnode
;
2402 struct bgp_dest
*bn
;
2403 struct bgp_path_info
*bpi
;
2404 const char *debugmsg
;
2406 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2409 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
2410 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
2413 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2415 if (!path_vpn
->net
) {
2416 #ifdef ENABLE_BGP_VNC
2417 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2418 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
2419 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
2426 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
2431 p
= bgp_dest_get_prefix(path_vpn
->net
);
2432 afi
= family2afi(p
->family
);
2434 /* Loop over VRFs */
2435 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2436 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
2438 zlog_debug("%s: from %s, skipping: %s",
2439 __func__
, bgp
->name_pretty
,
2444 /* Check for intersection of route targets */
2445 if (!ecommunity_include(
2446 bgp
->vpn_policy
[afi
]
2447 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
2448 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
2454 zlog_debug("%s: withdrawing from vrf %s", __func__
,
2457 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2459 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2462 && (struct bgp_path_info
*)bpi
->extra
->parent
2470 zlog_debug("%s: deleting bpi %p", __func__
,
2472 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
2473 bgp_path_info_delete(bn
, bpi
);
2474 bgp_process(bgp
, bn
, afi
, safi
);
2476 bgp_dest_unlock_node(bn
);
2480 void vpn_leak_to_vrf_withdraw_all(struct bgp
*to_bgp
, afi_t afi
)
2482 struct bgp_dest
*bn
;
2483 struct bgp_path_info
*bpi
;
2484 safi_t safi
= SAFI_UNICAST
;
2485 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2488 zlog_debug("%s: entry", __func__
);
2490 * Walk vrf table, delete bpi with bgp_orig in a different vrf
2492 for (bn
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); bn
;
2493 bn
= bgp_route_next(bn
)) {
2495 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2497 if (bpi
->extra
&& bpi
->extra
->bgp_orig
!= to_bgp
&&
2498 bpi
->extra
->parent
&&
2499 is_pi_family_vpn(bpi
->extra
->parent
)) {
2502 bgp_aggregate_decrement(to_bgp
,
2503 bgp_dest_get_prefix(bn
),
2505 bgp_path_info_delete(bn
, bpi
);
2506 bgp_process(to_bgp
, bn
, afi
, safi
);
2512 void vpn_leak_to_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*vpn_from
,
2515 struct bgp_dest
*pdest
;
2516 safi_t safi
= SAFI_MPLS_VPN
;
2523 for (pdest
= bgp_table_top(vpn_from
->rib
[afi
][safi
]); pdest
;
2524 pdest
= bgp_route_next(pdest
)) {
2525 struct bgp_table
*table
;
2526 struct bgp_dest
*bn
;
2527 struct bgp_path_info
*bpi
;
2529 /* This is the per-RD table of prefixes */
2530 table
= bgp_dest_get_bgp_table_info(pdest
);
2535 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
2537 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2541 bpi
->extra
->bgp_orig
== to_bgp
)
2544 vpn_leak_to_vrf_update_onevrf(to_bgp
, vpn_from
,
2552 * This function is called for definition/deletion/change to a route-map
2554 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
2556 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2558 struct route_map
*rmap
;
2560 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2561 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2566 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
2568 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2570 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
2571 && !strcmp(rmap_name
,
2572 bgp
->vpn_policy
[afi
]
2573 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
2577 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2578 __func__
, rmap_name
, bgp
->as
,
2581 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2582 bgp_get_default(), bgp
);
2584 zlog_debug("%s: after vpn_leak_prechange",
2587 /* in case of definition/deletion */
2588 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
2591 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2592 bgp_get_default(), bgp
);
2595 zlog_debug("%s: after vpn_leak_postchange",
2599 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
2600 && !strcmp(rmap_name
,
2601 bgp
->vpn_policy
[afi
]
2602 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
2605 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
2606 __func__
, rmap_name
, bgp
->as
,
2610 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2611 bgp_get_default(), bgp
);
2613 /* in case of definition/deletion */
2614 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
2617 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2618 bgp_get_default(), bgp
);
2623 /* This API is used during router-id change, reflect VPNs
2624 * auto RD and RT values and readvertise routes to VPN table.
2626 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
2630 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
2631 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2633 const char *export_name
;
2634 char buf
[RD_ADDRSTRLEN
];
2635 struct bgp
*bgp_import
;
2636 struct listnode
*node
;
2637 struct ecommunity
*ecom
;
2638 enum vpn_policy_direction idir
, edir
;
2641 * Router-id change that is not explicitly configured
2642 * (a change from zebra, frr restart for example)
2643 * should not replace a configured vpn RD/RT.
2647 zlog_debug("%s: skipping non explicit router-id change",
2652 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2653 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2656 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
2657 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2658 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2660 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2661 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
2665 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
2666 afi
, bgp_get_default(), bgp
);
2668 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2669 __func__
, export_name
);
2671 /* Remove import RT from VRFs */
2672 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2673 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2674 export_vrf
, node
, vname
)) {
2675 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2676 bgp_import
= bgp_get_default();
2678 bgp_import
= bgp_lookup_by_name(vname
);
2683 bgp_import
->vpn_policy
[afi
]
2685 (struct ecommunity_val
*)ecom
->val
);
2688 /* New router-id derive auto RD and RT and export
2691 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
2692 &bgp
->vrf_prd_auto
);
2693 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
2694 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2695 sizeof(buf
), bgp
->asnotation
);
2697 /* free up pre-existing memory if any and allocate
2698 * the ecommunity attribute with new RD/RT
2700 if (bgp
->vpn_policy
[afi
].rtlist
[edir
])
2702 &bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2703 bgp
->vpn_policy
[afi
].rtlist
[edir
] = ecommunity_str2com(
2704 buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2706 /* Update import_vrf rt_list */
2707 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2708 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2709 export_vrf
, node
, vname
)) {
2710 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2711 bgp_import
= bgp_get_default();
2713 bgp_import
= bgp_lookup_by_name(vname
);
2716 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
2717 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2719 bgp_import
->vpn_policy
[afi
]
2720 .rtlist
[idir
], ecom
);
2722 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2723 = ecommunity_dup(ecom
);
2726 /* Update routes to VPN */
2727 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
2728 afi
, bgp_get_default(),
2731 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2732 __func__
, export_name
);
2737 void vpn_policy_routemap_event(const char *rmap_name
)
2739 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2740 struct listnode
*mnode
, *mnnode
;
2744 zlog_debug("%s: entry", __func__
);
2746 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2749 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2750 vpn_policy_routemap_update(bgp
, rmap_name
);
2753 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2754 afi_t afi
, safi_t safi
)
2756 const char *export_name
;
2757 enum vpn_policy_direction idir
, edir
;
2758 char *vname
, *tmp_name
;
2759 char buf
[RD_ADDRSTRLEN
];
2760 struct ecommunity
*ecom
;
2761 bool first_export
= false;
2763 struct listnode
*node
;
2764 bool is_inst_match
= false;
2766 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2767 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2768 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2770 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2771 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2774 * Cross-ref both VRFs. Also, note if this is the first time
2775 * any VRF is importing from "import_vrf".
2777 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2778 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2780 /* Check the import_vrf list of destination vrf for the source vrf name,
2783 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2785 if (strcmp(vname
, tmp_name
) == 0) {
2786 is_inst_match
= true;
2791 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2794 XFREE(MTYPE_TMP
, vname
);
2796 /* Check if the source vrf already exports to any vrf,
2797 * first time export requires to setup auto derived RD/RT values.
2798 * Add the destination vrf name to export vrf list if it is
2801 is_inst_match
= false;
2802 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2803 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2804 first_export
= true;
2806 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2808 if (strcmp(vname
, tmp_name
) == 0) {
2809 is_inst_match
= true;
2815 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2818 XFREE(MTYPE_TMP
, vname
);
2820 /* Update import RT for current VRF using export RT of the VRF we're
2821 * importing from. First though, make sure "import_vrf" has that
2825 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2826 &from_bgp
->vrf_prd_auto
);
2827 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2828 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2829 BGP_VPN_POLICY_TOVPN_RD_SET
);
2830 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2831 sizeof(buf
), from_bgp
->asnotation
);
2832 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2833 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2834 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2835 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2836 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2837 BGP_PREVENT_VRF_2_VRF_LEAK
;
2839 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2840 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2841 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2842 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2843 .rtlist
[idir
], ecom
);
2845 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2846 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2849 const char *from_name
;
2850 char *ecom1
, *ecom2
;
2852 from_name
= from_bgp
->name
? from_bgp
->name
:
2855 ecom1
= ecommunity_ecom2str(
2856 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2857 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2859 ecom2
= ecommunity_ecom2str(
2860 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2861 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2864 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2865 __func__
, from_name
, export_name
, first_export
, ecom1
,
2868 ecommunity_strfree(&ecom1
);
2869 ecommunity_strfree(&ecom2
);
2872 /* Does "import_vrf" first need to export its routes or that
2873 * is already done and we just need to import those routes
2874 * from the global table?
2877 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2879 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2882 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2883 afi_t afi
, safi_t safi
)
2885 const char *export_name
, *tmp_name
;
2886 enum vpn_policy_direction idir
, edir
;
2888 struct ecommunity
*ecom
= NULL
;
2889 struct listnode
*node
;
2892 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2893 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2894 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2895 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2897 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2898 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2900 /* Were we importing from "import_vrf"? */
2901 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2903 if (strcmp(vname
, tmp_name
) == 0)
2908 * We do not check in the cli if the passed in bgp
2909 * instance is actually imported into us before
2910 * we call this function. As such if we do not
2911 * find this in the import_vrf list than
2912 * we just need to return safely.
2918 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2920 /* Remove "import_vrf" from our import list. */
2921 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2922 XFREE(MTYPE_TMP
, vname
);
2924 /* Remove routes imported from "import_vrf". */
2925 /* TODO: In the current logic, we have to first remove all
2926 * imported routes and then (if needed) import back routes
2928 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2930 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2931 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2932 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2933 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2934 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2935 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2937 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2939 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2940 (struct ecommunity_val
*)ecom
->val
);
2941 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2946 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2947 * below is checking for NULL that export_vrf can be
2948 * NULL, consequently it is complaining( like a cabbage )
2949 * that we could dereference and crash in the listcount(..)
2951 * So make it happy, under protest, with liberty and justice
2954 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2956 /* Remove us from "import_vrf's" export list. If no other VRF
2957 * is importing from "import_vrf", cleanup appropriately.
2959 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2961 if (strcmp(vname
, export_name
) == 0)
2966 * If we have gotten to this point then the vname must
2967 * exist. If not, we are in a world of trouble and
2968 * have slag sitting around.
2970 * import_vrf and export_vrf must match in having
2971 * the in/out names as appropriate.
2972 * export_vrf list could have been cleaned up
2973 * as part of no router bgp source instnace.
2978 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2979 XFREE(MTYPE_TMP
, vname
);
2981 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2982 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2983 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2984 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2985 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2986 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2987 sizeof(struct prefix_rd
));
2988 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2989 BGP_VPN_POLICY_TOVPN_RD_SET
);
2990 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2995 /* For testing purpose, static route of MPLS-VPN. */
2996 DEFUN (vpnv4_network
,
2998 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2999 "Specify a network to announce via BGP\n"
3001 "Specify Route Distinguisher\n"
3002 "VPN Route Distinguisher\n"
3003 "VPN NLRI label (tag)\n"
3004 "VPN NLRI label (tag)\n"
3007 int idx_ipv4_prefixlen
= 1;
3008 int idx_ext_community
= 3;
3010 return bgp_static_set_safi(
3011 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
3012 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
3013 NULL
, NULL
, NULL
, NULL
);
3016 DEFUN (vpnv4_network_route_map
,
3017 vpnv4_network_route_map_cmd
,
3018 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
3019 "Specify a network to announce via BGP\n"
3021 "Specify Route Distinguisher\n"
3022 "VPN Route Distinguisher\n"
3023 "VPN NLRI label (tag)\n"
3024 "VPN NLRI label (tag)\n"
3029 int idx_ipv4_prefixlen
= 1;
3030 int idx_ext_community
= 3;
3033 return bgp_static_set_safi(
3034 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
3035 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
3036 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
3039 /* For testing purpose, static route of MPLS-VPN. */
3040 DEFUN (no_vpnv4_network
,
3041 no_vpnv4_network_cmd
,
3042 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
3044 "Specify a network to announce via BGP\n"
3046 "Specify Route Distinguisher\n"
3047 "VPN Route Distinguisher\n"
3048 "VPN NLRI label (tag)\n"
3049 "VPN NLRI label (tag)\n"
3052 int idx_ipv4_prefixlen
= 2;
3053 int idx_ext_community
= 4;
3055 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
3056 argv
[idx_ipv4_prefixlen
]->arg
,
3057 argv
[idx_ext_community
]->arg
,
3058 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
3061 DEFUN (vpnv6_network
,
3063 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
3064 "Specify a network to announce via BGP\n"
3065 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
3066 "Specify Route Distinguisher\n"
3067 "VPN Route Distinguisher\n"
3068 "VPN NLRI label (tag)\n"
3069 "VPN NLRI label (tag)\n"
3074 int idx_ipv6_prefix
= 1;
3075 int idx_ext_community
= 3;
3079 return bgp_static_set_safi(
3080 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
3081 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
3082 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
3084 return bgp_static_set_safi(
3085 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
3086 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
3087 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
3090 /* For testing purpose, static route of MPLS-VPN. */
3091 DEFUN (no_vpnv6_network
,
3092 no_vpnv6_network_cmd
,
3093 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
3095 "Specify a network to announce via BGP\n"
3096 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
3097 "Specify Route Distinguisher\n"
3098 "VPN Route Distinguisher\n"
3099 "VPN NLRI label (tag)\n"
3100 "VPN NLRI label (tag)\n"
3103 int idx_ipv6_prefix
= 2;
3104 int idx_ext_community
= 4;
3106 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
3107 argv
[idx_ipv6_prefix
]->arg
,
3108 argv
[idx_ext_community
]->arg
,
3109 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
3112 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
3113 enum bgp_show_type type
, void *output_arg
, int tags
,
3117 struct bgp_table
*table
;
3118 uint16_t show_flags
= 0;
3121 SET_FLAG(show_flags
, BGP_SHOW_OPT_JSON
);
3123 bgp
= bgp_get_default();
3126 vty_out(vty
, "No BGP process is configured\n");
3128 vty_out(vty
, "{}\n");
3131 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
3132 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
3133 output_arg
, show_flags
);
3136 DEFUN (show_bgp_ip_vpn_all_rd
,
3137 show_bgp_ip_vpn_all_rd_cmd
,
3138 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
3142 "Display VPN NLRI specific information\n"
3143 "Display VPN NLRI specific information\n"
3144 "Display information for a route distinguisher\n"
3145 "VPN Route Distinguisher\n"
3146 "All VPN Route Distinguishers\n"
3150 struct prefix_rd prd
;
3154 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
3155 /* Constrain search if user supplies RD && RD != "all" */
3156 if (argv_find(argv
, argc
, "rd", &idx
)
3157 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
3158 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
3161 "%% Malformed Route Distinguisher\n");
3164 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
3165 bgp_show_type_normal
, NULL
, 0,
3166 use_json(argc
, argv
));
3168 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3169 bgp_show_type_normal
, NULL
, 0,
3170 use_json(argc
, argv
));
3176 ALIAS(show_bgp_ip_vpn_all_rd
,
3177 show_bgp_ip_vpn_rd_cmd
,
3178 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
3182 "Display VPN NLRI specific information\n"
3183 "Display information for a route distinguisher\n"
3184 "VPN Route Distinguisher\n"
3185 "All VPN Route Distinguishers\n"
3188 #ifdef KEEP_OLD_VPN_COMMANDS
3189 DEFUN (show_ip_bgp_vpn_rd
,
3190 show_ip_bgp_vpn_rd_cmd
,
3191 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
3197 "Display information for a route distinguisher\n"
3198 "VPN Route Distinguisher\n"
3199 "All VPN Route Distinguishers\n")
3201 int idx_ext_community
= argc
- 1;
3203 struct prefix_rd prd
;
3207 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3208 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3209 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3210 bgp_show_type_normal
, NULL
, 0,
3212 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3214 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3217 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
3223 DEFUN (show_ip_bgp_vpn_all
,
3224 show_ip_bgp_vpn_all_cmd
,
3225 "show [ip] bgp <vpnv4|vpnv6>",
3234 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
3235 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
3240 DEFUN (show_ip_bgp_vpn_all_tags
,
3241 show_ip_bgp_vpn_all_tags_cmd
,
3242 "show [ip] bgp <vpnv4|vpnv6> all tags",
3247 "Display information about all VPNv4/VPNV6 NLRIs\n"
3248 "Display BGP tags for prefixes\n")
3253 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
3254 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
3259 DEFUN (show_ip_bgp_vpn_rd_tags
,
3260 show_ip_bgp_vpn_rd_tags_cmd
,
3261 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
3266 "Display information for a route distinguisher\n"
3267 "VPN Route Distinguisher\n"
3268 "All VPN Route Distinguishers\n"
3269 "Display BGP tags for prefixes\n")
3271 int idx_ext_community
= 5;
3273 struct prefix_rd prd
;
3277 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3278 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3279 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3280 bgp_show_type_normal
, NULL
, 1,
3282 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3284 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3287 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
3293 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
3294 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
3295 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
3300 "Display information about all VPNv4/VPNv6 NLRIs\n"
3301 "Detailed information on TCP and BGP neighbor connections\n"
3302 "Neighbor to display information about\n"
3303 "Display routes learned from neighbor\n"
3310 bool uj
= use_json(argc
, argv
);
3314 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3315 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3318 json_object
*json_no
= NULL
;
3319 json_no
= json_object_new_object();
3320 json_object_string_add(json_no
, "warning",
3321 "Malformed address");
3322 vty_out(vty
, "%s\n",
3323 json_object_to_json_string(json_no
));
3324 json_object_free(json_no
);
3326 vty_out(vty
, "Malformed address: %s\n",
3327 argv
[idx_ipv4
]->arg
);
3331 peer
= peer_lookup(NULL
, &su
);
3332 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3334 json_object
*json_no
= NULL
;
3335 json_no
= json_object_new_object();
3336 json_object_string_add(
3338 "No such neighbor or address family");
3339 vty_out(vty
, "%s\n",
3340 json_object_to_json_string(json_no
));
3341 json_object_free(json_no
);
3344 "%% No such neighbor or address family\n");
3348 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
3354 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
3355 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
3356 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
3361 "Display information for a route distinguisher\n"
3362 "VPN Route Distinguisher\n"
3363 "All VPN Route Distinguishers\n"
3364 "Detailed information on TCP and BGP neighbor connections\n"
3365 "Neighbor to display information about\n"
3366 "Display routes learned from neighbor\n"
3369 int idx_ext_community
= 5;
3374 struct prefix_rd prd
;
3375 bool prefix_rd_all
= false;
3376 bool uj
= use_json(argc
, argv
);
3380 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3381 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3382 prefix_rd_all
= true;
3384 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3387 json_object
*json_no
= NULL
;
3388 json_no
= json_object_new_object();
3389 json_object_string_add(
3391 "Malformed Route Distinguisher");
3392 vty_out(vty
, "%s\n",
3393 json_object_to_json_string(
3395 json_object_free(json_no
);
3398 "%% Malformed Route Distinguisher\n");
3403 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3406 json_object
*json_no
= NULL
;
3407 json_no
= json_object_new_object();
3408 json_object_string_add(json_no
, "warning",
3409 "Malformed address");
3410 vty_out(vty
, "%s\n",
3411 json_object_to_json_string(json_no
));
3412 json_object_free(json_no
);
3414 vty_out(vty
, "Malformed address: %s\n",
3415 argv
[idx_ext_community
]->arg
);
3419 peer
= peer_lookup(NULL
, &su
);
3420 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3422 json_object
*json_no
= NULL
;
3423 json_no
= json_object_new_object();
3424 json_object_string_add(
3426 "No such neighbor or address family");
3427 vty_out(vty
, "%s\n",
3428 json_object_to_json_string(json_no
));
3429 json_object_free(json_no
);
3432 "%% No such neighbor or address family\n");
3437 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3438 bgp_show_type_neighbor
, &su
, 0,
3441 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
3442 bgp_show_type_neighbor
, &su
, 0,
3448 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
3449 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
3450 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
3455 "Display information about all VPNv4/VPNv6 NLRIs\n"
3456 "Detailed information on TCP and BGP neighbor connections\n"
3457 "Neighbor to display information about\n"
3458 "Display the routes advertised to a BGP neighbor\n"
3465 bool uj
= use_json(argc
, argv
);
3469 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3470 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3473 json_object
*json_no
= NULL
;
3474 json_no
= json_object_new_object();
3475 json_object_string_add(json_no
, "warning",
3476 "Malformed address");
3477 vty_out(vty
, "%s\n",
3478 json_object_to_json_string(json_no
));
3479 json_object_free(json_no
);
3481 vty_out(vty
, "Malformed address: %s\n",
3482 argv
[idx_ipv4
]->arg
);
3485 peer
= peer_lookup(NULL
, &su
);
3486 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3488 json_object
*json_no
= NULL
;
3489 json_no
= json_object_new_object();
3490 json_object_string_add(
3492 "No such neighbor or address family");
3493 vty_out(vty
, "%s\n",
3494 json_object_to_json_string(json_no
));
3495 json_object_free(json_no
);
3498 "%% No such neighbor or address family\n");
3501 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3507 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
3508 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
3509 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
3514 "Display information for a route distinguisher\n"
3515 "VPN Route Distinguisher\n"
3516 "All VPN Route Distinguishers\n"
3517 "Detailed information on TCP and BGP neighbor connections\n"
3518 "Neighbor to display information about\n"
3519 "Display the routes advertised to a BGP neighbor\n"
3522 int idx_ext_community
= 5;
3526 struct prefix_rd prd
;
3528 bool uj
= use_json(argc
, argv
);
3532 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3533 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3536 json_object
*json_no
= NULL
;
3537 json_no
= json_object_new_object();
3538 json_object_string_add(json_no
, "warning",
3539 "Malformed address");
3540 vty_out(vty
, "%s\n",
3541 json_object_to_json_string(json_no
));
3542 json_object_free(json_no
);
3544 vty_out(vty
, "Malformed address: %s\n",
3545 argv
[idx_ext_community
]->arg
);
3548 peer
= peer_lookup(NULL
, &su
);
3549 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3551 json_object
*json_no
= NULL
;
3552 json_no
= json_object_new_object();
3553 json_object_string_add(
3555 "No such neighbor or address family");
3556 vty_out(vty
, "%s\n",
3557 json_object_to_json_string(json_no
));
3558 json_object_free(json_no
);
3561 "%% No such neighbor or address family\n");
3565 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3566 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3568 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3571 json_object
*json_no
= NULL
;
3572 json_no
= json_object_new_object();
3573 json_object_string_add(
3575 "Malformed Route Distinguisher");
3576 vty_out(vty
, "%s\n",
3577 json_object_to_json_string(json_no
));
3578 json_object_free(json_no
);
3581 "%% Malformed Route Distinguisher\n");
3585 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
3590 #endif /* KEEP_OLD_VPN_COMMANDS */
3592 void bgp_mplsvpn_init(void)
3594 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
3595 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
3596 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
3598 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
3599 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
3601 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
3602 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
3603 #ifdef KEEP_OLD_VPN_COMMANDS
3604 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
3605 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
3606 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
3607 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
3608 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
3609 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
3610 install_element(VIEW_NODE
,
3611 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
3612 install_element(VIEW_NODE
,
3613 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
3614 #endif /* KEEP_OLD_VPN_COMMANDS */
3617 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
3619 struct listnode
*mnode
, *mnnode
;
3623 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
3626 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
3627 struct ecommunity
*ec
;
3629 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3632 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
3634 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
3637 if (ecommunity_include(ec
, eckey
))
3644 * The purpose of this function is to process leaks that were deferred
3645 * from earlier per-vrf configuration due to not-yet-existing default
3646 * vrf, in other words, configuration such as:
3648 * router bgp MMM vrf FOO
3649 * address-family ipv4 unicast
3651 * exit-address-family
3656 * This function gets called when the default instance ("router bgp NNN")
3659 void vpn_leak_postchange_all(void)
3661 struct listnode
*next
;
3663 struct bgp
*bgp_default
= bgp_get_default();
3665 assert(bgp_default
);
3667 /* First, do any exporting from VRFs to the single VPN RIB */
3668 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3670 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3673 vpn_leak_postchange(
3674 BGP_VPN_POLICY_DIR_TOVPN
,
3679 vpn_leak_postchange(
3680 BGP_VPN_POLICY_DIR_TOVPN
,
3686 /* Now, do any importing to VRFs from the single VPN RIB */
3687 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3689 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3692 vpn_leak_postchange(
3693 BGP_VPN_POLICY_DIR_FROMVPN
,
3698 vpn_leak_postchange(
3699 BGP_VPN_POLICY_DIR_FROMVPN
,
3706 /* When a bgp vrf instance is unconfigured, remove its routes
3707 * from the VPN table and this vrf could be importing routes from other
3708 * bgp vrf instnaces, unimport them.
3709 * VRF X and VRF Y are exporting routes to each other.
3710 * When VRF X is deleted, unimport its routes from all target vrfs,
3711 * also VRF Y should unimport its routes from VRF X table.
3712 * This will ensure VPN table is cleaned up appropriately.
3714 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
3717 const char *tmp_name
;
3719 struct listnode
*node
, *next
;
3720 safi_t safi
= SAFI_UNICAST
;
3722 bool is_vrf_leak_bind
;
3725 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3728 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3729 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3731 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3733 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3734 /* vrf leak is for IPv4 and IPv6 Unicast only */
3735 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3738 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3739 if (from_bgp
== to_bgp
)
3742 /* Unimport and remove source vrf from the
3743 * other vrfs import list.
3745 struct vpn_policy
*to_vpolicy
;
3747 is_vrf_leak_bind
= false;
3748 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3749 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
3751 if (strcmp(vname
, tmp_name
) == 0) {
3752 is_vrf_leak_bind
= true;
3756 /* skip this bgp instance as there is no leak to this
3759 if (!is_vrf_leak_bind
)
3763 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3764 __func__
, from_bgp
->name_pretty
,
3765 to_bgp
->name_pretty
, afi2str(afi
),
3766 to_vpolicy
->import_vrf
->count
);
3768 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
3770 /* readd vrf name as unimport removes import vrf name
3771 * from the destination vrf's import list where the
3772 * `import vrf` configuration still exist.
3774 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
3775 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
3777 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
3778 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
3780 /* If to_bgp exports its routes to the bgp vrf
3781 * which is being deleted, un-import the
3782 * to_bgp routes from VPN.
3784 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3787 if (strcmp(vname
, tmp_name
) == 0) {
3788 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3798 /* When a router bgp is configured, there could be a bgp vrf
3799 * instance importing routes from this newly configured
3800 * bgp vrf instance. Export routes from configured
3802 * VRF Y has import from bgp vrf x,
3803 * when a bgp vrf x instance is created, export its routes
3804 * to VRF Y instance.
3806 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3809 const char *export_name
;
3811 struct listnode
*node
, *next
;
3812 struct ecommunity
*ecom
;
3813 enum vpn_policy_direction idir
, edir
;
3814 safi_t safi
= SAFI_UNICAST
;
3818 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3819 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3821 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3822 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3824 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3826 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3827 /* vrf leak is for IPv4 and IPv6 Unicast only */
3828 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3831 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3832 if (from_bgp
== to_bgp
)
3835 /* bgp instance has import list, check to see if newly
3836 * configured bgp instance is the list.
3838 struct vpn_policy
*to_vpolicy
;
3840 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3841 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3843 if (strcmp(vname
, export_name
) != 0)
3847 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3849 export_name
, to_bgp
->name_pretty
);
3851 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3852 /* remove import rt, it will be readded
3853 * as part of import from vrf.
3857 to_vpolicy
->rtlist
[idir
],
3858 (struct ecommunity_val
*)
3860 vrf_import_from_vrf(to_bgp
, from_bgp
,