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
;
373 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
375 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
376 __func__
, bgp
->name_pretty
, afi2str(afi
));
380 tovpn_sid
= bgp
->vpn_policy
[afi
].tovpn_sid
;
383 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__
,
384 bgp
->name_pretty
, afi2str(afi
));
389 inet_ntop(AF_INET6
, tovpn_sid
, buf
, sizeof(buf
));
390 zlog_debug("%s: vrf %s: afi %s: setting sid %s for vrf id %d",
391 __func__
, bgp
->name_pretty
, afi2str(afi
), buf
,
395 vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
399 ctx
.table
= vrf
->data
.l
.table_id
;
400 act
= afi
== AFI_IP
? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
401 : ZEBRA_SEG6_LOCAL_ACTION_END_DT6
;
402 zclient_send_localsid(zclient
, tovpn_sid
, bgp
->vrf_id
, act
, &ctx
);
404 tovpn_sid_ls
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
405 *tovpn_sid_ls
= *tovpn_sid
;
406 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
= tovpn_sid_ls
;
410 * This function informs zebra of the srv6-function this vrf sets on routes
411 * leaked to VPN. Zebra should install this srv6-function in the kernel with
412 * an action of "End.DT46's IP FIB to route the PDU."
414 void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp
*bgp
)
416 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
417 enum seg6local_action_t act
;
418 struct seg6local_context ctx
= {};
419 struct in6_addr
*tovpn_sid
= NULL
;
420 struct in6_addr
*tovpn_sid_ls
= NULL
;
423 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
426 "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
427 __func__
, bgp
->name_pretty
);
431 tovpn_sid
= bgp
->tovpn_sid
;
434 zlog_debug("%s: vrf %s: sid not set", __func__
,
440 zlog_debug("%s: vrf %s: setting sid %pI6 for vrf id %d",
441 __func__
, bgp
->name_pretty
, tovpn_sid
, bgp
->vrf_id
);
443 vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
447 ctx
.table
= vrf
->data
.l
.table_id
;
448 act
= ZEBRA_SEG6_LOCAL_ACTION_END_DT46
;
449 zclient_send_localsid(zclient
, tovpn_sid
, bgp
->vrf_id
, act
, &ctx
);
451 tovpn_sid_ls
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
452 *tovpn_sid_ls
= *tovpn_sid
;
453 bgp
->tovpn_zebra_vrf_sid_last_sent
= tovpn_sid_ls
;
457 * This function informs zebra of the srv6-function this vrf sets on routes
458 * leaked to VPN. Zebra should install this srv6-function in the kernel with
459 * an action of "End.DT4/6/46's IP FIB to route the PDU."
461 void vpn_leak_zebra_vrf_sid_update(struct bgp
*bgp
, afi_t afi
)
463 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
465 if (bgp
->vpn_policy
[afi
].tovpn_sid
)
466 return vpn_leak_zebra_vrf_sid_update_per_af(bgp
, afi
);
469 return vpn_leak_zebra_vrf_sid_update_per_vrf(bgp
);
472 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__
,
473 bgp
->name_pretty
, afi2str(afi
));
477 * If zebra tells us vrf has become unconfigured, tell zebra not to
478 * use this srv6-function to forward to the vrf anymore
480 void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp
*bgp
, afi_t afi
)
482 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
484 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
486 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
487 __func__
, bgp
->name_pretty
, afi2str(afi
));
492 zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__
,
493 bgp
->name_pretty
, bgp
->vrf_id
);
495 zclient_send_localsid(zclient
,
496 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
,
497 bgp
->vrf_id
, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
, NULL
);
498 XFREE(MTYPE_BGP_SRV6_SID
,
499 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
);
503 * If zebra tells us vrf has become unconfigured, tell zebra not to
504 * use this srv6-function to forward to the vrf anymore
506 void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp
*bgp
)
508 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
510 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
513 "%s: vrf %s: vrf_id not set, can't set zebra vrf label",
514 __func__
, bgp
->name_pretty
);
519 zlog_debug("%s: deleting sid for vrf %s (id=%d)", __func__
,
520 bgp
->name_pretty
, bgp
->vrf_id
);
522 zclient_send_localsid(zclient
, bgp
->tovpn_zebra_vrf_sid_last_sent
,
523 bgp
->vrf_id
, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
,
525 XFREE(MTYPE_BGP_SRV6_SID
, bgp
->tovpn_zebra_vrf_sid_last_sent
);
529 * If zebra tells us vrf has become unconfigured, tell zebra not to
530 * use this srv6-function to forward to the vrf anymore
532 void vpn_leak_zebra_vrf_sid_withdraw(struct bgp
*bgp
, afi_t afi
)
534 if (bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
)
535 vpn_leak_zebra_vrf_sid_withdraw_per_af(bgp
, afi
);
537 if (bgp
->tovpn_zebra_vrf_sid_last_sent
)
538 vpn_leak_zebra_vrf_sid_withdraw_per_vrf(bgp
);
541 int vpn_leak_label_callback(
546 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
547 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
550 zlog_debug("%s: label=%u, allocated=%d",
551 __func__
, label
, allocated
);
555 * previously-allocated label is now invalid
557 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
558 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
560 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
561 vp
->afi
, bgp_get_default(), vp
->bgp
);
562 vp
->tovpn_label
= MPLS_LABEL_NONE
;
563 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
564 vp
->afi
, bgp_get_default(), vp
->bgp
);
570 * New label allocation
572 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
575 * not currently configured for auto label, reject allocation
580 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
581 if (label
== vp
->tovpn_label
) {
582 /* already have same label, accept but do nothing */
585 /* Shouldn't happen: different label allocation */
586 flog_err(EC_BGP_LABEL
,
587 "%s: %s had label %u but got new assignment %u",
588 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
593 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
594 vp
->afi
, bgp_get_default(), vp
->bgp
);
595 vp
->tovpn_label
= label
;
596 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
597 vp
->afi
, bgp_get_default(), vp
->bgp
);
602 static void sid_register(struct bgp
*bgp
, const struct in6_addr
*sid
,
603 const char *locator_name
)
605 struct bgp_srv6_function
*func
;
606 func
= XCALLOC(MTYPE_BGP_SRV6_FUNCTION
,
607 sizeof(struct bgp_srv6_function
));
609 snprintf(func
->locator_name
, sizeof(func
->locator_name
),
611 listnode_add(bgp
->srv6_functions
, func
);
614 static void sid_unregister(struct bgp
*bgp
, const struct in6_addr
*sid
)
616 struct listnode
*node
, *nnode
;
617 struct bgp_srv6_function
*func
;
619 for (ALL_LIST_ELEMENTS(bgp
->srv6_functions
, node
, nnode
, func
))
620 if (sid_same(&func
->sid
, sid
)) {
621 listnode_delete(bgp
->srv6_functions
, func
);
622 XFREE(MTYPE_BGP_SRV6_FUNCTION
, func
);
626 static bool sid_exist(struct bgp
*bgp
, const struct in6_addr
*sid
)
628 struct listnode
*node
;
629 struct bgp_srv6_function
*func
;
631 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_functions
, node
, func
))
632 if (sid_same(&func
->sid
, sid
))
638 * This function generates a new SID based on bgp->srv6_locator_chunks and
639 * index. The locator and generated SID are stored in arguments sid_locator
640 * and sid, respectively.
642 * if index != 0: try to allocate as index-mode
643 * else: try to allocate as auto-mode
645 static uint32_t alloc_new_sid(struct bgp
*bgp
, uint32_t index
,
646 struct srv6_locator_chunk
*sid_locator_chunk
,
647 struct in6_addr
*sid
)
649 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
650 struct listnode
*node
;
651 struct srv6_locator_chunk
*chunk
;
652 bool alloced
= false;
655 uint8_t func_len
= 0, shift_len
= 0;
656 uint32_t index_max
= 0;
658 if (!bgp
|| !sid_locator_chunk
|| !sid
)
661 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_locator_chunks
, node
, chunk
)) {
662 if (chunk
->function_bits_length
>
663 BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
) {
666 "%s: invalid SRv6 Locator chunk (%pFX): Function Length must be less or equal to %d",
667 __func__
, &chunk
->prefix
,
668 BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
);
672 index_max
= (1 << chunk
->function_bits_length
) - 1;
674 if (index
> index_max
) {
677 "%s: skipped SRv6 Locator chunk (%pFX): Function Length is too short to support specified index (%u)",
678 __func__
, &chunk
->prefix
, index
);
682 *sid
= chunk
->prefix
.prefix
;
683 *sid_locator_chunk
= *chunk
;
684 offset
= chunk
->block_bits_length
+ chunk
->node_bits_length
;
685 func_len
= chunk
->function_bits_length
;
686 shift_len
= BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
- func_len
;
689 label
= index
<< 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
,
699 transpose_sid(sid
, label
, offset
, func_len
);
700 if (sid_exist(bgp
, sid
))
706 for (uint32_t i
= 1; i
< index_max
; i
++) {
707 label
= i
<< shift_len
;
708 if (label
< MPLS_LABEL_UNRESERVED_MIN
) {
711 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
712 __func__
, &chunk
->prefix
,
716 transpose_sid(sid
, label
, offset
, func_len
);
717 if (sid_exist(bgp
, sid
))
727 sid_register(bgp
, sid
, bgp
->srv6_locator_name
);
731 void ensure_vrf_tovpn_sid_per_af(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
,
734 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
736 struct srv6_locator_chunk
*tovpn_sid_locator
;
737 struct in6_addr
*tovpn_sid
;
738 uint32_t tovpn_sid_index
= 0, tovpn_sid_transpose_label
;
739 bool tovpn_sid_auto
= false;
742 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
743 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
745 /* skip when tovpn sid is already allocated on vrf instance */
746 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
)
750 * skip when bgp vpn instance ins't allocated
751 * or srv6 locator chunk isn't allocated
753 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
756 tovpn_sid_index
= bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
;
757 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
758 BGP_VPN_POLICY_TOVPN_SID_AUTO
);
760 /* skip when VPN isn't configured on vrf-instance */
761 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
764 /* check invalid case both configured index and auto */
765 if (tovpn_sid_index
!= 0 && tovpn_sid_auto
) {
766 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
771 tovpn_sid_locator
= srv6_locator_chunk_alloc();
772 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
774 tovpn_sid_transpose_label
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
,
775 tovpn_sid_locator
, tovpn_sid
);
777 if (tovpn_sid_transpose_label
== 0) {
780 "%s: not allocated new sid for vrf %s: afi %s",
781 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
782 srv6_locator_chunk_free(tovpn_sid_locator
);
783 XFREE(MTYPE_BGP_SRV6_SID
, tovpn_sid
);
788 inet_ntop(AF_INET6
, tovpn_sid
, buf
, sizeof(buf
));
789 zlog_debug("%s: new sid %s allocated for vrf %s: afi %s",
790 __func__
, buf
, bgp_vrf
->name_pretty
,
794 bgp_vrf
->vpn_policy
[afi
].tovpn_sid
= tovpn_sid
;
795 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
= tovpn_sid_locator
;
796 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
=
797 tovpn_sid_transpose_label
;
800 void ensure_vrf_tovpn_sid_per_vrf(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
)
802 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
803 struct srv6_locator_chunk
*tovpn_sid_locator
;
804 struct in6_addr
*tovpn_sid
;
805 uint32_t tovpn_sid_index
= 0, tovpn_sid_transpose_label
;
806 bool tovpn_sid_auto
= false;
809 zlog_debug("%s: try to allocate new SID for vrf %s", __func__
,
810 bgp_vrf
->name_pretty
);
812 /* skip when tovpn sid is already allocated on vrf instance */
813 if (bgp_vrf
->tovpn_sid
)
817 * skip when bgp vpn instance ins't allocated
818 * or srv6 locator chunk isn't allocated
820 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
823 tovpn_sid_index
= bgp_vrf
->tovpn_sid_index
;
824 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_TOVPN_SID_AUTO
);
826 /* skip when VPN isn't configured on vrf-instance */
827 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
830 /* check invalid case both configured index and auto */
831 if (tovpn_sid_index
!= 0 && tovpn_sid_auto
) {
832 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
837 tovpn_sid_locator
= srv6_locator_chunk_alloc();
838 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
840 tovpn_sid_transpose_label
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
,
841 tovpn_sid_locator
, tovpn_sid
);
843 if (tovpn_sid_transpose_label
== 0) {
845 zlog_debug("%s: not allocated new sid for vrf %s",
846 __func__
, bgp_vrf
->name_pretty
);
847 srv6_locator_chunk_free(tovpn_sid_locator
);
848 XFREE(MTYPE_BGP_SRV6_SID
, tovpn_sid
);
853 zlog_debug("%s: new sid %pI6 allocated for vrf %s", __func__
,
854 tovpn_sid
, bgp_vrf
->name_pretty
);
856 bgp_vrf
->tovpn_sid
= tovpn_sid
;
857 bgp_vrf
->tovpn_sid_locator
= tovpn_sid_locator
;
858 bgp_vrf
->tovpn_sid_transpose_label
= tovpn_sid_transpose_label
;
861 void ensure_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
864 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
!= 0 ||
865 CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
866 BGP_VPN_POLICY_TOVPN_SID_AUTO
))
867 return ensure_vrf_tovpn_sid_per_af(bgp_vpn
, bgp_vrf
, afi
);
870 if (bgp_vrf
->tovpn_sid_index
!= 0 ||
871 CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_TOVPN_SID_AUTO
))
872 return ensure_vrf_tovpn_sid_per_vrf(bgp_vpn
, bgp_vrf
);
875 void delete_vrf_tovpn_sid_per_af(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
,
878 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
879 uint32_t tovpn_sid_index
= 0;
880 bool tovpn_sid_auto
= false;
883 zlog_debug("%s: try to remove SID for vrf %s: afi %s", __func__
,
884 bgp_vrf
->name_pretty
, afi2str(afi
));
886 tovpn_sid_index
= bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
;
887 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
888 BGP_VPN_POLICY_TOVPN_SID_AUTO
);
890 /* skip when VPN is configured on vrf-instance */
891 if (tovpn_sid_index
!= 0 || tovpn_sid_auto
)
894 srv6_locator_chunk_free(bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
);
895 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
= NULL
;
897 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
) {
898 sid_unregister(bgp_vrf
, bgp_vrf
->vpn_policy
[afi
].tovpn_sid
);
899 XFREE(MTYPE_BGP_SRV6_SID
, bgp_vrf
->vpn_policy
[afi
].tovpn_sid
);
901 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
= 0;
904 void delete_vrf_tovpn_sid_per_vrf(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
)
906 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
907 uint32_t tovpn_sid_index
= 0;
908 bool tovpn_sid_auto
= false;
911 zlog_debug("%s: try to remove SID for vrf %s", __func__
,
912 bgp_vrf
->name_pretty
);
914 tovpn_sid_index
= bgp_vrf
->tovpn_sid_index
;
916 CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VPN_POLICY_TOVPN_SID_AUTO
);
918 /* skip when VPN is configured on vrf-instance */
919 if (tovpn_sid_index
!= 0 || tovpn_sid_auto
)
922 srv6_locator_chunk_free(bgp_vrf
->tovpn_sid_locator
);
923 bgp_vrf
->tovpn_sid_locator
= NULL
;
925 if (bgp_vrf
->tovpn_sid
) {
926 sid_unregister(bgp_vrf
, bgp_vrf
->tovpn_sid
);
927 XFREE(MTYPE_BGP_SRV6_SID
, bgp_vrf
->tovpn_sid
);
929 bgp_vrf
->tovpn_sid_transpose_label
= 0;
932 void delete_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
934 delete_vrf_tovpn_sid_per_af(bgp_vpn
, bgp_vrf
, afi
);
935 delete_vrf_tovpn_sid_per_vrf(bgp_vpn
, bgp_vrf
);
939 * This function embeds upper `len` bits of `label` in `sid`,
940 * starting at offset `offset` as seen from the MSB of `sid`.
942 * e.g. Given that `label` is 0x12345 and `len` is 16,
943 * then `label` will be embedded in `sid` as follows:
946 * label: 0001 0002 0003 0004 0005
947 * sid: .... 0001 0002 0003 0004
953 * e.g. Given that `label` is 0x12345 and `len` is 8,
954 * `label` will be embedded in `sid` as follows:
957 * label: 0001 0002 0003 0004 0005
958 * sid: .... 0001 0002 0000 0000
964 void transpose_sid(struct in6_addr
*sid
, uint32_t label
, uint8_t offset
,
967 for (uint8_t idx
= 0; idx
< len
; idx
++) {
968 uint8_t tidx
= offset
+ idx
;
969 sid
->s6_addr
[tidx
/ 8] &= ~(0x1 << (7 - tidx
% 8));
970 if (label
>> (19 - idx
) & 0x1)
971 sid
->s6_addr
[tidx
/ 8] |= 0x1 << (7 - tidx
% 8);
975 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
987 if (n
!= bpi
->extra
->num_labels
)
990 for (i
= 0; i
< n
; ++i
) {
991 if (label
[i
] != bpi
->extra
->label
[i
])
998 * make encoded route labels match specified encoded label set
1000 static void setlabels(struct bgp_path_info
*bpi
,
1001 mpls_label_t
*label
, /* array of labels */
1002 uint32_t num_labels
)
1006 assert(num_labels
<= BGP_MAX_LABELS
);
1010 bpi
->extra
->num_labels
= 0;
1014 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
1017 for (i
= 0; i
< num_labels
; ++i
) {
1018 extra
->label
[i
] = label
[i
];
1019 if (!bgp_is_valid_label(&label
[i
])) {
1020 bgp_set_valid_label(&extra
->label
[i
]);
1023 extra
->num_labels
= num_labels
;
1027 * make encoded route SIDs match specified encoded sid set
1029 static void setsids(struct bgp_path_info
*bpi
,
1030 struct in6_addr
*sid
,
1034 struct bgp_path_info_extra
*extra
;
1038 assert(num_sids
<= BGP_MAX_SIDS
);
1042 bpi
->extra
->num_sids
= 0;
1046 extra
= bgp_path_info_extra_get(bpi
);
1047 for (i
= 0; i
< num_sids
; i
++)
1048 memcpy(&extra
->sid
[i
].sid
, &sid
[i
], sizeof(struct in6_addr
));
1049 extra
->num_sids
= num_sids
;
1052 static void unsetsids(struct bgp_path_info
*bpi
)
1054 struct bgp_path_info_extra
*extra
;
1056 extra
= bgp_path_info_extra_get(bpi
);
1057 extra
->num_sids
= 0;
1058 memset(extra
->sid
, 0, sizeof(extra
->sid
));
1061 static bool leak_update_nexthop_valid(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
1062 struct attr
*new_attr
, afi_t afi
,
1064 struct bgp_path_info
*source_bpi
,
1065 struct bgp_path_info
*bpi
,
1066 struct bgp
*bgp_orig
,
1067 const struct prefix
*p
, int debug
)
1069 struct bgp_path_info
*bpi_ultimate
;
1070 struct bgp
*bgp_nexthop
;
1073 bpi_ultimate
= bgp_get_imported_bpi_ultimate(source_bpi
);
1075 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
1076 bgp_nexthop
= bpi
->extra
->bgp_orig
;
1078 bgp_nexthop
= bgp_orig
;
1081 * No nexthop tracking for redistributed routes or for
1082 * EVPN-imported routes that get leaked.
1084 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
1085 is_pi_family_evpn(bpi_ultimate
))
1089 * TBD do we need to do anything about the
1090 * 'connected' parameter?
1092 nh_valid
= bgp_find_or_add_nexthop(to_bgp
, bgp_nexthop
, afi
,
1093 safi
, bpi
, NULL
, 0, p
);
1096 * If you are using SRv6 VPN instead of MPLS, it need to check
1097 * the SID allocation. If the sid is not allocated, the rib
1100 if (to_bgp
->srv6_enabled
&&
1101 (!new_attr
->srv6_l3vpn
&& !new_attr
->srv6_vpn
)) {
1106 zlog_debug("%s: %pFX nexthop is %svalid (in vrf %s)", __func__
,
1107 p
, (nh_valid
? "" : "not "),
1108 bgp_nexthop
->name_pretty
);
1114 * returns pointer to new bgp_path_info upon success
1116 static struct bgp_path_info
*
1117 leak_update(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
1118 struct attr
*new_attr
, /* already interned */
1119 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
1120 mpls_label_t
*label
, uint32_t num_labels
, struct bgp
*bgp_orig
,
1121 struct prefix
*nexthop_orig
, int nexthop_self_flag
, int debug
)
1123 const struct prefix
*p
= bgp_dest_get_prefix(bn
);
1124 struct bgp_path_info
*bpi
;
1125 struct bgp_path_info
*new;
1126 struct bgp_path_info_extra
*extra
;
1127 uint32_t num_sids
= 0;
1128 void *parent
= source_bpi
;
1130 if (new_attr
->srv6_l3vpn
|| new_attr
->srv6_vpn
)
1135 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
1136 __func__
, to_bgp
->name_pretty
, bn
, source_bpi
->type
,
1137 source_bpi
->sub_type
);
1140 * Routes that are redistributed into BGP from zebra do not get
1141 * nexthop tracking. However, if those routes are subsequently
1142 * imported to other RIBs within BGP, the leaked routes do not
1143 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
1144 * in order to determine if the route we are currently leaking
1145 * should have nexthop tracking, we must find the ultimate
1146 * parent so we can check its sub_type.
1148 * As of now, source_bpi may at most be a second-generation route
1149 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
1150 * Using a loop here supports more complex intra-bgp import-export
1151 * schemes that could be implemented in the future.
1158 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1159 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
1164 bool labelssame
= labels_same(bpi
, label
, num_labels
);
1166 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
1167 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
1170 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
1171 __func__
, to_bgp
->name_pretty
,
1172 source_bpi
->flags
, bpi
->flags
, p
);
1177 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
1178 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
1180 bgp_attr_unintern(&new_attr
);
1183 "%s: ->%s: %pBD: Found route, no change",
1184 __func__
, to_bgp
->name_pretty
, bn
);
1188 /* If the RT was changed via extended communities as an
1189 * import/export list, we should withdraw implicitly the old
1191 * For instance, RT list was modified using route-maps:
1192 * route-map test permit 10
1193 * set extcommunity rt none
1195 if (CHECK_FLAG(bpi
->attr
->flag
,
1196 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) &&
1197 CHECK_FLAG(new_attr
->flag
,
1198 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
1199 if (!ecommunity_cmp(
1200 bgp_attr_get_ecommunity(bpi
->attr
),
1201 bgp_attr_get_ecommunity(new_attr
))) {
1202 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1203 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
,
1205 bgp_path_info_delete(bn
, bpi
);
1209 /* attr is changed */
1210 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
1212 /* Rewrite BGP route information. */
1213 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1214 bgp_path_info_restore(bn
, bpi
);
1216 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1217 bgp_attr_unintern(&bpi
->attr
);
1218 bpi
->attr
= new_attr
;
1219 bpi
->uptime
= monotime(NULL
);
1225 setlabels(bpi
, label
, num_labels
);
1231 if (new_attr
->srv6_l3vpn
) {
1232 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
1235 extra
= bgp_path_info_extra_get(bpi
);
1237 extra
->sid
[0].loc_block_len
=
1238 new_attr
->srv6_l3vpn
->loc_block_len
;
1239 extra
->sid
[0].loc_node_len
=
1240 new_attr
->srv6_l3vpn
->loc_node_len
;
1241 extra
->sid
[0].func_len
=
1242 new_attr
->srv6_l3vpn
->func_len
;
1243 extra
->sid
[0].arg_len
=
1244 new_attr
->srv6_l3vpn
->arg_len
;
1245 extra
->sid
[0].transposition_len
=
1246 new_attr
->srv6_l3vpn
->transposition_len
;
1247 extra
->sid
[0].transposition_offset
=
1248 new_attr
->srv6_l3vpn
1249 ->transposition_offset
;
1250 } else if (new_attr
->srv6_vpn
)
1251 setsids(bpi
, &new_attr
->srv6_vpn
->sid
,
1256 if (nexthop_self_flag
)
1257 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
1259 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1260 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ACCEPT_OWN
);
1262 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1263 source_bpi
, bpi
, bgp_orig
, p
,
1265 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
1267 bgp_path_info_unset_flag(bn
, bpi
, BGP_PATH_VALID
);
1269 /* Process change. */
1270 bgp_aggregate_increment(to_bgp
, p
, bpi
, afi
, safi
);
1271 bgp_process(to_bgp
, bn
, afi
, safi
);
1272 bgp_dest_unlock_node(bn
);
1275 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
1276 __func__
, to_bgp
->name_pretty
, bn
);
1281 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
1284 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
1285 __func__
, to_bgp
->name_pretty
,
1286 source_bpi
->flags
, p
);
1291 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
1292 to_bgp
->peer_self
, new_attr
, bn
);
1294 if (source_bpi
->peer
) {
1295 extra
= bgp_path_info_extra_get(new);
1296 extra
->peer_orig
= peer_lock(source_bpi
->peer
);
1299 if (nexthop_self_flag
)
1300 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
1302 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1303 bgp_path_info_set_flag(bn
, new, BGP_PATH_ACCEPT_OWN
);
1305 bgp_path_info_extra_get(new);
1311 if (new_attr
->srv6_l3vpn
) {
1312 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
1314 extra
= bgp_path_info_extra_get(new);
1316 extra
->sid
[0].loc_block_len
=
1317 new_attr
->srv6_l3vpn
->loc_block_len
;
1318 extra
->sid
[0].loc_node_len
=
1319 new_attr
->srv6_l3vpn
->loc_node_len
;
1320 extra
->sid
[0].func_len
= new_attr
->srv6_l3vpn
->func_len
;
1321 extra
->sid
[0].arg_len
= new_attr
->srv6_l3vpn
->arg_len
;
1322 extra
->sid
[0].transposition_len
=
1323 new_attr
->srv6_l3vpn
->transposition_len
;
1324 extra
->sid
[0].transposition_offset
=
1325 new_attr
->srv6_l3vpn
->transposition_offset
;
1326 } else if (new_attr
->srv6_vpn
)
1327 setsids(new, &new_attr
->srv6_vpn
->sid
, num_sids
);
1332 setlabels(new, label
, num_labels
);
1334 new->extra
->parent
= bgp_path_info_lock(parent
);
1336 (struct bgp_dest
*)((struct bgp_path_info
*)parent
)->net
);
1338 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
1340 new->extra
->nexthop_orig
= *nexthop_orig
;
1342 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1343 source_bpi
, new, bgp_orig
, p
, debug
))
1344 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
1346 bgp_path_info_unset_flag(bn
, new, BGP_PATH_VALID
);
1348 bgp_aggregate_increment(to_bgp
, p
, new, afi
, safi
);
1349 bgp_path_info_add(bn
, new);
1351 bgp_dest_unlock_node(bn
);
1352 bgp_process(to_bgp
, bn
, afi
, safi
);
1355 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
1356 to_bgp
->name_pretty
, bn
);
1361 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1362 void vpn_leak_from_vrf_update(struct bgp
*to_bgp
, /* to */
1363 struct bgp
*from_bgp
, /* from */
1364 struct bgp_path_info
*path_vrf
) /* route */
1366 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1367 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1368 afi_t afi
= family2afi(p
->family
);
1369 struct attr static_attr
= {0};
1370 struct attr
*new_attr
= NULL
;
1371 safi_t safi
= SAFI_MPLS_VPN
;
1372 mpls_label_t label_val
;
1374 struct bgp_dest
*bn
;
1375 const char *debugmsg
;
1376 int nexthop_self_flag
= 0;
1379 zlog_debug("%s: from vrf %s", __func__
, from_bgp
->name_pretty
);
1381 if (debug
&& bgp_attr_get_ecommunity(path_vrf
->attr
)) {
1382 char *s
= ecommunity_ecom2str(
1383 bgp_attr_get_ecommunity(path_vrf
->attr
),
1384 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1386 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
1387 from_bgp
->name
, path_vrf
->type
, s
);
1388 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1396 zlog_debug("%s: can't get afi of prefix", __func__
);
1400 /* Is this route exportable into the VPN table? */
1401 if (!is_route_injectable_into_vpn(path_vrf
))
1404 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1406 zlog_debug("%s: %s skipping: %s", __func__
,
1407 from_bgp
->name
, debugmsg
);
1412 static_attr
= *path_vrf
->attr
;
1415 * route map handling
1417 if (from_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1418 struct bgp_path_info info
;
1419 route_map_result_t ret
;
1421 memset(&info
, 0, sizeof(info
));
1422 info
.peer
= to_bgp
->peer_self
;
1423 info
.attr
= &static_attr
;
1424 ret
= route_map_apply(from_bgp
->vpn_policy
[afi
]
1425 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1427 if (RMAP_DENYMATCH
== ret
) {
1428 bgp_attr_flush(&static_attr
); /* free any added parts */
1431 "%s: vrf %s route map \"%s\" says DENY, returning",
1432 __func__
, from_bgp
->name_pretty
,
1433 from_bgp
->vpn_policy
[afi
]
1434 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
1440 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1441 char *s
= ecommunity_ecom2str(
1442 bgp_attr_get_ecommunity(&static_attr
),
1443 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1445 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1447 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1451 * Add the vpn-policy rt-list
1453 struct ecommunity
*old_ecom
;
1454 struct ecommunity
*new_ecom
;
1456 /* Export with the 'from' instance's export RTs. */
1457 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1458 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1460 new_ecom
= ecommunity_dup(old_ecom
);
1461 if (CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1462 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1463 ecommunity_strip_rts(new_ecom
);
1464 new_ecom
= ecommunity_merge(
1465 new_ecom
, from_bgp
->vpn_policy
[afi
]
1466 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1467 if (!old_ecom
->refcnt
)
1468 ecommunity_free(&old_ecom
);
1470 new_ecom
= ecommunity_dup(
1471 from_bgp
->vpn_policy
[afi
]
1472 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1474 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1476 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1477 char *s
= ecommunity_ecom2str(
1478 bgp_attr_get_ecommunity(&static_attr
),
1479 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1481 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1483 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1486 community_strip_accept_own(&static_attr
);
1489 /* if policy nexthop not set, use 0 */
1490 if (CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1491 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1492 struct prefix
*nexthop
=
1493 &from_bgp
->vpn_policy
[afi
].tovpn_nexthop
;
1495 switch (nexthop
->family
) {
1497 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1499 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1501 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1502 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1506 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1507 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1514 if (!CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1515 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1516 if (afi
== AFI_IP
) {
1518 * For ipv4, copy to multiprotocol
1521 static_attr
.mp_nexthop_global_in
=
1522 static_attr
.nexthop
;
1523 static_attr
.mp_nexthop_len
=
1524 BGP_ATTR_NHLEN_IPV4
;
1526 * XXX Leave static_attr.nexthop
1530 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1533 /* Update based on next-hop family to account for
1534 * RFC 5549 (BGP unnumbered) scenario. Note that
1535 * specific action is only needed for the case of
1536 * IPv4 nexthops as the attr has been copied
1540 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1541 static_attr
.mp_nexthop_global_in
.s_addr
=
1542 static_attr
.nexthop
.s_addr
;
1543 static_attr
.mp_nexthop_len
=
1544 BGP_ATTR_NHLEN_IPV4
;
1546 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1549 nexthop_self_flag
= 1;
1552 label_val
= from_bgp
->vpn_policy
[afi
].tovpn_label
;
1553 if (label_val
== MPLS_LABEL_NONE
) {
1554 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1556 encode_label(label_val
, &label
);
1559 /* Set originator ID to "me" */
1560 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1561 static_attr
.originator_id
= to_bgp
->router_id
;
1563 /* Set SID for SRv6 VPN */
1564 if (from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
) {
1566 from_bgp
->vpn_policy
[afi
].tovpn_sid_transpose_label
,
1568 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1569 sizeof(struct bgp_attr_srv6_l3vpn
));
1570 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1571 static_attr
.srv6_l3vpn
->endpoint_behavior
= 0xffff;
1572 static_attr
.srv6_l3vpn
->loc_block_len
=
1573 from_bgp
->vpn_policy
[afi
]
1574 .tovpn_sid_locator
->block_bits_length
;
1575 static_attr
.srv6_l3vpn
->loc_node_len
=
1576 from_bgp
->vpn_policy
[afi
]
1577 .tovpn_sid_locator
->node_bits_length
;
1578 static_attr
.srv6_l3vpn
->func_len
=
1579 from_bgp
->vpn_policy
[afi
]
1580 .tovpn_sid_locator
->function_bits_length
;
1581 static_attr
.srv6_l3vpn
->arg_len
=
1582 from_bgp
->vpn_policy
[afi
]
1583 .tovpn_sid_locator
->argument_bits_length
;
1584 static_attr
.srv6_l3vpn
->transposition_len
=
1585 from_bgp
->vpn_policy
[afi
]
1586 .tovpn_sid_locator
->function_bits_length
;
1587 static_attr
.srv6_l3vpn
->transposition_offset
=
1588 from_bgp
->vpn_policy
[afi
]
1589 .tovpn_sid_locator
->block_bits_length
+
1590 from_bgp
->vpn_policy
[afi
]
1591 .tovpn_sid_locator
->node_bits_length
;
1593 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1594 &from_bgp
->vpn_policy
[afi
]
1595 .tovpn_sid_locator
->prefix
.prefix
,
1596 sizeof(struct in6_addr
));
1597 } else if (from_bgp
->tovpn_sid_locator
) {
1598 encode_label(from_bgp
->tovpn_sid_transpose_label
, &label
);
1599 static_attr
.srv6_l3vpn
=
1600 XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1601 sizeof(struct bgp_attr_srv6_l3vpn
));
1602 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1603 static_attr
.srv6_l3vpn
->endpoint_behavior
= 0xffff;
1604 static_attr
.srv6_l3vpn
->loc_block_len
=
1605 from_bgp
->tovpn_sid_locator
->block_bits_length
;
1606 static_attr
.srv6_l3vpn
->loc_node_len
=
1607 from_bgp
->tovpn_sid_locator
->node_bits_length
;
1608 static_attr
.srv6_l3vpn
->func_len
=
1609 from_bgp
->tovpn_sid_locator
->function_bits_length
;
1610 static_attr
.srv6_l3vpn
->arg_len
=
1611 from_bgp
->tovpn_sid_locator
->argument_bits_length
;
1612 static_attr
.srv6_l3vpn
->transposition_len
=
1613 from_bgp
->tovpn_sid_locator
->function_bits_length
;
1614 static_attr
.srv6_l3vpn
->transposition_offset
=
1615 from_bgp
->tovpn_sid_locator
->block_bits_length
+
1616 from_bgp
->tovpn_sid_locator
->node_bits_length
;
1617 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1618 &from_bgp
->tovpn_sid_locator
->prefix
.prefix
,
1619 sizeof(struct in6_addr
));
1623 new_attr
= bgp_attr_intern(
1624 &static_attr
); /* hashed refcounted everything */
1625 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1627 if (debug
&& bgp_attr_get_ecommunity(new_attr
)) {
1628 char *s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr
),
1629 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1631 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1632 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1635 /* Now new_attr is an allocated interned attr */
1637 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1638 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1640 struct bgp_path_info
*new_info
;
1643 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vrf
, &label
,
1644 1, from_bgp
, NULL
, nexthop_self_flag
, debug
);
1647 * Routes actually installed in the vpn RIB must also be
1648 * offered to all vrfs (because now they originate from
1651 * Acceptance into other vrfs depends on rt-lists.
1652 * Originating vrf will not accept the looped back route
1653 * because of loop checking.
1656 vpn_leak_to_vrf_update(from_bgp
, new_info
, NULL
);
1659 void vpn_leak_from_vrf_withdraw(struct bgp
*to_bgp
, /* to */
1660 struct bgp
*from_bgp
, /* from */
1661 struct bgp_path_info
*path_vrf
) /* route */
1663 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1664 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1665 afi_t afi
= family2afi(p
->family
);
1666 safi_t safi
= SAFI_MPLS_VPN
;
1667 struct bgp_path_info
*bpi
;
1668 struct bgp_dest
*bn
;
1669 const char *debugmsg
;
1673 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1674 __func__
, from_bgp
->name_pretty
, path_vrf
->net
,
1675 path_vrf
->type
, path_vrf
->sub_type
);
1683 zlog_debug("%s: can't get afi of prefix", __func__
);
1687 /* Is this route exportable into the VPN table? */
1688 if (!is_route_injectable_into_vpn(path_vrf
))
1691 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1693 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1698 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1700 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1701 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1707 * match original bpi imported from
1709 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1710 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1716 /* withdraw from looped vrfs as well */
1717 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1719 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1720 bgp_path_info_delete(bn
, bpi
);
1721 bgp_process(to_bgp
, bn
, afi
, safi
);
1723 bgp_dest_unlock_node(bn
);
1726 void vpn_leak_from_vrf_withdraw_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1729 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1730 struct bgp_dest
*pdest
;
1731 safi_t safi
= SAFI_MPLS_VPN
;
1734 * Walk vpn table, delete bpi with bgp_orig == from_bgp
1736 for (pdest
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); pdest
;
1737 pdest
= bgp_route_next(pdest
)) {
1739 struct bgp_table
*table
;
1740 struct bgp_dest
*bn
;
1741 struct bgp_path_info
*bpi
;
1743 /* This is the per-RD table of prefixes */
1744 table
= bgp_dest_get_bgp_table_info(pdest
);
1749 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1750 bpi
= bgp_dest_get_bgp_path_info(bn
);
1752 zlog_debug("%s: looking at prefix %pBD",
1756 for (; bpi
; bpi
= bpi
->next
) {
1758 zlog_debug("%s: type %d, sub_type %d",
1759 __func__
, bpi
->type
,
1761 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1765 if ((struct bgp
*)bpi
->extra
->bgp_orig
==
1769 zlog_debug("%s: deleting it",
1771 /* withdraw from leak-to vrfs as well */
1772 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1773 bgp_aggregate_decrement(
1774 to_bgp
, bgp_dest_get_prefix(bn
),
1776 bgp_path_info_delete(bn
, bpi
);
1777 bgp_process(to_bgp
, bn
, afi
, safi
);
1784 void vpn_leak_from_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1787 struct bgp_dest
*bn
;
1788 struct bgp_path_info
*bpi
;
1789 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1792 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1793 from_bgp
->name_pretty
);
1795 for (bn
= bgp_table_top(from_bgp
->rib
[afi
][SAFI_UNICAST
]); bn
;
1796 bn
= bgp_route_next(bn
)) {
1799 zlog_debug("%s: node=%p", __func__
, bn
);
1801 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1805 "%s: calling vpn_leak_from_vrf_update",
1807 vpn_leak_from_vrf_update(to_bgp
, from_bgp
, bpi
);
1812 static struct bgp
*bgp_lookup_by_rd(struct bgp_path_info
*bpi
,
1813 struct prefix_rd
*rd
, afi_t afi
)
1815 struct listnode
*node
, *nnode
;
1821 /* If ACCEPT_OWN is not enabled for this path - return. */
1822 if (!CHECK_FLAG(bpi
->flags
, BGP_PATH_ACCEPT_OWN
))
1825 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
1826 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1829 if (!CHECK_FLAG(bgp
->vpn_policy
[afi
].flags
,
1830 BGP_VPN_POLICY_TOVPN_RD_SET
))
1833 /* Check if we have source VRF by RD value */
1834 if (memcmp(&bgp
->vpn_policy
[afi
].tovpn_rd
.val
, rd
->val
,
1835 ECOMMUNITY_SIZE
) == 0)
1842 static bool vpn_leak_to_vrf_update_onevrf(struct bgp
*to_bgp
, /* to */
1843 struct bgp
*from_bgp
, /* from */
1844 struct bgp_path_info
*path_vpn
,
1845 struct prefix_rd
*prd
)
1847 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1848 afi_t afi
= family2afi(p
->family
);
1850 struct attr static_attr
= {0};
1851 struct attr
*new_attr
= NULL
;
1852 struct bgp_dest
*bn
;
1853 safi_t safi
= SAFI_UNICAST
;
1854 const char *debugmsg
;
1855 struct prefix nexthop_orig
;
1856 mpls_label_t
*pLabels
= NULL
;
1857 uint32_t num_labels
= 0;
1858 int nexthop_self_flag
= 1;
1859 struct bgp_path_info
*bpi_ultimate
= NULL
;
1860 int origin_local
= 0;
1861 struct bgp
*src_vrf
;
1863 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1865 if (!vpn_leak_from_vpn_active(to_bgp
, afi
, &debugmsg
)) {
1867 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1871 /* Check for intersection of route targets */
1872 if (!ecommunity_include(
1873 to_bgp
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1874 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1877 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
1878 from_bgp
->name_pretty
, to_bgp
->name_pretty
);
1882 /* A route MUST NOT ever be accepted back into its source VRF, even if
1883 * it carries one or more RTs that match that VRF.
1885 if (prd
&& memcmp(&prd
->val
, &to_bgp
->vpn_policy
[afi
].tovpn_rd
.val
,
1886 ECOMMUNITY_SIZE
) == 0) {
1889 "%s: skipping import, match RD (%pRD) of src VRF (%s) and the prefix (%pFX)",
1890 __func__
, prd
, to_bgp
->name_pretty
, p
);
1896 zlog_debug("%s: updating RD %pRD, %pFX to vrf %s", __func__
,
1897 prd
, p
, to_bgp
->name_pretty
);
1900 static_attr
= *path_vpn
->attr
;
1902 struct ecommunity
*old_ecom
;
1903 struct ecommunity
*new_ecom
;
1905 /* If doing VRF-to-VRF leaking, strip RTs. */
1906 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1907 if (old_ecom
&& CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1908 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1909 new_ecom
= ecommunity_dup(old_ecom
);
1910 ecommunity_strip_rts(new_ecom
);
1911 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1913 if (new_ecom
->size
== 0) {
1914 ecommunity_free(&new_ecom
);
1915 bgp_attr_set_ecommunity(&static_attr
, NULL
);
1918 if (!old_ecom
->refcnt
)
1919 ecommunity_free(&old_ecom
);
1922 community_strip_accept_own(&static_attr
);
1925 * Nexthop: stash and clear
1927 * Nexthop is valid in context of VPN core, but not in destination vrf.
1928 * Stash it for later label resolution by vrf ingress path and then
1929 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1931 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1933 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1934 nexthop_orig
.family
= nhfamily
;
1939 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1940 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
1942 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1943 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1944 static_attr
.nexthop
.s_addr
=
1945 nexthop_orig
.u
.prefix4
.s_addr
;
1947 static_attr
.mp_nexthop_global_in
=
1948 path_vpn
->attr
->mp_nexthop_global_in
;
1949 static_attr
.mp_nexthop_len
=
1950 path_vpn
->attr
->mp_nexthop_len
;
1952 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1956 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1957 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
1959 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1960 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1961 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1967 * route map handling
1969 if (to_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1970 struct bgp_path_info info
;
1971 route_map_result_t ret
;
1973 memset(&info
, 0, sizeof(info
));
1974 info
.peer
= to_bgp
->peer_self
;
1975 info
.attr
= &static_attr
;
1976 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1977 ret
= route_map_apply(to_bgp
->vpn_policy
[afi
]
1978 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1980 if (RMAP_DENYMATCH
== ret
) {
1981 bgp_attr_flush(&static_attr
); /* free any added parts */
1984 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1985 __func__
, to_bgp
->name_pretty
,
1986 to_bgp
->vpn_policy
[afi
]
1987 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1992 * if route-map changed nexthop, don't nexthop-self on output
1994 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1995 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1996 nexthop_self_flag
= 0;
1999 new_attr
= bgp_attr_intern(&static_attr
);
2000 bgp_attr_flush(&static_attr
);
2002 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2005 * ensure labels are copied
2007 * However, there is a special case: if the route originated in
2008 * another local VRF (as opposed to arriving via VPN), then the
2009 * nexthop is reached by hairpinning through this router (me)
2010 * using IP forwarding only (no LSP). Therefore, the route
2011 * imported to the VRF should not have labels attached. Note
2012 * that nexthop tracking is also involved: eliminating the
2013 * labels for these routes enables the non-labeled nexthops
2014 * from the originating VRF to be considered valid for this route.
2016 if (!CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
2017 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
2018 /* work back to original route */
2019 bpi_ultimate
= bgp_get_imported_bpi_ultimate(path_vpn
);
2022 * if original route was unicast,
2023 * then it did not arrive over vpn
2025 if (bpi_ultimate
->net
) {
2026 struct bgp_table
*table
;
2028 table
= bgp_dest_table(bpi_ultimate
->net
);
2029 if (table
&& (table
->safi
== SAFI_UNICAST
))
2034 if (!origin_local
&& path_vpn
->extra
2035 && path_vpn
->extra
->num_labels
) {
2036 num_labels
= path_vpn
->extra
->num_labels
;
2037 if (num_labels
> BGP_MAX_LABELS
)
2038 num_labels
= BGP_MAX_LABELS
;
2039 pLabels
= path_vpn
->extra
->label
;
2044 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
2045 path_vpn
->net
, num_labels
);
2048 * For VRF-2-VRF route-leaking,
2049 * the source will be the originating VRF.
2051 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?)
2052 * get the source VRF (BGP) by looking at the RD.
2054 struct bgp
*src_bgp
= bgp_lookup_by_rd(path_vpn
, prd
, afi
);
2056 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
2057 src_vrf
= path_vpn
->extra
->bgp_orig
;
2063 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
2064 num_labels
, src_vrf
, &nexthop_orig
, nexthop_self_flag
,
2069 bool vpn_leak_to_vrf_update(struct bgp
*from_bgp
,
2070 struct bgp_path_info
*path_vpn
,
2071 struct prefix_rd
*prd
)
2073 struct listnode
*mnode
, *mnnode
;
2075 bool leak_success
= false;
2077 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2080 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2082 /* Loop over VRFs */
2083 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2085 if (!path_vpn
->extra
2086 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
2087 leak_success
|= vpn_leak_to_vrf_update_onevrf(
2088 bgp
, from_bgp
, path_vpn
, prd
);
2091 return leak_success
;
2094 void vpn_leak_to_vrf_withdraw(struct bgp
*from_bgp
, /* from */
2095 struct bgp_path_info
*path_vpn
) /* route */
2097 const struct prefix
*p
;
2099 safi_t safi
= SAFI_UNICAST
;
2101 struct listnode
*mnode
, *mnnode
;
2102 struct bgp_dest
*bn
;
2103 struct bgp_path_info
*bpi
;
2104 const char *debugmsg
;
2106 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2109 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
2110 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
2113 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
2115 if (!path_vpn
->net
) {
2116 #ifdef ENABLE_BGP_VNC
2117 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
2118 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
2119 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
2126 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
2131 p
= bgp_dest_get_prefix(path_vpn
->net
);
2132 afi
= family2afi(p
->family
);
2134 /* Loop over VRFs */
2135 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2136 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
2138 zlog_debug("%s: skipping: %s", __func__
,
2143 /* Check for intersection of route targets */
2144 if (!ecommunity_include(
2145 bgp
->vpn_policy
[afi
]
2146 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
2147 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
2153 zlog_debug("%s: withdrawing from vrf %s", __func__
,
2156 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
2158 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2161 && (struct bgp_path_info
*)bpi
->extra
->parent
2169 zlog_debug("%s: deleting bpi %p", __func__
,
2171 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
2172 bgp_path_info_delete(bn
, bpi
);
2173 bgp_process(bgp
, bn
, afi
, safi
);
2175 bgp_dest_unlock_node(bn
);
2179 void vpn_leak_to_vrf_withdraw_all(struct bgp
*to_bgp
, afi_t afi
)
2181 struct bgp_dest
*bn
;
2182 struct bgp_path_info
*bpi
;
2183 safi_t safi
= SAFI_UNICAST
;
2184 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
2187 zlog_debug("%s: entry", __func__
);
2189 * Walk vrf table, delete bpi with bgp_orig in a different vrf
2191 for (bn
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); bn
;
2192 bn
= bgp_route_next(bn
)) {
2194 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2196 if (bpi
->extra
&& bpi
->extra
->bgp_orig
!= to_bgp
&&
2197 bpi
->extra
->parent
&&
2198 is_pi_family_vpn(bpi
->extra
->parent
)) {
2201 bgp_aggregate_decrement(to_bgp
,
2202 bgp_dest_get_prefix(bn
),
2204 bgp_path_info_delete(bn
, bpi
);
2205 bgp_process(to_bgp
, bn
, afi
, safi
);
2211 void vpn_leak_to_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*vpn_from
,
2214 struct bgp_dest
*pdest
;
2215 safi_t safi
= SAFI_MPLS_VPN
;
2222 for (pdest
= bgp_table_top(vpn_from
->rib
[afi
][safi
]); pdest
;
2223 pdest
= bgp_route_next(pdest
)) {
2224 struct bgp_table
*table
;
2225 struct bgp_dest
*bn
;
2226 struct bgp_path_info
*bpi
;
2228 /* This is the per-RD table of prefixes */
2229 table
= bgp_dest_get_bgp_table_info(pdest
);
2234 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
2236 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
2240 bpi
->extra
->bgp_orig
== to_bgp
)
2243 vpn_leak_to_vrf_update_onevrf(to_bgp
, vpn_from
,
2251 * This function is called for definition/deletion/change to a route-map
2253 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
2255 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2257 struct route_map
*rmap
;
2259 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2260 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2265 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
2267 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2269 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
2270 && !strcmp(rmap_name
,
2271 bgp
->vpn_policy
[afi
]
2272 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
2276 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
2277 __func__
, rmap_name
, bgp
->as
,
2280 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2281 bgp_get_default(), bgp
);
2283 zlog_debug("%s: after vpn_leak_prechange",
2286 /* in case of definition/deletion */
2287 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
2290 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
2291 bgp_get_default(), bgp
);
2294 zlog_debug("%s: after vpn_leak_postchange",
2298 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
2299 && !strcmp(rmap_name
,
2300 bgp
->vpn_policy
[afi
]
2301 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
2304 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
2305 __func__
, rmap_name
, bgp
->as
,
2309 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2310 bgp_get_default(), bgp
);
2312 /* in case of definition/deletion */
2313 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
2316 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
2317 bgp_get_default(), bgp
);
2322 /* This API is used during router-id change, reflect VPNs
2323 * auto RD and RT values and readvertise routes to VPN table.
2325 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
2329 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
2330 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2332 const char *export_name
;
2333 char buf
[RD_ADDRSTRLEN
];
2334 struct bgp
*bgp_import
;
2335 struct listnode
*node
;
2336 struct ecommunity
*ecom
;
2337 enum vpn_policy_direction idir
, edir
;
2340 * Router-id change that is not explicitly configured
2341 * (a change from zebra, frr restart for example)
2342 * should not replace a configured vpn RD/RT.
2346 zlog_debug("%s: skipping non explicit router-id change",
2351 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2352 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2355 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
2356 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2357 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2359 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2360 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
2364 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
2365 afi
, bgp_get_default(), bgp
);
2367 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2368 __func__
, export_name
);
2370 /* Remove import RT from VRFs */
2371 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2372 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2373 export_vrf
, node
, vname
)) {
2374 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2375 bgp_import
= bgp_get_default();
2377 bgp_import
= bgp_lookup_by_name(vname
);
2382 bgp_import
->vpn_policy
[afi
]
2384 (struct ecommunity_val
*)ecom
->val
);
2387 /* New router-id derive auto RD and RT and export
2390 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
2391 &bgp
->vrf_prd_auto
);
2392 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
2393 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2396 /* free up pre-existing memory if any and allocate
2397 * the ecommunity attribute with new RD/RT
2399 if (bgp
->vpn_policy
[afi
].rtlist
[edir
])
2401 &bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2402 bgp
->vpn_policy
[afi
].rtlist
[edir
] = ecommunity_str2com(
2403 buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2405 /* Update import_vrf rt_list */
2406 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2407 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2408 export_vrf
, node
, vname
)) {
2409 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2410 bgp_import
= bgp_get_default();
2412 bgp_import
= bgp_lookup_by_name(vname
);
2415 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
2416 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2418 bgp_import
->vpn_policy
[afi
]
2419 .rtlist
[idir
], ecom
);
2421 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2422 = ecommunity_dup(ecom
);
2425 /* Update routes to VPN */
2426 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
2427 afi
, bgp_get_default(),
2430 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2431 __func__
, export_name
);
2436 void vpn_policy_routemap_event(const char *rmap_name
)
2438 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2439 struct listnode
*mnode
, *mnnode
;
2443 zlog_debug("%s: entry", __func__
);
2445 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2448 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2449 vpn_policy_routemap_update(bgp
, rmap_name
);
2452 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2453 afi_t afi
, safi_t safi
)
2455 const char *export_name
;
2456 enum vpn_policy_direction idir
, edir
;
2457 char *vname
, *tmp_name
;
2458 char buf
[RD_ADDRSTRLEN
];
2459 struct ecommunity
*ecom
;
2460 bool first_export
= false;
2462 struct listnode
*node
;
2463 bool is_inst_match
= false;
2465 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2466 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2467 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2469 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2470 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2473 * Cross-ref both VRFs. Also, note if this is the first time
2474 * any VRF is importing from "import_vrf".
2476 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2477 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2479 /* Check the import_vrf list of destination vrf for the source vrf name,
2482 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2484 if (strcmp(vname
, tmp_name
) == 0) {
2485 is_inst_match
= true;
2490 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2493 XFREE(MTYPE_TMP
, vname
);
2495 /* Check if the source vrf already exports to any vrf,
2496 * first time export requires to setup auto derived RD/RT values.
2497 * Add the destination vrf name to export vrf list if it is
2500 is_inst_match
= false;
2501 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2502 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2503 first_export
= true;
2505 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2507 if (strcmp(vname
, tmp_name
) == 0) {
2508 is_inst_match
= true;
2514 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2517 XFREE(MTYPE_TMP
, vname
);
2519 /* Update import RT for current VRF using export RT of the VRF we're
2520 * importing from. First though, make sure "import_vrf" has that
2524 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2525 &from_bgp
->vrf_prd_auto
);
2526 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2527 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2528 BGP_VPN_POLICY_TOVPN_RD_SET
);
2529 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
2531 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2532 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2533 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2534 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2535 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2536 BGP_PREVENT_VRF_2_VRF_LEAK
;
2538 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2539 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2540 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2541 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2542 .rtlist
[idir
], ecom
);
2544 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2545 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2548 const char *from_name
;
2549 char *ecom1
, *ecom2
;
2551 from_name
= from_bgp
->name
? from_bgp
->name
:
2554 ecom1
= ecommunity_ecom2str(
2555 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2556 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2558 ecom2
= ecommunity_ecom2str(
2559 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2560 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2563 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2564 __func__
, from_name
, export_name
, first_export
, ecom1
,
2567 ecommunity_strfree(&ecom1
);
2568 ecommunity_strfree(&ecom2
);
2571 /* Does "import_vrf" first need to export its routes or that
2572 * is already done and we just need to import those routes
2573 * from the global table?
2576 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2578 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2581 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2582 afi_t afi
, safi_t safi
)
2584 const char *export_name
, *tmp_name
;
2585 enum vpn_policy_direction idir
, edir
;
2587 struct ecommunity
*ecom
= NULL
;
2588 struct listnode
*node
;
2591 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2592 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2593 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2594 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2596 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2597 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2599 /* Were we importing from "import_vrf"? */
2600 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2602 if (strcmp(vname
, tmp_name
) == 0)
2607 * We do not check in the cli if the passed in bgp
2608 * instance is actually imported into us before
2609 * we call this function. As such if we do not
2610 * find this in the import_vrf list than
2611 * we just need to return safely.
2617 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2619 /* Remove "import_vrf" from our import list. */
2620 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2621 XFREE(MTYPE_TMP
, vname
);
2623 /* Remove routes imported from "import_vrf". */
2624 /* TODO: In the current logic, we have to first remove all
2625 * imported routes and then (if needed) import back routes
2627 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2629 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2630 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2631 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2632 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2633 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2634 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2636 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2638 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2639 (struct ecommunity_val
*)ecom
->val
);
2640 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2645 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2646 * below is checking for NULL that export_vrf can be
2647 * NULL, consequently it is complaining( like a cabbage )
2648 * that we could dereference and crash in the listcount(..)
2650 * So make it happy, under protest, with liberty and justice
2653 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2655 /* Remove us from "import_vrf's" export list. If no other VRF
2656 * is importing from "import_vrf", cleanup appropriately.
2658 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2660 if (strcmp(vname
, export_name
) == 0)
2665 * If we have gotten to this point then the vname must
2666 * exist. If not, we are in a world of trouble and
2667 * have slag sitting around.
2669 * import_vrf and export_vrf must match in having
2670 * the in/out names as appropriate.
2671 * export_vrf list could have been cleaned up
2672 * as part of no router bgp source instnace.
2677 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2678 XFREE(MTYPE_TMP
, vname
);
2680 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2681 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2682 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2683 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2684 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2685 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2686 sizeof(struct prefix_rd
));
2687 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2688 BGP_VPN_POLICY_TOVPN_RD_SET
);
2689 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2694 /* For testing purpose, static route of MPLS-VPN. */
2695 DEFUN (vpnv4_network
,
2697 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2698 "Specify a network to announce via BGP\n"
2700 "Specify Route Distinguisher\n"
2701 "VPN Route Distinguisher\n"
2702 "VPN NLRI label (tag)\n"
2703 "VPN NLRI label (tag)\n"
2706 int idx_ipv4_prefixlen
= 1;
2707 int idx_ext_community
= 3;
2709 return bgp_static_set_safi(
2710 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2711 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
2712 NULL
, NULL
, NULL
, NULL
);
2715 DEFUN (vpnv4_network_route_map
,
2716 vpnv4_network_route_map_cmd
,
2717 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
2718 "Specify a network to announce via BGP\n"
2720 "Specify Route Distinguisher\n"
2721 "VPN Route Distinguisher\n"
2722 "VPN NLRI label (tag)\n"
2723 "VPN NLRI label (tag)\n"
2728 int idx_ipv4_prefixlen
= 1;
2729 int idx_ext_community
= 3;
2732 return bgp_static_set_safi(
2733 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2734 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2735 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2738 /* For testing purpose, static route of MPLS-VPN. */
2739 DEFUN (no_vpnv4_network
,
2740 no_vpnv4_network_cmd
,
2741 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2743 "Specify a network to announce via BGP\n"
2745 "Specify Route Distinguisher\n"
2746 "VPN Route Distinguisher\n"
2747 "VPN NLRI label (tag)\n"
2748 "VPN NLRI label (tag)\n"
2751 int idx_ipv4_prefixlen
= 2;
2752 int idx_ext_community
= 4;
2754 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
2755 argv
[idx_ipv4_prefixlen
]->arg
,
2756 argv
[idx_ext_community
]->arg
,
2757 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2760 DEFUN (vpnv6_network
,
2762 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
2763 "Specify a network to announce via BGP\n"
2764 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2765 "Specify Route Distinguisher\n"
2766 "VPN Route Distinguisher\n"
2767 "VPN NLRI label (tag)\n"
2768 "VPN NLRI label (tag)\n"
2773 int idx_ipv6_prefix
= 1;
2774 int idx_ext_community
= 3;
2778 return bgp_static_set_safi(
2779 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2780 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2781 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2783 return bgp_static_set_safi(
2784 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2785 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2786 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2789 /* For testing purpose, static route of MPLS-VPN. */
2790 DEFUN (no_vpnv6_network
,
2791 no_vpnv6_network_cmd
,
2792 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2794 "Specify a network to announce via BGP\n"
2795 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2796 "Specify Route Distinguisher\n"
2797 "VPN Route Distinguisher\n"
2798 "VPN NLRI label (tag)\n"
2799 "VPN NLRI label (tag)\n"
2802 int idx_ipv6_prefix
= 2;
2803 int idx_ext_community
= 4;
2805 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2806 argv
[idx_ipv6_prefix
]->arg
,
2807 argv
[idx_ext_community
]->arg
,
2808 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2811 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2812 enum bgp_show_type type
, void *output_arg
, int tags
,
2816 struct bgp_table
*table
;
2818 bgp
= bgp_get_default();
2821 vty_out(vty
, "No BGP process is configured\n");
2823 vty_out(vty
, "{}\n");
2826 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2827 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2828 output_arg
, use_json
);
2831 DEFUN (show_bgp_ip_vpn_all_rd
,
2832 show_bgp_ip_vpn_all_rd_cmd
,
2833 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2837 "Display VPN NLRI specific information\n"
2838 "Display VPN NLRI specific information\n"
2839 "Display information for a route distinguisher\n"
2840 "VPN Route Distinguisher\n"
2841 "All VPN Route Distinguishers\n"
2845 struct prefix_rd prd
;
2849 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2850 /* Constrain search if user supplies RD && RD != "all" */
2851 if (argv_find(argv
, argc
, "rd", &idx
)
2852 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
2853 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2856 "%% Malformed Route Distinguisher\n");
2859 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2860 bgp_show_type_normal
, NULL
, 0,
2861 use_json(argc
, argv
));
2863 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2864 bgp_show_type_normal
, NULL
, 0,
2865 use_json(argc
, argv
));
2871 ALIAS(show_bgp_ip_vpn_all_rd
,
2872 show_bgp_ip_vpn_rd_cmd
,
2873 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2877 "Display VPN NLRI specific information\n"
2878 "Display information for a route distinguisher\n"
2879 "VPN Route Distinguisher\n"
2880 "All VPN Route Distinguishers\n"
2883 #ifdef KEEP_OLD_VPN_COMMANDS
2884 DEFUN (show_ip_bgp_vpn_rd
,
2885 show_ip_bgp_vpn_rd_cmd
,
2886 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2892 "Display information for a route distinguisher\n"
2893 "VPN Route Distinguisher\n"
2894 "All VPN Route Distinguishers\n")
2896 int idx_ext_community
= argc
- 1;
2898 struct prefix_rd prd
;
2902 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2903 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2904 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2905 bgp_show_type_normal
, NULL
, 0,
2907 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2909 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2912 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2918 DEFUN (show_ip_bgp_vpn_all
,
2919 show_ip_bgp_vpn_all_cmd
,
2920 "show [ip] bgp <vpnv4|vpnv6>",
2929 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2930 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2935 DEFUN (show_ip_bgp_vpn_all_tags
,
2936 show_ip_bgp_vpn_all_tags_cmd
,
2937 "show [ip] bgp <vpnv4|vpnv6> all tags",
2942 "Display information about all VPNv4/VPNV6 NLRIs\n"
2943 "Display BGP tags for prefixes\n")
2948 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2949 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2954 DEFUN (show_ip_bgp_vpn_rd_tags
,
2955 show_ip_bgp_vpn_rd_tags_cmd
,
2956 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2961 "Display information for a route distinguisher\n"
2962 "VPN Route Distinguisher\n"
2963 "All VPN Route Distinguishers\n"
2964 "Display BGP tags for prefixes\n")
2966 int idx_ext_community
= 5;
2968 struct prefix_rd prd
;
2972 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2973 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2974 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2975 bgp_show_type_normal
, NULL
, 1,
2977 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2979 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2982 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2988 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2989 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2990 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2995 "Display information about all VPNv4/VPNv6 NLRIs\n"
2996 "Detailed information on TCP and BGP neighbor connections\n"
2997 "Neighbor to display information about\n"
2998 "Display routes learned from neighbor\n"
3005 bool uj
= use_json(argc
, argv
);
3009 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3010 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3013 json_object
*json_no
= NULL
;
3014 json_no
= json_object_new_object();
3015 json_object_string_add(json_no
, "warning",
3016 "Malformed address");
3017 vty_out(vty
, "%s\n",
3018 json_object_to_json_string(json_no
));
3019 json_object_free(json_no
);
3021 vty_out(vty
, "Malformed address: %s\n",
3022 argv
[idx_ipv4
]->arg
);
3026 peer
= peer_lookup(NULL
, &su
);
3027 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3029 json_object
*json_no
= NULL
;
3030 json_no
= json_object_new_object();
3031 json_object_string_add(
3033 "No such neighbor or address family");
3034 vty_out(vty
, "%s\n",
3035 json_object_to_json_string(json_no
));
3036 json_object_free(json_no
);
3039 "%% No such neighbor or address family\n");
3043 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
3049 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
3050 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
3051 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
3056 "Display information for a route distinguisher\n"
3057 "VPN Route Distinguisher\n"
3058 "All VPN Route Distinguishers\n"
3059 "Detailed information on TCP and BGP neighbor connections\n"
3060 "Neighbor to display information about\n"
3061 "Display routes learned from neighbor\n"
3064 int idx_ext_community
= 5;
3069 struct prefix_rd prd
;
3070 bool prefix_rd_all
= false;
3071 bool uj
= use_json(argc
, argv
);
3075 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3076 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3077 prefix_rd_all
= true;
3079 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3082 json_object
*json_no
= NULL
;
3083 json_no
= json_object_new_object();
3084 json_object_string_add(
3086 "Malformed Route Distinguisher");
3087 vty_out(vty
, "%s\n",
3088 json_object_to_json_string(
3090 json_object_free(json_no
);
3093 "%% Malformed Route Distinguisher\n");
3098 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3101 json_object
*json_no
= NULL
;
3102 json_no
= json_object_new_object();
3103 json_object_string_add(json_no
, "warning",
3104 "Malformed address");
3105 vty_out(vty
, "%s\n",
3106 json_object_to_json_string(json_no
));
3107 json_object_free(json_no
);
3109 vty_out(vty
, "Malformed address: %s\n",
3110 argv
[idx_ext_community
]->arg
);
3114 peer
= peer_lookup(NULL
, &su
);
3115 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3117 json_object
*json_no
= NULL
;
3118 json_no
= json_object_new_object();
3119 json_object_string_add(
3121 "No such neighbor or address family");
3122 vty_out(vty
, "%s\n",
3123 json_object_to_json_string(json_no
));
3124 json_object_free(json_no
);
3127 "%% No such neighbor or address family\n");
3132 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
3133 bgp_show_type_neighbor
, &su
, 0,
3136 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
3137 bgp_show_type_neighbor
, &su
, 0,
3143 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
3144 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
3145 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
3150 "Display information about all VPNv4/VPNv6 NLRIs\n"
3151 "Detailed information on TCP and BGP neighbor connections\n"
3152 "Neighbor to display information about\n"
3153 "Display the routes advertised to a BGP neighbor\n"
3160 bool uj
= use_json(argc
, argv
);
3164 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3165 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3168 json_object
*json_no
= NULL
;
3169 json_no
= json_object_new_object();
3170 json_object_string_add(json_no
, "warning",
3171 "Malformed address");
3172 vty_out(vty
, "%s\n",
3173 json_object_to_json_string(json_no
));
3174 json_object_free(json_no
);
3176 vty_out(vty
, "Malformed address: %s\n",
3177 argv
[idx_ipv4
]->arg
);
3180 peer
= peer_lookup(NULL
, &su
);
3181 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3183 json_object
*json_no
= NULL
;
3184 json_no
= json_object_new_object();
3185 json_object_string_add(
3187 "No such neighbor or address family");
3188 vty_out(vty
, "%s\n",
3189 json_object_to_json_string(json_no
));
3190 json_object_free(json_no
);
3193 "%% No such neighbor or address family\n");
3196 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3202 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
3203 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
3204 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
3209 "Display information for a route distinguisher\n"
3210 "VPN Route Distinguisher\n"
3211 "All VPN Route Distinguishers\n"
3212 "Detailed information on TCP and BGP neighbor connections\n"
3213 "Neighbor to display information about\n"
3214 "Display the routes advertised to a BGP neighbor\n"
3217 int idx_ext_community
= 5;
3221 struct prefix_rd prd
;
3223 bool uj
= use_json(argc
, argv
);
3227 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
3228 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
3231 json_object
*json_no
= NULL
;
3232 json_no
= json_object_new_object();
3233 json_object_string_add(json_no
, "warning",
3234 "Malformed address");
3235 vty_out(vty
, "%s\n",
3236 json_object_to_json_string(json_no
));
3237 json_object_free(json_no
);
3239 vty_out(vty
, "Malformed address: %s\n",
3240 argv
[idx_ext_community
]->arg
);
3243 peer
= peer_lookup(NULL
, &su
);
3244 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
3246 json_object
*json_no
= NULL
;
3247 json_no
= json_object_new_object();
3248 json_object_string_add(
3250 "No such neighbor or address family");
3251 vty_out(vty
, "%s\n",
3252 json_object_to_json_string(json_no
));
3253 json_object_free(json_no
);
3256 "%% No such neighbor or address family\n");
3260 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
3261 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
3263 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
3266 json_object
*json_no
= NULL
;
3267 json_no
= json_object_new_object();
3268 json_object_string_add(
3270 "Malformed Route Distinguisher");
3271 vty_out(vty
, "%s\n",
3272 json_object_to_json_string(json_no
));
3273 json_object_free(json_no
);
3276 "%% Malformed Route Distinguisher\n");
3280 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
3285 #endif /* KEEP_OLD_VPN_COMMANDS */
3287 void bgp_mplsvpn_init(void)
3289 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
3290 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
3291 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
3293 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
3294 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
3296 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
3297 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
3298 #ifdef KEEP_OLD_VPN_COMMANDS
3299 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
3300 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
3301 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
3302 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
3303 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
3304 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
3305 install_element(VIEW_NODE
,
3306 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
3307 install_element(VIEW_NODE
,
3308 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
3309 #endif /* KEEP_OLD_VPN_COMMANDS */
3312 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
3314 struct listnode
*mnode
, *mnnode
;
3318 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
3321 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
3322 struct ecommunity
*ec
;
3324 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3327 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
3329 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
3332 if (ecommunity_include(ec
, eckey
))
3339 * The purpose of this function is to process leaks that were deferred
3340 * from earlier per-vrf configuration due to not-yet-existing default
3341 * vrf, in other words, configuration such as:
3343 * router bgp MMM vrf FOO
3344 * address-family ipv4 unicast
3346 * exit-address-family
3351 * This function gets called when the default instance ("router bgp NNN")
3354 void vpn_leak_postchange_all(void)
3356 struct listnode
*next
;
3358 struct bgp
*bgp_default
= bgp_get_default();
3360 assert(bgp_default
);
3362 /* First, do any exporting from VRFs to the single VPN RIB */
3363 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3365 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3368 vpn_leak_postchange(
3369 BGP_VPN_POLICY_DIR_TOVPN
,
3374 vpn_leak_postchange(
3375 BGP_VPN_POLICY_DIR_TOVPN
,
3381 /* Now, do any importing to VRFs from the single VPN RIB */
3382 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3384 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3387 vpn_leak_postchange(
3388 BGP_VPN_POLICY_DIR_FROMVPN
,
3393 vpn_leak_postchange(
3394 BGP_VPN_POLICY_DIR_FROMVPN
,
3401 /* When a bgp vrf instance is unconfigured, remove its routes
3402 * from the VPN table and this vrf could be importing routes from other
3403 * bgp vrf instnaces, unimport them.
3404 * VRF X and VRF Y are exporting routes to each other.
3405 * When VRF X is deleted, unimport its routes from all target vrfs,
3406 * also VRF Y should unimport its routes from VRF X table.
3407 * This will ensure VPN table is cleaned up appropriately.
3409 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
3412 const char *tmp_name
;
3414 struct listnode
*node
, *next
;
3415 safi_t safi
= SAFI_UNICAST
;
3417 bool is_vrf_leak_bind
;
3420 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3423 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3424 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3426 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3428 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3429 /* vrf leak is for IPv4 and IPv6 Unicast only */
3430 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3433 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3434 if (from_bgp
== to_bgp
)
3437 /* Unimport and remove source vrf from the
3438 * other vrfs import list.
3440 struct vpn_policy
*to_vpolicy
;
3442 is_vrf_leak_bind
= false;
3443 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3444 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
3446 if (strcmp(vname
, tmp_name
) == 0) {
3447 is_vrf_leak_bind
= true;
3451 /* skip this bgp instance as there is no leak to this
3454 if (!is_vrf_leak_bind
)
3458 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3459 __func__
, from_bgp
->name_pretty
,
3460 to_bgp
->name_pretty
, afi2str(afi
),
3461 to_vpolicy
->import_vrf
->count
);
3463 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
3465 /* readd vrf name as unimport removes import vrf name
3466 * from the destination vrf's import list where the
3467 * `import vrf` configuration still exist.
3469 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
3470 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
3472 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
3473 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
3475 /* If to_bgp exports its routes to the bgp vrf
3476 * which is being deleted, un-import the
3477 * to_bgp routes from VPN.
3479 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3482 if (strcmp(vname
, tmp_name
) == 0) {
3483 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3493 /* When a router bgp is configured, there could be a bgp vrf
3494 * instance importing routes from this newly configured
3495 * bgp vrf instance. Export routes from configured
3497 * VRF Y has import from bgp vrf x,
3498 * when a bgp vrf x instance is created, export its routes
3499 * to VRF Y instance.
3501 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3504 const char *export_name
;
3506 struct listnode
*node
, *next
;
3507 struct ecommunity
*ecom
;
3508 enum vpn_policy_direction idir
, edir
;
3509 safi_t safi
= SAFI_UNICAST
;
3513 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3514 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3516 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3517 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3519 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3521 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3522 /* vrf leak is for IPv4 and IPv6 Unicast only */
3523 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3526 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3527 if (from_bgp
== to_bgp
)
3530 /* bgp instance has import list, check to see if newly
3531 * configured bgp instance is the list.
3533 struct vpn_policy
*to_vpolicy
;
3535 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3536 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3538 if (strcmp(vname
, export_name
) != 0)
3542 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3544 export_name
, to_bgp
->name_pretty
);
3546 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3547 /* remove import rt, it will be readded
3548 * as part of import from vrf.
3552 to_vpolicy
->rtlist
[idir
],
3553 (struct ecommunity_val
*)
3555 vrf_import_from_vrf(to_bgp
, from_bgp
,