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
;
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 addpath_id
= ntohl(*((uint32_t *)pnt
));
146 pnt
+= BGP_ADDPATH_ID_LEN
;
149 /* Fetch prefix length. */
151 p
.family
= afi2family(packet
->afi
);
152 psize
= PSIZE(prefixlen
);
154 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
157 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
158 peer
->host
, prefixlen
);
159 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH
;
162 /* sanity check against packet data */
163 if ((pnt
+ psize
) > lim
) {
166 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
167 peer
->host
, prefixlen
, (uint
)(lim
- pnt
));
168 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
171 /* sanity check against storage for the IP address portion */
172 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
175 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
177 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
179 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
182 /* Sanity check against max bitlen of the address family */
183 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
186 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
188 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
189 p
.family
, prefix_blen(&p
));
190 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
193 /* Copy label to prefix. */
194 memcpy(&label
, pnt
, BGP_LABEL_BYTES
);
195 bgp_set_valid_label(&label
);
197 /* Copy routing distinguisher to rd. */
198 memcpy(&prd
.val
, pnt
+ BGP_LABEL_BYTES
, 8);
200 /* Decode RD type. */
201 type
= decode_rd_type(pnt
+ BGP_LABEL_BYTES
);
205 decode_rd_as(pnt
+ 5, &rd_as
);
209 decode_rd_as4(pnt
+ 5, &rd_as
);
213 decode_rd_ip(pnt
+ 5, &rd_ip
);
217 case RD_TYPE_VNC_ETH
:
222 flog_err(EC_BGP_UPDATE_RCV
, "Unknown RD type %d", type
);
223 break; /* just report */
228 - VPN_PREFIXLEN_MIN_BYTES
* 8; /* exclude label & RD */
229 memcpy(p
.u
.val
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
230 psize
- VPN_PREFIXLEN_MIN_BYTES
);
233 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
234 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
235 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
237 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
238 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
239 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
242 /* Packet length consistency check. */
246 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
247 peer
->host
, lim
- pnt
);
248 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
252 #undef VPN_PREFIXLEN_MIN_BYTES
256 * This function informs zebra of the label this vrf sets on routes
257 * leaked to VPN. Zebra should install this label in the kernel with
258 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
260 * Sending this vrf-label association is qualified by a) whether vrf->vpn
261 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
262 * are set) and b) whether vpn-policy label is set.
264 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
265 * for this vrf, which zebra interprets to mean "delete this vrf-label
268 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
270 mpls_label_t label
= MPLS_LABEL_NONE
;
271 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
273 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
276 "%s: vrf %s: afi %s: vrf_id not set, "
277 "can't set zebra vrf label",
278 __func__
, bgp
->name_pretty
, afi2str(afi
));
283 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
284 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
288 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
289 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
293 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
)
294 label
= MPLS_LABEL_NONE
;
295 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
296 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
300 * If zebra tells us vrf has become unconfigured, tell zebra not to
301 * use this label to forward to the vrf anymore
303 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
305 mpls_label_t label
= MPLS_LABEL_NONE
;
306 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
308 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
311 "%s: vrf_id not set, can't delete zebra vrf label",
318 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
319 bgp
->name_pretty
, bgp
->vrf_id
);
322 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
323 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
326 int vpn_leak_label_callback(
331 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
332 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
335 zlog_debug("%s: label=%u, allocated=%d",
336 __func__
, label
, allocated
);
340 * previously-allocated label is now invalid
342 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
343 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
345 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
346 vp
->afi
, bgp_get_default(), vp
->bgp
);
347 vp
->tovpn_label
= MPLS_LABEL_NONE
;
348 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
349 vp
->afi
, bgp_get_default(), vp
->bgp
);
355 * New label allocation
357 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
360 * not currently configured for auto label, reject allocation
365 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
366 if (label
== vp
->tovpn_label
) {
367 /* already have same label, accept but do nothing */
370 /* Shouldn't happen: different label allocation */
371 flog_err(EC_BGP_LABEL
,
372 "%s: %s had label %u but got new assignment %u",
373 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
378 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
379 vp
->afi
, bgp_get_default(), vp
->bgp
);
380 vp
->tovpn_label
= label
;
381 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
382 vp
->afi
, bgp_get_default(), vp
->bgp
);
387 static int ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
395 for (i
= 0; i
< e1
->size
; ++i
) {
396 for (j
= 0; j
< e2
->size
; ++j
) {
397 if (!memcmp(e1
->val
+ (i
* ECOMMUNITY_SIZE
),
398 e2
->val
+ (j
* ECOMMUNITY_SIZE
),
408 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
420 if (n
!= bpi
->extra
->num_labels
)
423 for (i
= 0; i
< n
; ++i
) {
424 if (label
[i
] != bpi
->extra
->label
[i
])
431 * make encoded route labels match specified encoded label set
433 static void setlabels(struct bgp_path_info
*bpi
,
434 mpls_label_t
*label
, /* array of labels */
439 assert(num_labels
<= BGP_MAX_LABELS
);
443 bpi
->extra
->num_labels
= 0;
447 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
450 for (i
= 0; i
< num_labels
; ++i
) {
451 extra
->label
[i
] = label
[i
];
452 if (!bgp_is_valid_label(&label
[i
])) {
453 bgp_set_valid_label(&extra
->label
[i
]);
456 extra
->num_labels
= num_labels
;
460 * returns pointer to new bgp_path_info upon success
462 static struct bgp_path_info
*
463 leak_update(struct bgp
*bgp
, /* destination bgp instance */
464 struct bgp_node
*bn
, struct attr
*new_attr
, /* already interned */
465 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
466 mpls_label_t
*label
, uint32_t num_labels
, void *parent
,
467 struct bgp
*bgp_orig
, struct prefix
*nexthop_orig
,
468 int nexthop_self_flag
, int debug
)
470 struct prefix
*p
= &bn
->p
;
471 struct bgp_path_info
*bpi
;
472 struct bgp_path_info
*bpi_ultimate
;
473 struct bgp_path_info
*new;
474 char buf_prefix
[PREFIX_STRLEN
];
477 prefix2str(&bn
->p
, buf_prefix
, sizeof(buf_prefix
));
478 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
479 __func__
, bgp
->name_pretty
, buf_prefix
,
480 source_bpi
->type
, source_bpi
->sub_type
);
484 * Routes that are redistributed into BGP from zebra do not get
485 * nexthop tracking. However, if those routes are subsequently
486 * imported to other RIBs within BGP, the leaked routes do not
487 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
488 * in order to determine if the route we are currently leaking
489 * should have nexthop tracking, we must find the ultimate
490 * parent so we can check its sub_type.
492 * As of now, source_bpi may at most be a second-generation route
493 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
494 * Using a loop here supports more complex intra-bgp import-export
495 * schemes that could be implemented in the future.
498 for (bpi_ultimate
= source_bpi
;
499 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
500 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
506 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
507 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
512 bool labelssame
= labels_same(bpi
, label
, num_labels
);
514 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
515 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
517 bgp_attr_unintern(&new_attr
);
520 "%s: ->%s: %s: Found route, no change",
521 __func__
, bgp
->name_pretty
,
526 /* attr is changed */
527 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
529 /* Rewrite BGP route information. */
530 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
531 bgp_path_info_restore(bn
, bpi
);
533 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
534 bgp_attr_unintern(&bpi
->attr
);
535 bpi
->attr
= new_attr
;
536 bpi
->uptime
= bgp_clock();
542 setlabels(bpi
, label
, num_labels
);
544 if (nexthop_self_flag
)
545 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
547 struct bgp
*bgp_nexthop
= bgp
;
550 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
551 bgp_nexthop
= bpi
->extra
->bgp_orig
;
554 * No nexthop tracking for redistributed routes or for
555 * EVPN-imported routes that get leaked.
557 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
558 is_pi_family_evpn(bpi_ultimate
))
562 * TBD do we need to do anything about the
563 * 'connected' parameter?
565 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
569 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
570 __func__
, (nh_valid
? "" : "not "),
571 bgp_nexthop
->name_pretty
);
574 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
576 /* Process change. */
577 bgp_aggregate_increment(bgp
, p
, bpi
, afi
, safi
);
578 bgp_process(bgp
, bn
, afi
, safi
);
582 zlog_debug("%s: ->%s: %s Found route, changed attr",
583 __func__
, bgp
->name_pretty
, buf_prefix
);
588 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
589 bgp
->peer_self
, new_attr
, bn
);
591 if (nexthop_self_flag
)
592 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
594 bgp_path_info_extra_get(new);
597 setlabels(new, label
, num_labels
);
599 new->extra
->parent
= bgp_path_info_lock(parent
);
600 bgp_lock_node((struct bgp_node
*)((struct bgp_path_info
*)parent
)->net
);
602 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
604 new->extra
->nexthop_orig
= *nexthop_orig
;
607 * nexthop tracking for unicast routes
609 struct bgp
*bgp_nexthop
= bgp
;
612 if (new->extra
->bgp_orig
)
613 bgp_nexthop
= new->extra
->bgp_orig
;
616 * No nexthop tracking for redistributed routes because
617 * their originating protocols will do the tracking and
618 * withdraw those routes if the nexthops become unreachable
619 * This also holds good for EVPN-imported routes that get
622 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
623 is_pi_family_evpn(bpi_ultimate
))
627 * TBD do we need to do anything about the
628 * 'connected' parameter?
630 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
634 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
635 __func__
, (nh_valid
? "" : "not "),
636 bgp_nexthop
->name_pretty
);
638 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
640 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
641 bgp_path_info_add(bn
, new);
644 bgp_process(bgp
, bn
, afi
, safi
);
647 zlog_debug("%s: ->%s: %s: Added new route", __func__
,
648 bgp
->name_pretty
, buf_prefix
);
653 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
654 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
655 struct bgp
*bgp_vrf
, /* from */
656 struct bgp_path_info
*path_vrf
) /* route */
658 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
659 struct prefix
*p
= &path_vrf
->net
->p
;
660 afi_t afi
= family2afi(p
->family
);
661 struct attr static_attr
= {0};
662 struct attr
*new_attr
= NULL
;
663 safi_t safi
= SAFI_MPLS_VPN
;
664 mpls_label_t label_val
;
667 const char *debugmsg
;
668 int nexthop_self_flag
= 0;
671 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
673 if (debug
&& path_vrf
->attr
->ecommunity
) {
674 char *s
= ecommunity_ecom2str(path_vrf
->attr
->ecommunity
,
675 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
677 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
678 bgp_vrf
->name
, path_vrf
->type
, s
);
679 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
687 zlog_debug("%s: can't get afi of prefix", __func__
);
691 /* Is this route exportable into the VPN table? */
692 if (!is_route_injectable_into_vpn(path_vrf
))
695 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
697 zlog_debug("%s: %s skipping: %s", __func__
,
698 bgp_vrf
->name
, debugmsg
);
702 bgp_attr_dup(&static_attr
, path_vrf
->attr
); /* shallow copy */
707 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
708 struct bgp_path_info info
;
709 route_map_result_t ret
;
711 memset(&info
, 0, sizeof(info
));
712 info
.peer
= bgp_vpn
->peer_self
;
713 info
.attr
= &static_attr
;
714 ret
= route_map_apply(
715 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
717 if (RMAP_DENYMATCH
== ret
) {
718 bgp_attr_flush(&static_attr
); /* free any added parts */
721 "%s: vrf %s route map \"%s\" says DENY, returning",
722 __func__
, bgp_vrf
->name_pretty
,
723 bgp_vrf
->vpn_policy
[afi
]
724 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
730 if (debug
&& static_attr
.ecommunity
) {
731 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
732 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
734 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
736 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
740 * Add the vpn-policy rt-list
742 struct ecommunity
*old_ecom
;
743 struct ecommunity
*new_ecom
;
745 old_ecom
= static_attr
.ecommunity
;
747 new_ecom
= ecommunity_merge(
748 ecommunity_dup(old_ecom
),
749 bgp_vrf
->vpn_policy
[afi
]
750 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
751 if (!old_ecom
->refcnt
)
752 ecommunity_free(&old_ecom
);
754 new_ecom
= ecommunity_dup(
755 bgp_vrf
->vpn_policy
[afi
]
756 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
758 static_attr
.ecommunity
= new_ecom
;
759 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
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 merge static_attr.ecommunity{%s}",
767 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
771 /* if policy nexthop not set, use 0 */
772 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
773 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
774 struct prefix
*nexthop
=
775 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
777 switch (nexthop
->family
) {
779 /* prevent mp_nexthop_global_in <- self in bgp_route.c
781 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
783 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
784 static_attr
.mp_nexthop_len
= 4;
788 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
789 static_attr
.mp_nexthop_len
= 16;
796 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
797 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
800 * For ipv4, copy to multiprotocol
803 static_attr
.mp_nexthop_global_in
=
805 static_attr
.mp_nexthop_len
= 4;
807 * XXX Leave static_attr.nexthop
811 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
814 /* Update based on next-hop family to account for
815 * RFC 5549 (BGP unnumbered) scenario. Note that
816 * specific action is only needed for the case of
817 * IPv4 nexthops as the attr has been copied
821 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
822 static_attr
.mp_nexthop_global_in
.s_addr
=
823 static_attr
.nexthop
.s_addr
;
824 static_attr
.mp_nexthop_len
= 4;
826 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
829 nexthop_self_flag
= 1;
832 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
833 if (label_val
== MPLS_LABEL_NONE
) {
834 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
836 encode_label(label_val
, &label
);
839 /* Set originator ID to "me" */
840 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
841 static_attr
.originator_id
= bgp_vpn
->router_id
;
844 new_attr
= bgp_attr_intern(
845 &static_attr
); /* hashed refcounted everything */
846 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
848 if (debug
&& new_attr
->ecommunity
) {
849 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
850 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
852 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
853 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
856 /* Now new_attr is an allocated interned attr */
858 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
859 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
861 struct bgp_path_info
*new_info
;
863 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, path_vrf
,
864 &label
, 1, path_vrf
, bgp_vrf
, NULL
,
865 nexthop_self_flag
, debug
);
868 * Routes actually installed in the vpn RIB must also be
869 * offered to all vrfs (because now they originate from
872 * Acceptance into other vrfs depends on rt-lists.
873 * Originating vrf will not accept the looped back route
874 * because of loop checking.
877 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
880 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
881 struct bgp
*bgp_vrf
, /* from */
882 struct bgp_path_info
*path_vrf
) /* route */
884 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
885 struct prefix
*p
= &path_vrf
->net
->p
;
886 afi_t afi
= family2afi(p
->family
);
887 safi_t safi
= SAFI_MPLS_VPN
;
888 struct bgp_path_info
*bpi
;
890 const char *debugmsg
;
891 char buf_prefix
[PREFIX_STRLEN
];
894 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
896 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
897 __func__
, bgp_vrf
->name_pretty
, buf_prefix
,
898 path_vrf
->type
, path_vrf
->sub_type
);
906 zlog_debug("%s: can't get afi of prefix", __func__
);
910 /* Is this route exportable into the VPN table? */
911 if (!is_route_injectable_into_vpn(path_vrf
))
914 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
916 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
921 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
923 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
924 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
930 * match original bpi imported from
932 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
933 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
939 /* withdraw from looped vrfs as well */
940 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
942 bgp_aggregate_decrement(bgp_vpn
, p
, bpi
, afi
, safi
);
943 bgp_path_info_delete(bn
, bpi
);
944 bgp_process(bgp_vpn
, bn
, afi
, safi
);
949 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
950 struct bgp
*bgp_vrf
, /* from */
953 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
954 struct bgp_node
*prn
;
955 safi_t safi
= SAFI_MPLS_VPN
;
958 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
960 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
961 prn
= bgp_route_next(prn
)) {
963 struct bgp_table
*table
;
965 struct bgp_path_info
*bpi
;
967 /* This is the per-RD table of prefixes */
968 table
= bgp_node_get_bgp_table_info(prn
);
973 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
975 char buf
[PREFIX2STR_BUFFER
];
977 bpi
= bgp_node_get_bgp_path_info(bn
);
980 "%s: looking at prefix %s", __func__
,
981 prefix2str(&bn
->p
, buf
, sizeof(buf
)));
984 for (; bpi
; bpi
= bpi
->next
) {
986 zlog_debug("%s: type %d, sub_type %d",
989 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
993 if ((struct bgp
*)bpi
->extra
->bgp_orig
997 zlog_debug("%s: deleting it",
999 bgp_aggregate_decrement(bgp_vpn
, &bn
->p
,
1001 bgp_path_info_delete(bn
, bpi
);
1002 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1009 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
1010 struct bgp
*bgp_vrf
, /* from */
1013 struct bgp_node
*bn
;
1014 struct bgp_path_info
*bpi
;
1015 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1018 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1019 bgp_vrf
->name_pretty
);
1021 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
1022 bn
= bgp_route_next(bn
)) {
1025 zlog_debug("%s: node=%p", __func__
, bn
);
1027 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
1031 "%s: calling vpn_leak_from_vrf_update",
1033 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bpi
);
1039 vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1040 struct bgp
*bgp_vpn
, /* from */
1041 struct bgp_path_info
*path_vpn
) /* route */
1043 struct prefix
*p
= &path_vpn
->net
->p
;
1044 afi_t afi
= family2afi(p
->family
);
1046 struct attr static_attr
= {0};
1047 struct attr
*new_attr
= NULL
;
1048 struct bgp_node
*bn
;
1049 safi_t safi
= SAFI_UNICAST
;
1050 const char *debugmsg
;
1051 struct prefix nexthop_orig
;
1052 mpls_label_t
*pLabels
= NULL
;
1053 uint32_t num_labels
= 0;
1054 int nexthop_self_flag
= 1;
1055 struct bgp_path_info
*bpi_ultimate
= NULL
;
1056 int origin_local
= 0;
1057 struct bgp
*src_vrf
;
1059 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1061 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1063 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1067 /* Check for intersection of route targets */
1068 if (!ecom_intersect(
1069 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1070 path_vpn
->attr
->ecommunity
)) {
1076 char buf_prefix
[PREFIX_STRLEN
];
1078 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
1079 zlog_debug("%s: updating %s to vrf %s", __func__
,
1080 buf_prefix
, bgp_vrf
->name_pretty
);
1083 bgp_attr_dup(&static_attr
, path_vpn
->attr
); /* shallow copy */
1086 * Nexthop: stash and clear
1088 * Nexthop is valid in context of VPN core, but not in destination vrf.
1089 * Stash it for later label resolution by vrf ingress path and then
1090 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1092 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1094 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1095 nexthop_orig
.family
= nhfamily
;
1100 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1101 nexthop_orig
.prefixlen
= 32;
1103 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1104 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1105 static_attr
.nexthop
.s_addr
=
1106 nexthop_orig
.u
.prefix4
.s_addr
;
1108 static_attr
.mp_nexthop_global_in
=
1109 path_vpn
->attr
->mp_nexthop_global_in
;
1110 static_attr
.mp_nexthop_len
=
1111 path_vpn
->attr
->mp_nexthop_len
;
1113 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1117 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1118 nexthop_orig
.prefixlen
= 128;
1120 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1121 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1122 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1128 * route map handling
1130 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1131 struct bgp_path_info info
;
1132 route_map_result_t ret
;
1134 memset(&info
, 0, sizeof(info
));
1135 info
.peer
= bgp_vrf
->peer_self
;
1136 info
.attr
= &static_attr
;
1137 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1138 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1139 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1140 p
, RMAP_BGP
, &info
);
1141 if (RMAP_DENYMATCH
== ret
) {
1142 bgp_attr_flush(&static_attr
); /* free any added parts */
1145 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1146 __func__
, bgp_vrf
->name_pretty
,
1147 bgp_vrf
->vpn_policy
[afi
]
1148 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1153 * if route-map changed nexthop, don't nexthop-self on output
1155 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1156 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1157 nexthop_self_flag
= 0;
1160 new_attr
= bgp_attr_intern(&static_attr
);
1161 bgp_attr_flush(&static_attr
);
1163 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1166 * ensure labels are copied
1168 * However, there is a special case: if the route originated in
1169 * another local VRF (as opposed to arriving via VPN), then the
1170 * nexthop is reached by hairpinning through this router (me)
1171 * using IP forwarding only (no LSP). Therefore, the route
1172 * imported to the VRF should not have labels attached. Note
1173 * that nexthop tracking is also involved: eliminating the
1174 * labels for these routes enables the non-labeled nexthops
1175 * from the originating VRF to be considered valid for this route.
1177 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1178 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1179 /* work back to original route */
1180 for (bpi_ultimate
= path_vpn
;
1181 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
1182 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
1186 * if original route was unicast,
1187 * then it did not arrive over vpn
1189 if (bpi_ultimate
->net
) {
1190 struct bgp_table
*table
;
1192 table
= bgp_node_table(bpi_ultimate
->net
);
1193 if (table
&& (table
->safi
== SAFI_UNICAST
))
1198 if (!origin_local
&& path_vpn
->extra
1199 && path_vpn
->extra
->num_labels
) {
1200 num_labels
= path_vpn
->extra
->num_labels
;
1201 if (num_labels
> BGP_MAX_LABELS
)
1202 num_labels
= BGP_MAX_LABELS
;
1203 pLabels
= path_vpn
->extra
->label
;
1208 char buf_prefix
[PREFIX_STRLEN
];
1209 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
1210 zlog_debug("%s: pfx %s: num_labels %d", __func__
, buf_prefix
,
1215 * For VRF-2-VRF route-leaking,
1216 * the source will be the originating VRF.
1218 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1219 src_vrf
= path_vpn
->extra
->bgp_orig
;
1223 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
1224 num_labels
, path_vpn
, /* parent */
1225 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1228 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1229 struct bgp_path_info
*path_vpn
) /* route */
1231 struct listnode
*mnode
, *mnnode
;
1234 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1237 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1239 /* Loop over VRFs */
1240 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1242 if (!path_vpn
->extra
1243 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1244 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, path_vpn
);
1249 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1250 struct bgp_path_info
*path_vpn
) /* route */
1254 safi_t safi
= SAFI_UNICAST
;
1256 struct listnode
*mnode
, *mnnode
;
1257 struct bgp_node
*bn
;
1258 struct bgp_path_info
*bpi
;
1259 const char *debugmsg
;
1260 char buf_prefix
[PREFIX_STRLEN
];
1262 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1265 prefix2str(&path_vpn
->net
->p
, buf_prefix
, sizeof(buf_prefix
));
1266 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d", __func__
,
1267 buf_prefix
, path_vpn
->type
, path_vpn
->sub_type
);
1271 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1273 if (!path_vpn
->net
) {
1275 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1276 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
1277 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1284 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1289 p
= &path_vpn
->net
->p
;
1290 afi
= family2afi(p
->family
);
1292 /* Loop over VRFs */
1293 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1294 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1296 zlog_debug("%s: skipping: %s", __func__
,
1301 /* Check for intersection of route targets */
1302 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1303 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1304 path_vpn
->attr
->ecommunity
)) {
1310 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1313 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1315 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
1318 && (struct bgp_path_info
*)bpi
->extra
->parent
1326 zlog_debug("%s: deleting bpi %p", __func__
,
1328 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
1329 bgp_path_info_delete(bn
, bpi
);
1330 bgp_process(bgp
, bn
, afi
, safi
);
1332 bgp_unlock_node(bn
);
1336 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1339 struct bgp_node
*bn
;
1340 struct bgp_path_info
*bpi
;
1341 safi_t safi
= SAFI_UNICAST
;
1342 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1345 zlog_debug("%s: entry", __func__
);
1347 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1349 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1350 bn
= bgp_route_next(bn
)) {
1352 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
1355 && bpi
->extra
->bgp_orig
!= bgp_vrf
1356 && bpi
->extra
->parent
1357 && is_pi_family_vpn(bpi
->extra
->parent
)) {
1360 bgp_aggregate_decrement(bgp_vrf
, &bn
->p
, bpi
,
1362 bgp_path_info_delete(bn
, bpi
);
1363 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1369 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1370 struct bgp
*bgp_vpn
, /* from */
1373 struct prefix_rd prd
;
1374 struct bgp_node
*prn
;
1375 safi_t safi
= SAFI_MPLS_VPN
;
1382 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
1383 prn
= bgp_route_next(prn
)) {
1385 struct bgp_table
*table
;
1386 struct bgp_node
*bn
;
1387 struct bgp_path_info
*bpi
;
1389 memset(&prd
, 0, sizeof(prd
));
1390 prd
.family
= AF_UNSPEC
;
1392 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
1394 /* This is the per-RD table of prefixes */
1395 table
= bgp_node_get_bgp_table_info(prn
);
1400 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1402 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
1406 && bpi
->extra
->bgp_orig
== bgp_vrf
)
1409 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1417 * This function is called for definition/deletion/change to a route-map
1419 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1421 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1423 struct route_map
*rmap
;
1425 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1426 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1431 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1433 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1435 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1436 && !strcmp(rmap_name
,
1437 bgp
->vpn_policy
[afi
]
1438 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1442 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1443 __func__
, rmap_name
, bgp
->as
,
1446 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1447 bgp_get_default(), bgp
);
1449 zlog_debug("%s: after vpn_leak_prechange",
1452 /* in case of definition/deletion */
1453 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1456 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1457 bgp_get_default(), bgp
);
1460 zlog_debug("%s: after vpn_leak_postchange",
1464 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1465 && !strcmp(rmap_name
,
1466 bgp
->vpn_policy
[afi
]
1467 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1470 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1471 __func__
, rmap_name
, bgp
->as
,
1475 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1476 bgp_get_default(), bgp
);
1478 /* in case of definition/deletion */
1479 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1482 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1483 bgp_get_default(), bgp
);
1488 /* This API is used during router-id change, reflect VPNs
1489 * auto RD and RT values and readvertise routes to VPN table.
1491 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
1497 const char *export_name
;
1498 char buf
[RD_ADDRSTRLEN
];
1499 struct bgp
*bgp_import
;
1500 struct listnode
*node
;
1501 struct ecommunity
*ecom
;
1502 vpn_policy_direction_t idir
, edir
;
1504 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1505 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1508 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1509 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1510 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1512 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1513 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1515 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1516 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
1520 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
1521 afi
, bgp_get_default(), bgp
);
1523 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1524 __func__
, export_name
);
1526 /* Remove import RT from VRFs */
1527 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1528 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1529 export_vrf
, node
, vname
)) {
1530 bgp_import
= bgp_lookup_by_name(vname
);
1534 ecommunity_del_val(bgp_import
->vpn_policy
[afi
].
1536 (struct ecommunity_val
*)ecom
->val
);
1541 * Router-id changes that are not explicit config
1542 * changes should not replace configured RD/RT.
1545 if (CHECK_FLAG(bgp
->vpn_policy
[afi
].flags
,
1546 BGP_VPN_POLICY_TOVPN_RD_SET
)) {
1548 zlog_debug("%s: auto router-id change skipped",
1554 /* New router-id derive auto RD and RT and export
1557 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
1558 &bgp
->vrf_prd_auto
);
1559 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
1560 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
1562 bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1563 ecommunity_str2com(buf
,
1564 ECOMMUNITY_ROUTE_TARGET
, 0);
1566 /* Update import_vrf rt_list */
1567 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1568 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1569 export_vrf
, node
, vname
)) {
1570 bgp_import
= bgp_lookup_by_name(vname
);
1573 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
1574 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1576 bgp_import
->vpn_policy
[afi
]
1577 .rtlist
[idir
], ecom
);
1579 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1580 = ecommunity_dup(ecom
);
1585 /* Update routes to VPN */
1586 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
1587 afi
, bgp_get_default(),
1590 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
1591 __func__
, export_name
);
1596 void vpn_policy_routemap_event(const char *rmap_name
)
1598 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1599 struct listnode
*mnode
, *mnnode
;
1603 zlog_debug("%s: entry", __func__
);
1605 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1608 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1609 vpn_policy_routemap_update(bgp
, rmap_name
);
1612 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1613 afi_t afi
, safi_t safi
)
1615 const char *export_name
;
1616 vpn_policy_direction_t idir
, edir
;
1619 struct ecommunity
*ecom
;
1620 bool first_export
= false;
1623 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
1624 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1625 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1627 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1628 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1631 * Cross-ref both VRFs. Also, note if this is the first time
1632 * any VRF is importing from "import_vrf".
1634 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
1635 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
1637 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1639 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
))
1640 first_export
= true;
1641 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
1642 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1644 /* Update import RT for current VRF using export RT of the VRF we're
1645 * importing from. First though, make sure "import_vrf" has that
1649 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
1650 &from_bgp
->vrf_prd_auto
);
1651 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
1652 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1653 BGP_VPN_POLICY_TOVPN_RD_SET
);
1654 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
1656 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1657 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
1658 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1659 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1660 from_bgp
->vpn_policy
[afi
].tovpn_label
=
1661 BGP_PREVENT_VRF_2_VRF_LEAK
;
1663 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1664 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
1665 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
1666 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
1667 .rtlist
[idir
], ecom
);
1669 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
1670 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1673 const char *from_name
;
1675 from_name
= from_bgp
->name
? from_bgp
->name
:
1677 zlog_debug("%s from %s to %s first_export %u import-rt %s export-rt %s",
1678 __func__
, from_name
, export_name
, first_export
,
1679 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] ?
1680 (ecommunity_ecom2str(to_bgp
->vpn_policy
[afi
].
1682 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0)) : " ",
1683 to_bgp
->vpn_policy
[afi
].rtlist
[edir
] ?
1684 (ecommunity_ecom2str(to_bgp
->vpn_policy
[afi
].
1686 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0)) : " ");
1689 /* Does "import_vrf" first need to export its routes or that
1690 * is already done and we just need to import those routes
1691 * from the global table?
1694 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
1696 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1699 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1700 afi_t afi
, safi_t safi
)
1702 const char *export_name
, *tmp_name
;
1703 vpn_policy_direction_t idir
, edir
;
1705 struct ecommunity
*ecom
;
1706 struct listnode
*node
;
1709 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
1710 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
1711 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1712 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1714 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1715 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1717 /* Were we importing from "import_vrf"? */
1718 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
1720 if (strcmp(vname
, tmp_name
) == 0)
1725 * We do not check in the cli if the passed in bgp
1726 * instance is actually imported into us before
1727 * we call this function. As such if we do not
1728 * find this in the import_vrf list than
1729 * we just need to return safely.
1735 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
1737 /* Remove "import_vrf" from our import list. */
1738 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1739 XFREE(MTYPE_TMP
, vname
);
1741 /* Remove routes imported from "import_vrf". */
1742 /* TODO: In the current logic, we have to first remove all
1743 * imported routes and then (if needed) import back routes
1745 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
1747 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
1748 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
1749 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1750 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
1752 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1753 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
1754 (struct ecommunity_val
*)ecom
->val
);
1755 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1760 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1761 * below is checking for NULL that export_vrf can be
1762 * NULL, consequently it is complaining( like a cabbage )
1763 * that we could dereference and crash in the listcount(..)
1765 * So make it happy, under protest, with liberty and justice
1768 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
1770 /* Remove us from "import_vrf's" export list. If no other VRF
1771 * is importing from "import_vrf", cleanup appropriately.
1773 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1775 if (strcmp(vname
, export_name
) == 0)
1780 * If we have gotten to this point then the vname must
1781 * exist. If not, we are in a world of trouble and
1782 * have slag sitting around.
1784 * import_vrf and export_vrf must match in having
1785 * the in/out names as appropriate.
1789 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1790 XFREE(MTYPE_TMP
, vname
);
1792 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1793 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
1794 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
1795 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1796 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1797 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
1798 sizeof(struct prefix_rd
));
1799 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1800 BGP_VPN_POLICY_TOVPN_RD_SET
);
1801 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
1806 /* For testing purpose, static route of MPLS-VPN. */
1807 DEFUN (vpnv4_network
,
1809 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1810 "Specify a network to announce via BGP\n"
1812 "Specify Route Distinguisher\n"
1813 "VPN Route Distinguisher\n"
1814 "VPN NLRI label (tag)\n"
1815 "VPN NLRI label (tag)\n"
1818 int idx_ipv4_prefixlen
= 1;
1819 int idx_ext_community
= 3;
1821 return bgp_static_set_safi(
1822 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1823 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1824 NULL
, NULL
, NULL
, NULL
);
1827 DEFUN (vpnv4_network_route_map
,
1828 vpnv4_network_route_map_cmd
,
1829 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1830 "Specify a network to announce via BGP\n"
1832 "Specify Route Distinguisher\n"
1833 "VPN Route Distinguisher\n"
1834 "VPN NLRI label (tag)\n"
1835 "VPN NLRI label (tag)\n"
1840 int idx_ipv4_prefixlen
= 1;
1841 int idx_ext_community
= 3;
1844 return bgp_static_set_safi(
1845 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1846 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1847 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1850 /* For testing purpose, static route of MPLS-VPN. */
1851 DEFUN (no_vpnv4_network
,
1852 no_vpnv4_network_cmd
,
1853 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1855 "Specify a network to announce via BGP\n"
1857 "Specify Route Distinguisher\n"
1858 "VPN Route Distinguisher\n"
1859 "VPN NLRI label (tag)\n"
1860 "VPN NLRI label (tag)\n"
1863 int idx_ipv4_prefixlen
= 2;
1864 int idx_ext_community
= 4;
1866 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1867 argv
[idx_ipv4_prefixlen
]->arg
,
1868 argv
[idx_ext_community
]->arg
,
1869 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1872 DEFUN (vpnv6_network
,
1874 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1875 "Specify a network to announce via BGP\n"
1876 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1877 "Specify Route Distinguisher\n"
1878 "VPN Route Distinguisher\n"
1879 "VPN NLRI label (tag)\n"
1880 "VPN NLRI label (tag)\n"
1885 int idx_ipv6_prefix
= 1;
1886 int idx_ext_community
= 3;
1890 return bgp_static_set_safi(
1891 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1892 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1893 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1895 return bgp_static_set_safi(
1896 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1897 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1898 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1901 /* For testing purpose, static route of MPLS-VPN. */
1902 DEFUN (no_vpnv6_network
,
1903 no_vpnv6_network_cmd
,
1904 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1906 "Specify a network to announce via BGP\n"
1907 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1908 "Specify Route Distinguisher\n"
1909 "VPN Route Distinguisher\n"
1910 "VPN NLRI label (tag)\n"
1911 "VPN NLRI label (tag)\n"
1914 int idx_ipv6_prefix
= 2;
1915 int idx_ext_community
= 4;
1917 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
1918 argv
[idx_ipv6_prefix
]->arg
,
1919 argv
[idx_ext_community
]->arg
,
1920 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1923 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
1924 enum bgp_show_type type
, void *output_arg
, int tags
,
1928 struct bgp_table
*table
;
1930 bgp
= bgp_get_default();
1933 vty_out(vty
, "No BGP process is configured\n");
1935 vty_out(vty
, "{}\n");
1938 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
1939 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
1940 output_arg
, use_json
);
1943 DEFUN (show_bgp_ip_vpn_all_rd
,
1944 show_bgp_ip_vpn_all_rd_cmd
,
1945 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1949 "Display VPN NLRI specific information\n"
1950 "Display VPN NLRI specific information\n"
1951 "Display information for a route distinguisher\n"
1952 "VPN Route Distinguisher\n"
1956 struct prefix_rd prd
;
1960 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1961 if (argv_find(argv
, argc
, "rd", &idx
)) {
1962 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
1965 "%% Malformed Route Distinguisher\n");
1968 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
1969 bgp_show_type_normal
, NULL
, 0,
1970 use_json(argc
, argv
));
1972 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
1973 bgp_show_type_normal
, NULL
, 0,
1974 use_json(argc
, argv
));
1980 ALIAS(show_bgp_ip_vpn_all_rd
,
1981 show_bgp_ip_vpn_rd_cmd
,
1982 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1986 "Display VPN NLRI specific information\n"
1987 "Display information for a route distinguisher\n"
1988 "VPN Route Distinguisher\n"
1991 #ifdef KEEP_OLD_VPN_COMMANDS
1992 DEFUN (show_ip_bgp_vpn_rd
,
1993 show_ip_bgp_vpn_rd_cmd
,
1994 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
1999 "Address Family modifier\n"
2000 "Display information for a route distinguisher\n"
2001 "VPN Route Distinguisher\n")
2003 int idx_ext_community
= argc
- 1;
2005 struct prefix_rd prd
;
2009 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2010 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2012 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2015 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2021 DEFUN (show_ip_bgp_vpn_all
,
2022 show_ip_bgp_vpn_all_cmd
,
2023 "show [ip] bgp <vpnv4|vpnv6>",
2032 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2033 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2038 DEFUN (show_ip_bgp_vpn_all_tags
,
2039 show_ip_bgp_vpn_all_tags_cmd
,
2040 "show [ip] bgp <vpnv4|vpnv6> all tags",
2045 "Display information about all VPNv4/VPNV6 NLRIs\n"
2046 "Display BGP tags for prefixes\n")
2051 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2052 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2057 DEFUN (show_ip_bgp_vpn_rd_tags
,
2058 show_ip_bgp_vpn_rd_tags_cmd
,
2059 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
2064 "Display information for a route distinguisher\n"
2065 "VPN Route Distinguisher\n"
2066 "Display BGP tags for prefixes\n")
2068 int idx_ext_community
= 5;
2070 struct prefix_rd prd
;
2074 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2075 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2077 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2080 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2086 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2087 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2088 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2093 "Display information about all VPNv4/VPNv6 NLRIs\n"
2094 "Detailed information on TCP and BGP neighbor connections\n"
2095 "Neighbor to display information about\n"
2096 "Display routes learned from neighbor\n"
2103 bool uj
= use_json(argc
, argv
);
2107 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2108 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2111 json_object
*json_no
= NULL
;
2112 json_no
= json_object_new_object();
2113 json_object_string_add(json_no
, "warning",
2114 "Malformed address");
2115 vty_out(vty
, "%s\n",
2116 json_object_to_json_string(json_no
));
2117 json_object_free(json_no
);
2119 vty_out(vty
, "Malformed address: %s\n",
2120 argv
[idx_ipv4
]->arg
);
2124 peer
= peer_lookup(NULL
, &su
);
2125 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2127 json_object
*json_no
= NULL
;
2128 json_no
= json_object_new_object();
2129 json_object_string_add(
2131 "No such neighbor or address family");
2132 vty_out(vty
, "%s\n",
2133 json_object_to_json_string(json_no
));
2134 json_object_free(json_no
);
2137 "%% No such neighbor or address family\n");
2141 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2147 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2148 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2149 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
2154 "Display information for a route distinguisher\n"
2155 "VPN Route Distinguisher\n"
2156 "Detailed information on TCP and BGP neighbor connections\n"
2157 "Neighbor to display information about\n"
2158 "Display routes learned from neighbor\n"
2161 int idx_ext_community
= 5;
2166 struct prefix_rd prd
;
2167 bool uj
= use_json(argc
, argv
);
2171 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2172 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2175 json_object
*json_no
= NULL
;
2176 json_no
= json_object_new_object();
2177 json_object_string_add(
2179 "Malformed Route Distinguisher");
2180 vty_out(vty
, "%s\n",
2181 json_object_to_json_string(json_no
));
2182 json_object_free(json_no
);
2185 "%% Malformed Route Distinguisher\n");
2189 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2192 json_object
*json_no
= NULL
;
2193 json_no
= json_object_new_object();
2194 json_object_string_add(json_no
, "warning",
2195 "Malformed address");
2196 vty_out(vty
, "%s\n",
2197 json_object_to_json_string(json_no
));
2198 json_object_free(json_no
);
2200 vty_out(vty
, "Malformed address: %s\n",
2201 argv
[idx_ext_community
]->arg
);
2205 peer
= peer_lookup(NULL
, &su
);
2206 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2208 json_object
*json_no
= NULL
;
2209 json_no
= json_object_new_object();
2210 json_object_string_add(
2212 "No such neighbor or address family");
2213 vty_out(vty
, "%s\n",
2214 json_object_to_json_string(json_no
));
2215 json_object_free(json_no
);
2218 "%% No such neighbor or address family\n");
2222 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
2228 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2229 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2230 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2235 "Display information about all VPNv4/VPNv6 NLRIs\n"
2236 "Detailed information on TCP and BGP neighbor connections\n"
2237 "Neighbor to display information about\n"
2238 "Display the routes advertised to a BGP neighbor\n"
2245 bool uj
= use_json(argc
, argv
);
2249 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2250 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2253 json_object
*json_no
= NULL
;
2254 json_no
= json_object_new_object();
2255 json_object_string_add(json_no
, "warning",
2256 "Malformed address");
2257 vty_out(vty
, "%s\n",
2258 json_object_to_json_string(json_no
));
2259 json_object_free(json_no
);
2261 vty_out(vty
, "Malformed address: %s\n",
2262 argv
[idx_ipv4
]->arg
);
2265 peer
= peer_lookup(NULL
, &su
);
2266 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2268 json_object
*json_no
= NULL
;
2269 json_no
= json_object_new_object();
2270 json_object_string_add(
2272 "No such neighbor or address family");
2273 vty_out(vty
, "%s\n",
2274 json_object_to_json_string(json_no
));
2275 json_object_free(json_no
);
2278 "%% No such neighbor or address family\n");
2281 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2287 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2288 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2289 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2294 "Display information for a route distinguisher\n"
2295 "VPN Route Distinguisher\n"
2296 "Detailed information on TCP and BGP neighbor connections\n"
2297 "Neighbor to display information about\n"
2298 "Display the routes advertised to a BGP neighbor\n"
2301 int idx_ext_community
= 5;
2305 struct prefix_rd prd
;
2307 bool uj
= use_json(argc
, argv
);
2311 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2312 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2315 json_object
*json_no
= NULL
;
2316 json_no
= json_object_new_object();
2317 json_object_string_add(json_no
, "warning",
2318 "Malformed address");
2319 vty_out(vty
, "%s\n",
2320 json_object_to_json_string(json_no
));
2321 json_object_free(json_no
);
2323 vty_out(vty
, "Malformed address: %s\n",
2324 argv
[idx_ext_community
]->arg
);
2327 peer
= peer_lookup(NULL
, &su
);
2328 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2330 json_object
*json_no
= NULL
;
2331 json_no
= json_object_new_object();
2332 json_object_string_add(
2334 "No such neighbor or address family");
2335 vty_out(vty
, "%s\n",
2336 json_object_to_json_string(json_no
));
2337 json_object_free(json_no
);
2340 "%% No such neighbor or address family\n");
2344 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2347 json_object
*json_no
= NULL
;
2348 json_no
= json_object_new_object();
2349 json_object_string_add(
2351 "Malformed Route Distinguisher");
2352 vty_out(vty
, "%s\n",
2353 json_object_to_json_string(json_no
));
2354 json_object_free(json_no
);
2357 "%% Malformed Route Distinguisher\n");
2361 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2366 #endif /* KEEP_OLD_VPN_COMMANDS */
2368 void bgp_mplsvpn_init(void)
2370 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2371 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2372 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2374 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2375 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2377 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2378 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2379 #ifdef KEEP_OLD_VPN_COMMANDS
2380 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2381 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2382 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2383 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2384 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2385 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2386 install_element(VIEW_NODE
,
2387 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2388 install_element(VIEW_NODE
,
2389 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2390 #endif /* KEEP_OLD_VPN_COMMANDS */
2393 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2395 struct listnode
*mnode
, *mnnode
;
2398 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2399 struct ecommunity
*ec
;
2401 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2404 ec
= bgp
->vpn_policy
[AFI_IP
].import_redirect_rtlist
;
2406 if (ecom_intersect(ec
, eckey
))
2413 * The purpose of this function is to process leaks that were deferred
2414 * from earlier per-vrf configuration due to not-yet-existing default
2415 * vrf, in other words, configuration such as:
2417 * router bgp MMM vrf FOO
2418 * address-family ipv4 unicast
2420 * exit-address-family
2425 * This function gets called when the default instance ("router bgp NNN")
2428 void vpn_leak_postchange_all(void)
2430 struct listnode
*next
;
2432 struct bgp
*bgp_default
= bgp_get_default();
2434 assert(bgp_default
);
2436 /* First, do any exporting from VRFs to the single VPN RIB */
2437 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2439 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2442 vpn_leak_postchange(
2443 BGP_VPN_POLICY_DIR_TOVPN
,
2448 vpn_leak_postchange(
2449 BGP_VPN_POLICY_DIR_TOVPN
,
2455 /* Now, do any importing to VRFs from the single VPN RIB */
2456 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2458 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2461 vpn_leak_postchange(
2462 BGP_VPN_POLICY_DIR_FROMVPN
,
2467 vpn_leak_postchange(
2468 BGP_VPN_POLICY_DIR_FROMVPN
,