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
)
112 struct prefix_rd prd
= {0};
113 mpls_label_t label
= {0};
120 prd
.family
= AF_UNSPEC
;
124 lim
= pnt
+ packet
->length
;
130 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
131 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
132 PEER_CAP_ADDPATH_AF_TX_RCV
));
134 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
135 for (; pnt
< lim
; pnt
+= psize
) {
136 /* Clear prefix structure. */
137 memset(&p
, 0, sizeof(struct prefix
));
139 if (addpath_encoded
) {
141 /* When packet overflow occurs return immediately. */
142 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
143 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
145 memcpy(&addpath_id
, pnt
, BGP_ADDPATH_ID_LEN
);
146 addpath_id
= ntohl(addpath_id
);
147 pnt
+= BGP_ADDPATH_ID_LEN
;
150 /* Fetch prefix length. */
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 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH
;
163 /* sanity check against packet data */
164 if ((pnt
+ psize
) > lim
) {
167 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
168 peer
->host
, prefixlen
, (uint
)(lim
- pnt
));
169 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
172 /* sanity check against storage for the IP address portion */
173 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
176 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
178 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
180 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
183 /* Sanity check against max bitlen of the address family */
184 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
187 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
189 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
190 p
.family
, prefix_blen(&p
));
191 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
194 /* Copy label to prefix. */
195 memcpy(&label
, pnt
, BGP_LABEL_BYTES
);
196 bgp_set_valid_label(&label
);
198 /* Copy routing distinguisher to rd. */
199 memcpy(&prd
.val
, pnt
+ BGP_LABEL_BYTES
, 8);
201 /* Decode RD type. */
202 type
= decode_rd_type(pnt
+ BGP_LABEL_BYTES
);
206 decode_rd_as(pnt
+ 5, &rd_as
);
210 decode_rd_as4(pnt
+ 5, &rd_as
);
214 decode_rd_ip(pnt
+ 5, &rd_ip
);
218 case RD_TYPE_VNC_ETH
:
223 flog_err(EC_BGP_UPDATE_RCV
, "Unknown RD type %d", type
);
224 break; /* just report */
229 - VPN_PREFIXLEN_MIN_BYTES
* 8; /* exclude label & RD */
230 memcpy(p
.u
.val
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
231 psize
- VPN_PREFIXLEN_MIN_BYTES
);
234 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
235 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
236 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
238 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
239 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
240 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
243 /* Packet length consistency check. */
247 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
248 peer
->host
, lim
- pnt
);
249 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
253 #undef VPN_PREFIXLEN_MIN_BYTES
257 * This function informs zebra of the label this vrf sets on routes
258 * leaked to VPN. Zebra should install this label in the kernel with
259 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
261 * Sending this vrf-label association is qualified by a) whether vrf->vpn
262 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
263 * are set) and b) whether vpn-policy label is set.
265 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
266 * for this vrf, which zebra interprets to mean "delete this vrf-label
269 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
271 mpls_label_t label
= MPLS_LABEL_NONE
;
272 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
274 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
277 "%s: vrf %s: afi %s: vrf_id not set, "
278 "can't set zebra vrf label",
279 __func__
, bgp
->name_pretty
, afi2str(afi
));
284 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
285 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
289 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
290 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
294 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
)
295 label
= MPLS_LABEL_NONE
;
296 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
297 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
301 * If zebra tells us vrf has become unconfigured, tell zebra not to
302 * use this label to forward to the vrf anymore
304 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
306 mpls_label_t label
= MPLS_LABEL_NONE
;
307 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
309 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
312 "%s: vrf_id not set, can't delete zebra vrf label",
319 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
320 bgp
->name_pretty
, bgp
->vrf_id
);
323 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
324 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
327 int vpn_leak_label_callback(
332 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
333 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
336 zlog_debug("%s: label=%u, allocated=%d",
337 __func__
, label
, allocated
);
341 * previously-allocated label is now invalid
343 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
344 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
346 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
347 vp
->afi
, bgp_get_default(), vp
->bgp
);
348 vp
->tovpn_label
= MPLS_LABEL_NONE
;
349 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
350 vp
->afi
, bgp_get_default(), vp
->bgp
);
356 * New label allocation
358 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
361 * not currently configured for auto label, reject allocation
366 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
367 if (label
== vp
->tovpn_label
) {
368 /* already have same label, accept but do nothing */
371 /* Shouldn't happen: different label allocation */
372 flog_err(EC_BGP_LABEL
,
373 "%s: %s had label %u but got new assignment %u",
374 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
379 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
380 vp
->afi
, bgp_get_default(), vp
->bgp
);
381 vp
->tovpn_label
= label
;
382 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
383 vp
->afi
, bgp_get_default(), vp
->bgp
);
388 static int ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
396 for (i
= 0; i
< e1
->size
; ++i
) {
397 for (j
= 0; j
< e2
->size
; ++j
) {
398 if (!memcmp(e1
->val
+ (i
* ECOMMUNITY_SIZE
),
399 e2
->val
+ (j
* ECOMMUNITY_SIZE
),
409 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
421 if (n
!= bpi
->extra
->num_labels
)
424 for (i
= 0; i
< n
; ++i
) {
425 if (label
[i
] != bpi
->extra
->label
[i
])
432 * make encoded route labels match specified encoded label set
434 static void setlabels(struct bgp_path_info
*bpi
,
435 mpls_label_t
*label
, /* array of labels */
440 assert(num_labels
<= BGP_MAX_LABELS
);
444 bpi
->extra
->num_labels
= 0;
448 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
451 for (i
= 0; i
< num_labels
; ++i
) {
452 extra
->label
[i
] = label
[i
];
453 if (!bgp_is_valid_label(&label
[i
])) {
454 bgp_set_valid_label(&extra
->label
[i
]);
457 extra
->num_labels
= num_labels
;
461 * returns pointer to new bgp_path_info upon success
463 static struct bgp_path_info
*
464 leak_update(struct bgp
*bgp
, /* destination bgp instance */
465 struct bgp_node
*bn
, struct attr
*new_attr
, /* already interned */
466 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
467 mpls_label_t
*label
, uint32_t num_labels
, void *parent
,
468 struct bgp
*bgp_orig
, struct prefix
*nexthop_orig
,
469 int nexthop_self_flag
, int debug
)
471 struct prefix
*p
= &bn
->p
;
472 struct bgp_path_info
*bpi
;
473 struct bgp_path_info
*bpi_ultimate
;
474 struct bgp_path_info
*new;
475 char buf_prefix
[PREFIX_STRLEN
];
478 prefix2str(&bn
->p
, buf_prefix
, sizeof(buf_prefix
));
479 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
480 __func__
, bgp
->name_pretty
, buf_prefix
,
481 source_bpi
->type
, source_bpi
->sub_type
);
485 * Routes that are redistributed into BGP from zebra do not get
486 * nexthop tracking. However, if those routes are subsequently
487 * imported to other RIBs within BGP, the leaked routes do not
488 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
489 * in order to determine if the route we are currently leaking
490 * should have nexthop tracking, we must find the ultimate
491 * parent so we can check its sub_type.
493 * As of now, source_bpi may at most be a second-generation route
494 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
495 * Using a loop here supports more complex intra-bgp import-export
496 * schemes that could be implemented in the future.
499 for (bpi_ultimate
= source_bpi
;
500 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
501 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
507 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
508 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
513 bool labelssame
= labels_same(bpi
, label
, num_labels
);
515 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
516 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
518 bgp_attr_unintern(&new_attr
);
521 "%s: ->%s: %s: Found route, no change",
522 __func__
, bgp
->name_pretty
,
527 /* attr is changed */
528 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
530 /* Rewrite BGP route information. */
531 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
532 bgp_path_info_restore(bn
, bpi
);
534 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
535 bgp_attr_unintern(&bpi
->attr
);
536 bpi
->attr
= new_attr
;
537 bpi
->uptime
= bgp_clock();
543 setlabels(bpi
, label
, num_labels
);
545 if (nexthop_self_flag
)
546 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
548 struct bgp
*bgp_nexthop
= bgp
;
551 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
552 bgp_nexthop
= bpi
->extra
->bgp_orig
;
555 * No nexthop tracking for redistributed routes or for
556 * EVPN-imported routes that get leaked.
558 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
559 is_pi_family_evpn(bpi_ultimate
))
563 * TBD do we need to do anything about the
564 * 'connected' parameter?
566 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
570 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
571 __func__
, (nh_valid
? "" : "not "),
572 bgp_nexthop
->name_pretty
);
575 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
577 /* Process change. */
578 bgp_aggregate_increment(bgp
, p
, bpi
, afi
, safi
);
579 bgp_process(bgp
, bn
, afi
, safi
);
583 zlog_debug("%s: ->%s: %s Found route, changed attr",
584 __func__
, bgp
->name_pretty
, buf_prefix
);
589 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
590 bgp
->peer_self
, new_attr
, bn
);
592 if (nexthop_self_flag
)
593 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
595 bgp_path_info_extra_get(new);
598 setlabels(new, label
, num_labels
);
600 new->extra
->parent
= bgp_path_info_lock(parent
);
601 bgp_lock_node((struct bgp_node
*)((struct bgp_path_info
*)parent
)->net
);
603 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
605 new->extra
->nexthop_orig
= *nexthop_orig
;
608 * nexthop tracking for unicast routes
610 struct bgp
*bgp_nexthop
= bgp
;
613 if (new->extra
->bgp_orig
)
614 bgp_nexthop
= new->extra
->bgp_orig
;
617 * No nexthop tracking for redistributed routes because
618 * their originating protocols will do the tracking and
619 * withdraw those routes if the nexthops become unreachable
620 * This also holds good for EVPN-imported routes that get
623 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
624 is_pi_family_evpn(bpi_ultimate
))
628 * TBD do we need to do anything about the
629 * 'connected' parameter?
631 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
635 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
636 __func__
, (nh_valid
? "" : "not "),
637 bgp_nexthop
->name_pretty
);
639 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
641 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
642 bgp_path_info_add(bn
, new);
645 bgp_process(bgp
, bn
, afi
, safi
);
648 zlog_debug("%s: ->%s: %s: Added new route", __func__
,
649 bgp
->name_pretty
, buf_prefix
);
654 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
655 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
656 struct bgp
*bgp_vrf
, /* from */
657 struct bgp_path_info
*path_vrf
) /* route */
659 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
660 struct prefix
*p
= &path_vrf
->net
->p
;
661 afi_t afi
= family2afi(p
->family
);
662 struct attr static_attr
= {0};
663 struct attr
*new_attr
= NULL
;
664 safi_t safi
= SAFI_MPLS_VPN
;
665 mpls_label_t label_val
;
668 const char *debugmsg
;
669 int nexthop_self_flag
= 0;
672 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
674 if (debug
&& path_vrf
->attr
->ecommunity
) {
675 char *s
= ecommunity_ecom2str(path_vrf
->attr
->ecommunity
,
676 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
678 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
679 bgp_vrf
->name
, path_vrf
->type
, s
);
680 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
688 zlog_debug("%s: can't get afi of prefix", __func__
);
692 /* Is this route exportable into the VPN table? */
693 if (!is_route_injectable_into_vpn(path_vrf
))
696 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
698 zlog_debug("%s: %s skipping: %s", __func__
,
699 bgp_vrf
->name
, debugmsg
);
704 static_attr
= *path_vrf
->attr
;
709 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
710 struct bgp_path_info info
;
711 route_map_result_t ret
;
713 memset(&info
, 0, sizeof(info
));
714 info
.peer
= bgp_vpn
->peer_self
;
715 info
.attr
= &static_attr
;
716 ret
= route_map_apply(
717 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
719 if (RMAP_DENYMATCH
== ret
) {
720 bgp_attr_flush(&static_attr
); /* free any added parts */
723 "%s: vrf %s route map \"%s\" says DENY, returning",
724 __func__
, bgp_vrf
->name_pretty
,
725 bgp_vrf
->vpn_policy
[afi
]
726 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
732 if (debug
&& static_attr
.ecommunity
) {
733 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
734 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
736 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
738 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
742 * Add the vpn-policy rt-list
744 struct ecommunity
*old_ecom
;
745 struct ecommunity
*new_ecom
;
747 old_ecom
= static_attr
.ecommunity
;
749 new_ecom
= ecommunity_merge(
750 ecommunity_dup(old_ecom
),
751 bgp_vrf
->vpn_policy
[afi
]
752 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
753 if (!old_ecom
->refcnt
)
754 ecommunity_free(&old_ecom
);
756 new_ecom
= ecommunity_dup(
757 bgp_vrf
->vpn_policy
[afi
]
758 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
760 static_attr
.ecommunity
= new_ecom
;
761 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
763 if (debug
&& static_attr
.ecommunity
) {
764 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
765 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
767 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
769 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
773 /* if policy nexthop not set, use 0 */
774 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
775 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
776 struct prefix
*nexthop
=
777 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
779 switch (nexthop
->family
) {
781 /* prevent mp_nexthop_global_in <- self in bgp_route.c
783 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
785 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
786 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
790 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
791 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
798 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
799 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
802 * For ipv4, copy to multiprotocol
805 static_attr
.mp_nexthop_global_in
=
807 static_attr
.mp_nexthop_len
=
810 * XXX Leave static_attr.nexthop
814 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
817 /* Update based on next-hop family to account for
818 * RFC 5549 (BGP unnumbered) scenario. Note that
819 * specific action is only needed for the case of
820 * IPv4 nexthops as the attr has been copied
824 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
825 static_attr
.mp_nexthop_global_in
.s_addr
=
826 static_attr
.nexthop
.s_addr
;
827 static_attr
.mp_nexthop_len
=
830 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
833 nexthop_self_flag
= 1;
836 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
837 if (label_val
== MPLS_LABEL_NONE
) {
838 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
840 encode_label(label_val
, &label
);
843 /* Set originator ID to "me" */
844 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
845 static_attr
.originator_id
= bgp_vpn
->router_id
;
848 new_attr
= bgp_attr_intern(
849 &static_attr
); /* hashed refcounted everything */
850 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
852 if (debug
&& new_attr
->ecommunity
) {
853 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
854 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
856 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
857 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
860 /* Now new_attr is an allocated interned attr */
862 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
863 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
865 struct bgp_path_info
*new_info
;
867 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, path_vrf
,
868 &label
, 1, path_vrf
, bgp_vrf
, NULL
,
869 nexthop_self_flag
, debug
);
872 * Routes actually installed in the vpn RIB must also be
873 * offered to all vrfs (because now they originate from
876 * Acceptance into other vrfs depends on rt-lists.
877 * Originating vrf will not accept the looped back route
878 * because of loop checking.
881 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
884 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
885 struct bgp
*bgp_vrf
, /* from */
886 struct bgp_path_info
*path_vrf
) /* route */
888 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
889 struct prefix
*p
= &path_vrf
->net
->p
;
890 afi_t afi
= family2afi(p
->family
);
891 safi_t safi
= SAFI_MPLS_VPN
;
892 struct bgp_path_info
*bpi
;
894 const char *debugmsg
;
895 char buf_prefix
[PREFIX_STRLEN
];
898 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
900 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
901 __func__
, bgp_vrf
->name_pretty
, buf_prefix
,
902 path_vrf
->type
, path_vrf
->sub_type
);
910 zlog_debug("%s: can't get afi of prefix", __func__
);
914 /* Is this route exportable into the VPN table? */
915 if (!is_route_injectable_into_vpn(path_vrf
))
918 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
920 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
925 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
927 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
928 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
934 * match original bpi imported from
936 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
937 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
943 /* withdraw from looped vrfs as well */
944 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
946 bgp_aggregate_decrement(bgp_vpn
, p
, bpi
, afi
, safi
);
947 bgp_path_info_delete(bn
, bpi
);
948 bgp_process(bgp_vpn
, bn
, afi
, safi
);
953 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
954 struct bgp
*bgp_vrf
, /* from */
957 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
958 struct bgp_node
*prn
;
959 safi_t safi
= SAFI_MPLS_VPN
;
962 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
964 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
965 prn
= bgp_route_next(prn
)) {
967 struct bgp_table
*table
;
969 struct bgp_path_info
*bpi
;
971 /* This is the per-RD table of prefixes */
972 table
= bgp_node_get_bgp_table_info(prn
);
977 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
979 char buf
[PREFIX2STR_BUFFER
];
981 bpi
= bgp_node_get_bgp_path_info(bn
);
984 "%s: looking at prefix %s", __func__
,
985 prefix2str(&bn
->p
, buf
, sizeof(buf
)));
988 for (; bpi
; bpi
= bpi
->next
) {
990 zlog_debug("%s: type %d, sub_type %d",
993 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
997 if ((struct bgp
*)bpi
->extra
->bgp_orig
1001 zlog_debug("%s: deleting it",
1003 bgp_aggregate_decrement(bgp_vpn
, &bn
->p
,
1005 bgp_path_info_delete(bn
, bpi
);
1006 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1013 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
1014 struct bgp
*bgp_vrf
, /* from */
1017 struct bgp_node
*bn
;
1018 struct bgp_path_info
*bpi
;
1019 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1022 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1023 bgp_vrf
->name_pretty
);
1025 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
1026 bn
= bgp_route_next(bn
)) {
1029 zlog_debug("%s: node=%p", __func__
, bn
);
1031 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
1035 "%s: calling vpn_leak_from_vrf_update",
1037 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bpi
);
1043 vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1044 struct bgp
*bgp_vpn
, /* from */
1045 struct bgp_path_info
*path_vpn
) /* route */
1047 struct prefix
*p
= &path_vpn
->net
->p
;
1048 afi_t afi
= family2afi(p
->family
);
1050 struct attr static_attr
= {0};
1051 struct attr
*new_attr
= NULL
;
1052 struct bgp_node
*bn
;
1053 safi_t safi
= SAFI_UNICAST
;
1054 const char *debugmsg
;
1055 struct prefix nexthop_orig
;
1056 mpls_label_t
*pLabels
= NULL
;
1057 uint32_t num_labels
= 0;
1058 int nexthop_self_flag
= 1;
1059 struct bgp_path_info
*bpi_ultimate
= NULL
;
1060 int origin_local
= 0;
1061 struct bgp
*src_vrf
;
1063 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1065 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1067 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1071 /* Check for intersection of route targets */
1072 if (!ecom_intersect(
1073 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1074 path_vpn
->attr
->ecommunity
)) {
1080 char buf_prefix
[PREFIX_STRLEN
];
1082 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
1083 zlog_debug("%s: updating %s to vrf %s", __func__
,
1084 buf_prefix
, bgp_vrf
->name_pretty
);
1088 static_attr
= *path_vpn
->attr
;
1091 * Nexthop: stash and clear
1093 * Nexthop is valid in context of VPN core, but not in destination vrf.
1094 * Stash it for later label resolution by vrf ingress path and then
1095 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1097 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1099 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1100 nexthop_orig
.family
= nhfamily
;
1105 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1106 nexthop_orig
.prefixlen
= 32;
1108 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1109 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1110 static_attr
.nexthop
.s_addr
=
1111 nexthop_orig
.u
.prefix4
.s_addr
;
1113 static_attr
.mp_nexthop_global_in
=
1114 path_vpn
->attr
->mp_nexthop_global_in
;
1115 static_attr
.mp_nexthop_len
=
1116 path_vpn
->attr
->mp_nexthop_len
;
1118 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1122 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1123 nexthop_orig
.prefixlen
= 128;
1125 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1126 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1127 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1133 * route map handling
1135 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1136 struct bgp_path_info info
;
1137 route_map_result_t ret
;
1139 memset(&info
, 0, sizeof(info
));
1140 info
.peer
= bgp_vrf
->peer_self
;
1141 info
.attr
= &static_attr
;
1142 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1143 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1144 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1145 p
, RMAP_BGP
, &info
);
1146 if (RMAP_DENYMATCH
== ret
) {
1147 bgp_attr_flush(&static_attr
); /* free any added parts */
1150 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1151 __func__
, bgp_vrf
->name_pretty
,
1152 bgp_vrf
->vpn_policy
[afi
]
1153 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1158 * if route-map changed nexthop, don't nexthop-self on output
1160 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1161 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1162 nexthop_self_flag
= 0;
1165 new_attr
= bgp_attr_intern(&static_attr
);
1166 bgp_attr_flush(&static_attr
);
1168 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1171 * ensure labels are copied
1173 * However, there is a special case: if the route originated in
1174 * another local VRF (as opposed to arriving via VPN), then the
1175 * nexthop is reached by hairpinning through this router (me)
1176 * using IP forwarding only (no LSP). Therefore, the route
1177 * imported to the VRF should not have labels attached. Note
1178 * that nexthop tracking is also involved: eliminating the
1179 * labels for these routes enables the non-labeled nexthops
1180 * from the originating VRF to be considered valid for this route.
1182 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1183 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1184 /* work back to original route */
1185 for (bpi_ultimate
= path_vpn
;
1186 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
1187 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
1191 * if original route was unicast,
1192 * then it did not arrive over vpn
1194 if (bpi_ultimate
->net
) {
1195 struct bgp_table
*table
;
1197 table
= bgp_node_table(bpi_ultimate
->net
);
1198 if (table
&& (table
->safi
== SAFI_UNICAST
))
1203 if (!origin_local
&& path_vpn
->extra
1204 && path_vpn
->extra
->num_labels
) {
1205 num_labels
= path_vpn
->extra
->num_labels
;
1206 if (num_labels
> BGP_MAX_LABELS
)
1207 num_labels
= BGP_MAX_LABELS
;
1208 pLabels
= path_vpn
->extra
->label
;
1213 char buf_prefix
[PREFIX_STRLEN
];
1214 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
1215 zlog_debug("%s: pfx %s: num_labels %d", __func__
, buf_prefix
,
1220 * For VRF-2-VRF route-leaking,
1221 * the source will be the originating VRF.
1223 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1224 src_vrf
= path_vpn
->extra
->bgp_orig
;
1228 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
1229 num_labels
, path_vpn
, /* parent */
1230 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1233 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1234 struct bgp_path_info
*path_vpn
) /* route */
1236 struct listnode
*mnode
, *mnnode
;
1239 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1242 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1244 /* Loop over VRFs */
1245 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1247 if (!path_vpn
->extra
1248 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1249 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, path_vpn
);
1254 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1255 struct bgp_path_info
*path_vpn
) /* route */
1259 safi_t safi
= SAFI_UNICAST
;
1261 struct listnode
*mnode
, *mnnode
;
1262 struct bgp_node
*bn
;
1263 struct bgp_path_info
*bpi
;
1264 const char *debugmsg
;
1265 char buf_prefix
[PREFIX_STRLEN
];
1267 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1270 prefix2str(&path_vpn
->net
->p
, buf_prefix
, sizeof(buf_prefix
));
1271 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d", __func__
,
1272 buf_prefix
, path_vpn
->type
, path_vpn
->sub_type
);
1276 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1278 if (!path_vpn
->net
) {
1280 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1281 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
1282 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1289 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1294 p
= &path_vpn
->net
->p
;
1295 afi
= family2afi(p
->family
);
1297 /* Loop over VRFs */
1298 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1299 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1301 zlog_debug("%s: skipping: %s", __func__
,
1306 /* Check for intersection of route targets */
1307 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1308 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1309 path_vpn
->attr
->ecommunity
)) {
1315 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1318 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1320 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
1323 && (struct bgp_path_info
*)bpi
->extra
->parent
1331 zlog_debug("%s: deleting bpi %p", __func__
,
1333 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
1334 bgp_path_info_delete(bn
, bpi
);
1335 bgp_process(bgp
, bn
, afi
, safi
);
1337 bgp_unlock_node(bn
);
1341 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1344 struct bgp_node
*bn
;
1345 struct bgp_path_info
*bpi
;
1346 safi_t safi
= SAFI_UNICAST
;
1347 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1350 zlog_debug("%s: entry", __func__
);
1352 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1354 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1355 bn
= bgp_route_next(bn
)) {
1357 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
1360 && bpi
->extra
->bgp_orig
!= bgp_vrf
1361 && bpi
->extra
->parent
1362 && is_pi_family_vpn(bpi
->extra
->parent
)) {
1365 bgp_aggregate_decrement(bgp_vrf
, &bn
->p
, bpi
,
1367 bgp_path_info_delete(bn
, bpi
);
1368 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1374 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1375 struct bgp
*bgp_vpn
, /* from */
1378 struct prefix_rd prd
;
1379 struct bgp_node
*prn
;
1380 safi_t safi
= SAFI_MPLS_VPN
;
1387 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
1388 prn
= bgp_route_next(prn
)) {
1390 struct bgp_table
*table
;
1391 struct bgp_node
*bn
;
1392 struct bgp_path_info
*bpi
;
1394 memset(&prd
, 0, sizeof(prd
));
1395 prd
.family
= AF_UNSPEC
;
1397 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
1399 /* This is the per-RD table of prefixes */
1400 table
= bgp_node_get_bgp_table_info(prn
);
1405 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1407 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
1411 && bpi
->extra
->bgp_orig
== bgp_vrf
)
1414 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1422 * This function is called for definition/deletion/change to a route-map
1424 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1426 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1428 struct route_map
*rmap
;
1430 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1431 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1436 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1438 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1440 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1441 && !strcmp(rmap_name
,
1442 bgp
->vpn_policy
[afi
]
1443 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1447 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1448 __func__
, rmap_name
, bgp
->as
,
1451 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1452 bgp_get_default(), bgp
);
1454 zlog_debug("%s: after vpn_leak_prechange",
1457 /* in case of definition/deletion */
1458 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1461 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1462 bgp_get_default(), bgp
);
1465 zlog_debug("%s: after vpn_leak_postchange",
1469 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1470 && !strcmp(rmap_name
,
1471 bgp
->vpn_policy
[afi
]
1472 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1475 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1476 __func__
, rmap_name
, bgp
->as
,
1480 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1481 bgp_get_default(), bgp
);
1483 /* in case of definition/deletion */
1484 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1487 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1488 bgp_get_default(), bgp
);
1493 /* This API is used during router-id change, reflect VPNs
1494 * auto RD and RT values and readvertise routes to VPN table.
1496 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
1502 const char *export_name
;
1503 char buf
[RD_ADDRSTRLEN
];
1504 struct bgp
*bgp_import
;
1505 struct listnode
*node
;
1506 struct ecommunity
*ecom
;
1507 vpn_policy_direction_t idir
, edir
;
1509 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1510 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1513 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1514 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1515 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1517 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1518 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1520 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1521 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
1525 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
1526 afi
, bgp_get_default(), bgp
);
1528 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1529 __func__
, export_name
);
1531 /* Remove import RT from VRFs */
1532 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1533 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1534 export_vrf
, node
, vname
)) {
1535 bgp_import
= bgp_lookup_by_name(vname
);
1539 ecommunity_del_val(bgp_import
->vpn_policy
[afi
].
1541 (struct ecommunity_val
*)ecom
->val
);
1546 * Router-id changes that are not explicit config
1547 * changes should not replace configured RD/RT.
1550 if (CHECK_FLAG(bgp
->vpn_policy
[afi
].flags
,
1551 BGP_VPN_POLICY_TOVPN_RD_SET
)) {
1553 zlog_debug("%s: auto router-id change skipped",
1559 /* New router-id derive auto RD and RT and export
1562 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
1563 &bgp
->vrf_prd_auto
);
1564 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
1565 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
1567 bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1568 ecommunity_str2com(buf
,
1569 ECOMMUNITY_ROUTE_TARGET
, 0);
1571 /* Update import_vrf rt_list */
1572 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1573 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1574 export_vrf
, node
, vname
)) {
1575 bgp_import
= bgp_lookup_by_name(vname
);
1578 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
1579 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1581 bgp_import
->vpn_policy
[afi
]
1582 .rtlist
[idir
], ecom
);
1584 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1585 = ecommunity_dup(ecom
);
1590 /* Update routes to VPN */
1591 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
1592 afi
, bgp_get_default(),
1595 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
1596 __func__
, export_name
);
1601 void vpn_policy_routemap_event(const char *rmap_name
)
1603 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1604 struct listnode
*mnode
, *mnnode
;
1608 zlog_debug("%s: entry", __func__
);
1610 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1613 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1614 vpn_policy_routemap_update(bgp
, rmap_name
);
1617 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1618 afi_t afi
, safi_t safi
)
1620 const char *export_name
;
1621 vpn_policy_direction_t idir
, edir
;
1622 char *vname
, *tmp_name
;
1623 char buf
[RD_ADDRSTRLEN
];
1624 struct ecommunity
*ecom
;
1625 bool first_export
= false;
1627 struct listnode
*node
;
1628 bool is_inst_match
= false;
1630 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
1631 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1632 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1634 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1635 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1638 * Cross-ref both VRFs. Also, note if this is the first time
1639 * any VRF is importing from "import_vrf".
1641 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
1642 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
1644 /* Check the import_vrf list of destination vrf for the source vrf name,
1647 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
1649 if (strcmp(vname
, tmp_name
) == 0) {
1650 is_inst_match
= true;
1655 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
1658 /* Check if the source vrf already exports to any vrf,
1659 * first time export requires to setup auto derived RD/RT values.
1660 * Add the destination vrf name to export vrf list if it is
1663 is_inst_match
= false;
1664 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
1665 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1666 first_export
= true;
1668 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1670 if (strcmp(vname
, tmp_name
) == 0) {
1671 is_inst_match
= true;
1677 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
1679 /* Update import RT for current VRF using export RT of the VRF we're
1680 * importing from. First though, make sure "import_vrf" has that
1684 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
1685 &from_bgp
->vrf_prd_auto
);
1686 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
1687 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1688 BGP_VPN_POLICY_TOVPN_RD_SET
);
1689 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
1691 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1692 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
1693 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1694 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1695 from_bgp
->vpn_policy
[afi
].tovpn_label
=
1696 BGP_PREVENT_VRF_2_VRF_LEAK
;
1698 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1699 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
1700 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
1701 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
1702 .rtlist
[idir
], ecom
);
1704 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
1705 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1708 const char *from_name
;
1710 from_name
= from_bgp
->name
? from_bgp
->name
:
1712 zlog_debug("%s from %s to %s first_export %u import-rt %s export-rt %s",
1713 __func__
, from_name
, export_name
, first_export
,
1714 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] ?
1715 (ecommunity_ecom2str(to_bgp
->vpn_policy
[afi
].
1717 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0)) : " ",
1718 to_bgp
->vpn_policy
[afi
].rtlist
[edir
] ?
1719 (ecommunity_ecom2str(to_bgp
->vpn_policy
[afi
].
1721 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0)) : " ");
1724 /* Does "import_vrf" first need to export its routes or that
1725 * is already done and we just need to import those routes
1726 * from the global table?
1729 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
1731 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1734 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1735 afi_t afi
, safi_t safi
)
1737 const char *export_name
, *tmp_name
;
1738 vpn_policy_direction_t idir
, edir
;
1740 struct ecommunity
*ecom
= NULL
;
1741 struct listnode
*node
;
1744 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
1745 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
1746 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1747 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1749 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1750 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1752 /* Were we importing from "import_vrf"? */
1753 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
1755 if (strcmp(vname
, tmp_name
) == 0)
1760 * We do not check in the cli if the passed in bgp
1761 * instance is actually imported into us before
1762 * we call this function. As such if we do not
1763 * find this in the import_vrf list than
1764 * we just need to return safely.
1770 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
1772 /* Remove "import_vrf" from our import list. */
1773 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1774 XFREE(MTYPE_TMP
, vname
);
1776 /* Remove routes imported from "import_vrf". */
1777 /* TODO: In the current logic, we have to first remove all
1778 * imported routes and then (if needed) import back routes
1780 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
1782 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
1783 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
1784 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1785 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
1786 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
1788 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1790 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
1791 (struct ecommunity_val
*)ecom
->val
);
1792 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1797 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1798 * below is checking for NULL that export_vrf can be
1799 * NULL, consequently it is complaining( like a cabbage )
1800 * that we could dereference and crash in the listcount(..)
1802 * So make it happy, under protest, with liberty and justice
1805 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
1807 /* Remove us from "import_vrf's" export list. If no other VRF
1808 * is importing from "import_vrf", cleanup appropriately.
1810 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1812 if (strcmp(vname
, export_name
) == 0)
1817 * If we have gotten to this point then the vname must
1818 * exist. If not, we are in a world of trouble and
1819 * have slag sitting around.
1821 * import_vrf and export_vrf must match in having
1822 * the in/out names as appropriate.
1823 * export_vrf list could have been cleaned up
1824 * as part of no router bgp source instnace.
1829 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1830 XFREE(MTYPE_TMP
, vname
);
1832 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1833 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
1834 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
1835 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1836 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1837 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
1838 sizeof(struct prefix_rd
));
1839 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1840 BGP_VPN_POLICY_TOVPN_RD_SET
);
1841 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
1846 /* For testing purpose, static route of MPLS-VPN. */
1847 DEFUN (vpnv4_network
,
1849 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1850 "Specify a network to announce via BGP\n"
1852 "Specify Route Distinguisher\n"
1853 "VPN Route Distinguisher\n"
1854 "VPN NLRI label (tag)\n"
1855 "VPN NLRI label (tag)\n"
1858 int idx_ipv4_prefixlen
= 1;
1859 int idx_ext_community
= 3;
1861 return bgp_static_set_safi(
1862 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1863 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1864 NULL
, NULL
, NULL
, NULL
);
1867 DEFUN (vpnv4_network_route_map
,
1868 vpnv4_network_route_map_cmd
,
1869 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1870 "Specify a network to announce via BGP\n"
1872 "Specify Route Distinguisher\n"
1873 "VPN Route Distinguisher\n"
1874 "VPN NLRI label (tag)\n"
1875 "VPN NLRI label (tag)\n"
1880 int idx_ipv4_prefixlen
= 1;
1881 int idx_ext_community
= 3;
1884 return bgp_static_set_safi(
1885 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1886 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1887 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1890 /* For testing purpose, static route of MPLS-VPN. */
1891 DEFUN (no_vpnv4_network
,
1892 no_vpnv4_network_cmd
,
1893 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1895 "Specify a network to announce via BGP\n"
1897 "Specify Route Distinguisher\n"
1898 "VPN Route Distinguisher\n"
1899 "VPN NLRI label (tag)\n"
1900 "VPN NLRI label (tag)\n"
1903 int idx_ipv4_prefixlen
= 2;
1904 int idx_ext_community
= 4;
1906 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1907 argv
[idx_ipv4_prefixlen
]->arg
,
1908 argv
[idx_ext_community
]->arg
,
1909 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1912 DEFUN (vpnv6_network
,
1914 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1915 "Specify a network to announce via BGP\n"
1916 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1917 "Specify Route Distinguisher\n"
1918 "VPN Route Distinguisher\n"
1919 "VPN NLRI label (tag)\n"
1920 "VPN NLRI label (tag)\n"
1925 int idx_ipv6_prefix
= 1;
1926 int idx_ext_community
= 3;
1930 return bgp_static_set_safi(
1931 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1932 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1933 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1935 return bgp_static_set_safi(
1936 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1937 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1938 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1941 /* For testing purpose, static route of MPLS-VPN. */
1942 DEFUN (no_vpnv6_network
,
1943 no_vpnv6_network_cmd
,
1944 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1946 "Specify a network to announce via BGP\n"
1947 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1948 "Specify Route Distinguisher\n"
1949 "VPN Route Distinguisher\n"
1950 "VPN NLRI label (tag)\n"
1951 "VPN NLRI label (tag)\n"
1954 int idx_ipv6_prefix
= 2;
1955 int idx_ext_community
= 4;
1957 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
1958 argv
[idx_ipv6_prefix
]->arg
,
1959 argv
[idx_ext_community
]->arg
,
1960 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1963 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
1964 enum bgp_show_type type
, void *output_arg
, int tags
,
1968 struct bgp_table
*table
;
1970 bgp
= bgp_get_default();
1973 vty_out(vty
, "No BGP process is configured\n");
1975 vty_out(vty
, "{}\n");
1978 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
1979 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
1980 output_arg
, use_json
);
1983 DEFUN (show_bgp_ip_vpn_all_rd
,
1984 show_bgp_ip_vpn_all_rd_cmd
,
1985 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1989 "Display VPN NLRI specific information\n"
1990 "Display VPN NLRI specific information\n"
1991 "Display information for a route distinguisher\n"
1992 "VPN Route Distinguisher\n"
1996 struct prefix_rd prd
;
2000 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2001 if (argv_find(argv
, argc
, "rd", &idx
)) {
2002 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2005 "%% Malformed Route Distinguisher\n");
2008 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2009 bgp_show_type_normal
, NULL
, 0,
2010 use_json(argc
, argv
));
2012 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2013 bgp_show_type_normal
, NULL
, 0,
2014 use_json(argc
, argv
));
2020 ALIAS(show_bgp_ip_vpn_all_rd
,
2021 show_bgp_ip_vpn_rd_cmd
,
2022 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
2026 "Display VPN NLRI specific information\n"
2027 "Display information for a route distinguisher\n"
2028 "VPN Route Distinguisher\n"
2031 #ifdef KEEP_OLD_VPN_COMMANDS
2032 DEFUN (show_ip_bgp_vpn_rd
,
2033 show_ip_bgp_vpn_rd_cmd
,
2034 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
2039 "Address Family modifier\n"
2040 "Display information for a route distinguisher\n"
2041 "VPN Route Distinguisher\n")
2043 int idx_ext_community
= argc
- 1;
2045 struct prefix_rd prd
;
2049 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2050 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2052 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2055 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2061 DEFUN (show_ip_bgp_vpn_all
,
2062 show_ip_bgp_vpn_all_cmd
,
2063 "show [ip] bgp <vpnv4|vpnv6>",
2072 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2073 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2078 DEFUN (show_ip_bgp_vpn_all_tags
,
2079 show_ip_bgp_vpn_all_tags_cmd
,
2080 "show [ip] bgp <vpnv4|vpnv6> all tags",
2085 "Display information about all VPNv4/VPNV6 NLRIs\n"
2086 "Display BGP tags for prefixes\n")
2091 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2092 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2097 DEFUN (show_ip_bgp_vpn_rd_tags
,
2098 show_ip_bgp_vpn_rd_tags_cmd
,
2099 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
2104 "Display information for a route distinguisher\n"
2105 "VPN Route Distinguisher\n"
2106 "Display BGP tags for prefixes\n")
2108 int idx_ext_community
= 5;
2110 struct prefix_rd prd
;
2114 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2115 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2117 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2120 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2126 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2127 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2128 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2133 "Display information about all VPNv4/VPNv6 NLRIs\n"
2134 "Detailed information on TCP and BGP neighbor connections\n"
2135 "Neighbor to display information about\n"
2136 "Display routes learned from neighbor\n"
2143 bool uj
= use_json(argc
, argv
);
2147 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2148 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2151 json_object
*json_no
= NULL
;
2152 json_no
= json_object_new_object();
2153 json_object_string_add(json_no
, "warning",
2154 "Malformed address");
2155 vty_out(vty
, "%s\n",
2156 json_object_to_json_string(json_no
));
2157 json_object_free(json_no
);
2159 vty_out(vty
, "Malformed address: %s\n",
2160 argv
[idx_ipv4
]->arg
);
2164 peer
= peer_lookup(NULL
, &su
);
2165 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2167 json_object
*json_no
= NULL
;
2168 json_no
= json_object_new_object();
2169 json_object_string_add(
2171 "No such neighbor or address family");
2172 vty_out(vty
, "%s\n",
2173 json_object_to_json_string(json_no
));
2174 json_object_free(json_no
);
2177 "%% No such neighbor or address family\n");
2181 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2187 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2188 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2189 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
2194 "Display information for a route distinguisher\n"
2195 "VPN Route Distinguisher\n"
2196 "Detailed information on TCP and BGP neighbor connections\n"
2197 "Neighbor to display information about\n"
2198 "Display routes learned from neighbor\n"
2201 int idx_ext_community
= 5;
2206 struct prefix_rd prd
;
2207 bool uj
= use_json(argc
, argv
);
2211 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2212 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2215 json_object
*json_no
= NULL
;
2216 json_no
= json_object_new_object();
2217 json_object_string_add(
2219 "Malformed Route Distinguisher");
2220 vty_out(vty
, "%s\n",
2221 json_object_to_json_string(json_no
));
2222 json_object_free(json_no
);
2225 "%% Malformed Route Distinguisher\n");
2229 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2232 json_object
*json_no
= NULL
;
2233 json_no
= json_object_new_object();
2234 json_object_string_add(json_no
, "warning",
2235 "Malformed address");
2236 vty_out(vty
, "%s\n",
2237 json_object_to_json_string(json_no
));
2238 json_object_free(json_no
);
2240 vty_out(vty
, "Malformed address: %s\n",
2241 argv
[idx_ext_community
]->arg
);
2245 peer
= peer_lookup(NULL
, &su
);
2246 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2248 json_object
*json_no
= NULL
;
2249 json_no
= json_object_new_object();
2250 json_object_string_add(
2252 "No such neighbor or address family");
2253 vty_out(vty
, "%s\n",
2254 json_object_to_json_string(json_no
));
2255 json_object_free(json_no
);
2258 "%% No such neighbor or address family\n");
2262 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
2268 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2269 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2270 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2275 "Display information about all VPNv4/VPNv6 NLRIs\n"
2276 "Detailed information on TCP and BGP neighbor connections\n"
2277 "Neighbor to display information about\n"
2278 "Display the routes advertised to a BGP neighbor\n"
2285 bool uj
= use_json(argc
, argv
);
2289 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2290 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2293 json_object
*json_no
= NULL
;
2294 json_no
= json_object_new_object();
2295 json_object_string_add(json_no
, "warning",
2296 "Malformed address");
2297 vty_out(vty
, "%s\n",
2298 json_object_to_json_string(json_no
));
2299 json_object_free(json_no
);
2301 vty_out(vty
, "Malformed address: %s\n",
2302 argv
[idx_ipv4
]->arg
);
2305 peer
= peer_lookup(NULL
, &su
);
2306 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2308 json_object
*json_no
= NULL
;
2309 json_no
= json_object_new_object();
2310 json_object_string_add(
2312 "No such neighbor or address family");
2313 vty_out(vty
, "%s\n",
2314 json_object_to_json_string(json_no
));
2315 json_object_free(json_no
);
2318 "%% No such neighbor or address family\n");
2321 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2327 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2328 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2329 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2334 "Display information for a route distinguisher\n"
2335 "VPN Route Distinguisher\n"
2336 "Detailed information on TCP and BGP neighbor connections\n"
2337 "Neighbor to display information about\n"
2338 "Display the routes advertised to a BGP neighbor\n"
2341 int idx_ext_community
= 5;
2345 struct prefix_rd prd
;
2347 bool uj
= use_json(argc
, argv
);
2351 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2352 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2355 json_object
*json_no
= NULL
;
2356 json_no
= json_object_new_object();
2357 json_object_string_add(json_no
, "warning",
2358 "Malformed address");
2359 vty_out(vty
, "%s\n",
2360 json_object_to_json_string(json_no
));
2361 json_object_free(json_no
);
2363 vty_out(vty
, "Malformed address: %s\n",
2364 argv
[idx_ext_community
]->arg
);
2367 peer
= peer_lookup(NULL
, &su
);
2368 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2370 json_object
*json_no
= NULL
;
2371 json_no
= json_object_new_object();
2372 json_object_string_add(
2374 "No such neighbor or address family");
2375 vty_out(vty
, "%s\n",
2376 json_object_to_json_string(json_no
));
2377 json_object_free(json_no
);
2380 "%% No such neighbor or address family\n");
2384 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2387 json_object
*json_no
= NULL
;
2388 json_no
= json_object_new_object();
2389 json_object_string_add(
2391 "Malformed Route Distinguisher");
2392 vty_out(vty
, "%s\n",
2393 json_object_to_json_string(json_no
));
2394 json_object_free(json_no
);
2397 "%% Malformed Route Distinguisher\n");
2401 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2406 #endif /* KEEP_OLD_VPN_COMMANDS */
2408 void bgp_mplsvpn_init(void)
2410 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2411 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2412 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2414 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2415 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2417 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2418 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2419 #ifdef KEEP_OLD_VPN_COMMANDS
2420 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2421 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2422 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2423 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2424 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2425 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2426 install_element(VIEW_NODE
,
2427 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2428 install_element(VIEW_NODE
,
2429 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2430 #endif /* KEEP_OLD_VPN_COMMANDS */
2433 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2435 struct listnode
*mnode
, *mnnode
;
2438 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2439 struct ecommunity
*ec
;
2441 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2444 ec
= bgp
->vpn_policy
[AFI_IP
].import_redirect_rtlist
;
2446 if (ecom_intersect(ec
, eckey
))
2453 * The purpose of this function is to process leaks that were deferred
2454 * from earlier per-vrf configuration due to not-yet-existing default
2455 * vrf, in other words, configuration such as:
2457 * router bgp MMM vrf FOO
2458 * address-family ipv4 unicast
2460 * exit-address-family
2465 * This function gets called when the default instance ("router bgp NNN")
2468 void vpn_leak_postchange_all(void)
2470 struct listnode
*next
;
2472 struct bgp
*bgp_default
= bgp_get_default();
2474 assert(bgp_default
);
2476 /* First, do any exporting from VRFs to the single VPN RIB */
2477 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2479 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2482 vpn_leak_postchange(
2483 BGP_VPN_POLICY_DIR_TOVPN
,
2488 vpn_leak_postchange(
2489 BGP_VPN_POLICY_DIR_TOVPN
,
2495 /* Now, do any importing to VRFs from the single VPN RIB */
2496 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2498 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2501 vpn_leak_postchange(
2502 BGP_VPN_POLICY_DIR_FROMVPN
,
2507 vpn_leak_postchange(
2508 BGP_VPN_POLICY_DIR_FROMVPN
,
2515 /* When a bgp vrf instance is unconfigured, remove its routes
2516 * from the VPN table and this vrf could be importing routes from other
2517 * bgp vrf instnaces, unimport them.
2518 * VRF X and VRF Y are exporting routes to each other.
2519 * When VRF X is deleted, unimport its routes from all target vrfs,
2520 * also VRF Y should unimport its routes from VRF X table.
2521 * This will ensure VPN table is cleaned up appropriately.
2523 int bgp_vpn_leak_unimport(struct bgp
*from_bgp
, struct vty
*vty
)
2526 const char *tmp_name
;
2528 struct listnode
*node
, *next
;
2529 safi_t safi
= SAFI_UNICAST
;
2531 bool is_vrf_leak_bind
;
2534 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2537 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2538 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2540 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2542 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2543 /* vrf leak is for IPv4 and IPv6 Unicast only */
2544 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
2547 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
2548 if (from_bgp
== to_bgp
)
2551 /* Unimport and remove source vrf from the
2552 * other vrfs import list.
2554 struct vpn_policy
*to_vpolicy
;
2556 is_vrf_leak_bind
= false;
2557 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
2558 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
2560 if (strcmp(vname
, tmp_name
) == 0) {
2561 is_vrf_leak_bind
= true;
2565 /* skip this bgp instance as there is no leak to this
2568 if (!is_vrf_leak_bind
)
2572 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
2573 __func__
, from_bgp
->name_pretty
,
2574 to_bgp
->name_pretty
, afi2str(afi
),
2575 to_vpolicy
->import_vrf
->count
);
2577 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
2579 /* readd vrf name as unimport removes import vrf name
2580 * from the destination vrf's import list where the
2581 * `import vrf` configuration still exist.
2583 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
2584 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2586 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2587 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2589 /* If to_bgp exports its routes to the bgp vrf
2590 * which is being deleted, un-import the
2591 * to_bgp routes from VPN.
2593 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
2596 if (strcmp(vname
, tmp_name
) == 0) {
2597 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
2607 /* When a router bgp is configured, there could be a bgp vrf
2608 * instance importing routes from this newly configured
2609 * bgp vrf instance. Export routes from configured
2611 * VRF Y has import from bgp vrf x,
2612 * when a bgp vrf x instance is created, export its routes
2613 * to VRF Y instance.
2615 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
2618 const char *export_name
;
2620 struct listnode
*node
, *next
;
2621 struct ecommunity
*ecom
;
2622 vpn_policy_direction_t idir
, edir
;
2623 safi_t safi
= SAFI_UNICAST
;
2627 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2628 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2630 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2631 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2633 export_name
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2634 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2636 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2637 /* vrf leak is for IPv4 and IPv6 Unicast only */
2638 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
2641 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
2642 if (from_bgp
== to_bgp
)
2645 /* bgp instance has import list, check to see if newly
2646 * configured bgp instance is the list.
2648 struct vpn_policy
*to_vpolicy
;
2650 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
2651 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
2653 if (strcmp(vname
, export_name
) != 0)
2657 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
2659 export_name
, to_bgp
->name_pretty
);
2661 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2662 /* remove import rt, it will be readded
2663 * as part of import from vrf.
2667 to_vpolicy
->rtlist
[idir
],
2668 (struct ecommunity_val
*)
2670 vrf_import_from_vrf(to_bgp
, from_bgp
,