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 *pnt
++ = (label
>> 12) & 0xff;
91 *pnt
++ = (label
>> 4) & 0xff;
92 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
95 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
96 struct bgp_nlri
*packet
)
106 struct prefix_rd prd
;
107 mpls_label_t label
= {0};
114 prd
.family
= AF_UNSPEC
;
118 lim
= pnt
+ packet
->length
;
124 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
125 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
126 PEER_CAP_ADDPATH_AF_TX_RCV
));
128 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
129 for (; pnt
< lim
; pnt
+= psize
) {
130 /* Clear prefix structure. */
131 memset(&p
, 0, sizeof(struct prefix
));
133 if (addpath_encoded
) {
135 /* When packet overflow occurs return immediately. */
136 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
139 addpath_id
= ntohl(*((uint32_t *)pnt
));
140 pnt
+= BGP_ADDPATH_ID_LEN
;
143 /* Fetch prefix length. */
145 p
.family
= afi2family(packet
->afi
);
146 psize
= PSIZE(prefixlen
);
148 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
150 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
151 peer
->host
, prefixlen
);
155 /* sanity check against packet data */
156 if ((pnt
+ psize
) > lim
) {
158 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
159 peer
->host
, prefixlen
, (uint
)(lim
- pnt
));
163 /* sanity check against storage for the IP address portion */
164 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
166 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
168 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
173 /* Sanity check against max bitlen of the address family */
174 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
176 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
178 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
179 p
.family
, prefix_blen(&p
));
183 /* Copy label to prefix. */
184 memcpy(&label
, pnt
, BGP_LABEL_BYTES
);
185 bgp_set_valid_label(&label
);
187 /* Copy routing distinguisher to rd. */
188 memcpy(&prd
.val
, pnt
+ BGP_LABEL_BYTES
, 8);
190 /* Decode RD type. */
191 type
= decode_rd_type(pnt
+ BGP_LABEL_BYTES
);
195 decode_rd_as(pnt
+ 5, &rd_as
);
199 decode_rd_as4(pnt
+ 5, &rd_as
);
203 decode_rd_ip(pnt
+ 5, &rd_ip
);
207 case RD_TYPE_VNC_ETH
:
212 zlog_err("Unknown RD type %d", type
);
213 break; /* just report */
218 - VPN_PREFIXLEN_MIN_BYTES
* 8; /* exclude label & RD */
219 memcpy(&p
.u
.prefix
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
220 psize
- VPN_PREFIXLEN_MIN_BYTES
);
223 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
224 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
225 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
227 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
228 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
229 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
232 /* Packet length consistency check. */
235 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
236 peer
->host
, lim
- pnt
);
241 #undef VPN_PREFIXLEN_MIN_BYTES
245 * This function informs zebra of the label this vrf sets on routes
246 * leaked to VPN. Zebra should install this label in the kernel with
247 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
249 * Sending this vrf-label association is qualified by a) whether vrf->vpn
250 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
251 * are set) and b) whether vpn-policy label is set.
253 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
254 * for this vrf, which zebra interprets to mean "delete this vrf-label
257 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
259 mpls_label_t label
= MPLS_LABEL_NONE
;
260 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
262 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
265 "%s: vrf %s: afi %s: vrf_id not set, "
266 "can't set zebra vrf label",
267 __func__
, bgp
->name_pretty
, afi2str(afi
));
272 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
273 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
277 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
278 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
282 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
283 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
287 * If zebra tells us vrf has become unconfigured, tell zebra not to
288 * use this label to forward to the vrf anymore
290 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
292 mpls_label_t label
= MPLS_LABEL_NONE
;
293 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
295 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
298 "%s: vrf_id not set, can't delete zebra vrf label",
305 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
306 bgp
->name_pretty
, bgp
->vrf_id
);
309 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
310 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
313 int vpn_leak_label_callback(
318 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
319 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
322 zlog_debug("%s: label=%u, allocated=%d",
323 __func__
, label
, allocated
);
327 * previously-allocated label is now invalid
329 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
330 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
332 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
333 vp
->afi
, bgp_get_default(), vp
->bgp
);
334 vp
->tovpn_label
= MPLS_LABEL_NONE
;
335 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
336 vp
->afi
, bgp_get_default(), vp
->bgp
);
342 * New label allocation
344 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
347 * not currently configured for auto label, reject allocation
352 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
353 if (label
== vp
->tovpn_label
) {
354 /* already have same label, accept but do nothing */
357 /* Shouldn't happen: different label allocation */
358 zlog_err("%s: %s had label %u but got new assignment %u",
359 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
, label
);
363 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
364 vp
->afi
, bgp_get_default(), vp
->bgp
);
365 vp
->tovpn_label
= label
;
366 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
367 vp
->afi
, bgp_get_default(), vp
->bgp
);
372 static int ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
380 for (i
= 0; i
< e1
->size
; ++i
) {
381 for (j
= 0; j
< e2
->size
; ++j
) {
382 if (!memcmp(e1
->val
+ (i
* ECOMMUNITY_SIZE
),
383 e2
->val
+ (j
* ECOMMUNITY_SIZE
),
393 static bool labels_same(struct bgp_info
*bi
, mpls_label_t
*label
, uint32_t n
)
404 if (n
!= bi
->extra
->num_labels
)
407 for (i
= 0; i
< n
; ++i
) {
408 if (label
[i
] != bi
->extra
->label
[i
])
415 * make encoded route labels match specified encoded label set
417 static void setlabels(
419 mpls_label_t
*label
, /* array of labels */
424 assert(num_labels
<= BGP_MAX_LABELS
);
428 bi
->extra
->num_labels
= 0;
432 struct bgp_info_extra
*extra
= bgp_info_extra_get(bi
);
435 for (i
= 0; i
< num_labels
; ++i
) {
436 extra
->label
[i
] = label
[i
];
437 if (!bgp_is_valid_label(&label
[i
])) {
438 bgp_set_valid_label(&extra
->label
[i
]);
441 extra
->num_labels
= num_labels
;
445 * returns pointer to new bgp_info upon success
447 static struct bgp_info
*
449 struct bgp
*bgp
, /* destination bgp instance */
451 struct attr
*new_attr
, /* already interned */
454 struct bgp_info
*source_bi
,
458 struct bgp
*bgp_orig
,
459 struct prefix
*nexthop_orig
,
460 int nexthop_self_flag
,
463 struct prefix
*p
= &bn
->p
;
465 struct bgp_info
*new;
466 char buf_prefix
[PREFIX_STRLEN
];
469 prefix2str(&bn
->p
, buf_prefix
, sizeof(buf_prefix
));
470 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
471 __func__
, bgp
->name_pretty
, buf_prefix
,
472 source_bi
->type
, source_bi
->sub_type
);
478 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
479 if (bi
->extra
&& bi
->extra
->parent
== parent
)
484 bool labelssame
= labels_same(bi
, label
, num_labels
);
486 if (attrhash_cmp(bi
->attr
, new_attr
)
488 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
490 bgp_attr_unintern(&new_attr
);
493 "%s: ->%s: %s: Found route, no change",
494 __func__
, bgp
->name_pretty
,
499 /* attr is changed */
500 bgp_info_set_flag(bn
, bi
, BGP_INFO_ATTR_CHANGED
);
502 /* Rewrite BGP route information. */
503 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
504 bgp_info_restore(bn
, bi
);
506 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
507 bgp_attr_unintern(&bi
->attr
);
509 bi
->uptime
= bgp_clock();
515 setlabels(bi
, label
, num_labels
);
517 if (nexthop_self_flag
)
518 bgp_info_set_flag(bn
, bi
, BGP_INFO_ANNC_NH_SELF
);
520 struct bgp
*bgp_nexthop
= bgp
;
523 if (bi
->extra
&& bi
->extra
->bgp_orig
)
524 bgp_nexthop
= bi
->extra
->bgp_orig
;
526 /* No nexthop tracking for redistributed routes */
527 if (source_bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
531 * TBD do we need to do anything about the
532 * 'connected' parameter?
534 nh_valid
= bgp_find_or_add_nexthop(
539 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
540 __func__
, (nh_valid
? "" : "not "),
541 bgp_nexthop
->name_pretty
);
544 bgp_info_set_flag(bn
, bi
, BGP_INFO_VALID
);
546 /* Process change. */
547 bgp_aggregate_increment(bgp
, p
, bi
, afi
, safi
);
548 bgp_process(bgp
, bn
, afi
, safi
);
552 zlog_debug("%s: ->%s: %s Found route, changed attr",
553 __func__
, bgp
->name_pretty
, buf_prefix
);
558 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
559 bgp
->peer_self
, new_attr
, bn
);
561 if (nexthop_self_flag
)
562 bgp_info_set_flag(bn
, new, BGP_INFO_ANNC_NH_SELF
);
565 setlabels(new, label
, num_labels
);
567 bgp_info_extra_get(new);
568 new->extra
->parent
= parent
;
571 new->extra
->bgp_orig
= bgp_orig
;
573 new->extra
->nexthop_orig
= *nexthop_orig
;
576 * nexthop tracking for unicast routes
578 struct bgp
*bgp_nexthop
= bgp
;
581 if (new->extra
&& new->extra
->bgp_orig
)
582 bgp_nexthop
= new->extra
->bgp_orig
;
585 * No nexthop tracking for redistributed routes because
586 * their originating protocols will do the tracking and
587 * withdraw those routes if the nexthops become unreachable
589 if (source_bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
593 * TBD do we need to do anything about the
594 * 'connected' parameter?
596 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
600 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
601 __func__
, (nh_valid
? "" : "not "),
602 bgp_nexthop
->name_pretty
);
604 bgp_info_set_flag(bn
, new, BGP_INFO_VALID
);
606 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
607 bgp_info_add(bn
, new);
610 bgp_process(bgp
, bn
, afi
, safi
);
613 zlog_debug("%s: ->%s: %s: Added new route", __func__
,
614 bgp
->name_pretty
, buf_prefix
);
619 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
620 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
621 struct bgp
*bgp_vrf
, /* from */
622 struct bgp_info
*info_vrf
) /* route */
624 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
625 struct prefix
*p
= &info_vrf
->net
->p
;
626 afi_t afi
= family2afi(p
->family
);
627 struct attr static_attr
= {0};
628 struct attr
*new_attr
= NULL
;
629 safi_t safi
= SAFI_MPLS_VPN
;
630 mpls_label_t label_val
;
633 const char *debugmsg
;
634 int nexthop_self_flag
= 0;
637 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
639 if (debug
&& info_vrf
->attr
->ecommunity
) {
640 char *s
= ecommunity_ecom2str(info_vrf
->attr
->ecommunity
,
641 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
643 zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__
,
644 bgp_vrf
->name
, info_vrf
->type
, s
);
645 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
653 zlog_debug("%s: can't get afi of prefix", __func__
);
657 /* loop check - should not be an imported route. */
658 if (info_vrf
->extra
&& info_vrf
->extra
->bgp_orig
)
662 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
664 zlog_debug("%s: %s skipping: %s", __func__
,
665 bgp_vrf
->name
, debugmsg
);
669 bgp_attr_dup(&static_attr
, info_vrf
->attr
); /* shallow copy */
674 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
675 struct bgp_info info
;
676 route_map_result_t ret
;
678 memset(&info
, 0, sizeof(info
));
679 info
.peer
= bgp_vpn
->peer_self
;
680 info
.attr
= &static_attr
;
681 ret
= route_map_apply(
682 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
684 if (RMAP_DENYMATCH
== ret
) {
685 bgp_attr_flush(&static_attr
); /* free any added parts */
688 "%s: vrf %s route map \"%s\" says DENY, returning",
689 __func__
, bgp_vrf
->name_pretty
,
690 bgp_vrf
->vpn_policy
[afi
]
691 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
697 if (debug
&& static_attr
.ecommunity
) {
698 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
699 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
701 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
703 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
707 * Add the vpn-policy rt-list
709 struct ecommunity
*old_ecom
;
710 struct ecommunity
*new_ecom
;
712 old_ecom
= static_attr
.ecommunity
;
714 new_ecom
= ecommunity_merge(
715 ecommunity_dup(old_ecom
),
716 bgp_vrf
->vpn_policy
[afi
]
717 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
718 if (!old_ecom
->refcnt
)
719 ecommunity_free(&old_ecom
);
721 new_ecom
= ecommunity_dup(
722 bgp_vrf
->vpn_policy
[afi
]
723 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
725 static_attr
.ecommunity
= new_ecom
;
726 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
728 if (debug
&& static_attr
.ecommunity
) {
729 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
730 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
732 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
734 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
738 /* if policy nexthop not set, use 0 */
739 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
740 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
741 struct prefix
*nexthop
=
742 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
744 switch (nexthop
->family
) {
746 /* prevent mp_nexthop_global_in <- self in bgp_route.c
748 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
750 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
751 static_attr
.mp_nexthop_len
= 4;
755 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
756 static_attr
.mp_nexthop_len
= 16;
763 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
764 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
766 /* For ipv4, copy to multiprotocol nexthop field */
767 static_attr
.mp_nexthop_global_in
= static_attr
.nexthop
;
768 static_attr
.mp_nexthop_len
= 4;
769 /* XXX Leave static_attr.nexthop intact for NHT */
770 static_attr
.flag
&= ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
773 /* Update based on next-hop family to account for
774 * RFC 5549 (BGP unnumbered) scenario. Note that
775 * specific action is only needed for the case of
776 * IPv4 nexthops as the attr has been copied
780 !BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf
->attr
)) {
781 static_attr
.mp_nexthop_global_in
.s_addr
=
782 static_attr
.nexthop
.s_addr
;
783 static_attr
.mp_nexthop_len
= 4;
785 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
788 nexthop_self_flag
= 1;
791 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
792 if (label_val
== MPLS_LABEL_NONE
) {
793 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
795 encode_label(label_val
, &label
);
798 /* Set originator ID to "me" */
799 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
800 static_attr
.originator_id
= bgp_vpn
->router_id
;
803 new_attr
= bgp_attr_intern(
804 &static_attr
); /* hashed refcounted everything */
805 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
807 if (debug
&& new_attr
->ecommunity
) {
808 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
809 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
811 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
812 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
815 /* Now new_attr is an allocated interned attr */
817 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
818 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
820 struct bgp_info
*new_info
;
822 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, info_vrf
,
823 &label
, 1, info_vrf
, bgp_vrf
, NULL
,
824 nexthop_self_flag
, debug
);
827 * Routes actually installed in the vpn RIB must also be
828 * offered to all vrfs (because now they originate from
831 * Acceptance into other vrfs depends on rt-lists.
832 * Originating vrf will not accept the looped back route
833 * because of loop checking.
836 vpn_leak_to_vrf_update(bgp_vpn
, new_info
);
839 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
840 struct bgp
*bgp_vrf
, /* from */
841 struct bgp_info
*info_vrf
) /* route */
843 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
844 struct prefix
*p
= &info_vrf
->net
->p
;
845 afi_t afi
= family2afi(p
->family
);
846 safi_t safi
= SAFI_MPLS_VPN
;
849 const char *debugmsg
;
850 char buf_prefix
[PREFIX_STRLEN
];
853 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
855 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
856 __func__
, bgp_vrf
->name_pretty
, buf_prefix
,
857 info_vrf
->type
, info_vrf
->sub_type
);
860 if (info_vrf
->sub_type
!= BGP_ROUTE_NORMAL
861 && info_vrf
->sub_type
!= BGP_ROUTE_STATIC
862 && info_vrf
->sub_type
!= BGP_ROUTE_REDISTRIBUTE
) {
865 zlog_debug("%s: wrong sub_type %d", __func__
,
874 zlog_debug("%s: can't get afi of prefix", __func__
);
878 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
880 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
885 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__
, info_vrf
);
887 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
888 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
892 * match original bi imported from
894 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
895 if (bi
->extra
&& bi
->extra
->parent
== info_vrf
) {
901 /* withdraw from looped vrfs as well */
902 vpn_leak_to_vrf_withdraw(bgp_vpn
, bi
);
904 bgp_aggregate_decrement(bgp_vpn
, p
, bi
, afi
, safi
);
905 bgp_info_delete(bn
, bi
);
906 bgp_process(bgp_vpn
, bn
, afi
, safi
);
911 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
912 struct bgp
*bgp_vrf
, /* from */
915 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
916 struct bgp_node
*prn
;
917 safi_t safi
= SAFI_MPLS_VPN
;
920 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
922 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
923 prn
= bgp_route_next(prn
)) {
925 struct bgp_table
*table
;
929 /* This is the per-RD table of prefixes */
935 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
937 char buf
[PREFIX2STR_BUFFER
];
939 if (debug
&& bn
->info
) {
941 "%s: looking at prefix %s", __func__
,
942 prefix2str(&bn
->p
, buf
, sizeof(buf
)));
945 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
947 zlog_debug("%s: type %d, sub_type %d",
950 if (bi
->sub_type
!= BGP_ROUTE_IMPORTED
)
954 if ((struct bgp
*)bi
->extra
->bgp_orig
958 zlog_debug("%s: deleting it\n",
960 bgp_aggregate_decrement(bgp_vpn
, &bn
->p
,
962 bgp_info_delete(bn
, bi
);
963 bgp_process(bgp_vpn
, bn
, afi
, safi
);
970 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
971 struct bgp
*bgp_vrf
, /* from */
976 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
979 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
980 bgp_vrf
->name_pretty
);
982 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
983 bn
= bgp_route_next(bn
)) {
986 zlog_debug("%s: node=%p", __func__
, bn
);
988 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
991 "%s: calling vpn_leak_from_vrf_update",
993 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bi
);
998 static void vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
999 struct bgp
*bgp_vpn
, /* from */
1000 struct bgp_info
*info_vpn
) /* route */
1002 struct prefix
*p
= &info_vpn
->net
->p
;
1003 afi_t afi
= family2afi(p
->family
);
1005 struct attr static_attr
= {0};
1006 struct attr
*new_attr
= NULL
;
1007 struct bgp_node
*bn
;
1008 safi_t safi
= SAFI_UNICAST
;
1009 const char *debugmsg
;
1010 struct prefix nexthop_orig
;
1011 mpls_label_t
*pLabels
= NULL
;
1012 uint32_t num_labels
= 0;
1013 int nexthop_self_flag
= 1;
1014 struct bgp_info
*bi_ultimate
= NULL
;
1015 int origin_local
= 0;
1016 struct bgp
*src_vrf
;
1018 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1020 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1022 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1026 /* Check for intersection of route targets */
1027 if (!ecom_intersect(
1028 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1029 info_vpn
->attr
->ecommunity
)) {
1035 zlog_debug("%s: updating to vrf %s", __func__
,
1036 bgp_vrf
->name_pretty
);
1038 bgp_attr_dup(&static_attr
, info_vpn
->attr
); /* shallow copy */
1041 * Nexthop: stash and clear
1043 * Nexthop is valid in context of VPN core, but not in destination vrf.
1044 * Stash it for later label resolution by vrf ingress path and then
1045 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1047 uint8_t nhfamily
= NEXTHOP_FAMILY(info_vpn
->attr
->mp_nexthop_len
);
1049 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1050 nexthop_orig
.family
= nhfamily
;
1055 nexthop_orig
.u
.prefix4
= info_vpn
->attr
->mp_nexthop_global_in
;
1056 nexthop_orig
.prefixlen
= 32;
1058 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1059 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1060 static_attr
.nexthop
.s_addr
=
1061 nexthop_orig
.u
.prefix4
.s_addr
;
1063 static_attr
.mp_nexthop_global_in
=
1064 info_vpn
->attr
->mp_nexthop_global_in
;
1065 static_attr
.mp_nexthop_len
=
1066 info_vpn
->attr
->mp_nexthop_len
;
1068 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1072 nexthop_orig
.u
.prefix6
= info_vpn
->attr
->mp_nexthop_global
;
1073 nexthop_orig
.prefixlen
= 128;
1075 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1076 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1077 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1083 * route map handling
1085 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1086 struct bgp_info info
;
1087 route_map_result_t ret
;
1089 memset(&info
, 0, sizeof(info
));
1090 info
.peer
= bgp_vrf
->peer_self
;
1091 info
.attr
= &static_attr
;
1092 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1093 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1094 p
, RMAP_BGP
, &info
);
1095 if (RMAP_DENYMATCH
== ret
) {
1096 bgp_attr_flush(&static_attr
); /* free any added parts */
1099 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1100 __func__
, bgp_vrf
->name_pretty
,
1101 bgp_vrf
->vpn_policy
[afi
]
1102 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1107 * if route-map changed nexthop, don't nexthop-self on output
1109 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1110 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1111 nexthop_self_flag
= 0;
1114 new_attr
= bgp_attr_intern(&static_attr
);
1115 bgp_attr_flush(&static_attr
);
1117 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1120 * ensure labels are copied
1122 * However, there is a special case: if the route originated in
1123 * another local VRF (as opposed to arriving via VPN), then the
1124 * nexthop is reached by hairpinning through this router (me)
1125 * using IP forwarding only (no LSP). Therefore, the route
1126 * imported to the VRF should not have labels attached. Note
1127 * that nexthop tracking is also involved: eliminating the
1128 * labels for these routes enables the non-labeled nexthops
1129 * from the originating VRF to be considered valid for this route.
1131 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1132 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1133 /* work back to original route */
1134 for (bi_ultimate
= info_vpn
;
1135 bi_ultimate
->extra
&& bi_ultimate
->extra
->parent
;
1136 bi_ultimate
= bi_ultimate
->extra
->parent
)
1140 * if original route was unicast,
1141 * then it did not arrive over vpn
1143 if (bi_ultimate
->net
) {
1144 struct bgp_table
*table
;
1146 table
= bgp_node_table(bi_ultimate
->net
);
1147 if (table
&& (table
->safi
== SAFI_UNICAST
))
1152 if (!origin_local
&&
1153 info_vpn
->extra
&& info_vpn
->extra
->num_labels
) {
1154 num_labels
= info_vpn
->extra
->num_labels
;
1155 if (num_labels
> BGP_MAX_LABELS
)
1156 num_labels
= BGP_MAX_LABELS
;
1157 pLabels
= info_vpn
->extra
->label
;
1162 char buf_prefix
[PREFIX_STRLEN
];
1163 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
1164 zlog_debug("%s: pfx %s: num_labels %d", __func__
, buf_prefix
,
1169 * For VRF route-leaking, the source will be the originating VRF.
1171 if (info_vpn
->extra
&& info_vpn
->extra
->bgp_orig
)
1172 src_vrf
= info_vpn
->extra
->bgp_orig
;
1176 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, info_vpn
,
1177 pLabels
, num_labels
,
1178 info_vpn
, /* parent */
1179 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1182 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1183 struct bgp_info
*info_vpn
) /* route */
1185 struct listnode
*mnode
, *mnnode
;
1188 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1191 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1193 /* Loop over VRFs */
1194 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1196 if (!info_vpn
->extra
1197 || info_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1198 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, info_vpn
);
1203 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1204 struct bgp_info
*info_vpn
) /* route */
1208 safi_t safi
= SAFI_UNICAST
;
1210 struct listnode
*mnode
, *mnnode
;
1211 struct bgp_node
*bn
;
1212 struct bgp_info
*bi
;
1213 const char *debugmsg
;
1214 char buf_prefix
[PREFIX_STRLEN
];
1216 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1219 prefix2str(&info_vpn
->net
->p
, buf_prefix
, sizeof(buf_prefix
));
1220 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1221 __func__
, buf_prefix
,
1222 info_vpn
->type
, info_vpn
->sub_type
);
1226 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1228 if (!info_vpn
->net
) {
1230 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1231 if (info_vpn
->type
== ZEBRA_ROUTE_BGP
&&
1232 info_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1238 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1243 p
= &info_vpn
->net
->p
;
1244 afi
= family2afi(p
->family
);
1246 /* Loop over VRFs */
1247 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1248 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1250 zlog_debug("%s: skipping: %s", __func__
,
1255 /* Check for intersection of route targets */
1256 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1257 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1258 info_vpn
->attr
->ecommunity
)) {
1264 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1267 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1268 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
1270 && (struct bgp_info
*)bi
->extra
->parent
1278 zlog_debug("%s: deleting bi %p", __func__
, bi
);
1279 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
1280 bgp_info_delete(bn
, bi
);
1281 bgp_process(bgp
, bn
, afi
, safi
);
1283 bgp_unlock_node(bn
);
1287 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1290 struct bgp_node
*bn
;
1291 struct bgp_info
*bi
;
1292 safi_t safi
= SAFI_UNICAST
;
1293 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1296 zlog_debug("%s: entry", __func__
);
1298 * Walk vrf table, delete bi with bgp_orig in a different vrf
1300 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1301 bn
= bgp_route_next(bn
)) {
1303 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1304 if (bi
->extra
&& bi
->extra
->bgp_orig
!= bgp_vrf
) {
1307 bgp_aggregate_decrement(bgp_vrf
, &bn
->p
, bi
,
1309 bgp_info_delete(bn
, bi
);
1310 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1316 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1317 struct bgp
*bgp_vpn
, /* from */
1320 struct prefix_rd prd
;
1321 struct bgp_node
*prn
;
1322 safi_t safi
= SAFI_MPLS_VPN
;
1327 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
1328 prn
= bgp_route_next(prn
)) {
1330 struct bgp_table
*table
;
1331 struct bgp_node
*bn
;
1332 struct bgp_info
*bi
;
1334 memset(&prd
, 0, sizeof(prd
));
1335 prd
.family
= AF_UNSPEC
;
1337 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
1339 /* This is the per-RD table of prefixes */
1345 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1347 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1349 if (bi
->extra
&& bi
->extra
->bgp_orig
== bgp_vrf
)
1352 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1360 * This function is called for definition/deletion/change to a route-map
1362 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1364 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1366 struct route_map
*rmap
;
1368 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1369 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1374 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1376 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1378 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1379 && !strcmp(rmap_name
,
1380 bgp
->vpn_policy
[afi
]
1381 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1385 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1386 __func__
, rmap_name
, bgp
->as
,
1389 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1390 bgp_get_default(), bgp
);
1392 zlog_debug("%s: after vpn_leak_prechange",
1395 /* in case of definition/deletion */
1396 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1399 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1400 bgp_get_default(), bgp
);
1403 zlog_debug("%s: after vpn_leak_postchange",
1407 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1408 && !strcmp(rmap_name
,
1409 bgp
->vpn_policy
[afi
]
1410 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1413 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1414 __func__
, rmap_name
, bgp
->as
,
1418 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1419 bgp_get_default(), bgp
);
1421 /* in case of definition/deletion */
1422 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1425 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1426 bgp_get_default(), bgp
);
1431 void vpn_policy_routemap_event(const char *rmap_name
)
1433 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1434 struct listnode
*mnode
, *mnnode
;
1438 zlog_debug("%s: entry", __func__
);
1440 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1443 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1444 vpn_policy_routemap_update(bgp
, rmap_name
);
1447 void vrf_import_from_vrf(struct bgp
*bgp
, struct bgp
*vrf_bgp
,
1448 afi_t afi
, safi_t safi
)
1450 const char *export_name
;
1451 vpn_policy_direction_t idir
, edir
;
1454 struct ecommunity
*ecom
;
1455 bool first_export
= false;
1457 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1458 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1459 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1462 /* Cross-ref both VRFs. Also, note if this is the first time
1463 * any VRF is importing from "import_vrf".
1465 vname
= XSTRDUP(MTYPE_TMP
, vrf_bgp
->name
);
1466 listnode_add(bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1468 if (!listcount(vrf_bgp
->vpn_policy
[afi
].export_vrf
))
1469 first_export
= true;
1470 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
1471 listnode_add(vrf_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1473 /* Update import RT for current VRF using export RT of the VRF we're
1474 * importing from. First though, make sure "import_vrf" has that
1478 form_auto_rd(vrf_bgp
->router_id
, vrf_bgp
->vrf_rd_id
,
1479 &vrf_bgp
->vrf_prd_auto
);
1480 vrf_bgp
->vpn_policy
[afi
].tovpn_rd
= vrf_bgp
->vrf_prd_auto
;
1481 SET_FLAG(vrf_bgp
->vpn_policy
[afi
].flags
,
1482 BGP_VPN_POLICY_TOVPN_RD_SET
);
1483 prefix_rd2str(&vrf_bgp
->vpn_policy
[afi
].tovpn_rd
,
1485 vrf_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1486 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
1487 SET_FLAG(vrf_bgp
->af_flags
[afi
][safi
],
1488 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1490 ecom
= vrf_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1491 if (bgp
->vpn_policy
[afi
].rtlist
[idir
])
1492 bgp
->vpn_policy
[afi
].rtlist
[idir
] =
1493 ecommunity_merge(bgp
->vpn_policy
[afi
]
1494 .rtlist
[idir
], ecom
);
1496 bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
1497 SET_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1499 /* Does "import_vrf" first need to export its routes or that
1500 * is already done and we just need to import those routes
1501 * from the global table?
1504 vpn_leak_postchange(edir
, afi
, bgp_get_default(), vrf_bgp
);
1506 vpn_leak_postchange(idir
, afi
, bgp_get_default(), bgp
);
1509 void vrf_unimport_from_vrf(struct bgp
*bgp
, struct bgp
*vrf_bgp
,
1510 afi_t afi
, safi_t safi
)
1512 const char *export_name
;
1513 vpn_policy_direction_t idir
, edir
;
1515 struct ecommunity
*ecom
;
1516 struct listnode
*node
;
1518 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1519 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1520 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1522 /* Were we importing from "import_vrf"? */
1523 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].import_vrf
, node
,
1525 if (strcmp(vname
, vrf_bgp
->name
) == 0)
1531 /* Remove "import_vrf" from our import list. */
1532 listnode_delete(bgp
->vpn_policy
[afi
].import_vrf
, vname
);
1533 XFREE(MTYPE_TMP
, vname
);
1535 /* Remove routes imported from "import_vrf". */
1536 /* TODO: In the current logic, we have to first remove all
1537 * imported routes and then (if needed) import back routes
1539 vpn_leak_prechange(idir
, afi
, bgp_get_default(), bgp
);
1541 if (bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
1542 UNSET_FLAG(bgp
->af_flags
[afi
][safi
],
1543 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
1544 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[idir
]);
1546 ecom
= vrf_bgp
->vpn_policy
[afi
].rtlist
[edir
];
1547 ecommunity_del_val(bgp
->vpn_policy
[afi
].rtlist
[idir
],
1548 (struct ecommunity_val
*)ecom
->val
);
1549 vpn_leak_postchange(idir
, afi
, bgp_get_default(), bgp
);
1552 /* Remove us from "import_vrf's" export list. If no other VRF
1553 * is importing from "import_vrf", cleanup appropriately.
1555 for (ALL_LIST_ELEMENTS_RO(vrf_bgp
->vpn_policy
[afi
].export_vrf
,
1557 if (strcmp(vname
, export_name
) == 0)
1561 listnode_delete(vrf_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
1562 XFREE(MTYPE_TMP
, vname
);
1564 if (!listcount(vrf_bgp
->vpn_policy
[afi
].export_vrf
)) {
1565 vpn_leak_prechange(edir
, afi
, bgp_get_default(), vrf_bgp
);
1566 ecommunity_free(&vrf_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
1567 UNSET_FLAG(vrf_bgp
->af_flags
[afi
][safi
],
1568 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
1569 memset(&vrf_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
1570 sizeof(struct prefix_rd
));
1571 UNSET_FLAG(vrf_bgp
->vpn_policy
[afi
].flags
,
1572 BGP_VPN_POLICY_TOVPN_RD_SET
);
1576 /* For testing purpose, static route of MPLS-VPN. */
1577 DEFUN (vpnv4_network
,
1579 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1580 "Specify a network to announce via BGP\n"
1582 "Specify Route Distinguisher\n"
1583 "VPN Route Distinguisher\n"
1584 "VPN NLRI label (tag)\n"
1585 "VPN NLRI label (tag)\n"
1588 int idx_ipv4_prefixlen
= 1;
1589 int idx_ext_community
= 3;
1591 return bgp_static_set_safi(
1592 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1593 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1594 NULL
, NULL
, NULL
, NULL
);
1597 DEFUN (vpnv4_network_route_map
,
1598 vpnv4_network_route_map_cmd
,
1599 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1600 "Specify a network to announce via BGP\n"
1602 "Specify Route Distinguisher\n"
1603 "VPN Route Distinguisher\n"
1604 "VPN NLRI label (tag)\n"
1605 "VPN NLRI label (tag)\n"
1610 int idx_ipv4_prefixlen
= 1;
1611 int idx_ext_community
= 3;
1614 return bgp_static_set_safi(
1615 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1616 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1617 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1620 /* For testing purpose, static route of MPLS-VPN. */
1621 DEFUN (no_vpnv4_network
,
1622 no_vpnv4_network_cmd
,
1623 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1625 "Specify a network to announce via BGP\n"
1627 "Specify Route Distinguisher\n"
1628 "VPN Route Distinguisher\n"
1629 "VPN NLRI label (tag)\n"
1630 "VPN NLRI label (tag)\n"
1633 int idx_ipv4_prefixlen
= 2;
1634 int idx_ext_community
= 4;
1636 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1637 argv
[idx_ipv4_prefixlen
]->arg
,
1638 argv
[idx_ext_community
]->arg
,
1639 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1642 DEFUN (vpnv6_network
,
1644 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1645 "Specify a network to announce via BGP\n"
1646 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1647 "Specify Route Distinguisher\n"
1648 "VPN Route Distinguisher\n"
1649 "VPN NLRI label (tag)\n"
1650 "VPN NLRI label (tag)\n"
1655 int idx_ipv6_prefix
= 1;
1656 int idx_ext_community
= 3;
1660 return bgp_static_set_safi(
1661 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1662 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1663 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1665 return bgp_static_set_safi(
1666 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1667 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1668 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1671 /* For testing purpose, static route of MPLS-VPN. */
1672 DEFUN (no_vpnv6_network
,
1673 no_vpnv6_network_cmd
,
1674 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1676 "Specify a network to announce via BGP\n"
1677 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1678 "Specify Route Distinguisher\n"
1679 "VPN Route Distinguisher\n"
1680 "VPN NLRI label (tag)\n"
1681 "VPN NLRI label (tag)\n"
1684 int idx_ipv6_prefix
= 2;
1685 int idx_ext_community
= 4;
1687 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
1688 argv
[idx_ipv6_prefix
]->arg
,
1689 argv
[idx_ext_community
]->arg
,
1690 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1693 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
1694 enum bgp_show_type type
, void *output_arg
, int tags
,
1698 struct bgp_table
*table
;
1700 bgp
= bgp_get_default();
1703 vty_out(vty
, "No BGP process is configured\n");
1705 vty_out(vty
, "{}\n");
1708 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
1709 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
1710 output_arg
, use_json
);
1713 DEFUN (show_bgp_ip_vpn_all_rd
,
1714 show_bgp_ip_vpn_all_rd_cmd
,
1715 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1719 "Display VPN NLRI specific information\n"
1720 "Display VPN NLRI specific information\n"
1721 "Display information for a route distinguisher\n"
1722 "VPN Route Distinguisher\n"
1726 struct prefix_rd prd
;
1730 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1731 if (argv_find(argv
, argc
, "rd", &idx
)) {
1732 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
1735 "%% Malformed Route Distinguisher\n");
1738 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
1739 bgp_show_type_normal
, NULL
, 0,
1740 use_json(argc
, argv
));
1742 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
1743 bgp_show_type_normal
, NULL
, 0,
1744 use_json(argc
, argv
));
1750 ALIAS(show_bgp_ip_vpn_all_rd
,
1751 show_bgp_ip_vpn_rd_cmd
,
1752 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1756 "Display VPN NLRI specific information\n"
1757 "Display information for a route distinguisher\n"
1758 "VPN Route Distinguisher\n"
1761 #ifdef KEEP_OLD_VPN_COMMANDS
1762 DEFUN (show_ip_bgp_vpn_rd
,
1763 show_ip_bgp_vpn_rd_cmd
,
1764 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
1769 "Address Family modifier\n"
1770 "Display information for a route distinguisher\n"
1771 "VPN Route Distinguisher\n")
1773 int idx_ext_community
= argc
- 1;
1775 struct prefix_rd prd
;
1779 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1780 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1782 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1785 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1791 DEFUN (show_ip_bgp_vpn_all
,
1792 show_ip_bgp_vpn_all_cmd
,
1793 "show [ip] bgp <vpnv4|vpnv6>",
1802 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1803 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1808 DEFUN (show_ip_bgp_vpn_all_tags
,
1809 show_ip_bgp_vpn_all_tags_cmd
,
1810 "show [ip] bgp <vpnv4|vpnv6> all tags",
1815 "Display information about all VPNv4/VPNV6 NLRIs\n"
1816 "Display BGP tags for prefixes\n")
1821 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1822 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1827 DEFUN (show_ip_bgp_vpn_rd_tags
,
1828 show_ip_bgp_vpn_rd_tags_cmd
,
1829 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
1834 "Display information for a route distinguisher\n"
1835 "VPN Route Distinguisher\n"
1836 "Display BGP tags for prefixes\n")
1838 int idx_ext_community
= 5;
1840 struct prefix_rd prd
;
1844 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1845 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1847 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1850 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1856 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1857 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1858 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1863 "Display information about all VPNv4/VPNv6 NLRIs\n"
1864 "Detailed information on TCP and BGP neighbor connections\n"
1865 "Neighbor to display information about\n"
1866 "Display routes learned from neighbor\n"
1873 uint8_t uj
= use_json(argc
, argv
);
1877 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1878 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1881 json_object
*json_no
= NULL
;
1882 json_no
= json_object_new_object();
1883 json_object_string_add(json_no
, "warning",
1884 "Malformed address");
1885 vty_out(vty
, "%s\n",
1886 json_object_to_json_string(json_no
));
1887 json_object_free(json_no
);
1889 vty_out(vty
, "Malformed address: %s\n",
1890 argv
[idx_ipv4
]->arg
);
1894 peer
= peer_lookup(NULL
, &su
);
1895 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1897 json_object
*json_no
= NULL
;
1898 json_no
= json_object_new_object();
1899 json_object_string_add(
1901 "No such neighbor or address family");
1902 vty_out(vty
, "%s\n",
1903 json_object_to_json_string(json_no
));
1904 json_object_free(json_no
);
1907 "%% No such neighbor or address family\n");
1911 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
1917 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
1918 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
1919 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
1924 "Display information for a route distinguisher\n"
1925 "VPN Route Distinguisher\n"
1926 "Detailed information on TCP and BGP neighbor connections\n"
1927 "Neighbor to display information about\n"
1928 "Display routes learned from neighbor\n"
1931 int idx_ext_community
= 5;
1936 struct prefix_rd prd
;
1937 uint8_t uj
= use_json(argc
, argv
);
1941 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1942 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1945 json_object
*json_no
= NULL
;
1946 json_no
= json_object_new_object();
1947 json_object_string_add(
1949 "Malformed Route Distinguisher");
1950 vty_out(vty
, "%s\n",
1951 json_object_to_json_string(json_no
));
1952 json_object_free(json_no
);
1955 "%% Malformed Route Distinguisher\n");
1959 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1962 json_object
*json_no
= NULL
;
1963 json_no
= json_object_new_object();
1964 json_object_string_add(json_no
, "warning",
1965 "Malformed address");
1966 vty_out(vty
, "%s\n",
1967 json_object_to_json_string(json_no
));
1968 json_object_free(json_no
);
1970 vty_out(vty
, "Malformed address: %s\n",
1971 argv
[idx_ext_community
]->arg
);
1975 peer
= peer_lookup(NULL
, &su
);
1976 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1978 json_object
*json_no
= NULL
;
1979 json_no
= json_object_new_object();
1980 json_object_string_add(
1982 "No such neighbor or address family");
1983 vty_out(vty
, "%s\n",
1984 json_object_to_json_string(json_no
));
1985 json_object_free(json_no
);
1988 "%% No such neighbor or address family\n");
1992 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
1998 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
1999 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2000 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2005 "Display information about all VPNv4/VPNv6 NLRIs\n"
2006 "Detailed information on TCP and BGP neighbor connections\n"
2007 "Neighbor to display information about\n"
2008 "Display the routes advertised to a BGP neighbor\n"
2015 uint8_t uj
= use_json(argc
, argv
);
2019 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2020 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2023 json_object
*json_no
= NULL
;
2024 json_no
= json_object_new_object();
2025 json_object_string_add(json_no
, "warning",
2026 "Malformed address");
2027 vty_out(vty
, "%s\n",
2028 json_object_to_json_string(json_no
));
2029 json_object_free(json_no
);
2031 vty_out(vty
, "Malformed address: %s\n",
2032 argv
[idx_ipv4
]->arg
);
2035 peer
= peer_lookup(NULL
, &su
);
2036 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2038 json_object
*json_no
= NULL
;
2039 json_no
= json_object_new_object();
2040 json_object_string_add(
2042 "No such neighbor or address family");
2043 vty_out(vty
, "%s\n",
2044 json_object_to_json_string(json_no
));
2045 json_object_free(json_no
);
2048 "%% No such neighbor or address family\n");
2051 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2057 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2058 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2059 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2064 "Display information for a route distinguisher\n"
2065 "VPN Route Distinguisher\n"
2066 "Detailed information on TCP and BGP neighbor connections\n"
2067 "Neighbor to display information about\n"
2068 "Display the routes advertised to a BGP neighbor\n"
2071 int idx_ext_community
= 5;
2075 struct prefix_rd prd
;
2077 uint8_t uj
= use_json(argc
, argv
);
2081 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2082 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2085 json_object
*json_no
= NULL
;
2086 json_no
= json_object_new_object();
2087 json_object_string_add(json_no
, "warning",
2088 "Malformed address");
2089 vty_out(vty
, "%s\n",
2090 json_object_to_json_string(json_no
));
2091 json_object_free(json_no
);
2093 vty_out(vty
, "Malformed address: %s\n",
2094 argv
[idx_ext_community
]->arg
);
2097 peer
= peer_lookup(NULL
, &su
);
2098 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2100 json_object
*json_no
= NULL
;
2101 json_no
= json_object_new_object();
2102 json_object_string_add(
2104 "No such neighbor or address family");
2105 vty_out(vty
, "%s\n",
2106 json_object_to_json_string(json_no
));
2107 json_object_free(json_no
);
2110 "%% No such neighbor or address family\n");
2114 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2117 json_object
*json_no
= NULL
;
2118 json_no
= json_object_new_object();
2119 json_object_string_add(
2121 "Malformed Route Distinguisher");
2122 vty_out(vty
, "%s\n",
2123 json_object_to_json_string(json_no
));
2124 json_object_free(json_no
);
2127 "%% Malformed Route Distinguisher\n");
2131 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2136 #endif /* KEEP_OLD_VPN_COMMANDS */
2138 void bgp_mplsvpn_init(void)
2140 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2141 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2142 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2144 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2145 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2147 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2148 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2149 #ifdef KEEP_OLD_VPN_COMMANDS
2150 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2151 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2152 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2153 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2154 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2155 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2156 install_element(VIEW_NODE
,
2157 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2158 install_element(VIEW_NODE
,
2159 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2160 #endif /* KEEP_OLD_VPN_COMMANDS */
2163 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2165 struct listnode
*mnode
, *mnnode
;
2168 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2169 struct ecommunity
*ec
;
2171 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2174 ec
= bgp
->vpn_policy
[AFI_IP
].import_redirect_rtlist
;
2176 if (ecom_intersect(ec
, eckey
))