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(EC_BGP_UPDATE_RCV
, "Unknown RD type %d", type
);
222 break; /* just report */
227 - VPN_PREFIXLEN_MIN_BYTES
* 8; /* exclude label & RD */
228 memcpy(p
.u
.val
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
229 psize
- VPN_PREFIXLEN_MIN_BYTES
);
232 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
233 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
234 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
236 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
237 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
238 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
241 /* Packet length consistency check. */
245 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
246 peer
->host
, lim
- pnt
);
251 #undef VPN_PREFIXLEN_MIN_BYTES
255 * This function informs zebra of the label this vrf sets on routes
256 * leaked to VPN. Zebra should install this label in the kernel with
257 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
259 * Sending this vrf-label association is qualified by a) whether vrf->vpn
260 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
261 * are set) and b) whether vpn-policy label is set.
263 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
264 * for this vrf, which zebra interprets to mean "delete this vrf-label
267 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
269 mpls_label_t label
= MPLS_LABEL_NONE
;
270 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
272 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
275 "%s: vrf %s: afi %s: vrf_id not set, "
276 "can't set zebra vrf label",
277 __func__
, bgp
->name_pretty
, afi2str(afi
));
282 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
283 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
287 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
288 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
292 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
293 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
297 * If zebra tells us vrf has become unconfigured, tell zebra not to
298 * use this label to forward to the vrf anymore
300 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
302 mpls_label_t label
= MPLS_LABEL_NONE
;
303 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
305 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
308 "%s: vrf_id not set, can't delete zebra vrf label",
315 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
316 bgp
->name_pretty
, bgp
->vrf_id
);
319 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
320 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
323 int vpn_leak_label_callback(
328 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
329 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
332 zlog_debug("%s: label=%u, allocated=%d",
333 __func__
, label
, allocated
);
337 * previously-allocated label is now invalid
339 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
340 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
342 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
343 vp
->afi
, bgp_get_default(), vp
->bgp
);
344 vp
->tovpn_label
= MPLS_LABEL_NONE
;
345 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
346 vp
->afi
, bgp_get_default(), vp
->bgp
);
352 * New label allocation
354 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
357 * not currently configured for auto label, reject allocation
362 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
363 if (label
== vp
->tovpn_label
) {
364 /* already have same label, accept but do nothing */
367 /* Shouldn't happen: different label allocation */
368 flog_err(EC_BGP_LABEL
,
369 "%s: %s had label %u but got new assignment %u",
370 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
375 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
376 vp
->afi
, bgp_get_default(), vp
->bgp
);
377 vp
->tovpn_label
= label
;
378 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
379 vp
->afi
, bgp_get_default(), vp
->bgp
);
384 static int ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
392 for (i
= 0; i
< e1
->size
; ++i
) {
393 for (j
= 0; j
< e2
->size
; ++j
) {
394 if (!memcmp(e1
->val
+ (i
* ECOMMUNITY_SIZE
),
395 e2
->val
+ (j
* ECOMMUNITY_SIZE
),
405 static bool labels_same(struct bgp_info
*bi
, mpls_label_t
*label
, uint32_t n
)
416 if (n
!= bi
->extra
->num_labels
)
419 for (i
= 0; i
< n
; ++i
) {
420 if (label
[i
] != bi
->extra
->label
[i
])
427 * make encoded route labels match specified encoded label set
429 static void setlabels(
431 mpls_label_t
*label
, /* array of labels */
436 assert(num_labels
<= BGP_MAX_LABELS
);
440 bi
->extra
->num_labels
= 0;
444 struct bgp_info_extra
*extra
= bgp_info_extra_get(bi
);
447 for (i
= 0; i
< num_labels
; ++i
) {
448 extra
->label
[i
] = label
[i
];
449 if (!bgp_is_valid_label(&label
[i
])) {
450 bgp_set_valid_label(&extra
->label
[i
]);
453 extra
->num_labels
= num_labels
;
457 * returns pointer to new bgp_info upon success
459 static struct bgp_info
*
461 struct bgp
*bgp
, /* destination bgp instance */
463 struct attr
*new_attr
, /* already interned */
466 struct bgp_info
*source_bi
,
470 struct bgp
*bgp_orig
,
471 struct prefix
*nexthop_orig
,
472 int nexthop_self_flag
,
475 struct prefix
*p
= &bn
->p
;
477 struct bgp_info
*bi_ultimate
;
478 struct bgp_info
*new;
479 char buf_prefix
[PREFIX_STRLEN
];
482 prefix2str(&bn
->p
, buf_prefix
, sizeof(buf_prefix
));
483 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
484 __func__
, bgp
->name_pretty
, buf_prefix
,
485 source_bi
->type
, source_bi
->sub_type
);
489 * Routes that are redistributed into BGP from zebra do not get
490 * nexthop tracking. However, if those routes are subsequently
491 * imported to other RIBs within BGP, the leaked routes do not
492 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
493 * in order to determine if the route we are currently leaking
494 * should have nexthop tracking, we must find the ultimate
495 * parent so we can check its sub_type.
497 * As of now, source_bi may at most be a second-generation route
498 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
499 * Using a loop here supports more complex intra-bgp import-export
500 * schemes that could be implemented in the future.
503 for (bi_ultimate
= source_bi
;
504 bi_ultimate
->extra
&& bi_ultimate
->extra
->parent
;
505 bi_ultimate
= bi_ultimate
->extra
->parent
)
511 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
512 if (bi
->extra
&& bi
->extra
->parent
== parent
)
517 bool labelssame
= labels_same(bi
, label
, num_labels
);
519 if (attrhash_cmp(bi
->attr
, new_attr
)
521 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
523 bgp_attr_unintern(&new_attr
);
526 "%s: ->%s: %s: Found route, no change",
527 __func__
, bgp
->name_pretty
,
532 /* attr is changed */
533 bgp_info_set_flag(bn
, bi
, BGP_INFO_ATTR_CHANGED
);
535 /* Rewrite BGP route information. */
536 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
537 bgp_info_restore(bn
, bi
);
539 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
540 bgp_attr_unintern(&bi
->attr
);
542 bi
->uptime
= bgp_clock();
548 setlabels(bi
, label
, num_labels
);
550 if (nexthop_self_flag
)
551 bgp_info_set_flag(bn
, bi
, BGP_INFO_ANNC_NH_SELF
);
553 struct bgp
*bgp_nexthop
= bgp
;
556 if (bi
->extra
&& bi
->extra
->bgp_orig
)
557 bgp_nexthop
= bi
->extra
->bgp_orig
;
559 /* No nexthop tracking for redistributed routes */
560 if (bi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
564 * TBD do we need to do anything about the
565 * 'connected' parameter?
567 nh_valid
= bgp_find_or_add_nexthop(
572 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
573 __func__
, (nh_valid
? "" : "not "),
574 bgp_nexthop
->name_pretty
);
577 bgp_info_set_flag(bn
, bi
, BGP_INFO_VALID
);
579 /* Process change. */
580 bgp_aggregate_increment(bgp
, p
, bi
, afi
, safi
);
581 bgp_process(bgp
, bn
, afi
, safi
);
585 zlog_debug("%s: ->%s: %s Found route, changed attr",
586 __func__
, bgp
->name_pretty
, buf_prefix
);
591 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
592 bgp
->peer_self
, new_attr
, bn
);
594 if (nexthop_self_flag
)
595 bgp_info_set_flag(bn
, new, BGP_INFO_ANNC_NH_SELF
);
597 bgp_info_extra_get(new);
600 setlabels(new, label
, num_labels
);
602 new->extra
->parent
= bgp_info_lock(parent
);
603 bgp_lock_node((struct bgp_node
*)((struct bgp_info
*)parent
)->net
);
605 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
607 new->extra
->nexthop_orig
= *nexthop_orig
;
610 * nexthop tracking for unicast routes
612 struct bgp
*bgp_nexthop
= bgp
;
615 if (new->extra
->bgp_orig
)
616 bgp_nexthop
= new->extra
->bgp_orig
;
619 * No nexthop tracking for redistributed routes because
620 * their originating protocols will do the tracking and
621 * withdraw those routes if the nexthops become unreachable
623 if (bi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
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_info_set_flag(bn
, new, BGP_INFO_VALID
);
640 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
641 bgp_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_info
*info_vrf
) /* route */
658 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
659 struct prefix
*p
= &info_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
&& info_vrf
->attr
->ecommunity
) {
674 char *s
= ecommunity_ecom2str(info_vrf
->attr
->ecommunity
,
675 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
677 zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__
,
678 bgp_vrf
->name
, info_vrf
->type
, s
);
679 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
687 zlog_debug("%s: can't get afi of prefix", __func__
);
691 /* loop check - should not be an imported route. */
692 if (info_vrf
->extra
&& info_vrf
->extra
->bgp_orig
)
696 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
698 zlog_debug("%s: %s skipping: %s", __func__
,
699 bgp_vrf
->name
, debugmsg
);
703 bgp_attr_dup(&static_attr
, info_vrf
->attr
); /* shallow copy */
708 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
709 struct bgp_info info
;
710 route_map_result_t ret
;
712 memset(&info
, 0, sizeof(info
));
713 info
.peer
= bgp_vpn
->peer_self
;
714 info
.attr
= &static_attr
;
715 ret
= route_map_apply(
716 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
718 if (RMAP_DENYMATCH
== ret
) {
719 bgp_attr_flush(&static_attr
); /* free any added parts */
722 "%s: vrf %s route map \"%s\" says DENY, returning",
723 __func__
, bgp_vrf
->name_pretty
,
724 bgp_vrf
->vpn_policy
[afi
]
725 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
731 if (debug
&& static_attr
.ecommunity
) {
732 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
733 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
735 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
737 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
741 * Add the vpn-policy rt-list
743 struct ecommunity
*old_ecom
;
744 struct ecommunity
*new_ecom
;
746 old_ecom
= static_attr
.ecommunity
;
748 new_ecom
= ecommunity_merge(
749 ecommunity_dup(old_ecom
),
750 bgp_vrf
->vpn_policy
[afi
]
751 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
752 if (!old_ecom
->refcnt
)
753 ecommunity_free(&old_ecom
);
755 new_ecom
= ecommunity_dup(
756 bgp_vrf
->vpn_policy
[afi
]
757 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
759 static_attr
.ecommunity
= new_ecom
;
760 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
762 if (debug
&& static_attr
.ecommunity
) {
763 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
764 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
766 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
768 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
772 /* if policy nexthop not set, use 0 */
773 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
774 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
775 struct prefix
*nexthop
=
776 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
778 switch (nexthop
->family
) {
780 /* prevent mp_nexthop_global_in <- self in bgp_route.c
782 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
784 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
785 static_attr
.mp_nexthop_len
= 4;
789 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
790 static_attr
.mp_nexthop_len
= 16;
797 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
798 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
801 * For ipv4, copy to multiprotocol
804 static_attr
.mp_nexthop_global_in
=
806 static_attr
.mp_nexthop_len
= 4;
808 * XXX Leave static_attr.nexthop
812 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
815 /* Update based on next-hop family to account for
816 * RFC 5549 (BGP unnumbered) scenario. Note that
817 * specific action is only needed for the case of
818 * IPv4 nexthops as the attr has been copied
822 !BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf
->attr
)) {
823 static_attr
.mp_nexthop_global_in
.s_addr
=
824 static_attr
.nexthop
.s_addr
;
825 static_attr
.mp_nexthop_len
= 4;
827 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
830 nexthop_self_flag
= 1;
833 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
834 if (label_val
== MPLS_LABEL_NONE
) {
835 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
837 encode_label(label_val
, &label
);
840 /* Set originator ID to "me" */
841 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
842 static_attr
.originator_id
= bgp_vpn
->router_id
;
845 new_attr
= bgp_attr_intern(
846 &static_attr
); /* hashed refcounted everything */
847 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
849 if (debug
&& new_attr
->ecommunity
) {
850 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
851 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
853 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
854 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
857 /* Now new_attr is an allocated interned attr */
859 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
860 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
862 struct bgp_info
*new_info
;
864 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, info_vrf
,
865 &label
, 1, info_vrf
, bgp_vrf
, NULL
,
866 nexthop_self_flag
, debug
);
869 * Routes actually installed in the vpn RIB must also be
870 * offered to all vrfs (because now they originate from
873 * Acceptance into other vrfs depends on rt-lists.
874 * Originating vrf will not accept the looped back route
875 * because of loop checking.
878 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
881 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
882 struct bgp
*bgp_vrf
, /* from */
883 struct bgp_info
*info_vrf
) /* route */
885 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
886 struct prefix
*p
= &info_vrf
->net
->p
;
887 afi_t afi
= family2afi(p
->family
);
888 safi_t safi
= SAFI_MPLS_VPN
;
891 const char *debugmsg
;
892 char buf_prefix
[PREFIX_STRLEN
];
895 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
897 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
898 __func__
, bgp_vrf
->name_pretty
, buf_prefix
,
899 info_vrf
->type
, info_vrf
->sub_type
);
902 if (info_vrf
->sub_type
!= BGP_ROUTE_NORMAL
903 && info_vrf
->sub_type
!= BGP_ROUTE_STATIC
904 && info_vrf
->sub_type
!= BGP_ROUTE_REDISTRIBUTE
) {
907 zlog_debug("%s: wrong sub_type %d", __func__
,
916 zlog_debug("%s: can't get afi of prefix", __func__
);
920 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
922 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
927 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__
, info_vrf
);
929 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
930 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
934 * match original bi imported from
936 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
937 if (bi
->extra
&& bi
->extra
->parent
== info_vrf
) {
943 /* withdraw from looped vrfs as well */
944 vpn_leak_to_vrf_withdraw(bgp_vpn
, bi
);
946 bgp_aggregate_decrement(bgp_vpn
, p
, bi
, afi
, safi
);
947 bgp_info_delete(bn
, bi
);
948 bgp_process(bgp_vpn
, bn
, afi
, safi
);
953 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
954 struct bgp
*bgp_vrf
, /* from */
957 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
958 struct bgp_node
*prn
;
959 safi_t safi
= SAFI_MPLS_VPN
;
962 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
964 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
965 prn
= bgp_route_next(prn
)) {
967 struct bgp_table
*table
;
971 /* This is the per-RD table of prefixes */
977 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
979 char buf
[PREFIX2STR_BUFFER
];
981 if (debug
&& bn
->info
) {
983 "%s: looking at prefix %s", __func__
,
984 prefix2str(&bn
->p
, buf
, sizeof(buf
)));
987 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
989 zlog_debug("%s: type %d, sub_type %d",
992 if (bi
->sub_type
!= BGP_ROUTE_IMPORTED
)
996 if ((struct bgp
*)bi
->extra
->bgp_orig
1000 zlog_debug("%s: deleting it\n",
1002 bgp_aggregate_decrement(bgp_vpn
, &bn
->p
,
1004 bgp_info_delete(bn
, bi
);
1005 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1012 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
1013 struct bgp
*bgp_vrf
, /* from */
1016 struct bgp_node
*bn
;
1017 struct bgp_info
*bi
;
1018 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1021 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1022 bgp_vrf
->name_pretty
);
1024 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
1025 bn
= bgp_route_next(bn
)) {
1028 zlog_debug("%s: node=%p", __func__
, bn
);
1030 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1033 "%s: calling vpn_leak_from_vrf_update",
1035 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bi
);
1040 static void vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1041 struct bgp
*bgp_vpn
, /* from */
1042 struct bgp_info
*info_vpn
) /* route */
1044 struct prefix
*p
= &info_vpn
->net
->p
;
1045 afi_t afi
= family2afi(p
->family
);
1047 struct attr static_attr
= {0};
1048 struct attr
*new_attr
= NULL
;
1049 struct bgp_node
*bn
;
1050 safi_t safi
= SAFI_UNICAST
;
1051 const char *debugmsg
;
1052 struct prefix nexthop_orig
;
1053 mpls_label_t
*pLabels
= NULL
;
1054 uint32_t num_labels
= 0;
1055 int nexthop_self_flag
= 1;
1056 struct bgp_info
*bi_ultimate
= NULL
;
1057 int origin_local
= 0;
1058 struct bgp
*src_vrf
;
1060 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1062 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1064 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1068 /* Check for intersection of route targets */
1069 if (!ecom_intersect(
1070 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1071 info_vpn
->attr
->ecommunity
)) {
1077 zlog_debug("%s: updating to vrf %s", __func__
,
1078 bgp_vrf
->name_pretty
);
1080 bgp_attr_dup(&static_attr
, info_vpn
->attr
); /* shallow copy */
1083 * Nexthop: stash and clear
1085 * Nexthop is valid in context of VPN core, but not in destination vrf.
1086 * Stash it for later label resolution by vrf ingress path and then
1087 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1089 uint8_t nhfamily
= NEXTHOP_FAMILY(info_vpn
->attr
->mp_nexthop_len
);
1091 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1092 nexthop_orig
.family
= nhfamily
;
1097 nexthop_orig
.u
.prefix4
= info_vpn
->attr
->mp_nexthop_global_in
;
1098 nexthop_orig
.prefixlen
= 32;
1100 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1101 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1102 static_attr
.nexthop
.s_addr
=
1103 nexthop_orig
.u
.prefix4
.s_addr
;
1105 static_attr
.mp_nexthop_global_in
=
1106 info_vpn
->attr
->mp_nexthop_global_in
;
1107 static_attr
.mp_nexthop_len
=
1108 info_vpn
->attr
->mp_nexthop_len
;
1110 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1114 nexthop_orig
.u
.prefix6
= info_vpn
->attr
->mp_nexthop_global
;
1115 nexthop_orig
.prefixlen
= 128;
1117 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1118 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1119 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1125 * route map handling
1127 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1128 struct bgp_info info
;
1129 route_map_result_t ret
;
1131 memset(&info
, 0, sizeof(info
));
1132 info
.peer
= bgp_vrf
->peer_self
;
1133 info
.attr
= &static_attr
;
1134 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1135 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1136 p
, RMAP_BGP
, &info
);
1137 if (RMAP_DENYMATCH
== ret
) {
1138 bgp_attr_flush(&static_attr
); /* free any added parts */
1141 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1142 __func__
, bgp_vrf
->name_pretty
,
1143 bgp_vrf
->vpn_policy
[afi
]
1144 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1149 * if route-map changed nexthop, don't nexthop-self on output
1151 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1152 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1153 nexthop_self_flag
= 0;
1156 new_attr
= bgp_attr_intern(&static_attr
);
1157 bgp_attr_flush(&static_attr
);
1159 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1162 * ensure labels are copied
1164 * However, there is a special case: if the route originated in
1165 * another local VRF (as opposed to arriving via VPN), then the
1166 * nexthop is reached by hairpinning through this router (me)
1167 * using IP forwarding only (no LSP). Therefore, the route
1168 * imported to the VRF should not have labels attached. Note
1169 * that nexthop tracking is also involved: eliminating the
1170 * labels for these routes enables the non-labeled nexthops
1171 * from the originating VRF to be considered valid for this route.
1173 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1174 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1175 /* work back to original route */
1176 for (bi_ultimate
= info_vpn
;
1177 bi_ultimate
->extra
&& bi_ultimate
->extra
->parent
;
1178 bi_ultimate
= bi_ultimate
->extra
->parent
)
1182 * if original route was unicast,
1183 * then it did not arrive over vpn
1185 if (bi_ultimate
->net
) {
1186 struct bgp_table
*table
;
1188 table
= bgp_node_table(bi_ultimate
->net
);
1189 if (table
&& (table
->safi
== SAFI_UNICAST
))
1194 if (!origin_local
&&
1195 info_vpn
->extra
&& info_vpn
->extra
->num_labels
) {
1196 num_labels
= info_vpn
->extra
->num_labels
;
1197 if (num_labels
> BGP_MAX_LABELS
)
1198 num_labels
= BGP_MAX_LABELS
;
1199 pLabels
= info_vpn
->extra
->label
;
1204 char buf_prefix
[PREFIX_STRLEN
];
1205 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
1206 zlog_debug("%s: pfx %s: num_labels %d", __func__
, buf_prefix
,
1211 * For VRF-2-VRF route-leaking,
1212 * the source will be the originating VRF.
1214 if (info_vpn
->extra
&& info_vpn
->extra
->bgp_orig
)
1215 src_vrf
= info_vpn
->extra
->bgp_orig
;
1219 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, info_vpn
,
1220 pLabels
, num_labels
,
1221 info_vpn
, /* parent */
1222 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1225 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1226 struct bgp_info
*info_vpn
) /* route */
1228 struct listnode
*mnode
, *mnnode
;
1231 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1234 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1236 /* Loop over VRFs */
1237 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1239 if (!info_vpn
->extra
1240 || info_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1241 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, info_vpn
);
1246 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1247 struct bgp_info
*info_vpn
) /* route */
1251 safi_t safi
= SAFI_UNICAST
;
1253 struct listnode
*mnode
, *mnnode
;
1254 struct bgp_node
*bn
;
1255 struct bgp_info
*bi
;
1256 const char *debugmsg
;
1257 char buf_prefix
[PREFIX_STRLEN
];
1259 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1262 prefix2str(&info_vpn
->net
->p
, buf_prefix
, sizeof(buf_prefix
));
1263 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1264 __func__
, buf_prefix
,
1265 info_vpn
->type
, info_vpn
->sub_type
);
1269 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1271 if (!info_vpn
->net
) {
1273 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1274 if (info_vpn
->type
== ZEBRA_ROUTE_BGP
&&
1275 info_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1281 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1286 p
= &info_vpn
->net
->p
;
1287 afi
= family2afi(p
->family
);
1289 /* Loop over VRFs */
1290 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1291 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1293 zlog_debug("%s: skipping: %s", __func__
,
1298 /* Check for intersection of route targets */
1299 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1300 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1301 info_vpn
->attr
->ecommunity
)) {
1307 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1310 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1311 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
1313 && (struct bgp_info
*)bi
->extra
->parent
1321 zlog_debug("%s: deleting bi %p", __func__
, bi
);
1322 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
1323 bgp_info_delete(bn
, bi
);
1324 bgp_process(bgp
, bn
, afi
, safi
);
1326 bgp_unlock_node(bn
);
1330 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1333 struct bgp_node
*bn
;
1334 struct bgp_info
*bi
;
1335 safi_t safi
= SAFI_UNICAST
;
1336 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1339 zlog_debug("%s: entry", __func__
);
1341 * Walk vrf table, delete bi with bgp_orig in a different vrf
1343 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1344 bn
= bgp_route_next(bn
)) {
1346 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1347 if (bi
->extra
&& bi
->extra
->bgp_orig
!= bgp_vrf
) {
1350 bgp_aggregate_decrement(bgp_vrf
, &bn
->p
, bi
,
1352 bgp_info_delete(bn
, bi
);
1353 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1359 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1360 struct bgp
*bgp_vpn
, /* from */
1363 struct prefix_rd prd
;
1364 struct bgp_node
*prn
;
1365 safi_t safi
= SAFI_MPLS_VPN
;
1372 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
1373 prn
= bgp_route_next(prn
)) {
1375 struct bgp_table
*table
;
1376 struct bgp_node
*bn
;
1377 struct bgp_info
*bi
;
1379 memset(&prd
, 0, sizeof(prd
));
1380 prd
.family
= AF_UNSPEC
;
1382 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
1384 /* This is the per-RD table of prefixes */
1390 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1392 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1394 if (bi
->extra
&& bi
->extra
->bgp_orig
== bgp_vrf
)
1397 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1405 * This function is called for definition/deletion/change to a route-map
1407 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1409 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1411 struct route_map
*rmap
;
1413 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1414 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1419 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1421 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1423 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1424 && !strcmp(rmap_name
,
1425 bgp
->vpn_policy
[afi
]
1426 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1430 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1431 __func__
, rmap_name
, bgp
->as
,
1434 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1435 bgp_get_default(), bgp
);
1437 zlog_debug("%s: after vpn_leak_prechange",
1440 /* in case of definition/deletion */
1441 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1444 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1445 bgp_get_default(), bgp
);
1448 zlog_debug("%s: after vpn_leak_postchange",
1452 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1453 && !strcmp(rmap_name
,
1454 bgp
->vpn_policy
[afi
]
1455 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1458 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1459 __func__
, rmap_name
, bgp
->as
,
1463 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1464 bgp_get_default(), bgp
);
1466 /* in case of definition/deletion */
1467 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1470 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1471 bgp_get_default(), bgp
);
1476 void vpn_policy_routemap_event(const char *rmap_name
)
1478 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1479 struct listnode
*mnode
, *mnnode
;
1483 zlog_debug("%s: entry", __func__
);
1485 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1488 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1489 vpn_policy_routemap_update(bgp
, rmap_name
);
1492 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1493 afi_t afi
, safi_t safi
)
1495 const char *export_name
;
1496 vpn_policy_direction_t idir
, edir
;
1499 struct ecommunity
*ecom
;
1500 bool first_export
= false;
1502 export_name
= to_bgp
->name
? to_bgp
->name
: BGP_DEFAULT_NAME
;
1503 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1504 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1507 * Cross-ref both VRFs. Also, note if this is the first time
1508 * any VRF is importing from "import_vrf".
1510 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
1511 : XSTRDUP(MTYPE_TMP
, BGP_DEFAULT_NAME
));
1513 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1515 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
))
1516 first_export
= true;
1517 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
1518 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1520 /* Update import RT for current VRF using export RT of the VRF we're
1521 * importing from. First though, make sure "import_vrf" has that
1525 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
1526 &from_bgp
->vrf_prd_auto
);
1527 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
1528 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1529 BGP_VPN_POLICY_TOVPN_RD_SET
);
1530 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
1532 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1533 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
1534 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1535 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1536 from_bgp
->vpn_policy
[afi
].tovpn_label
=
1537 BGP_PREVENT_VRF_2_VRF_LEAK
;
1539 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1540 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
1541 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
1542 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
1543 .rtlist
[idir
], ecom
);
1545 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
1546 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1548 /* Does "import_vrf" first need to export its routes or that
1549 * is already done and we just need to import those routes
1550 * from the global table?
1553 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
1555 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1558 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1559 afi_t afi
, safi_t safi
)
1561 const char *export_name
, *tmp_name
;
1562 vpn_policy_direction_t idir
, edir
;
1564 struct ecommunity
*ecom
;
1565 struct listnode
*node
;
1567 export_name
= to_bgp
->name
? to_bgp
->name
: BGP_DEFAULT_NAME
;
1568 tmp_name
= from_bgp
->name
? from_bgp
->name
: BGP_DEFAULT_NAME
;
1569 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1570 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1572 /* Were we importing from "import_vrf"? */
1573 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
1575 if (strcmp(vname
, tmp_name
) == 0)
1580 * We do not check in the cli if the passed in bgp
1581 * instance is actually imported into us before
1582 * we call this function. As such if we do not
1583 * find this in the import_vrf list than
1584 * we just need to return safely.
1589 /* Remove "import_vrf" from our import list. */
1590 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1591 XFREE(MTYPE_TMP
, vname
);
1593 /* Remove routes imported from "import_vrf". */
1594 /* TODO: In the current logic, we have to first remove all
1595 * imported routes and then (if needed) import back routes
1597 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
1599 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
1600 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
1601 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1602 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
1604 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1605 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
1606 (struct ecommunity_val
*)ecom
->val
);
1607 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1612 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1613 * below is checking for NULL that export_vrf can be
1614 * NULL, consequently it is complaining( like a cabbage )
1615 * that we could dereference and crash in the listcount(..)
1617 * So make it happy, under protest, with liberty and justice
1620 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
1622 /* Remove us from "import_vrf's" export list. If no other VRF
1623 * is importing from "import_vrf", cleanup appropriately.
1625 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1627 if (strcmp(vname
, export_name
) == 0)
1632 * If we have gotten to this point then the vname must
1633 * exist. If not, we are in a world of trouble and
1634 * have slag sitting around.
1636 * import_vrf and export_vrf must match in having
1637 * the in/out names as appropriate.
1641 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1642 XFREE(MTYPE_TMP
, vname
);
1644 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1645 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
1646 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
1647 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1648 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1649 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
1650 sizeof(struct prefix_rd
));
1651 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1652 BGP_VPN_POLICY_TOVPN_RD_SET
);
1653 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
1658 /* For testing purpose, static route of MPLS-VPN. */
1659 DEFUN (vpnv4_network
,
1661 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1662 "Specify a network to announce via BGP\n"
1664 "Specify Route Distinguisher\n"
1665 "VPN Route Distinguisher\n"
1666 "VPN NLRI label (tag)\n"
1667 "VPN NLRI label (tag)\n"
1670 int idx_ipv4_prefixlen
= 1;
1671 int idx_ext_community
= 3;
1673 return bgp_static_set_safi(
1674 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1675 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1676 NULL
, NULL
, NULL
, NULL
);
1679 DEFUN (vpnv4_network_route_map
,
1680 vpnv4_network_route_map_cmd
,
1681 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1682 "Specify a network to announce via BGP\n"
1684 "Specify Route Distinguisher\n"
1685 "VPN Route Distinguisher\n"
1686 "VPN NLRI label (tag)\n"
1687 "VPN NLRI label (tag)\n"
1692 int idx_ipv4_prefixlen
= 1;
1693 int idx_ext_community
= 3;
1696 return bgp_static_set_safi(
1697 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1698 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1699 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1702 /* For testing purpose, static route of MPLS-VPN. */
1703 DEFUN (no_vpnv4_network
,
1704 no_vpnv4_network_cmd
,
1705 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1707 "Specify a network to announce via BGP\n"
1709 "Specify Route Distinguisher\n"
1710 "VPN Route Distinguisher\n"
1711 "VPN NLRI label (tag)\n"
1712 "VPN NLRI label (tag)\n"
1715 int idx_ipv4_prefixlen
= 2;
1716 int idx_ext_community
= 4;
1718 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1719 argv
[idx_ipv4_prefixlen
]->arg
,
1720 argv
[idx_ext_community
]->arg
,
1721 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1724 DEFUN (vpnv6_network
,
1726 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1727 "Specify a network to announce via BGP\n"
1728 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1729 "Specify Route Distinguisher\n"
1730 "VPN Route Distinguisher\n"
1731 "VPN NLRI label (tag)\n"
1732 "VPN NLRI label (tag)\n"
1737 int idx_ipv6_prefix
= 1;
1738 int idx_ext_community
= 3;
1742 return bgp_static_set_safi(
1743 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1744 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1745 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1747 return bgp_static_set_safi(
1748 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1749 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1750 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1753 /* For testing purpose, static route of MPLS-VPN. */
1754 DEFUN (no_vpnv6_network
,
1755 no_vpnv6_network_cmd
,
1756 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1758 "Specify a network to announce via BGP\n"
1759 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1760 "Specify Route Distinguisher\n"
1761 "VPN Route Distinguisher\n"
1762 "VPN NLRI label (tag)\n"
1763 "VPN NLRI label (tag)\n"
1766 int idx_ipv6_prefix
= 2;
1767 int idx_ext_community
= 4;
1769 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
1770 argv
[idx_ipv6_prefix
]->arg
,
1771 argv
[idx_ext_community
]->arg
,
1772 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1775 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
1776 enum bgp_show_type type
, void *output_arg
, int tags
,
1780 struct bgp_table
*table
;
1782 bgp
= bgp_get_default();
1785 vty_out(vty
, "No BGP process is configured\n");
1787 vty_out(vty
, "{}\n");
1790 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
1791 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
1792 output_arg
, use_json
);
1795 DEFUN (show_bgp_ip_vpn_all_rd
,
1796 show_bgp_ip_vpn_all_rd_cmd
,
1797 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1801 "Display VPN NLRI specific information\n"
1802 "Display VPN NLRI specific information\n"
1803 "Display information for a route distinguisher\n"
1804 "VPN Route Distinguisher\n"
1808 struct prefix_rd prd
;
1812 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1813 if (argv_find(argv
, argc
, "rd", &idx
)) {
1814 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
1817 "%% Malformed Route Distinguisher\n");
1820 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
1821 bgp_show_type_normal
, NULL
, 0,
1822 use_json(argc
, argv
));
1824 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
1825 bgp_show_type_normal
, NULL
, 0,
1826 use_json(argc
, argv
));
1832 ALIAS(show_bgp_ip_vpn_all_rd
,
1833 show_bgp_ip_vpn_rd_cmd
,
1834 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1838 "Display VPN NLRI specific information\n"
1839 "Display information for a route distinguisher\n"
1840 "VPN Route Distinguisher\n"
1843 #ifdef KEEP_OLD_VPN_COMMANDS
1844 DEFUN (show_ip_bgp_vpn_rd
,
1845 show_ip_bgp_vpn_rd_cmd
,
1846 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
1851 "Address Family modifier\n"
1852 "Display information for a route distinguisher\n"
1853 "VPN Route Distinguisher\n")
1855 int idx_ext_community
= argc
- 1;
1857 struct prefix_rd prd
;
1861 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1862 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1864 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1867 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1873 DEFUN (show_ip_bgp_vpn_all
,
1874 show_ip_bgp_vpn_all_cmd
,
1875 "show [ip] bgp <vpnv4|vpnv6>",
1884 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1885 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1890 DEFUN (show_ip_bgp_vpn_all_tags
,
1891 show_ip_bgp_vpn_all_tags_cmd
,
1892 "show [ip] bgp <vpnv4|vpnv6> all tags",
1897 "Display information about all VPNv4/VPNV6 NLRIs\n"
1898 "Display BGP tags for prefixes\n")
1903 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1904 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1909 DEFUN (show_ip_bgp_vpn_rd_tags
,
1910 show_ip_bgp_vpn_rd_tags_cmd
,
1911 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
1916 "Display information for a route distinguisher\n"
1917 "VPN Route Distinguisher\n"
1918 "Display BGP tags for prefixes\n")
1920 int idx_ext_community
= 5;
1922 struct prefix_rd prd
;
1926 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1927 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1929 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1932 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1938 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1939 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1940 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1945 "Display information about all VPNv4/VPNv6 NLRIs\n"
1946 "Detailed information on TCP and BGP neighbor connections\n"
1947 "Neighbor to display information about\n"
1948 "Display routes learned from neighbor\n"
1955 bool uj
= use_json(argc
, argv
);
1959 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1960 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1963 json_object
*json_no
= NULL
;
1964 json_no
= json_object_new_object();
1965 json_object_string_add(json_no
, "warning",
1966 "Malformed address");
1967 vty_out(vty
, "%s\n",
1968 json_object_to_json_string(json_no
));
1969 json_object_free(json_no
);
1971 vty_out(vty
, "Malformed address: %s\n",
1972 argv
[idx_ipv4
]->arg
);
1976 peer
= peer_lookup(NULL
, &su
);
1977 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1979 json_object
*json_no
= NULL
;
1980 json_no
= json_object_new_object();
1981 json_object_string_add(
1983 "No such neighbor or address family");
1984 vty_out(vty
, "%s\n",
1985 json_object_to_json_string(json_no
));
1986 json_object_free(json_no
);
1989 "%% No such neighbor or address family\n");
1993 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
1999 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2000 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2001 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
2006 "Display information for a route distinguisher\n"
2007 "VPN Route Distinguisher\n"
2008 "Detailed information on TCP and BGP neighbor connections\n"
2009 "Neighbor to display information about\n"
2010 "Display routes learned from neighbor\n"
2013 int idx_ext_community
= 5;
2018 struct prefix_rd prd
;
2019 bool uj
= use_json(argc
, argv
);
2023 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2024 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2027 json_object
*json_no
= NULL
;
2028 json_no
= json_object_new_object();
2029 json_object_string_add(
2031 "Malformed Route Distinguisher");
2032 vty_out(vty
, "%s\n",
2033 json_object_to_json_string(json_no
));
2034 json_object_free(json_no
);
2037 "%% Malformed Route Distinguisher\n");
2041 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2044 json_object
*json_no
= NULL
;
2045 json_no
= json_object_new_object();
2046 json_object_string_add(json_no
, "warning",
2047 "Malformed address");
2048 vty_out(vty
, "%s\n",
2049 json_object_to_json_string(json_no
));
2050 json_object_free(json_no
);
2052 vty_out(vty
, "Malformed address: %s\n",
2053 argv
[idx_ext_community
]->arg
);
2057 peer
= peer_lookup(NULL
, &su
);
2058 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2060 json_object
*json_no
= NULL
;
2061 json_no
= json_object_new_object();
2062 json_object_string_add(
2064 "No such neighbor or address family");
2065 vty_out(vty
, "%s\n",
2066 json_object_to_json_string(json_no
));
2067 json_object_free(json_no
);
2070 "%% No such neighbor or address family\n");
2074 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
2080 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2081 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2082 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2087 "Display information about all VPNv4/VPNv6 NLRIs\n"
2088 "Detailed information on TCP and BGP neighbor connections\n"
2089 "Neighbor to display information about\n"
2090 "Display the routes advertised to a BGP neighbor\n"
2097 bool uj
= use_json(argc
, argv
);
2101 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2102 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2105 json_object
*json_no
= NULL
;
2106 json_no
= json_object_new_object();
2107 json_object_string_add(json_no
, "warning",
2108 "Malformed address");
2109 vty_out(vty
, "%s\n",
2110 json_object_to_json_string(json_no
));
2111 json_object_free(json_no
);
2113 vty_out(vty
, "Malformed address: %s\n",
2114 argv
[idx_ipv4
]->arg
);
2117 peer
= peer_lookup(NULL
, &su
);
2118 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2120 json_object
*json_no
= NULL
;
2121 json_no
= json_object_new_object();
2122 json_object_string_add(
2124 "No such neighbor or address family");
2125 vty_out(vty
, "%s\n",
2126 json_object_to_json_string(json_no
));
2127 json_object_free(json_no
);
2130 "%% No such neighbor or address family\n");
2133 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2139 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2140 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2141 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2146 "Display information for a route distinguisher\n"
2147 "VPN Route Distinguisher\n"
2148 "Detailed information on TCP and BGP neighbor connections\n"
2149 "Neighbor to display information about\n"
2150 "Display the routes advertised to a BGP neighbor\n"
2153 int idx_ext_community
= 5;
2157 struct prefix_rd prd
;
2159 bool uj
= use_json(argc
, argv
);
2163 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2164 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2167 json_object
*json_no
= NULL
;
2168 json_no
= json_object_new_object();
2169 json_object_string_add(json_no
, "warning",
2170 "Malformed address");
2171 vty_out(vty
, "%s\n",
2172 json_object_to_json_string(json_no
));
2173 json_object_free(json_no
);
2175 vty_out(vty
, "Malformed address: %s\n",
2176 argv
[idx_ext_community
]->arg
);
2179 peer
= peer_lookup(NULL
, &su
);
2180 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2182 json_object
*json_no
= NULL
;
2183 json_no
= json_object_new_object();
2184 json_object_string_add(
2186 "No such neighbor or address family");
2187 vty_out(vty
, "%s\n",
2188 json_object_to_json_string(json_no
));
2189 json_object_free(json_no
);
2192 "%% No such neighbor or address family\n");
2196 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2199 json_object
*json_no
= NULL
;
2200 json_no
= json_object_new_object();
2201 json_object_string_add(
2203 "Malformed Route Distinguisher");
2204 vty_out(vty
, "%s\n",
2205 json_object_to_json_string(json_no
));
2206 json_object_free(json_no
);
2209 "%% Malformed Route Distinguisher\n");
2213 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2218 #endif /* KEEP_OLD_VPN_COMMANDS */
2220 void bgp_mplsvpn_init(void)
2222 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2223 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2224 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2226 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2227 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2229 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2230 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2231 #ifdef KEEP_OLD_VPN_COMMANDS
2232 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2233 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2234 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2235 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2236 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2237 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2238 install_element(VIEW_NODE
,
2239 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2240 install_element(VIEW_NODE
,
2241 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2242 #endif /* KEEP_OLD_VPN_COMMANDS */
2245 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2247 struct listnode
*mnode
, *mnnode
;
2250 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2251 struct ecommunity
*ec
;
2253 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2256 ec
= bgp
->vpn_policy
[AFI_IP
].import_redirect_rtlist
;
2258 if (ecom_intersect(ec
, eckey
))
2265 * The purpose of this function is to process leaks that were deferred
2266 * from earlier per-vrf configuration due to not-yet-existing default
2267 * vrf, in other words, configuration such as:
2269 * router bgp MMM vrf FOO
2270 * address-family ipv4 unicast
2272 * exit-address-family
2277 * This function gets called when the default instance ("router bgp NNN")
2280 void vpn_leak_postchange_all(void)
2282 struct listnode
*next
;
2284 struct bgp
*bgp_default
= bgp_get_default();
2286 assert(bgp_default
);
2288 /* First, do any exporting from VRFs to the single VPN RIB */
2289 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2291 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2294 vpn_leak_postchange(
2295 BGP_VPN_POLICY_DIR_TOVPN
,
2300 vpn_leak_postchange(
2301 BGP_VPN_POLICY_DIR_TOVPN
,
2307 /* Now, do any importing to VRFs from the single VPN RIB */
2308 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2310 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2313 vpn_leak_postchange(
2314 BGP_VPN_POLICY_DIR_FROMVPN
,
2319 vpn_leak_postchange(
2320 BGP_VPN_POLICY_DIR_FROMVPN
,