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"
51 #include "bgpd/rfapi/rfapi_backend.h"
55 * Definitions and external declarations.
57 extern struct zclient
*zclient
;
59 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
60 int *index
, afi_t
*afi
)
63 if (argv_find(argv
, argc
, "vpnv4", index
)) {
67 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
75 uint32_t decode_label(mpls_label_t
*label_pnt
)
78 uint8_t *pnt
= (uint8_t *)label_pnt
;
80 l
= ((uint32_t)*pnt
++ << 12);
81 l
|= (uint32_t)*pnt
++ << 4;
82 l
|= (uint32_t)((*pnt
& 0xf0) >> 4);
86 void encode_label(mpls_label_t label
, mpls_label_t
*label_pnt
)
88 uint8_t *pnt
= (uint8_t *)label_pnt
;
91 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
) {
95 *pnt
++ = (label
>> 12) & 0xff;
96 *pnt
++ = (label
>> 4) & 0xff;
97 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
100 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
101 struct bgp_nlri
*packet
)
111 struct prefix_rd prd
;
112 mpls_label_t label
= {0};
119 prd
.family
= AF_UNSPEC
;
123 lim
= pnt
+ packet
->length
;
129 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
130 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
131 PEER_CAP_ADDPATH_AF_TX_RCV
));
133 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
134 for (; pnt
< lim
; pnt
+= psize
) {
135 /* Clear prefix structure. */
136 memset(&p
, 0, sizeof(struct prefix
));
138 if (addpath_encoded
) {
140 /* When packet overflow occurs return immediately. */
141 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
144 addpath_id
= ntohl(*((uint32_t *)pnt
));
145 pnt
+= BGP_ADDPATH_ID_LEN
;
148 /* Fetch prefix length. */
150 p
.family
= afi2family(packet
->afi
);
151 psize
= PSIZE(prefixlen
);
153 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
156 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
157 peer
->host
, prefixlen
);
161 /* sanity check against packet data */
162 if ((pnt
+ psize
) > lim
) {
165 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
166 peer
->host
, prefixlen
, (uint
)(lim
- pnt
));
170 /* sanity check against storage for the IP address portion */
171 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
174 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
176 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
181 /* Sanity check against max bitlen of the address family */
182 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
185 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
187 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
188 p
.family
, prefix_blen(&p
));
192 /* Copy label to prefix. */
193 memcpy(&label
, pnt
, BGP_LABEL_BYTES
);
194 bgp_set_valid_label(&label
);
196 /* Copy routing distinguisher to rd. */
197 memcpy(&prd
.val
, pnt
+ BGP_LABEL_BYTES
, 8);
199 /* Decode RD type. */
200 type
= decode_rd_type(pnt
+ BGP_LABEL_BYTES
);
204 decode_rd_as(pnt
+ 5, &rd_as
);
208 decode_rd_as4(pnt
+ 5, &rd_as
);
212 decode_rd_ip(pnt
+ 5, &rd_ip
);
216 case RD_TYPE_VNC_ETH
:
221 flog_err(BGP_ERR_UPDATE_RCV
, "Unknown RD type %d",
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
);
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 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
294 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
298 * If zebra tells us vrf has become unconfigured, tell zebra not to
299 * use this label to forward to the vrf anymore
301 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
303 mpls_label_t label
= MPLS_LABEL_NONE
;
304 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
306 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
309 "%s: vrf_id not set, can't delete zebra vrf label",
316 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
317 bgp
->name_pretty
, bgp
->vrf_id
);
320 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
321 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
324 int vpn_leak_label_callback(
329 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
330 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
333 zlog_debug("%s: label=%u, allocated=%d",
334 __func__
, label
, allocated
);
338 * previously-allocated label is now invalid
340 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
341 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
343 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
344 vp
->afi
, bgp_get_default(), vp
->bgp
);
345 vp
->tovpn_label
= MPLS_LABEL_NONE
;
346 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
347 vp
->afi
, bgp_get_default(), vp
->bgp
);
353 * New label allocation
355 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
358 * not currently configured for auto label, reject allocation
363 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
364 if (label
== vp
->tovpn_label
) {
365 /* already have same label, accept but do nothing */
368 /* Shouldn't happen: different label allocation */
369 flog_err(BGP_ERR_LABEL
,
370 "%s: %s had label %u but got new assignment %u",
371 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
376 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
377 vp
->afi
, bgp_get_default(), vp
->bgp
);
378 vp
->tovpn_label
= label
;
379 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
380 vp
->afi
, bgp_get_default(), vp
->bgp
);
385 static int ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
393 for (i
= 0; i
< e1
->size
; ++i
) {
394 for (j
= 0; j
< e2
->size
; ++j
) {
395 if (!memcmp(e1
->val
+ (i
* ECOMMUNITY_SIZE
),
396 e2
->val
+ (j
* ECOMMUNITY_SIZE
),
406 static bool labels_same(struct bgp_info
*bi
, mpls_label_t
*label
, uint32_t n
)
417 if (n
!= bi
->extra
->num_labels
)
420 for (i
= 0; i
< n
; ++i
) {
421 if (label
[i
] != bi
->extra
->label
[i
])
428 * make encoded route labels match specified encoded label set
430 static void setlabels(
432 mpls_label_t
*label
, /* array of labels */
437 assert(num_labels
<= BGP_MAX_LABELS
);
441 bi
->extra
->num_labels
= 0;
445 struct bgp_info_extra
*extra
= bgp_info_extra_get(bi
);
448 for (i
= 0; i
< num_labels
; ++i
) {
449 extra
->label
[i
] = label
[i
];
450 if (!bgp_is_valid_label(&label
[i
])) {
451 bgp_set_valid_label(&extra
->label
[i
]);
454 extra
->num_labels
= num_labels
;
458 * returns pointer to new bgp_info upon success
460 static struct bgp_info
*
462 struct bgp
*bgp
, /* destination bgp instance */
464 struct attr
*new_attr
, /* already interned */
467 struct bgp_info
*source_bi
,
471 struct bgp
*bgp_orig
,
472 struct prefix
*nexthop_orig
,
473 int nexthop_self_flag
,
476 struct prefix
*p
= &bn
->p
;
478 struct bgp_info
*bi_ultimate
;
479 struct bgp_info
*new;
480 char buf_prefix
[PREFIX_STRLEN
];
483 prefix2str(&bn
->p
, buf_prefix
, sizeof(buf_prefix
));
484 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
485 __func__
, bgp
->name_pretty
, buf_prefix
,
486 source_bi
->type
, source_bi
->sub_type
);
490 * Routes that are redistributed into BGP from zebra do not get
491 * nexthop tracking. However, if those routes are subsequently
492 * imported to other RIBs within BGP, the leaked routes do not
493 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
494 * in order to determine if the route we are currently leaking
495 * should have nexthop tracking, we must find the ultimate
496 * parent so we can check its sub_type.
498 * As of now, source_bi may at most be a second-generation route
499 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
500 * Using a loop here supports more complex intra-bgp import-export
501 * schemes that could be implemented in the future.
504 for (bi_ultimate
= source_bi
;
505 bi_ultimate
->extra
&& bi_ultimate
->extra
->parent
;
506 bi_ultimate
= bi_ultimate
->extra
->parent
)
512 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
513 if (bi
->extra
&& bi
->extra
->parent
== parent
)
518 bool labelssame
= labels_same(bi
, label
, num_labels
);
520 if (attrhash_cmp(bi
->attr
, new_attr
)
522 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
524 bgp_attr_unintern(&new_attr
);
527 "%s: ->%s: %s: Found route, no change",
528 __func__
, bgp
->name_pretty
,
533 /* attr is changed */
534 bgp_info_set_flag(bn
, bi
, BGP_INFO_ATTR_CHANGED
);
536 /* Rewrite BGP route information. */
537 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
538 bgp_info_restore(bn
, bi
);
540 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
541 bgp_attr_unintern(&bi
->attr
);
543 bi
->uptime
= bgp_clock();
549 setlabels(bi
, label
, num_labels
);
551 if (nexthop_self_flag
)
552 bgp_info_set_flag(bn
, bi
, BGP_INFO_ANNC_NH_SELF
);
554 struct bgp
*bgp_nexthop
= bgp
;
557 if (bi
->extra
&& bi
->extra
->bgp_orig
)
558 bgp_nexthop
= bi
->extra
->bgp_orig
;
560 /* No nexthop tracking for redistributed routes */
561 if (bi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
565 * TBD do we need to do anything about the
566 * 'connected' parameter?
568 nh_valid
= bgp_find_or_add_nexthop(
573 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
574 __func__
, (nh_valid
? "" : "not "),
575 bgp_nexthop
->name_pretty
);
578 bgp_info_set_flag(bn
, bi
, BGP_INFO_VALID
);
580 /* Process change. */
581 bgp_aggregate_increment(bgp
, p
, bi
, afi
, safi
);
582 bgp_process(bgp
, bn
, afi
, safi
);
586 zlog_debug("%s: ->%s: %s Found route, changed attr",
587 __func__
, bgp
->name_pretty
, buf_prefix
);
592 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
593 bgp
->peer_self
, new_attr
, bn
);
595 if (nexthop_self_flag
)
596 bgp_info_set_flag(bn
, new, BGP_INFO_ANNC_NH_SELF
);
598 bgp_info_extra_get(new);
601 setlabels(new, label
, num_labels
);
603 new->extra
->parent
= bgp_info_lock(parent
);
604 bgp_lock_node((struct bgp_node
*)((struct bgp_info
*)parent
)->net
);
606 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
608 new->extra
->nexthop_orig
= *nexthop_orig
;
611 * nexthop tracking for unicast routes
613 struct bgp
*bgp_nexthop
= bgp
;
616 if (new->extra
->bgp_orig
)
617 bgp_nexthop
= new->extra
->bgp_orig
;
620 * No nexthop tracking for redistributed routes because
621 * their originating protocols will do the tracking and
622 * withdraw those routes if the nexthops become unreachable
624 if (bi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
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_info_set_flag(bn
, new, BGP_INFO_VALID
);
641 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
642 bgp_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_info
*info_vrf
) /* route */
659 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
660 struct prefix
*p
= &info_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
&& info_vrf
->attr
->ecommunity
) {
675 char *s
= ecommunity_ecom2str(info_vrf
->attr
->ecommunity
,
676 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
678 zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__
,
679 bgp_vrf
->name
, info_vrf
->type
, s
);
680 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
688 zlog_debug("%s: can't get afi of prefix", __func__
);
692 /* loop check - should not be an imported route. */
693 if (info_vrf
->extra
&& info_vrf
->extra
->bgp_orig
)
697 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
699 zlog_debug("%s: %s skipping: %s", __func__
,
700 bgp_vrf
->name
, debugmsg
);
704 bgp_attr_dup(&static_attr
, info_vrf
->attr
); /* shallow copy */
709 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
710 struct bgp_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
= 4;
790 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
791 static_attr
.mp_nexthop_len
= 16;
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
= 4;
809 * XXX Leave static_attr.nexthop
813 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
816 /* Update based on next-hop family to account for
817 * RFC 5549 (BGP unnumbered) scenario. Note that
818 * specific action is only needed for the case of
819 * IPv4 nexthops as the attr has been copied
823 !BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf
->attr
)) {
824 static_attr
.mp_nexthop_global_in
.s_addr
=
825 static_attr
.nexthop
.s_addr
;
826 static_attr
.mp_nexthop_len
= 4;
828 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
831 nexthop_self_flag
= 1;
834 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
835 if (label_val
== MPLS_LABEL_NONE
) {
836 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
838 encode_label(label_val
, &label
);
841 /* Set originator ID to "me" */
842 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
843 static_attr
.originator_id
= bgp_vpn
->router_id
;
846 new_attr
= bgp_attr_intern(
847 &static_attr
); /* hashed refcounted everything */
848 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
850 if (debug
&& new_attr
->ecommunity
) {
851 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
852 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
854 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
855 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
858 /* Now new_attr is an allocated interned attr */
860 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
861 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
863 struct bgp_info
*new_info
;
865 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, info_vrf
,
866 &label
, 1, info_vrf
, bgp_vrf
, NULL
,
867 nexthop_self_flag
, debug
);
870 * Routes actually installed in the vpn RIB must also be
871 * offered to all vrfs (because now they originate from
874 * Acceptance into other vrfs depends on rt-lists.
875 * Originating vrf will not accept the looped back route
876 * because of loop checking.
879 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
882 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
883 struct bgp
*bgp_vrf
, /* from */
884 struct bgp_info
*info_vrf
) /* route */
886 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
887 struct prefix
*p
= &info_vrf
->net
->p
;
888 afi_t afi
= family2afi(p
->family
);
889 safi_t safi
= SAFI_MPLS_VPN
;
892 const char *debugmsg
;
893 char buf_prefix
[PREFIX_STRLEN
];
896 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
898 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
899 __func__
, bgp_vrf
->name_pretty
, buf_prefix
,
900 info_vrf
->type
, info_vrf
->sub_type
);
903 if (info_vrf
->sub_type
!= BGP_ROUTE_NORMAL
904 && info_vrf
->sub_type
!= BGP_ROUTE_STATIC
905 && info_vrf
->sub_type
!= BGP_ROUTE_REDISTRIBUTE
) {
908 zlog_debug("%s: wrong sub_type %d", __func__
,
917 zlog_debug("%s: can't get afi of prefix", __func__
);
921 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
923 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
928 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__
, info_vrf
);
930 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
931 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
935 * match original bi imported from
937 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
938 if (bi
->extra
&& bi
->extra
->parent
== info_vrf
) {
944 /* withdraw from looped vrfs as well */
945 vpn_leak_to_vrf_withdraw(bgp_vpn
, bi
);
947 bgp_aggregate_decrement(bgp_vpn
, p
, bi
, afi
, safi
);
948 bgp_info_delete(bn
, bi
);
949 bgp_process(bgp_vpn
, bn
, afi
, safi
);
954 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
955 struct bgp
*bgp_vrf
, /* from */
958 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
959 struct bgp_node
*prn
;
960 safi_t safi
= SAFI_MPLS_VPN
;
963 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
965 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
966 prn
= bgp_route_next(prn
)) {
968 struct bgp_table
*table
;
972 /* This is the per-RD table of prefixes */
978 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
980 char buf
[PREFIX2STR_BUFFER
];
982 if (debug
&& bn
->info
) {
984 "%s: looking at prefix %s", __func__
,
985 prefix2str(&bn
->p
, buf
, sizeof(buf
)));
988 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
990 zlog_debug("%s: type %d, sub_type %d",
993 if (bi
->sub_type
!= BGP_ROUTE_IMPORTED
)
997 if ((struct bgp
*)bi
->extra
->bgp_orig
1001 zlog_debug("%s: deleting it\n",
1003 bgp_aggregate_decrement(bgp_vpn
, &bn
->p
,
1005 bgp_info_delete(bn
, bi
);
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_info
*bi
;
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 (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1034 "%s: calling vpn_leak_from_vrf_update",
1036 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bi
);
1041 static void vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1042 struct bgp
*bgp_vpn
, /* from */
1043 struct bgp_info
*info_vpn
) /* route */
1045 struct prefix
*p
= &info_vpn
->net
->p
;
1046 afi_t afi
= family2afi(p
->family
);
1048 struct attr static_attr
= {0};
1049 struct attr
*new_attr
= NULL
;
1050 struct bgp_node
*bn
;
1051 safi_t safi
= SAFI_UNICAST
;
1052 const char *debugmsg
;
1053 struct prefix nexthop_orig
;
1054 mpls_label_t
*pLabels
= NULL
;
1055 uint32_t num_labels
= 0;
1056 int nexthop_self_flag
= 1;
1057 struct bgp_info
*bi_ultimate
= NULL
;
1058 int origin_local
= 0;
1059 struct bgp
*src_vrf
;
1061 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1063 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1065 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1069 /* Check for intersection of route targets */
1070 if (!ecom_intersect(
1071 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1072 info_vpn
->attr
->ecommunity
)) {
1078 zlog_debug("%s: updating to vrf %s", __func__
,
1079 bgp_vrf
->name_pretty
);
1081 bgp_attr_dup(&static_attr
, info_vpn
->attr
); /* shallow copy */
1084 * Nexthop: stash and clear
1086 * Nexthop is valid in context of VPN core, but not in destination vrf.
1087 * Stash it for later label resolution by vrf ingress path and then
1088 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1090 uint8_t nhfamily
= NEXTHOP_FAMILY(info_vpn
->attr
->mp_nexthop_len
);
1092 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1093 nexthop_orig
.family
= nhfamily
;
1098 nexthop_orig
.u
.prefix4
= info_vpn
->attr
->mp_nexthop_global_in
;
1099 nexthop_orig
.prefixlen
= 32;
1101 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1102 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1103 static_attr
.nexthop
.s_addr
=
1104 nexthop_orig
.u
.prefix4
.s_addr
;
1106 static_attr
.mp_nexthop_global_in
=
1107 info_vpn
->attr
->mp_nexthop_global_in
;
1108 static_attr
.mp_nexthop_len
=
1109 info_vpn
->attr
->mp_nexthop_len
;
1111 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1115 nexthop_orig
.u
.prefix6
= info_vpn
->attr
->mp_nexthop_global
;
1116 nexthop_orig
.prefixlen
= 128;
1118 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1119 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1120 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1126 * route map handling
1128 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1129 struct bgp_info info
;
1130 route_map_result_t ret
;
1132 memset(&info
, 0, sizeof(info
));
1133 info
.peer
= bgp_vrf
->peer_self
;
1134 info
.attr
= &static_attr
;
1135 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1136 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1137 p
, RMAP_BGP
, &info
);
1138 if (RMAP_DENYMATCH
== ret
) {
1139 bgp_attr_flush(&static_attr
); /* free any added parts */
1142 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1143 __func__
, bgp_vrf
->name_pretty
,
1144 bgp_vrf
->vpn_policy
[afi
]
1145 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1150 * if route-map changed nexthop, don't nexthop-self on output
1152 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1153 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1154 nexthop_self_flag
= 0;
1157 new_attr
= bgp_attr_intern(&static_attr
);
1158 bgp_attr_flush(&static_attr
);
1160 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1163 * ensure labels are copied
1165 * However, there is a special case: if the route originated in
1166 * another local VRF (as opposed to arriving via VPN), then the
1167 * nexthop is reached by hairpinning through this router (me)
1168 * using IP forwarding only (no LSP). Therefore, the route
1169 * imported to the VRF should not have labels attached. Note
1170 * that nexthop tracking is also involved: eliminating the
1171 * labels for these routes enables the non-labeled nexthops
1172 * from the originating VRF to be considered valid for this route.
1174 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1175 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1176 /* work back to original route */
1177 for (bi_ultimate
= info_vpn
;
1178 bi_ultimate
->extra
&& bi_ultimate
->extra
->parent
;
1179 bi_ultimate
= bi_ultimate
->extra
->parent
)
1183 * if original route was unicast,
1184 * then it did not arrive over vpn
1186 if (bi_ultimate
->net
) {
1187 struct bgp_table
*table
;
1189 table
= bgp_node_table(bi_ultimate
->net
);
1190 if (table
&& (table
->safi
== SAFI_UNICAST
))
1195 if (!origin_local
&&
1196 info_vpn
->extra
&& info_vpn
->extra
->num_labels
) {
1197 num_labels
= info_vpn
->extra
->num_labels
;
1198 if (num_labels
> BGP_MAX_LABELS
)
1199 num_labels
= BGP_MAX_LABELS
;
1200 pLabels
= info_vpn
->extra
->label
;
1205 char buf_prefix
[PREFIX_STRLEN
];
1206 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
1207 zlog_debug("%s: pfx %s: num_labels %d", __func__
, buf_prefix
,
1212 * For VRF-2-VRF route-leaking,
1213 * the source will be the originating VRF.
1215 if (info_vpn
->extra
&& info_vpn
->extra
->bgp_orig
)
1216 src_vrf
= info_vpn
->extra
->bgp_orig
;
1220 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, info_vpn
,
1221 pLabels
, num_labels
,
1222 info_vpn
, /* parent */
1223 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1226 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1227 struct bgp_info
*info_vpn
) /* route */
1229 struct listnode
*mnode
, *mnnode
;
1232 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1235 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1237 /* Loop over VRFs */
1238 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1240 if (!info_vpn
->extra
1241 || info_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1242 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, info_vpn
);
1247 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1248 struct bgp_info
*info_vpn
) /* route */
1252 safi_t safi
= SAFI_UNICAST
;
1254 struct listnode
*mnode
, *mnnode
;
1255 struct bgp_node
*bn
;
1256 struct bgp_info
*bi
;
1257 const char *debugmsg
;
1258 char buf_prefix
[PREFIX_STRLEN
];
1260 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1263 prefix2str(&info_vpn
->net
->p
, buf_prefix
, sizeof(buf_prefix
));
1264 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1265 __func__
, buf_prefix
,
1266 info_vpn
->type
, info_vpn
->sub_type
);
1270 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1272 if (!info_vpn
->net
) {
1274 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1275 if (info_vpn
->type
== ZEBRA_ROUTE_BGP
&&
1276 info_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1282 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1287 p
= &info_vpn
->net
->p
;
1288 afi
= family2afi(p
->family
);
1290 /* Loop over VRFs */
1291 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1292 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1294 zlog_debug("%s: skipping: %s", __func__
,
1299 /* Check for intersection of route targets */
1300 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1301 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1302 info_vpn
->attr
->ecommunity
)) {
1308 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1311 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1312 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
1314 && (struct bgp_info
*)bi
->extra
->parent
1322 zlog_debug("%s: deleting bi %p", __func__
, bi
);
1323 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
1324 bgp_info_delete(bn
, bi
);
1325 bgp_process(bgp
, bn
, afi
, safi
);
1327 bgp_unlock_node(bn
);
1331 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1334 struct bgp_node
*bn
;
1335 struct bgp_info
*bi
;
1336 safi_t safi
= SAFI_UNICAST
;
1337 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1340 zlog_debug("%s: entry", __func__
);
1342 * Walk vrf table, delete bi with bgp_orig in a different vrf
1344 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1345 bn
= bgp_route_next(bn
)) {
1347 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1348 if (bi
->extra
&& bi
->extra
->bgp_orig
!= bgp_vrf
) {
1351 bgp_aggregate_decrement(bgp_vrf
, &bn
->p
, bi
,
1353 bgp_info_delete(bn
, bi
);
1354 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1360 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1361 struct bgp
*bgp_vpn
, /* from */
1364 struct prefix_rd prd
;
1365 struct bgp_node
*prn
;
1366 safi_t safi
= SAFI_MPLS_VPN
;
1373 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
1374 prn
= bgp_route_next(prn
)) {
1376 struct bgp_table
*table
;
1377 struct bgp_node
*bn
;
1378 struct bgp_info
*bi
;
1380 memset(&prd
, 0, sizeof(prd
));
1381 prd
.family
= AF_UNSPEC
;
1383 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
1385 /* This is the per-RD table of prefixes */
1391 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1393 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1395 if (bi
->extra
&& bi
->extra
->bgp_orig
== bgp_vrf
)
1398 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1406 * This function is called for definition/deletion/change to a route-map
1408 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1410 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1412 struct route_map
*rmap
;
1414 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1415 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1420 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1422 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1424 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1425 && !strcmp(rmap_name
,
1426 bgp
->vpn_policy
[afi
]
1427 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1431 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1432 __func__
, rmap_name
, bgp
->as
,
1435 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1436 bgp_get_default(), bgp
);
1438 zlog_debug("%s: after vpn_leak_prechange",
1441 /* in case of definition/deletion */
1442 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1445 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1446 bgp_get_default(), bgp
);
1449 zlog_debug("%s: after vpn_leak_postchange",
1453 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1454 && !strcmp(rmap_name
,
1455 bgp
->vpn_policy
[afi
]
1456 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1459 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1460 __func__
, rmap_name
, bgp
->as
,
1464 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1465 bgp_get_default(), bgp
);
1467 /* in case of definition/deletion */
1468 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1471 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1472 bgp_get_default(), bgp
);
1477 void vpn_policy_routemap_event(const char *rmap_name
)
1479 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1480 struct listnode
*mnode
, *mnnode
;
1484 zlog_debug("%s: entry", __func__
);
1486 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1489 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1490 vpn_policy_routemap_update(bgp
, rmap_name
);
1493 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1494 afi_t afi
, safi_t safi
)
1496 const char *export_name
;
1497 vpn_policy_direction_t idir
, edir
;
1500 struct ecommunity
*ecom
;
1501 bool first_export
= false;
1503 export_name
= to_bgp
->name
? to_bgp
->name
: BGP_DEFAULT_NAME
;
1504 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1505 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1508 * Cross-ref both VRFs. Also, note if this is the first time
1509 * any VRF is importing from "import_vrf".
1511 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
1512 : XSTRDUP(MTYPE_TMP
, BGP_DEFAULT_NAME
));
1514 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1516 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
))
1517 first_export
= true;
1518 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
1519 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1521 /* Update import RT for current VRF using export RT of the VRF we're
1522 * importing from. First though, make sure "import_vrf" has that
1526 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
1527 &from_bgp
->vrf_prd_auto
);
1528 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
1529 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1530 BGP_VPN_POLICY_TOVPN_RD_SET
);
1531 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
1533 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1534 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
1535 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1536 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1537 from_bgp
->vpn_policy
[afi
].tovpn_label
=
1538 BGP_PREVENT_VRF_2_VRF_LEAK
;
1540 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1541 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
1542 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
1543 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
1544 .rtlist
[idir
], ecom
);
1546 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
1547 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1549 /* Does "import_vrf" first need to export its routes or that
1550 * is already done and we just need to import those routes
1551 * from the global table?
1554 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
1556 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1559 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1560 afi_t afi
, safi_t safi
)
1562 const char *export_name
, *tmp_name
;
1563 vpn_policy_direction_t idir
, edir
;
1565 struct ecommunity
*ecom
;
1566 struct listnode
*node
;
1568 export_name
= to_bgp
->name
? to_bgp
->name
: BGP_DEFAULT_NAME
;
1569 tmp_name
= from_bgp
->name
? from_bgp
->name
: BGP_DEFAULT_NAME
;
1570 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1571 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1573 /* Were we importing from "import_vrf"? */
1574 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
1576 if (strcmp(vname
, tmp_name
) == 0)
1581 * We do not check in the cli if the passed in bgp
1582 * instance is actually imported into us before
1583 * we call this function. As such if we do not
1584 * find this in the import_vrf list than
1585 * we just need to return safely.
1590 /* Remove "import_vrf" from our import list. */
1591 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1592 XFREE(MTYPE_TMP
, vname
);
1594 /* Remove routes imported from "import_vrf". */
1595 /* TODO: In the current logic, we have to first remove all
1596 * imported routes and then (if needed) import back routes
1598 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
1600 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
1601 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
1602 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1603 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
1605 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1606 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
1607 (struct ecommunity_val
*)ecom
->val
);
1608 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1613 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1614 * below is checking for NULL that export_vrf can be
1615 * NULL, consequently it is complaining( like a cabbage )
1616 * that we could dereference and crash in the listcount(..)
1618 * So make it happy, under protest, with liberty and justice
1621 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
1623 /* Remove us from "import_vrf's" export list. If no other VRF
1624 * is importing from "import_vrf", cleanup appropriately.
1626 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1628 if (strcmp(vname
, export_name
) == 0)
1633 * If we have gotten to this point then the vname must
1634 * exist. If not, we are in a world of trouble and
1635 * have slag sitting around.
1637 * import_vrf and export_vrf must match in having
1638 * the in/out names as appropriate.
1642 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1643 XFREE(MTYPE_TMP
, vname
);
1645 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1646 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
1647 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
1648 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1649 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1650 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
1651 sizeof(struct prefix_rd
));
1652 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1653 BGP_VPN_POLICY_TOVPN_RD_SET
);
1654 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
1659 /* For testing purpose, static route of MPLS-VPN. */
1660 DEFUN (vpnv4_network
,
1662 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1663 "Specify a network to announce via BGP\n"
1665 "Specify Route Distinguisher\n"
1666 "VPN Route Distinguisher\n"
1667 "VPN NLRI label (tag)\n"
1668 "VPN NLRI label (tag)\n"
1671 int idx_ipv4_prefixlen
= 1;
1672 int idx_ext_community
= 3;
1674 return bgp_static_set_safi(
1675 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1676 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1677 NULL
, NULL
, NULL
, NULL
);
1680 DEFUN (vpnv4_network_route_map
,
1681 vpnv4_network_route_map_cmd
,
1682 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1683 "Specify a network to announce via BGP\n"
1685 "Specify Route Distinguisher\n"
1686 "VPN Route Distinguisher\n"
1687 "VPN NLRI label (tag)\n"
1688 "VPN NLRI label (tag)\n"
1693 int idx_ipv4_prefixlen
= 1;
1694 int idx_ext_community
= 3;
1697 return bgp_static_set_safi(
1698 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1699 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1700 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1703 /* For testing purpose, static route of MPLS-VPN. */
1704 DEFUN (no_vpnv4_network
,
1705 no_vpnv4_network_cmd
,
1706 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1708 "Specify a network to announce via BGP\n"
1710 "Specify Route Distinguisher\n"
1711 "VPN Route Distinguisher\n"
1712 "VPN NLRI label (tag)\n"
1713 "VPN NLRI label (tag)\n"
1716 int idx_ipv4_prefixlen
= 2;
1717 int idx_ext_community
= 4;
1719 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1720 argv
[idx_ipv4_prefixlen
]->arg
,
1721 argv
[idx_ext_community
]->arg
,
1722 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1725 DEFUN (vpnv6_network
,
1727 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1728 "Specify a network to announce via BGP\n"
1729 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1730 "Specify Route Distinguisher\n"
1731 "VPN Route Distinguisher\n"
1732 "VPN NLRI label (tag)\n"
1733 "VPN NLRI label (tag)\n"
1738 int idx_ipv6_prefix
= 1;
1739 int idx_ext_community
= 3;
1743 return bgp_static_set_safi(
1744 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1745 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1746 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1748 return bgp_static_set_safi(
1749 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1750 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1751 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1754 /* For testing purpose, static route of MPLS-VPN. */
1755 DEFUN (no_vpnv6_network
,
1756 no_vpnv6_network_cmd
,
1757 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1759 "Specify a network to announce via BGP\n"
1760 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1761 "Specify Route Distinguisher\n"
1762 "VPN Route Distinguisher\n"
1763 "VPN NLRI label (tag)\n"
1764 "VPN NLRI label (tag)\n"
1767 int idx_ipv6_prefix
= 2;
1768 int idx_ext_community
= 4;
1770 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
1771 argv
[idx_ipv6_prefix
]->arg
,
1772 argv
[idx_ext_community
]->arg
,
1773 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1776 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
1777 enum bgp_show_type type
, void *output_arg
, int tags
,
1781 struct bgp_table
*table
;
1783 bgp
= bgp_get_default();
1786 vty_out(vty
, "No BGP process is configured\n");
1788 vty_out(vty
, "{}\n");
1791 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
1792 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
1793 output_arg
, use_json
);
1796 DEFUN (show_bgp_ip_vpn_all_rd
,
1797 show_bgp_ip_vpn_all_rd_cmd
,
1798 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1802 "Display VPN NLRI specific information\n"
1803 "Display VPN NLRI specific information\n"
1804 "Display information for a route distinguisher\n"
1805 "VPN Route Distinguisher\n"
1809 struct prefix_rd prd
;
1813 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1814 if (argv_find(argv
, argc
, "rd", &idx
)) {
1815 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
1818 "%% Malformed Route Distinguisher\n");
1821 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
1822 bgp_show_type_normal
, NULL
, 0,
1823 use_json(argc
, argv
));
1825 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
1826 bgp_show_type_normal
, NULL
, 0,
1827 use_json(argc
, argv
));
1833 ALIAS(show_bgp_ip_vpn_all_rd
,
1834 show_bgp_ip_vpn_rd_cmd
,
1835 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1839 "Display VPN NLRI specific information\n"
1840 "Display information for a route distinguisher\n"
1841 "VPN Route Distinguisher\n"
1844 #ifdef KEEP_OLD_VPN_COMMANDS
1845 DEFUN (show_ip_bgp_vpn_rd
,
1846 show_ip_bgp_vpn_rd_cmd
,
1847 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
1852 "Address Family modifier\n"
1853 "Display information for a route distinguisher\n"
1854 "VPN Route Distinguisher\n")
1856 int idx_ext_community
= argc
- 1;
1858 struct prefix_rd prd
;
1862 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1863 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1865 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1868 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1874 DEFUN (show_ip_bgp_vpn_all
,
1875 show_ip_bgp_vpn_all_cmd
,
1876 "show [ip] bgp <vpnv4|vpnv6>",
1885 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1886 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1891 DEFUN (show_ip_bgp_vpn_all_tags
,
1892 show_ip_bgp_vpn_all_tags_cmd
,
1893 "show [ip] bgp <vpnv4|vpnv6> all tags",
1898 "Display information about all VPNv4/VPNV6 NLRIs\n"
1899 "Display BGP tags for prefixes\n")
1904 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1905 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1910 DEFUN (show_ip_bgp_vpn_rd_tags
,
1911 show_ip_bgp_vpn_rd_tags_cmd
,
1912 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
1917 "Display information for a route distinguisher\n"
1918 "VPN Route Distinguisher\n"
1919 "Display BGP tags for prefixes\n")
1921 int idx_ext_community
= 5;
1923 struct prefix_rd prd
;
1927 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1928 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1930 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1933 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1939 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1940 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1941 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1946 "Display information about all VPNv4/VPNv6 NLRIs\n"
1947 "Detailed information on TCP and BGP neighbor connections\n"
1948 "Neighbor to display information about\n"
1949 "Display routes learned from neighbor\n"
1956 uint8_t uj
= use_json(argc
, argv
);
1960 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1961 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1964 json_object
*json_no
= NULL
;
1965 json_no
= json_object_new_object();
1966 json_object_string_add(json_no
, "warning",
1967 "Malformed address");
1968 vty_out(vty
, "%s\n",
1969 json_object_to_json_string(json_no
));
1970 json_object_free(json_no
);
1972 vty_out(vty
, "Malformed address: %s\n",
1973 argv
[idx_ipv4
]->arg
);
1977 peer
= peer_lookup(NULL
, &su
);
1978 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1980 json_object
*json_no
= NULL
;
1981 json_no
= json_object_new_object();
1982 json_object_string_add(
1984 "No such neighbor or address family");
1985 vty_out(vty
, "%s\n",
1986 json_object_to_json_string(json_no
));
1987 json_object_free(json_no
);
1990 "%% No such neighbor or address family\n");
1994 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2000 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2001 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2002 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
2007 "Display information for a route distinguisher\n"
2008 "VPN Route Distinguisher\n"
2009 "Detailed information on TCP and BGP neighbor connections\n"
2010 "Neighbor to display information about\n"
2011 "Display routes learned from neighbor\n"
2014 int idx_ext_community
= 5;
2019 struct prefix_rd prd
;
2020 uint8_t uj
= use_json(argc
, argv
);
2024 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2025 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2028 json_object
*json_no
= NULL
;
2029 json_no
= json_object_new_object();
2030 json_object_string_add(
2032 "Malformed Route Distinguisher");
2033 vty_out(vty
, "%s\n",
2034 json_object_to_json_string(json_no
));
2035 json_object_free(json_no
);
2038 "%% Malformed Route Distinguisher\n");
2042 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2045 json_object
*json_no
= NULL
;
2046 json_no
= json_object_new_object();
2047 json_object_string_add(json_no
, "warning",
2048 "Malformed address");
2049 vty_out(vty
, "%s\n",
2050 json_object_to_json_string(json_no
));
2051 json_object_free(json_no
);
2053 vty_out(vty
, "Malformed address: %s\n",
2054 argv
[idx_ext_community
]->arg
);
2058 peer
= peer_lookup(NULL
, &su
);
2059 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2061 json_object
*json_no
= NULL
;
2062 json_no
= json_object_new_object();
2063 json_object_string_add(
2065 "No such neighbor or address family");
2066 vty_out(vty
, "%s\n",
2067 json_object_to_json_string(json_no
));
2068 json_object_free(json_no
);
2071 "%% No such neighbor or address family\n");
2075 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
2081 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2082 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2083 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2088 "Display information about all VPNv4/VPNv6 NLRIs\n"
2089 "Detailed information on TCP and BGP neighbor connections\n"
2090 "Neighbor to display information about\n"
2091 "Display the routes advertised to a BGP neighbor\n"
2098 uint8_t uj
= use_json(argc
, argv
);
2102 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2103 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2106 json_object
*json_no
= NULL
;
2107 json_no
= json_object_new_object();
2108 json_object_string_add(json_no
, "warning",
2109 "Malformed address");
2110 vty_out(vty
, "%s\n",
2111 json_object_to_json_string(json_no
));
2112 json_object_free(json_no
);
2114 vty_out(vty
, "Malformed address: %s\n",
2115 argv
[idx_ipv4
]->arg
);
2118 peer
= peer_lookup(NULL
, &su
);
2119 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2121 json_object
*json_no
= NULL
;
2122 json_no
= json_object_new_object();
2123 json_object_string_add(
2125 "No such neighbor or address family");
2126 vty_out(vty
, "%s\n",
2127 json_object_to_json_string(json_no
));
2128 json_object_free(json_no
);
2131 "%% No such neighbor or address family\n");
2134 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2140 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2141 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2142 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2147 "Display information for a route distinguisher\n"
2148 "VPN Route Distinguisher\n"
2149 "Detailed information on TCP and BGP neighbor connections\n"
2150 "Neighbor to display information about\n"
2151 "Display the routes advertised to a BGP neighbor\n"
2154 int idx_ext_community
= 5;
2158 struct prefix_rd prd
;
2160 uint8_t uj
= use_json(argc
, argv
);
2164 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2165 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2168 json_object
*json_no
= NULL
;
2169 json_no
= json_object_new_object();
2170 json_object_string_add(json_no
, "warning",
2171 "Malformed address");
2172 vty_out(vty
, "%s\n",
2173 json_object_to_json_string(json_no
));
2174 json_object_free(json_no
);
2176 vty_out(vty
, "Malformed address: %s\n",
2177 argv
[idx_ext_community
]->arg
);
2180 peer
= peer_lookup(NULL
, &su
);
2181 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2183 json_object
*json_no
= NULL
;
2184 json_no
= json_object_new_object();
2185 json_object_string_add(
2187 "No such neighbor or address family");
2188 vty_out(vty
, "%s\n",
2189 json_object_to_json_string(json_no
));
2190 json_object_free(json_no
);
2193 "%% No such neighbor or address family\n");
2197 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2200 json_object
*json_no
= NULL
;
2201 json_no
= json_object_new_object();
2202 json_object_string_add(
2204 "Malformed Route Distinguisher");
2205 vty_out(vty
, "%s\n",
2206 json_object_to_json_string(json_no
));
2207 json_object_free(json_no
);
2210 "%% Malformed Route Distinguisher\n");
2214 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2219 #endif /* KEEP_OLD_VPN_COMMANDS */
2221 void bgp_mplsvpn_init(void)
2223 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2224 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2225 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2227 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2228 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2230 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2231 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2232 #ifdef KEEP_OLD_VPN_COMMANDS
2233 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2234 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2235 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2236 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2237 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2238 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2239 install_element(VIEW_NODE
,
2240 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2241 install_element(VIEW_NODE
,
2242 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2243 #endif /* KEEP_OLD_VPN_COMMANDS */
2246 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2248 struct listnode
*mnode
, *mnnode
;
2251 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2252 struct ecommunity
*ec
;
2254 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2257 ec
= bgp
->vpn_policy
[AFI_IP
].import_redirect_rtlist
;
2259 if (ecom_intersect(ec
, eckey
))
2266 * The purpose of this function is to process leaks that were deferred
2267 * from earlier per-vrf configuration due to not-yet-existing default
2268 * vrf, in other words, configuration such as:
2270 * router bgp MMM vrf FOO
2271 * address-family ipv4 unicast
2273 * exit-address-family
2278 * This function gets called when the default instance ("router bgp NNN")
2281 void vpn_leak_postchange_all(void)
2283 struct listnode
*next
;
2285 struct bgp
*bgp_default
= bgp_get_default();
2287 assert(bgp_default
);
2289 /* First, do any exporting from VRFs to the single VPN RIB */
2290 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2292 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2295 vpn_leak_postchange(
2296 BGP_VPN_POLICY_DIR_TOVPN
,
2301 vpn_leak_postchange(
2302 BGP_VPN_POLICY_DIR_TOVPN
,
2308 /* Now, do any importing to VRFs from the single VPN RIB */
2309 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2311 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2314 vpn_leak_postchange(
2315 BGP_VPN_POLICY_DIR_FROMVPN
,
2320 vpn_leak_postchange(
2321 BGP_VPN_POLICY_DIR_FROMVPN
,