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"
52 #include "bgpd/rfapi/rfapi_backend.h"
56 * Definitions and external declarations.
58 extern struct zclient
*zclient
;
60 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
61 int *index
, afi_t
*afi
)
64 if (argv_find(argv
, argc
, "vpnv4", index
)) {
68 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
76 uint32_t decode_label(mpls_label_t
*label_pnt
)
79 uint8_t *pnt
= (uint8_t *)label_pnt
;
81 l
= ((uint32_t)*pnt
++ << 12);
82 l
|= (uint32_t)*pnt
++ << 4;
83 l
|= (uint32_t)((*pnt
& 0xf0) >> 4);
87 void encode_label(mpls_label_t label
, mpls_label_t
*label_pnt
)
89 uint8_t *pnt
= (uint8_t *)label_pnt
;
92 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
) {
96 *pnt
++ = (label
>> 12) & 0xff;
97 *pnt
++ = (label
>> 4) & 0xff;
98 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
101 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
102 struct bgp_nlri
*packet
)
110 struct prefix_rd prd
= {0};
111 mpls_label_t label
= {0};
119 prd
.family
= AF_UNSPEC
;
122 struct stream
*data
= stream_new(packet
->length
);
123 stream_put(data
, packet
->nlri
, packet
->length
);
129 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
130 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
131 PEER_CAP_ADDPATH_AF_TX_RCV
));
133 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
134 while (STREAM_READABLE(data
) > 0) {
135 /* Clear prefix structure. */
136 memset(&p
, 0, sizeof(struct prefix
));
138 if (addpath_encoded
) {
139 STREAM_GET(&addpath_id
, data
, BGP_ADDPATH_ID_LEN
);
140 addpath_id
= ntohl(addpath_id
);
143 if (STREAM_READABLE(data
) < 1) {
146 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no prefix length)",
147 peer
->host
, packet
->length
);
148 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
152 /* Fetch prefix length. */
153 STREAM_GETC(data
, prefixlen
);
154 p
.family
= afi2family(packet
->afi
);
155 psize
= PSIZE(prefixlen
);
157 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
160 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
161 peer
->host
, prefixlen
);
162 ret
= BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH
;
166 /* sanity check against packet data */
167 if (STREAM_READABLE(data
) < psize
) {
170 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
171 peer
->host
, prefixlen
, packet
->length
);
172 ret
= BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
176 /* sanity check against storage for the IP address portion */
177 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
180 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
182 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
184 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
188 /* Sanity check against max bitlen of the address family */
189 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
192 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
194 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
195 p
.family
, prefix_blen(&p
));
196 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
200 /* Copy label to prefix. */
201 if (STREAM_READABLE(data
) < BGP_LABEL_BYTES
) {
204 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no label)",
205 peer
->host
, packet
->length
);
206 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
210 STREAM_GET(&label
, data
, BGP_LABEL_BYTES
);
211 bgp_set_valid_label(&label
);
213 /* Copy routing distinguisher to rd. */
214 if (STREAM_READABLE(data
) < 8) {
217 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no RD)",
218 peer
->host
, packet
->length
);
219 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
222 STREAM_GET(&prd
.val
, data
, 8);
224 /* Decode RD type. */
225 type
= decode_rd_type(prd
.val
);
229 decode_rd_as(&prd
.val
[2], &rd_as
);
233 decode_rd_as4(&prd
.val
[2], &rd_as
);
237 decode_rd_ip(&prd
.val
[2], &rd_ip
);
240 #ifdef ENABLE_BGP_VNC
241 case RD_TYPE_VNC_ETH
:
246 flog_err(EC_BGP_UPDATE_RCV
, "Unknown RD type %d", type
);
247 break; /* just report */
250 /* exclude label & RD */
251 p
.prefixlen
= prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8;
252 STREAM_GET(p
.u
.val
, data
, psize
- VPN_PREFIXLEN_MIN_BYTES
);
255 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
256 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
257 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
259 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
260 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
261 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
264 /* Packet length consistency check. */
265 if (STREAM_READABLE(data
) != 0) {
268 "%s [Error] Update packet error / VPN (%td data remaining after parsing)",
269 peer
->host
, STREAM_READABLE(data
));
270 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
278 "%s [Error] Update packet error / VPN (NLRI of size %u - length error)",
279 peer
->host
, packet
->length
);
280 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
286 #undef VPN_PREFIXLEN_MIN_BYTES
290 * This function informs zebra of the label this vrf sets on routes
291 * leaked to VPN. Zebra should install this label in the kernel with
292 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
294 * Sending this vrf-label association is qualified by a) whether vrf->vpn
295 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
296 * are set) and b) whether vpn-policy label is set.
298 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
299 * for this vrf, which zebra interprets to mean "delete this vrf-label
302 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
304 mpls_label_t label
= MPLS_LABEL_NONE
;
305 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
307 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
310 "%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
311 __func__
, bgp
->name_pretty
, afi2str(afi
));
316 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
317 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
321 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
322 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
326 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
)
327 label
= MPLS_LABEL_NONE
;
328 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
329 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
333 * If zebra tells us vrf has become unconfigured, tell zebra not to
334 * use this label to forward to the vrf anymore
336 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
338 mpls_label_t label
= MPLS_LABEL_NONE
;
339 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
341 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
344 "%s: vrf_id not set, can't delete zebra vrf label",
351 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
352 bgp
->name_pretty
, bgp
->vrf_id
);
355 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
356 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
359 int vpn_leak_label_callback(
364 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
365 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
368 zlog_debug("%s: label=%u, allocated=%d",
369 __func__
, label
, allocated
);
373 * previously-allocated label is now invalid
375 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
376 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
378 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
379 vp
->afi
, bgp_get_default(), vp
->bgp
);
380 vp
->tovpn_label
= MPLS_LABEL_NONE
;
381 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
382 vp
->afi
, bgp_get_default(), vp
->bgp
);
388 * New label allocation
390 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
393 * not currently configured for auto label, reject allocation
398 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
399 if (label
== vp
->tovpn_label
) {
400 /* already have same label, accept but do nothing */
403 /* Shouldn't happen: different label allocation */
404 flog_err(EC_BGP_LABEL
,
405 "%s: %s had label %u but got new assignment %u",
406 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
411 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
412 vp
->afi
, bgp_get_default(), vp
->bgp
);
413 vp
->tovpn_label
= label
;
414 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
415 vp
->afi
, bgp_get_default(), vp
->bgp
);
420 static bool ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
427 for (i
= 0; i
< e1
->size
; ++i
) {
428 for (j
= 0; j
< e2
->size
; ++j
) {
429 if (!memcmp(e1
->val
+ (i
* e1
->unit_size
),
430 e2
->val
+ (j
* e2
->unit_size
),
440 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
452 if (n
!= bpi
->extra
->num_labels
)
455 for (i
= 0; i
< n
; ++i
) {
456 if (label
[i
] != bpi
->extra
->label
[i
])
463 * make encoded route labels match specified encoded label set
465 static void setlabels(struct bgp_path_info
*bpi
,
466 mpls_label_t
*label
, /* array of labels */
471 assert(num_labels
<= BGP_MAX_LABELS
);
475 bpi
->extra
->num_labels
= 0;
479 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
482 for (i
= 0; i
< num_labels
; ++i
) {
483 extra
->label
[i
] = label
[i
];
484 if (!bgp_is_valid_label(&label
[i
])) {
485 bgp_set_valid_label(&extra
->label
[i
]);
488 extra
->num_labels
= num_labels
;
492 * returns pointer to new bgp_path_info upon success
494 static struct bgp_path_info
*
495 leak_update(struct bgp
*bgp
, /* destination bgp instance */
496 struct bgp_dest
*bn
, struct attr
*new_attr
, /* already interned */
497 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
498 mpls_label_t
*label
, uint32_t num_labels
, void *parent
,
499 struct bgp
*bgp_orig
, struct prefix
*nexthop_orig
,
500 int nexthop_self_flag
, int debug
)
502 const struct prefix
*p
= bgp_dest_get_prefix(bn
);
503 struct bgp_path_info
*bpi
;
504 struct bgp_path_info
*bpi_ultimate
;
505 struct bgp_path_info
*new;
509 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
510 __func__
, bgp
->name_pretty
, bn
, source_bpi
->type
,
511 source_bpi
->sub_type
);
514 * Routes that are redistributed into BGP from zebra do not get
515 * nexthop tracking. However, if those routes are subsequently
516 * imported to other RIBs within BGP, the leaked routes do not
517 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
518 * in order to determine if the route we are currently leaking
519 * should have nexthop tracking, we must find the ultimate
520 * parent so we can check its sub_type.
522 * As of now, source_bpi may at most be a second-generation route
523 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
524 * Using a loop here supports more complex intra-bgp import-export
525 * schemes that could be implemented in the future.
528 for (bpi_ultimate
= source_bpi
;
529 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
530 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
536 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
537 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
542 bool labelssame
= labels_same(bpi
, label
, num_labels
);
544 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
545 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
547 bgp_attr_unintern(&new_attr
);
550 "%s: ->%s: %pBD: Found route, no change",
551 __func__
, bgp
->name_pretty
, bn
);
555 /* attr is changed */
556 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
558 /* Rewrite BGP route information. */
559 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
560 bgp_path_info_restore(bn
, bpi
);
562 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
563 bgp_attr_unintern(&bpi
->attr
);
564 bpi
->attr
= new_attr
;
565 bpi
->uptime
= bgp_clock();
571 setlabels(bpi
, label
, num_labels
);
573 if (nexthop_self_flag
)
574 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
576 struct bgp
*bgp_nexthop
= bgp
;
579 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
580 bgp_nexthop
= bpi
->extra
->bgp_orig
;
583 * No nexthop tracking for redistributed routes or for
584 * EVPN-imported routes that get leaked.
586 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
587 is_pi_family_evpn(bpi_ultimate
))
591 * TBD do we need to do anything about the
592 * 'connected' parameter?
594 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
598 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
599 __func__
, (nh_valid
? "" : "not "),
600 bgp_nexthop
->name_pretty
);
603 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
605 /* Process change. */
606 bgp_aggregate_increment(bgp
, p
, bpi
, afi
, safi
);
607 bgp_process(bgp
, bn
, afi
, safi
);
608 bgp_dest_unlock_node(bn
);
611 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
612 __func__
, bgp
->name_pretty
, bn
);
617 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
618 bgp
->peer_self
, new_attr
, bn
);
620 if (nexthop_self_flag
)
621 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
623 bgp_path_info_extra_get(new);
626 setlabels(new, label
, num_labels
);
628 new->extra
->parent
= bgp_path_info_lock(parent
);
630 (struct bgp_dest
*)((struct bgp_path_info
*)parent
)->net
);
632 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
634 new->extra
->nexthop_orig
= *nexthop_orig
;
637 * nexthop tracking for unicast routes
639 struct bgp
*bgp_nexthop
= bgp
;
642 if (new->extra
->bgp_orig
)
643 bgp_nexthop
= new->extra
->bgp_orig
;
646 * No nexthop tracking for redistributed routes because
647 * their originating protocols will do the tracking and
648 * withdraw those routes if the nexthops become unreachable
649 * This also holds good for EVPN-imported routes that get
652 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
653 is_pi_family_evpn(bpi_ultimate
))
657 * TBD do we need to do anything about the
658 * 'connected' parameter?
660 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
664 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
665 __func__
, (nh_valid
? "" : "not "),
666 bgp_nexthop
->name_pretty
);
668 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
670 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
671 bgp_path_info_add(bn
, new);
673 bgp_dest_unlock_node(bn
);
674 bgp_process(bgp
, bn
, afi
, safi
);
677 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
678 bgp
->name_pretty
, bn
);
683 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
684 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
685 struct bgp
*bgp_vrf
, /* from */
686 struct bgp_path_info
*path_vrf
) /* route */
688 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
689 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
690 afi_t afi
= family2afi(p
->family
);
691 struct attr static_attr
= {0};
692 struct attr
*new_attr
= NULL
;
693 safi_t safi
= SAFI_MPLS_VPN
;
694 mpls_label_t label_val
;
697 const char *debugmsg
;
698 int nexthop_self_flag
= 0;
701 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
703 if (debug
&& path_vrf
->attr
->ecommunity
) {
704 char *s
= ecommunity_ecom2str(path_vrf
->attr
->ecommunity
,
705 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
707 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
708 bgp_vrf
->name
, path_vrf
->type
, s
);
709 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
717 zlog_debug("%s: can't get afi of prefix", __func__
);
721 /* Is this route exportable into the VPN table? */
722 if (!is_route_injectable_into_vpn(path_vrf
))
725 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
727 zlog_debug("%s: %s skipping: %s", __func__
,
728 bgp_vrf
->name
, debugmsg
);
733 static_attr
= *path_vrf
->attr
;
738 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
739 struct bgp_path_info info
;
740 route_map_result_t ret
;
742 memset(&info
, 0, sizeof(info
));
743 info
.peer
= bgp_vpn
->peer_self
;
744 info
.attr
= &static_attr
;
745 ret
= route_map_apply(
746 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
748 if (RMAP_DENYMATCH
== ret
) {
749 bgp_attr_flush(&static_attr
); /* free any added parts */
752 "%s: vrf %s route map \"%s\" says DENY, returning",
753 __func__
, bgp_vrf
->name_pretty
,
754 bgp_vrf
->vpn_policy
[afi
]
755 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
761 if (debug
&& static_attr
.ecommunity
) {
762 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
763 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
765 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
767 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
771 * Add the vpn-policy rt-list
773 struct ecommunity
*old_ecom
;
774 struct ecommunity
*new_ecom
;
776 /* Export with the 'from' instance's export RTs. */
777 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
778 old_ecom
= static_attr
.ecommunity
;
780 new_ecom
= ecommunity_dup(old_ecom
);
781 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
782 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
783 ecommunity_strip_rts(new_ecom
);
784 new_ecom
= ecommunity_merge(new_ecom
,
785 bgp_vrf
->vpn_policy
[afi
]
786 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
787 if (!old_ecom
->refcnt
)
788 ecommunity_free(&old_ecom
);
790 new_ecom
= ecommunity_dup(
791 bgp_vrf
->vpn_policy
[afi
]
792 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
794 static_attr
.ecommunity
= new_ecom
;
795 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
797 if (debug
&& static_attr
.ecommunity
) {
798 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
799 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
801 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
803 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
807 /* if policy nexthop not set, use 0 */
808 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
809 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
810 struct prefix
*nexthop
=
811 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
813 switch (nexthop
->family
) {
815 /* prevent mp_nexthop_global_in <- self in bgp_route.c
817 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
819 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
820 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
824 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
825 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
832 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
833 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
836 * For ipv4, copy to multiprotocol
839 static_attr
.mp_nexthop_global_in
=
841 static_attr
.mp_nexthop_len
=
844 * XXX Leave static_attr.nexthop
848 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
851 /* Update based on next-hop family to account for
852 * RFC 5549 (BGP unnumbered) scenario. Note that
853 * specific action is only needed for the case of
854 * IPv4 nexthops as the attr has been copied
858 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
859 static_attr
.mp_nexthop_global_in
.s_addr
=
860 static_attr
.nexthop
.s_addr
;
861 static_attr
.mp_nexthop_len
=
864 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
867 nexthop_self_flag
= 1;
870 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
871 if (label_val
== MPLS_LABEL_NONE
) {
872 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
874 encode_label(label_val
, &label
);
877 /* Set originator ID to "me" */
878 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
879 static_attr
.originator_id
= bgp_vpn
->router_id
;
882 new_attr
= bgp_attr_intern(
883 &static_attr
); /* hashed refcounted everything */
884 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
886 if (debug
&& new_attr
->ecommunity
) {
887 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
888 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
890 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
891 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
894 /* Now new_attr is an allocated interned attr */
896 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
897 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
899 struct bgp_path_info
*new_info
;
901 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, path_vrf
,
902 &label
, 1, path_vrf
, bgp_vrf
, NULL
,
903 nexthop_self_flag
, debug
);
906 * Routes actually installed in the vpn RIB must also be
907 * offered to all vrfs (because now they originate from
910 * Acceptance into other vrfs depends on rt-lists.
911 * Originating vrf will not accept the looped back route
912 * because of loop checking.
915 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
918 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
919 struct bgp
*bgp_vrf
, /* from */
920 struct bgp_path_info
*path_vrf
) /* route */
922 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
923 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
924 afi_t afi
= family2afi(p
->family
);
925 safi_t safi
= SAFI_MPLS_VPN
;
926 struct bgp_path_info
*bpi
;
928 const char *debugmsg
;
932 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
933 __func__
, bgp_vrf
->name_pretty
, path_vrf
->net
,
934 path_vrf
->type
, path_vrf
->sub_type
);
942 zlog_debug("%s: can't get afi of prefix", __func__
);
946 /* Is this route exportable into the VPN table? */
947 if (!is_route_injectable_into_vpn(path_vrf
))
950 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
952 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
957 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
959 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
960 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
966 * match original bpi imported from
968 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
969 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
975 /* withdraw from looped vrfs as well */
976 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
978 bgp_aggregate_decrement(bgp_vpn
, p
, bpi
, afi
, safi
);
979 bgp_path_info_delete(bn
, bpi
);
980 bgp_process(bgp_vpn
, bn
, afi
, safi
);
982 bgp_dest_unlock_node(bn
);
985 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
986 struct bgp
*bgp_vrf
, /* from */
989 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
990 struct bgp_dest
*pdest
;
991 safi_t safi
= SAFI_MPLS_VPN
;
994 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
996 for (pdest
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); pdest
;
997 pdest
= bgp_route_next(pdest
)) {
999 struct bgp_table
*table
;
1000 struct bgp_dest
*bn
;
1001 struct bgp_path_info
*bpi
;
1003 /* This is the per-RD table of prefixes */
1004 table
= bgp_dest_get_bgp_table_info(pdest
);
1009 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1010 bpi
= bgp_dest_get_bgp_path_info(bn
);
1012 zlog_debug("%s: looking at prefix %pBD",
1016 for (; bpi
; bpi
= bpi
->next
) {
1018 zlog_debug("%s: type %d, sub_type %d",
1019 __func__
, bpi
->type
,
1021 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1025 if ((struct bgp
*)bpi
->extra
->bgp_orig
1029 zlog_debug("%s: deleting it",
1031 bgp_aggregate_decrement(
1033 bgp_dest_get_prefix(bn
), bpi
,
1035 bgp_path_info_delete(bn
, bpi
);
1036 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1043 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
1044 struct bgp
*bgp_vrf
, /* from */
1047 struct bgp_dest
*bn
;
1048 struct bgp_path_info
*bpi
;
1049 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1052 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1053 bgp_vrf
->name_pretty
);
1055 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
1056 bn
= bgp_route_next(bn
)) {
1059 zlog_debug("%s: node=%p", __func__
, bn
);
1061 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1065 "%s: calling vpn_leak_from_vrf_update",
1067 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bpi
);
1073 vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1074 struct bgp
*bgp_vpn
, /* from */
1075 struct bgp_path_info
*path_vpn
) /* route */
1077 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1078 afi_t afi
= family2afi(p
->family
);
1080 struct attr static_attr
= {0};
1081 struct attr
*new_attr
= NULL
;
1082 struct bgp_dest
*bn
;
1083 safi_t safi
= SAFI_UNICAST
;
1084 const char *debugmsg
;
1085 struct prefix nexthop_orig
;
1086 mpls_label_t
*pLabels
= NULL
;
1087 uint32_t num_labels
= 0;
1088 int nexthop_self_flag
= 1;
1089 struct bgp_path_info
*bpi_ultimate
= NULL
;
1090 int origin_local
= 0;
1091 struct bgp
*src_vrf
;
1093 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1095 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1097 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1101 /* Check for intersection of route targets */
1102 if (!ecom_intersect(
1103 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1104 path_vpn
->attr
->ecommunity
)) {
1110 zlog_debug("%s: updating %pFX to vrf %s", __func__
, p
,
1111 bgp_vrf
->name_pretty
);
1114 static_attr
= *path_vpn
->attr
;
1116 struct ecommunity
*old_ecom
;
1117 struct ecommunity
*new_ecom
;
1119 /* If doing VRF-to-VRF leaking, strip RTs. */
1120 old_ecom
= static_attr
.ecommunity
;
1121 if (old_ecom
&& CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1122 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1123 new_ecom
= ecommunity_dup(old_ecom
);
1124 ecommunity_strip_rts(new_ecom
);
1125 static_attr
.ecommunity
= new_ecom
;
1127 if (new_ecom
->size
== 0) {
1128 UNSET_FLAG(static_attr
.flag
,
1129 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
1130 ecommunity_free(&new_ecom
);
1131 static_attr
.ecommunity
= NULL
;
1134 if (!old_ecom
->refcnt
)
1135 ecommunity_free(&old_ecom
);
1139 * Nexthop: stash and clear
1141 * Nexthop is valid in context of VPN core, but not in destination vrf.
1142 * Stash it for later label resolution by vrf ingress path and then
1143 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1145 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1147 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1148 nexthop_orig
.family
= nhfamily
;
1153 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1154 nexthop_orig
.prefixlen
= 32;
1156 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1157 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1158 static_attr
.nexthop
.s_addr
=
1159 nexthop_orig
.u
.prefix4
.s_addr
;
1161 static_attr
.mp_nexthop_global_in
=
1162 path_vpn
->attr
->mp_nexthop_global_in
;
1163 static_attr
.mp_nexthop_len
=
1164 path_vpn
->attr
->mp_nexthop_len
;
1166 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1170 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1171 nexthop_orig
.prefixlen
= 128;
1173 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1174 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1175 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1181 * route map handling
1183 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1184 struct bgp_path_info info
;
1185 route_map_result_t ret
;
1187 memset(&info
, 0, sizeof(info
));
1188 info
.peer
= bgp_vrf
->peer_self
;
1189 info
.attr
= &static_attr
;
1190 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1191 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1192 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1193 p
, RMAP_BGP
, &info
);
1194 if (RMAP_DENYMATCH
== ret
) {
1195 bgp_attr_flush(&static_attr
); /* free any added parts */
1198 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1199 __func__
, bgp_vrf
->name_pretty
,
1200 bgp_vrf
->vpn_policy
[afi
]
1201 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1206 * if route-map changed nexthop, don't nexthop-self on output
1208 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1209 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1210 nexthop_self_flag
= 0;
1213 new_attr
= bgp_attr_intern(&static_attr
);
1214 bgp_attr_flush(&static_attr
);
1216 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1219 * ensure labels are copied
1221 * However, there is a special case: if the route originated in
1222 * another local VRF (as opposed to arriving via VPN), then the
1223 * nexthop is reached by hairpinning through this router (me)
1224 * using IP forwarding only (no LSP). Therefore, the route
1225 * imported to the VRF should not have labels attached. Note
1226 * that nexthop tracking is also involved: eliminating the
1227 * labels for these routes enables the non-labeled nexthops
1228 * from the originating VRF to be considered valid for this route.
1230 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1231 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1232 /* work back to original route */
1233 for (bpi_ultimate
= path_vpn
;
1234 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
1235 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
1239 * if original route was unicast,
1240 * then it did not arrive over vpn
1242 if (bpi_ultimate
->net
) {
1243 struct bgp_table
*table
;
1245 table
= bgp_dest_table(bpi_ultimate
->net
);
1246 if (table
&& (table
->safi
== SAFI_UNICAST
))
1251 if (!origin_local
&& path_vpn
->extra
1252 && path_vpn
->extra
->num_labels
) {
1253 num_labels
= path_vpn
->extra
->num_labels
;
1254 if (num_labels
> BGP_MAX_LABELS
)
1255 num_labels
= BGP_MAX_LABELS
;
1256 pLabels
= path_vpn
->extra
->label
;
1261 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
1262 path_vpn
->net
, num_labels
);
1265 * For VRF-2-VRF route-leaking,
1266 * the source will be the originating VRF.
1268 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1269 src_vrf
= path_vpn
->extra
->bgp_orig
;
1273 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
1274 num_labels
, path_vpn
, /* parent */
1275 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1278 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1279 struct bgp_path_info
*path_vpn
) /* route */
1281 struct listnode
*mnode
, *mnnode
;
1284 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1287 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1289 /* Loop over VRFs */
1290 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1292 if (!path_vpn
->extra
1293 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1294 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, path_vpn
);
1299 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1300 struct bgp_path_info
*path_vpn
) /* route */
1302 const struct prefix
*p
;
1304 safi_t safi
= SAFI_UNICAST
;
1306 struct listnode
*mnode
, *mnnode
;
1307 struct bgp_dest
*bn
;
1308 struct bgp_path_info
*bpi
;
1309 const char *debugmsg
;
1311 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1314 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
1315 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
1318 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1320 if (!path_vpn
->net
) {
1321 #ifdef ENABLE_BGP_VNC
1322 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1323 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
1324 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1331 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1336 p
= bgp_dest_get_prefix(path_vpn
->net
);
1337 afi
= family2afi(p
->family
);
1339 /* Loop over VRFs */
1340 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1341 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1343 zlog_debug("%s: skipping: %s", __func__
,
1348 /* Check for intersection of route targets */
1349 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1350 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1351 path_vpn
->attr
->ecommunity
)) {
1357 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1360 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1362 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1365 && (struct bgp_path_info
*)bpi
->extra
->parent
1373 zlog_debug("%s: deleting bpi %p", __func__
,
1375 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
1376 bgp_path_info_delete(bn
, bpi
);
1377 bgp_process(bgp
, bn
, afi
, safi
);
1379 bgp_dest_unlock_node(bn
);
1383 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1386 struct bgp_dest
*bn
;
1387 struct bgp_path_info
*bpi
;
1388 safi_t safi
= SAFI_UNICAST
;
1389 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1392 zlog_debug("%s: entry", __func__
);
1394 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1396 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1397 bn
= bgp_route_next(bn
)) {
1399 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1402 && bpi
->extra
->bgp_orig
!= bgp_vrf
1403 && bpi
->extra
->parent
1404 && is_pi_family_vpn(bpi
->extra
->parent
)) {
1407 bgp_aggregate_decrement(bgp_vrf
,
1408 bgp_dest_get_prefix(bn
),
1410 bgp_path_info_delete(bn
, bpi
);
1411 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1417 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1418 struct bgp
*bgp_vpn
, /* from */
1421 struct prefix_rd prd
;
1422 struct bgp_dest
*pdest
;
1423 safi_t safi
= SAFI_MPLS_VPN
;
1430 for (pdest
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); pdest
;
1431 pdest
= bgp_route_next(pdest
)) {
1432 const struct prefix
*p
= bgp_dest_get_prefix(pdest
);
1433 struct bgp_table
*table
;
1434 struct bgp_dest
*bn
;
1435 struct bgp_path_info
*bpi
;
1437 memset(&prd
, 0, sizeof(prd
));
1438 prd
.family
= AF_UNSPEC
;
1440 memcpy(prd
.val
, &p
->u
.val
, 8);
1442 /* This is the per-RD table of prefixes */
1443 table
= bgp_dest_get_bgp_table_info(pdest
);
1448 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1450 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1454 && bpi
->extra
->bgp_orig
== bgp_vrf
)
1457 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1465 * This function is called for definition/deletion/change to a route-map
1467 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1469 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1471 struct route_map
*rmap
;
1473 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1474 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1479 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1481 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1483 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1484 && !strcmp(rmap_name
,
1485 bgp
->vpn_policy
[afi
]
1486 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1490 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1491 __func__
, rmap_name
, bgp
->as
,
1494 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1495 bgp_get_default(), bgp
);
1497 zlog_debug("%s: after vpn_leak_prechange",
1500 /* in case of definition/deletion */
1501 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1504 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1505 bgp_get_default(), bgp
);
1508 zlog_debug("%s: after vpn_leak_postchange",
1512 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1513 && !strcmp(rmap_name
,
1514 bgp
->vpn_policy
[afi
]
1515 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1518 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1519 __func__
, rmap_name
, bgp
->as
,
1523 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1524 bgp_get_default(), bgp
);
1526 /* in case of definition/deletion */
1527 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1530 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1531 bgp_get_default(), bgp
);
1536 /* This API is used during router-id change, reflect VPNs
1537 * auto RD and RT values and readvertise routes to VPN table.
1539 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
1545 const char *export_name
;
1546 char buf
[RD_ADDRSTRLEN
];
1547 struct bgp
*bgp_import
;
1548 struct listnode
*node
;
1549 struct ecommunity
*ecom
;
1550 vpn_policy_direction_t idir
, edir
;
1552 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1553 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1556 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1557 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1558 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1560 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1561 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1563 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1564 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
1568 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
1569 afi
, bgp_get_default(), bgp
);
1571 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1572 __func__
, export_name
);
1574 /* Remove import RT from VRFs */
1575 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1576 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1577 export_vrf
, node
, vname
)) {
1578 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1579 bgp_import
= bgp_get_default();
1581 bgp_import
= bgp_lookup_by_name(vname
);
1585 ecommunity_del_val(bgp_import
->vpn_policy
[afi
].
1587 (struct ecommunity_val
*)ecom
->val
);
1592 * Router-id changes that are not explicit config
1593 * changes should not replace configured RD/RT.
1596 if (CHECK_FLAG(bgp
->vpn_policy
[afi
].flags
,
1597 BGP_VPN_POLICY_TOVPN_RD_SET
)) {
1599 zlog_debug("%s: auto router-id change skipped",
1605 /* New router-id derive auto RD and RT and export
1608 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
1609 &bgp
->vrf_prd_auto
);
1610 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
1611 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
1613 bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1614 ecommunity_str2com(buf
,
1615 ECOMMUNITY_ROUTE_TARGET
, 0);
1617 /* Update import_vrf rt_list */
1618 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1619 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1620 export_vrf
, node
, vname
)) {
1621 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1622 bgp_import
= bgp_get_default();
1624 bgp_import
= bgp_lookup_by_name(vname
);
1627 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
1628 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1630 bgp_import
->vpn_policy
[afi
]
1631 .rtlist
[idir
], ecom
);
1633 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1634 = ecommunity_dup(ecom
);
1639 /* Update routes to VPN */
1640 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
1641 afi
, bgp_get_default(),
1644 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
1645 __func__
, export_name
);
1650 void vpn_policy_routemap_event(const char *rmap_name
)
1652 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1653 struct listnode
*mnode
, *mnnode
;
1657 zlog_debug("%s: entry", __func__
);
1659 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1662 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1663 vpn_policy_routemap_update(bgp
, rmap_name
);
1666 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1667 afi_t afi
, safi_t safi
)
1669 const char *export_name
;
1670 vpn_policy_direction_t idir
, edir
;
1671 char *vname
, *tmp_name
;
1672 char buf
[RD_ADDRSTRLEN
];
1673 struct ecommunity
*ecom
;
1674 bool first_export
= false;
1676 struct listnode
*node
;
1677 bool is_inst_match
= false;
1679 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
1680 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1681 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1683 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1684 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1687 * Cross-ref both VRFs. Also, note if this is the first time
1688 * any VRF is importing from "import_vrf".
1690 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
1691 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
1693 /* Check the import_vrf list of destination vrf for the source vrf name,
1696 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
1698 if (strcmp(vname
, tmp_name
) == 0) {
1699 is_inst_match
= true;
1704 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
1707 /* Check if the source vrf already exports to any vrf,
1708 * first time export requires to setup auto derived RD/RT values.
1709 * Add the destination vrf name to export vrf list if it is
1712 is_inst_match
= false;
1713 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
1714 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1715 first_export
= true;
1717 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1719 if (strcmp(vname
, tmp_name
) == 0) {
1720 is_inst_match
= true;
1726 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
1728 /* Update import RT for current VRF using export RT of the VRF we're
1729 * importing from. First though, make sure "import_vrf" has that
1733 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
1734 &from_bgp
->vrf_prd_auto
);
1735 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
1736 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1737 BGP_VPN_POLICY_TOVPN_RD_SET
);
1738 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
1740 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1741 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
1742 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1743 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1744 from_bgp
->vpn_policy
[afi
].tovpn_label
=
1745 BGP_PREVENT_VRF_2_VRF_LEAK
;
1747 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1748 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
1749 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
1750 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
1751 .rtlist
[idir
], ecom
);
1753 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
1754 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1757 const char *from_name
;
1759 from_name
= from_bgp
->name
? from_bgp
->name
:
1761 zlog_debug("%s from %s to %s first_export %u import-rt %s export-rt %s",
1762 __func__
, from_name
, export_name
, first_export
,
1763 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] ?
1764 (ecommunity_ecom2str(to_bgp
->vpn_policy
[afi
].
1766 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0)) : " ",
1767 to_bgp
->vpn_policy
[afi
].rtlist
[edir
] ?
1768 (ecommunity_ecom2str(to_bgp
->vpn_policy
[afi
].
1770 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0)) : " ");
1773 /* Does "import_vrf" first need to export its routes or that
1774 * is already done and we just need to import those routes
1775 * from the global table?
1778 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
1780 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1783 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1784 afi_t afi
, safi_t safi
)
1786 const char *export_name
, *tmp_name
;
1787 vpn_policy_direction_t idir
, edir
;
1789 struct ecommunity
*ecom
= NULL
;
1790 struct listnode
*node
;
1793 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
1794 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
1795 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1796 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1798 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1799 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1801 /* Were we importing from "import_vrf"? */
1802 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
1804 if (strcmp(vname
, tmp_name
) == 0)
1809 * We do not check in the cli if the passed in bgp
1810 * instance is actually imported into us before
1811 * we call this function. As such if we do not
1812 * find this in the import_vrf list than
1813 * we just need to return safely.
1819 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
1821 /* Remove "import_vrf" from our import list. */
1822 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1823 XFREE(MTYPE_TMP
, vname
);
1825 /* Remove routes imported from "import_vrf". */
1826 /* TODO: In the current logic, we have to first remove all
1827 * imported routes and then (if needed) import back routes
1829 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
1831 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
1832 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
1833 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
1834 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1835 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
1836 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
1838 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1840 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
1841 (struct ecommunity_val
*)ecom
->val
);
1842 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1847 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1848 * below is checking for NULL that export_vrf can be
1849 * NULL, consequently it is complaining( like a cabbage )
1850 * that we could dereference and crash in the listcount(..)
1852 * So make it happy, under protest, with liberty and justice
1855 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
1857 /* Remove us from "import_vrf's" export list. If no other VRF
1858 * is importing from "import_vrf", cleanup appropriately.
1860 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1862 if (strcmp(vname
, export_name
) == 0)
1867 * If we have gotten to this point then the vname must
1868 * exist. If not, we are in a world of trouble and
1869 * have slag sitting around.
1871 * import_vrf and export_vrf must match in having
1872 * the in/out names as appropriate.
1873 * export_vrf list could have been cleaned up
1874 * as part of no router bgp source instnace.
1879 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1880 XFREE(MTYPE_TMP
, vname
);
1882 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1883 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
1884 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
1885 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1886 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1887 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
1888 sizeof(struct prefix_rd
));
1889 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1890 BGP_VPN_POLICY_TOVPN_RD_SET
);
1891 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
1896 /* For testing purpose, static route of MPLS-VPN. */
1897 DEFUN (vpnv4_network
,
1899 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1900 "Specify a network to announce via BGP\n"
1902 "Specify Route Distinguisher\n"
1903 "VPN Route Distinguisher\n"
1904 "VPN NLRI label (tag)\n"
1905 "VPN NLRI label (tag)\n"
1908 int idx_ipv4_prefixlen
= 1;
1909 int idx_ext_community
= 3;
1911 return bgp_static_set_safi(
1912 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1913 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1914 NULL
, NULL
, NULL
, NULL
);
1917 DEFUN (vpnv4_network_route_map
,
1918 vpnv4_network_route_map_cmd
,
1919 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1920 "Specify a network to announce via BGP\n"
1922 "Specify Route Distinguisher\n"
1923 "VPN Route Distinguisher\n"
1924 "VPN NLRI label (tag)\n"
1925 "VPN NLRI label (tag)\n"
1930 int idx_ipv4_prefixlen
= 1;
1931 int idx_ext_community
= 3;
1934 return bgp_static_set_safi(
1935 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1936 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1937 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1940 /* For testing purpose, static route of MPLS-VPN. */
1941 DEFUN (no_vpnv4_network
,
1942 no_vpnv4_network_cmd
,
1943 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1945 "Specify a network to announce via BGP\n"
1947 "Specify Route Distinguisher\n"
1948 "VPN Route Distinguisher\n"
1949 "VPN NLRI label (tag)\n"
1950 "VPN NLRI label (tag)\n"
1953 int idx_ipv4_prefixlen
= 2;
1954 int idx_ext_community
= 4;
1956 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1957 argv
[idx_ipv4_prefixlen
]->arg
,
1958 argv
[idx_ext_community
]->arg
,
1959 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1962 DEFUN (vpnv6_network
,
1964 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1965 "Specify a network to announce via BGP\n"
1966 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1967 "Specify Route Distinguisher\n"
1968 "VPN Route Distinguisher\n"
1969 "VPN NLRI label (tag)\n"
1970 "VPN NLRI label (tag)\n"
1975 int idx_ipv6_prefix
= 1;
1976 int idx_ext_community
= 3;
1980 return bgp_static_set_safi(
1981 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1982 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1983 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1985 return bgp_static_set_safi(
1986 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1987 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1988 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1991 /* For testing purpose, static route of MPLS-VPN. */
1992 DEFUN (no_vpnv6_network
,
1993 no_vpnv6_network_cmd
,
1994 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1996 "Specify a network to announce via BGP\n"
1997 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1998 "Specify Route Distinguisher\n"
1999 "VPN Route Distinguisher\n"
2000 "VPN NLRI label (tag)\n"
2001 "VPN NLRI label (tag)\n"
2004 int idx_ipv6_prefix
= 2;
2005 int idx_ext_community
= 4;
2007 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2008 argv
[idx_ipv6_prefix
]->arg
,
2009 argv
[idx_ext_community
]->arg
,
2010 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2013 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2014 enum bgp_show_type type
, void *output_arg
, int tags
,
2018 struct bgp_table
*table
;
2020 bgp
= bgp_get_default();
2023 vty_out(vty
, "No BGP process is configured\n");
2025 vty_out(vty
, "{}\n");
2028 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2029 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2030 output_arg
, use_json
);
2033 DEFUN (show_bgp_ip_vpn_all_rd
,
2034 show_bgp_ip_vpn_all_rd_cmd
,
2035 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
2039 "Display VPN NLRI specific information\n"
2040 "Display VPN NLRI specific information\n"
2041 "Display information for a route distinguisher\n"
2042 "VPN Route Distinguisher\n"
2046 struct prefix_rd prd
;
2050 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2051 if (argv_find(argv
, argc
, "rd", &idx
)) {
2052 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2055 "%% Malformed Route Distinguisher\n");
2058 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2059 bgp_show_type_normal
, NULL
, 0,
2060 use_json(argc
, argv
));
2062 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2063 bgp_show_type_normal
, NULL
, 0,
2064 use_json(argc
, argv
));
2070 ALIAS(show_bgp_ip_vpn_all_rd
,
2071 show_bgp_ip_vpn_rd_cmd
,
2072 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
2076 "Display VPN NLRI specific information\n"
2077 "Display information for a route distinguisher\n"
2078 "VPN Route Distinguisher\n"
2081 #ifdef KEEP_OLD_VPN_COMMANDS
2082 DEFUN (show_ip_bgp_vpn_rd
,
2083 show_ip_bgp_vpn_rd_cmd
,
2084 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
2089 "Address Family modifier\n"
2090 "Display information for a route distinguisher\n"
2091 "VPN Route Distinguisher\n")
2093 int idx_ext_community
= argc
- 1;
2095 struct prefix_rd prd
;
2099 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2100 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2102 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2105 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2111 DEFUN (show_ip_bgp_vpn_all
,
2112 show_ip_bgp_vpn_all_cmd
,
2113 "show [ip] bgp <vpnv4|vpnv6>",
2122 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2123 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2128 DEFUN (show_ip_bgp_vpn_all_tags
,
2129 show_ip_bgp_vpn_all_tags_cmd
,
2130 "show [ip] bgp <vpnv4|vpnv6> all tags",
2135 "Display information about all VPNv4/VPNV6 NLRIs\n"
2136 "Display BGP tags for prefixes\n")
2141 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2142 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2147 DEFUN (show_ip_bgp_vpn_rd_tags
,
2148 show_ip_bgp_vpn_rd_tags_cmd
,
2149 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
2154 "Display information for a route distinguisher\n"
2155 "VPN Route Distinguisher\n"
2156 "Display BGP tags for prefixes\n")
2158 int idx_ext_community
= 5;
2160 struct prefix_rd prd
;
2164 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2165 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2167 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2170 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2176 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2177 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2178 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2183 "Display information about all VPNv4/VPNv6 NLRIs\n"
2184 "Detailed information on TCP and BGP neighbor connections\n"
2185 "Neighbor to display information about\n"
2186 "Display routes learned from neighbor\n"
2193 bool uj
= use_json(argc
, argv
);
2197 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2198 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2201 json_object
*json_no
= NULL
;
2202 json_no
= json_object_new_object();
2203 json_object_string_add(json_no
, "warning",
2204 "Malformed address");
2205 vty_out(vty
, "%s\n",
2206 json_object_to_json_string(json_no
));
2207 json_object_free(json_no
);
2209 vty_out(vty
, "Malformed address: %s\n",
2210 argv
[idx_ipv4
]->arg
);
2214 peer
= peer_lookup(NULL
, &su
);
2215 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2217 json_object
*json_no
= NULL
;
2218 json_no
= json_object_new_object();
2219 json_object_string_add(
2221 "No such neighbor or address family");
2222 vty_out(vty
, "%s\n",
2223 json_object_to_json_string(json_no
));
2224 json_object_free(json_no
);
2227 "%% No such neighbor or address family\n");
2231 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2237 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2238 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2239 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
2244 "Display information for a route distinguisher\n"
2245 "VPN Route Distinguisher\n"
2246 "Detailed information on TCP and BGP neighbor connections\n"
2247 "Neighbor to display information about\n"
2248 "Display routes learned from neighbor\n"
2251 int idx_ext_community
= 5;
2256 struct prefix_rd prd
;
2257 bool uj
= use_json(argc
, argv
);
2261 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2262 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2265 json_object
*json_no
= NULL
;
2266 json_no
= json_object_new_object();
2267 json_object_string_add(
2269 "Malformed Route Distinguisher");
2270 vty_out(vty
, "%s\n",
2271 json_object_to_json_string(json_no
));
2272 json_object_free(json_no
);
2275 "%% Malformed Route Distinguisher\n");
2279 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2282 json_object
*json_no
= NULL
;
2283 json_no
= json_object_new_object();
2284 json_object_string_add(json_no
, "warning",
2285 "Malformed address");
2286 vty_out(vty
, "%s\n",
2287 json_object_to_json_string(json_no
));
2288 json_object_free(json_no
);
2290 vty_out(vty
, "Malformed address: %s\n",
2291 argv
[idx_ext_community
]->arg
);
2295 peer
= peer_lookup(NULL
, &su
);
2296 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2298 json_object
*json_no
= NULL
;
2299 json_no
= json_object_new_object();
2300 json_object_string_add(
2302 "No such neighbor or address family");
2303 vty_out(vty
, "%s\n",
2304 json_object_to_json_string(json_no
));
2305 json_object_free(json_no
);
2308 "%% No such neighbor or address family\n");
2312 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
2318 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2319 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2320 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2325 "Display information about all VPNv4/VPNv6 NLRIs\n"
2326 "Detailed information on TCP and BGP neighbor connections\n"
2327 "Neighbor to display information about\n"
2328 "Display the routes advertised to a BGP neighbor\n"
2335 bool uj
= use_json(argc
, argv
);
2339 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2340 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2343 json_object
*json_no
= NULL
;
2344 json_no
= json_object_new_object();
2345 json_object_string_add(json_no
, "warning",
2346 "Malformed address");
2347 vty_out(vty
, "%s\n",
2348 json_object_to_json_string(json_no
));
2349 json_object_free(json_no
);
2351 vty_out(vty
, "Malformed address: %s\n",
2352 argv
[idx_ipv4
]->arg
);
2355 peer
= peer_lookup(NULL
, &su
);
2356 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2358 json_object
*json_no
= NULL
;
2359 json_no
= json_object_new_object();
2360 json_object_string_add(
2362 "No such neighbor or address family");
2363 vty_out(vty
, "%s\n",
2364 json_object_to_json_string(json_no
));
2365 json_object_free(json_no
);
2368 "%% No such neighbor or address family\n");
2371 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2377 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2378 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2379 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2384 "Display information for a route distinguisher\n"
2385 "VPN Route Distinguisher\n"
2386 "Detailed information on TCP and BGP neighbor connections\n"
2387 "Neighbor to display information about\n"
2388 "Display the routes advertised to a BGP neighbor\n"
2391 int idx_ext_community
= 5;
2395 struct prefix_rd prd
;
2397 bool uj
= use_json(argc
, argv
);
2401 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2402 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2405 json_object
*json_no
= NULL
;
2406 json_no
= json_object_new_object();
2407 json_object_string_add(json_no
, "warning",
2408 "Malformed address");
2409 vty_out(vty
, "%s\n",
2410 json_object_to_json_string(json_no
));
2411 json_object_free(json_no
);
2413 vty_out(vty
, "Malformed address: %s\n",
2414 argv
[idx_ext_community
]->arg
);
2417 peer
= peer_lookup(NULL
, &su
);
2418 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2420 json_object
*json_no
= NULL
;
2421 json_no
= json_object_new_object();
2422 json_object_string_add(
2424 "No such neighbor or address family");
2425 vty_out(vty
, "%s\n",
2426 json_object_to_json_string(json_no
));
2427 json_object_free(json_no
);
2430 "%% No such neighbor or address family\n");
2434 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2437 json_object
*json_no
= NULL
;
2438 json_no
= json_object_new_object();
2439 json_object_string_add(
2441 "Malformed Route Distinguisher");
2442 vty_out(vty
, "%s\n",
2443 json_object_to_json_string(json_no
));
2444 json_object_free(json_no
);
2447 "%% Malformed Route Distinguisher\n");
2451 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2456 #endif /* KEEP_OLD_VPN_COMMANDS */
2458 void bgp_mplsvpn_init(void)
2460 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2461 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2462 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2464 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2465 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2467 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2468 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2469 #ifdef KEEP_OLD_VPN_COMMANDS
2470 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2471 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2472 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2473 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2474 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2475 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2476 install_element(VIEW_NODE
,
2477 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2478 install_element(VIEW_NODE
,
2479 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2480 #endif /* KEEP_OLD_VPN_COMMANDS */
2483 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2485 struct listnode
*mnode
, *mnnode
;
2489 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
2492 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2493 struct ecommunity
*ec
;
2495 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2498 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
2500 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
2503 if (ecom_intersect(ec
, eckey
))
2510 * The purpose of this function is to process leaks that were deferred
2511 * from earlier per-vrf configuration due to not-yet-existing default
2512 * vrf, in other words, configuration such as:
2514 * router bgp MMM vrf FOO
2515 * address-family ipv4 unicast
2517 * exit-address-family
2522 * This function gets called when the default instance ("router bgp NNN")
2525 void vpn_leak_postchange_all(void)
2527 struct listnode
*next
;
2529 struct bgp
*bgp_default
= bgp_get_default();
2531 assert(bgp_default
);
2533 /* First, do any exporting from VRFs to the single VPN RIB */
2534 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2536 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2539 vpn_leak_postchange(
2540 BGP_VPN_POLICY_DIR_TOVPN
,
2545 vpn_leak_postchange(
2546 BGP_VPN_POLICY_DIR_TOVPN
,
2552 /* Now, do any importing to VRFs from the single VPN RIB */
2553 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2555 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2558 vpn_leak_postchange(
2559 BGP_VPN_POLICY_DIR_FROMVPN
,
2564 vpn_leak_postchange(
2565 BGP_VPN_POLICY_DIR_FROMVPN
,
2572 /* When a bgp vrf instance is unconfigured, remove its routes
2573 * from the VPN table and this vrf could be importing routes from other
2574 * bgp vrf instnaces, unimport them.
2575 * VRF X and VRF Y are exporting routes to each other.
2576 * When VRF X is deleted, unimport its routes from all target vrfs,
2577 * also VRF Y should unimport its routes from VRF X table.
2578 * This will ensure VPN table is cleaned up appropriately.
2580 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
2583 const char *tmp_name
;
2585 struct listnode
*node
, *next
;
2586 safi_t safi
= SAFI_UNICAST
;
2588 bool is_vrf_leak_bind
;
2591 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2594 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2595 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2597 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2599 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2600 /* vrf leak is for IPv4 and IPv6 Unicast only */
2601 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
2604 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
2605 if (from_bgp
== to_bgp
)
2608 /* Unimport and remove source vrf from the
2609 * other vrfs import list.
2611 struct vpn_policy
*to_vpolicy
;
2613 is_vrf_leak_bind
= false;
2614 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
2615 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
2617 if (strcmp(vname
, tmp_name
) == 0) {
2618 is_vrf_leak_bind
= true;
2622 /* skip this bgp instance as there is no leak to this
2625 if (!is_vrf_leak_bind
)
2629 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
2630 __func__
, from_bgp
->name_pretty
,
2631 to_bgp
->name_pretty
, afi2str(afi
),
2632 to_vpolicy
->import_vrf
->count
);
2634 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
2636 /* readd vrf name as unimport removes import vrf name
2637 * from the destination vrf's import list where the
2638 * `import vrf` configuration still exist.
2640 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
2641 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2643 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2644 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2646 /* If to_bgp exports its routes to the bgp vrf
2647 * which is being deleted, un-import the
2648 * to_bgp routes from VPN.
2650 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
2653 if (strcmp(vname
, tmp_name
) == 0) {
2654 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
2664 /* When a router bgp is configured, there could be a bgp vrf
2665 * instance importing routes from this newly configured
2666 * bgp vrf instance. Export routes from configured
2668 * VRF Y has import from bgp vrf x,
2669 * when a bgp vrf x instance is created, export its routes
2670 * to VRF Y instance.
2672 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
2675 const char *export_name
;
2677 struct listnode
*node
, *next
;
2678 struct ecommunity
*ecom
;
2679 vpn_policy_direction_t idir
, edir
;
2680 safi_t safi
= SAFI_UNICAST
;
2684 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2685 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2687 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2688 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2690 export_name
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2691 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2693 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2694 /* vrf leak is for IPv4 and IPv6 Unicast only */
2695 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
2698 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
2699 if (from_bgp
== to_bgp
)
2702 /* bgp instance has import list, check to see if newly
2703 * configured bgp instance is the list.
2705 struct vpn_policy
*to_vpolicy
;
2707 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
2708 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
2710 if (strcmp(vname
, export_name
) != 0)
2714 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
2716 export_name
, to_bgp
->name_pretty
);
2718 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2719 /* remove import rt, it will be readded
2720 * as part of import from vrf.
2724 to_vpolicy
->rtlist
[idir
],
2725 (struct ecommunity_val
*)
2727 vrf_import_from_vrf(to_bgp
, from_bgp
,