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 static int ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
321 for (i
= 0; i
< e1
->size
; ++i
) {
322 for (j
= 0; j
< e2
->size
; ++j
) {
323 if (!memcmp(e1
->val
+ (i
* ECOMMUNITY_SIZE
),
324 e2
->val
+ (j
* ECOMMUNITY_SIZE
),
335 * returns pointer to new bgp_info upon success
337 static struct bgp_info
*
339 struct bgp
*bgp
, /* destination bgp instance */
341 struct attr
*new_attr
, /* already interned */
344 struct bgp_info
*source_bi
,
348 struct bgp
*bgp_orig
,
349 struct prefix
*nexthop_orig
,
350 int nexthop_self_flag
,
353 struct prefix
*p
= &bn
->p
;
355 struct bgp_info
*new;
356 char buf_prefix
[PREFIX_STRLEN
];
359 prefix2str(&bn
->p
, buf_prefix
, sizeof(buf_prefix
));
360 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
361 __func__
, bgp
->name_pretty
, buf_prefix
,
362 source_bi
->type
, source_bi
->sub_type
);
368 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
369 if (bi
->extra
&& bi
->extra
->parent
== parent
)
374 if (attrhash_cmp(bi
->attr
, new_attr
)
375 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
377 bgp_attr_unintern(&new_attr
);
380 "%s: ->%s: %s: Found route, no change",
381 __func__
, bgp
->name_pretty
,
386 /* attr is changed */
387 bgp_info_set_flag(bn
, bi
, BGP_INFO_ATTR_CHANGED
);
389 /* Rewrite BGP route information. */
390 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
391 bgp_info_restore(bn
, bi
);
393 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
394 bgp_attr_unintern(&bi
->attr
);
396 bi
->uptime
= bgp_clock();
398 if (nexthop_self_flag
)
399 bgp_info_set_flag(bn
, bi
, BGP_INFO_ANNC_NH_SELF
);
401 struct bgp
*bgp_nexthop
= bgp
;
404 if (bi
->extra
&& bi
->extra
->bgp_orig
)
405 bgp_nexthop
= bi
->extra
->bgp_orig
;
407 /* No nexthop tracking for redistributed routes */
408 if (source_bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
412 * TBD do we need to do anything about the
413 * 'connected' parameter?
415 nh_valid
= bgp_find_or_add_nexthop(
420 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
421 __func__
, (nh_valid
? "" : "not "),
422 bgp_nexthop
->name_pretty
);
425 bgp_info_set_flag(bn
, bi
, BGP_INFO_VALID
);
427 /* Process change. */
428 bgp_aggregate_increment(bgp
, p
, bi
, afi
, safi
);
429 bgp_process(bgp
, bn
, afi
, safi
);
433 zlog_debug("%s: ->%s: %s Found route, changed attr",
434 __func__
, bgp
->name_pretty
, buf_prefix
);
439 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
440 bgp
->peer_self
, new_attr
, bn
);
442 if (nexthop_self_flag
)
443 bgp_info_set_flag(bn
, new, BGP_INFO_ANNC_NH_SELF
);
445 bgp_info_extra_get(new);
449 for (i
= 0; i
< num_labels
; ++i
) {
450 new->extra
->label
[i
] = label
[i
];
451 if (!bgp_is_valid_label(&label
[i
])) {
454 "%s: %s: marking label %d valid",
455 __func__
, buf_prefix
, i
);
457 bgp_set_valid_label(&new->extra
->label
[i
]);
460 new->extra
->num_labels
= num_labels
;
462 new->extra
->parent
= parent
;
465 new->extra
->bgp_orig
= bgp_orig
;
467 new->extra
->nexthop_orig
= *nexthop_orig
;
470 * nexthop tracking for unicast routes
472 struct bgp
*bgp_nexthop
= bgp
;
475 if (new->extra
&& new->extra
->bgp_orig
)
476 bgp_nexthop
= new->extra
->bgp_orig
;
479 * No nexthop tracking for redistributed routes because
480 * their originating protocols will do the tracking and
481 * withdraw those routes if the nexthops become unreachable
483 if (source_bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
487 * TBD do we need to do anything about the
488 * 'connected' parameter?
490 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
494 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
495 __func__
, (nh_valid
? "" : "not "),
496 bgp_nexthop
->name_pretty
);
498 bgp_info_set_flag(bn
, new, BGP_INFO_VALID
);
500 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
501 bgp_info_add(bn
, new);
504 bgp_process(bgp
, bn
, afi
, safi
);
507 zlog_debug("%s: ->%s: %s: Added new route", __func__
,
508 bgp
->name_pretty
, buf_prefix
);
513 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
514 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
515 struct bgp
*bgp_vrf
, /* from */
516 struct bgp_info
*info_vrf
) /* route */
518 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
519 struct prefix
*p
= &info_vrf
->net
->p
;
520 afi_t afi
= family2afi(p
->family
);
521 struct attr static_attr
= {0};
522 struct attr
*new_attr
= NULL
;
523 safi_t safi
= SAFI_MPLS_VPN
;
524 mpls_label_t label_val
;
527 const char *debugmsg
;
528 int nexthop_self_flag
= 0;
531 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
533 if (debug
&& info_vrf
->attr
->ecommunity
) {
534 char *s
= ecommunity_ecom2str(info_vrf
->attr
->ecommunity
,
535 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
537 zlog_debug("%s: info_vrf->type=%d, EC{%s}", __func__
,
539 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
547 zlog_debug("%s: can't get afi of prefix", __func__
);
552 if (info_vrf
->extra
&& info_vrf
->extra
->bgp_orig
== bgp_vpn
)
556 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
558 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
562 bgp_attr_dup(&static_attr
, info_vrf
->attr
); /* shallow copy */
567 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
568 struct bgp_info info
;
569 route_map_result_t ret
;
571 memset(&info
, 0, sizeof(info
));
572 info
.peer
= bgp_vpn
->peer_self
;
573 info
.attr
= &static_attr
;
574 ret
= route_map_apply(
575 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
577 if (RMAP_DENYMATCH
== ret
) {
578 bgp_attr_flush(&static_attr
); /* free any added parts */
581 "%s: vrf %s route map \"%s\" says DENY, returning",
582 __func__
, bgp_vrf
->name_pretty
,
583 bgp_vrf
->vpn_policy
[afi
]
584 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
590 if (debug
&& static_attr
.ecommunity
) {
591 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
592 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
594 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
596 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
600 * Add the vpn-policy rt-list
602 struct ecommunity
*old_ecom
;
603 struct ecommunity
*new_ecom
;
605 old_ecom
= static_attr
.ecommunity
;
607 new_ecom
= ecommunity_merge(
608 ecommunity_dup(old_ecom
),
609 bgp_vrf
->vpn_policy
[afi
]
610 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
611 if (!old_ecom
->refcnt
)
612 ecommunity_free(&old_ecom
);
614 new_ecom
= ecommunity_dup(
615 bgp_vrf
->vpn_policy
[afi
]
616 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
618 static_attr
.ecommunity
= new_ecom
;
619 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
621 if (debug
&& static_attr
.ecommunity
) {
622 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
623 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
625 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
627 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
631 /* if policy nexthop not set, use 0 */
632 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
633 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
635 struct prefix
*nexthop
=
636 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
637 switch (nexthop
->family
) {
639 /* prevent mp_nexthop_global_in <- self in bgp_route.c
641 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
643 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
644 static_attr
.mp_nexthop_len
= 4;
648 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
649 static_attr
.mp_nexthop_len
= 16;
657 /* For ipv4, copy to multiprotocol nexthop field */
658 static_attr
.mp_nexthop_global_in
= static_attr
.nexthop
;
659 static_attr
.mp_nexthop_len
= 4;
660 /* XXX Leave static_attr.nexthop intact for NHT */
661 static_attr
.flag
&= ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
663 nexthop_self_flag
= 1;
666 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
667 if (label_val
== MPLS_LABEL_NONE
) {
668 /* TBD get from label manager */
669 label
= MPLS_LABEL_IMPLICIT_NULL
;
671 encode_label(label_val
, &label
);
674 /* Set originator ID to "me" */
675 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
676 static_attr
.originator_id
= bgp_vpn
->router_id
;
679 new_attr
= bgp_attr_intern(
680 &static_attr
); /* hashed refcounted everything */
681 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
683 if (debug
&& new_attr
->ecommunity
) {
684 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
685 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
687 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
688 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
691 /* Now new_attr is an allocated interned attr */
693 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
694 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
696 struct bgp_info
*new_info
;
698 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, info_vrf
,
699 &label
, 1, info_vrf
, bgp_vrf
, NULL
,
700 nexthop_self_flag
, debug
);
703 * Routes actually installed in the vpn RIB must also be
704 * offered to all vrfs (because now they originate from
707 * Acceptance into other vrfs depends on rt-lists.
708 * Originating vrf will not accept the looped back route
709 * because of loop checking.
712 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
715 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
716 struct bgp
*bgp_vrf
, /* from */
717 struct bgp_info
*info_vrf
) /* route */
719 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
720 struct prefix
*p
= &info_vrf
->net
->p
;
721 afi_t afi
= family2afi(p
->family
);
722 safi_t safi
= SAFI_MPLS_VPN
;
725 const char *debugmsg
;
726 char buf_prefix
[PREFIX_STRLEN
];
729 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
731 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
732 __func__
, bgp_vrf
->name_pretty
, buf_prefix
,
733 info_vrf
->type
, info_vrf
->sub_type
);
736 if (info_vrf
->type
!= ZEBRA_ROUTE_BGP
) {
738 zlog_debug("%s: wrong type %d", __func__
,
742 if (info_vrf
->sub_type
!= BGP_ROUTE_NORMAL
743 && info_vrf
->sub_type
!= BGP_ROUTE_STATIC
) {
746 zlog_debug("%s: wrong sub_type %d", __func__
,
755 zlog_debug("%s: can't get afi of prefix", __func__
);
759 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
761 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
766 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__
, info_vrf
);
768 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
769 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
773 * match original bi imported from
775 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
776 if (bi
->extra
&& bi
->extra
->parent
== info_vrf
) {
782 /* withdraw from looped vrfs as well */
783 vpn_leak_to_vrf_withdraw(bgp_vpn
, bi
);
785 bgp_aggregate_decrement(bgp_vpn
, p
, bi
, afi
, safi
);
786 bgp_info_delete(bn
, bi
);
787 bgp_process(bgp_vpn
, bn
, afi
, safi
);
792 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
793 struct bgp
*bgp_vrf
, /* from */
796 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
797 struct bgp_node
*prn
;
798 safi_t safi
= SAFI_MPLS_VPN
;
801 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
803 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
804 prn
= bgp_route_next(prn
)) {
806 struct bgp_table
*table
;
810 /* This is the per-RD table of prefixes */
816 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
818 char buf
[PREFIX2STR_BUFFER
];
820 if (debug
&& bn
->info
) {
822 "%s: looking at prefix %s", __func__
,
823 prefix2str(&bn
->p
, buf
, sizeof(buf
)));
826 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
828 zlog_debug("%s: type %d, sub_type %d",
831 if (bi
->sub_type
!= BGP_ROUTE_IMPORTED
)
835 if ((struct bgp
*)bi
->extra
->bgp_orig
839 zlog_debug("%s: deleting it\n",
841 bgp_aggregate_decrement(bgp_vpn
, &bn
->p
,
843 bgp_info_delete(bn
, bi
);
844 bgp_process(bgp_vpn
, bn
, afi
, safi
);
851 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
852 struct bgp
*bgp_vrf
, /* from */
857 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
860 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
861 bgp_vrf
->name_pretty
);
863 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
864 bn
= bgp_route_next(bn
)) {
867 zlog_debug("%s: node=%p", __func__
, bn
);
869 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
872 "%s: calling vpn_leak_from_vrf_update",
874 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bi
);
879 static void vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
880 struct bgp
*bgp_vpn
, /* from */
881 struct bgp_info
*info_vpn
) /* route */
883 struct prefix
*p
= &info_vpn
->net
->p
;
884 afi_t afi
= family2afi(p
->family
);
886 struct attr static_attr
= {0};
887 struct attr
*new_attr
= NULL
;
889 safi_t safi
= SAFI_UNICAST
;
890 const char *debugmsg
;
891 struct prefix nexthop_orig
;
892 mpls_label_t
*pLabels
= NULL
;
894 int nexthop_self_flag
= 1;
896 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
898 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
900 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
904 /* Check for intersection of route targets */
906 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
907 info_vpn
->attr
->ecommunity
)) {
913 zlog_debug("%s: updating to vrf %s", __func__
,
914 bgp_vrf
->name_pretty
);
916 bgp_attr_dup(&static_attr
, info_vpn
->attr
); /* shallow copy */
919 * Nexthop: stash and clear
921 * Nexthop is valid in context of VPN core, but not in destination vrf.
922 * Stash it for later label resolution by vrf ingress path and then
923 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
925 uint8_t nhfamily
= NEXTHOP_FAMILY(info_vpn
->attr
->mp_nexthop_len
);
927 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
928 nexthop_orig
.family
= nhfamily
;
934 nexthop_orig
.u
.prefix4
= info_vpn
->attr
->mp_nexthop_global_in
;
935 nexthop_orig
.prefixlen
= 32;
936 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
941 nexthop_orig
.u
.prefix6
= info_vpn
->attr
->mp_nexthop_global
;
942 nexthop_orig
.prefixlen
= 128;
950 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
951 struct bgp_info info
;
952 route_map_result_t ret
;
954 memset(&info
, 0, sizeof(info
));
955 info
.peer
= bgp_vrf
->peer_self
;
956 info
.attr
= &static_attr
;
957 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
958 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
960 if (RMAP_DENYMATCH
== ret
) {
961 bgp_attr_flush(&static_attr
); /* free any added parts */
964 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
965 __func__
, bgp_vrf
->name_pretty
,
966 bgp_vrf
->vpn_policy
[afi
]
967 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
972 * if route-map changed nexthop, don't nexthop-self on output
974 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
975 BATTR_RMAP_NEXTHOP_UNCHANGED
))
976 nexthop_self_flag
= 0;
979 new_attr
= bgp_attr_intern(&static_attr
);
980 bgp_attr_flush(&static_attr
);
982 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
985 * ensure labels are copied
987 if (info_vpn
->extra
&& info_vpn
->extra
->num_labels
) {
988 num_labels
= info_vpn
->extra
->num_labels
;
989 if (num_labels
> BGP_MAX_LABELS
)
990 num_labels
= BGP_MAX_LABELS
;
991 pLabels
= info_vpn
->extra
->label
;
994 char buf_prefix
[PREFIX_STRLEN
];
995 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
996 zlog_debug("%s: pfx %s: num_labels %d", __func__
, buf_prefix
,
1000 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, info_vpn
,
1001 pLabels
, num_labels
,
1002 info_vpn
, /* parent */
1003 bgp_vpn
, &nexthop_orig
, nexthop_self_flag
, debug
);
1006 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1007 struct bgp_info
*info_vpn
) /* route */
1009 struct listnode
*mnode
, *mnnode
;
1012 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1015 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1017 /* Loop over VRFs */
1018 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1020 if (!info_vpn
->extra
1021 || info_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1022 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, info_vpn
);
1027 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1028 struct bgp_info
*info_vpn
) /* route */
1032 safi_t safi
= SAFI_UNICAST
;
1034 struct listnode
*mnode
, *mnnode
;
1035 struct bgp_node
*bn
;
1036 struct bgp_info
*bi
;
1037 const char *debugmsg
;
1038 char buf_prefix
[PREFIX_STRLEN
];
1040 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1043 prefix2str(&info_vpn
->net
->p
, buf_prefix
, sizeof(buf_prefix
));
1044 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1045 __func__
, buf_prefix
,
1046 info_vpn
->type
, info_vpn
->sub_type
);
1050 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
1052 if (!info_vpn
->net
) {
1054 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1055 if (info_vpn
->type
== ZEBRA_ROUTE_BGP
&&
1056 info_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1062 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1067 p
= &info_vpn
->net
->p
;
1068 afi
= family2afi(p
->family
);
1070 /* Loop over VRFs */
1071 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1072 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1074 zlog_debug("%s: skipping: %s", __func__
,
1079 /* Check for intersection of route targets */
1080 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1081 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1082 info_vpn
->attr
->ecommunity
)) {
1088 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1091 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1092 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
1094 && (struct bgp_info
*)bi
->extra
->parent
1102 zlog_debug("%s: deleting bi %p", __func__
, bi
);
1103 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
1104 bgp_info_delete(bn
, bi
);
1105 bgp_process(bgp
, bn
, afi
, safi
);
1107 bgp_unlock_node(bn
);
1111 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1114 struct bgp_node
*bn
;
1115 struct bgp_info
*bi
;
1116 safi_t safi
= SAFI_UNICAST
;
1117 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1118 struct bgp
*bgp_vpn
= bgp_get_default();
1121 zlog_debug("%s: entry", __func__
);
1123 * Walk vrf table, delete bi with bgp_orig == bgp_vpn
1125 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1126 bn
= bgp_route_next(bn
)) {
1128 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1129 if (bi
->extra
&& bi
->extra
->bgp_orig
== bgp_vpn
) {
1132 bgp_aggregate_decrement(bgp_vrf
, &bn
->p
, bi
,
1134 bgp_info_delete(bn
, bi
);
1135 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1141 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1142 struct bgp
*bgp_vpn
, /* from */
1145 struct prefix_rd prd
;
1146 struct bgp_node
*prn
;
1147 safi_t safi
= SAFI_MPLS_VPN
;
1152 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
1153 prn
= bgp_route_next(prn
)) {
1155 struct bgp_table
*table
;
1156 struct bgp_node
*bn
;
1157 struct bgp_info
*bi
;
1159 memset(&prd
, 0, sizeof(prd
));
1160 prd
.family
= AF_UNSPEC
;
1162 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
1164 /* This is the per-RD table of prefixes */
1170 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1172 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1174 if (bi
->extra
&& bi
->extra
->bgp_orig
== bgp_vrf
)
1177 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1184 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1186 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1188 struct route_map
*rmap
;
1190 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1191 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1196 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1198 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1200 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)
1201 && bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1202 && !strcmp(rmap_name
,
1203 bgp
->vpn_policy
[afi
]
1204 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1208 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1209 __func__
, rmap_name
, bgp
->as
,
1212 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1213 bgp_get_default(), bgp
);
1215 zlog_debug("%s: after vpn_leak_prechange",
1219 bgp
->vpn_policy
[afi
]
1220 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
] = NULL
;
1222 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1223 bgp_get_default(), bgp
);
1225 zlog_debug("%s: after vpn_leak_postchange",
1229 char *mapname
= bgp
->vpn_policy
[afi
]
1230 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
];
1232 if (vpn_leak_from_vpn_active(bgp
, afi
, NULL
) &&
1234 !strcmp(rmap_name
, mapname
)) {
1237 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1238 __func__
, rmap_name
, bgp
->as
,
1242 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1243 bgp_get_default(), bgp
);
1246 bgp
->vpn_policy
[afi
]
1247 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1251 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1252 bgp_get_default(), bgp
);
1257 void vpn_policy_routemap_event(const char *rmap_name
)
1259 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1260 struct listnode
*mnode
, *mnnode
;
1264 zlog_debug("%s: entry", __func__
);
1266 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1269 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1270 vpn_policy_routemap_update(bgp
, rmap_name
);
1273 /* For testing purpose, static route of MPLS-VPN. */
1274 DEFUN (vpnv4_network
,
1276 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1277 "Specify a network to announce via BGP\n"
1279 "Specify Route Distinguisher\n"
1280 "VPN Route Distinguisher\n"
1281 "VPN NLRI label (tag)\n"
1282 "VPN NLRI label (tag)\n"
1285 int idx_ipv4_prefixlen
= 1;
1286 int idx_ext_community
= 3;
1288 return bgp_static_set_safi(
1289 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1290 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1291 NULL
, NULL
, NULL
, NULL
);
1294 DEFUN (vpnv4_network_route_map
,
1295 vpnv4_network_route_map_cmd
,
1296 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1297 "Specify a network to announce via BGP\n"
1299 "Specify Route Distinguisher\n"
1300 "VPN Route Distinguisher\n"
1301 "VPN NLRI label (tag)\n"
1302 "VPN NLRI label (tag)\n"
1307 int idx_ipv4_prefixlen
= 1;
1308 int idx_ext_community
= 3;
1311 return bgp_static_set_safi(
1312 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1313 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1314 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1317 /* For testing purpose, static route of MPLS-VPN. */
1318 DEFUN (no_vpnv4_network
,
1319 no_vpnv4_network_cmd
,
1320 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1322 "Specify a network to announce via BGP\n"
1324 "Specify Route Distinguisher\n"
1325 "VPN Route Distinguisher\n"
1326 "VPN NLRI label (tag)\n"
1327 "VPN NLRI label (tag)\n"
1330 int idx_ipv4_prefixlen
= 2;
1331 int idx_ext_community
= 4;
1333 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1334 argv
[idx_ipv4_prefixlen
]->arg
,
1335 argv
[idx_ext_community
]->arg
,
1336 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1339 DEFUN (vpnv6_network
,
1341 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1342 "Specify a network to announce via BGP\n"
1343 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1344 "Specify Route Distinguisher\n"
1345 "VPN Route Distinguisher\n"
1346 "VPN NLRI label (tag)\n"
1347 "VPN NLRI label (tag)\n"
1352 int idx_ipv6_prefix
= 1;
1353 int idx_ext_community
= 3;
1357 return bgp_static_set_safi(
1358 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1359 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1360 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1362 return bgp_static_set_safi(
1363 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1364 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1365 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1368 /* For testing purpose, static route of MPLS-VPN. */
1369 DEFUN (no_vpnv6_network
,
1370 no_vpnv6_network_cmd
,
1371 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1373 "Specify a network to announce via BGP\n"
1374 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1375 "Specify Route Distinguisher\n"
1376 "VPN Route Distinguisher\n"
1377 "VPN NLRI label (tag)\n"
1378 "VPN NLRI label (tag)\n"
1381 int idx_ipv6_prefix
= 2;
1382 int idx_ext_community
= 4;
1384 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
1385 argv
[idx_ipv6_prefix
]->arg
,
1386 argv
[idx_ext_community
]->arg
,
1387 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1390 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
1391 enum bgp_show_type type
, void *output_arg
, int tags
,
1395 struct bgp_table
*table
;
1397 bgp
= bgp_get_default();
1400 vty_out(vty
, "No BGP process is configured\n");
1402 vty_out(vty
, "{}\n");
1405 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
1406 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
1407 output_arg
, use_json
);
1410 DEFUN (show_bgp_ip_vpn_all_rd
,
1411 show_bgp_ip_vpn_all_rd_cmd
,
1412 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1416 "Display VPN NLRI specific information\n"
1417 "Display VPN NLRI specific information\n"
1418 "Display information for a route distinguisher\n"
1419 "VPN Route Distinguisher\n"
1423 struct prefix_rd prd
;
1427 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1428 if (argv_find(argv
, argc
, "rd", &idx
)) {
1429 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
1432 "%% Malformed Route Distinguisher\n");
1435 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
1436 bgp_show_type_normal
, NULL
, 0,
1437 use_json(argc
, argv
));
1439 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
1440 bgp_show_type_normal
, NULL
, 0,
1441 use_json(argc
, argv
));
1447 ALIAS(show_bgp_ip_vpn_all_rd
,
1448 show_bgp_ip_vpn_rd_cmd
,
1449 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1453 "Display VPN NLRI specific information\n"
1454 "Display information for a route distinguisher\n"
1455 "VPN Route Distinguisher\n"
1458 #ifdef KEEP_OLD_VPN_COMMANDS
1459 DEFUN (show_ip_bgp_vpn_rd
,
1460 show_ip_bgp_vpn_rd_cmd
,
1461 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
1466 "Address Family modifier\n"
1467 "Display information for a route distinguisher\n"
1468 "VPN Route Distinguisher\n")
1470 int idx_ext_community
= argc
- 1;
1472 struct prefix_rd prd
;
1476 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1477 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1479 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1482 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1488 DEFUN (show_ip_bgp_vpn_all
,
1489 show_ip_bgp_vpn_all_cmd
,
1490 "show [ip] bgp <vpnv4|vpnv6>",
1499 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1500 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1505 DEFUN (show_ip_bgp_vpn_all_tags
,
1506 show_ip_bgp_vpn_all_tags_cmd
,
1507 "show [ip] bgp <vpnv4|vpnv6> all tags",
1512 "Display information about all VPNv4/VPNV6 NLRIs\n"
1513 "Display BGP tags for prefixes\n")
1518 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1519 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1524 DEFUN (show_ip_bgp_vpn_rd_tags
,
1525 show_ip_bgp_vpn_rd_tags_cmd
,
1526 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
1531 "Display information for a route distinguisher\n"
1532 "VPN Route Distinguisher\n"
1533 "Display BGP tags for prefixes\n")
1535 int idx_ext_community
= 5;
1537 struct prefix_rd prd
;
1541 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1542 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1544 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1547 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1553 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1554 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1555 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1560 "Display information about all VPNv4/VPNv6 NLRIs\n"
1561 "Detailed information on TCP and BGP neighbor connections\n"
1562 "Neighbor to display information about\n"
1563 "Display routes learned from neighbor\n"
1570 uint8_t uj
= use_json(argc
, argv
);
1574 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1575 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1578 json_object
*json_no
= NULL
;
1579 json_no
= json_object_new_object();
1580 json_object_string_add(json_no
, "warning",
1581 "Malformed address");
1582 vty_out(vty
, "%s\n",
1583 json_object_to_json_string(json_no
));
1584 json_object_free(json_no
);
1586 vty_out(vty
, "Malformed address: %s\n",
1587 argv
[idx_ipv4
]->arg
);
1591 peer
= peer_lookup(NULL
, &su
);
1592 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1594 json_object
*json_no
= NULL
;
1595 json_no
= json_object_new_object();
1596 json_object_string_add(
1598 "No such neighbor or address family");
1599 vty_out(vty
, "%s\n",
1600 json_object_to_json_string(json_no
));
1601 json_object_free(json_no
);
1604 "%% No such neighbor or address family\n");
1608 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
1614 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
1615 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
1616 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
1621 "Display information for a route distinguisher\n"
1622 "VPN Route Distinguisher\n"
1623 "Detailed information on TCP and BGP neighbor connections\n"
1624 "Neighbor to display information about\n"
1625 "Display routes learned from neighbor\n"
1628 int idx_ext_community
= 5;
1633 struct prefix_rd prd
;
1634 uint8_t uj
= use_json(argc
, argv
);
1638 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1639 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1642 json_object
*json_no
= NULL
;
1643 json_no
= json_object_new_object();
1644 json_object_string_add(
1646 "Malformed Route Distinguisher");
1647 vty_out(vty
, "%s\n",
1648 json_object_to_json_string(json_no
));
1649 json_object_free(json_no
);
1652 "%% Malformed Route Distinguisher\n");
1656 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1659 json_object
*json_no
= NULL
;
1660 json_no
= json_object_new_object();
1661 json_object_string_add(json_no
, "warning",
1662 "Malformed address");
1663 vty_out(vty
, "%s\n",
1664 json_object_to_json_string(json_no
));
1665 json_object_free(json_no
);
1667 vty_out(vty
, "Malformed address: %s\n",
1668 argv
[idx_ext_community
]->arg
);
1672 peer
= peer_lookup(NULL
, &su
);
1673 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1675 json_object
*json_no
= NULL
;
1676 json_no
= json_object_new_object();
1677 json_object_string_add(
1679 "No such neighbor or address family");
1680 vty_out(vty
, "%s\n",
1681 json_object_to_json_string(json_no
));
1682 json_object_free(json_no
);
1685 "%% No such neighbor or address family\n");
1689 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
1695 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
1696 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
1697 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1702 "Display information about all VPNv4/VPNv6 NLRIs\n"
1703 "Detailed information on TCP and BGP neighbor connections\n"
1704 "Neighbor to display information about\n"
1705 "Display the routes advertised to a BGP neighbor\n"
1712 uint8_t uj
= use_json(argc
, argv
);
1716 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1717 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1720 json_object
*json_no
= NULL
;
1721 json_no
= json_object_new_object();
1722 json_object_string_add(json_no
, "warning",
1723 "Malformed address");
1724 vty_out(vty
, "%s\n",
1725 json_object_to_json_string(json_no
));
1726 json_object_free(json_no
);
1728 vty_out(vty
, "Malformed address: %s\n",
1729 argv
[idx_ipv4
]->arg
);
1732 peer
= peer_lookup(NULL
, &su
);
1733 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1735 json_object
*json_no
= NULL
;
1736 json_no
= json_object_new_object();
1737 json_object_string_add(
1739 "No such neighbor or address family");
1740 vty_out(vty
, "%s\n",
1741 json_object_to_json_string(json_no
));
1742 json_object_free(json_no
);
1745 "%% No such neighbor or address family\n");
1748 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
1754 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
1755 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
1756 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
1761 "Display information for a route distinguisher\n"
1762 "VPN Route Distinguisher\n"
1763 "Detailed information on TCP and BGP neighbor connections\n"
1764 "Neighbor to display information about\n"
1765 "Display the routes advertised to a BGP neighbor\n"
1768 int idx_ext_community
= 5;
1772 struct prefix_rd prd
;
1774 uint8_t uj
= use_json(argc
, argv
);
1778 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1779 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1782 json_object
*json_no
= NULL
;
1783 json_no
= json_object_new_object();
1784 json_object_string_add(json_no
, "warning",
1785 "Malformed address");
1786 vty_out(vty
, "%s\n",
1787 json_object_to_json_string(json_no
));
1788 json_object_free(json_no
);
1790 vty_out(vty
, "Malformed address: %s\n",
1791 argv
[idx_ext_community
]->arg
);
1794 peer
= peer_lookup(NULL
, &su
);
1795 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1797 json_object
*json_no
= NULL
;
1798 json_no
= json_object_new_object();
1799 json_object_string_add(
1801 "No such neighbor or address family");
1802 vty_out(vty
, "%s\n",
1803 json_object_to_json_string(json_no
));
1804 json_object_free(json_no
);
1807 "%% No such neighbor or address family\n");
1811 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1814 json_object
*json_no
= NULL
;
1815 json_no
= json_object_new_object();
1816 json_object_string_add(
1818 "Malformed Route Distinguisher");
1819 vty_out(vty
, "%s\n",
1820 json_object_to_json_string(json_no
));
1821 json_object_free(json_no
);
1824 "%% Malformed Route Distinguisher\n");
1828 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
1833 #endif /* KEEP_OLD_VPN_COMMANDS */
1835 void bgp_mplsvpn_init(void)
1837 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
1838 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
1839 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
1841 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
1842 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
1844 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
1845 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
1846 #ifdef KEEP_OLD_VPN_COMMANDS
1847 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
1848 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
1849 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
1850 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
1851 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
1852 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
1853 install_element(VIEW_NODE
,
1854 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
1855 install_element(VIEW_NODE
,
1856 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
1857 #endif /* KEEP_OLD_VPN_COMMANDS */
1860 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
1862 struct listnode
*mnode
, *mnnode
;
1865 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1866 struct ecommunity
*ec
;
1868 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1871 ec
= bgp
->vpn_policy
[AFI_IP
].import_redirect_rtlist
;
1873 if (ecom_intersect(ec
, eckey
))