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_table.h"
37 #include "bgpd/bgp_route.h"
38 #include "bgpd/bgp_attr.h"
39 #include "bgpd/bgp_label.h"
40 #include "bgpd/bgp_mplsvpn.h"
41 #include "bgpd/bgp_packet.h"
42 #include "bgpd/bgp_vty.h"
43 #include "bgpd/bgp_vpn.h"
44 #include "bgpd/bgp_ecommunity.h"
45 #include "bgpd/bgp_zebra.h"
46 #include "bgpd/bgp_nexthop.h"
47 #include "bgpd/bgp_nht.h"
50 #include "bgpd/rfapi/rfapi_backend.h"
54 * Definitions and external declarations.
56 extern struct zclient
*zclient
;
58 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
59 int *index
, afi_t
*afi
)
62 if (argv_find(argv
, argc
, "vpnv4", index
)) {
66 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
74 uint32_t decode_label(mpls_label_t
*label_pnt
)
77 uint8_t *pnt
= (uint8_t *)label_pnt
;
79 l
= ((uint32_t)*pnt
++ << 12);
80 l
|= (uint32_t)*pnt
++ << 4;
81 l
|= (uint32_t)((*pnt
& 0xf0) >> 4);
85 void encode_label(mpls_label_t label
, mpls_label_t
*label_pnt
)
87 uint8_t *pnt
= (uint8_t *)label_pnt
;
90 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
) {
94 *pnt
++ = (label
>> 12) & 0xff;
95 *pnt
++ = (label
>> 4) & 0xff;
96 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
99 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
100 struct bgp_nlri
*packet
)
110 struct prefix_rd prd
;
111 mpls_label_t label
= {0};
118 prd
.family
= AF_UNSPEC
;
122 lim
= pnt
+ packet
->length
;
128 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
129 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
130 PEER_CAP_ADDPATH_AF_TX_RCV
));
132 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
133 for (; pnt
< lim
; pnt
+= psize
) {
134 /* Clear prefix structure. */
135 memset(&p
, 0, sizeof(struct prefix
));
137 if (addpath_encoded
) {
139 /* When packet overflow occurs return immediately. */
140 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
143 addpath_id
= ntohl(*((uint32_t *)pnt
));
144 pnt
+= BGP_ADDPATH_ID_LEN
;
147 /* Fetch prefix length. */
149 p
.family
= afi2family(packet
->afi
);
150 psize
= PSIZE(prefixlen
);
152 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
154 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
155 peer
->host
, prefixlen
);
159 /* sanity check against packet data */
160 if ((pnt
+ psize
) > lim
) {
162 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
163 peer
->host
, prefixlen
, (uint
)(lim
- pnt
));
167 /* sanity check against storage for the IP address portion */
168 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
170 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
172 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
177 /* Sanity check against max bitlen of the address family */
178 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
180 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
182 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
183 p
.family
, prefix_blen(&p
));
187 /* Copy label to prefix. */
188 memcpy(&label
, pnt
, BGP_LABEL_BYTES
);
189 bgp_set_valid_label(&label
);
191 /* Copy routing distinguisher to rd. */
192 memcpy(&prd
.val
, pnt
+ BGP_LABEL_BYTES
, 8);
194 /* Decode RD type. */
195 type
= decode_rd_type(pnt
+ BGP_LABEL_BYTES
);
199 decode_rd_as(pnt
+ 5, &rd_as
);
203 decode_rd_as4(pnt
+ 5, &rd_as
);
207 decode_rd_ip(pnt
+ 5, &rd_ip
);
211 case RD_TYPE_VNC_ETH
:
216 zlog_err("Unknown RD type %d", type
);
217 break; /* just report */
222 - VPN_PREFIXLEN_MIN_BYTES
* 8; /* exclude label & RD */
223 memcpy(p
.u
.val
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
224 psize
- VPN_PREFIXLEN_MIN_BYTES
);
227 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
228 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
229 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
231 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
232 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
233 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
236 /* Packet length consistency check. */
239 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
240 peer
->host
, lim
- pnt
);
245 #undef VPN_PREFIXLEN_MIN_BYTES
249 * This function informs zebra of the label this vrf sets on routes
250 * leaked to VPN. Zebra should install this label in the kernel with
251 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
253 * Sending this vrf-label association is qualified by a) whether vrf->vpn
254 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
255 * are set) and b) whether vpn-policy label is set.
257 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
258 * for this vrf, which zebra interprets to mean "delete this vrf-label
261 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
263 mpls_label_t label
= MPLS_LABEL_NONE
;
264 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
266 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
269 "%s: vrf %s: afi %s: vrf_id not set, "
270 "can't set zebra vrf label",
271 __func__
, bgp
->name_pretty
, afi2str(afi
));
276 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
277 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
281 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
282 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
286 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
287 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
291 * If zebra tells us vrf has become unconfigured, tell zebra not to
292 * use this label to forward to the vrf anymore
294 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
296 mpls_label_t label
= MPLS_LABEL_NONE
;
297 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
299 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
302 "%s: vrf_id not set, can't delete zebra vrf label",
309 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
310 bgp
->name_pretty
, bgp
->vrf_id
);
313 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
314 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
317 int vpn_leak_label_callback(
322 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
323 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
326 zlog_debug("%s: label=%u, allocated=%d",
327 __func__
, label
, allocated
);
331 * previously-allocated label is now invalid
333 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
334 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
336 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
337 vp
->afi
, bgp_get_default(), vp
->bgp
);
338 vp
->tovpn_label
= MPLS_LABEL_NONE
;
339 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
340 vp
->afi
, bgp_get_default(), vp
->bgp
);
346 * New label allocation
348 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
351 * not currently configured for auto label, reject allocation
356 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
357 if (label
== vp
->tovpn_label
) {
358 /* already have same label, accept but do nothing */
361 /* Shouldn't happen: different label allocation */
362 zlog_err("%s: %s had label %u but got new assignment %u",
363 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
, label
);
367 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
368 vp
->afi
, bgp_get_default(), vp
->bgp
);
369 vp
->tovpn_label
= label
;
370 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
371 vp
->afi
, bgp_get_default(), vp
->bgp
);
376 static int ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
384 for (i
= 0; i
< e1
->size
; ++i
) {
385 for (j
= 0; j
< e2
->size
; ++j
) {
386 if (!memcmp(e1
->val
+ (i
* ECOMMUNITY_SIZE
),
387 e2
->val
+ (j
* ECOMMUNITY_SIZE
),
397 static bool labels_same(struct bgp_info
*bi
, mpls_label_t
*label
, uint32_t n
)
408 if (n
!= bi
->extra
->num_labels
)
411 for (i
= 0; i
< n
; ++i
) {
412 if (label
[i
] != bi
->extra
->label
[i
])
419 * make encoded route labels match specified encoded label set
421 static void setlabels(
423 mpls_label_t
*label
, /* array of labels */
428 assert(num_labels
<= BGP_MAX_LABELS
);
432 bi
->extra
->num_labels
= 0;
436 struct bgp_info_extra
*extra
= bgp_info_extra_get(bi
);
439 for (i
= 0; i
< num_labels
; ++i
) {
440 extra
->label
[i
] = label
[i
];
441 if (!bgp_is_valid_label(&label
[i
])) {
442 bgp_set_valid_label(&extra
->label
[i
]);
445 extra
->num_labels
= num_labels
;
449 * returns pointer to new bgp_info upon success
451 static struct bgp_info
*
453 struct bgp
*bgp
, /* destination bgp instance */
455 struct attr
*new_attr
, /* already interned */
458 struct bgp_info
*source_bi
,
462 struct bgp
*bgp_orig
,
463 struct prefix
*nexthop_orig
,
464 int nexthop_self_flag
,
467 struct prefix
*p
= &bn
->p
;
469 struct bgp_info
*bi_ultimate
;
470 struct bgp_info
*new;
471 char buf_prefix
[PREFIX_STRLEN
];
474 prefix2str(&bn
->p
, buf_prefix
, sizeof(buf_prefix
));
475 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
476 __func__
, bgp
->name_pretty
, buf_prefix
,
477 source_bi
->type
, source_bi
->sub_type
);
481 * Routes that are redistributed into BGP from zebra do not get
482 * nexthop tracking. However, if those routes are subsequently
483 * imported to other RIBs within BGP, the leaked routes do not
484 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
485 * in order to determine if the route we are currently leaking
486 * should have nexthop tracking, we must find the ultimate
487 * parent so we can check its sub_type.
489 * As of now, source_bi may at most be a second-generation route
490 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
491 * Using a loop here supports more complex intra-bgp import-export
492 * schemes that could be implemented in the future.
495 for (bi_ultimate
= source_bi
;
496 bi_ultimate
->extra
&& bi_ultimate
->extra
->parent
;
497 bi_ultimate
= bi_ultimate
->extra
->parent
)
503 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
504 if (bi
->extra
&& bi
->extra
->parent
== parent
)
509 bool labelssame
= labels_same(bi
, label
, num_labels
);
511 if (attrhash_cmp(bi
->attr
, new_attr
)
513 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
515 bgp_attr_unintern(&new_attr
);
518 "%s: ->%s: %s: Found route, no change",
519 __func__
, bgp
->name_pretty
,
524 /* attr is changed */
525 bgp_info_set_flag(bn
, bi
, BGP_INFO_ATTR_CHANGED
);
527 /* Rewrite BGP route information. */
528 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
529 bgp_info_restore(bn
, bi
);
531 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
532 bgp_attr_unintern(&bi
->attr
);
534 bi
->uptime
= bgp_clock();
540 setlabels(bi
, label
, num_labels
);
542 if (nexthop_self_flag
)
543 bgp_info_set_flag(bn
, bi
, BGP_INFO_ANNC_NH_SELF
);
545 struct bgp
*bgp_nexthop
= bgp
;
548 if (bi
->extra
&& bi
->extra
->bgp_orig
)
549 bgp_nexthop
= bi
->extra
->bgp_orig
;
551 /* No nexthop tracking for redistributed routes */
552 if (bi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
556 * TBD do we need to do anything about the
557 * 'connected' parameter?
559 nh_valid
= bgp_find_or_add_nexthop(
564 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
565 __func__
, (nh_valid
? "" : "not "),
566 bgp_nexthop
->name_pretty
);
569 bgp_info_set_flag(bn
, bi
, BGP_INFO_VALID
);
571 /* Process change. */
572 bgp_aggregate_increment(bgp
, p
, bi
, afi
, safi
);
573 bgp_process(bgp
, bn
, afi
, safi
);
577 zlog_debug("%s: ->%s: %s Found route, changed attr",
578 __func__
, bgp
->name_pretty
, buf_prefix
);
583 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
584 bgp
->peer_self
, new_attr
, bn
);
586 if (nexthop_self_flag
)
587 bgp_info_set_flag(bn
, new, BGP_INFO_ANNC_NH_SELF
);
589 bgp_info_extra_get(new);
592 setlabels(new, label
, num_labels
);
594 new->extra
->parent
= bgp_info_lock(parent
);
595 bgp_lock_node((struct bgp_node
*)((struct bgp_info
*)parent
)->net
);
597 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
599 new->extra
->nexthop_orig
= *nexthop_orig
;
602 * nexthop tracking for unicast routes
604 struct bgp
*bgp_nexthop
= bgp
;
607 if (new->extra
->bgp_orig
)
608 bgp_nexthop
= new->extra
->bgp_orig
;
611 * No nexthop tracking for redistributed routes because
612 * their originating protocols will do the tracking and
613 * withdraw those routes if the nexthops become unreachable
615 if (bi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
619 * TBD do we need to do anything about the
620 * 'connected' parameter?
622 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
626 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
627 __func__
, (nh_valid
? "" : "not "),
628 bgp_nexthop
->name_pretty
);
630 bgp_info_set_flag(bn
, new, BGP_INFO_VALID
);
632 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
633 bgp_info_add(bn
, new);
636 bgp_process(bgp
, bn
, afi
, safi
);
639 zlog_debug("%s: ->%s: %s: Added new route", __func__
,
640 bgp
->name_pretty
, buf_prefix
);
645 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
646 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
647 struct bgp
*bgp_vrf
, /* from */
648 struct bgp_info
*info_vrf
) /* route */
650 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
651 struct prefix
*p
= &info_vrf
->net
->p
;
652 afi_t afi
= family2afi(p
->family
);
653 struct attr static_attr
= {0};
654 struct attr
*new_attr
= NULL
;
655 safi_t safi
= SAFI_MPLS_VPN
;
656 mpls_label_t label_val
;
659 const char *debugmsg
;
660 int nexthop_self_flag
= 0;
663 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
665 if (debug
&& info_vrf
->attr
->ecommunity
) {
666 char *s
= ecommunity_ecom2str(info_vrf
->attr
->ecommunity
,
667 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
669 zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__
,
670 bgp_vrf
->name
, info_vrf
->type
, s
);
671 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
679 zlog_debug("%s: can't get afi of prefix", __func__
);
683 /* loop check - should not be an imported route. */
684 if (info_vrf
->extra
&& info_vrf
->extra
->bgp_orig
)
688 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
690 zlog_debug("%s: %s skipping: %s", __func__
,
691 bgp_vrf
->name
, debugmsg
);
695 bgp_attr_dup(&static_attr
, info_vrf
->attr
); /* shallow copy */
700 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
701 struct bgp_info info
;
702 route_map_result_t ret
;
704 memset(&info
, 0, sizeof(info
));
705 info
.peer
= bgp_vpn
->peer_self
;
706 info
.attr
= &static_attr
;
707 ret
= route_map_apply(
708 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
710 if (RMAP_DENYMATCH
== ret
) {
711 bgp_attr_flush(&static_attr
); /* free any added parts */
714 "%s: vrf %s route map \"%s\" says DENY, returning",
715 __func__
, bgp_vrf
->name_pretty
,
716 bgp_vrf
->vpn_policy
[afi
]
717 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
723 if (debug
&& static_attr
.ecommunity
) {
724 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
725 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
727 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
729 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
733 * Add the vpn-policy rt-list
735 struct ecommunity
*old_ecom
;
736 struct ecommunity
*new_ecom
;
738 old_ecom
= static_attr
.ecommunity
;
740 new_ecom
= ecommunity_merge(
741 ecommunity_dup(old_ecom
),
742 bgp_vrf
->vpn_policy
[afi
]
743 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
744 if (!old_ecom
->refcnt
)
745 ecommunity_free(&old_ecom
);
747 new_ecom
= ecommunity_dup(
748 bgp_vrf
->vpn_policy
[afi
]
749 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
751 static_attr
.ecommunity
= new_ecom
;
752 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
754 if (debug
&& static_attr
.ecommunity
) {
755 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
756 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
758 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
760 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
764 /* if policy nexthop not set, use 0 */
765 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
766 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
767 struct prefix
*nexthop
=
768 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
770 switch (nexthop
->family
) {
772 /* prevent mp_nexthop_global_in <- self in bgp_route.c
774 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
776 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
777 static_attr
.mp_nexthop_len
= 4;
781 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
782 static_attr
.mp_nexthop_len
= 16;
789 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
790 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
793 * For ipv4, copy to multiprotocol
796 static_attr
.mp_nexthop_global_in
=
798 static_attr
.mp_nexthop_len
= 4;
800 * XXX Leave static_attr.nexthop
804 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
807 /* Update based on next-hop family to account for
808 * RFC 5549 (BGP unnumbered) scenario. Note that
809 * specific action is only needed for the case of
810 * IPv4 nexthops as the attr has been copied
814 !BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf
->attr
)) {
815 static_attr
.mp_nexthop_global_in
.s_addr
=
816 static_attr
.nexthop
.s_addr
;
817 static_attr
.mp_nexthop_len
= 4;
819 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
822 nexthop_self_flag
= 1;
825 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
826 if (label_val
== MPLS_LABEL_NONE
) {
827 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
829 encode_label(label_val
, &label
);
832 /* Set originator ID to "me" */
833 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
834 static_attr
.originator_id
= bgp_vpn
->router_id
;
837 new_attr
= bgp_attr_intern(
838 &static_attr
); /* hashed refcounted everything */
839 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
841 if (debug
&& new_attr
->ecommunity
) {
842 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
843 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
845 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
846 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
849 /* Now new_attr is an allocated interned attr */
851 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
852 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
854 struct bgp_info
*new_info
;
856 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, info_vrf
,
857 &label
, 1, info_vrf
, bgp_vrf
, NULL
,
858 nexthop_self_flag
, debug
);
861 * Routes actually installed in the vpn RIB must also be
862 * offered to all vrfs (because now they originate from
865 * Acceptance into other vrfs depends on rt-lists.
866 * Originating vrf will not accept the looped back route
867 * because of loop checking.
870 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
873 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
874 struct bgp
*bgp_vrf
, /* from */
875 struct bgp_info
*info_vrf
) /* route */
877 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
878 struct prefix
*p
= &info_vrf
->net
->p
;
879 afi_t afi
= family2afi(p
->family
);
880 safi_t safi
= SAFI_MPLS_VPN
;
883 const char *debugmsg
;
884 char buf_prefix
[PREFIX_STRLEN
];
887 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
889 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
890 __func__
, bgp_vrf
->name_pretty
, buf_prefix
,
891 info_vrf
->type
, info_vrf
->sub_type
);
894 if (info_vrf
->sub_type
!= BGP_ROUTE_NORMAL
895 && info_vrf
->sub_type
!= BGP_ROUTE_STATIC
896 && info_vrf
->sub_type
!= BGP_ROUTE_REDISTRIBUTE
) {
899 zlog_debug("%s: wrong sub_type %d", __func__
,
908 zlog_debug("%s: can't get afi of prefix", __func__
);
912 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
914 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
919 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__
, info_vrf
);
921 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
922 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
926 * match original bi imported from
928 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
929 if (bi
->extra
&& bi
->extra
->parent
== info_vrf
) {
935 /* withdraw from looped vrfs as well */
936 vpn_leak_to_vrf_withdraw(bgp_vpn
, bi
);
938 bgp_aggregate_decrement(bgp_vpn
, p
, bi
, afi
, safi
);
939 bgp_info_delete(bn
, bi
);
940 bgp_process(bgp_vpn
, bn
, afi
, safi
);
945 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
946 struct bgp
*bgp_vrf
, /* from */
949 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
950 struct bgp_node
*prn
;
951 safi_t safi
= SAFI_MPLS_VPN
;
954 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
956 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
957 prn
= bgp_route_next(prn
)) {
959 struct bgp_table
*table
;
963 /* This is the per-RD table of prefixes */
969 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
971 char buf
[PREFIX2STR_BUFFER
];
973 if (debug
&& bn
->info
) {
975 "%s: looking at prefix %s", __func__
,
976 prefix2str(&bn
->p
, buf
, sizeof(buf
)));
979 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
981 zlog_debug("%s: type %d, sub_type %d",
984 if (bi
->sub_type
!= BGP_ROUTE_IMPORTED
)
988 if ((struct bgp
*)bi
->extra
->bgp_orig
992 zlog_debug("%s: deleting it\n",
994 bgp_aggregate_decrement(bgp_vpn
, &bn
->p
,
996 bgp_info_delete(bn
, bi
);
997 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1004 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
1005 struct bgp
*bgp_vrf
, /* from */
1008 struct bgp_node
*bn
;
1009 struct bgp_info
*bi
;
1010 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1013 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1014 bgp_vrf
->name_pretty
);
1016 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
1017 bn
= bgp_route_next(bn
)) {
1020 zlog_debug("%s: node=%p", __func__
, bn
);
1022 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1025 "%s: calling vpn_leak_from_vrf_update",
1027 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bi
);
1032 static void vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1033 struct bgp
*bgp_vpn
, /* from */
1034 struct bgp_info
*info_vpn
) /* route */
1036 struct prefix
*p
= &info_vpn
->net
->p
;
1037 afi_t afi
= family2afi(p
->family
);
1039 struct attr static_attr
= {0};
1040 struct attr
*new_attr
= NULL
;
1041 struct bgp_node
*bn
;
1042 safi_t safi
= SAFI_UNICAST
;
1043 const char *debugmsg
;
1044 struct prefix nexthop_orig
;
1045 mpls_label_t
*pLabels
= NULL
;
1046 uint32_t num_labels
= 0;
1047 int nexthop_self_flag
= 1;
1048 struct bgp_info
*bi_ultimate
= NULL
;
1049 int origin_local
= 0;
1050 struct bgp
*src_vrf
;
1052 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1054 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1056 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1060 /* Check for intersection of route targets */
1061 if (!ecom_intersect(
1062 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1063 info_vpn
->attr
->ecommunity
)) {
1069 zlog_debug("%s: updating to vrf %s", __func__
,
1070 bgp_vrf
->name_pretty
);
1072 bgp_attr_dup(&static_attr
, info_vpn
->attr
); /* shallow copy */
1075 * Nexthop: stash and clear
1077 * Nexthop is valid in context of VPN core, but not in destination vrf.
1078 * Stash it for later label resolution by vrf ingress path and then
1079 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1081 uint8_t nhfamily
= NEXTHOP_FAMILY(info_vpn
->attr
->mp_nexthop_len
);
1083 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1084 nexthop_orig
.family
= nhfamily
;
1089 nexthop_orig
.u
.prefix4
= info_vpn
->attr
->mp_nexthop_global_in
;
1090 nexthop_orig
.prefixlen
= 32;
1092 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1093 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1094 static_attr
.nexthop
.s_addr
=
1095 nexthop_orig
.u
.prefix4
.s_addr
;
1097 static_attr
.mp_nexthop_global_in
=
1098 info_vpn
->attr
->mp_nexthop_global_in
;
1099 static_attr
.mp_nexthop_len
=
1100 info_vpn
->attr
->mp_nexthop_len
;
1102 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1106 nexthop_orig
.u
.prefix6
= info_vpn
->attr
->mp_nexthop_global
;
1107 nexthop_orig
.prefixlen
= 128;
1109 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1110 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1111 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1117 * route map handling
1119 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1120 struct bgp_info info
;
1121 route_map_result_t ret
;
1123 memset(&info
, 0, sizeof(info
));
1124 info
.peer
= bgp_vrf
->peer_self
;
1125 info
.attr
= &static_attr
;
1126 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1127 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1128 p
, RMAP_BGP
, &info
);
1129 if (RMAP_DENYMATCH
== ret
) {
1130 bgp_attr_flush(&static_attr
); /* free any added parts */
1133 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1134 __func__
, bgp_vrf
->name_pretty
,
1135 bgp_vrf
->vpn_policy
[afi
]
1136 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1141 * if route-map changed nexthop, don't nexthop-self on output
1143 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1144 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1145 nexthop_self_flag
= 0;
1148 new_attr
= bgp_attr_intern(&static_attr
);
1149 bgp_attr_flush(&static_attr
);
1151 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1154 * ensure labels are copied
1156 * However, there is a special case: if the route originated in
1157 * another local VRF (as opposed to arriving via VPN), then the
1158 * nexthop is reached by hairpinning through this router (me)
1159 * using IP forwarding only (no LSP). Therefore, the route
1160 * imported to the VRF should not have labels attached. Note
1161 * that nexthop tracking is also involved: eliminating the
1162 * labels for these routes enables the non-labeled nexthops
1163 * from the originating VRF to be considered valid for this route.
1165 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1166 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1167 /* work back to original route */
1168 for (bi_ultimate
= info_vpn
;
1169 bi_ultimate
->extra
&& bi_ultimate
->extra
->parent
;
1170 bi_ultimate
= bi_ultimate
->extra
->parent
)
1174 * if original route was unicast,
1175 * then it did not arrive over vpn
1177 if (bi_ultimate
->net
) {
1178 struct bgp_table
*table
;
1180 table
= bgp_node_table(bi_ultimate
->net
);
1181 if (table
&& (table
->safi
== SAFI_UNICAST
))
1186 if (!origin_local
&&
1187 info_vpn
->extra
&& info_vpn
->extra
->num_labels
) {
1188 num_labels
= info_vpn
->extra
->num_labels
;
1189 if (num_labels
> BGP_MAX_LABELS
)
1190 num_labels
= BGP_MAX_LABELS
;
1191 pLabels
= info_vpn
->extra
->label
;
1196 char buf_prefix
[PREFIX_STRLEN
];
1197 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
1198 zlog_debug("%s: pfx %s: num_labels %d", __func__
, buf_prefix
,
1203 * For VRF-2-VRF route-leaking,
1204 * the source will be the originating VRF.
1206 if (info_vpn
->extra
&& info_vpn
->extra
->bgp_orig
)
1207 src_vrf
= info_vpn
->extra
->bgp_orig
;
1211 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, info_vpn
,
1212 pLabels
, num_labels
,
1213 info_vpn
, /* parent */
1214 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1217 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1218 struct bgp_info
*info_vpn
) /* route */
1220 struct listnode
*mnode
, *mnnode
;
1223 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1226 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1228 /* Loop over VRFs */
1229 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1231 if (!info_vpn
->extra
1232 || info_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1233 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, info_vpn
);
1238 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1239 struct bgp_info
*info_vpn
) /* route */
1243 safi_t safi
= SAFI_UNICAST
;
1245 struct listnode
*mnode
, *mnnode
;
1246 struct bgp_node
*bn
;
1247 struct bgp_info
*bi
;
1248 const char *debugmsg
;
1249 char buf_prefix
[PREFIX_STRLEN
];
1251 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1254 prefix2str(&info_vpn
->net
->p
, buf_prefix
, sizeof(buf_prefix
));
1255 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1256 __func__
, buf_prefix
,
1257 info_vpn
->type
, info_vpn
->sub_type
);
1261 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1263 if (!info_vpn
->net
) {
1265 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1266 if (info_vpn
->type
== ZEBRA_ROUTE_BGP
&&
1267 info_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1273 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1278 p
= &info_vpn
->net
->p
;
1279 afi
= family2afi(p
->family
);
1281 /* Loop over VRFs */
1282 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1283 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1285 zlog_debug("%s: skipping: %s", __func__
,
1290 /* Check for intersection of route targets */
1291 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1292 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1293 info_vpn
->attr
->ecommunity
)) {
1299 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1302 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1303 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
1305 && (struct bgp_info
*)bi
->extra
->parent
1313 zlog_debug("%s: deleting bi %p", __func__
, bi
);
1314 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
1315 bgp_info_delete(bn
, bi
);
1316 bgp_process(bgp
, bn
, afi
, safi
);
1318 bgp_unlock_node(bn
);
1322 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1325 struct bgp_node
*bn
;
1326 struct bgp_info
*bi
;
1327 safi_t safi
= SAFI_UNICAST
;
1328 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1331 zlog_debug("%s: entry", __func__
);
1333 * Walk vrf table, delete bi with bgp_orig in a different vrf
1335 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1336 bn
= bgp_route_next(bn
)) {
1338 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1339 if (bi
->extra
&& bi
->extra
->bgp_orig
!= bgp_vrf
) {
1342 bgp_aggregate_decrement(bgp_vrf
, &bn
->p
, bi
,
1344 bgp_info_delete(bn
, bi
);
1345 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1351 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1352 struct bgp
*bgp_vpn
, /* from */
1355 struct prefix_rd prd
;
1356 struct bgp_node
*prn
;
1357 safi_t safi
= SAFI_MPLS_VPN
;
1364 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
1365 prn
= bgp_route_next(prn
)) {
1367 struct bgp_table
*table
;
1368 struct bgp_node
*bn
;
1369 struct bgp_info
*bi
;
1371 memset(&prd
, 0, sizeof(prd
));
1372 prd
.family
= AF_UNSPEC
;
1374 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
1376 /* This is the per-RD table of prefixes */
1382 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1384 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1386 if (bi
->extra
&& bi
->extra
->bgp_orig
== bgp_vrf
)
1389 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1397 * This function is called for definition/deletion/change to a route-map
1399 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1401 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1403 struct route_map
*rmap
;
1405 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1406 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1411 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1413 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1415 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1416 && !strcmp(rmap_name
,
1417 bgp
->vpn_policy
[afi
]
1418 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1422 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1423 __func__
, rmap_name
, bgp
->as
,
1426 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1427 bgp_get_default(), bgp
);
1429 zlog_debug("%s: after vpn_leak_prechange",
1432 /* in case of definition/deletion */
1433 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1436 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1437 bgp_get_default(), bgp
);
1440 zlog_debug("%s: after vpn_leak_postchange",
1444 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1445 && !strcmp(rmap_name
,
1446 bgp
->vpn_policy
[afi
]
1447 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1450 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1451 __func__
, rmap_name
, bgp
->as
,
1455 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1456 bgp_get_default(), bgp
);
1458 /* in case of definition/deletion */
1459 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1462 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1463 bgp_get_default(), bgp
);
1468 void vpn_policy_routemap_event(const char *rmap_name
)
1470 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1471 struct listnode
*mnode
, *mnnode
;
1475 zlog_debug("%s: entry", __func__
);
1477 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1480 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1481 vpn_policy_routemap_update(bgp
, rmap_name
);
1484 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1485 afi_t afi
, safi_t safi
)
1487 const char *export_name
;
1488 vpn_policy_direction_t idir
, edir
;
1491 struct ecommunity
*ecom
;
1492 bool first_export
= false;
1494 export_name
= to_bgp
->name
? to_bgp
->name
: BGP_DEFAULT_NAME
;
1495 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1496 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1499 * Cross-ref both VRFs. Also, note if this is the first time
1500 * any VRF is importing from "import_vrf".
1502 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
1503 : XSTRDUP(MTYPE_TMP
, BGP_DEFAULT_NAME
));
1505 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1507 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
))
1508 first_export
= true;
1509 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
1510 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1512 /* Update import RT for current VRF using export RT of the VRF we're
1513 * importing from. First though, make sure "import_vrf" has that
1517 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
1518 &from_bgp
->vrf_prd_auto
);
1519 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
1520 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1521 BGP_VPN_POLICY_TOVPN_RD_SET
);
1522 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
1524 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1525 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
1526 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1527 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1528 from_bgp
->vpn_policy
[afi
].tovpn_label
=
1529 BGP_PREVENT_VRF_2_VRF_LEAK
;
1531 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1532 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
1533 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
1534 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
1535 .rtlist
[idir
], ecom
);
1537 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
1538 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1540 /* Does "import_vrf" first need to export its routes or that
1541 * is already done and we just need to import those routes
1542 * from the global table?
1545 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
1547 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1550 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1551 afi_t afi
, safi_t safi
)
1553 const char *export_name
, *tmp_name
;
1554 vpn_policy_direction_t idir
, edir
;
1556 struct ecommunity
*ecom
;
1557 struct listnode
*node
;
1559 export_name
= to_bgp
->name
? to_bgp
->name
: BGP_DEFAULT_NAME
;
1560 tmp_name
= from_bgp
->name
? from_bgp
->name
: BGP_DEFAULT_NAME
;
1561 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1562 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1564 /* Were we importing from "import_vrf"? */
1565 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
1567 if (strcmp(vname
, tmp_name
) == 0)
1572 * We do not check in the cli if the passed in bgp
1573 * instance is actually imported into us before
1574 * we call this function. As such if we do not
1575 * find this in the import_vrf list than
1576 * we just need to return safely.
1581 /* Remove "import_vrf" from our import list. */
1582 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1583 XFREE(MTYPE_TMP
, vname
);
1585 /* Remove routes imported from "import_vrf". */
1586 /* TODO: In the current logic, we have to first remove all
1587 * imported routes and then (if needed) import back routes
1589 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
1591 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
1592 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
1593 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1594 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
1596 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1597 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
1598 (struct ecommunity_val
*)ecom
->val
);
1599 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
1604 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1605 * below is checking for NULL that export_vrf can be
1606 * NULL, consequently it is complaining( like a cabbage )
1607 * that we could dereference and crash in the listcount(..)
1609 * So make it happy, under protest, with liberty and justice
1612 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
1614 /* Remove us from "import_vrf's" export list. If no other VRF
1615 * is importing from "import_vrf", cleanup appropriately.
1617 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1619 if (strcmp(vname
, export_name
) == 0)
1624 * If we have gotten to this point then the vname must
1625 * exist. If not, we are in a world of trouble and
1626 * have slag sitting around.
1628 * import_vrf and export_vrf must match in having
1629 * the in/out names as appropriate.
1633 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1634 XFREE(MTYPE_TMP
, vname
);
1636 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1637 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
1638 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
1639 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
1640 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1641 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
1642 sizeof(struct prefix_rd
));
1643 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
1644 BGP_VPN_POLICY_TOVPN_RD_SET
);
1645 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
1650 /* For testing purpose, static route of MPLS-VPN. */
1651 DEFUN (vpnv4_network
,
1653 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1654 "Specify a network to announce via BGP\n"
1656 "Specify Route Distinguisher\n"
1657 "VPN Route Distinguisher\n"
1658 "VPN NLRI label (tag)\n"
1659 "VPN NLRI label (tag)\n"
1662 int idx_ipv4_prefixlen
= 1;
1663 int idx_ext_community
= 3;
1665 return bgp_static_set_safi(
1666 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1667 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1668 NULL
, NULL
, NULL
, NULL
);
1671 DEFUN (vpnv4_network_route_map
,
1672 vpnv4_network_route_map_cmd
,
1673 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1674 "Specify a network to announce via BGP\n"
1676 "Specify Route Distinguisher\n"
1677 "VPN Route Distinguisher\n"
1678 "VPN NLRI label (tag)\n"
1679 "VPN NLRI label (tag)\n"
1684 int idx_ipv4_prefixlen
= 1;
1685 int idx_ext_community
= 3;
1688 return bgp_static_set_safi(
1689 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1690 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1691 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1694 /* For testing purpose, static route of MPLS-VPN. */
1695 DEFUN (no_vpnv4_network
,
1696 no_vpnv4_network_cmd
,
1697 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1699 "Specify a network to announce via BGP\n"
1701 "Specify Route Distinguisher\n"
1702 "VPN Route Distinguisher\n"
1703 "VPN NLRI label (tag)\n"
1704 "VPN NLRI label (tag)\n"
1707 int idx_ipv4_prefixlen
= 2;
1708 int idx_ext_community
= 4;
1710 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1711 argv
[idx_ipv4_prefixlen
]->arg
,
1712 argv
[idx_ext_community
]->arg
,
1713 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1716 DEFUN (vpnv6_network
,
1718 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1719 "Specify a network to announce via BGP\n"
1720 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1721 "Specify Route Distinguisher\n"
1722 "VPN Route Distinguisher\n"
1723 "VPN NLRI label (tag)\n"
1724 "VPN NLRI label (tag)\n"
1729 int idx_ipv6_prefix
= 1;
1730 int idx_ext_community
= 3;
1734 return bgp_static_set_safi(
1735 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1736 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1737 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1739 return bgp_static_set_safi(
1740 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1741 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1742 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1745 /* For testing purpose, static route of MPLS-VPN. */
1746 DEFUN (no_vpnv6_network
,
1747 no_vpnv6_network_cmd
,
1748 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1750 "Specify a network to announce via BGP\n"
1751 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1752 "Specify Route Distinguisher\n"
1753 "VPN Route Distinguisher\n"
1754 "VPN NLRI label (tag)\n"
1755 "VPN NLRI label (tag)\n"
1758 int idx_ipv6_prefix
= 2;
1759 int idx_ext_community
= 4;
1761 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
1762 argv
[idx_ipv6_prefix
]->arg
,
1763 argv
[idx_ext_community
]->arg
,
1764 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1767 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
1768 enum bgp_show_type type
, void *output_arg
, int tags
,
1772 struct bgp_table
*table
;
1774 bgp
= bgp_get_default();
1777 vty_out(vty
, "No BGP process is configured\n");
1779 vty_out(vty
, "{}\n");
1782 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
1783 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
1784 output_arg
, use_json
);
1787 DEFUN (show_bgp_ip_vpn_all_rd
,
1788 show_bgp_ip_vpn_all_rd_cmd
,
1789 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1793 "Display VPN NLRI specific information\n"
1794 "Display VPN NLRI specific information\n"
1795 "Display information for a route distinguisher\n"
1796 "VPN Route Distinguisher\n"
1800 struct prefix_rd prd
;
1804 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1805 if (argv_find(argv
, argc
, "rd", &idx
)) {
1806 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
1809 "%% Malformed Route Distinguisher\n");
1812 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
1813 bgp_show_type_normal
, NULL
, 0,
1814 use_json(argc
, argv
));
1816 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
1817 bgp_show_type_normal
, NULL
, 0,
1818 use_json(argc
, argv
));
1824 ALIAS(show_bgp_ip_vpn_all_rd
,
1825 show_bgp_ip_vpn_rd_cmd
,
1826 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1830 "Display VPN NLRI specific information\n"
1831 "Display information for a route distinguisher\n"
1832 "VPN Route Distinguisher\n"
1835 #ifdef KEEP_OLD_VPN_COMMANDS
1836 DEFUN (show_ip_bgp_vpn_rd
,
1837 show_ip_bgp_vpn_rd_cmd
,
1838 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
1843 "Address Family modifier\n"
1844 "Display information for a route distinguisher\n"
1845 "VPN Route Distinguisher\n")
1847 int idx_ext_community
= argc
- 1;
1849 struct prefix_rd prd
;
1853 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1854 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1856 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1859 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1865 DEFUN (show_ip_bgp_vpn_all
,
1866 show_ip_bgp_vpn_all_cmd
,
1867 "show [ip] bgp <vpnv4|vpnv6>",
1876 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1877 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1882 DEFUN (show_ip_bgp_vpn_all_tags
,
1883 show_ip_bgp_vpn_all_tags_cmd
,
1884 "show [ip] bgp <vpnv4|vpnv6> all tags",
1889 "Display information about all VPNv4/VPNV6 NLRIs\n"
1890 "Display BGP tags for prefixes\n")
1895 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1896 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1901 DEFUN (show_ip_bgp_vpn_rd_tags
,
1902 show_ip_bgp_vpn_rd_tags_cmd
,
1903 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
1908 "Display information for a route distinguisher\n"
1909 "VPN Route Distinguisher\n"
1910 "Display BGP tags for prefixes\n")
1912 int idx_ext_community
= 5;
1914 struct prefix_rd prd
;
1918 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1919 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1921 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1924 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1930 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1931 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1932 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1937 "Display information about all VPNv4/VPNv6 NLRIs\n"
1938 "Detailed information on TCP and BGP neighbor connections\n"
1939 "Neighbor to display information about\n"
1940 "Display routes learned from neighbor\n"
1947 uint8_t uj
= use_json(argc
, argv
);
1951 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1952 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1955 json_object
*json_no
= NULL
;
1956 json_no
= json_object_new_object();
1957 json_object_string_add(json_no
, "warning",
1958 "Malformed address");
1959 vty_out(vty
, "%s\n",
1960 json_object_to_json_string(json_no
));
1961 json_object_free(json_no
);
1963 vty_out(vty
, "Malformed address: %s\n",
1964 argv
[idx_ipv4
]->arg
);
1968 peer
= peer_lookup(NULL
, &su
);
1969 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1971 json_object
*json_no
= NULL
;
1972 json_no
= json_object_new_object();
1973 json_object_string_add(
1975 "No such neighbor or address family");
1976 vty_out(vty
, "%s\n",
1977 json_object_to_json_string(json_no
));
1978 json_object_free(json_no
);
1981 "%% No such neighbor or address family\n");
1985 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
1991 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
1992 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
1993 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
1998 "Display information for a route distinguisher\n"
1999 "VPN Route Distinguisher\n"
2000 "Detailed information on TCP and BGP neighbor connections\n"
2001 "Neighbor to display information about\n"
2002 "Display routes learned from neighbor\n"
2005 int idx_ext_community
= 5;
2010 struct prefix_rd prd
;
2011 uint8_t uj
= use_json(argc
, argv
);
2015 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2016 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2019 json_object
*json_no
= NULL
;
2020 json_no
= json_object_new_object();
2021 json_object_string_add(
2023 "Malformed Route Distinguisher");
2024 vty_out(vty
, "%s\n",
2025 json_object_to_json_string(json_no
));
2026 json_object_free(json_no
);
2029 "%% Malformed Route Distinguisher\n");
2033 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2036 json_object
*json_no
= NULL
;
2037 json_no
= json_object_new_object();
2038 json_object_string_add(json_no
, "warning",
2039 "Malformed address");
2040 vty_out(vty
, "%s\n",
2041 json_object_to_json_string(json_no
));
2042 json_object_free(json_no
);
2044 vty_out(vty
, "Malformed address: %s\n",
2045 argv
[idx_ext_community
]->arg
);
2049 peer
= peer_lookup(NULL
, &su
);
2050 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2052 json_object
*json_no
= NULL
;
2053 json_no
= json_object_new_object();
2054 json_object_string_add(
2056 "No such neighbor or address family");
2057 vty_out(vty
, "%s\n",
2058 json_object_to_json_string(json_no
));
2059 json_object_free(json_no
);
2062 "%% No such neighbor or address family\n");
2066 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
2072 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2073 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2074 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2079 "Display information about all VPNv4/VPNv6 NLRIs\n"
2080 "Detailed information on TCP and BGP neighbor connections\n"
2081 "Neighbor to display information about\n"
2082 "Display the routes advertised to a BGP neighbor\n"
2089 uint8_t uj
= use_json(argc
, argv
);
2093 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2094 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2097 json_object
*json_no
= NULL
;
2098 json_no
= json_object_new_object();
2099 json_object_string_add(json_no
, "warning",
2100 "Malformed address");
2101 vty_out(vty
, "%s\n",
2102 json_object_to_json_string(json_no
));
2103 json_object_free(json_no
);
2105 vty_out(vty
, "Malformed address: %s\n",
2106 argv
[idx_ipv4
]->arg
);
2109 peer
= peer_lookup(NULL
, &su
);
2110 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2112 json_object
*json_no
= NULL
;
2113 json_no
= json_object_new_object();
2114 json_object_string_add(
2116 "No such neighbor or address family");
2117 vty_out(vty
, "%s\n",
2118 json_object_to_json_string(json_no
));
2119 json_object_free(json_no
);
2122 "%% No such neighbor or address family\n");
2125 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2131 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2132 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2133 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2138 "Display information for a route distinguisher\n"
2139 "VPN Route Distinguisher\n"
2140 "Detailed information on TCP and BGP neighbor connections\n"
2141 "Neighbor to display information about\n"
2142 "Display the routes advertised to a BGP neighbor\n"
2145 int idx_ext_community
= 5;
2149 struct prefix_rd prd
;
2151 uint8_t uj
= use_json(argc
, argv
);
2155 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2156 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2159 json_object
*json_no
= NULL
;
2160 json_no
= json_object_new_object();
2161 json_object_string_add(json_no
, "warning",
2162 "Malformed address");
2163 vty_out(vty
, "%s\n",
2164 json_object_to_json_string(json_no
));
2165 json_object_free(json_no
);
2167 vty_out(vty
, "Malformed address: %s\n",
2168 argv
[idx_ext_community
]->arg
);
2171 peer
= peer_lookup(NULL
, &su
);
2172 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2174 json_object
*json_no
= NULL
;
2175 json_no
= json_object_new_object();
2176 json_object_string_add(
2178 "No such neighbor or address family");
2179 vty_out(vty
, "%s\n",
2180 json_object_to_json_string(json_no
));
2181 json_object_free(json_no
);
2184 "%% No such neighbor or address family\n");
2188 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2191 json_object
*json_no
= NULL
;
2192 json_no
= json_object_new_object();
2193 json_object_string_add(
2195 "Malformed Route Distinguisher");
2196 vty_out(vty
, "%s\n",
2197 json_object_to_json_string(json_no
));
2198 json_object_free(json_no
);
2201 "%% Malformed Route Distinguisher\n");
2205 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2210 #endif /* KEEP_OLD_VPN_COMMANDS */
2212 void bgp_mplsvpn_init(void)
2214 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2215 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2216 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2218 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2219 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2221 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2222 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2223 #ifdef KEEP_OLD_VPN_COMMANDS
2224 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2225 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2226 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2227 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2228 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2229 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2230 install_element(VIEW_NODE
,
2231 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2232 install_element(VIEW_NODE
,
2233 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2234 #endif /* KEEP_OLD_VPN_COMMANDS */
2237 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2239 struct listnode
*mnode
, *mnnode
;
2242 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2243 struct ecommunity
*ec
;
2245 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2248 ec
= bgp
->vpn_policy
[AFI_IP
].import_redirect_rtlist
;
2250 if (ecom_intersect(ec
, eckey
))
2257 * The purpose of this function is to process leaks that were deferred
2258 * from earlier per-vrf configuration due to not-yet-existing default
2259 * vrf, in other words, configuration such as:
2261 * router bgp MMM vrf FOO
2262 * address-family ipv4 unicast
2264 * exit-address-family
2269 * This function gets called when the default instance ("router bgp NNN")
2272 void vpn_leak_postchange_all(void)
2274 struct listnode
*next
;
2276 struct bgp
*bgp_default
= bgp_get_default();
2278 assert(bgp_default
);
2280 /* First, do any exporting from VRFs to the single VPN RIB */
2281 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2283 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2286 vpn_leak_postchange(
2287 BGP_VPN_POLICY_DIR_TOVPN
,
2292 vpn_leak_postchange(
2293 BGP_VPN_POLICY_DIR_TOVPN
,
2299 /* Now, do any importing to VRFs from the single VPN RIB */
2300 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2302 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2305 vpn_leak_postchange(
2306 BGP_VPN_POLICY_DIR_FROMVPN
,
2311 vpn_leak_postchange(
2312 BGP_VPN_POLICY_DIR_FROMVPN
,