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(struct prefix
));
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 * if index != 0: try to allocate as index-mode
520 * else: try to allocate as auto-mode
522 static uint32_t alloc_new_sid(struct bgp
*bgp
, uint32_t index
,
523 struct in6_addr
*sid_locator
)
525 struct listnode
*node
;
526 struct prefix_ipv6
*chunk
;
527 struct in6_addr sid_buf
;
528 bool alloced
= false;
531 if (!bgp
|| !sid_locator
)
534 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_locator_chunks
, node
, chunk
)) {
535 *sid_locator
= chunk
->prefix
;
536 sid_buf
= chunk
->prefix
;
539 transpose_sid(&sid_buf
, label
, 64, 16);
540 if (sid_exist(bgp
, &sid_buf
))
546 for (size_t i
= 1; i
< 255; i
++) {
548 transpose_sid(&sid_buf
, label
, 64, 16);
549 if (sid_exist(bgp
, &sid_buf
))
559 sid_register(bgp
, &sid_buf
, bgp
->srv6_locator_name
);
563 void ensure_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
565 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
567 struct in6_addr
*tovpn_sid
, *tovpn_sid_locator
;
568 uint32_t tovpn_sid_index
= 0, tovpn_sid_transpose_label
;
569 bool tovpn_sid_auto
= false;
572 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
573 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
575 /* skip when tovpn sid is already allocated on vrf instance */
576 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
)
580 * skip when bgp vpn instance ins't allocated
581 * or srv6 locator chunk isn't allocated
583 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
586 tovpn_sid_index
= bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
;
587 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
588 BGP_VPN_POLICY_TOVPN_SID_AUTO
);
590 /* skip when VPN isn't configured on vrf-instance */
591 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
594 /* check invalid case both configured index and auto */
595 if (tovpn_sid_index
!= 0 && tovpn_sid_auto
) {
596 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
602 XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
603 tovpn_sid_transpose_label
=
604 alloc_new_sid(bgp_vpn
, tovpn_sid_index
, tovpn_sid_locator
);
605 if (tovpn_sid_transpose_label
== 0) {
606 zlog_debug("%s: not allocated new sid for vrf %s: afi %s",
607 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
611 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
612 *tovpn_sid
= *tovpn_sid_locator
;
613 transpose_sid(tovpn_sid
, tovpn_sid_transpose_label
,
614 BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET
,
615 BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH
);
618 inet_ntop(AF_INET6
, tovpn_sid
, buf
, sizeof(buf
));
619 zlog_debug("%s: new sid %s allocated for vrf %s: afi %s",
620 __func__
, buf
, bgp_vrf
->name_pretty
,
624 bgp_vrf
->vpn_policy
[afi
].tovpn_sid
= tovpn_sid
;
625 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
= tovpn_sid_locator
;
626 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
=
627 tovpn_sid_transpose_label
;
630 void transpose_sid(struct in6_addr
*sid
, uint32_t label
, uint8_t offset
,
633 for (uint8_t idx
= 0; idx
< len
; idx
++) {
634 uint8_t tidx
= offset
+ idx
;
635 sid
->s6_addr
[tidx
/ 8] &= ~(0x1 << (7 - tidx
% 8));
636 if (label
>> (19 - idx
) & 0x1)
637 sid
->s6_addr
[tidx
/ 8] |= 0x1 << (7 - tidx
% 8);
641 static bool ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
647 for (i
= 0; i
< e1
->size
; ++i
) {
648 for (j
= 0; j
< e2
->size
; ++j
) {
649 if (!memcmp(e1
->val
+ (i
* e1
->unit_size
),
650 e2
->val
+ (j
* e2
->unit_size
),
660 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
672 if (n
!= bpi
->extra
->num_labels
)
675 for (i
= 0; i
< n
; ++i
) {
676 if (label
[i
] != bpi
->extra
->label
[i
])
683 * make encoded route labels match specified encoded label set
685 static void setlabels(struct bgp_path_info
*bpi
,
686 mpls_label_t
*label
, /* array of labels */
691 assert(num_labels
<= BGP_MAX_LABELS
);
695 bpi
->extra
->num_labels
= 0;
699 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
702 for (i
= 0; i
< num_labels
; ++i
) {
703 extra
->label
[i
] = label
[i
];
704 if (!bgp_is_valid_label(&label
[i
])) {
705 bgp_set_valid_label(&extra
->label
[i
]);
708 extra
->num_labels
= num_labels
;
712 * make encoded route SIDs match specified encoded sid set
714 static void setsids(struct bgp_path_info
*bpi
,
715 struct in6_addr
*sid
,
719 struct bgp_path_info_extra
*extra
;
723 assert(num_sids
<= BGP_MAX_SIDS
);
727 bpi
->extra
->num_sids
= 0;
731 extra
= bgp_path_info_extra_get(bpi
);
732 for (i
= 0; i
< num_sids
; i
++)
733 memcpy(&extra
->sid
[i
].sid
, &sid
[i
], sizeof(struct in6_addr
));
734 extra
->num_sids
= num_sids
;
737 static void unsetsids(struct bgp_path_info
*bpi
)
739 struct bgp_path_info_extra
*extra
;
741 extra
= bgp_path_info_extra_get(bpi
);
743 memset(extra
->sid
, 0, sizeof(extra
->sid
));
747 * returns pointer to new bgp_path_info upon success
749 static struct bgp_path_info
*
750 leak_update(struct bgp
*bgp
, /* destination bgp instance */
751 struct bgp_dest
*bn
, struct attr
*new_attr
, /* already interned */
752 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
753 mpls_label_t
*label
, uint32_t num_labels
, void *parent
,
754 struct bgp
*bgp_orig
, struct prefix
*nexthop_orig
,
755 int nexthop_self_flag
, int debug
)
757 const struct prefix
*p
= bgp_dest_get_prefix(bn
);
758 struct bgp_path_info
*bpi
;
759 struct bgp_path_info
*bpi_ultimate
;
760 struct bgp_path_info
*new;
761 struct bgp_path_info_extra
*extra
;
762 uint32_t num_sids
= 0;
764 if (new_attr
->srv6_l3vpn
|| new_attr
->srv6_vpn
)
769 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
770 __func__
, bgp
->name_pretty
, bn
, source_bpi
->type
,
771 source_bpi
->sub_type
);
774 * Routes that are redistributed into BGP from zebra do not get
775 * nexthop tracking. However, if those routes are subsequently
776 * imported to other RIBs within BGP, the leaked routes do not
777 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
778 * in order to determine if the route we are currently leaking
779 * should have nexthop tracking, we must find the ultimate
780 * parent so we can check its sub_type.
782 * As of now, source_bpi may at most be a second-generation route
783 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
784 * Using a loop here supports more complex intra-bgp import-export
785 * schemes that could be implemented in the future.
788 bpi_ultimate
= bgp_get_imported_bpi_ultimate(source_bpi
);
793 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
794 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
799 bool labelssame
= labels_same(bpi
, label
, num_labels
);
801 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
802 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
805 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
806 __func__
, bgp
->name_pretty
,
807 source_bpi
->flags
, bpi
->flags
, p
);
812 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
813 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
815 bgp_attr_unintern(&new_attr
);
818 "%s: ->%s: %pBD: Found route, no change",
819 __func__
, bgp
->name_pretty
, bn
);
823 /* attr is changed */
824 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
826 /* Rewrite BGP route information. */
827 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
828 bgp_path_info_restore(bn
, bpi
);
830 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
831 bgp_attr_unintern(&bpi
->attr
);
832 bpi
->attr
= new_attr
;
833 bpi
->uptime
= bgp_clock();
839 setlabels(bpi
, label
, num_labels
);
845 if (new_attr
->srv6_l3vpn
) {
846 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
849 extra
= bgp_path_info_extra_get(bpi
);
851 extra
->sid
[0].loc_block_len
=
852 new_attr
->srv6_l3vpn
->loc_block_len
;
853 extra
->sid
[0].loc_node_len
=
854 new_attr
->srv6_l3vpn
->loc_node_len
;
855 extra
->sid
[0].func_len
=
856 new_attr
->srv6_l3vpn
->func_len
;
857 extra
->sid
[0].arg_len
=
858 new_attr
->srv6_l3vpn
->arg_len
;
859 extra
->sid
[0].transposition_len
=
860 new_attr
->srv6_l3vpn
->transposition_len
;
861 extra
->sid
[0].transposition_offset
=
863 ->transposition_offset
;
864 } else if (new_attr
->srv6_vpn
)
865 setsids(bpi
, &new_attr
->srv6_vpn
->sid
,
870 if (nexthop_self_flag
)
871 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
873 struct bgp
*bgp_nexthop
= bgp
;
876 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
877 bgp_nexthop
= bpi
->extra
->bgp_orig
;
880 * No nexthop tracking for redistributed routes or for
881 * EVPN-imported routes that get leaked.
883 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
884 is_pi_family_evpn(bpi_ultimate
))
888 * TBD do we need to do anything about the
889 * 'connected' parameter?
891 nh_valid
= bgp_find_or_add_nexthop(
892 bgp
, bgp_nexthop
, afi
, safi
, bpi
, NULL
, 0, p
);
895 * If you are using SRv6 VPN instead of MPLS, it need to check
896 * the SID allocation. If the sid is not allocated, the rib
899 if (bgp
->srv6_enabled
900 && (!new_attr
->srv6_l3vpn
&& !new_attr
->srv6_vpn
)) {
901 bgp_path_info_unset_flag(bn
, bpi
, BGP_PATH_VALID
);
906 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
907 __func__
, (nh_valid
? "" : "not "),
908 bgp_nexthop
->name_pretty
);
911 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
913 /* Process change. */
914 bgp_aggregate_increment(bgp
, p
, bpi
, afi
, safi
);
915 bgp_process(bgp
, bn
, afi
, safi
);
916 bgp_dest_unlock_node(bn
);
919 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
920 __func__
, bgp
->name_pretty
, bn
);
925 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
928 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
929 __func__
, bgp
->name_pretty
,
930 source_bpi
->flags
, p
);
935 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
936 bgp
->peer_self
, new_attr
, bn
);
938 if (nexthop_self_flag
)
939 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
941 bgp_path_info_extra_get(new);
947 if (new_attr
->srv6_l3vpn
) {
948 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
950 extra
= bgp_path_info_extra_get(new);
952 extra
->sid
[0].loc_block_len
=
953 new_attr
->srv6_l3vpn
->loc_block_len
;
954 extra
->sid
[0].loc_node_len
=
955 new_attr
->srv6_l3vpn
->loc_node_len
;
956 extra
->sid
[0].func_len
= new_attr
->srv6_l3vpn
->func_len
;
957 extra
->sid
[0].arg_len
= new_attr
->srv6_l3vpn
->arg_len
;
958 extra
->sid
[0].transposition_len
=
959 new_attr
->srv6_l3vpn
->transposition_len
;
960 extra
->sid
[0].transposition_offset
=
961 new_attr
->srv6_l3vpn
->transposition_offset
;
962 } else if (new_attr
->srv6_vpn
)
963 setsids(new, &new_attr
->srv6_vpn
->sid
, num_sids
);
968 setlabels(new, label
, num_labels
);
970 new->extra
->parent
= bgp_path_info_lock(parent
);
972 (struct bgp_dest
*)((struct bgp_path_info
*)parent
)->net
);
974 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
976 new->extra
->nexthop_orig
= *nexthop_orig
;
979 * nexthop tracking for unicast routes
981 struct bgp
*bgp_nexthop
= bgp
;
984 if (new->extra
->bgp_orig
)
985 bgp_nexthop
= new->extra
->bgp_orig
;
988 * No nexthop tracking for redistributed routes because
989 * their originating protocols will do the tracking and
990 * withdraw those routes if the nexthops become unreachable
991 * This also holds good for EVPN-imported routes that get
994 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
995 is_pi_family_evpn(bpi_ultimate
))
999 * TBD do we need to do anything about the
1000 * 'connected' parameter?
1002 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
, afi
, safi
,
1006 * If you are using SRv6 VPN instead of MPLS, it need to check
1007 * the SID allocation. If the sid is not allocated, the rib
1010 if (bgp
->srv6_enabled
1011 && (!new->attr
->srv6_l3vpn
&& !new->attr
->srv6_vpn
)) {
1012 bgp_path_info_unset_flag(bn
, new, BGP_PATH_VALID
);
1017 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
1018 __func__
, (nh_valid
? "" : "not "),
1019 bgp_nexthop
->name_pretty
);
1021 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
1023 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
1024 bgp_path_info_add(bn
, new);
1026 bgp_dest_unlock_node(bn
);
1027 bgp_process(bgp
, bn
, afi
, safi
);
1030 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
1031 bgp
->name_pretty
, bn
);
1036 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1037 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
1038 struct bgp
*bgp_vrf
, /* from */
1039 struct bgp_path_info
*path_vrf
) /* route */
1041 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1042 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1043 afi_t afi
= family2afi(p
->family
);
1044 struct attr static_attr
= {0};
1045 struct attr
*new_attr
= NULL
;
1046 safi_t safi
= SAFI_MPLS_VPN
;
1047 mpls_label_t label_val
;
1049 struct bgp_dest
*bn
;
1050 const char *debugmsg
;
1051 int nexthop_self_flag
= 0;
1054 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
1056 if (debug
&& bgp_attr_get_ecommunity(path_vrf
->attr
)) {
1057 char *s
= ecommunity_ecom2str(
1058 bgp_attr_get_ecommunity(path_vrf
->attr
),
1059 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1061 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
1062 bgp_vrf
->name
, path_vrf
->type
, s
);
1063 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1071 zlog_debug("%s: can't get afi of prefix", __func__
);
1075 /* Is this route exportable into the VPN table? */
1076 if (!is_route_injectable_into_vpn(path_vrf
))
1079 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1081 zlog_debug("%s: %s skipping: %s", __func__
,
1082 bgp_vrf
->name
, debugmsg
);
1087 static_attr
= *path_vrf
->attr
;
1090 * route map handling
1092 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1093 struct bgp_path_info info
;
1094 route_map_result_t ret
;
1096 memset(&info
, 0, sizeof(info
));
1097 info
.peer
= bgp_vpn
->peer_self
;
1098 info
.attr
= &static_attr
;
1099 ret
= route_map_apply(
1100 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1102 if (RMAP_DENYMATCH
== ret
) {
1103 bgp_attr_flush(&static_attr
); /* free any added parts */
1106 "%s: vrf %s route map \"%s\" says DENY, returning",
1107 __func__
, bgp_vrf
->name_pretty
,
1108 bgp_vrf
->vpn_policy
[afi
]
1109 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
1115 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1116 char *s
= ecommunity_ecom2str(
1117 bgp_attr_get_ecommunity(&static_attr
),
1118 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1120 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1122 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1126 * Add the vpn-policy rt-list
1128 struct ecommunity
*old_ecom
;
1129 struct ecommunity
*new_ecom
;
1131 /* Export with the 'from' instance's export RTs. */
1132 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1133 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1135 new_ecom
= ecommunity_dup(old_ecom
);
1136 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
1137 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1138 ecommunity_strip_rts(new_ecom
);
1139 new_ecom
= ecommunity_merge(new_ecom
,
1140 bgp_vrf
->vpn_policy
[afi
]
1141 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1142 if (!old_ecom
->refcnt
)
1143 ecommunity_free(&old_ecom
);
1145 new_ecom
= ecommunity_dup(
1146 bgp_vrf
->vpn_policy
[afi
]
1147 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1149 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1150 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
1152 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1153 char *s
= ecommunity_ecom2str(
1154 bgp_attr_get_ecommunity(&static_attr
),
1155 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1157 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1159 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1163 /* if policy nexthop not set, use 0 */
1164 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
1165 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1166 struct prefix
*nexthop
=
1167 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
1169 switch (nexthop
->family
) {
1171 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1173 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1175 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1176 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1180 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1181 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1188 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
1189 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1190 if (afi
== AFI_IP
) {
1192 * For ipv4, copy to multiprotocol
1195 static_attr
.mp_nexthop_global_in
=
1196 static_attr
.nexthop
;
1197 static_attr
.mp_nexthop_len
=
1198 BGP_ATTR_NHLEN_IPV4
;
1200 * XXX Leave static_attr.nexthop
1204 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1207 /* Update based on next-hop family to account for
1208 * RFC 5549 (BGP unnumbered) scenario. Note that
1209 * specific action is only needed for the case of
1210 * IPv4 nexthops as the attr has been copied
1214 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1215 static_attr
.mp_nexthop_global_in
.s_addr
=
1216 static_attr
.nexthop
.s_addr
;
1217 static_attr
.mp_nexthop_len
=
1218 BGP_ATTR_NHLEN_IPV4
;
1220 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1223 nexthop_self_flag
= 1;
1226 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
1227 if (label_val
== MPLS_LABEL_NONE
) {
1228 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1230 encode_label(label_val
, &label
);
1233 /* Set originator ID to "me" */
1234 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1235 static_attr
.originator_id
= bgp_vpn
->router_id
;
1237 /* Set SID for SRv6 VPN */
1238 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
) {
1239 encode_label(bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
,
1241 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1242 sizeof(struct bgp_attr_srv6_l3vpn
));
1243 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1244 static_attr
.srv6_l3vpn
->endpoint_behavior
= 0xffff;
1245 static_attr
.srv6_l3vpn
->loc_block_len
=
1246 BGP_PREFIX_SID_SRV6_LOCATOR_BLOCK_LENGTH
;
1247 static_attr
.srv6_l3vpn
->loc_node_len
=
1248 BGP_PREFIX_SID_SRV6_LOCATOR_NODE_LENGTH
;
1249 static_attr
.srv6_l3vpn
->func_len
=
1250 BGP_PREFIX_SID_SRV6_FUNCTION_LENGTH
;
1251 static_attr
.srv6_l3vpn
->arg_len
=
1252 BGP_PREFIX_SID_SRV6_ARGUMENT_LENGTH
;
1253 static_attr
.srv6_l3vpn
->transposition_len
=
1254 BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH
;
1255 static_attr
.srv6_l3vpn
->transposition_offset
=
1256 BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET
;
1257 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1258 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
,
1259 sizeof(struct in6_addr
));
1263 new_attr
= bgp_attr_intern(
1264 &static_attr
); /* hashed refcounted everything */
1265 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1267 if (debug
&& bgp_attr_get_ecommunity(new_attr
)) {
1268 char *s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr
),
1269 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1271 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1272 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1275 /* Now new_attr is an allocated interned attr */
1277 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
1278 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
1280 struct bgp_path_info
*new_info
;
1282 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, path_vrf
,
1283 &label
, 1, path_vrf
, bgp_vrf
, NULL
,
1284 nexthop_self_flag
, debug
);
1287 * Routes actually installed in the vpn RIB must also be
1288 * offered to all vrfs (because now they originate from
1291 * Acceptance into other vrfs depends on rt-lists.
1292 * Originating vrf will not accept the looped back route
1293 * because of loop checking.
1296 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
1299 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
1300 struct bgp
*bgp_vrf
, /* from */
1301 struct bgp_path_info
*path_vrf
) /* route */
1303 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1304 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1305 afi_t afi
= family2afi(p
->family
);
1306 safi_t safi
= SAFI_MPLS_VPN
;
1307 struct bgp_path_info
*bpi
;
1308 struct bgp_dest
*bn
;
1309 const char *debugmsg
;
1313 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1314 __func__
, bgp_vrf
->name_pretty
, path_vrf
->net
,
1315 path_vrf
->type
, path_vrf
->sub_type
);
1323 zlog_debug("%s: can't get afi of prefix", __func__
);
1327 /* Is this route exportable into the VPN table? */
1328 if (!is_route_injectable_into_vpn(path_vrf
))
1331 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1333 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1338 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1340 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
1341 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
1347 * match original bpi imported from
1349 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1350 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1356 /* withdraw from looped vrfs as well */
1357 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
1359 bgp_aggregate_decrement(bgp_vpn
, p
, bpi
, afi
, safi
);
1360 bgp_path_info_delete(bn
, bpi
);
1361 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1363 bgp_dest_unlock_node(bn
);
1366 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
1367 struct bgp
*bgp_vrf
, /* from */
1370 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1371 struct bgp_dest
*pdest
;
1372 safi_t safi
= SAFI_MPLS_VPN
;
1375 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
1377 for (pdest
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); pdest
;
1378 pdest
= bgp_route_next(pdest
)) {
1380 struct bgp_table
*table
;
1381 struct bgp_dest
*bn
;
1382 struct bgp_path_info
*bpi
;
1384 /* This is the per-RD table of prefixes */
1385 table
= bgp_dest_get_bgp_table_info(pdest
);
1390 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1391 bpi
= bgp_dest_get_bgp_path_info(bn
);
1393 zlog_debug("%s: looking at prefix %pBD",
1397 for (; bpi
; bpi
= bpi
->next
) {
1399 zlog_debug("%s: type %d, sub_type %d",
1400 __func__
, bpi
->type
,
1402 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1406 if ((struct bgp
*)bpi
->extra
->bgp_orig
1410 zlog_debug("%s: deleting it",
1412 /* withdraw from leak-to vrfs as well */
1413 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
1414 bgp_aggregate_decrement(
1416 bgp_dest_get_prefix(bn
), bpi
,
1418 bgp_path_info_delete(bn
, bpi
);
1419 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1426 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
1427 struct bgp
*bgp_vrf
, /* from */
1430 struct bgp_dest
*bn
;
1431 struct bgp_path_info
*bpi
;
1432 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1435 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1436 bgp_vrf
->name_pretty
);
1438 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
1439 bn
= bgp_route_next(bn
)) {
1442 zlog_debug("%s: node=%p", __func__
, bn
);
1444 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1448 "%s: calling vpn_leak_from_vrf_update",
1450 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bpi
);
1456 vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1457 struct bgp
*bgp_vpn
, /* from */
1458 struct bgp_path_info
*path_vpn
) /* route */
1460 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1461 afi_t afi
= family2afi(p
->family
);
1463 struct attr static_attr
= {0};
1464 struct attr
*new_attr
= NULL
;
1465 struct bgp_dest
*bn
;
1466 safi_t safi
= SAFI_UNICAST
;
1467 const char *debugmsg
;
1468 struct prefix nexthop_orig
;
1469 mpls_label_t
*pLabels
= NULL
;
1470 uint32_t num_labels
= 0;
1471 int nexthop_self_flag
= 1;
1472 struct bgp_path_info
*bpi_ultimate
= NULL
;
1473 int origin_local
= 0;
1474 struct bgp
*src_vrf
;
1476 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1478 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1480 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1484 /* Check for intersection of route targets */
1485 if (!ecom_intersect(
1486 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1487 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1490 "from vpn to vrf %s, skipping after no intersection of route targets",
1491 bgp_vrf
->name_pretty
);
1496 zlog_debug("%s: updating %pFX to vrf %s", __func__
, p
,
1497 bgp_vrf
->name_pretty
);
1500 static_attr
= *path_vpn
->attr
;
1502 struct ecommunity
*old_ecom
;
1503 struct ecommunity
*new_ecom
;
1505 /* If doing VRF-to-VRF leaking, strip RTs. */
1506 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1507 if (old_ecom
&& CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1508 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1509 new_ecom
= ecommunity_dup(old_ecom
);
1510 ecommunity_strip_rts(new_ecom
);
1511 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1513 if (new_ecom
->size
== 0) {
1514 UNSET_FLAG(static_attr
.flag
,
1515 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
1516 ecommunity_free(&new_ecom
);
1517 bgp_attr_set_ecommunity(&static_attr
, NULL
);
1520 if (!old_ecom
->refcnt
)
1521 ecommunity_free(&old_ecom
);
1525 * Nexthop: stash and clear
1527 * Nexthop is valid in context of VPN core, but not in destination vrf.
1528 * Stash it for later label resolution by vrf ingress path and then
1529 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1531 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1533 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1534 nexthop_orig
.family
= nhfamily
;
1539 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1540 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
1542 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1543 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1544 static_attr
.nexthop
.s_addr
=
1545 nexthop_orig
.u
.prefix4
.s_addr
;
1547 static_attr
.mp_nexthop_global_in
=
1548 path_vpn
->attr
->mp_nexthop_global_in
;
1549 static_attr
.mp_nexthop_len
=
1550 path_vpn
->attr
->mp_nexthop_len
;
1552 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1556 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1557 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
1559 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1560 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1561 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1567 * route map handling
1569 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1570 struct bgp_path_info info
;
1571 route_map_result_t ret
;
1573 memset(&info
, 0, sizeof(info
));
1574 info
.peer
= bgp_vrf
->peer_self
;
1575 info
.attr
= &static_attr
;
1576 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1577 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1578 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1580 if (RMAP_DENYMATCH
== ret
) {
1581 bgp_attr_flush(&static_attr
); /* free any added parts */
1584 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1585 __func__
, bgp_vrf
->name_pretty
,
1586 bgp_vrf
->vpn_policy
[afi
]
1587 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1592 * if route-map changed nexthop, don't nexthop-self on output
1594 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1595 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1596 nexthop_self_flag
= 0;
1599 new_attr
= bgp_attr_intern(&static_attr
);
1600 bgp_attr_flush(&static_attr
);
1602 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1605 * ensure labels are copied
1607 * However, there is a special case: if the route originated in
1608 * another local VRF (as opposed to arriving via VPN), then the
1609 * nexthop is reached by hairpinning through this router (me)
1610 * using IP forwarding only (no LSP). Therefore, the route
1611 * imported to the VRF should not have labels attached. Note
1612 * that nexthop tracking is also involved: eliminating the
1613 * labels for these routes enables the non-labeled nexthops
1614 * from the originating VRF to be considered valid for this route.
1616 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1617 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1618 /* work back to original route */
1619 bpi_ultimate
= bgp_get_imported_bpi_ultimate(path_vpn
);
1622 * if original route was unicast,
1623 * then it did not arrive over vpn
1625 if (bpi_ultimate
->net
) {
1626 struct bgp_table
*table
;
1628 table
= bgp_dest_table(bpi_ultimate
->net
);
1629 if (table
&& (table
->safi
== SAFI_UNICAST
))
1634 if (!origin_local
&& path_vpn
->extra
1635 && path_vpn
->extra
->num_labels
) {
1636 num_labels
= path_vpn
->extra
->num_labels
;
1637 if (num_labels
> BGP_MAX_LABELS
)
1638 num_labels
= BGP_MAX_LABELS
;
1639 pLabels
= path_vpn
->extra
->label
;
1644 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
1645 path_vpn
->net
, num_labels
);
1648 * For VRF-2-VRF route-leaking,
1649 * the source will be the originating VRF.
1651 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1652 src_vrf
= path_vpn
->extra
->bgp_orig
;
1656 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
1657 num_labels
, path_vpn
, /* parent */
1658 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1661 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1662 struct bgp_path_info
*path_vpn
) /* route */
1664 struct listnode
*mnode
, *mnnode
;
1667 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1670 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1672 /* Loop over VRFs */
1673 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1675 if (!path_vpn
->extra
1676 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1677 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, path_vpn
);
1682 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1683 struct bgp_path_info
*path_vpn
) /* route */
1685 const struct prefix
*p
;
1687 safi_t safi
= SAFI_UNICAST
;
1689 struct listnode
*mnode
, *mnnode
;
1690 struct bgp_dest
*bn
;
1691 struct bgp_path_info
*bpi
;
1692 const char *debugmsg
;
1694 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1697 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
1698 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
1701 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1703 if (!path_vpn
->net
) {
1704 #ifdef ENABLE_BGP_VNC
1705 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1706 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
1707 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1714 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1719 p
= bgp_dest_get_prefix(path_vpn
->net
);
1720 afi
= family2afi(p
->family
);
1722 /* Loop over VRFs */
1723 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1724 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1726 zlog_debug("%s: skipping: %s", __func__
,
1731 /* Check for intersection of route targets */
1732 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1733 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1734 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1740 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1743 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1745 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1748 && (struct bgp_path_info
*)bpi
->extra
->parent
1756 zlog_debug("%s: deleting bpi %p", __func__
,
1758 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
1759 bgp_path_info_delete(bn
, bpi
);
1760 bgp_process(bgp
, bn
, afi
, safi
);
1762 bgp_dest_unlock_node(bn
);
1766 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1769 struct bgp_dest
*bn
;
1770 struct bgp_path_info
*bpi
;
1771 safi_t safi
= SAFI_UNICAST
;
1772 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1775 zlog_debug("%s: entry", __func__
);
1777 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1779 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1780 bn
= bgp_route_next(bn
)) {
1782 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1785 && bpi
->extra
->bgp_orig
!= bgp_vrf
1786 && bpi
->extra
->parent
1787 && is_pi_family_vpn(bpi
->extra
->parent
)) {
1790 bgp_aggregate_decrement(bgp_vrf
,
1791 bgp_dest_get_prefix(bn
),
1793 bgp_path_info_delete(bn
, bpi
);
1794 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1800 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1801 struct bgp
*bgp_vpn
, /* from */
1804 struct bgp_dest
*pdest
;
1805 safi_t safi
= SAFI_MPLS_VPN
;
1812 for (pdest
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); pdest
;
1813 pdest
= bgp_route_next(pdest
)) {
1814 struct bgp_table
*table
;
1815 struct bgp_dest
*bn
;
1816 struct bgp_path_info
*bpi
;
1818 /* This is the per-RD table of prefixes */
1819 table
= bgp_dest_get_bgp_table_info(pdest
);
1824 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1826 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1830 && bpi
->extra
->bgp_orig
== bgp_vrf
)
1833 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1841 * This function is called for definition/deletion/change to a route-map
1843 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1845 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1847 struct route_map
*rmap
;
1849 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1850 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1855 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1857 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1859 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1860 && !strcmp(rmap_name
,
1861 bgp
->vpn_policy
[afi
]
1862 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1866 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1867 __func__
, rmap_name
, bgp
->as
,
1870 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1871 bgp_get_default(), bgp
);
1873 zlog_debug("%s: after vpn_leak_prechange",
1876 /* in case of definition/deletion */
1877 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1880 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1881 bgp_get_default(), bgp
);
1884 zlog_debug("%s: after vpn_leak_postchange",
1888 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1889 && !strcmp(rmap_name
,
1890 bgp
->vpn_policy
[afi
]
1891 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1894 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1895 __func__
, rmap_name
, bgp
->as
,
1899 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1900 bgp_get_default(), bgp
);
1902 /* in case of definition/deletion */
1903 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1906 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1907 bgp_get_default(), bgp
);
1912 /* This API is used during router-id change, reflect VPNs
1913 * auto RD and RT values and readvertise routes to VPN table.
1915 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
1919 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
1920 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1922 const char *export_name
;
1923 char buf
[RD_ADDRSTRLEN
];
1924 struct bgp
*bgp_import
;
1925 struct listnode
*node
;
1926 struct ecommunity
*ecom
;
1927 vpn_policy_direction_t idir
, edir
;
1930 * Router-id change that is not explicitly configured
1931 * (a change from zebra, frr restart for example)
1932 * should not replace a configured vpn RD/RT.
1936 zlog_debug("%s: skipping non explicit router-id change",
1941 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1942 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1945 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1946 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1947 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1949 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1950 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
1954 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
1955 afi
, bgp_get_default(), bgp
);
1957 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1958 __func__
, export_name
);
1960 /* Remove import RT from VRFs */
1961 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1962 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1963 export_vrf
, node
, vname
)) {
1964 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1965 bgp_import
= bgp_get_default();
1967 bgp_import
= bgp_lookup_by_name(vname
);
1972 bgp_import
->vpn_policy
[afi
]
1974 (struct ecommunity_val
*)ecom
->val
);
1977 /* New router-id derive auto RD and RT and export
1980 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
1981 &bgp
->vrf_prd_auto
);
1982 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
1983 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
1985 bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1986 ecommunity_str2com(buf
,
1987 ECOMMUNITY_ROUTE_TARGET
, 0);
1989 /* Update import_vrf rt_list */
1990 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1991 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1992 export_vrf
, node
, vname
)) {
1993 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1994 bgp_import
= bgp_get_default();
1996 bgp_import
= bgp_lookup_by_name(vname
);
1999 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
2000 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2002 bgp_import
->vpn_policy
[afi
]
2003 .rtlist
[idir
], ecom
);
2005 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2006 = ecommunity_dup(ecom
);
2009 /* Update routes to VPN */
2010 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
2011 afi
, bgp_get_default(),
2014 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2015 __func__
, export_name
);
2020 void vpn_policy_routemap_event(const char *rmap_name
)
2022 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2023 struct listnode
*mnode
, *mnnode
;
2027 zlog_debug("%s: entry", __func__
);
2029 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2032 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2033 vpn_policy_routemap_update(bgp
, rmap_name
);
2036 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2037 afi_t afi
, safi_t safi
)
2039 const char *export_name
;
2040 vpn_policy_direction_t idir
, edir
;
2041 char *vname
, *tmp_name
;
2042 char buf
[RD_ADDRSTRLEN
];
2043 struct ecommunity
*ecom
;
2044 bool first_export
= false;
2046 struct listnode
*node
;
2047 bool is_inst_match
= false;
2049 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2050 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2051 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2053 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2054 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2057 * Cross-ref both VRFs. Also, note if this is the first time
2058 * any VRF is importing from "import_vrf".
2060 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2061 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2063 /* Check the import_vrf list of destination vrf for the source vrf name,
2066 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2068 if (strcmp(vname
, tmp_name
) == 0) {
2069 is_inst_match
= true;
2074 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2077 XFREE(MTYPE_TMP
, vname
);
2079 /* Check if the source vrf already exports to any vrf,
2080 * first time export requires to setup auto derived RD/RT values.
2081 * Add the destination vrf name to export vrf list if it is
2084 is_inst_match
= false;
2085 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2086 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2087 first_export
= true;
2089 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2091 if (strcmp(vname
, tmp_name
) == 0) {
2092 is_inst_match
= true;
2098 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2101 XFREE(MTYPE_TMP
, vname
);
2103 /* Update import RT for current VRF using export RT of the VRF we're
2104 * importing from. First though, make sure "import_vrf" has that
2108 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2109 &from_bgp
->vrf_prd_auto
);
2110 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2111 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2112 BGP_VPN_POLICY_TOVPN_RD_SET
);
2113 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
2115 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2116 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2117 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2118 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2119 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2120 BGP_PREVENT_VRF_2_VRF_LEAK
;
2122 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2123 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2124 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2125 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2126 .rtlist
[idir
], ecom
);
2128 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2129 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2132 const char *from_name
;
2133 char *ecom1
, *ecom2
;
2135 from_name
= from_bgp
->name
? from_bgp
->name
:
2138 ecom1
= ecommunity_ecom2str(
2139 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2140 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2142 ecom2
= ecommunity_ecom2str(
2143 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2144 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2147 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2148 __func__
, from_name
, export_name
, first_export
, ecom1
,
2151 ecommunity_strfree(&ecom1
);
2152 ecommunity_strfree(&ecom2
);
2155 /* Does "import_vrf" first need to export its routes or that
2156 * is already done and we just need to import those routes
2157 * from the global table?
2160 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2162 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2165 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2166 afi_t afi
, safi_t safi
)
2168 const char *export_name
, *tmp_name
;
2169 vpn_policy_direction_t idir
, edir
;
2171 struct ecommunity
*ecom
= NULL
;
2172 struct listnode
*node
;
2175 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2176 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2177 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2178 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2180 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2181 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2183 /* Were we importing from "import_vrf"? */
2184 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2186 if (strcmp(vname
, tmp_name
) == 0)
2191 * We do not check in the cli if the passed in bgp
2192 * instance is actually imported into us before
2193 * we call this function. As such if we do not
2194 * find this in the import_vrf list than
2195 * we just need to return safely.
2201 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2203 /* Remove "import_vrf" from our import list. */
2204 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2205 XFREE(MTYPE_TMP
, vname
);
2207 /* Remove routes imported from "import_vrf". */
2208 /* TODO: In the current logic, we have to first remove all
2209 * imported routes and then (if needed) import back routes
2211 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2213 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2214 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2215 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2216 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2217 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2218 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2220 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2222 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2223 (struct ecommunity_val
*)ecom
->val
);
2224 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2229 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2230 * below is checking for NULL that export_vrf can be
2231 * NULL, consequently it is complaining( like a cabbage )
2232 * that we could dereference and crash in the listcount(..)
2234 * So make it happy, under protest, with liberty and justice
2237 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2239 /* Remove us from "import_vrf's" export list. If no other VRF
2240 * is importing from "import_vrf", cleanup appropriately.
2242 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2244 if (strcmp(vname
, export_name
) == 0)
2249 * If we have gotten to this point then the vname must
2250 * exist. If not, we are in a world of trouble and
2251 * have slag sitting around.
2253 * import_vrf and export_vrf must match in having
2254 * the in/out names as appropriate.
2255 * export_vrf list could have been cleaned up
2256 * as part of no router bgp source instnace.
2261 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2262 XFREE(MTYPE_TMP
, vname
);
2264 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2265 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2266 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2267 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2268 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2269 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2270 sizeof(struct prefix_rd
));
2271 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2272 BGP_VPN_POLICY_TOVPN_RD_SET
);
2273 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2278 /* For testing purpose, static route of MPLS-VPN. */
2279 DEFUN (vpnv4_network
,
2281 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2282 "Specify a network to announce via BGP\n"
2284 "Specify Route Distinguisher\n"
2285 "VPN Route Distinguisher\n"
2286 "VPN NLRI label (tag)\n"
2287 "VPN NLRI label (tag)\n"
2290 int idx_ipv4_prefixlen
= 1;
2291 int idx_ext_community
= 3;
2293 return bgp_static_set_safi(
2294 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2295 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
2296 NULL
, NULL
, NULL
, NULL
);
2299 DEFUN (vpnv4_network_route_map
,
2300 vpnv4_network_route_map_cmd
,
2301 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
2302 "Specify a network to announce via BGP\n"
2304 "Specify Route Distinguisher\n"
2305 "VPN Route Distinguisher\n"
2306 "VPN NLRI label (tag)\n"
2307 "VPN NLRI label (tag)\n"
2312 int idx_ipv4_prefixlen
= 1;
2313 int idx_ext_community
= 3;
2316 return bgp_static_set_safi(
2317 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2318 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2319 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2322 /* For testing purpose, static route of MPLS-VPN. */
2323 DEFUN (no_vpnv4_network
,
2324 no_vpnv4_network_cmd
,
2325 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2327 "Specify a network to announce via BGP\n"
2329 "Specify Route Distinguisher\n"
2330 "VPN Route Distinguisher\n"
2331 "VPN NLRI label (tag)\n"
2332 "VPN NLRI label (tag)\n"
2335 int idx_ipv4_prefixlen
= 2;
2336 int idx_ext_community
= 4;
2338 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
2339 argv
[idx_ipv4_prefixlen
]->arg
,
2340 argv
[idx_ext_community
]->arg
,
2341 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2344 DEFUN (vpnv6_network
,
2346 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
2347 "Specify a network to announce via BGP\n"
2348 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2349 "Specify Route Distinguisher\n"
2350 "VPN Route Distinguisher\n"
2351 "VPN NLRI label (tag)\n"
2352 "VPN NLRI label (tag)\n"
2357 int idx_ipv6_prefix
= 1;
2358 int idx_ext_community
= 3;
2362 return bgp_static_set_safi(
2363 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2364 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2365 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2367 return bgp_static_set_safi(
2368 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2369 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2370 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2373 /* For testing purpose, static route of MPLS-VPN. */
2374 DEFUN (no_vpnv6_network
,
2375 no_vpnv6_network_cmd
,
2376 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2378 "Specify a network to announce via BGP\n"
2379 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2380 "Specify Route Distinguisher\n"
2381 "VPN Route Distinguisher\n"
2382 "VPN NLRI label (tag)\n"
2383 "VPN NLRI label (tag)\n"
2386 int idx_ipv6_prefix
= 2;
2387 int idx_ext_community
= 4;
2389 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2390 argv
[idx_ipv6_prefix
]->arg
,
2391 argv
[idx_ext_community
]->arg
,
2392 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2395 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2396 enum bgp_show_type type
, void *output_arg
, int tags
,
2400 struct bgp_table
*table
;
2402 bgp
= bgp_get_default();
2405 vty_out(vty
, "No BGP process is configured\n");
2407 vty_out(vty
, "{}\n");
2410 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2411 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2412 output_arg
, use_json
);
2415 DEFUN (show_bgp_ip_vpn_all_rd
,
2416 show_bgp_ip_vpn_all_rd_cmd
,
2417 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2421 "Display VPN NLRI specific information\n"
2422 "Display VPN NLRI specific information\n"
2423 "Display information for a route distinguisher\n"
2424 "VPN Route Distinguisher\n"
2425 "All VPN Route Distinguishers\n"
2429 struct prefix_rd prd
;
2433 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2434 /* Constrain search if user supplies RD && RD != "all" */
2435 if (argv_find(argv
, argc
, "rd", &idx
)
2436 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
2437 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2440 "%% Malformed Route Distinguisher\n");
2443 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2444 bgp_show_type_normal
, NULL
, 0,
2445 use_json(argc
, argv
));
2447 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2448 bgp_show_type_normal
, NULL
, 0,
2449 use_json(argc
, argv
));
2455 ALIAS(show_bgp_ip_vpn_all_rd
,
2456 show_bgp_ip_vpn_rd_cmd
,
2457 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2461 "Display VPN NLRI specific information\n"
2462 "Display information for a route distinguisher\n"
2463 "VPN Route Distinguisher\n"
2464 "All VPN Route Distinguishers\n"
2467 #ifdef KEEP_OLD_VPN_COMMANDS
2468 DEFUN (show_ip_bgp_vpn_rd
,
2469 show_ip_bgp_vpn_rd_cmd
,
2470 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2475 "Address Family modifier\n"
2476 "Display information for a route distinguisher\n"
2477 "VPN Route Distinguisher\n"
2478 "All VPN Route Distinguishers\n")
2480 int idx_ext_community
= argc
- 1;
2482 struct prefix_rd prd
;
2486 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2487 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2488 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2489 bgp_show_type_normal
, NULL
, 0,
2491 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2493 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2496 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2502 DEFUN (show_ip_bgp_vpn_all
,
2503 show_ip_bgp_vpn_all_cmd
,
2504 "show [ip] bgp <vpnv4|vpnv6>",
2513 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2514 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2519 DEFUN (show_ip_bgp_vpn_all_tags
,
2520 show_ip_bgp_vpn_all_tags_cmd
,
2521 "show [ip] bgp <vpnv4|vpnv6> all tags",
2526 "Display information about all VPNv4/VPNV6 NLRIs\n"
2527 "Display BGP tags for prefixes\n")
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_rd_tags
,
2539 show_ip_bgp_vpn_rd_tags_cmd
,
2540 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2545 "Display information for a route distinguisher\n"
2546 "VPN Route Distinguisher\n"
2547 "All VPN Route Distinguishers\n"
2548 "Display BGP tags for prefixes\n")
2550 int idx_ext_community
= 5;
2552 struct prefix_rd prd
;
2556 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2557 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2558 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2559 bgp_show_type_normal
, NULL
, 1,
2561 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2563 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2566 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2572 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2573 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2574 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2579 "Display information about all VPNv4/VPNv6 NLRIs\n"
2580 "Detailed information on TCP and BGP neighbor connections\n"
2581 "Neighbor to display information about\n"
2582 "Display routes learned from neighbor\n"
2589 bool uj
= use_json(argc
, argv
);
2593 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2594 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2597 json_object
*json_no
= NULL
;
2598 json_no
= json_object_new_object();
2599 json_object_string_add(json_no
, "warning",
2600 "Malformed address");
2601 vty_out(vty
, "%s\n",
2602 json_object_to_json_string(json_no
));
2603 json_object_free(json_no
);
2605 vty_out(vty
, "Malformed address: %s\n",
2606 argv
[idx_ipv4
]->arg
);
2610 peer
= peer_lookup(NULL
, &su
);
2611 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2613 json_object
*json_no
= NULL
;
2614 json_no
= json_object_new_object();
2615 json_object_string_add(
2617 "No such neighbor or address family");
2618 vty_out(vty
, "%s\n",
2619 json_object_to_json_string(json_no
));
2620 json_object_free(json_no
);
2623 "%% No such neighbor or address family\n");
2627 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2633 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2634 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2635 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
2640 "Display information for a route distinguisher\n"
2641 "VPN Route Distinguisher\n"
2642 "All VPN Route Distinguishers\n"
2643 "Detailed information on TCP and BGP neighbor connections\n"
2644 "Neighbor to display information about\n"
2645 "Display routes learned from neighbor\n"
2648 int idx_ext_community
= 5;
2653 struct prefix_rd prd
;
2654 bool prefix_rd_all
= false;
2655 bool uj
= use_json(argc
, argv
);
2659 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2660 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2661 prefix_rd_all
= true;
2663 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2666 json_object
*json_no
= NULL
;
2667 json_no
= json_object_new_object();
2668 json_object_string_add(
2670 "Malformed Route Distinguisher");
2671 vty_out(vty
, "%s\n",
2672 json_object_to_json_string(
2674 json_object_free(json_no
);
2677 "%% Malformed Route Distinguisher\n");
2682 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2685 json_object
*json_no
= NULL
;
2686 json_no
= json_object_new_object();
2687 json_object_string_add(json_no
, "warning",
2688 "Malformed address");
2689 vty_out(vty
, "%s\n",
2690 json_object_to_json_string(json_no
));
2691 json_object_free(json_no
);
2693 vty_out(vty
, "Malformed address: %s\n",
2694 argv
[idx_ext_community
]->arg
);
2698 peer
= peer_lookup(NULL
, &su
);
2699 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2701 json_object
*json_no
= NULL
;
2702 json_no
= json_object_new_object();
2703 json_object_string_add(
2705 "No such neighbor or address family");
2706 vty_out(vty
, "%s\n",
2707 json_object_to_json_string(json_no
));
2708 json_object_free(json_no
);
2711 "%% No such neighbor or address family\n");
2716 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2717 bgp_show_type_neighbor
, &su
, 0,
2720 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2721 bgp_show_type_neighbor
, &su
, 0,
2727 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2728 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2729 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2734 "Display information about all VPNv4/VPNv6 NLRIs\n"
2735 "Detailed information on TCP and BGP neighbor connections\n"
2736 "Neighbor to display information about\n"
2737 "Display the routes advertised to a BGP neighbor\n"
2744 bool uj
= use_json(argc
, argv
);
2748 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2749 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2752 json_object
*json_no
= NULL
;
2753 json_no
= json_object_new_object();
2754 json_object_string_add(json_no
, "warning",
2755 "Malformed address");
2756 vty_out(vty
, "%s\n",
2757 json_object_to_json_string(json_no
));
2758 json_object_free(json_no
);
2760 vty_out(vty
, "Malformed address: %s\n",
2761 argv
[idx_ipv4
]->arg
);
2764 peer
= peer_lookup(NULL
, &su
);
2765 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2767 json_object
*json_no
= NULL
;
2768 json_no
= json_object_new_object();
2769 json_object_string_add(
2771 "No such neighbor or address family");
2772 vty_out(vty
, "%s\n",
2773 json_object_to_json_string(json_no
));
2774 json_object_free(json_no
);
2777 "%% No such neighbor or address family\n");
2780 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2786 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2787 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2788 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
2793 "Display information for a route distinguisher\n"
2794 "VPN Route Distinguisher\n"
2795 "All VPN Route Distinguishers\n"
2796 "Detailed information on TCP and BGP neighbor connections\n"
2797 "Neighbor to display information about\n"
2798 "Display the routes advertised to a BGP neighbor\n"
2801 int idx_ext_community
= 5;
2805 struct prefix_rd prd
;
2807 bool uj
= use_json(argc
, argv
);
2811 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2812 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2815 json_object
*json_no
= NULL
;
2816 json_no
= json_object_new_object();
2817 json_object_string_add(json_no
, "warning",
2818 "Malformed address");
2819 vty_out(vty
, "%s\n",
2820 json_object_to_json_string(json_no
));
2821 json_object_free(json_no
);
2823 vty_out(vty
, "Malformed address: %s\n",
2824 argv
[idx_ext_community
]->arg
);
2827 peer
= peer_lookup(NULL
, &su
);
2828 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2830 json_object
*json_no
= NULL
;
2831 json_no
= json_object_new_object();
2832 json_object_string_add(
2834 "No such neighbor or address family");
2835 vty_out(vty
, "%s\n",
2836 json_object_to_json_string(json_no
));
2837 json_object_free(json_no
);
2840 "%% No such neighbor or address family\n");
2844 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2845 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2847 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2850 json_object
*json_no
= NULL
;
2851 json_no
= json_object_new_object();
2852 json_object_string_add(
2854 "Malformed Route Distinguisher");
2855 vty_out(vty
, "%s\n",
2856 json_object_to_json_string(json_no
));
2857 json_object_free(json_no
);
2860 "%% Malformed Route Distinguisher\n");
2864 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2869 #endif /* KEEP_OLD_VPN_COMMANDS */
2871 void bgp_mplsvpn_init(void)
2873 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2874 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2875 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2877 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2878 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2880 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2881 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2882 #ifdef KEEP_OLD_VPN_COMMANDS
2883 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2884 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2885 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2886 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2887 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2888 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2889 install_element(VIEW_NODE
,
2890 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2891 install_element(VIEW_NODE
,
2892 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2893 #endif /* KEEP_OLD_VPN_COMMANDS */
2896 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2898 struct listnode
*mnode
, *mnnode
;
2902 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
2905 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2906 struct ecommunity
*ec
;
2908 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2911 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
2913 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
2916 if (ecom_intersect(ec
, eckey
))
2923 * The purpose of this function is to process leaks that were deferred
2924 * from earlier per-vrf configuration due to not-yet-existing default
2925 * vrf, in other words, configuration such as:
2927 * router bgp MMM vrf FOO
2928 * address-family ipv4 unicast
2930 * exit-address-family
2935 * This function gets called when the default instance ("router bgp NNN")
2938 void vpn_leak_postchange_all(void)
2940 struct listnode
*next
;
2942 struct bgp
*bgp_default
= bgp_get_default();
2944 assert(bgp_default
);
2946 /* First, do any exporting from VRFs to the single VPN RIB */
2947 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2949 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2952 vpn_leak_postchange(
2953 BGP_VPN_POLICY_DIR_TOVPN
,
2958 vpn_leak_postchange(
2959 BGP_VPN_POLICY_DIR_TOVPN
,
2965 /* Now, do any importing to VRFs from 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_FROMVPN
,
2977 vpn_leak_postchange(
2978 BGP_VPN_POLICY_DIR_FROMVPN
,
2985 /* When a bgp vrf instance is unconfigured, remove its routes
2986 * from the VPN table and this vrf could be importing routes from other
2987 * bgp vrf instnaces, unimport them.
2988 * VRF X and VRF Y are exporting routes to each other.
2989 * When VRF X is deleted, unimport its routes from all target vrfs,
2990 * also VRF Y should unimport its routes from VRF X table.
2991 * This will ensure VPN table is cleaned up appropriately.
2993 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
2996 const char *tmp_name
;
2998 struct listnode
*node
, *next
;
2999 safi_t safi
= SAFI_UNICAST
;
3001 bool is_vrf_leak_bind
;
3004 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3007 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3008 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3010 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3012 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3013 /* vrf leak is for IPv4 and IPv6 Unicast only */
3014 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3017 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3018 if (from_bgp
== to_bgp
)
3021 /* Unimport and remove source vrf from the
3022 * other vrfs import list.
3024 struct vpn_policy
*to_vpolicy
;
3026 is_vrf_leak_bind
= false;
3027 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3028 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
3030 if (strcmp(vname
, tmp_name
) == 0) {
3031 is_vrf_leak_bind
= true;
3035 /* skip this bgp instance as there is no leak to this
3038 if (!is_vrf_leak_bind
)
3042 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3043 __func__
, from_bgp
->name_pretty
,
3044 to_bgp
->name_pretty
, afi2str(afi
),
3045 to_vpolicy
->import_vrf
->count
);
3047 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
3049 /* readd vrf name as unimport removes import vrf name
3050 * from the destination vrf's import list where the
3051 * `import vrf` configuration still exist.
3053 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
3054 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
3056 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
3057 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
3059 /* If to_bgp exports its routes to the bgp vrf
3060 * which is being deleted, un-import the
3061 * to_bgp routes from VPN.
3063 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3066 if (strcmp(vname
, tmp_name
) == 0) {
3067 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3077 /* When a router bgp is configured, there could be a bgp vrf
3078 * instance importing routes from this newly configured
3079 * bgp vrf instance. Export routes from configured
3081 * VRF Y has import from bgp vrf x,
3082 * when a bgp vrf x instance is created, export its routes
3083 * to VRF Y instance.
3085 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3088 const char *export_name
;
3090 struct listnode
*node
, *next
;
3091 struct ecommunity
*ecom
;
3092 vpn_policy_direction_t idir
, edir
;
3093 safi_t safi
= SAFI_UNICAST
;
3097 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3098 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3100 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3101 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3103 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3105 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3106 /* vrf leak is for IPv4 and IPv6 Unicast only */
3107 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3110 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3111 if (from_bgp
== to_bgp
)
3114 /* bgp instance has import list, check to see if newly
3115 * configured bgp instance is the list.
3117 struct vpn_policy
*to_vpolicy
;
3119 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3120 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3122 if (strcmp(vname
, export_name
) != 0)
3126 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3128 export_name
, to_bgp
->name_pretty
);
3130 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3131 /* remove import rt, it will be readded
3132 * as part of import from vrf.
3136 to_vpolicy
->rtlist
[idir
],
3137 (struct ecommunity_val
*)
3139 vrf_import_from_vrf(to_bgp
, from_bgp
,