2 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "bgpd/bgpd.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_table.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_attr.h"
40 #include "bgpd/bgp_label.h"
41 #include "bgpd/bgp_mplsvpn.h"
42 #include "bgpd/bgp_packet.h"
43 #include "bgpd/bgp_vty.h"
44 #include "bgpd/bgp_vpn.h"
45 #include "bgpd/bgp_community.h"
46 #include "bgpd/bgp_ecommunity.h"
47 #include "bgpd/bgp_zebra.h"
48 #include "bgpd/bgp_nexthop.h"
49 #include "bgpd/bgp_nht.h"
50 #include "bgpd/bgp_evpn.h"
51 #include "bgpd/bgp_memory.h"
54 #include "bgpd/rfapi/rfapi_backend.h"
58 * Definitions and external declarations.
60 extern struct zclient
*zclient
;
62 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
63 int *index
, afi_t
*afi
)
66 if (argv_find(argv
, argc
, "vpnv4", index
)) {
70 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
78 uint32_t decode_label(mpls_label_t
*label_pnt
)
81 uint8_t *pnt
= (uint8_t *)label_pnt
;
83 l
= ((uint32_t)*pnt
++ << 12);
84 l
|= (uint32_t)*pnt
++ << 4;
85 l
|= (uint32_t)((*pnt
& 0xf0) >> 4);
89 void encode_label(mpls_label_t label
, mpls_label_t
*label_pnt
)
91 uint8_t *pnt
= (uint8_t *)label_pnt
;
94 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
) {
98 *pnt
++ = (label
>> 12) & 0xff;
99 *pnt
++ = (label
>> 4) & 0xff;
100 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
103 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
104 struct bgp_nlri
*packet
)
112 struct prefix_rd prd
= {0};
113 mpls_label_t label
= {0};
116 bool addpath_capable
;
121 prd
.family
= AF_UNSPEC
;
124 struct stream
*data
= stream_new(packet
->length
);
125 stream_put(data
, packet
->nlri
, packet
->length
);
130 addpath_capable
= bgp_addpath_encode_rx(peer
, afi
, safi
);
132 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
133 while (STREAM_READABLE(data
) > 0) {
134 /* Clear prefix structure. */
135 memset(&p
, 0, sizeof(p
));
137 if (addpath_capable
) {
138 STREAM_GET(&addpath_id
, data
, BGP_ADDPATH_ID_LEN
);
139 addpath_id
= ntohl(addpath_id
);
142 if (STREAM_READABLE(data
) < 1) {
145 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no prefix length)",
146 peer
->host
, packet
->length
);
147 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
151 /* Fetch prefix length. */
152 STREAM_GETC(data
, prefixlen
);
153 p
.family
= afi2family(packet
->afi
);
154 psize
= PSIZE(prefixlen
);
156 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
159 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
160 peer
->host
, prefixlen
);
161 ret
= BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH
;
165 /* sanity check against packet data */
166 if (STREAM_READABLE(data
) < psize
) {
169 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
170 peer
->host
, prefixlen
, packet
->length
);
171 ret
= BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
175 /* sanity check against storage for the IP address portion */
176 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
179 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
181 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
183 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
187 /* Sanity check against max bitlen of the address family */
188 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
191 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
193 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
194 p
.family
, prefix_blen(&p
));
195 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
199 /* Copy label to prefix. */
200 if (STREAM_READABLE(data
) < BGP_LABEL_BYTES
) {
203 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no label)",
204 peer
->host
, packet
->length
);
205 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
209 STREAM_GET(&label
, data
, BGP_LABEL_BYTES
);
210 bgp_set_valid_label(&label
);
212 /* Copy routing distinguisher to rd. */
213 if (STREAM_READABLE(data
) < 8) {
216 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no RD)",
217 peer
->host
, packet
->length
);
218 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
221 STREAM_GET(&prd
.val
, data
, 8);
223 /* Decode RD type. */
224 type
= decode_rd_type(prd
.val
);
228 decode_rd_as(&prd
.val
[2], &rd_as
);
232 decode_rd_as4(&prd
.val
[2], &rd_as
);
236 decode_rd_ip(&prd
.val
[2], &rd_ip
);
239 #ifdef ENABLE_BGP_VNC
240 case RD_TYPE_VNC_ETH
:
245 flog_err(EC_BGP_UPDATE_RCV
, "Unknown RD type %d", type
);
246 break; /* just report */
249 /* exclude label & RD */
250 p
.prefixlen
= prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8;
251 STREAM_GET(p
.u
.val
, data
, psize
- VPN_PREFIXLEN_MIN_BYTES
);
254 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
255 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
256 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
258 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
259 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
260 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
263 /* Packet length consistency check. */
264 if (STREAM_READABLE(data
) != 0) {
267 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
268 peer
->host
, STREAM_READABLE(data
));
269 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
277 "%s [Error] Update packet error / VPN (NLRI of size %u - length error)",
278 peer
->host
, packet
->length
);
279 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
285 #undef VPN_PREFIXLEN_MIN_BYTES
289 * This function informs zebra of the label this vrf sets on routes
290 * leaked to VPN. Zebra should install this label in the kernel with
291 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
293 * Sending this vrf-label association is qualified by a) whether vrf->vpn
294 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
295 * are set) and b) whether vpn-policy label is set.
297 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
298 * for this vrf, which zebra interprets to mean "delete this vrf-label
301 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
303 mpls_label_t label
= MPLS_LABEL_NONE
;
304 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
306 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
309 "%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
310 __func__
, bgp
->name_pretty
, afi2str(afi
));
315 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
316 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
320 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
321 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
325 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
)
326 label
= MPLS_LABEL_NONE
;
327 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
328 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
332 * If zebra tells us vrf has become unconfigured, tell zebra not to
333 * use this label to forward to the vrf anymore
335 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
337 mpls_label_t label
= MPLS_LABEL_NONE
;
338 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
340 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
343 "%s: vrf_id not set, can't delete zebra vrf label",
350 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
351 bgp
->name_pretty
, bgp
->vrf_id
);
354 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
355 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
359 * This function informs zebra of the srv6-function this vrf sets on routes
360 * leaked to VPN. Zebra should install this srv6-function in the kernel with
361 * an action of "End.DT4/6's IP FIB to route the PDU."
363 void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp
*bgp
, afi_t afi
)
365 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
366 enum seg6local_action_t act
;
367 struct seg6local_context ctx
= {};
368 struct in6_addr
*tovpn_sid
= NULL
;
369 struct in6_addr
*tovpn_sid_ls
= NULL
;
372 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
374 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
375 __func__
, bgp
->name_pretty
, afi2str(afi
));
379 tovpn_sid
= bgp
->vpn_policy
[afi
].tovpn_sid
;
382 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__
,
383 bgp
->name_pretty
, afi2str(afi
));
388 zlog_debug("%s: vrf %s: afi %s: setting sid %pI6 for vrf id %d",
389 __func__
, bgp
->name_pretty
, afi2str(afi
), tovpn_sid
,
392 vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
396 ctx
.table
= vrf
->data
.l
.table_id
;
397 act
= afi
== AFI_IP
? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
398 : ZEBRA_SEG6_LOCAL_ACTION_END_DT6
;
399 zclient_send_localsid(zclient
, tovpn_sid
, bgp
->vrf_id
, act
, &ctx
);
401 tovpn_sid_ls
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
402 *tovpn_sid_ls
= *tovpn_sid
;
403 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
= tovpn_sid_ls
;
407 * This function informs zebra of the srv6-function this vrf sets on routes
408 * leaked to VPN. Zebra should install this srv6-function in the kernel with
409 * an action of "End.DT46's IP FIB to route the PDU."
411 void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp
*bgp
)
413 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
414 enum seg6local_action_t act
;
415 struct seg6local_context ctx
= {};
416 struct in6_addr
*tovpn_sid
= NULL
;
417 struct in6_addr
*tovpn_sid_ls
= NULL
;
420 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
423 "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
424 __func__
, bgp
->name_pretty
);
428 tovpn_sid
= bgp
->tovpn_sid
;
431 zlog_debug("%s: vrf %s: sid not set", __func__
,
437 zlog_debug("%s: vrf %s: setting sid %pI6 for vrf id %d",
438 __func__
, bgp
->name_pretty
, tovpn_sid
, bgp
->vrf_id
);
440 vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
444 ctx
.table
= vrf
->data
.l
.table_id
;
445 act
= ZEBRA_SEG6_LOCAL_ACTION_END_DT46
;
446 zclient_send_localsid(zclient
, tovpn_sid
, bgp
->vrf_id
, act
, &ctx
);
448 tovpn_sid_ls
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
449 *tovpn_sid_ls
= *tovpn_sid
;
450 bgp
->tovpn_zebra_vrf_sid_last_sent
= tovpn_sid_ls
;
454 * This function informs zebra of the srv6-function this vrf sets on routes
455 * leaked to VPN. Zebra should install this srv6-function in the kernel with
456 * an action of "End.DT4/6/46's IP FIB to route the PDU."
458 void vpn_leak_zebra_vrf_sid_update(struct bgp
*bgp
, afi_t afi
)
460 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
462 if (bgp
->vpn_policy
[afi
].tovpn_sid
)
463 return vpn_leak_zebra_vrf_sid_update_per_af(bgp
, afi
);
466 return vpn_leak_zebra_vrf_sid_update_per_vrf(bgp
);
469 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__
,
470 bgp
->name_pretty
, afi2str(afi
));
474 * If zebra tells us vrf has become unconfigured, tell zebra not to
475 * use this srv6-function to forward to the vrf anymore
477 void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp
*bgp
, afi_t afi
)
479 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
481 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
483 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
484 __func__
, bgp
->name_pretty
, afi2str(afi
));
489 zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__
,
490 bgp
->name_pretty
, bgp
->vrf_id
);
492 zclient_send_localsid(zclient
,
493 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
,
494 bgp
->vrf_id
, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
, NULL
);
495 XFREE(MTYPE_BGP_SRV6_SID
,
496 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
);
500 * If zebra tells us vrf has become unconfigured, tell zebra not to
501 * use this srv6-function to forward to the vrf anymore
503 void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp
*bgp
)
505 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
507 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
510 "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
511 __func__
, bgp
->name_pretty
);
516 zlog_debug("%s: deleting sid for vrf %s (id=%d)", __func__
,
517 bgp
->name_pretty
, bgp
->vrf_id
);
519 zclient_send_localsid(zclient
, bgp
->tovpn_zebra_vrf_sid_last_sent
,
520 bgp
->vrf_id
, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
,
522 XFREE(MTYPE_BGP_SRV6_SID
, bgp
->tovpn_zebra_vrf_sid_last_sent
);
526 * If zebra tells us vrf has become unconfigured, tell zebra not to
527 * use this srv6-function to forward to the vrf anymore
529 void vpn_leak_zebra_vrf_sid_withdraw(struct bgp
*bgp
, afi_t afi
)
531 if (bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
)
532 vpn_leak_zebra_vrf_sid_withdraw_per_af(bgp
, afi
);
534 if (bgp
->tovpn_zebra_vrf_sid_last_sent
)
535 vpn_leak_zebra_vrf_sid_withdraw_per_vrf(bgp
);
538 int vpn_leak_label_callback(
543 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
544 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
547 zlog_debug("%s: label=%u, allocated=%d",
548 __func__
, label
, allocated
);
552 * previously-allocated label is now invalid
554 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
555 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
557 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
558 vp
->afi
, bgp_get_default(), vp
->bgp
);
559 vp
->tovpn_label
= MPLS_LABEL_NONE
;
560 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
561 vp
->afi
, bgp_get_default(), vp
->bgp
);
567 * New label allocation
569 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
572 * not currently configured for auto label, reject allocation
577 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
578 if (label
== vp
->tovpn_label
) {
579 /* already have same label, accept but do nothing */
582 /* Shouldn't happen: different label allocation */
583 flog_err(EC_BGP_LABEL
,
584 "%s: %s had label %u but got new assignment %u",
585 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
590 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
591 vp
->afi
, bgp_get_default(), vp
->bgp
);
592 vp
->tovpn_label
= label
;
593 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
594 vp
->afi
, bgp_get_default(), vp
->bgp
);
599 static void sid_register(struct bgp
*bgp
, const struct in6_addr
*sid
,
600 const char *locator_name
)
602 struct bgp_srv6_function
*func
;
603 func
= XCALLOC(MTYPE_BGP_SRV6_FUNCTION
,
604 sizeof(struct bgp_srv6_function
));
606 snprintf(func
->locator_name
, sizeof(func
->locator_name
),
608 listnode_add(bgp
->srv6_functions
, func
);
611 static void sid_unregister(struct bgp
*bgp
, const struct in6_addr
*sid
)
613 struct listnode
*node
, *nnode
;
614 struct bgp_srv6_function
*func
;
616 for (ALL_LIST_ELEMENTS(bgp
->srv6_functions
, node
, nnode
, func
))
617 if (sid_same(&func
->sid
, sid
)) {
618 listnode_delete(bgp
->srv6_functions
, func
);
619 XFREE(MTYPE_BGP_SRV6_FUNCTION
, func
);
623 static bool sid_exist(struct bgp
*bgp
, const struct in6_addr
*sid
)
625 struct listnode
*node
;
626 struct bgp_srv6_function
*func
;
628 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_functions
, node
, func
))
629 if (sid_same(&func
->sid
, sid
))
635 * This function generates a new SID based on bgp->srv6_locator_chunks and
636 * index. The locator and generated SID are stored in arguments sid_locator
637 * and sid, respectively.
639 * if index != 0: try to allocate as index-mode
640 * else: try to allocate as auto-mode
642 static uint32_t alloc_new_sid(struct bgp
*bgp
, uint32_t index
,
643 struct srv6_locator_chunk
*sid_locator_chunk
,
644 struct in6_addr
*sid
)
646 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
647 struct listnode
*node
;
648 struct srv6_locator_chunk
*chunk
;
649 bool alloced
= false;
652 uint8_t func_len
= 0, shift_len
= 0;
653 uint32_t index_max
= 0;
655 if (!bgp
|| !sid_locator_chunk
|| !sid
)
658 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_locator_chunks
, node
, chunk
)) {
659 if (chunk
->function_bits_length
>
660 BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
) {
663 "%s: invalid SRv6 Locator chunk (%pFX): Function Length must be less or equal to %d",
664 __func__
, &chunk
->prefix
,
665 BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
);
669 index_max
= (1 << chunk
->function_bits_length
) - 1;
671 if (index
> index_max
) {
674 "%s: skipped SRv6 Locator chunk (%pFX): Function Length is too short to support specified index (%u)",
675 __func__
, &chunk
->prefix
, index
);
679 *sid
= chunk
->prefix
.prefix
;
680 *sid_locator_chunk
= *chunk
;
681 offset
= chunk
->block_bits_length
+ chunk
->node_bits_length
;
682 func_len
= chunk
->function_bits_length
;
683 shift_len
= BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
- func_len
;
686 label
= index
<< shift_len
;
687 if (label
< MPLS_LABEL_UNRESERVED_MIN
) {
690 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
691 __func__
, &chunk
->prefix
,
696 transpose_sid(sid
, label
, offset
, func_len
);
697 if (sid_exist(bgp
, sid
))
703 for (uint32_t i
= 1; i
< index_max
; i
++) {
704 label
= i
<< shift_len
;
705 if (label
< MPLS_LABEL_UNRESERVED_MIN
) {
708 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
709 __func__
, &chunk
->prefix
,
713 transpose_sid(sid
, label
, offset
, func_len
);
714 if (sid_exist(bgp
, sid
))
724 sid_register(bgp
, sid
, bgp
->srv6_locator_name
);
728 void ensure_vrf_tovpn_sid_per_af(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
,
731 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
732 struct srv6_locator_chunk
*tovpn_sid_locator
;
733 struct in6_addr
*tovpn_sid
;
734 uint32_t tovpn_sid_index
= 0, tovpn_sid_transpose_label
;
735 bool tovpn_sid_auto
= false;
738 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
739 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
741 /* skip when tovpn sid is already allocated on vrf instance */
742 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
)
746 * skip when bgp vpn instance ins't allocated
747 * or srv6 locator chunk isn't allocated
749 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
752 tovpn_sid_index
= bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
;
753 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
754 BGP_VPN_POLICY_TOVPN_SID_AUTO
);
756 /* skip when VPN isn't configured on vrf-instance */
757 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
760 /* check invalid case both configured index and auto */
761 if (tovpn_sid_index
!= 0 && tovpn_sid_auto
) {
762 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
767 tovpn_sid_locator
= srv6_locator_chunk_alloc();
768 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
770 tovpn_sid_transpose_label
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
,
771 tovpn_sid_locator
, tovpn_sid
);
773 if (tovpn_sid_transpose_label
== 0) {
776 "%s: not allocated new sid for vrf %s: afi %s",
777 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
778 srv6_locator_chunk_free(&tovpn_sid_locator
);
779 XFREE(MTYPE_BGP_SRV6_SID
, tovpn_sid
);
784 zlog_debug("%s: new sid %pI6 allocated for vrf %s: afi %s",
785 __func__
, tovpn_sid
, bgp_vrf
->name_pretty
,
788 bgp_vrf
->vpn_policy
[afi
].tovpn_sid
= tovpn_sid
;
789 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
= tovpn_sid_locator
;
790 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
=
791 tovpn_sid_transpose_label
;
794 void ensure_vrf_tovpn_sid_per_vrf(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
)
796 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
797 struct srv6_locator_chunk
*tovpn_sid_locator
;
798 struct in6_addr
*tovpn_sid
;
799 uint32_t tovpn_sid_index
= 0, tovpn_sid_transpose_label
;
800 bool tovpn_sid_auto
= false;
803 zlog_debug("%s: try to allocate new SID for vrf %s", __func__
,
804 bgp_vrf
->name_pretty
);
806 /* skip when tovpn sid is already allocated on vrf instance */
807 if (bgp_vrf
->tovpn_sid
)
811 * skip when bgp vpn instance ins't allocated
812 * or srv6 locator chunk isn't allocated
814 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
817 tovpn_sid_index
= bgp_vrf
->tovpn_sid_index
;
818 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_TOVPN_SID_AUTO
);
820 /* skip when VPN isn't configured on vrf-instance */
821 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
824 /* check invalid case both configured index and auto */
825 if (tovpn_sid_index
!= 0 && tovpn_sid_auto
) {
826 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
831 tovpn_sid_locator
= srv6_locator_chunk_alloc();
832 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
834 tovpn_sid_transpose_label
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
,
835 tovpn_sid_locator
, tovpn_sid
);
837 if (tovpn_sid_transpose_label
== 0) {
839 zlog_debug("%s: not allocated new sid for vrf %s",
840 __func__
, bgp_vrf
->name_pretty
);
841 srv6_locator_chunk_free(&tovpn_sid_locator
);
842 XFREE(MTYPE_BGP_SRV6_SID
, tovpn_sid
);
847 zlog_debug("%s: new sid %pI6 allocated for vrf %s", __func__
,
848 tovpn_sid
, bgp_vrf
->name_pretty
);
850 bgp_vrf
->tovpn_sid
= tovpn_sid
;
851 bgp_vrf
->tovpn_sid_locator
= tovpn_sid_locator
;
852 bgp_vrf
->tovpn_sid_transpose_label
= tovpn_sid_transpose_label
;
855 void ensure_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
858 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
!= 0 ||
859 CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
860 BGP_VPN_POLICY_TOVPN_SID_AUTO
))
861 return ensure_vrf_tovpn_sid_per_af(bgp_vpn
, bgp_vrf
, afi
);
864 if (bgp_vrf
->tovpn_sid_index
!= 0 ||
865 CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_TOVPN_SID_AUTO
))
866 return ensure_vrf_tovpn_sid_per_vrf(bgp_vpn
, bgp_vrf
);
869 void delete_vrf_tovpn_sid_per_af(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
,
872 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
873 uint32_t tovpn_sid_index
= 0;
874 bool tovpn_sid_auto
= false;
877 zlog_debug("%s: try to remove SID for vrf %s: afi %s", __func__
,
878 bgp_vrf
->name_pretty
, afi2str(afi
));
880 tovpn_sid_index
= bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
;
881 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
882 BGP_VPN_POLICY_TOVPN_SID_AUTO
);
884 /* skip when VPN is configured on vrf-instance */
885 if (tovpn_sid_index
!= 0 || tovpn_sid_auto
)
888 srv6_locator_chunk_free(&bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
);
890 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
) {
891 sid_unregister(bgp_vpn
, bgp_vrf
->vpn_policy
[afi
].tovpn_sid
);
892 XFREE(MTYPE_BGP_SRV6_SID
, bgp_vrf
->vpn_policy
[afi
].tovpn_sid
);
894 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
= 0;
897 void delete_vrf_tovpn_sid_per_vrf(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
)
899 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
900 uint32_t tovpn_sid_index
= 0;
901 bool tovpn_sid_auto
= false;
904 zlog_debug("%s: try to remove SID for vrf %s", __func__
,
905 bgp_vrf
->name_pretty
);
907 tovpn_sid_index
= bgp_vrf
->tovpn_sid_index
;
909 CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VPN_POLICY_TOVPN_SID_AUTO
);
911 /* skip when VPN is configured on vrf-instance */
912 if (tovpn_sid_index
!= 0 || tovpn_sid_auto
)
915 srv6_locator_chunk_free(&bgp_vrf
->tovpn_sid_locator
);
917 if (bgp_vrf
->tovpn_sid
) {
918 sid_unregister(bgp_vpn
, bgp_vrf
->tovpn_sid
);
919 XFREE(MTYPE_BGP_SRV6_SID
, bgp_vrf
->tovpn_sid
);
921 bgp_vrf
->tovpn_sid_transpose_label
= 0;
924 void delete_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
926 delete_vrf_tovpn_sid_per_af(bgp_vpn
, bgp_vrf
, afi
);
927 delete_vrf_tovpn_sid_per_vrf(bgp_vpn
, bgp_vrf
);
931 * This function embeds upper `len` bits of `label` in `sid`,
932 * starting at offset `offset` as seen from the MSB of `sid`.
934 * e.g. Given that `label` is 0x12345 and `len` is 16,
935 * then `label` will be embedded in `sid` as follows:
938 * label: 0001 0002 0003 0004 0005
939 * sid: .... 0001 0002 0003 0004
945 * e.g. Given that `label` is 0x12345 and `len` is 8,
946 * `label` will be embedded in `sid` as follows:
949 * label: 0001 0002 0003 0004 0005
950 * sid: .... 0001 0002 0000 0000
956 void transpose_sid(struct in6_addr
*sid
, uint32_t label
, uint8_t offset
,
959 for (uint8_t idx
= 0; idx
< len
; idx
++) {
960 uint8_t tidx
= offset
+ idx
;
961 sid
->s6_addr
[tidx
/ 8] &= ~(0x1 << (7 - tidx
% 8));
962 if (label
>> (19 - idx
) & 0x1)
963 sid
->s6_addr
[tidx
/ 8] |= 0x1 << (7 - tidx
% 8);
967 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
979 if (n
!= bpi
->extra
->num_labels
)
982 for (i
= 0; i
< n
; ++i
) {
983 if (label
[i
] != bpi
->extra
->label
[i
])
990 * make encoded route labels match specified encoded label set
992 static void setlabels(struct bgp_path_info
*bpi
,
993 mpls_label_t
*label
, /* array of labels */
998 assert(num_labels
<= BGP_MAX_LABELS
);
1002 bpi
->extra
->num_labels
= 0;
1006 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
1009 for (i
= 0; i
< num_labels
; ++i
) {
1010 extra
->label
[i
] = label
[i
];
1011 if (!bgp_is_valid_label(&label
[i
])) {
1012 bgp_set_valid_label(&extra
->label
[i
]);
1015 extra
->num_labels
= num_labels
;
1019 * make encoded route SIDs match specified encoded sid set
1021 static void setsids(struct bgp_path_info
*bpi
,
1022 struct in6_addr
*sid
,
1026 struct bgp_path_info_extra
*extra
;
1030 assert(num_sids
<= BGP_MAX_SIDS
);
1034 bpi
->extra
->num_sids
= 0;
1038 extra
= bgp_path_info_extra_get(bpi
);
1039 for (i
= 0; i
< num_sids
; i
++)
1040 memcpy(&extra
->sid
[i
].sid
, &sid
[i
], sizeof(struct in6_addr
));
1041 extra
->num_sids
= num_sids
;
1044 static void unsetsids(struct bgp_path_info
*bpi
)
1046 struct bgp_path_info_extra
*extra
;
1048 extra
= bgp_path_info_extra_get(bpi
);
1049 extra
->num_sids
= 0;
1050 memset(extra
->sid
, 0, sizeof(extra
->sid
));
1053 static bool leak_update_nexthop_valid(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
1054 struct attr
*new_attr
, afi_t afi
,
1056 struct bgp_path_info
*source_bpi
,
1057 struct bgp_path_info
*bpi
,
1058 struct bgp
*bgp_orig
,
1059 const struct prefix
*p
, int debug
)
1061 struct bgp_path_info
*bpi_ultimate
;
1062 struct bgp
*bgp_nexthop
;
1063 struct bgp_table
*table
;
1066 bpi_ultimate
= bgp_get_imported_bpi_ultimate(source_bpi
);
1067 table
= bgp_dest_table(bpi_ultimate
->net
);
1069 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
1070 bgp_nexthop
= bpi
->extra
->bgp_orig
;
1072 bgp_nexthop
= bgp_orig
;
1075 * No nexthop tracking for redistributed routes,
1076 * for static (i.e. coming from the bgp network statement or for
1077 * EVPN-imported routes that get leaked.
1079 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
1080 is_pi_family_evpn(bpi_ultimate
))
1082 else if (bpi_ultimate
->type
== ZEBRA_ROUTE_BGP
&&
1083 bpi_ultimate
->sub_type
== BGP_ROUTE_STATIC
&& table
&&
1084 (table
->safi
== SAFI_UNICAST
||
1085 table
->safi
== SAFI_LABELED_UNICAST
)) {
1086 /* Routes from network statement */
1087 if (!CHECK_FLAG(bgp_nexthop
->flags
, BGP_FLAG_IMPORT_CHECK
))
1091 * TBD do we need to do anything about the
1092 * 'connected' parameter?
1094 nh_valid
= bgp_find_or_add_nexthop(to_bgp
, bgp_nexthop
, afi
,
1095 safi
, bpi
, NULL
, 0, p
);
1098 * If you are using SRv6 VPN instead of MPLS, it need to check
1099 * the SID allocation. If the sid is not allocated, the rib
1102 if (to_bgp
->srv6_enabled
&&
1103 (!new_attr
->srv6_l3vpn
&& !new_attr
->srv6_vpn
)) {
1108 zlog_debug("%s: %pFX nexthop is %svalid (in vrf %s)", __func__
,
1109 p
, (nh_valid
? "" : "not "),
1110 bgp_nexthop
->name_pretty
);
1116 * returns pointer to new bgp_path_info upon success
1118 static struct bgp_path_info
*
1119 leak_update(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
1120 struct attr
*new_attr
, /* already interned */
1121 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
1122 mpls_label_t
*label
, uint32_t num_labels
, struct bgp
*bgp_orig
,
1123 struct prefix
*nexthop_orig
, int nexthop_self_flag
, int debug
)
1125 const struct prefix
*p
= bgp_dest_get_prefix(bn
);
1126 struct bgp_path_info
*bpi
;
1127 struct bgp_path_info
*new;
1128 struct bgp_path_info_extra
*extra
;
1129 uint32_t num_sids
= 0;
1130 void *parent
= source_bpi
;
1132 if (new_attr
->srv6_l3vpn
|| new_attr
->srv6_vpn
)
1137 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
1138 __func__
, to_bgp
->name_pretty
, bn
, source_bpi
->type
,
1139 source_bpi
->sub_type
);
1142 * Routes that are redistributed into BGP from zebra do not get
1143 * nexthop tracking. However, if those routes are subsequently
1144 * imported to other RIBs within BGP, the leaked routes do not
1145 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
1146 * in order to determine if the route we are currently leaking
1147 * should have nexthop tracking, we must find the ultimate
1148 * parent so we can check its sub_type.
1150 * As of now, source_bpi may at most be a second-generation route
1151 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
1152 * Using a loop here supports more complex intra-bgp import-export
1153 * schemes that could be implemented in the future.
1160 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1161 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
1166 bool labelssame
= labels_same(bpi
, label
, num_labels
);
1168 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
1169 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
1172 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
1173 __func__
, to_bgp
->name_pretty
,
1174 source_bpi
->flags
, bpi
->flags
, p
);
1179 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
1180 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
1182 bgp_attr_unintern(&new_attr
);
1185 "%s: ->%s: %pBD: Found route, no change",
1186 __func__
, to_bgp
->name_pretty
, bn
);
1190 /* If the RT was changed via extended communities as an
1191 * import/export list, we should withdraw implicitly the old
1193 * For instance, RT list was modified using route-maps:
1194 * route-map test permit 10
1195 * set extcommunity rt none
1197 if (CHECK_FLAG(bpi
->attr
->flag
,
1198 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) &&
1199 CHECK_FLAG(new_attr
->flag
,
1200 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
1201 if (!ecommunity_cmp(
1202 bgp_attr_get_ecommunity(bpi
->attr
),
1203 bgp_attr_get_ecommunity(new_attr
))) {
1204 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1205 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
,
1207 bgp_path_info_delete(bn
, bpi
);
1211 /* attr is changed */
1212 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
1214 /* Rewrite BGP route information. */
1215 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1216 bgp_path_info_restore(bn
, bpi
);
1218 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1219 bgp_attr_unintern(&bpi
->attr
);
1220 bpi
->attr
= new_attr
;
1221 bpi
->uptime
= monotime(NULL
);
1227 setlabels(bpi
, label
, num_labels
);
1233 if (new_attr
->srv6_l3vpn
) {
1234 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
1237 extra
= bgp_path_info_extra_get(bpi
);
1239 extra
->sid
[0].loc_block_len
=
1240 new_attr
->srv6_l3vpn
->loc_block_len
;
1241 extra
->sid
[0].loc_node_len
=
1242 new_attr
->srv6_l3vpn
->loc_node_len
;
1243 extra
->sid
[0].func_len
=
1244 new_attr
->srv6_l3vpn
->func_len
;
1245 extra
->sid
[0].arg_len
=
1246 new_attr
->srv6_l3vpn
->arg_len
;
1247 extra
->sid
[0].transposition_len
=
1248 new_attr
->srv6_l3vpn
->transposition_len
;
1249 extra
->sid
[0].transposition_offset
=
1250 new_attr
->srv6_l3vpn
1251 ->transposition_offset
;
1252 } else if (new_attr
->srv6_vpn
)
1253 setsids(bpi
, &new_attr
->srv6_vpn
->sid
,
1258 if (nexthop_self_flag
)
1259 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
1261 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1262 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ACCEPT_OWN
);
1264 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1265 source_bpi
, bpi
, bgp_orig
, p
,
1267 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
1269 bgp_path_info_unset_flag(bn
, bpi
, BGP_PATH_VALID
);
1271 /* Process change. */
1272 bgp_aggregate_increment(to_bgp
, p
, bpi
, afi
, safi
);
1273 bgp_process(to_bgp
, bn
, afi
, safi
);
1274 bgp_dest_unlock_node(bn
);
1277 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
1278 __func__
, to_bgp
->name_pretty
, bn
);
1283 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
1286 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
1287 __func__
, to_bgp
->name_pretty
,
1288 source_bpi
->flags
, p
);
1293 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
1294 to_bgp
->peer_self
, new_attr
, bn
);
1296 if (source_bpi
->peer
) {
1297 extra
= bgp_path_info_extra_get(new);
1298 extra
->peer_orig
= peer_lock(source_bpi
->peer
);
1301 if (nexthop_self_flag
)
1302 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
1304 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1305 bgp_path_info_set_flag(bn
, new, BGP_PATH_ACCEPT_OWN
);
1307 bgp_path_info_extra_get(new);
1313 if (new_attr
->srv6_l3vpn
) {
1314 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
1316 extra
= bgp_path_info_extra_get(new);
1318 extra
->sid
[0].loc_block_len
=
1319 new_attr
->srv6_l3vpn
->loc_block_len
;
1320 extra
->sid
[0].loc_node_len
=
1321 new_attr
->srv6_l3vpn
->loc_node_len
;
1322 extra
->sid
[0].func_len
= new_attr
->srv6_l3vpn
->func_len
;
1323 extra
->sid
[0].arg_len
= new_attr
->srv6_l3vpn
->arg_len
;
1324 extra
->sid
[0].transposition_len
=
1325 new_attr
->srv6_l3vpn
->transposition_len
;
1326 extra
->sid
[0].transposition_offset
=
1327 new_attr
->srv6_l3vpn
->transposition_offset
;
1328 } else if (new_attr
->srv6_vpn
)
1329 setsids(new, &new_attr
->srv6_vpn
->sid
, num_sids
);
1334 setlabels(new, label
, num_labels
);
1336 new->extra
->parent
= bgp_path_info_lock(parent
);
1338 (struct bgp_dest
*)((struct bgp_path_info
*)parent
)->net
);
1340 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
1342 new->extra
->nexthop_orig
= *nexthop_orig
;
1344 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1345 source_bpi
, new, bgp_orig
, p
, debug
))
1346 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
1348 bgp_path_info_unset_flag(bn
, new, BGP_PATH_VALID
);
1350 bgp_aggregate_increment(to_bgp
, p
, new, afi
, safi
);
1351 bgp_path_info_add(bn
, new);
1353 bgp_dest_unlock_node(bn
);
1354 bgp_process(to_bgp
, bn
, afi
, safi
);
1357 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
1358 to_bgp
->name_pretty
, bn
);
1363 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1364 void vpn_leak_from_vrf_update(struct bgp
*to_bgp
, /* to */
1365 struct bgp
*from_bgp
, /* from */
1366 struct bgp_path_info
*path_vrf
) /* route */
1368 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1369 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1370 afi_t afi
= family2afi(p
->family
);
1371 struct attr static_attr
= {0};
1372 struct attr
*new_attr
= NULL
;
1373 safi_t safi
= SAFI_MPLS_VPN
;
1374 mpls_label_t label_val
;
1376 struct bgp_dest
*bn
;
1377 const char *debugmsg
;
1378 int nexthop_self_flag
= 0;
1381 zlog_debug("%s: from vrf %s", __func__
, from_bgp
->name_pretty
);
1383 if (debug
&& bgp_attr_get_ecommunity(path_vrf
->attr
)) {
1384 char *s
= ecommunity_ecom2str(
1385 bgp_attr_get_ecommunity(path_vrf
->attr
),
1386 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1388 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
1389 from_bgp
->name
, path_vrf
->type
, s
);
1390 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1398 zlog_debug("%s: can't get afi of prefix", __func__
);
1402 /* Is this route exportable into the VPN table? */
1403 if (!is_route_injectable_into_vpn(path_vrf
))
1406 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1408 zlog_debug("%s: %s skipping: %s", __func__
,
1409 from_bgp
->name
, debugmsg
);
1414 static_attr
= *path_vrf
->attr
;
1417 * route map handling
1419 if (from_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1420 struct bgp_path_info info
;
1421 route_map_result_t ret
;
1423 memset(&info
, 0, sizeof(info
));
1424 info
.peer
= to_bgp
->peer_self
;
1425 info
.attr
= &static_attr
;
1426 ret
= route_map_apply(from_bgp
->vpn_policy
[afi
]
1427 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1429 if (RMAP_DENYMATCH
== ret
) {
1430 bgp_attr_flush(&static_attr
); /* free any added parts */
1433 "%s: vrf %s route map \"%s\" says DENY, returning",
1434 __func__
, from_bgp
->name_pretty
,
1435 from_bgp
->vpn_policy
[afi
]
1436 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
1442 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1443 char *s
= ecommunity_ecom2str(
1444 bgp_attr_get_ecommunity(&static_attr
),
1445 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1447 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1449 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1453 * Add the vpn-policy rt-list
1455 struct ecommunity
*old_ecom
;
1456 struct ecommunity
*new_ecom
;
1458 /* Export with the 'from' instance's export RTs. */
1459 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1460 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1462 new_ecom
= ecommunity_dup(old_ecom
);
1463 if (CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1464 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1465 ecommunity_strip_rts(new_ecom
);
1466 new_ecom
= ecommunity_merge(
1467 new_ecom
, from_bgp
->vpn_policy
[afi
]
1468 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1469 if (!old_ecom
->refcnt
)
1470 ecommunity_free(&old_ecom
);
1472 new_ecom
= ecommunity_dup(
1473 from_bgp
->vpn_policy
[afi
]
1474 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1476 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1478 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1479 char *s
= ecommunity_ecom2str(
1480 bgp_attr_get_ecommunity(&static_attr
),
1481 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1483 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1485 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1488 community_strip_accept_own(&static_attr
);
1491 /* if policy nexthop not set, use 0 */
1492 if (CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1493 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1494 struct prefix
*nexthop
=
1495 &from_bgp
->vpn_policy
[afi
].tovpn_nexthop
;
1497 switch (nexthop
->family
) {
1499 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1501 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1503 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1504 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1508 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1509 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1516 if (!CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1517 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1518 if (afi
== AFI_IP
&&
1519 !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1521 * For ipv4, copy to multiprotocol
1524 static_attr
.mp_nexthop_global_in
=
1525 static_attr
.nexthop
;
1526 static_attr
.mp_nexthop_len
=
1527 BGP_ATTR_NHLEN_IPV4
;
1529 * XXX Leave static_attr.nexthop
1533 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1536 /* Update based on next-hop family to account for
1537 * RFC 5549 (BGP unnumbered) scenario. Note that
1538 * specific action is only needed for the case of
1539 * IPv4 nexthops as the attr has been copied
1543 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1544 static_attr
.mp_nexthop_global_in
.s_addr
=
1545 static_attr
.nexthop
.s_addr
;
1546 static_attr
.mp_nexthop_len
=
1547 BGP_ATTR_NHLEN_IPV4
;
1549 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1552 nexthop_self_flag
= 1;
1555 label_val
= from_bgp
->vpn_policy
[afi
].tovpn_label
;
1556 if (label_val
== MPLS_LABEL_NONE
) {
1557 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1559 encode_label(label_val
, &label
);
1562 /* Set originator ID to "me" */
1563 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1564 static_attr
.originator_id
= to_bgp
->router_id
;
1566 /* Set SID for SRv6 VPN */
1567 if (from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
) {
1568 struct srv6_locator_chunk
*locator
=
1569 from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
;
1571 from_bgp
->vpn_policy
[afi
].tovpn_sid_transpose_label
,
1573 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1574 sizeof(struct bgp_attr_srv6_l3vpn
));
1575 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1576 static_attr
.srv6_l3vpn
->endpoint_behavior
=
1578 ? (CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1579 ? SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID
1580 : SRV6_ENDPOINT_BEHAVIOR_END_DT4
)
1581 : (CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1582 ? SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID
1583 : SRV6_ENDPOINT_BEHAVIOR_END_DT6
);
1584 static_attr
.srv6_l3vpn
->loc_block_len
=
1585 from_bgp
->vpn_policy
[afi
]
1586 .tovpn_sid_locator
->block_bits_length
;
1587 static_attr
.srv6_l3vpn
->loc_node_len
=
1588 from_bgp
->vpn_policy
[afi
]
1589 .tovpn_sid_locator
->node_bits_length
;
1590 static_attr
.srv6_l3vpn
->func_len
=
1591 from_bgp
->vpn_policy
[afi
]
1592 .tovpn_sid_locator
->function_bits_length
;
1593 static_attr
.srv6_l3vpn
->arg_len
=
1594 from_bgp
->vpn_policy
[afi
]
1595 .tovpn_sid_locator
->argument_bits_length
;
1596 static_attr
.srv6_l3vpn
->transposition_len
=
1597 from_bgp
->vpn_policy
[afi
]
1598 .tovpn_sid_locator
->function_bits_length
;
1599 static_attr
.srv6_l3vpn
->transposition_offset
=
1600 from_bgp
->vpn_policy
[afi
]
1601 .tovpn_sid_locator
->block_bits_length
+
1602 from_bgp
->vpn_policy
[afi
]
1603 .tovpn_sid_locator
->node_bits_length
;
1605 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1606 &from_bgp
->vpn_policy
[afi
]
1607 .tovpn_sid_locator
->prefix
.prefix
,
1608 sizeof(struct in6_addr
));
1609 } else if (from_bgp
->tovpn_sid_locator
) {
1610 struct srv6_locator_chunk
*locator
=
1611 from_bgp
->tovpn_sid_locator
;
1612 encode_label(from_bgp
->tovpn_sid_transpose_label
, &label
);
1613 static_attr
.srv6_l3vpn
=
1614 XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1615 sizeof(struct bgp_attr_srv6_l3vpn
));
1616 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1617 static_attr
.srv6_l3vpn
->endpoint_behavior
=
1618 CHECK_FLAG(locator
->flags
, SRV6_LOCATOR_USID
)
1619 ? SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID
1620 : SRV6_ENDPOINT_BEHAVIOR_END_DT46
;
1621 static_attr
.srv6_l3vpn
->loc_block_len
=
1622 from_bgp
->tovpn_sid_locator
->block_bits_length
;
1623 static_attr
.srv6_l3vpn
->loc_node_len
=
1624 from_bgp
->tovpn_sid_locator
->node_bits_length
;
1625 static_attr
.srv6_l3vpn
->func_len
=
1626 from_bgp
->tovpn_sid_locator
->function_bits_length
;
1627 static_attr
.srv6_l3vpn
->arg_len
=
1628 from_bgp
->tovpn_sid_locator
->argument_bits_length
;
1629 static_attr
.srv6_l3vpn
->transposition_len
=
1630 from_bgp
->tovpn_sid_locator
->function_bits_length
;
1631 static_attr
.srv6_l3vpn
->transposition_offset
=
1632 from_bgp
->tovpn_sid_locator
->block_bits_length
+
1633 from_bgp
->tovpn_sid_locator
->node_bits_length
;
1634 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1635 &from_bgp
->tovpn_sid_locator
->prefix
.prefix
,
1636 sizeof(struct in6_addr
));
1640 new_attr
= bgp_attr_intern(
1641 &static_attr
); /* hashed refcounted everything */
1642 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1644 if (debug
&& bgp_attr_get_ecommunity(new_attr
)) {
1645 char *s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr
),
1646 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1648 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1649 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1652 /* Now new_attr is an allocated interned attr */
1654 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1655 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1657 struct bgp_path_info
*new_info
;
1660 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vrf
, &label
,
1661 1, from_bgp
, NULL
, nexthop_self_flag
, debug
);
1664 * Routes actually installed in the vpn RIB must also be
1665 * offered to all vrfs (because now they originate from
1668 * Acceptance into other vrfs depends on rt-lists.
1669 * Originating vrf will not accept the looped back route
1670 * because of loop checking.
1673 vpn_leak_to_vrf_update(from_bgp
, new_info
, NULL
);
1676 void vpn_leak_from_vrf_withdraw(struct bgp
*to_bgp
, /* to */
1677 struct bgp
*from_bgp
, /* from */
1678 struct bgp_path_info
*path_vrf
) /* route */
1680 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1681 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1682 afi_t afi
= family2afi(p
->family
);
1683 safi_t safi
= SAFI_MPLS_VPN
;
1684 struct bgp_path_info
*bpi
;
1685 struct bgp_dest
*bn
;
1686 const char *debugmsg
;
1690 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1691 __func__
, from_bgp
->name_pretty
, path_vrf
->net
,
1692 path_vrf
->type
, path_vrf
->sub_type
);
1700 zlog_debug("%s: can't get afi of prefix", __func__
);
1704 /* Is this route exportable into the VPN table? */
1705 if (!is_route_injectable_into_vpn(path_vrf
))
1708 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1710 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1715 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1717 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1718 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1724 * match original bpi imported from
1726 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1727 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1733 /* withdraw from looped vrfs as well */
1734 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1736 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1737 bgp_path_info_delete(bn
, bpi
);
1738 bgp_process(to_bgp
, bn
, afi
, safi
);
1740 bgp_dest_unlock_node(bn
);
1743 void vpn_leak_from_vrf_withdraw_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1746 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1747 struct bgp_dest
*pdest
;
1748 safi_t safi
= SAFI_MPLS_VPN
;
1751 * Walk vpn table, delete bpi with bgp_orig == from_bgp
1753 for (pdest
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); pdest
;
1754 pdest
= bgp_route_next(pdest
)) {
1756 struct bgp_table
*table
;
1757 struct bgp_dest
*bn
;
1758 struct bgp_path_info
*bpi
;
1760 /* This is the per-RD table of prefixes */
1761 table
= bgp_dest_get_bgp_table_info(pdest
);
1766 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1767 bpi
= bgp_dest_get_bgp_path_info(bn
);
1769 zlog_debug("%s: looking at prefix %pBD",
1773 for (; bpi
; bpi
= bpi
->next
) {
1775 zlog_debug("%s: type %d, sub_type %d",
1776 __func__
, bpi
->type
,
1778 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1782 if ((struct bgp
*)bpi
->extra
->bgp_orig
==
1786 zlog_debug("%s: deleting it",
1788 /* withdraw from leak-to vrfs as well */
1789 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1790 bgp_aggregate_decrement(
1791 to_bgp
, bgp_dest_get_prefix(bn
),
1793 bgp_path_info_delete(bn
, bpi
);
1794 bgp_process(to_bgp
, bn
, afi
, safi
);
1801 void vpn_leak_from_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1804 struct bgp_dest
*bn
;
1805 struct bgp_path_info
*bpi
;
1806 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1809 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1810 from_bgp
->name_pretty
);
1812 for (bn
= bgp_table_top(from_bgp
->rib
[afi
][SAFI_UNICAST
]); bn
;
1813 bn
= bgp_route_next(bn
)) {
1816 zlog_debug("%s: node=%p", __func__
, bn
);
1818 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1822 "%s: calling vpn_leak_from_vrf_update",
1824 vpn_leak_from_vrf_update(to_bgp
, from_bgp
, bpi
);
1829 static struct bgp
*bgp_lookup_by_rd(struct bgp_path_info
*bpi
,
1830 struct prefix_rd
*rd
, afi_t afi
)
1832 struct listnode
*node
, *nnode
;
1838 /* If ACCEPT_OWN is not enabled for this path - return. */
1839 if (!CHECK_FLAG(bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1842 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
1843 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1846 if (!CHECK_FLAG(bgp
->vpn_policy
[afi
].flags
,
1847 BGP_VPN_POLICY_TOVPN_RD_SET
))
1850 /* Check if we have source VRF by RD value */
1851 if (memcmp(&bgp
->vpn_policy
[afi
].tovpn_rd
.val
, rd
->val
,
1852 ECOMMUNITY_SIZE
) == 0)
1859 static bool vpn_leak_to_vrf_update_onevrf(struct bgp
*to_bgp
, /* to */
1860 struct bgp
*from_bgp
, /* from */
1861 struct bgp_path_info
*path_vpn
,
1862 struct prefix_rd
*prd
)
1864 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1865 afi_t afi
= family2afi(p
->family
);
1867 struct attr static_attr
= {0};
1868 struct attr
*new_attr
= NULL
;
1869 struct bgp_dest
*bn
;
1870 safi_t safi
= SAFI_UNICAST
;
1871 const char *debugmsg
;
1872 struct prefix nexthop_orig
;
1873 mpls_label_t
*pLabels
= NULL
;
1874 uint32_t num_labels
= 0;
1875 int nexthop_self_flag
= 1;
1876 struct bgp_path_info
*bpi_ultimate
= NULL
;
1877 int origin_local
= 0;
1878 struct bgp
*src_vrf
;
1880 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1882 if (!vpn_leak_from_vpn_active(to_bgp
, afi
, &debugmsg
)) {
1884 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1888 /* Check for intersection of route targets */
1889 if (!ecommunity_include(
1890 to_bgp
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1891 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1894 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
1895 from_bgp
->name_pretty
, to_bgp
->name_pretty
);
1899 /* A route MUST NOT ever be accepted back into its source VRF, even if
1900 * it carries one or more RTs that match that VRF.
1902 if (prd
&& memcmp(&prd
->val
, &to_bgp
->vpn_policy
[afi
].tovpn_rd
.val
,
1903 ECOMMUNITY_SIZE
) == 0) {
1906 "%s: skipping import, match RD (%pRD) of src VRF (%s) and the prefix (%pFX)",
1907 __func__
, prd
, to_bgp
->name_pretty
, p
);
1913 zlog_debug("%s: updating RD %pRD, %pFX to vrf %s", __func__
,
1914 prd
, p
, to_bgp
->name_pretty
);
1917 static_attr
= *path_vpn
->attr
;
1919 struct ecommunity
*old_ecom
;
1920 struct ecommunity
*new_ecom
;
1922 /* If doing VRF-to-VRF leaking, strip RTs. */
1923 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1924 if (old_ecom
&& CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1925 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1926 new_ecom
= ecommunity_dup(old_ecom
);
1927 ecommunity_strip_rts(new_ecom
);
1928 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1930 if (new_ecom
->size
== 0) {
1931 ecommunity_free(&new_ecom
);
1932 bgp_attr_set_ecommunity(&static_attr
, NULL
);
1935 if (!old_ecom
->refcnt
)
1936 ecommunity_free(&old_ecom
);
1939 community_strip_accept_own(&static_attr
);
1942 * Nexthop: stash and clear
1944 * Nexthop is valid in context of VPN core, but not in destination vrf.
1945 * Stash it for later label resolution by vrf ingress path and then
1946 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1948 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1950 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1951 nexthop_orig
.family
= nhfamily
;
1956 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1957 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
1959 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1960 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1961 static_attr
.nexthop
.s_addr
=
1962 nexthop_orig
.u
.prefix4
.s_addr
;
1964 static_attr
.mp_nexthop_global_in
=
1965 path_vpn
->attr
->mp_nexthop_global_in
;
1966 static_attr
.mp_nexthop_len
=
1967 path_vpn
->attr
->mp_nexthop_len
;
1969 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1973 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1974 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
1976 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1977 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1978 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1984 * route map handling
1986 if (to_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1987 struct bgp_path_info info
;
1988 route_map_result_t ret
;
1990 memset(&info
, 0, sizeof(info
));
1991 info
.peer
= to_bgp
->peer_self
;
1992 info
.attr
= &static_attr
;
1993 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1994 ret
= route_map_apply(to_bgp
->vpn_policy
[afi
]
1995 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1997 if (RMAP_DENYMATCH
== ret
) {
1998 bgp_attr_flush(&static_attr
); /* free any added parts */
2001 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
2002 __func__
, to_bgp
->name_pretty
,
2003 to_bgp
->vpn_policy
[afi
]
2004 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
2009 * if route-map changed nexthop, don't nexthop-self on output
2011 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
2012 BATTR_RMAP_NEXTHOP_UNCHANGED
))
2013 nexthop_self_flag
= 0;
2016 new_attr
= bgp_attr_intern(&static_attr
);
2017 bgp_attr_flush(&static_attr
);
2019 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2022 * ensure labels are copied
2024 * However, there is a special case: if the route originated in
2025 * another local VRF (as opposed to arriving via VPN), then the
2026 * nexthop is reached by hairpinning through this router (me)
2027 * using IP forwarding only (no LSP). Therefore, the route
2028 * imported to the VRF should not have labels attached. Note
2029 * that nexthop tracking is also involved: eliminating the
2030 * labels for these routes enables the non-labeled nexthops
2031 * from the originating VRF to be considered valid for this route.
2033 if (!CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2034 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2035 /* work back to original route */
2036 bpi_ultimate
= bgp_get_imported_bpi_ultimate(path_vpn
);
2039 * if original route was unicast,
2040 * then it did not arrive over vpn
2042 if (bpi_ultimate
->net
) {
2043 struct bgp_table
*table
;
2045 table
= bgp_dest_table(bpi_ultimate
->net
);
2046 if (table
&& (table
->safi
== SAFI_UNICAST
))
2051 if (!origin_local
&& path_vpn
->extra
2052 && path_vpn
->extra
->num_labels
) {
2053 num_labels
= path_vpn
->extra
->num_labels
;
2054 if (num_labels
> BGP_MAX_LABELS
)
2055 num_labels
= BGP_MAX_LABELS
;
2056 pLabels
= path_vpn
->extra
->label
;
2061 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
2062 path_vpn
->net
, num_labels
);
2065 * For VRF-2-VRF route-leaking,
2066 * the source will be the originating VRF.
2068 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
2069 * get the source VRF (BGP) by looking at the RD.
2071 struct bgp
*src_bgp
= bgp_lookup_by_rd(path_vpn
, prd
, afi
);
2073 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
2074 src_vrf
= path_vpn
->extra
->bgp_orig
;
2080 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
2081 num_labels
, src_vrf
, &nexthop_orig
, nexthop_self_flag
,
2086 bool vpn_leak_to_vrf_update(struct bgp
*from_bgp
,
2087 struct bgp_path_info
*path_vpn
,
2088 struct prefix_rd
*prd
)
2090 struct listnode
*mnode
, *mnnode
;
2092 bool leak_success
= false;
2094 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2097 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2099 /* Loop over VRFs */
2100 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2102 if (!path_vpn
->extra
2103 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
2104 leak_success
|= vpn_leak_to_vrf_update_onevrf(
2105 bgp
, from_bgp
, path_vpn
, prd
);
2108 return leak_success
;
2111 void vpn_leak_to_vrf_withdraw(struct bgp
*from_bgp
, /* from */
2112 struct bgp_path_info
*path_vpn
) /* route */
2114 const struct prefix
*p
;
2116 safi_t safi
= SAFI_UNICAST
;
2118 struct listnode
*mnode
, *mnnode
;
2119 struct bgp_dest
*bn
;
2120 struct bgp_path_info
*bpi
;
2121 const char *debugmsg
;
2123 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2126 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
2127 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
2130 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2132 if (!path_vpn
->net
) {
2133 #ifdef ENABLE_BGP_VNC
2134 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2135 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
2136 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
2143 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
2148 p
= bgp_dest_get_prefix(path_vpn
->net
);
2149 afi
= family2afi(p
->family
);
2151 /* Loop over VRFs */
2152 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2153 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
2155 zlog_debug("%s: skipping: %s", __func__
,
2160 /* Check for intersection of route targets */
2161 if (!ecommunity_include(
2162 bgp
->vpn_policy
[afi
]
2163 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
2164 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
2170 zlog_debug("%s: withdrawing from vrf %s", __func__
,
2173 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2175 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2178 && (struct bgp_path_info
*)bpi
->extra
->parent
2186 zlog_debug("%s: deleting bpi %p", __func__
,
2188 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
2189 bgp_path_info_delete(bn
, bpi
);
2190 bgp_process(bgp
, bn
, afi
, safi
);
2192 bgp_dest_unlock_node(bn
);
2196 void vpn_leak_to_vrf_withdraw_all(struct bgp
*to_bgp
, afi_t afi
)
2198 struct bgp_dest
*bn
;
2199 struct bgp_path_info
*bpi
;
2200 safi_t safi
= SAFI_UNICAST
;
2201 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2204 zlog_debug("%s: entry", __func__
);
2206 * Walk vrf table, delete bpi with bgp_orig in a different vrf
2208 for (bn
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); bn
;
2209 bn
= bgp_route_next(bn
)) {
2211 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2213 if (bpi
->extra
&& bpi
->extra
->bgp_orig
!= to_bgp
&&
2214 bpi
->extra
->parent
&&
2215 is_pi_family_vpn(bpi
->extra
->parent
)) {
2218 bgp_aggregate_decrement(to_bgp
,
2219 bgp_dest_get_prefix(bn
),
2221 bgp_path_info_delete(bn
, bpi
);
2222 bgp_process(to_bgp
, bn
, afi
, safi
);
2228 void vpn_leak_to_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*vpn_from
,
2231 struct bgp_dest
*pdest
;
2232 safi_t safi
= SAFI_MPLS_VPN
;
2239 for (pdest
= bgp_table_top(vpn_from
->rib
[afi
][safi
]); pdest
;
2240 pdest
= bgp_route_next(pdest
)) {
2241 struct bgp_table
*table
;
2242 struct bgp_dest
*bn
;
2243 struct bgp_path_info
*bpi
;
2245 /* This is the per-RD table of prefixes */
2246 table
= bgp_dest_get_bgp_table_info(pdest
);
2251 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
2253 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2257 bpi
->extra
->bgp_orig
== to_bgp
)
2260 vpn_leak_to_vrf_update_onevrf(to_bgp
, vpn_from
,
2268 * This function is called for definition/deletion/change to a route-map
2270 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
2272 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2274 struct route_map
*rmap
;
2276 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2277 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2282 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
2284 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2286 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
2287 && !strcmp(rmap_name
,
2288 bgp
->vpn_policy
[afi
]
2289 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
2293 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2294 __func__
, rmap_name
, bgp
->as
,
2297 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2298 bgp_get_default(), bgp
);
2300 zlog_debug("%s: after vpn_leak_prechange",
2303 /* in case of definition/deletion */
2304 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
2307 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2308 bgp_get_default(), bgp
);
2311 zlog_debug("%s: after vpn_leak_postchange",
2315 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
2316 && !strcmp(rmap_name
,
2317 bgp
->vpn_policy
[afi
]
2318 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
2321 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
2322 __func__
, rmap_name
, bgp
->as
,
2326 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2327 bgp_get_default(), bgp
);
2329 /* in case of definition/deletion */
2330 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
2333 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2334 bgp_get_default(), bgp
);
2339 /* This API is used during router-id change, reflect VPNs
2340 * auto RD and RT values and readvertise routes to VPN table.
2342 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
2346 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
2347 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2349 const char *export_name
;
2350 char buf
[RD_ADDRSTRLEN
];
2351 struct bgp
*bgp_import
;
2352 struct listnode
*node
;
2353 struct ecommunity
*ecom
;
2354 enum vpn_policy_direction idir
, edir
;
2357 * Router-id change that is not explicitly configured
2358 * (a change from zebra, frr restart for example)
2359 * should not replace a configured vpn RD/RT.
2363 zlog_debug("%s: skipping non explicit router-id change",
2368 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2369 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2372 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
2373 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2374 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2376 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2377 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
2381 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
2382 afi
, bgp_get_default(), bgp
);
2384 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2385 __func__
, export_name
);
2387 /* Remove import RT from VRFs */
2388 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2389 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2390 export_vrf
, node
, vname
)) {
2391 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2392 bgp_import
= bgp_get_default();
2394 bgp_import
= bgp_lookup_by_name(vname
);
2399 bgp_import
->vpn_policy
[afi
]
2401 (struct ecommunity_val
*)ecom
->val
);
2404 /* New router-id derive auto RD and RT and export
2407 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
2408 &bgp
->vrf_prd_auto
);
2409 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
2410 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2413 /* free up pre-existing memory if any and allocate
2414 * the ecommunity attribute with new RD/RT
2416 if (bgp
->vpn_policy
[afi
].rtlist
[edir
])
2418 &bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2419 bgp
->vpn_policy
[afi
].rtlist
[edir
] = ecommunity_str2com(
2420 buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2422 /* Update import_vrf rt_list */
2423 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2424 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2425 export_vrf
, node
, vname
)) {
2426 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2427 bgp_import
= bgp_get_default();
2429 bgp_import
= bgp_lookup_by_name(vname
);
2432 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
2433 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2435 bgp_import
->vpn_policy
[afi
]
2436 .rtlist
[idir
], ecom
);
2438 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2439 = ecommunity_dup(ecom
);
2442 /* Update routes to VPN */
2443 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
2444 afi
, bgp_get_default(),
2447 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2448 __func__
, export_name
);
2453 void vpn_policy_routemap_event(const char *rmap_name
)
2455 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2456 struct listnode
*mnode
, *mnnode
;
2460 zlog_debug("%s: entry", __func__
);
2462 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2465 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2466 vpn_policy_routemap_update(bgp
, rmap_name
);
2469 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2470 afi_t afi
, safi_t safi
)
2472 const char *export_name
;
2473 enum vpn_policy_direction idir
, edir
;
2474 char *vname
, *tmp_name
;
2475 char buf
[RD_ADDRSTRLEN
];
2476 struct ecommunity
*ecom
;
2477 bool first_export
= false;
2479 struct listnode
*node
;
2480 bool is_inst_match
= false;
2482 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2483 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2484 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2486 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2487 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2490 * Cross-ref both VRFs. Also, note if this is the first time
2491 * any VRF is importing from "import_vrf".
2493 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2494 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2496 /* Check the import_vrf list of destination vrf for the source vrf name,
2499 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2501 if (strcmp(vname
, tmp_name
) == 0) {
2502 is_inst_match
= true;
2507 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2510 XFREE(MTYPE_TMP
, vname
);
2512 /* Check if the source vrf already exports to any vrf,
2513 * first time export requires to setup auto derived RD/RT values.
2514 * Add the destination vrf name to export vrf list if it is
2517 is_inst_match
= false;
2518 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2519 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2520 first_export
= true;
2522 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2524 if (strcmp(vname
, tmp_name
) == 0) {
2525 is_inst_match
= true;
2531 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2534 XFREE(MTYPE_TMP
, vname
);
2536 /* Update import RT for current VRF using export RT of the VRF we're
2537 * importing from. First though, make sure "import_vrf" has that
2541 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2542 &from_bgp
->vrf_prd_auto
);
2543 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2544 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2545 BGP_VPN_POLICY_TOVPN_RD_SET
);
2546 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
2548 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2549 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2550 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2551 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2552 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2553 BGP_PREVENT_VRF_2_VRF_LEAK
;
2555 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2556 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2557 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2558 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2559 .rtlist
[idir
], ecom
);
2561 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2562 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2565 const char *from_name
;
2566 char *ecom1
, *ecom2
;
2568 from_name
= from_bgp
->name
? from_bgp
->name
:
2571 ecom1
= ecommunity_ecom2str(
2572 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2573 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2575 ecom2
= ecommunity_ecom2str(
2576 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2577 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2580 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2581 __func__
, from_name
, export_name
, first_export
, ecom1
,
2584 ecommunity_strfree(&ecom1
);
2585 ecommunity_strfree(&ecom2
);
2588 /* Does "import_vrf" first need to export its routes or that
2589 * is already done and we just need to import those routes
2590 * from the global table?
2593 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2595 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2598 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2599 afi_t afi
, safi_t safi
)
2601 const char *export_name
, *tmp_name
;
2602 enum vpn_policy_direction idir
, edir
;
2604 struct ecommunity
*ecom
= NULL
;
2605 struct listnode
*node
;
2608 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2609 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2610 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2611 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2613 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2614 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2616 /* Were we importing from "import_vrf"? */
2617 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2619 if (strcmp(vname
, tmp_name
) == 0)
2624 * We do not check in the cli if the passed in bgp
2625 * instance is actually imported into us before
2626 * we call this function. As such if we do not
2627 * find this in the import_vrf list than
2628 * we just need to return safely.
2634 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2636 /* Remove "import_vrf" from our import list. */
2637 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2638 XFREE(MTYPE_TMP
, vname
);
2640 /* Remove routes imported from "import_vrf". */
2641 /* TODO: In the current logic, we have to first remove all
2642 * imported routes and then (if needed) import back routes
2644 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2646 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2647 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2648 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2649 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2650 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2651 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2653 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2655 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2656 (struct ecommunity_val
*)ecom
->val
);
2657 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2662 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2663 * below is checking for NULL that export_vrf can be
2664 * NULL, consequently it is complaining( like a cabbage )
2665 * that we could dereference and crash in the listcount(..)
2667 * So make it happy, under protest, with liberty and justice
2670 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2672 /* Remove us from "import_vrf's" export list. If no other VRF
2673 * is importing from "import_vrf", cleanup appropriately.
2675 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2677 if (strcmp(vname
, export_name
) == 0)
2682 * If we have gotten to this point then the vname must
2683 * exist. If not, we are in a world of trouble and
2684 * have slag sitting around.
2686 * import_vrf and export_vrf must match in having
2687 * the in/out names as appropriate.
2688 * export_vrf list could have been cleaned up
2689 * as part of no router bgp source instnace.
2694 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2695 XFREE(MTYPE_TMP
, vname
);
2697 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2698 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2699 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2700 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2701 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2702 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2703 sizeof(struct prefix_rd
));
2704 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2705 BGP_VPN_POLICY_TOVPN_RD_SET
);
2706 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2711 /* For testing purpose, static route of MPLS-VPN. */
2712 DEFUN (vpnv4_network
,
2714 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2715 "Specify a network to announce via BGP\n"
2717 "Specify Route Distinguisher\n"
2718 "VPN Route Distinguisher\n"
2719 "VPN NLRI label (tag)\n"
2720 "VPN NLRI label (tag)\n"
2723 int idx_ipv4_prefixlen
= 1;
2724 int idx_ext_community
= 3;
2726 return bgp_static_set_safi(
2727 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2728 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
2729 NULL
, NULL
, NULL
, NULL
);
2732 DEFUN (vpnv4_network_route_map
,
2733 vpnv4_network_route_map_cmd
,
2734 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
2735 "Specify a network to announce via BGP\n"
2737 "Specify Route Distinguisher\n"
2738 "VPN Route Distinguisher\n"
2739 "VPN NLRI label (tag)\n"
2740 "VPN NLRI label (tag)\n"
2745 int idx_ipv4_prefixlen
= 1;
2746 int idx_ext_community
= 3;
2749 return bgp_static_set_safi(
2750 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2751 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2752 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2755 /* For testing purpose, static route of MPLS-VPN. */
2756 DEFUN (no_vpnv4_network
,
2757 no_vpnv4_network_cmd
,
2758 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2760 "Specify a network to announce via BGP\n"
2762 "Specify Route Distinguisher\n"
2763 "VPN Route Distinguisher\n"
2764 "VPN NLRI label (tag)\n"
2765 "VPN NLRI label (tag)\n"
2768 int idx_ipv4_prefixlen
= 2;
2769 int idx_ext_community
= 4;
2771 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
2772 argv
[idx_ipv4_prefixlen
]->arg
,
2773 argv
[idx_ext_community
]->arg
,
2774 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2777 DEFUN (vpnv6_network
,
2779 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
2780 "Specify a network to announce via BGP\n"
2781 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2782 "Specify Route Distinguisher\n"
2783 "VPN Route Distinguisher\n"
2784 "VPN NLRI label (tag)\n"
2785 "VPN NLRI label (tag)\n"
2790 int idx_ipv6_prefix
= 1;
2791 int idx_ext_community
= 3;
2795 return bgp_static_set_safi(
2796 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2797 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2798 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2800 return bgp_static_set_safi(
2801 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2802 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2803 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2806 /* For testing purpose, static route of MPLS-VPN. */
2807 DEFUN (no_vpnv6_network
,
2808 no_vpnv6_network_cmd
,
2809 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2811 "Specify a network to announce via BGP\n"
2812 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2813 "Specify Route Distinguisher\n"
2814 "VPN Route Distinguisher\n"
2815 "VPN NLRI label (tag)\n"
2816 "VPN NLRI label (tag)\n"
2819 int idx_ipv6_prefix
= 2;
2820 int idx_ext_community
= 4;
2822 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2823 argv
[idx_ipv6_prefix
]->arg
,
2824 argv
[idx_ext_community
]->arg
,
2825 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2828 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2829 enum bgp_show_type type
, void *output_arg
, int tags
,
2833 struct bgp_table
*table
;
2835 bgp
= bgp_get_default();
2838 vty_out(vty
, "No BGP process is configured\n");
2840 vty_out(vty
, "{}\n");
2843 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2844 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2845 output_arg
, use_json
);
2848 DEFUN (show_bgp_ip_vpn_all_rd
,
2849 show_bgp_ip_vpn_all_rd_cmd
,
2850 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2854 "Display VPN NLRI specific information\n"
2855 "Display VPN NLRI specific information\n"
2856 "Display information for a route distinguisher\n"
2857 "VPN Route Distinguisher\n"
2858 "All VPN Route Distinguishers\n"
2862 struct prefix_rd prd
;
2866 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2867 /* Constrain search if user supplies RD && RD != "all" */
2868 if (argv_find(argv
, argc
, "rd", &idx
)
2869 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
2870 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2873 "%% Malformed Route Distinguisher\n");
2876 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2877 bgp_show_type_normal
, NULL
, 0,
2878 use_json(argc
, argv
));
2880 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2881 bgp_show_type_normal
, NULL
, 0,
2882 use_json(argc
, argv
));
2888 ALIAS(show_bgp_ip_vpn_all_rd
,
2889 show_bgp_ip_vpn_rd_cmd
,
2890 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2894 "Display VPN NLRI specific information\n"
2895 "Display information for a route distinguisher\n"
2896 "VPN Route Distinguisher\n"
2897 "All VPN Route Distinguishers\n"
2900 #ifdef KEEP_OLD_VPN_COMMANDS
2901 DEFUN (show_ip_bgp_vpn_rd
,
2902 show_ip_bgp_vpn_rd_cmd
,
2903 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2909 "Display information for a route distinguisher\n"
2910 "VPN Route Distinguisher\n"
2911 "All VPN Route Distinguishers\n")
2913 int idx_ext_community
= argc
- 1;
2915 struct prefix_rd prd
;
2919 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2920 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2921 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2922 bgp_show_type_normal
, NULL
, 0,
2924 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2926 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2929 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2935 DEFUN (show_ip_bgp_vpn_all
,
2936 show_ip_bgp_vpn_all_cmd
,
2937 "show [ip] bgp <vpnv4|vpnv6>",
2946 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2947 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2952 DEFUN (show_ip_bgp_vpn_all_tags
,
2953 show_ip_bgp_vpn_all_tags_cmd
,
2954 "show [ip] bgp <vpnv4|vpnv6> all tags",
2959 "Display information about all VPNv4/VPNV6 NLRIs\n"
2960 "Display BGP tags for prefixes\n")
2965 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2966 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2971 DEFUN (show_ip_bgp_vpn_rd_tags
,
2972 show_ip_bgp_vpn_rd_tags_cmd
,
2973 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2978 "Display information for a route distinguisher\n"
2979 "VPN Route Distinguisher\n"
2980 "All VPN Route Distinguishers\n"
2981 "Display BGP tags for prefixes\n")
2983 int idx_ext_community
= 5;
2985 struct prefix_rd prd
;
2989 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2990 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2991 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2992 bgp_show_type_normal
, NULL
, 1,
2994 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2996 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2999 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
3005 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
3006 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
3007 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
3012 "Display information about all VPNv4/VPNv6 NLRIs\n"
3013 "Detailed information on TCP and BGP neighbor connections\n"
3014 "Neighbor to display information about\n"
3015 "Display routes learned from neighbor\n"
3022 bool uj
= use_json(argc
, argv
);
3026 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3027 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3030 json_object
*json_no
= NULL
;
3031 json_no
= json_object_new_object();
3032 json_object_string_add(json_no
, "warning",
3033 "Malformed address");
3034 vty_out(vty
, "%s\n",
3035 json_object_to_json_string(json_no
));
3036 json_object_free(json_no
);
3038 vty_out(vty
, "Malformed address: %s\n",
3039 argv
[idx_ipv4
]->arg
);
3043 peer
= peer_lookup(NULL
, &su
);
3044 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3046 json_object
*json_no
= NULL
;
3047 json_no
= json_object_new_object();
3048 json_object_string_add(
3050 "No such neighbor or address family");
3051 vty_out(vty
, "%s\n",
3052 json_object_to_json_string(json_no
));
3053 json_object_free(json_no
);
3056 "%% No such neighbor or address family\n");
3060 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
3066 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
3067 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
3068 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
3073 "Display information for a route distinguisher\n"
3074 "VPN Route Distinguisher\n"
3075 "All VPN Route Distinguishers\n"
3076 "Detailed information on TCP and BGP neighbor connections\n"
3077 "Neighbor to display information about\n"
3078 "Display routes learned from neighbor\n"
3081 int idx_ext_community
= 5;
3086 struct prefix_rd prd
;
3087 bool prefix_rd_all
= false;
3088 bool uj
= use_json(argc
, argv
);
3092 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3093 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3094 prefix_rd_all
= true;
3096 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3099 json_object
*json_no
= NULL
;
3100 json_no
= json_object_new_object();
3101 json_object_string_add(
3103 "Malformed Route Distinguisher");
3104 vty_out(vty
, "%s\n",
3105 json_object_to_json_string(
3107 json_object_free(json_no
);
3110 "%% Malformed Route Distinguisher\n");
3115 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3118 json_object
*json_no
= NULL
;
3119 json_no
= json_object_new_object();
3120 json_object_string_add(json_no
, "warning",
3121 "Malformed address");
3122 vty_out(vty
, "%s\n",
3123 json_object_to_json_string(json_no
));
3124 json_object_free(json_no
);
3126 vty_out(vty
, "Malformed address: %s\n",
3127 argv
[idx_ext_community
]->arg
);
3131 peer
= peer_lookup(NULL
, &su
);
3132 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3134 json_object
*json_no
= NULL
;
3135 json_no
= json_object_new_object();
3136 json_object_string_add(
3138 "No such neighbor or address family");
3139 vty_out(vty
, "%s\n",
3140 json_object_to_json_string(json_no
));
3141 json_object_free(json_no
);
3144 "%% No such neighbor or address family\n");
3149 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3150 bgp_show_type_neighbor
, &su
, 0,
3153 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
3154 bgp_show_type_neighbor
, &su
, 0,
3160 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
3161 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
3162 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
3167 "Display information about all VPNv4/VPNv6 NLRIs\n"
3168 "Detailed information on TCP and BGP neighbor connections\n"
3169 "Neighbor to display information about\n"
3170 "Display the routes advertised to a BGP neighbor\n"
3177 bool uj
= use_json(argc
, argv
);
3181 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3182 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3185 json_object
*json_no
= NULL
;
3186 json_no
= json_object_new_object();
3187 json_object_string_add(json_no
, "warning",
3188 "Malformed address");
3189 vty_out(vty
, "%s\n",
3190 json_object_to_json_string(json_no
));
3191 json_object_free(json_no
);
3193 vty_out(vty
, "Malformed address: %s\n",
3194 argv
[idx_ipv4
]->arg
);
3197 peer
= peer_lookup(NULL
, &su
);
3198 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3200 json_object
*json_no
= NULL
;
3201 json_no
= json_object_new_object();
3202 json_object_string_add(
3204 "No such neighbor or address family");
3205 vty_out(vty
, "%s\n",
3206 json_object_to_json_string(json_no
));
3207 json_object_free(json_no
);
3210 "%% No such neighbor or address family\n");
3213 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3219 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
3220 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
3221 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
3226 "Display information for a route distinguisher\n"
3227 "VPN Route Distinguisher\n"
3228 "All VPN Route Distinguishers\n"
3229 "Detailed information on TCP and BGP neighbor connections\n"
3230 "Neighbor to display information about\n"
3231 "Display the routes advertised to a BGP neighbor\n"
3234 int idx_ext_community
= 5;
3238 struct prefix_rd prd
;
3240 bool uj
= use_json(argc
, argv
);
3244 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3245 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3248 json_object
*json_no
= NULL
;
3249 json_no
= json_object_new_object();
3250 json_object_string_add(json_no
, "warning",
3251 "Malformed address");
3252 vty_out(vty
, "%s\n",
3253 json_object_to_json_string(json_no
));
3254 json_object_free(json_no
);
3256 vty_out(vty
, "Malformed address: %s\n",
3257 argv
[idx_ext_community
]->arg
);
3260 peer
= peer_lookup(NULL
, &su
);
3261 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3263 json_object
*json_no
= NULL
;
3264 json_no
= json_object_new_object();
3265 json_object_string_add(
3267 "No such neighbor or address family");
3268 vty_out(vty
, "%s\n",
3269 json_object_to_json_string(json_no
));
3270 json_object_free(json_no
);
3273 "%% No such neighbor or address family\n");
3277 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3278 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3280 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3283 json_object
*json_no
= NULL
;
3284 json_no
= json_object_new_object();
3285 json_object_string_add(
3287 "Malformed Route Distinguisher");
3288 vty_out(vty
, "%s\n",
3289 json_object_to_json_string(json_no
));
3290 json_object_free(json_no
);
3293 "%% Malformed Route Distinguisher\n");
3297 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
3302 #endif /* KEEP_OLD_VPN_COMMANDS */
3304 void bgp_mplsvpn_init(void)
3306 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
3307 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
3308 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
3310 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
3311 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
3313 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
3314 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
3315 #ifdef KEEP_OLD_VPN_COMMANDS
3316 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
3317 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
3318 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
3319 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
3320 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
3321 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
3322 install_element(VIEW_NODE
,
3323 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
3324 install_element(VIEW_NODE
,
3325 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
3326 #endif /* KEEP_OLD_VPN_COMMANDS */
3329 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
3331 struct listnode
*mnode
, *mnnode
;
3335 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
3338 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
3339 struct ecommunity
*ec
;
3341 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3344 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
3346 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
3349 if (ecommunity_include(ec
, eckey
))
3356 * The purpose of this function is to process leaks that were deferred
3357 * from earlier per-vrf configuration due to not-yet-existing default
3358 * vrf, in other words, configuration such as:
3360 * router bgp MMM vrf FOO
3361 * address-family ipv4 unicast
3363 * exit-address-family
3368 * This function gets called when the default instance ("router bgp NNN")
3371 void vpn_leak_postchange_all(void)
3373 struct listnode
*next
;
3375 struct bgp
*bgp_default
= bgp_get_default();
3377 assert(bgp_default
);
3379 /* First, do any exporting from VRFs to the single VPN RIB */
3380 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3382 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3385 vpn_leak_postchange(
3386 BGP_VPN_POLICY_DIR_TOVPN
,
3391 vpn_leak_postchange(
3392 BGP_VPN_POLICY_DIR_TOVPN
,
3398 /* Now, do any importing to VRFs from the single VPN RIB */
3399 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3401 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3404 vpn_leak_postchange(
3405 BGP_VPN_POLICY_DIR_FROMVPN
,
3410 vpn_leak_postchange(
3411 BGP_VPN_POLICY_DIR_FROMVPN
,
3418 /* When a bgp vrf instance is unconfigured, remove its routes
3419 * from the VPN table and this vrf could be importing routes from other
3420 * bgp vrf instnaces, unimport them.
3421 * VRF X and VRF Y are exporting routes to each other.
3422 * When VRF X is deleted, unimport its routes from all target vrfs,
3423 * also VRF Y should unimport its routes from VRF X table.
3424 * This will ensure VPN table is cleaned up appropriately.
3426 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
3429 const char *tmp_name
;
3431 struct listnode
*node
, *next
;
3432 safi_t safi
= SAFI_UNICAST
;
3434 bool is_vrf_leak_bind
;
3437 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3440 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3441 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3443 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3445 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3446 /* vrf leak is for IPv4 and IPv6 Unicast only */
3447 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3450 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3451 if (from_bgp
== to_bgp
)
3454 /* Unimport and remove source vrf from the
3455 * other vrfs import list.
3457 struct vpn_policy
*to_vpolicy
;
3459 is_vrf_leak_bind
= false;
3460 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3461 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
3463 if (strcmp(vname
, tmp_name
) == 0) {
3464 is_vrf_leak_bind
= true;
3468 /* skip this bgp instance as there is no leak to this
3471 if (!is_vrf_leak_bind
)
3475 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3476 __func__
, from_bgp
->name_pretty
,
3477 to_bgp
->name_pretty
, afi2str(afi
),
3478 to_vpolicy
->import_vrf
->count
);
3480 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
3482 /* readd vrf name as unimport removes import vrf name
3483 * from the destination vrf's import list where the
3484 * `import vrf` configuration still exist.
3486 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
3487 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
3489 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
3490 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
3492 /* If to_bgp exports its routes to the bgp vrf
3493 * which is being deleted, un-import the
3494 * to_bgp routes from VPN.
3496 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3499 if (strcmp(vname
, tmp_name
) == 0) {
3500 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3510 /* When a router bgp is configured, there could be a bgp vrf
3511 * instance importing routes from this newly configured
3512 * bgp vrf instance. Export routes from configured
3514 * VRF Y has import from bgp vrf x,
3515 * when a bgp vrf x instance is created, export its routes
3516 * to VRF Y instance.
3518 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3521 const char *export_name
;
3523 struct listnode
*node
, *next
;
3524 struct ecommunity
*ecom
;
3525 enum vpn_policy_direction idir
, edir
;
3526 safi_t safi
= SAFI_UNICAST
;
3530 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3531 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3533 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3534 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3536 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3538 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3539 /* vrf leak is for IPv4 and IPv6 Unicast only */
3540 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3543 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3544 if (from_bgp
== to_bgp
)
3547 /* bgp instance has import list, check to see if newly
3548 * configured bgp instance is the list.
3550 struct vpn_policy
*to_vpolicy
;
3552 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3553 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3555 if (strcmp(vname
, export_name
) != 0)
3559 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3561 export_name
, to_bgp
->name_pretty
);
3563 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3564 /* remove import rt, it will be readded
3565 * as part of import from vrf.
3569 to_vpolicy
->rtlist
[idir
],
3570 (struct ecommunity_val
*)
3572 vrf_import_from_vrf(to_bgp
, from_bgp
,