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 srv6_locator_chunk
*sid_locator_chunk
,
528 struct in6_addr
*sid
)
530 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
531 struct listnode
*node
;
532 struct srv6_locator_chunk
*chunk
;
533 bool alloced
= false;
536 uint8_t func_len
= 0, shift_len
= 0;
537 uint32_t index_max
= 0;
539 if (!bgp
|| !sid_locator_chunk
|| !sid
)
542 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_locator_chunks
, node
, chunk
)) {
543 if (chunk
->function_bits_length
>
544 BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
) {
547 "%s: invalid SRv6 Locator chunk (%pFX): Function Length must be less or equal to %d",
548 __func__
, &chunk
->prefix
,
549 BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
);
553 index_max
= (1 << chunk
->function_bits_length
) - 1;
555 if (index
> index_max
) {
558 "%s: skipped SRv6 Locator chunk (%pFX): Function Length is too short to support specified index (%u)",
559 __func__
, &chunk
->prefix
, index
);
563 *sid
= chunk
->prefix
.prefix
;
564 *sid_locator_chunk
= *chunk
;
565 offset
= chunk
->block_bits_length
+ chunk
->node_bits_length
;
566 func_len
= chunk
->function_bits_length
;
567 shift_len
= BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH
- func_len
;
570 label
= index
<< shift_len
;
571 if (label
< MPLS_LABEL_UNRESERVED_MIN
) {
574 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
575 __func__
, &chunk
->prefix
,
580 transpose_sid(sid
, label
, offset
, func_len
);
581 if (sid_exist(bgp
, sid
))
587 for (uint32_t i
= 1; i
< index_max
; i
++) {
588 label
= i
<< shift_len
;
589 if (label
< MPLS_LABEL_UNRESERVED_MIN
) {
592 "%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
593 __func__
, &chunk
->prefix
,
597 transpose_sid(sid
, label
, offset
, func_len
);
598 if (sid_exist(bgp
, sid
))
608 sid_register(bgp
, sid
, bgp
->srv6_locator_name
);
612 void ensure_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
614 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
616 struct srv6_locator_chunk
*tovpn_sid_locator
;
617 struct in6_addr
*tovpn_sid
;
618 uint32_t tovpn_sid_index
= 0, tovpn_sid_transpose_label
;
619 bool tovpn_sid_auto
= false;
622 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
623 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
625 /* skip when tovpn sid is already allocated on vrf instance */
626 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
)
630 * skip when bgp vpn instance ins't allocated
631 * or srv6 locator chunk isn't allocated
633 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
636 tovpn_sid_index
= bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
;
637 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
638 BGP_VPN_POLICY_TOVPN_SID_AUTO
);
640 /* skip when VPN isn't configured on vrf-instance */
641 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
644 /* check invalid case both configured index and auto */
645 if (tovpn_sid_index
!= 0 && tovpn_sid_auto
) {
646 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
651 tovpn_sid_locator
= srv6_locator_chunk_alloc();
652 tovpn_sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
654 tovpn_sid_transpose_label
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
,
655 tovpn_sid_locator
, tovpn_sid
);
657 if (tovpn_sid_transpose_label
== 0) {
658 zlog_debug("%s: not allocated new sid for vrf %s: afi %s",
659 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
660 srv6_locator_chunk_free(tovpn_sid_locator
);
661 XFREE(MTYPE_BGP_SRV6_SID
, tovpn_sid
);
666 inet_ntop(AF_INET6
, tovpn_sid
, buf
, sizeof(buf
));
667 zlog_debug("%s: new sid %s allocated for vrf %s: afi %s",
668 __func__
, buf
, bgp_vrf
->name_pretty
,
672 bgp_vrf
->vpn_policy
[afi
].tovpn_sid
= tovpn_sid
;
673 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_locator
= tovpn_sid_locator
;
674 bgp_vrf
->vpn_policy
[afi
].tovpn_sid_transpose_label
=
675 tovpn_sid_transpose_label
;
679 * This function embeds upper `len` bits of `label` in `sid`,
680 * starting at offset `offset` as seen from the MSB of `sid`.
682 * e.g. Given that `label` is 0x12345 and `len` is 16,
683 * then `label` will be embedded in `sid` as follows:
686 * label: 0001 0002 0003 0004 0005
687 * sid: .... 0001 0002 0003 0004
693 * e.g. Given that `label` is 0x12345 and `len` is 8,
694 * `label` will be embedded in `sid` as follows:
697 * label: 0001 0002 0003 0004 0005
698 * sid: .... 0001 0002 0000 0000
704 void transpose_sid(struct in6_addr
*sid
, uint32_t label
, uint8_t offset
,
707 for (uint8_t idx
= 0; idx
< len
; idx
++) {
708 uint8_t tidx
= offset
+ idx
;
709 sid
->s6_addr
[tidx
/ 8] &= ~(0x1 << (7 - tidx
% 8));
710 if (label
>> (19 - idx
) & 0x1)
711 sid
->s6_addr
[tidx
/ 8] |= 0x1 << (7 - tidx
% 8);
715 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
727 if (n
!= bpi
->extra
->num_labels
)
730 for (i
= 0; i
< n
; ++i
) {
731 if (label
[i
] != bpi
->extra
->label
[i
])
738 * make encoded route labels match specified encoded label set
740 static void setlabels(struct bgp_path_info
*bpi
,
741 mpls_label_t
*label
, /* array of labels */
746 assert(num_labels
<= BGP_MAX_LABELS
);
750 bpi
->extra
->num_labels
= 0;
754 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
757 for (i
= 0; i
< num_labels
; ++i
) {
758 extra
->label
[i
] = label
[i
];
759 if (!bgp_is_valid_label(&label
[i
])) {
760 bgp_set_valid_label(&extra
->label
[i
]);
763 extra
->num_labels
= num_labels
;
767 * make encoded route SIDs match specified encoded sid set
769 static void setsids(struct bgp_path_info
*bpi
,
770 struct in6_addr
*sid
,
774 struct bgp_path_info_extra
*extra
;
778 assert(num_sids
<= BGP_MAX_SIDS
);
782 bpi
->extra
->num_sids
= 0;
786 extra
= bgp_path_info_extra_get(bpi
);
787 for (i
= 0; i
< num_sids
; i
++)
788 memcpy(&extra
->sid
[i
].sid
, &sid
[i
], sizeof(struct in6_addr
));
789 extra
->num_sids
= num_sids
;
792 static void unsetsids(struct bgp_path_info
*bpi
)
794 struct bgp_path_info_extra
*extra
;
796 extra
= bgp_path_info_extra_get(bpi
);
798 memset(extra
->sid
, 0, sizeof(extra
->sid
));
801 static bool leak_update_nexthop_valid(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
802 struct attr
*new_attr
, afi_t afi
,
804 struct bgp_path_info
*source_bpi
,
805 struct bgp_path_info
*bpi
,
806 struct bgp
*bgp_orig
,
807 const struct prefix
*p
, int debug
)
809 struct bgp_path_info
*bpi_ultimate
;
810 struct bgp
*bgp_nexthop
;
813 bpi_ultimate
= bgp_get_imported_bpi_ultimate(source_bpi
);
815 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
816 bgp_nexthop
= bpi
->extra
->bgp_orig
;
818 bgp_nexthop
= bgp_orig
;
821 * No nexthop tracking for redistributed routes or for
822 * EVPN-imported routes that get leaked.
824 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
825 is_pi_family_evpn(bpi_ultimate
))
829 * TBD do we need to do anything about the
830 * 'connected' parameter?
832 nh_valid
= bgp_find_or_add_nexthop(to_bgp
, bgp_nexthop
, afi
,
833 safi
, bpi
, NULL
, 0, p
);
836 * If you are using SRv6 VPN instead of MPLS, it need to check
837 * the SID allocation. If the sid is not allocated, the rib
840 if (to_bgp
->srv6_enabled
&&
841 (!new_attr
->srv6_l3vpn
&& !new_attr
->srv6_vpn
)) {
846 zlog_debug("%s: %pFX nexthop is %svalid (in vrf %s)", __func__
,
847 p
, (nh_valid
? "" : "not "),
848 bgp_nexthop
->name_pretty
);
854 * returns pointer to new bgp_path_info upon success
856 static struct bgp_path_info
*
857 leak_update(struct bgp
*to_bgp
, struct bgp_dest
*bn
,
858 struct attr
*new_attr
, /* already interned */
859 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
860 mpls_label_t
*label
, uint32_t num_labels
, struct bgp
*bgp_orig
,
861 struct prefix
*nexthop_orig
, int nexthop_self_flag
, int debug
)
863 const struct prefix
*p
= bgp_dest_get_prefix(bn
);
864 struct bgp_path_info
*bpi
;
865 struct bgp_path_info
*new;
866 struct bgp_path_info_extra
*extra
;
867 uint32_t num_sids
= 0;
868 void *parent
= source_bpi
;
870 if (new_attr
->srv6_l3vpn
|| new_attr
->srv6_vpn
)
875 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
876 __func__
, to_bgp
->name_pretty
, bn
, source_bpi
->type
,
877 source_bpi
->sub_type
);
880 * Routes that are redistributed into BGP from zebra do not get
881 * nexthop tracking. However, if those routes are subsequently
882 * imported to other RIBs within BGP, the leaked routes do not
883 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
884 * in order to determine if the route we are currently leaking
885 * should have nexthop tracking, we must find the ultimate
886 * parent so we can check its sub_type.
888 * As of now, source_bpi may at most be a second-generation route
889 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
890 * Using a loop here supports more complex intra-bgp import-export
891 * schemes that could be implemented in the future.
898 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
899 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
904 bool labelssame
= labels_same(bpi
, label
, num_labels
);
906 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
907 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
910 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
911 __func__
, to_bgp
->name_pretty
,
912 source_bpi
->flags
, bpi
->flags
, p
);
917 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
918 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
920 bgp_attr_unintern(&new_attr
);
923 "%s: ->%s: %pBD: Found route, no change",
924 __func__
, to_bgp
->name_pretty
, bn
);
928 /* If the RT was changed via extended communities as an
929 * import/export list, we should withdraw implicitly the old
931 * For instance, RT list was modified using route-maps:
932 * route-map test permit 10
933 * set extcommunity rt none
935 if (CHECK_FLAG(bpi
->attr
->flag
,
936 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) &&
937 CHECK_FLAG(new_attr
->flag
,
938 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
940 bgp_attr_get_ecommunity(bpi
->attr
),
941 bgp_attr_get_ecommunity(new_attr
))) {
942 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
943 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
,
945 bgp_path_info_delete(bn
, bpi
);
949 /* attr is changed */
950 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
952 /* Rewrite BGP route information. */
953 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
954 bgp_path_info_restore(bn
, bpi
);
956 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
957 bgp_attr_unintern(&bpi
->attr
);
958 bpi
->attr
= new_attr
;
959 bpi
->uptime
= monotime(NULL
);
965 setlabels(bpi
, label
, num_labels
);
971 if (new_attr
->srv6_l3vpn
) {
972 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
975 extra
= bgp_path_info_extra_get(bpi
);
977 extra
->sid
[0].loc_block_len
=
978 new_attr
->srv6_l3vpn
->loc_block_len
;
979 extra
->sid
[0].loc_node_len
=
980 new_attr
->srv6_l3vpn
->loc_node_len
;
981 extra
->sid
[0].func_len
=
982 new_attr
->srv6_l3vpn
->func_len
;
983 extra
->sid
[0].arg_len
=
984 new_attr
->srv6_l3vpn
->arg_len
;
985 extra
->sid
[0].transposition_len
=
986 new_attr
->srv6_l3vpn
->transposition_len
;
987 extra
->sid
[0].transposition_offset
=
989 ->transposition_offset
;
990 } else if (new_attr
->srv6_vpn
)
991 setsids(bpi
, &new_attr
->srv6_vpn
->sid
,
996 if (nexthop_self_flag
)
997 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
999 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1000 source_bpi
, bpi
, bgp_orig
, p
,
1002 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
1004 bgp_path_info_unset_flag(bn
, bpi
, BGP_PATH_VALID
);
1006 /* Process change. */
1007 bgp_aggregate_increment(to_bgp
, p
, bpi
, afi
, safi
);
1008 bgp_process(to_bgp
, bn
, afi
, safi
);
1009 bgp_dest_unlock_node(bn
);
1012 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
1013 __func__
, to_bgp
->name_pretty
, bn
);
1018 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
1021 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
1022 __func__
, to_bgp
->name_pretty
,
1023 source_bpi
->flags
, p
);
1028 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
1029 to_bgp
->peer_self
, new_attr
, bn
);
1031 if (source_bpi
->peer
) {
1032 extra
= bgp_path_info_extra_get(new);
1033 extra
->peer_orig
= peer_lock(source_bpi
->peer
);
1036 if (nexthop_self_flag
)
1037 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
1039 bgp_path_info_extra_get(new);
1045 if (new_attr
->srv6_l3vpn
) {
1046 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
1048 extra
= bgp_path_info_extra_get(new);
1050 extra
->sid
[0].loc_block_len
=
1051 new_attr
->srv6_l3vpn
->loc_block_len
;
1052 extra
->sid
[0].loc_node_len
=
1053 new_attr
->srv6_l3vpn
->loc_node_len
;
1054 extra
->sid
[0].func_len
= new_attr
->srv6_l3vpn
->func_len
;
1055 extra
->sid
[0].arg_len
= new_attr
->srv6_l3vpn
->arg_len
;
1056 extra
->sid
[0].transposition_len
=
1057 new_attr
->srv6_l3vpn
->transposition_len
;
1058 extra
->sid
[0].transposition_offset
=
1059 new_attr
->srv6_l3vpn
->transposition_offset
;
1060 } else if (new_attr
->srv6_vpn
)
1061 setsids(new, &new_attr
->srv6_vpn
->sid
, num_sids
);
1066 setlabels(new, label
, num_labels
);
1068 new->extra
->parent
= bgp_path_info_lock(parent
);
1070 (struct bgp_dest
*)((struct bgp_path_info
*)parent
)->net
);
1072 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
1074 new->extra
->nexthop_orig
= *nexthop_orig
;
1076 if (leak_update_nexthop_valid(to_bgp
, bn
, new_attr
, afi
, safi
,
1077 source_bpi
, new, bgp_orig
, p
, debug
))
1078 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
1080 bgp_path_info_unset_flag(bn
, new, BGP_PATH_VALID
);
1082 bgp_aggregate_increment(to_bgp
, p
, new, afi
, safi
);
1083 bgp_path_info_add(bn
, new);
1085 bgp_dest_unlock_node(bn
);
1086 bgp_process(to_bgp
, bn
, afi
, safi
);
1089 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
1090 to_bgp
->name_pretty
, bn
);
1095 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
1096 void vpn_leak_from_vrf_update(struct bgp
*to_bgp
, /* to */
1097 struct bgp
*from_bgp
, /* from */
1098 struct bgp_path_info
*path_vrf
) /* route */
1100 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1101 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1102 afi_t afi
= family2afi(p
->family
);
1103 struct attr static_attr
= {0};
1104 struct attr
*new_attr
= NULL
;
1105 safi_t safi
= SAFI_MPLS_VPN
;
1106 mpls_label_t label_val
;
1108 struct bgp_dest
*bn
;
1109 const char *debugmsg
;
1110 int nexthop_self_flag
= 0;
1113 zlog_debug("%s: from vrf %s", __func__
, from_bgp
->name_pretty
);
1115 if (debug
&& bgp_attr_get_ecommunity(path_vrf
->attr
)) {
1116 char *s
= ecommunity_ecom2str(
1117 bgp_attr_get_ecommunity(path_vrf
->attr
),
1118 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1120 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
1121 from_bgp
->name
, path_vrf
->type
, s
);
1122 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1130 zlog_debug("%s: can't get afi of prefix", __func__
);
1134 /* Is this route exportable into the VPN table? */
1135 if (!is_route_injectable_into_vpn(path_vrf
))
1138 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1140 zlog_debug("%s: %s skipping: %s", __func__
,
1141 from_bgp
->name
, debugmsg
);
1146 static_attr
= *path_vrf
->attr
;
1149 * route map handling
1151 if (from_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1152 struct bgp_path_info info
;
1153 route_map_result_t ret
;
1155 memset(&info
, 0, sizeof(info
));
1156 info
.peer
= to_bgp
->peer_self
;
1157 info
.attr
= &static_attr
;
1158 ret
= route_map_apply(from_bgp
->vpn_policy
[afi
]
1159 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1161 if (RMAP_DENYMATCH
== ret
) {
1162 bgp_attr_flush(&static_attr
); /* free any added parts */
1165 "%s: vrf %s route map \"%s\" says DENY, returning",
1166 __func__
, from_bgp
->name_pretty
,
1167 from_bgp
->vpn_policy
[afi
]
1168 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
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 route map static_attr.ecommunity{%s}",
1181 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1185 * Add the vpn-policy rt-list
1187 struct ecommunity
*old_ecom
;
1188 struct ecommunity
*new_ecom
;
1190 /* Export with the 'from' instance's export RTs. */
1191 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1192 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1194 new_ecom
= ecommunity_dup(old_ecom
);
1195 if (CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1196 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1197 ecommunity_strip_rts(new_ecom
);
1198 new_ecom
= ecommunity_merge(
1199 new_ecom
, from_bgp
->vpn_policy
[afi
]
1200 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1201 if (!old_ecom
->refcnt
)
1202 ecommunity_free(&old_ecom
);
1204 new_ecom
= ecommunity_dup(
1205 from_bgp
->vpn_policy
[afi
]
1206 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1208 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1210 if (debug
&& bgp_attr_get_ecommunity(&static_attr
)) {
1211 char *s
= ecommunity_ecom2str(
1212 bgp_attr_get_ecommunity(&static_attr
),
1213 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1215 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1217 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1221 /* if policy nexthop not set, use 0 */
1222 if (CHECK_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1223 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1224 struct prefix
*nexthop
=
1225 &from_bgp
->vpn_policy
[afi
].tovpn_nexthop
;
1227 switch (nexthop
->family
) {
1229 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1231 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1233 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1234 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1238 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1239 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1246 if (!CHECK_FLAG(from_bgp
->af_flags
[afi
][SAFI_UNICAST
],
1247 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1248 if (afi
== AFI_IP
) {
1250 * For ipv4, copy to multiprotocol
1253 static_attr
.mp_nexthop_global_in
=
1254 static_attr
.nexthop
;
1255 static_attr
.mp_nexthop_len
=
1256 BGP_ATTR_NHLEN_IPV4
;
1258 * XXX Leave static_attr.nexthop
1262 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1265 /* Update based on next-hop family to account for
1266 * RFC 5549 (BGP unnumbered) scenario. Note that
1267 * specific action is only needed for the case of
1268 * IPv4 nexthops as the attr has been copied
1272 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1273 static_attr
.mp_nexthop_global_in
.s_addr
=
1274 static_attr
.nexthop
.s_addr
;
1275 static_attr
.mp_nexthop_len
=
1276 BGP_ATTR_NHLEN_IPV4
;
1278 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1281 nexthop_self_flag
= 1;
1284 label_val
= from_bgp
->vpn_policy
[afi
].tovpn_label
;
1285 if (label_val
== MPLS_LABEL_NONE
) {
1286 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1288 encode_label(label_val
, &label
);
1291 /* Set originator ID to "me" */
1292 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1293 static_attr
.originator_id
= to_bgp
->router_id
;
1295 /* Set SID for SRv6 VPN */
1296 if (from_bgp
->vpn_policy
[afi
].tovpn_sid_locator
) {
1298 from_bgp
->vpn_policy
[afi
].tovpn_sid_transpose_label
,
1300 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1301 sizeof(struct bgp_attr_srv6_l3vpn
));
1302 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1303 static_attr
.srv6_l3vpn
->endpoint_behavior
= 0xffff;
1304 static_attr
.srv6_l3vpn
->loc_block_len
=
1305 from_bgp
->vpn_policy
[afi
]
1306 .tovpn_sid_locator
->block_bits_length
;
1307 static_attr
.srv6_l3vpn
->loc_node_len
=
1308 from_bgp
->vpn_policy
[afi
]
1309 .tovpn_sid_locator
->node_bits_length
;
1310 static_attr
.srv6_l3vpn
->func_len
=
1311 from_bgp
->vpn_policy
[afi
]
1312 .tovpn_sid_locator
->function_bits_length
;
1313 static_attr
.srv6_l3vpn
->arg_len
=
1314 from_bgp
->vpn_policy
[afi
]
1315 .tovpn_sid_locator
->argument_bits_length
;
1316 static_attr
.srv6_l3vpn
->transposition_len
=
1317 from_bgp
->vpn_policy
[afi
]
1318 .tovpn_sid_locator
->function_bits_length
;
1319 static_attr
.srv6_l3vpn
->transposition_offset
=
1320 from_bgp
->vpn_policy
[afi
]
1321 .tovpn_sid_locator
->block_bits_length
+
1322 from_bgp
->vpn_policy
[afi
]
1323 .tovpn_sid_locator
->node_bits_length
;
1325 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1326 &from_bgp
->vpn_policy
[afi
]
1327 .tovpn_sid_locator
->prefix
.prefix
,
1328 sizeof(struct in6_addr
));
1332 new_attr
= bgp_attr_intern(
1333 &static_attr
); /* hashed refcounted everything */
1334 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1336 if (debug
&& bgp_attr_get_ecommunity(new_attr
)) {
1337 char *s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(new_attr
),
1338 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1340 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1341 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1344 /* Now new_attr is an allocated interned attr */
1346 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1347 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1349 struct bgp_path_info
*new_info
;
1352 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vrf
, &label
,
1353 1, from_bgp
, NULL
, nexthop_self_flag
, debug
);
1356 * Routes actually installed in the vpn RIB must also be
1357 * offered to all vrfs (because now they originate from
1360 * Acceptance into other vrfs depends on rt-lists.
1361 * Originating vrf will not accept the looped back route
1362 * because of loop checking.
1365 vpn_leak_to_vrf_update(from_bgp
, new_info
);
1368 void vpn_leak_from_vrf_withdraw(struct bgp
*to_bgp
, /* to */
1369 struct bgp
*from_bgp
, /* from */
1370 struct bgp_path_info
*path_vrf
) /* route */
1372 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1373 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1374 afi_t afi
= family2afi(p
->family
);
1375 safi_t safi
= SAFI_MPLS_VPN
;
1376 struct bgp_path_info
*bpi
;
1377 struct bgp_dest
*bn
;
1378 const char *debugmsg
;
1382 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1383 __func__
, from_bgp
->name_pretty
, path_vrf
->net
,
1384 path_vrf
->type
, path_vrf
->sub_type
);
1392 zlog_debug("%s: can't get afi of prefix", __func__
);
1396 /* Is this route exportable into the VPN table? */
1397 if (!is_route_injectable_into_vpn(path_vrf
))
1400 if (!vpn_leak_to_vpn_active(from_bgp
, afi
, &debugmsg
)) {
1402 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1407 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1409 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
,
1410 &(from_bgp
->vpn_policy
[afi
].tovpn_rd
));
1416 * match original bpi imported from
1418 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1419 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1425 /* withdraw from looped vrfs as well */
1426 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1428 bgp_aggregate_decrement(to_bgp
, p
, bpi
, afi
, safi
);
1429 bgp_path_info_delete(bn
, bpi
);
1430 bgp_process(to_bgp
, bn
, afi
, safi
);
1432 bgp_dest_unlock_node(bn
);
1435 void vpn_leak_from_vrf_withdraw_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1438 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1439 struct bgp_dest
*pdest
;
1440 safi_t safi
= SAFI_MPLS_VPN
;
1443 * Walk vpn table, delete bpi with bgp_orig == from_bgp
1445 for (pdest
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); pdest
;
1446 pdest
= bgp_route_next(pdest
)) {
1448 struct bgp_table
*table
;
1449 struct bgp_dest
*bn
;
1450 struct bgp_path_info
*bpi
;
1452 /* This is the per-RD table of prefixes */
1453 table
= bgp_dest_get_bgp_table_info(pdest
);
1458 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1459 bpi
= bgp_dest_get_bgp_path_info(bn
);
1461 zlog_debug("%s: looking at prefix %pBD",
1465 for (; bpi
; bpi
= bpi
->next
) {
1467 zlog_debug("%s: type %d, sub_type %d",
1468 __func__
, bpi
->type
,
1470 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1474 if ((struct bgp
*)bpi
->extra
->bgp_orig
==
1478 zlog_debug("%s: deleting it",
1480 /* withdraw from leak-to vrfs as well */
1481 vpn_leak_to_vrf_withdraw(to_bgp
, bpi
);
1482 bgp_aggregate_decrement(
1483 to_bgp
, bgp_dest_get_prefix(bn
),
1485 bgp_path_info_delete(bn
, bpi
);
1486 bgp_process(to_bgp
, bn
, afi
, safi
);
1493 void vpn_leak_from_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1496 struct bgp_dest
*bn
;
1497 struct bgp_path_info
*bpi
;
1498 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1501 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1502 from_bgp
->name_pretty
);
1504 for (bn
= bgp_table_top(from_bgp
->rib
[afi
][SAFI_UNICAST
]); bn
;
1505 bn
= bgp_route_next(bn
)) {
1508 zlog_debug("%s: node=%p", __func__
, bn
);
1510 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1514 "%s: calling vpn_leak_from_vrf_update",
1516 vpn_leak_from_vrf_update(to_bgp
, from_bgp
, bpi
);
1522 vpn_leak_to_vrf_update_onevrf(struct bgp
*to_bgp
, /* to */
1523 struct bgp
*from_bgp
, /* from */
1524 struct bgp_path_info
*path_vpn
) /* route */
1526 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1527 afi_t afi
= family2afi(p
->family
);
1529 struct attr static_attr
= {0};
1530 struct attr
*new_attr
= NULL
;
1531 struct bgp_dest
*bn
;
1532 safi_t safi
= SAFI_UNICAST
;
1533 const char *debugmsg
;
1534 struct prefix nexthop_orig
;
1535 mpls_label_t
*pLabels
= NULL
;
1536 uint32_t num_labels
= 0;
1537 int nexthop_self_flag
= 1;
1538 struct bgp_path_info
*bpi_ultimate
= NULL
;
1539 int origin_local
= 0;
1540 struct bgp
*src_vrf
;
1542 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1544 if (!vpn_leak_from_vpn_active(to_bgp
, afi
, &debugmsg
)) {
1546 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1550 /* Check for intersection of route targets */
1551 if (!ecommunity_include(
1552 to_bgp
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1553 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1556 "from vpn (%s) to vrf (%s), skipping after no intersection of route targets",
1557 from_bgp
->name_pretty
, to_bgp
->name_pretty
);
1562 zlog_debug("%s: updating %pFX to vrf %s", __func__
, p
,
1563 to_bgp
->name_pretty
);
1566 static_attr
= *path_vpn
->attr
;
1568 struct ecommunity
*old_ecom
;
1569 struct ecommunity
*new_ecom
;
1571 /* If doing VRF-to-VRF leaking, strip RTs. */
1572 old_ecom
= bgp_attr_get_ecommunity(&static_attr
);
1573 if (old_ecom
&& CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1574 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1575 new_ecom
= ecommunity_dup(old_ecom
);
1576 ecommunity_strip_rts(new_ecom
);
1577 bgp_attr_set_ecommunity(&static_attr
, new_ecom
);
1579 if (new_ecom
->size
== 0) {
1580 ecommunity_free(&new_ecom
);
1581 bgp_attr_set_ecommunity(&static_attr
, NULL
);
1584 if (!old_ecom
->refcnt
)
1585 ecommunity_free(&old_ecom
);
1589 * Nexthop: stash and clear
1591 * Nexthop is valid in context of VPN core, but not in destination vrf.
1592 * Stash it for later label resolution by vrf ingress path and then
1593 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1595 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1597 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1598 nexthop_orig
.family
= nhfamily
;
1603 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1604 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
1606 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1607 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1608 static_attr
.nexthop
.s_addr
=
1609 nexthop_orig
.u
.prefix4
.s_addr
;
1611 static_attr
.mp_nexthop_global_in
=
1612 path_vpn
->attr
->mp_nexthop_global_in
;
1613 static_attr
.mp_nexthop_len
=
1614 path_vpn
->attr
->mp_nexthop_len
;
1616 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1620 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1621 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
1623 if (CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1624 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1625 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1631 * route map handling
1633 if (to_bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1634 struct bgp_path_info info
;
1635 route_map_result_t ret
;
1637 memset(&info
, 0, sizeof(info
));
1638 info
.peer
= to_bgp
->peer_self
;
1639 info
.attr
= &static_attr
;
1640 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1641 ret
= route_map_apply(to_bgp
->vpn_policy
[afi
]
1642 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1644 if (RMAP_DENYMATCH
== ret
) {
1645 bgp_attr_flush(&static_attr
); /* free any added parts */
1648 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1649 __func__
, to_bgp
->name_pretty
,
1650 to_bgp
->vpn_policy
[afi
]
1651 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1656 * if route-map changed nexthop, don't nexthop-self on output
1658 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1659 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1660 nexthop_self_flag
= 0;
1663 new_attr
= bgp_attr_intern(&static_attr
);
1664 bgp_attr_flush(&static_attr
);
1666 bn
= bgp_afi_node_get(to_bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1669 * ensure labels are copied
1671 * However, there is a special case: if the route originated in
1672 * another local VRF (as opposed to arriving via VPN), then the
1673 * nexthop is reached by hairpinning through this router (me)
1674 * using IP forwarding only (no LSP). Therefore, the route
1675 * imported to the VRF should not have labels attached. Note
1676 * that nexthop tracking is also involved: eliminating the
1677 * labels for these routes enables the non-labeled nexthops
1678 * from the originating VRF to be considered valid for this route.
1680 if (!CHECK_FLAG(to_bgp
->af_flags
[afi
][safi
],
1681 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1682 /* work back to original route */
1683 bpi_ultimate
= bgp_get_imported_bpi_ultimate(path_vpn
);
1686 * if original route was unicast,
1687 * then it did not arrive over vpn
1689 if (bpi_ultimate
->net
) {
1690 struct bgp_table
*table
;
1692 table
= bgp_dest_table(bpi_ultimate
->net
);
1693 if (table
&& (table
->safi
== SAFI_UNICAST
))
1698 if (!origin_local
&& path_vpn
->extra
1699 && path_vpn
->extra
->num_labels
) {
1700 num_labels
= path_vpn
->extra
->num_labels
;
1701 if (num_labels
> BGP_MAX_LABELS
)
1702 num_labels
= BGP_MAX_LABELS
;
1703 pLabels
= path_vpn
->extra
->label
;
1708 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
1709 path_vpn
->net
, num_labels
);
1712 * For VRF-2-VRF route-leaking,
1713 * the source will be the originating VRF.
1715 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1716 src_vrf
= path_vpn
->extra
->bgp_orig
;
1720 leak_update(to_bgp
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
1721 num_labels
, src_vrf
, &nexthop_orig
, nexthop_self_flag
,
1726 bool vpn_leak_to_vrf_update(struct bgp
*from_bgp
, /* from */
1727 struct bgp_path_info
*path_vpn
) /* route */
1729 struct listnode
*mnode
, *mnnode
;
1731 bool leak_success
= false;
1733 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1736 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1738 /* Loop over VRFs */
1739 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1741 if (!path_vpn
->extra
1742 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1743 leak_success
|= vpn_leak_to_vrf_update_onevrf(
1744 bgp
, from_bgp
, path_vpn
);
1747 return leak_success
;
1750 void vpn_leak_to_vrf_withdraw(struct bgp
*from_bgp
, /* from */
1751 struct bgp_path_info
*path_vpn
) /* route */
1753 const struct prefix
*p
;
1755 safi_t safi
= SAFI_UNICAST
;
1757 struct listnode
*mnode
, *mnnode
;
1758 struct bgp_dest
*bn
;
1759 struct bgp_path_info
*bpi
;
1760 const char *debugmsg
;
1762 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1765 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
1766 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
1769 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1771 if (!path_vpn
->net
) {
1772 #ifdef ENABLE_BGP_VNC
1773 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1774 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
1775 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1782 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1787 p
= bgp_dest_get_prefix(path_vpn
->net
);
1788 afi
= family2afi(p
->family
);
1790 /* Loop over VRFs */
1791 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1792 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1794 zlog_debug("%s: skipping: %s", __func__
,
1799 /* Check for intersection of route targets */
1800 if (!ecommunity_include(
1801 bgp
->vpn_policy
[afi
]
1802 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1803 bgp_attr_get_ecommunity(path_vpn
->attr
))) {
1809 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1812 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1814 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1817 && (struct bgp_path_info
*)bpi
->extra
->parent
1825 zlog_debug("%s: deleting bpi %p", __func__
,
1827 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
1828 bgp_path_info_delete(bn
, bpi
);
1829 bgp_process(bgp
, bn
, afi
, safi
);
1831 bgp_dest_unlock_node(bn
);
1835 void vpn_leak_to_vrf_withdraw_all(struct bgp
*to_bgp
, afi_t afi
)
1837 struct bgp_dest
*bn
;
1838 struct bgp_path_info
*bpi
;
1839 safi_t safi
= SAFI_UNICAST
;
1840 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1843 zlog_debug("%s: entry", __func__
);
1845 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1847 for (bn
= bgp_table_top(to_bgp
->rib
[afi
][safi
]); bn
;
1848 bn
= bgp_route_next(bn
)) {
1850 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1852 if (bpi
->extra
&& bpi
->extra
->bgp_orig
!= to_bgp
&&
1853 bpi
->extra
->parent
&&
1854 is_pi_family_vpn(bpi
->extra
->parent
)) {
1857 bgp_aggregate_decrement(to_bgp
,
1858 bgp_dest_get_prefix(bn
),
1860 bgp_path_info_delete(bn
, bpi
);
1861 bgp_process(to_bgp
, bn
, afi
, safi
);
1867 void vpn_leak_to_vrf_update_all(struct bgp
*to_bgp
, struct bgp
*vpn_from
,
1870 struct bgp_dest
*pdest
;
1871 safi_t safi
= SAFI_MPLS_VPN
;
1878 for (pdest
= bgp_table_top(vpn_from
->rib
[afi
][safi
]); pdest
;
1879 pdest
= bgp_route_next(pdest
)) {
1880 struct bgp_table
*table
;
1881 struct bgp_dest
*bn
;
1882 struct bgp_path_info
*bpi
;
1884 /* This is the per-RD table of prefixes */
1885 table
= bgp_dest_get_bgp_table_info(pdest
);
1890 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1892 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1896 bpi
->extra
->bgp_orig
== to_bgp
)
1899 vpn_leak_to_vrf_update_onevrf(to_bgp
, vpn_from
,
1907 * This function is called for definition/deletion/change to a route-map
1909 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1911 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1913 struct route_map
*rmap
;
1915 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1916 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1921 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1923 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1925 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1926 && !strcmp(rmap_name
,
1927 bgp
->vpn_policy
[afi
]
1928 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1932 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1933 __func__
, rmap_name
, bgp
->as
,
1936 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1937 bgp_get_default(), bgp
);
1939 zlog_debug("%s: after vpn_leak_prechange",
1942 /* in case of definition/deletion */
1943 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1946 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1947 bgp_get_default(), bgp
);
1950 zlog_debug("%s: after vpn_leak_postchange",
1954 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1955 && !strcmp(rmap_name
,
1956 bgp
->vpn_policy
[afi
]
1957 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1960 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1961 __func__
, rmap_name
, bgp
->as
,
1965 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1966 bgp_get_default(), bgp
);
1968 /* in case of definition/deletion */
1969 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1972 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1973 bgp_get_default(), bgp
);
1978 /* This API is used during router-id change, reflect VPNs
1979 * auto RD and RT values and readvertise routes to VPN table.
1981 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
1985 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
1986 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1988 const char *export_name
;
1989 char buf
[RD_ADDRSTRLEN
];
1990 struct bgp
*bgp_import
;
1991 struct listnode
*node
;
1992 struct ecommunity
*ecom
;
1993 enum vpn_policy_direction idir
, edir
;
1996 * Router-id change that is not explicitly configured
1997 * (a change from zebra, frr restart for example)
1998 * should not replace a configured vpn RD/RT.
2002 zlog_debug("%s: skipping non explicit router-id change",
2007 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
2008 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2011 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
2012 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2013 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2015 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2016 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
2020 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
2021 afi
, bgp_get_default(), bgp
);
2023 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
2024 __func__
, export_name
);
2026 /* Remove import RT from VRFs */
2027 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2028 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2029 export_vrf
, node
, vname
)) {
2030 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2031 bgp_import
= bgp_get_default();
2033 bgp_import
= bgp_lookup_by_name(vname
);
2038 bgp_import
->vpn_policy
[afi
]
2040 (struct ecommunity_val
*)ecom
->val
);
2043 /* New router-id derive auto RD and RT and export
2046 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
2047 &bgp
->vrf_prd_auto
);
2048 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
2049 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
2052 /* free up pre-existing memory if any and allocate
2053 * the ecommunity attribute with new RD/RT
2055 if (bgp
->vpn_policy
[afi
].rtlist
[edir
])
2057 &bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2058 bgp
->vpn_policy
[afi
].rtlist
[edir
] = ecommunity_str2com(
2059 buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2061 /* Update import_vrf rt_list */
2062 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
2063 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
2064 export_vrf
, node
, vname
)) {
2065 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
2066 bgp_import
= bgp_get_default();
2068 bgp_import
= bgp_lookup_by_name(vname
);
2071 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
2072 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2074 bgp_import
->vpn_policy
[afi
]
2075 .rtlist
[idir
], ecom
);
2077 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
2078 = ecommunity_dup(ecom
);
2081 /* Update routes to VPN */
2082 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
2083 afi
, bgp_get_default(),
2086 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
2087 __func__
, export_name
);
2092 void vpn_policy_routemap_event(const char *rmap_name
)
2094 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
2095 struct listnode
*mnode
, *mnnode
;
2099 zlog_debug("%s: entry", __func__
);
2101 if (bm
->bgp
== NULL
) /* may be called during cleanup */
2104 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
2105 vpn_policy_routemap_update(bgp
, rmap_name
);
2108 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2109 afi_t afi
, safi_t safi
)
2111 const char *export_name
;
2112 enum vpn_policy_direction idir
, edir
;
2113 char *vname
, *tmp_name
;
2114 char buf
[RD_ADDRSTRLEN
];
2115 struct ecommunity
*ecom
;
2116 bool first_export
= false;
2118 struct listnode
*node
;
2119 bool is_inst_match
= false;
2121 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2122 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2123 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2125 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2126 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2129 * Cross-ref both VRFs. Also, note if this is the first time
2130 * any VRF is importing from "import_vrf".
2132 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2133 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2135 /* Check the import_vrf list of destination vrf for the source vrf name,
2138 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2140 if (strcmp(vname
, tmp_name
) == 0) {
2141 is_inst_match
= true;
2146 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2149 XFREE(MTYPE_TMP
, vname
);
2151 /* Check if the source vrf already exports to any vrf,
2152 * first time export requires to setup auto derived RD/RT values.
2153 * Add the destination vrf name to export vrf list if it is
2156 is_inst_match
= false;
2157 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2158 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2159 first_export
= true;
2161 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2163 if (strcmp(vname
, tmp_name
) == 0) {
2164 is_inst_match
= true;
2170 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2173 XFREE(MTYPE_TMP
, vname
);
2175 /* Update import RT for current VRF using export RT of the VRF we're
2176 * importing from. First though, make sure "import_vrf" has that
2180 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2181 &from_bgp
->vrf_prd_auto
);
2182 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2183 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2184 BGP_VPN_POLICY_TOVPN_RD_SET
);
2185 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
2187 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2188 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2189 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2190 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2191 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2192 BGP_PREVENT_VRF_2_VRF_LEAK
;
2194 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2195 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2196 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2197 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2198 .rtlist
[idir
], ecom
);
2200 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2201 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2204 const char *from_name
;
2205 char *ecom1
, *ecom2
;
2207 from_name
= from_bgp
->name
? from_bgp
->name
:
2210 ecom1
= ecommunity_ecom2str(
2211 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2212 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2214 ecom2
= ecommunity_ecom2str(
2215 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2216 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2219 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2220 __func__
, from_name
, export_name
, first_export
, ecom1
,
2223 ecommunity_strfree(&ecom1
);
2224 ecommunity_strfree(&ecom2
);
2227 /* Does "import_vrf" first need to export its routes or that
2228 * is already done and we just need to import those routes
2229 * from the global table?
2232 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2234 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2237 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2238 afi_t afi
, safi_t safi
)
2240 const char *export_name
, *tmp_name
;
2241 enum vpn_policy_direction idir
, edir
;
2243 struct ecommunity
*ecom
= NULL
;
2244 struct listnode
*node
;
2247 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2248 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2249 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2250 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2252 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2253 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2255 /* Were we importing from "import_vrf"? */
2256 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2258 if (strcmp(vname
, tmp_name
) == 0)
2263 * We do not check in the cli if the passed in bgp
2264 * instance is actually imported into us before
2265 * we call this function. As such if we do not
2266 * find this in the import_vrf list than
2267 * we just need to return safely.
2273 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2275 /* Remove "import_vrf" from our import list. */
2276 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2277 XFREE(MTYPE_TMP
, vname
);
2279 /* Remove routes imported from "import_vrf". */
2280 /* TODO: In the current logic, we have to first remove all
2281 * imported routes and then (if needed) import back routes
2283 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2285 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2286 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2287 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2288 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2289 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2290 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2292 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2294 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2295 (struct ecommunity_val
*)ecom
->val
);
2296 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2301 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2302 * below is checking for NULL that export_vrf can be
2303 * NULL, consequently it is complaining( like a cabbage )
2304 * that we could dereference and crash in the listcount(..)
2306 * So make it happy, under protest, with liberty and justice
2309 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2311 /* Remove us from "import_vrf's" export list. If no other VRF
2312 * is importing from "import_vrf", cleanup appropriately.
2314 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2316 if (strcmp(vname
, export_name
) == 0)
2321 * If we have gotten to this point then the vname must
2322 * exist. If not, we are in a world of trouble and
2323 * have slag sitting around.
2325 * import_vrf and export_vrf must match in having
2326 * the in/out names as appropriate.
2327 * export_vrf list could have been cleaned up
2328 * as part of no router bgp source instnace.
2333 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2334 XFREE(MTYPE_TMP
, vname
);
2336 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2337 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2338 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2339 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2340 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2341 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2342 sizeof(struct prefix_rd
));
2343 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2344 BGP_VPN_POLICY_TOVPN_RD_SET
);
2345 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2350 /* For testing purpose, static route of MPLS-VPN. */
2351 DEFUN (vpnv4_network
,
2353 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2354 "Specify a network to announce via BGP\n"
2356 "Specify Route Distinguisher\n"
2357 "VPN Route Distinguisher\n"
2358 "VPN NLRI label (tag)\n"
2359 "VPN NLRI label (tag)\n"
2362 int idx_ipv4_prefixlen
= 1;
2363 int idx_ext_community
= 3;
2365 return bgp_static_set_safi(
2366 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2367 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
2368 NULL
, NULL
, NULL
, NULL
);
2371 DEFUN (vpnv4_network_route_map
,
2372 vpnv4_network_route_map_cmd
,
2373 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map RMAP_NAME",
2374 "Specify a network to announce via BGP\n"
2376 "Specify Route Distinguisher\n"
2377 "VPN Route Distinguisher\n"
2378 "VPN NLRI label (tag)\n"
2379 "VPN NLRI label (tag)\n"
2384 int idx_ipv4_prefixlen
= 1;
2385 int idx_ext_community
= 3;
2388 return bgp_static_set_safi(
2389 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2390 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2391 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2394 /* For testing purpose, static route of MPLS-VPN. */
2395 DEFUN (no_vpnv4_network
,
2396 no_vpnv4_network_cmd
,
2397 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2399 "Specify a network to announce via BGP\n"
2401 "Specify Route Distinguisher\n"
2402 "VPN Route Distinguisher\n"
2403 "VPN NLRI label (tag)\n"
2404 "VPN NLRI label (tag)\n"
2407 int idx_ipv4_prefixlen
= 2;
2408 int idx_ext_community
= 4;
2410 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
2411 argv
[idx_ipv4_prefixlen
]->arg
,
2412 argv
[idx_ext_community
]->arg
,
2413 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2416 DEFUN (vpnv6_network
,
2418 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map RMAP_NAME]",
2419 "Specify a network to announce via BGP\n"
2420 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2421 "Specify Route Distinguisher\n"
2422 "VPN Route Distinguisher\n"
2423 "VPN NLRI label (tag)\n"
2424 "VPN NLRI label (tag)\n"
2429 int idx_ipv6_prefix
= 1;
2430 int idx_ext_community
= 3;
2434 return bgp_static_set_safi(
2435 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2436 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2437 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2439 return bgp_static_set_safi(
2440 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2441 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2442 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2445 /* For testing purpose, static route of MPLS-VPN. */
2446 DEFUN (no_vpnv6_network
,
2447 no_vpnv6_network_cmd
,
2448 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2450 "Specify a network to announce via BGP\n"
2451 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2452 "Specify Route Distinguisher\n"
2453 "VPN Route Distinguisher\n"
2454 "VPN NLRI label (tag)\n"
2455 "VPN NLRI label (tag)\n"
2458 int idx_ipv6_prefix
= 2;
2459 int idx_ext_community
= 4;
2461 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2462 argv
[idx_ipv6_prefix
]->arg
,
2463 argv
[idx_ext_community
]->arg
,
2464 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2467 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2468 enum bgp_show_type type
, void *output_arg
, int tags
,
2472 struct bgp_table
*table
;
2474 bgp
= bgp_get_default();
2477 vty_out(vty
, "No BGP process is configured\n");
2479 vty_out(vty
, "{}\n");
2482 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2483 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2484 output_arg
, use_json
);
2487 DEFUN (show_bgp_ip_vpn_all_rd
,
2488 show_bgp_ip_vpn_all_rd_cmd
,
2489 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2493 "Display VPN NLRI specific information\n"
2494 "Display VPN NLRI specific information\n"
2495 "Display information for a route distinguisher\n"
2496 "VPN Route Distinguisher\n"
2497 "All VPN Route Distinguishers\n"
2501 struct prefix_rd prd
;
2505 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2506 /* Constrain search if user supplies RD && RD != "all" */
2507 if (argv_find(argv
, argc
, "rd", &idx
)
2508 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
2509 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2512 "%% Malformed Route Distinguisher\n");
2515 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2516 bgp_show_type_normal
, NULL
, 0,
2517 use_json(argc
, argv
));
2519 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2520 bgp_show_type_normal
, NULL
, 0,
2521 use_json(argc
, argv
));
2527 ALIAS(show_bgp_ip_vpn_all_rd
,
2528 show_bgp_ip_vpn_rd_cmd
,
2529 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2533 "Display VPN NLRI specific information\n"
2534 "Display information for a route distinguisher\n"
2535 "VPN Route Distinguisher\n"
2536 "All VPN Route Distinguishers\n"
2539 #ifdef KEEP_OLD_VPN_COMMANDS
2540 DEFUN (show_ip_bgp_vpn_rd
,
2541 show_ip_bgp_vpn_rd_cmd
,
2542 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2548 "Display information for a route distinguisher\n"
2549 "VPN Route Distinguisher\n"
2550 "All VPN Route Distinguishers\n")
2552 int idx_ext_community
= argc
- 1;
2554 struct prefix_rd prd
;
2558 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2559 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2560 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2561 bgp_show_type_normal
, NULL
, 0,
2563 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2565 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2568 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2574 DEFUN (show_ip_bgp_vpn_all
,
2575 show_ip_bgp_vpn_all_cmd
,
2576 "show [ip] bgp <vpnv4|vpnv6>",
2585 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2586 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2591 DEFUN (show_ip_bgp_vpn_all_tags
,
2592 show_ip_bgp_vpn_all_tags_cmd
,
2593 "show [ip] bgp <vpnv4|vpnv6> all tags",
2598 "Display information about all VPNv4/VPNV6 NLRIs\n"
2599 "Display BGP tags for prefixes\n")
2604 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2605 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2610 DEFUN (show_ip_bgp_vpn_rd_tags
,
2611 show_ip_bgp_vpn_rd_tags_cmd
,
2612 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2617 "Display information for a route distinguisher\n"
2618 "VPN Route Distinguisher\n"
2619 "All VPN Route Distinguishers\n"
2620 "Display BGP tags for prefixes\n")
2622 int idx_ext_community
= 5;
2624 struct prefix_rd prd
;
2628 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2629 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2630 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2631 bgp_show_type_normal
, NULL
, 1,
2633 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2635 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2638 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2644 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2645 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2646 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2651 "Display information about all VPNv4/VPNv6 NLRIs\n"
2652 "Detailed information on TCP and BGP neighbor connections\n"
2653 "Neighbor to display information about\n"
2654 "Display routes learned from neighbor\n"
2661 bool uj
= use_json(argc
, argv
);
2665 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2666 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2669 json_object
*json_no
= NULL
;
2670 json_no
= json_object_new_object();
2671 json_object_string_add(json_no
, "warning",
2672 "Malformed address");
2673 vty_out(vty
, "%s\n",
2674 json_object_to_json_string(json_no
));
2675 json_object_free(json_no
);
2677 vty_out(vty
, "Malformed address: %s\n",
2678 argv
[idx_ipv4
]->arg
);
2682 peer
= peer_lookup(NULL
, &su
);
2683 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2685 json_object
*json_no
= NULL
;
2686 json_no
= json_object_new_object();
2687 json_object_string_add(
2689 "No such neighbor or address family");
2690 vty_out(vty
, "%s\n",
2691 json_object_to_json_string(json_no
));
2692 json_object_free(json_no
);
2695 "%% No such neighbor or address family\n");
2699 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2705 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2706 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2707 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
2712 "Display information for a route distinguisher\n"
2713 "VPN Route Distinguisher\n"
2714 "All VPN Route Distinguishers\n"
2715 "Detailed information on TCP and BGP neighbor connections\n"
2716 "Neighbor to display information about\n"
2717 "Display routes learned from neighbor\n"
2720 int idx_ext_community
= 5;
2725 struct prefix_rd prd
;
2726 bool prefix_rd_all
= false;
2727 bool uj
= use_json(argc
, argv
);
2731 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2732 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2733 prefix_rd_all
= true;
2735 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2738 json_object
*json_no
= NULL
;
2739 json_no
= json_object_new_object();
2740 json_object_string_add(
2742 "Malformed Route Distinguisher");
2743 vty_out(vty
, "%s\n",
2744 json_object_to_json_string(
2746 json_object_free(json_no
);
2749 "%% Malformed Route Distinguisher\n");
2754 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2757 json_object
*json_no
= NULL
;
2758 json_no
= json_object_new_object();
2759 json_object_string_add(json_no
, "warning",
2760 "Malformed address");
2761 vty_out(vty
, "%s\n",
2762 json_object_to_json_string(json_no
));
2763 json_object_free(json_no
);
2765 vty_out(vty
, "Malformed address: %s\n",
2766 argv
[idx_ext_community
]->arg
);
2770 peer
= peer_lookup(NULL
, &su
);
2771 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2773 json_object
*json_no
= NULL
;
2774 json_no
= json_object_new_object();
2775 json_object_string_add(
2777 "No such neighbor or address family");
2778 vty_out(vty
, "%s\n",
2779 json_object_to_json_string(json_no
));
2780 json_object_free(json_no
);
2783 "%% No such neighbor or address family\n");
2788 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2789 bgp_show_type_neighbor
, &su
, 0,
2792 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2793 bgp_show_type_neighbor
, &su
, 0,
2799 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2800 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2801 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2806 "Display information about all VPNv4/VPNv6 NLRIs\n"
2807 "Detailed information on TCP and BGP neighbor connections\n"
2808 "Neighbor to display information about\n"
2809 "Display the routes advertised to a BGP neighbor\n"
2816 bool uj
= use_json(argc
, argv
);
2820 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2821 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2824 json_object
*json_no
= NULL
;
2825 json_no
= json_object_new_object();
2826 json_object_string_add(json_no
, "warning",
2827 "Malformed address");
2828 vty_out(vty
, "%s\n",
2829 json_object_to_json_string(json_no
));
2830 json_object_free(json_no
);
2832 vty_out(vty
, "Malformed address: %s\n",
2833 argv
[idx_ipv4
]->arg
);
2836 peer
= peer_lookup(NULL
, &su
);
2837 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2839 json_object
*json_no
= NULL
;
2840 json_no
= json_object_new_object();
2841 json_object_string_add(
2843 "No such neighbor or address family");
2844 vty_out(vty
, "%s\n",
2845 json_object_to_json_string(json_no
));
2846 json_object_free(json_no
);
2849 "%% No such neighbor or address family\n");
2852 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2858 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2859 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2860 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
2865 "Display information for a route distinguisher\n"
2866 "VPN Route Distinguisher\n"
2867 "All VPN Route Distinguishers\n"
2868 "Detailed information on TCP and BGP neighbor connections\n"
2869 "Neighbor to display information about\n"
2870 "Display the routes advertised to a BGP neighbor\n"
2873 int idx_ext_community
= 5;
2877 struct prefix_rd prd
;
2879 bool uj
= use_json(argc
, argv
);
2883 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2884 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2887 json_object
*json_no
= NULL
;
2888 json_no
= json_object_new_object();
2889 json_object_string_add(json_no
, "warning",
2890 "Malformed address");
2891 vty_out(vty
, "%s\n",
2892 json_object_to_json_string(json_no
));
2893 json_object_free(json_no
);
2895 vty_out(vty
, "Malformed address: %s\n",
2896 argv
[idx_ext_community
]->arg
);
2899 peer
= peer_lookup(NULL
, &su
);
2900 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2902 json_object
*json_no
= NULL
;
2903 json_no
= json_object_new_object();
2904 json_object_string_add(
2906 "No such neighbor or address family");
2907 vty_out(vty
, "%s\n",
2908 json_object_to_json_string(json_no
));
2909 json_object_free(json_no
);
2912 "%% No such neighbor or address family\n");
2916 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2917 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2919 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2922 json_object
*json_no
= NULL
;
2923 json_no
= json_object_new_object();
2924 json_object_string_add(
2926 "Malformed Route Distinguisher");
2927 vty_out(vty
, "%s\n",
2928 json_object_to_json_string(json_no
));
2929 json_object_free(json_no
);
2932 "%% Malformed Route Distinguisher\n");
2936 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2941 #endif /* KEEP_OLD_VPN_COMMANDS */
2943 void bgp_mplsvpn_init(void)
2945 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2946 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2947 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2949 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2950 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2952 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2953 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2954 #ifdef KEEP_OLD_VPN_COMMANDS
2955 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2956 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2957 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2958 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2959 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2960 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2961 install_element(VIEW_NODE
,
2962 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2963 install_element(VIEW_NODE
,
2964 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2965 #endif /* KEEP_OLD_VPN_COMMANDS */
2968 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2970 struct listnode
*mnode
, *mnnode
;
2974 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
2977 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2978 struct ecommunity
*ec
;
2980 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2983 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
2985 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
2988 if (ecommunity_include(ec
, eckey
))
2995 * The purpose of this function is to process leaks that were deferred
2996 * from earlier per-vrf configuration due to not-yet-existing default
2997 * vrf, in other words, configuration such as:
2999 * router bgp MMM vrf FOO
3000 * address-family ipv4 unicast
3002 * exit-address-family
3007 * This function gets called when the default instance ("router bgp NNN")
3010 void vpn_leak_postchange_all(void)
3012 struct listnode
*next
;
3014 struct bgp
*bgp_default
= bgp_get_default();
3016 assert(bgp_default
);
3018 /* First, do any exporting from VRFs to the single VPN RIB */
3019 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3021 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3024 vpn_leak_postchange(
3025 BGP_VPN_POLICY_DIR_TOVPN
,
3030 vpn_leak_postchange(
3031 BGP_VPN_POLICY_DIR_TOVPN
,
3037 /* Now, do any importing to VRFs from the single VPN RIB */
3038 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
3040 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3043 vpn_leak_postchange(
3044 BGP_VPN_POLICY_DIR_FROMVPN
,
3049 vpn_leak_postchange(
3050 BGP_VPN_POLICY_DIR_FROMVPN
,
3057 /* When a bgp vrf instance is unconfigured, remove its routes
3058 * from the VPN table and this vrf could be importing routes from other
3059 * bgp vrf instnaces, unimport them.
3060 * VRF X and VRF Y are exporting routes to each other.
3061 * When VRF X is deleted, unimport its routes from all target vrfs,
3062 * also VRF Y should unimport its routes from VRF X table.
3063 * This will ensure VPN table is cleaned up appropriately.
3065 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
3068 const char *tmp_name
;
3070 struct listnode
*node
, *next
;
3071 safi_t safi
= SAFI_UNICAST
;
3073 bool is_vrf_leak_bind
;
3076 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
3079 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3080 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3082 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3084 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3085 /* vrf leak is for IPv4 and IPv6 Unicast only */
3086 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3089 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3090 if (from_bgp
== to_bgp
)
3093 /* Unimport and remove source vrf from the
3094 * other vrfs import list.
3096 struct vpn_policy
*to_vpolicy
;
3098 is_vrf_leak_bind
= false;
3099 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3100 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
3102 if (strcmp(vname
, tmp_name
) == 0) {
3103 is_vrf_leak_bind
= true;
3107 /* skip this bgp instance as there is no leak to this
3110 if (!is_vrf_leak_bind
)
3114 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
3115 __func__
, from_bgp
->name_pretty
,
3116 to_bgp
->name_pretty
, afi2str(afi
),
3117 to_vpolicy
->import_vrf
->count
);
3119 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
3121 /* readd vrf name as unimport removes import vrf name
3122 * from the destination vrf's import list where the
3123 * `import vrf` configuration still exist.
3125 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
3126 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
3128 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
3129 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
3131 /* If to_bgp exports its routes to the bgp vrf
3132 * which is being deleted, un-import the
3133 * to_bgp routes from VPN.
3135 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3138 if (strcmp(vname
, tmp_name
) == 0) {
3139 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3149 /* When a router bgp is configured, there could be a bgp vrf
3150 * instance importing routes from this newly configured
3151 * bgp vrf instance. Export routes from configured
3153 * VRF Y has import from bgp vrf x,
3154 * when a bgp vrf x instance is created, export its routes
3155 * to VRF Y instance.
3157 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3160 const char *export_name
;
3162 struct listnode
*node
, *next
;
3163 struct ecommunity
*ecom
;
3164 enum vpn_policy_direction idir
, edir
;
3165 safi_t safi
= SAFI_UNICAST
;
3169 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3170 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3172 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3173 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3175 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3177 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3178 /* vrf leak is for IPv4 and IPv6 Unicast only */
3179 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3182 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3183 if (from_bgp
== to_bgp
)
3186 /* bgp instance has import list, check to see if newly
3187 * configured bgp instance is the list.
3189 struct vpn_policy
*to_vpolicy
;
3191 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3192 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3194 if (strcmp(vname
, export_name
) != 0)
3198 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3200 export_name
, to_bgp
->name_pretty
);
3202 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3203 /* remove import rt, it will be readded
3204 * as part of import from vrf.
3208 to_vpolicy
->rtlist
[idir
],
3209 (struct ecommunity_val
*)
3211 vrf_import_from_vrf(to_bgp
, from_bgp
,