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_ecommunity.h"
46 #include "bgpd/bgp_zebra.h"
47 #include "bgpd/bgp_nexthop.h"
48 #include "bgpd/bgp_nht.h"
49 #include "bgpd/bgp_evpn.h"
50 #include "bgpd/bgp_memory.h"
53 #include "bgpd/rfapi/rfapi_backend.h"
57 * Definitions and external declarations.
59 extern struct zclient
*zclient
;
61 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
62 int *index
, afi_t
*afi
)
65 if (argv_find(argv
, argc
, "vpnv4", index
)) {
69 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
77 uint32_t decode_label(mpls_label_t
*label_pnt
)
80 uint8_t *pnt
= (uint8_t *)label_pnt
;
82 l
= ((uint32_t)*pnt
++ << 12);
83 l
|= (uint32_t)*pnt
++ << 4;
84 l
|= (uint32_t)((*pnt
& 0xf0) >> 4);
88 void encode_label(mpls_label_t label
, mpls_label_t
*label_pnt
)
90 uint8_t *pnt
= (uint8_t *)label_pnt
;
93 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
) {
97 *pnt
++ = (label
>> 12) & 0xff;
98 *pnt
++ = (label
>> 4) & 0xff;
99 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
102 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
103 struct bgp_nlri
*packet
)
111 struct prefix_rd prd
= {0};
112 mpls_label_t label
= {0};
115 bool addpath_capable
;
120 prd
.family
= AF_UNSPEC
;
123 struct stream
*data
= stream_new(packet
->length
);
124 stream_put(data
, packet
->nlri
, packet
->length
);
129 addpath_capable
= bgp_addpath_encode_rx(peer
, afi
, safi
);
131 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
132 while (STREAM_READABLE(data
) > 0) {
133 /* Clear prefix structure. */
134 memset(&p
, 0, sizeof(p
));
136 if (addpath_capable
) {
137 STREAM_GET(&addpath_id
, data
, BGP_ADDPATH_ID_LEN
);
138 addpath_id
= ntohl(addpath_id
);
141 if (STREAM_READABLE(data
) < 1) {
144 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no prefix length)",
145 peer
->host
, packet
->length
);
146 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
150 /* Fetch prefix length. */
151 STREAM_GETC(data
, prefixlen
);
152 p
.family
= afi2family(packet
->afi
);
153 psize
= PSIZE(prefixlen
);
155 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
158 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
159 peer
->host
, prefixlen
);
160 ret
= BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH
;
164 /* sanity check against packet data */
165 if (STREAM_READABLE(data
) < psize
) {
168 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
169 peer
->host
, prefixlen
, packet
->length
);
170 ret
= BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
174 /* sanity check against storage for the IP address portion */
175 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
178 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
180 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
182 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
186 /* Sanity check against max bitlen of the address family */
187 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
190 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
192 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
193 p
.family
, prefix_blen(&p
));
194 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
198 /* Copy label to prefix. */
199 if (STREAM_READABLE(data
) < BGP_LABEL_BYTES
) {
202 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no label)",
203 peer
->host
, packet
->length
);
204 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
208 STREAM_GET(&label
, data
, BGP_LABEL_BYTES
);
209 bgp_set_valid_label(&label
);
211 /* Copy routing distinguisher to rd. */
212 if (STREAM_READABLE(data
) < 8) {
215 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no RD)",
216 peer
->host
, packet
->length
);
217 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
220 STREAM_GET(&prd
.val
, data
, 8);
222 /* Decode RD type. */
223 type
= decode_rd_type(prd
.val
);
227 decode_rd_as(&prd
.val
[2], &rd_as
);
231 decode_rd_as4(&prd
.val
[2], &rd_as
);
235 decode_rd_ip(&prd
.val
[2], &rd_ip
);
238 #ifdef ENABLE_BGP_VNC
239 case RD_TYPE_VNC_ETH
:
244 flog_err(EC_BGP_UPDATE_RCV
, "Unknown RD type %d", type
);
245 break; /* just report */
248 /* exclude label & RD */
249 p
.prefixlen
= prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8;
250 STREAM_GET(p
.u
.val
, data
, psize
- VPN_PREFIXLEN_MIN_BYTES
);
253 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
254 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
255 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
257 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
258 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
259 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
262 /* Packet length consistency check. */
263 if (STREAM_READABLE(data
) != 0) {
266 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
267 peer
->host
, STREAM_READABLE(data
));
268 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
276 "%s [Error] Update packet error / VPN (NLRI of size %u - length error)",
277 peer
->host
, packet
->length
);
278 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
284 #undef VPN_PREFIXLEN_MIN_BYTES
288 * This function informs zebra of the label this vrf sets on routes
289 * leaked to VPN. Zebra should install this label in the kernel with
290 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
292 * Sending this vrf-label association is qualified by a) whether vrf->vpn
293 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
294 * are set) and b) whether vpn-policy label is set.
296 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
297 * for this vrf, which zebra interprets to mean "delete this vrf-label
300 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
302 mpls_label_t label
= MPLS_LABEL_NONE
;
303 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
305 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
308 "%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
309 __func__
, bgp
->name_pretty
, afi2str(afi
));
314 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
315 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
319 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
320 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
324 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
)
325 label
= MPLS_LABEL_NONE
;
326 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
327 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
331 * If zebra tells us vrf has become unconfigured, tell zebra not to
332 * use this label to forward to the vrf anymore
334 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
336 mpls_label_t label
= MPLS_LABEL_NONE
;
337 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
339 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
342 "%s: vrf_id not set, can't delete zebra vrf label",
349 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
350 bgp
->name_pretty
, bgp
->vrf_id
);
353 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
354 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
358 * This function informs zebra of the srv6-function this vrf sets on routes
359 * leaked to VPN. Zebra should install this srv6-function in the kernel with
360 * an action of "End.DT4/6's IP FIB to route the PDU."
362 void vpn_leak_zebra_vrf_sid_update(struct bgp
*bgp
, afi_t afi
)
364 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
365 enum seg6local_action_t act
;
366 struct seg6local_context ctx
= {};
367 struct in6_addr
*tovpn_sid
= NULL
;
368 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 inet_ntop(AF_INET6
, tovpn_sid
, buf
, sizeof(buf
));
389 zlog_debug("%s: vrf %s: afi %s: setting sid %s for vrf id %d",
390 __func__
, bgp
->name_pretty
, afi2str(afi
), buf
,
394 vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
398 ctx
.table
= vrf
->data
.l
.table_id
;
399 act
= afi
== AFI_IP
? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
400 : ZEBRA_SEG6_LOCAL_ACTION_END_DT6
;
401 zclient_send_localsid(zclient
, tovpn_sid
, bgp
->vrf_id
, act
, &ctx
);
403 tovpn_sid_ls
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
404 *tovpn_sid_ls
= *tovpn_sid
;
405 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
= tovpn_sid_ls
;
409 * If zebra tells us vrf has become unconfigured, tell zebra not to
410 * use this srv6-function to forward to the vrf anymore
412 void vpn_leak_zebra_vrf_sid_withdraw(struct bgp
*bgp
, afi_t afi
)
414 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
416 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
418 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
419 __func__
, bgp
->name_pretty
, afi2str(afi
));
424 zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__
,
425 bgp
->name_pretty
, bgp
->vrf_id
);
427 zclient_send_localsid(zclient
,
428 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
,
429 bgp
->vrf_id
, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
, NULL
);
430 XFREE(MTYPE_BGP_SRV6_SID
,
431 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
);
434 int vpn_leak_label_callback(
439 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
440 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
443 zlog_debug("%s: label=%u, allocated=%d",
444 __func__
, label
, allocated
);
448 * previously-allocated label is now invalid
450 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
451 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
453 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
454 vp
->afi
, bgp_get_default(), vp
->bgp
);
455 vp
->tovpn_label
= MPLS_LABEL_NONE
;
456 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
457 vp
->afi
, bgp_get_default(), vp
->bgp
);
463 * New label allocation
465 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
468 * not currently configured for auto label, reject allocation
473 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
474 if (label
== vp
->tovpn_label
) {
475 /* already have same label, accept but do nothing */
478 /* Shouldn't happen: different label allocation */
479 flog_err(EC_BGP_LABEL
,
480 "%s: %s had label %u but got new assignment %u",
481 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
486 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
487 vp
->afi
, bgp_get_default(), vp
->bgp
);
488 vp
->tovpn_label
= label
;
489 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
490 vp
->afi
, bgp_get_default(), vp
->bgp
);
495 static void sid_register(struct bgp
*bgp
, const struct in6_addr
*sid
,
496 const char *locator_name
)
498 struct bgp_srv6_function
*func
;
499 func
= XCALLOC(MTYPE_BGP_SRV6_FUNCTION
,
500 sizeof(struct bgp_srv6_function
));
502 snprintf(func
->locator_name
, sizeof(func
->locator_name
),
504 listnode_add(bgp
->srv6_functions
, func
);
507 static bool sid_exist(struct bgp
*bgp
, const struct in6_addr
*sid
)
509 struct listnode
*node
;
510 struct bgp_srv6_function
*func
;
512 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_functions
, node
, func
))
513 if (sid_same(&func
->sid
, sid
))
519 * This function generates a new SID based on bgp->srv6_locator_chunks and
520 * index. The locator and generated SID are stored in arguments sid_locator
521 * and sid, respectively.
523 * if index != 0: try to allocate as index-mode
524 * else: try to allocate as auto-mode
526 static uint32_t alloc_new_sid(struct bgp
*bgp
, uint32_t index
,
527 struct in6_addr
*sid_locator
,
528 struct in6_addr
*sid
)
530 struct listnode
*node
;
531 struct srv6_locator_chunk
*chunk
;
532 bool alloced
= false;
537 if (!bgp
|| !sid_locator
|| !sid
)
540 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_locator_chunks
, node
, chunk
)) {
541 *sid_locator
= chunk
->prefix
.prefix
;
542 *sid
= chunk
->prefix
.prefix
;
543 offset
= chunk
->block_bits_length
+ chunk
->node_bits_length
;
544 len
= chunk
->function_bits_length
?: 16;
548 transpose_sid(sid
, label
, offset
, len
);
549 if (sid_exist(bgp
, sid
))
555 for (size_t i
= 1; i
< 255; i
++) {
557 transpose_sid(sid
, label
, offset
, len
);
558 if (sid_exist(bgp
, sid
))
568 sid_register(bgp
, sid
, bgp
->srv6_locator_name
);
572 void ensure_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
574 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
576 struct in6_addr
*tovpn_sid
, *tovpn_sid_locator
;
577 uint32_t tovpn_sid_index
= 0, tovpn_sid_transpose_label
;
578 bool tovpn_sid_auto
= false;
581 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
582 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
584 /* skip when tovpn sid is already allocated on vrf instance */
585 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
)
589 * skip when bgp vpn instance ins't allocated
590 * or srv6 locator chunk isn't allocated
592 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
595 tovpn_sid_index
= bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
;
596 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
597 BGP_VPN_POLICY_TOVPN_SID_AUTO
);
599 /* skip when VPN isn't configured on vrf-instance */
600 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
603 /* check invalid case both configured index and auto */
604 if (tovpn_sid_index
!= 0 && tovpn_sid_auto
) {
605 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
611 XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
612 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
614 tovpn_sid_transpose_label
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
,
615 tovpn_sid_locator
, tovpn_sid
);
617 if (tovpn_sid_transpose_label
== 0) {
618 zlog_debug("%s: not allocated new sid for vrf %s: afi %s",
619 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
620 XFREE(MTYPE_BGP_SRV6_SID
, tovpn_sid_locator
);
621 XFREE(MTYPE_BGP_SRV6_SID
, tovpn_sid
);
626 inet_ntop(AF_INET6
, tovpn_sid
, buf
, sizeof(buf
));
627 zlog_debug("%s: new sid %s allocated for vrf %s: afi %s",
628 __func__
, buf
, bgp_vrf
->name_pretty
,
632 bgp_vrf
->vpn_policy
[afi
].tovpn_sid
= tovpn_sid
;
633 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
= tovpn_sid_locator
;
634 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
=
635 tovpn_sid_transpose_label
;
639 * This function shifts "label" 4 bits to the right and
640 * embeds it by length "len", starting at offset "offset"
641 * as seen from the MSB (Most Significant Bit) of "sid".
643 * e.g. if "label" is 0x1000 and "len" is 16, "label" is
644 * embedded in "sid" as follows:
647 * label: 0000 0001 0000 0000 0000
648 * sid: .... 0000 0001 0000 0000
654 void transpose_sid(struct in6_addr
*sid
, uint32_t label
, uint8_t offset
,
657 for (uint8_t idx
= 0; idx
< len
; idx
++) {
658 uint8_t tidx
= offset
+ idx
;
659 sid
->s6_addr
[tidx
/ 8] &= ~(0x1 << (7 - tidx
% 8));
660 if (label
>> (len
+ 3 - idx
) & 0x1)
661 sid
->s6_addr
[tidx
/ 8] |= 0x1 << (7 - tidx
% 8);
665 static bool ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
671 for (i
= 0; i
< e1
->size
; ++i
) {
672 for (j
= 0; j
< e2
->size
; ++j
) {
673 if (!memcmp(e1
->val
+ (i
* e1
->unit_size
),
674 e2
->val
+ (j
* e2
->unit_size
),
684 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
696 if (n
!= bpi
->extra
->num_labels
)
699 for (i
= 0; i
< n
; ++i
) {
700 if (label
[i
] != bpi
->extra
->label
[i
])
707 * make encoded route labels match specified encoded label set
709 static void setlabels(struct bgp_path_info
*bpi
,
710 mpls_label_t
*label
, /* array of labels */
715 assert(num_labels
<= BGP_MAX_LABELS
);
719 bpi
->extra
->num_labels
= 0;
723 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
726 for (i
= 0; i
< num_labels
; ++i
) {
727 extra
->label
[i
] = label
[i
];
728 if (!bgp_is_valid_label(&label
[i
])) {
729 bgp_set_valid_label(&extra
->label
[i
]);
732 extra
->num_labels
= num_labels
;
736 * make encoded route SIDs match specified encoded sid set
738 static void setsids(struct bgp_path_info
*bpi
,
739 struct in6_addr
*sid
,
743 struct bgp_path_info_extra
*extra
;
747 assert(num_sids
<= BGP_MAX_SIDS
);
751 bpi
->extra
->num_sids
= 0;
755 extra
= bgp_path_info_extra_get(bpi
);
756 for (i
= 0; i
< num_sids
; i
++)
757 memcpy(&extra
->sid
[i
].sid
, &sid
[i
], sizeof(struct in6_addr
));
758 extra
->num_sids
= num_sids
;
761 static void unsetsids(struct bgp_path_info
*bpi
)
763 struct bgp_path_info_extra
*extra
;
765 extra
= bgp_path_info_extra_get(bpi
);
767 memset(extra
->sid
, 0, sizeof(extra
->sid
));
770 static bool leak_update_nexthop_valid(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
771 struct attr
*new_attr
, afi_t afi
,
773 struct bgp_path_info
*source_bpi
,
774 struct bgp_path_info
*bpi
,
775 struct bgp
*bgp_orig
,
776 const struct prefix
*p
, int debug
)
778 struct bgp_path_info
*bpi_ultimate
;
779 struct bgp
*bgp_nexthop
;
782 bpi_ultimate
= bgp_get_imported_bpi_ultimate(source_bpi
);
784 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
785 bgp_nexthop
= bpi
->extra
->bgp_orig
;
787 bgp_nexthop
= bgp_orig
;
790 * No nexthop tracking for redistributed routes or for
791 * EVPN-imported routes that get leaked.
793 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
794 is_pi_family_evpn(bpi_ultimate
))
798 * TBD do we need to do anything about the
799 * 'connected' parameter?
801 nh_valid
= bgp_find_or_add_nexthop(to_bgp
, bgp_nexthop
, afi
,
802 safi
, bpi
, NULL
, 0, p
);
805 * If you are using SRv6 VPN instead of MPLS, it need to check
806 * the SID allocation. If the sid is not allocated, the rib
809 if (to_bgp
->srv6_enabled
&&
810 (!new_attr
->srv6_l3vpn
&& !new_attr
->srv6_vpn
)) {
815 zlog_debug("%s: %pFX nexthop is %svalid (in vrf %s)", __func__
,
816 p
, (nh_valid
? "" : "not "),
817 bgp_nexthop
->name_pretty
);
823 * returns pointer to new bgp_path_info upon success
825 static struct bgp_path_info
*
826 leak_update(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
827 struct attr
*new_attr
, /* already interned */
828 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
829 mpls_label_t
*label
, uint32_t num_labels
, struct bgp
*bgp_orig
,
830 struct prefix
*nexthop_orig
, int nexthop_self_flag
, int debug
)
832 const struct prefix
*p
= bgp_dest_get_prefix(bn
);
833 struct bgp_path_info
*bpi
;
834 struct bgp_path_info
*new;
835 struct bgp_path_info_extra
*extra
;
836 uint32_t num_sids
= 0;
837 void *parent
= source_bpi
;
839 if (new_attr
->srv6_l3vpn
|| new_attr
->srv6_vpn
)
844 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
845 __func__
, to_bgp
->name_pretty
, bn
, source_bpi
->type
,
846 source_bpi
->sub_type
);
849 * Routes that are redistributed into BGP from zebra do not get
850 * nexthop tracking. However, if those routes are subsequently
851 * imported to other RIBs within BGP, the leaked routes do not
852 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
853 * in order to determine if the route we are currently leaking
854 * should have nexthop tracking, we must find the ultimate
855 * parent so we can check its sub_type.
857 * As of now, source_bpi may at most be a second-generation route
858 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
859 * Using a loop here supports more complex intra-bgp import-export
860 * schemes that could be implemented in the future.
867 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
868 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
873 bool labelssame
= labels_same(bpi
, label
, num_labels
);
875 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
876 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
879 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
880 __func__
, to_bgp
->name_pretty
,
881 source_bpi
->flags
, bpi
->flags
, p
);
886 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
887 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
889 bgp_attr_unintern(&new_attr
);
892 "%s: ->%s: %pBD: Found route, no change",
893 __func__
, to_bgp
->name_pretty
, bn
);
897 /* If the RT was changed via extended communities as an
898 * import/export list, we should withdraw implicitly the old
900 * For instance, RT list was modified using route-maps:
901 * route-map test permit 10
902 * set extcommunity rt none
904 if (CHECK_FLAG(bpi
->attr
->flag
,
905 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) &&
906 CHECK_FLAG(new_attr
->flag
,
907 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
909 bgp_attr_get_ecommunity(bpi
->attr
),
910 bgp_attr_get_ecommunity(new_attr
))) {
911 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
912 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
,
914 bgp_path_info_delete(bn
, bpi
);
918 /* attr is changed */
919 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
921 /* Rewrite BGP route information. */
922 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
923 bgp_path_info_restore(bn
, bpi
);
925 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
926 bgp_attr_unintern(&bpi
->attr
);
927 bpi
->attr
= new_attr
;
928 bpi
->uptime
= bgp_clock();
934 setlabels(bpi
, label
, num_labels
);
940 if (new_attr
->srv6_l3vpn
) {
941 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
944 extra
= bgp_path_info_extra_get(bpi
);
946 extra
->sid
[0].loc_block_len
=
947 new_attr
->srv6_l3vpn
->loc_block_len
;
948 extra
->sid
[0].loc_node_len
=
949 new_attr
->srv6_l3vpn
->loc_node_len
;
950 extra
->sid
[0].func_len
=
951 new_attr
->srv6_l3vpn
->func_len
;
952 extra
->sid
[0].arg_len
=
953 new_attr
->srv6_l3vpn
->arg_len
;
954 extra
->sid
[0].transposition_len
=
955 new_attr
->srv6_l3vpn
->transposition_len
;
956 extra
->sid
[0].transposition_offset
=
958 ->transposition_offset
;
959 } else if (new_attr
->srv6_vpn
)
960 setsids(bpi
, &new_attr
->srv6_vpn
->sid
,
965 if (nexthop_self_flag
)
966 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
968 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
969 source_bpi
, bpi
, bgp_orig
, p
,
971 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
973 bgp_path_info_unset_flag(bn
, bpi
, BGP_PATH_VALID
);
975 /* Process change. */
976 bgp_aggregate_increment(to_bgp
, p
, bpi
, afi
, safi
);
977 bgp_process(to_bgp
, bn
, afi
, safi
);
978 bgp_dest_unlock_node(bn
);
981 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
982 __func__
, to_bgp
->name_pretty
, bn
);
987 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
990 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
991 __func__
, to_bgp
->name_pretty
,
992 source_bpi
->flags
, p
);
997 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
998 to_bgp
->peer_self
, new_attr
, bn
);
1000 if (nexthop_self_flag
)
1001 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
1003 bgp_path_info_extra_get(new);
1009 if (new_attr
->srv6_l3vpn
) {
1010 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
1012 extra
= bgp_path_info_extra_get(new);
1014 extra
->sid
[0].loc_block_len
=
1015 new_attr
->srv6_l3vpn
->loc_block_len
;
1016 extra
->sid
[0].loc_node_len
=
1017 new_attr
->srv6_l3vpn
->loc_node_len
;
1018 extra
->sid
[0].func_len
= new_attr
->srv6_l3vpn
->func_len
;
1019 extra
->sid
[0].arg_len
= new_attr
->srv6_l3vpn
->arg_len
;
1020 extra
->sid
[0].transposition_len
=
1021 new_attr
->srv6_l3vpn
->transposition_len
;
1022 extra
->sid
[0].transposition_offset
=
1023 new_attr
->srv6_l3vpn
->transposition_offset
;
1024 } else if (new_attr
->srv6_vpn
)
1025 setsids(new, &new_attr
->srv6_vpn
->sid
, num_sids
);
1030 setlabels(new, label
, num_labels
);
1032 new->extra
->parent
= bgp_path_info_lock(parent
);
1034 (struct bgp_dest
*)((struct bgp_path_info
*)parent
)->net
);
1036 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
1038 new->extra
->nexthop_orig
= *nexthop_orig
;
1040 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1041 source_bpi
, new, bgp_orig
, p
, debug
))
1042 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
1044 bgp_path_info_unset_flag(bn
, new, BGP_PATH_VALID
);
1046 bgp_aggregate_increment(to_bgp
, p
, new, afi
, safi
);
1047 bgp_path_info_add(bn
, new);
1049 bgp_dest_unlock_node(bn
);
1050 bgp_process(to_bgp
, bn
, afi
, safi
);
1053 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
1054 to_bgp
->name_pretty
, bn
);
1059 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1060 void vpn_leak_from_vrf_update(struct bgp
*to_bgp
, /* to */
1061 struct bgp
*from_bgp
, /* from */
1062 struct bgp_path_info
*path_vrf
) /* route */
1064 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1065 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1066 afi_t afi
= family2afi(p
->family
);
1067 struct attr static_attr
= {0};
1068 struct attr
*new_attr
= NULL
;
1069 safi_t safi
= SAFI_MPLS_VPN
;
1070 mpls_label_t label_val
;
1072 struct bgp_dest
*bn
;
1073 const char *debugmsg
;
1074 int nexthop_self_flag
= 0;
1077 zlog_debug("%s: from vrf %s", __func__
, from_bgp
->name_pretty
);
1079 if (debug
&& bgp_attr_get_ecommunity(path_vrf
->attr
)) {
1080 char *s
= ecommunity_ecom2str(
1081 bgp_attr_get_ecommunity(path_vrf
->attr
),
1082 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1084 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
1085 from_bgp
->name
, path_vrf
->type
, s
);
1086 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1094 zlog_debug("%s: can't get afi of prefix", __func__
);
1098 /* Is this route exportable into the VPN table? */
1099 if (!is_route_injectable_into_vpn(path_vrf
))
1102 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1104 zlog_debug("%s: %s skipping: %s", __func__
,
1105 from_bgp
->name
, debugmsg
);
1110 static_attr
= *path_vrf
->attr
;
1113 * route map handling
1115 if (from_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1116 struct bgp_path_info info
;
1117 route_map_result_t ret
;
1119 memset(&info
, 0, sizeof(info
));
1120 info
.peer
= to_bgp
->peer_self
;
1121 info
.attr
= &static_attr
;
1122 ret
= route_map_apply(from_bgp
->vpn_policy
[afi
]
1123 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1125 if (RMAP_DENYMATCH
== ret
) {
1126 bgp_attr_flush(&static_attr
); /* free any added parts */
1129 "%s: vrf %s route map \"%s\" says DENY, returning",
1130 __func__
, from_bgp
->name_pretty
,
1131 from_bgp
->vpn_policy
[afi
]
1132 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
1138 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1139 char *s
= ecommunity_ecom2str(
1140 bgp_attr_get_ecommunity(&static_attr
),
1141 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1143 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1145 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1149 * Add the vpn-policy rt-list
1151 struct ecommunity
*old_ecom
;
1152 struct ecommunity
*new_ecom
;
1154 /* Export with the 'from' instance's export RTs. */
1155 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1156 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1158 new_ecom
= ecommunity_dup(old_ecom
);
1159 if (CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1160 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1161 ecommunity_strip_rts(new_ecom
);
1162 new_ecom
= ecommunity_merge(
1163 new_ecom
, from_bgp
->vpn_policy
[afi
]
1164 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1165 if (!old_ecom
->refcnt
)
1166 ecommunity_free(&old_ecom
);
1168 new_ecom
= ecommunity_dup(
1169 from_bgp
->vpn_policy
[afi
]
1170 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1172 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1174 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1175 char *s
= ecommunity_ecom2str(
1176 bgp_attr_get_ecommunity(&static_attr
),
1177 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1179 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1181 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1185 /* if policy nexthop not set, use 0 */
1186 if (CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1187 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1188 struct prefix
*nexthop
=
1189 &from_bgp
->vpn_policy
[afi
].tovpn_nexthop
;
1191 switch (nexthop
->family
) {
1193 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1195 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1197 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1198 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1202 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1203 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1210 if (!CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1211 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1212 if (afi
== AFI_IP
) {
1214 * For ipv4, copy to multiprotocol
1217 static_attr
.mp_nexthop_global_in
=
1218 static_attr
.nexthop
;
1219 static_attr
.mp_nexthop_len
=
1220 BGP_ATTR_NHLEN_IPV4
;
1222 * XXX Leave static_attr.nexthop
1226 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1229 /* Update based on next-hop family to account for
1230 * RFC 5549 (BGP unnumbered) scenario. Note that
1231 * specific action is only needed for the case of
1232 * IPv4 nexthops as the attr has been copied
1236 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1237 static_attr
.mp_nexthop_global_in
.s_addr
=
1238 static_attr
.nexthop
.s_addr
;
1239 static_attr
.mp_nexthop_len
=
1240 BGP_ATTR_NHLEN_IPV4
;
1242 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1245 nexthop_self_flag
= 1;
1248 label_val
= from_bgp
->vpn_policy
[afi
].tovpn_label
;
1249 if (label_val
== MPLS_LABEL_NONE
) {
1250 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1252 encode_label(label_val
, &label
);
1255 /* Set originator ID to "me" */
1256 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1257 static_attr
.originator_id
= to_bgp
->router_id
;
1259 /* Set SID for SRv6 VPN */
1260 if (from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
) {
1262 from_bgp
->vpn_policy
[afi
].tovpn_sid_transpose_label
,
1264 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1265 sizeof(struct bgp_attr_srv6_l3vpn
));
1266 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1267 static_attr
.srv6_l3vpn
->endpoint_behavior
= 0xffff;
1268 static_attr
.srv6_l3vpn
->loc_block_len
=
1269 BGP_PREFIX_SID_SRV6_LOCATOR_BLOCK_LENGTH
;
1270 static_attr
.srv6_l3vpn
->loc_node_len
=
1271 BGP_PREFIX_SID_SRV6_LOCATOR_NODE_LENGTH
;
1272 static_attr
.srv6_l3vpn
->func_len
=
1273 BGP_PREFIX_SID_SRV6_FUNCTION_LENGTH
;
1274 static_attr
.srv6_l3vpn
->arg_len
=
1275 BGP_PREFIX_SID_SRV6_ARGUMENT_LENGTH
;
1276 static_attr
.srv6_l3vpn
->transposition_len
=
1277 BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH
;
1278 static_attr
.srv6_l3vpn
->transposition_offset
=
1279 BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET
;
1280 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1281 from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
,
1282 sizeof(struct in6_addr
));
1286 new_attr
= bgp_attr_intern(
1287 &static_attr
); /* hashed refcounted everything */
1288 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1290 if (debug
&& bgp_attr_get_ecommunity(new_attr
)) {
1291 char *s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr
),
1292 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1294 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1295 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1298 /* Now new_attr is an allocated interned attr */
1300 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1301 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1303 struct bgp_path_info
*new_info
;
1306 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vrf
, &label
,
1307 1, from_bgp
, NULL
, nexthop_self_flag
, debug
);
1310 * Routes actually installed in the vpn RIB must also be
1311 * offered to all vrfs (because now they originate from
1314 * Acceptance into other vrfs depends on rt-lists.
1315 * Originating vrf will not accept the looped back route
1316 * because of loop checking.
1319 vpn_leak_to_vrf_update(from_bgp
, new_info
);
1322 void vpn_leak_from_vrf_withdraw(struct bgp
*to_bgp
, /* to */
1323 struct bgp
*from_bgp
, /* from */
1324 struct bgp_path_info
*path_vrf
) /* route */
1326 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1327 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1328 afi_t afi
= family2afi(p
->family
);
1329 safi_t safi
= SAFI_MPLS_VPN
;
1330 struct bgp_path_info
*bpi
;
1331 struct bgp_dest
*bn
;
1332 const char *debugmsg
;
1336 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1337 __func__
, from_bgp
->name_pretty
, path_vrf
->net
,
1338 path_vrf
->type
, path_vrf
->sub_type
);
1346 zlog_debug("%s: can't get afi of prefix", __func__
);
1350 /* Is this route exportable into the VPN table? */
1351 if (!is_route_injectable_into_vpn(path_vrf
))
1354 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1356 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1361 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1363 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1364 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1370 * match original bpi imported from
1372 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1373 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1379 /* withdraw from looped vrfs as well */
1380 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1382 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1383 bgp_path_info_delete(bn
, bpi
);
1384 bgp_process(to_bgp
, bn
, afi
, safi
);
1386 bgp_dest_unlock_node(bn
);
1389 void vpn_leak_from_vrf_withdraw_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1392 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1393 struct bgp_dest
*pdest
;
1394 safi_t safi
= SAFI_MPLS_VPN
;
1397 * Walk vpn table, delete bpi with bgp_orig == from_bgp
1399 for (pdest
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); pdest
;
1400 pdest
= bgp_route_next(pdest
)) {
1402 struct bgp_table
*table
;
1403 struct bgp_dest
*bn
;
1404 struct bgp_path_info
*bpi
;
1406 /* This is the per-RD table of prefixes */
1407 table
= bgp_dest_get_bgp_table_info(pdest
);
1412 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1413 bpi
= bgp_dest_get_bgp_path_info(bn
);
1415 zlog_debug("%s: looking at prefix %pBD",
1419 for (; bpi
; bpi
= bpi
->next
) {
1421 zlog_debug("%s: type %d, sub_type %d",
1422 __func__
, bpi
->type
,
1424 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1428 if ((struct bgp
*)bpi
->extra
->bgp_orig
==
1432 zlog_debug("%s: deleting it",
1434 /* withdraw from leak-to vrfs as well */
1435 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1436 bgp_aggregate_decrement(
1437 to_bgp
, bgp_dest_get_prefix(bn
),
1439 bgp_path_info_delete(bn
, bpi
);
1440 bgp_process(to_bgp
, bn
, afi
, safi
);
1447 void vpn_leak_from_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1450 struct bgp_dest
*bn
;
1451 struct bgp_path_info
*bpi
;
1452 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1455 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1456 from_bgp
->name_pretty
);
1458 for (bn
= bgp_table_top(from_bgp
->rib
[afi
][SAFI_UNICAST
]); bn
;
1459 bn
= bgp_route_next(bn
)) {
1462 zlog_debug("%s: node=%p", __func__
, bn
);
1464 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1468 "%s: calling vpn_leak_from_vrf_update",
1470 vpn_leak_from_vrf_update(to_bgp
, from_bgp
, bpi
);
1476 vpn_leak_to_vrf_update_onevrf(struct bgp
*to_bgp
, /* to */
1477 struct bgp
*from_bgp
, /* from */
1478 struct bgp_path_info
*path_vpn
) /* route */
1480 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1481 afi_t afi
= family2afi(p
->family
);
1483 struct attr static_attr
= {0};
1484 struct attr
*new_attr
= NULL
;
1485 struct bgp_dest
*bn
;
1486 safi_t safi
= SAFI_UNICAST
;
1487 const char *debugmsg
;
1488 struct prefix nexthop_orig
;
1489 mpls_label_t
*pLabels
= NULL
;
1490 uint32_t num_labels
= 0;
1491 int nexthop_self_flag
= 1;
1492 struct bgp_path_info
*bpi_ultimate
= NULL
;
1493 int origin_local
= 0;
1494 struct bgp
*src_vrf
;
1496 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1498 if (!vpn_leak_from_vpn_active(to_bgp
, afi
, &debugmsg
)) {
1500 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1504 /* Check for intersection of route targets */
1505 if (!ecom_intersect(
1506 to_bgp
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1507 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1510 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
1511 from_bgp
->name_pretty
, to_bgp
->name_pretty
);
1516 zlog_debug("%s: updating %pFX to vrf %s", __func__
, p
,
1517 to_bgp
->name_pretty
);
1520 static_attr
= *path_vpn
->attr
;
1522 struct ecommunity
*old_ecom
;
1523 struct ecommunity
*new_ecom
;
1525 /* If doing VRF-to-VRF leaking, strip RTs. */
1526 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1527 if (old_ecom
&& CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1528 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1529 new_ecom
= ecommunity_dup(old_ecom
);
1530 ecommunity_strip_rts(new_ecom
);
1531 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1533 if (new_ecom
->size
== 0) {
1534 ecommunity_free(&new_ecom
);
1535 bgp_attr_set_ecommunity(&static_attr
, NULL
);
1538 if (!old_ecom
->refcnt
)
1539 ecommunity_free(&old_ecom
);
1543 * Nexthop: stash and clear
1545 * Nexthop is valid in context of VPN core, but not in destination vrf.
1546 * Stash it for later label resolution by vrf ingress path and then
1547 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1549 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1551 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1552 nexthop_orig
.family
= nhfamily
;
1557 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1558 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
1560 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1561 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1562 static_attr
.nexthop
.s_addr
=
1563 nexthop_orig
.u
.prefix4
.s_addr
;
1565 static_attr
.mp_nexthop_global_in
=
1566 path_vpn
->attr
->mp_nexthop_global_in
;
1567 static_attr
.mp_nexthop_len
=
1568 path_vpn
->attr
->mp_nexthop_len
;
1570 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1574 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1575 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
1577 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1578 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1579 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1585 * route map handling
1587 if (to_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1588 struct bgp_path_info info
;
1589 route_map_result_t ret
;
1591 memset(&info
, 0, sizeof(info
));
1592 info
.peer
= to_bgp
->peer_self
;
1593 info
.attr
= &static_attr
;
1594 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1595 ret
= route_map_apply(to_bgp
->vpn_policy
[afi
]
1596 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1598 if (RMAP_DENYMATCH
== ret
) {
1599 bgp_attr_flush(&static_attr
); /* free any added parts */
1602 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1603 __func__
, to_bgp
->name_pretty
,
1604 to_bgp
->vpn_policy
[afi
]
1605 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1610 * if route-map changed nexthop, don't nexthop-self on output
1612 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1613 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1614 nexthop_self_flag
= 0;
1617 new_attr
= bgp_attr_intern(&static_attr
);
1618 bgp_attr_flush(&static_attr
);
1620 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1623 * ensure labels are copied
1625 * However, there is a special case: if the route originated in
1626 * another local VRF (as opposed to arriving via VPN), then the
1627 * nexthop is reached by hairpinning through this router (me)
1628 * using IP forwarding only (no LSP). Therefore, the route
1629 * imported to the VRF should not have labels attached. Note
1630 * that nexthop tracking is also involved: eliminating the
1631 * labels for these routes enables the non-labeled nexthops
1632 * from the originating VRF to be considered valid for this route.
1634 if (!CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1635 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1636 /* work back to original route */
1637 bpi_ultimate
= bgp_get_imported_bpi_ultimate(path_vpn
);
1640 * if original route was unicast,
1641 * then it did not arrive over vpn
1643 if (bpi_ultimate
->net
) {
1644 struct bgp_table
*table
;
1646 table
= bgp_dest_table(bpi_ultimate
->net
);
1647 if (table
&& (table
->safi
== SAFI_UNICAST
))
1652 if (!origin_local
&& path_vpn
->extra
1653 && path_vpn
->extra
->num_labels
) {
1654 num_labels
= path_vpn
->extra
->num_labels
;
1655 if (num_labels
> BGP_MAX_LABELS
)
1656 num_labels
= BGP_MAX_LABELS
;
1657 pLabels
= path_vpn
->extra
->label
;
1662 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
1663 path_vpn
->net
, num_labels
);
1666 * For VRF-2-VRF route-leaking,
1667 * the source will be the originating VRF.
1669 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1670 src_vrf
= path_vpn
->extra
->bgp_orig
;
1674 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
1675 num_labels
, src_vrf
, &nexthop_orig
, nexthop_self_flag
,
1680 bool vpn_leak_to_vrf_update(struct bgp
*from_bgp
, /* from */
1681 struct bgp_path_info
*path_vpn
) /* route */
1683 struct listnode
*mnode
, *mnnode
;
1685 bool leak_success
= false;
1687 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1690 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1692 /* Loop over VRFs */
1693 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1695 if (!path_vpn
->extra
1696 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1697 leak_success
|= vpn_leak_to_vrf_update_onevrf(
1698 bgp
, from_bgp
, path_vpn
);
1701 return leak_success
;
1704 void vpn_leak_to_vrf_withdraw(struct bgp
*from_bgp
, /* from */
1705 struct bgp_path_info
*path_vpn
) /* route */
1707 const struct prefix
*p
;
1709 safi_t safi
= SAFI_UNICAST
;
1711 struct listnode
*mnode
, *mnnode
;
1712 struct bgp_dest
*bn
;
1713 struct bgp_path_info
*bpi
;
1714 const char *debugmsg
;
1716 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1719 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
1720 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
1723 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1725 if (!path_vpn
->net
) {
1726 #ifdef ENABLE_BGP_VNC
1727 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1728 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
1729 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1736 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1741 p
= bgp_dest_get_prefix(path_vpn
->net
);
1742 afi
= family2afi(p
->family
);
1744 /* Loop over VRFs */
1745 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1746 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1748 zlog_debug("%s: skipping: %s", __func__
,
1753 /* Check for intersection of route targets */
1754 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1755 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1756 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1762 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1765 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1767 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1770 && (struct bgp_path_info
*)bpi
->extra
->parent
1778 zlog_debug("%s: deleting bpi %p", __func__
,
1780 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
1781 bgp_path_info_delete(bn
, bpi
);
1782 bgp_process(bgp
, bn
, afi
, safi
);
1784 bgp_dest_unlock_node(bn
);
1788 void vpn_leak_to_vrf_withdraw_all(struct bgp
*to_bgp
, afi_t afi
)
1790 struct bgp_dest
*bn
;
1791 struct bgp_path_info
*bpi
;
1792 safi_t safi
= SAFI_UNICAST
;
1793 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1796 zlog_debug("%s: entry", __func__
);
1798 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1800 for (bn
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); bn
;
1801 bn
= bgp_route_next(bn
)) {
1803 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1805 if (bpi
->extra
&& bpi
->extra
->bgp_orig
!= to_bgp
&&
1806 bpi
->extra
->parent
&&
1807 is_pi_family_vpn(bpi
->extra
->parent
)) {
1810 bgp_aggregate_decrement(to_bgp
,
1811 bgp_dest_get_prefix(bn
),
1813 bgp_path_info_delete(bn
, bpi
);
1814 bgp_process(to_bgp
, bn
, afi
, safi
);
1820 void vpn_leak_to_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*vpn_from
,
1823 struct bgp_dest
*pdest
;
1824 safi_t safi
= SAFI_MPLS_VPN
;
1831 for (pdest
= bgp_table_top(vpn_from
->rib
[afi
][safi
]); pdest
;
1832 pdest
= bgp_route_next(pdest
)) {
1833 struct bgp_table
*table
;
1834 struct bgp_dest
*bn
;
1835 struct bgp_path_info
*bpi
;
1837 /* This is the per-RD table of prefixes */
1838 table
= bgp_dest_get_bgp_table_info(pdest
);
1843 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1845 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1849 bpi
->extra
->bgp_orig
== to_bgp
)
1852 vpn_leak_to_vrf_update_onevrf(to_bgp
, vpn_from
,
1860 * This function is called for definition/deletion/change to a route-map
1862 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1864 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1866 struct route_map
*rmap
;
1868 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1869 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1874 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1876 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1878 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1879 && !strcmp(rmap_name
,
1880 bgp
->vpn_policy
[afi
]
1881 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1885 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1886 __func__
, rmap_name
, bgp
->as
,
1889 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1890 bgp_get_default(), bgp
);
1892 zlog_debug("%s: after vpn_leak_prechange",
1895 /* in case of definition/deletion */
1896 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1899 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1900 bgp_get_default(), bgp
);
1903 zlog_debug("%s: after vpn_leak_postchange",
1907 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1908 && !strcmp(rmap_name
,
1909 bgp
->vpn_policy
[afi
]
1910 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1913 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1914 __func__
, rmap_name
, bgp
->as
,
1918 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1919 bgp_get_default(), bgp
);
1921 /* in case of definition/deletion */
1922 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1925 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1926 bgp_get_default(), bgp
);
1931 /* This API is used during router-id change, reflect VPNs
1932 * auto RD and RT values and readvertise routes to VPN table.
1934 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
1938 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
1939 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1941 const char *export_name
;
1942 char buf
[RD_ADDRSTRLEN
];
1943 struct bgp
*bgp_import
;
1944 struct listnode
*node
;
1945 struct ecommunity
*ecom
;
1946 enum vpn_policy_direction idir
, edir
;
1949 * Router-id change that is not explicitly configured
1950 * (a change from zebra, frr restart for example)
1951 * should not replace a configured vpn RD/RT.
1955 zlog_debug("%s: skipping non explicit router-id change",
1960 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1961 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1964 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1965 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1966 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1968 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1969 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
1973 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
1974 afi
, bgp_get_default(), bgp
);
1976 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1977 __func__
, export_name
);
1979 /* Remove import RT from VRFs */
1980 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1981 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1982 export_vrf
, node
, vname
)) {
1983 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1984 bgp_import
= bgp_get_default();
1986 bgp_import
= bgp_lookup_by_name(vname
);
1991 bgp_import
->vpn_policy
[afi
]
1993 (struct ecommunity_val
*)ecom
->val
);
1996 /* New router-id derive auto RD and RT and export
1999 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
2000 &bgp
->vrf_prd_auto
);
2001 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
2002 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2004 bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2005 ecommunity_str2com(buf
,
2006 ECOMMUNITY_ROUTE_TARGET
, 0);
2008 /* Update import_vrf rt_list */
2009 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2010 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2011 export_vrf
, node
, vname
)) {
2012 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2013 bgp_import
= bgp_get_default();
2015 bgp_import
= bgp_lookup_by_name(vname
);
2018 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
2019 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2021 bgp_import
->vpn_policy
[afi
]
2022 .rtlist
[idir
], ecom
);
2024 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2025 = ecommunity_dup(ecom
);
2028 /* Update routes to VPN */
2029 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
2030 afi
, bgp_get_default(),
2033 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2034 __func__
, export_name
);
2039 void vpn_policy_routemap_event(const char *rmap_name
)
2041 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2042 struct listnode
*mnode
, *mnnode
;
2046 zlog_debug("%s: entry", __func__
);
2048 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2051 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2052 vpn_policy_routemap_update(bgp
, rmap_name
);
2055 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2056 afi_t afi
, safi_t safi
)
2058 const char *export_name
;
2059 enum vpn_policy_direction idir
, edir
;
2060 char *vname
, *tmp_name
;
2061 char buf
[RD_ADDRSTRLEN
];
2062 struct ecommunity
*ecom
;
2063 bool first_export
= false;
2065 struct listnode
*node
;
2066 bool is_inst_match
= false;
2068 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2069 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2070 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2072 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2073 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2076 * Cross-ref both VRFs. Also, note if this is the first time
2077 * any VRF is importing from "import_vrf".
2079 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2080 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2082 /* Check the import_vrf list of destination vrf for the source vrf name,
2085 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2087 if (strcmp(vname
, tmp_name
) == 0) {
2088 is_inst_match
= true;
2093 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2096 XFREE(MTYPE_TMP
, vname
);
2098 /* Check if the source vrf already exports to any vrf,
2099 * first time export requires to setup auto derived RD/RT values.
2100 * Add the destination vrf name to export vrf list if it is
2103 is_inst_match
= false;
2104 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2105 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2106 first_export
= true;
2108 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2110 if (strcmp(vname
, tmp_name
) == 0) {
2111 is_inst_match
= true;
2117 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2120 XFREE(MTYPE_TMP
, vname
);
2122 /* Update import RT for current VRF using export RT of the VRF we're
2123 * importing from. First though, make sure "import_vrf" has that
2127 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2128 &from_bgp
->vrf_prd_auto
);
2129 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2130 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2131 BGP_VPN_POLICY_TOVPN_RD_SET
);
2132 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
2134 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2135 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2136 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2137 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2138 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2139 BGP_PREVENT_VRF_2_VRF_LEAK
;
2141 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2142 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2143 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2144 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2145 .rtlist
[idir
], ecom
);
2147 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2148 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2151 const char *from_name
;
2152 char *ecom1
, *ecom2
;
2154 from_name
= from_bgp
->name
? from_bgp
->name
:
2157 ecom1
= ecommunity_ecom2str(
2158 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2159 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2161 ecom2
= ecommunity_ecom2str(
2162 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2163 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2166 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2167 __func__
, from_name
, export_name
, first_export
, ecom1
,
2170 ecommunity_strfree(&ecom1
);
2171 ecommunity_strfree(&ecom2
);
2174 /* Does "import_vrf" first need to export its routes or that
2175 * is already done and we just need to import those routes
2176 * from the global table?
2179 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2181 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2184 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2185 afi_t afi
, safi_t safi
)
2187 const char *export_name
, *tmp_name
;
2188 enum vpn_policy_direction idir
, edir
;
2190 struct ecommunity
*ecom
= NULL
;
2191 struct listnode
*node
;
2194 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2195 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2196 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2197 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2199 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2200 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2202 /* Were we importing from "import_vrf"? */
2203 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2205 if (strcmp(vname
, tmp_name
) == 0)
2210 * We do not check in the cli if the passed in bgp
2211 * instance is actually imported into us before
2212 * we call this function. As such if we do not
2213 * find this in the import_vrf list than
2214 * we just need to return safely.
2220 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2222 /* Remove "import_vrf" from our import list. */
2223 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2224 XFREE(MTYPE_TMP
, vname
);
2226 /* Remove routes imported from "import_vrf". */
2227 /* TODO: In the current logic, we have to first remove all
2228 * imported routes and then (if needed) import back routes
2230 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2232 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2233 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2234 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2235 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2236 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2237 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2239 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2241 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2242 (struct ecommunity_val
*)ecom
->val
);
2243 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2248 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2249 * below is checking for NULL that export_vrf can be
2250 * NULL, consequently it is complaining( like a cabbage )
2251 * that we could dereference and crash in the listcount(..)
2253 * So make it happy, under protest, with liberty and justice
2256 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2258 /* Remove us from "import_vrf's" export list. If no other VRF
2259 * is importing from "import_vrf", cleanup appropriately.
2261 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2263 if (strcmp(vname
, export_name
) == 0)
2268 * If we have gotten to this point then the vname must
2269 * exist. If not, we are in a world of trouble and
2270 * have slag sitting around.
2272 * import_vrf and export_vrf must match in having
2273 * the in/out names as appropriate.
2274 * export_vrf list could have been cleaned up
2275 * as part of no router bgp source instnace.
2280 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2281 XFREE(MTYPE_TMP
, vname
);
2283 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2284 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2285 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2286 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2287 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2288 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2289 sizeof(struct prefix_rd
));
2290 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2291 BGP_VPN_POLICY_TOVPN_RD_SET
);
2292 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2297 /* For testing purpose, static route of MPLS-VPN. */
2298 DEFUN (vpnv4_network
,
2300 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2301 "Specify a network to announce via BGP\n"
2303 "Specify Route Distinguisher\n"
2304 "VPN Route Distinguisher\n"
2305 "VPN NLRI label (tag)\n"
2306 "VPN NLRI label (tag)\n"
2309 int idx_ipv4_prefixlen
= 1;
2310 int idx_ext_community
= 3;
2312 return bgp_static_set_safi(
2313 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2314 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
2315 NULL
, NULL
, NULL
, NULL
);
2318 DEFUN (vpnv4_network_route_map
,
2319 vpnv4_network_route_map_cmd
,
2320 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
2321 "Specify a network to announce via BGP\n"
2323 "Specify Route Distinguisher\n"
2324 "VPN Route Distinguisher\n"
2325 "VPN NLRI label (tag)\n"
2326 "VPN NLRI label (tag)\n"
2331 int idx_ipv4_prefixlen
= 1;
2332 int idx_ext_community
= 3;
2335 return bgp_static_set_safi(
2336 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2337 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2338 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2341 /* For testing purpose, static route of MPLS-VPN. */
2342 DEFUN (no_vpnv4_network
,
2343 no_vpnv4_network_cmd
,
2344 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2346 "Specify a network to announce via BGP\n"
2348 "Specify Route Distinguisher\n"
2349 "VPN Route Distinguisher\n"
2350 "VPN NLRI label (tag)\n"
2351 "VPN NLRI label (tag)\n"
2354 int idx_ipv4_prefixlen
= 2;
2355 int idx_ext_community
= 4;
2357 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
2358 argv
[idx_ipv4_prefixlen
]->arg
,
2359 argv
[idx_ext_community
]->arg
,
2360 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2363 DEFUN (vpnv6_network
,
2365 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
2366 "Specify a network to announce via BGP\n"
2367 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2368 "Specify Route Distinguisher\n"
2369 "VPN Route Distinguisher\n"
2370 "VPN NLRI label (tag)\n"
2371 "VPN NLRI label (tag)\n"
2376 int idx_ipv6_prefix
= 1;
2377 int idx_ext_community
= 3;
2381 return bgp_static_set_safi(
2382 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2383 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2384 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2386 return bgp_static_set_safi(
2387 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2388 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2389 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2392 /* For testing purpose, static route of MPLS-VPN. */
2393 DEFUN (no_vpnv6_network
,
2394 no_vpnv6_network_cmd
,
2395 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2397 "Specify a network to announce via BGP\n"
2398 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2399 "Specify Route Distinguisher\n"
2400 "VPN Route Distinguisher\n"
2401 "VPN NLRI label (tag)\n"
2402 "VPN NLRI label (tag)\n"
2405 int idx_ipv6_prefix
= 2;
2406 int idx_ext_community
= 4;
2408 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2409 argv
[idx_ipv6_prefix
]->arg
,
2410 argv
[idx_ext_community
]->arg
,
2411 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2414 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2415 enum bgp_show_type type
, void *output_arg
, int tags
,
2419 struct bgp_table
*table
;
2421 bgp
= bgp_get_default();
2424 vty_out(vty
, "No BGP process is configured\n");
2426 vty_out(vty
, "{}\n");
2429 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2430 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2431 output_arg
, use_json
);
2434 DEFUN (show_bgp_ip_vpn_all_rd
,
2435 show_bgp_ip_vpn_all_rd_cmd
,
2436 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2440 "Display VPN NLRI specific information\n"
2441 "Display VPN NLRI specific information\n"
2442 "Display information for a route distinguisher\n"
2443 "VPN Route Distinguisher\n"
2444 "All VPN Route Distinguishers\n"
2448 struct prefix_rd prd
;
2452 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2453 /* Constrain search if user supplies RD && RD != "all" */
2454 if (argv_find(argv
, argc
, "rd", &idx
)
2455 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
2456 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2459 "%% Malformed Route Distinguisher\n");
2462 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2463 bgp_show_type_normal
, NULL
, 0,
2464 use_json(argc
, argv
));
2466 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2467 bgp_show_type_normal
, NULL
, 0,
2468 use_json(argc
, argv
));
2474 ALIAS(show_bgp_ip_vpn_all_rd
,
2475 show_bgp_ip_vpn_rd_cmd
,
2476 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2480 "Display VPN NLRI specific information\n"
2481 "Display information for a route distinguisher\n"
2482 "VPN Route Distinguisher\n"
2483 "All VPN Route Distinguishers\n"
2486 #ifdef KEEP_OLD_VPN_COMMANDS
2487 DEFUN (show_ip_bgp_vpn_rd
,
2488 show_ip_bgp_vpn_rd_cmd
,
2489 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2494 "Address Family modifier\n"
2495 "Display information for a route distinguisher\n"
2496 "VPN Route Distinguisher\n"
2497 "All VPN Route Distinguishers\n")
2499 int idx_ext_community
= argc
- 1;
2501 struct prefix_rd prd
;
2505 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2506 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2507 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2508 bgp_show_type_normal
, NULL
, 0,
2510 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2512 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2515 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2521 DEFUN (show_ip_bgp_vpn_all
,
2522 show_ip_bgp_vpn_all_cmd
,
2523 "show [ip] bgp <vpnv4|vpnv6>",
2532 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2533 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2538 DEFUN (show_ip_bgp_vpn_all_tags
,
2539 show_ip_bgp_vpn_all_tags_cmd
,
2540 "show [ip] bgp <vpnv4|vpnv6> all tags",
2545 "Display information about all VPNv4/VPNV6 NLRIs\n"
2546 "Display BGP tags for prefixes\n")
2551 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2552 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2557 DEFUN (show_ip_bgp_vpn_rd_tags
,
2558 show_ip_bgp_vpn_rd_tags_cmd
,
2559 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2564 "Display information for a route distinguisher\n"
2565 "VPN Route Distinguisher\n"
2566 "All VPN Route Distinguishers\n"
2567 "Display BGP tags for prefixes\n")
2569 int idx_ext_community
= 5;
2571 struct prefix_rd prd
;
2575 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2576 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2577 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2578 bgp_show_type_normal
, NULL
, 1,
2580 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2582 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2585 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2591 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2592 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2593 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2598 "Display information about all VPNv4/VPNv6 NLRIs\n"
2599 "Detailed information on TCP and BGP neighbor connections\n"
2600 "Neighbor to display information about\n"
2601 "Display routes learned from neighbor\n"
2608 bool uj
= use_json(argc
, argv
);
2612 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2613 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2616 json_object
*json_no
= NULL
;
2617 json_no
= json_object_new_object();
2618 json_object_string_add(json_no
, "warning",
2619 "Malformed address");
2620 vty_out(vty
, "%s\n",
2621 json_object_to_json_string(json_no
));
2622 json_object_free(json_no
);
2624 vty_out(vty
, "Malformed address: %s\n",
2625 argv
[idx_ipv4
]->arg
);
2629 peer
= peer_lookup(NULL
, &su
);
2630 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2632 json_object
*json_no
= NULL
;
2633 json_no
= json_object_new_object();
2634 json_object_string_add(
2636 "No such neighbor or address family");
2637 vty_out(vty
, "%s\n",
2638 json_object_to_json_string(json_no
));
2639 json_object_free(json_no
);
2642 "%% No such neighbor or address family\n");
2646 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2652 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2653 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2654 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
2659 "Display information for a route distinguisher\n"
2660 "VPN Route Distinguisher\n"
2661 "All VPN Route Distinguishers\n"
2662 "Detailed information on TCP and BGP neighbor connections\n"
2663 "Neighbor to display information about\n"
2664 "Display routes learned from neighbor\n"
2667 int idx_ext_community
= 5;
2672 struct prefix_rd prd
;
2673 bool prefix_rd_all
= false;
2674 bool uj
= use_json(argc
, argv
);
2678 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2679 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2680 prefix_rd_all
= true;
2682 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2685 json_object
*json_no
= NULL
;
2686 json_no
= json_object_new_object();
2687 json_object_string_add(
2689 "Malformed Route Distinguisher");
2690 vty_out(vty
, "%s\n",
2691 json_object_to_json_string(
2693 json_object_free(json_no
);
2696 "%% Malformed Route Distinguisher\n");
2701 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2704 json_object
*json_no
= NULL
;
2705 json_no
= json_object_new_object();
2706 json_object_string_add(json_no
, "warning",
2707 "Malformed address");
2708 vty_out(vty
, "%s\n",
2709 json_object_to_json_string(json_no
));
2710 json_object_free(json_no
);
2712 vty_out(vty
, "Malformed address: %s\n",
2713 argv
[idx_ext_community
]->arg
);
2717 peer
= peer_lookup(NULL
, &su
);
2718 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2720 json_object
*json_no
= NULL
;
2721 json_no
= json_object_new_object();
2722 json_object_string_add(
2724 "No such neighbor or address family");
2725 vty_out(vty
, "%s\n",
2726 json_object_to_json_string(json_no
));
2727 json_object_free(json_no
);
2730 "%% No such neighbor or address family\n");
2735 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2736 bgp_show_type_neighbor
, &su
, 0,
2739 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2740 bgp_show_type_neighbor
, &su
, 0,
2746 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2747 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2748 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2753 "Display information about all VPNv4/VPNv6 NLRIs\n"
2754 "Detailed information on TCP and BGP neighbor connections\n"
2755 "Neighbor to display information about\n"
2756 "Display the routes advertised to a BGP neighbor\n"
2763 bool uj
= use_json(argc
, argv
);
2767 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2768 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2771 json_object
*json_no
= NULL
;
2772 json_no
= json_object_new_object();
2773 json_object_string_add(json_no
, "warning",
2774 "Malformed address");
2775 vty_out(vty
, "%s\n",
2776 json_object_to_json_string(json_no
));
2777 json_object_free(json_no
);
2779 vty_out(vty
, "Malformed address: %s\n",
2780 argv
[idx_ipv4
]->arg
);
2783 peer
= peer_lookup(NULL
, &su
);
2784 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2786 json_object
*json_no
= NULL
;
2787 json_no
= json_object_new_object();
2788 json_object_string_add(
2790 "No such neighbor or address family");
2791 vty_out(vty
, "%s\n",
2792 json_object_to_json_string(json_no
));
2793 json_object_free(json_no
);
2796 "%% No such neighbor or address family\n");
2799 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2805 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2806 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2807 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
2812 "Display information for a route distinguisher\n"
2813 "VPN Route Distinguisher\n"
2814 "All VPN Route Distinguishers\n"
2815 "Detailed information on TCP and BGP neighbor connections\n"
2816 "Neighbor to display information about\n"
2817 "Display the routes advertised to a BGP neighbor\n"
2820 int idx_ext_community
= 5;
2824 struct prefix_rd prd
;
2826 bool uj
= use_json(argc
, argv
);
2830 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2831 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2834 json_object
*json_no
= NULL
;
2835 json_no
= json_object_new_object();
2836 json_object_string_add(json_no
, "warning",
2837 "Malformed address");
2838 vty_out(vty
, "%s\n",
2839 json_object_to_json_string(json_no
));
2840 json_object_free(json_no
);
2842 vty_out(vty
, "Malformed address: %s\n",
2843 argv
[idx_ext_community
]->arg
);
2846 peer
= peer_lookup(NULL
, &su
);
2847 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2849 json_object
*json_no
= NULL
;
2850 json_no
= json_object_new_object();
2851 json_object_string_add(
2853 "No such neighbor or address family");
2854 vty_out(vty
, "%s\n",
2855 json_object_to_json_string(json_no
));
2856 json_object_free(json_no
);
2859 "%% No such neighbor or address family\n");
2863 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2864 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2866 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2869 json_object
*json_no
= NULL
;
2870 json_no
= json_object_new_object();
2871 json_object_string_add(
2873 "Malformed Route Distinguisher");
2874 vty_out(vty
, "%s\n",
2875 json_object_to_json_string(json_no
));
2876 json_object_free(json_no
);
2879 "%% Malformed Route Distinguisher\n");
2883 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2888 #endif /* KEEP_OLD_VPN_COMMANDS */
2890 void bgp_mplsvpn_init(void)
2892 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2893 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2894 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2896 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2897 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2899 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2900 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2901 #ifdef KEEP_OLD_VPN_COMMANDS
2902 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2903 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2904 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2905 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2906 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2907 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2908 install_element(VIEW_NODE
,
2909 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2910 install_element(VIEW_NODE
,
2911 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2912 #endif /* KEEP_OLD_VPN_COMMANDS */
2915 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2917 struct listnode
*mnode
, *mnnode
;
2921 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
2924 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2925 struct ecommunity
*ec
;
2927 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2930 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
2932 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
2935 if (ecom_intersect(ec
, eckey
))
2942 * The purpose of this function is to process leaks that were deferred
2943 * from earlier per-vrf configuration due to not-yet-existing default
2944 * vrf, in other words, configuration such as:
2946 * router bgp MMM vrf FOO
2947 * address-family ipv4 unicast
2949 * exit-address-family
2954 * This function gets called when the default instance ("router bgp NNN")
2957 void vpn_leak_postchange_all(void)
2959 struct listnode
*next
;
2961 struct bgp
*bgp_default
= bgp_get_default();
2963 assert(bgp_default
);
2965 /* First, do any exporting from VRFs to the single VPN RIB */
2966 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2968 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2971 vpn_leak_postchange(
2972 BGP_VPN_POLICY_DIR_TOVPN
,
2977 vpn_leak_postchange(
2978 BGP_VPN_POLICY_DIR_TOVPN
,
2984 /* Now, do any importing to VRFs from the single VPN RIB */
2985 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2987 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2990 vpn_leak_postchange(
2991 BGP_VPN_POLICY_DIR_FROMVPN
,
2996 vpn_leak_postchange(
2997 BGP_VPN_POLICY_DIR_FROMVPN
,
3004 /* When a bgp vrf instance is unconfigured, remove its routes
3005 * from the VPN table and this vrf could be importing routes from other
3006 * bgp vrf instnaces, unimport them.
3007 * VRF X and VRF Y are exporting routes to each other.
3008 * When VRF X is deleted, unimport its routes from all target vrfs,
3009 * also VRF Y should unimport its routes from VRF X table.
3010 * This will ensure VPN table is cleaned up appropriately.
3012 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
3015 const char *tmp_name
;
3017 struct listnode
*node
, *next
;
3018 safi_t safi
= SAFI_UNICAST
;
3020 bool is_vrf_leak_bind
;
3023 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3026 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3027 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3029 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3031 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3032 /* vrf leak is for IPv4 and IPv6 Unicast only */
3033 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3036 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3037 if (from_bgp
== to_bgp
)
3040 /* Unimport and remove source vrf from the
3041 * other vrfs import list.
3043 struct vpn_policy
*to_vpolicy
;
3045 is_vrf_leak_bind
= false;
3046 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3047 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
3049 if (strcmp(vname
, tmp_name
) == 0) {
3050 is_vrf_leak_bind
= true;
3054 /* skip this bgp instance as there is no leak to this
3057 if (!is_vrf_leak_bind
)
3061 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3062 __func__
, from_bgp
->name_pretty
,
3063 to_bgp
->name_pretty
, afi2str(afi
),
3064 to_vpolicy
->import_vrf
->count
);
3066 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
3068 /* readd vrf name as unimport removes import vrf name
3069 * from the destination vrf's import list where the
3070 * `import vrf` configuration still exist.
3072 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
3073 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
3075 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
3076 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
3078 /* If to_bgp exports its routes to the bgp vrf
3079 * which is being deleted, un-import the
3080 * to_bgp routes from VPN.
3082 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3085 if (strcmp(vname
, tmp_name
) == 0) {
3086 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3096 /* When a router bgp is configured, there could be a bgp vrf
3097 * instance importing routes from this newly configured
3098 * bgp vrf instance. Export routes from configured
3100 * VRF Y has import from bgp vrf x,
3101 * when a bgp vrf x instance is created, export its routes
3102 * to VRF Y instance.
3104 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3107 const char *export_name
;
3109 struct listnode
*node
, *next
;
3110 struct ecommunity
*ecom
;
3111 enum vpn_policy_direction idir
, edir
;
3112 safi_t safi
= SAFI_UNICAST
;
3116 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3117 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3119 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3120 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3122 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3124 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3125 /* vrf leak is for IPv4 and IPv6 Unicast only */
3126 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3129 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3130 if (from_bgp
== to_bgp
)
3133 /* bgp instance has import list, check to see if newly
3134 * configured bgp instance is the list.
3136 struct vpn_policy
*to_vpolicy
;
3138 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3139 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3141 if (strcmp(vname
, export_name
) != 0)
3145 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3147 export_name
, to_bgp
->name_pretty
);
3149 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3150 /* remove import rt, it will be readded
3151 * as part of import from vrf.
3155 to_vpolicy
->rtlist
[idir
],
3156 (struct ecommunity_val
*)
3158 vrf_import_from_vrf(to_bgp
, from_bgp
,