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"
49 #include "bgpd/rfapi/rfapi_backend.h"
53 * Definitions and external declarations.
55 extern struct zclient
*zclient
;
57 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
58 int *index
, afi_t
*afi
)
61 if (argv_find(argv
, argc
, "vpnv4", index
)) {
65 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
73 u_int32_t
decode_label(mpls_label_t
*label_pnt
)
76 u_char
*pnt
= (u_char
*)label_pnt
;
78 l
= ((u_int32_t
)*pnt
++ << 12);
79 l
|= (u_int32_t
)*pnt
++ << 4;
80 l
|= (u_int32_t
)((*pnt
& 0xf0) >> 4);
84 void encode_label(mpls_label_t label
, mpls_label_t
*label_pnt
)
86 u_char
*pnt
= (u_char
*)label_pnt
;
89 *pnt
++ = (label
>> 12) & 0xff;
90 *pnt
++ = (label
>> 4) & 0xff;
91 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
94 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
95 struct bgp_nlri
*packet
)
105 struct prefix_rd prd
;
106 mpls_label_t label
= {0};
110 u_int32_t addpath_id
;
113 prd
.family
= AF_UNSPEC
;
117 lim
= pnt
+ packet
->length
;
123 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
124 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
125 PEER_CAP_ADDPATH_AF_TX_RCV
));
127 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
128 for (; pnt
< lim
; pnt
+= psize
) {
129 /* Clear prefix structure. */
130 memset(&p
, 0, sizeof(struct prefix
));
132 if (addpath_encoded
) {
134 /* When packet overflow occurs return immediately. */
135 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
138 addpath_id
= ntohl(*((uint32_t *)pnt
));
139 pnt
+= BGP_ADDPATH_ID_LEN
;
142 /* Fetch prefix length. */
144 p
.family
= afi2family(packet
->afi
);
145 psize
= PSIZE(prefixlen
);
147 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
149 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
150 peer
->host
, prefixlen
);
154 /* sanity check against packet data */
155 if ((pnt
+ psize
) > lim
) {
157 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
158 peer
->host
, prefixlen
, (uint
)(lim
- pnt
));
162 /* sanity check against storage for the IP address portion */
163 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
165 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
167 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
172 /* Sanity check against max bitlen of the address family */
173 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
175 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
177 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
178 p
.family
, prefix_blen(&p
));
182 /* Copy label to prefix. */
183 memcpy(&label
, pnt
, BGP_LABEL_BYTES
);
184 bgp_set_valid_label(&label
);
186 /* Copy routing distinguisher to rd. */
187 memcpy(&prd
.val
, pnt
+ BGP_LABEL_BYTES
, 8);
189 /* Decode RD type. */
190 type
= decode_rd_type(pnt
+ BGP_LABEL_BYTES
);
194 decode_rd_as(pnt
+ 5, &rd_as
);
198 decode_rd_as4(pnt
+ 5, &rd_as
);
202 decode_rd_ip(pnt
+ 5, &rd_ip
);
206 case RD_TYPE_VNC_ETH
:
211 zlog_err("Unknown RD type %d", type
);
212 break; /* just report */
217 - VPN_PREFIXLEN_MIN_BYTES
* 8; /* exclude label & RD */
218 memcpy(&p
.u
.prefix
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
219 psize
- VPN_PREFIXLEN_MIN_BYTES
);
222 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
223 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
224 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
226 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
227 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
228 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
231 /* Packet length consistency check. */
234 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
235 peer
->host
, lim
- pnt
);
240 #undef VPN_PREFIXLEN_MIN_BYTES
244 * This function informs zebra of the label this vrf sets on routes
245 * leaked to VPN. Zebra should install this label in the kernel with
246 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
248 * Sending this vrf-label association is qualified by a) whether vrf->vpn
249 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
250 * are set) and b) whether vpn-policy label is set.
252 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
253 * for this vrf, which zebra interprets to mean "delete this vrf-label
256 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
258 mpls_label_t label
= MPLS_LABEL_NONE
;
259 const char *name
= "default";
260 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
262 if (debug
&& (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
)) {
266 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
269 "%s: vrf %s: afi %s: vrf_id not set, "
270 "can't set zebra vrf label",
271 __func__
, name
, afi2str(afi
));
276 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
277 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
281 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
282 __func__
, name
, afi2str(afi
), label
, bgp
->vrf_id
);
285 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
286 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
290 * If zebra tells us vrf has become unconfigured, tell zebra not to
291 * use this label to forward to the vrf anymore
293 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
295 mpls_label_t label
= MPLS_LABEL_NONE
;
296 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
298 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
301 "%s: vrf_id not set, can't delete zebra vrf label",
308 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
309 (bgp
->name
? bgp
->name
: "default"), bgp
->vrf_id
);
312 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
313 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
316 static int ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
324 for (i
= 0; i
< e1
->size
; ++i
) {
325 for (j
= 0; j
< e2
->size
; ++j
) {
326 if (!memcmp(e1
->val
+ (i
* ECOMMUNITY_SIZE
),
327 e2
->val
+ (j
* ECOMMUNITY_SIZE
),
338 * returns pointer to new bgp_info upon success
340 static struct bgp_info
*
341 leak_update(struct bgp
*bgp
, /* destination bgp instance */
342 struct bgp_node
*bn
, struct attr
*new_attr
, /* already interned */
343 afi_t afi
, safi_t safi
, struct bgp_info
*source_bi
, u_char type
,
344 u_char sub_type
, mpls_label_t
*label
, int num_labels
, void *parent
,
345 struct bgp
*bgp_orig
, struct prefix
*nexthop_orig
, int debug
)
347 struct prefix
*p
= &bn
->p
;
349 struct bgp_info
*new;
350 char buf_prefix
[PREFIX_STRLEN
];
351 const char *pDestInstanceName
= "default";
354 prefix2str(&bn
->p
, buf_prefix
, sizeof(buf_prefix
));
356 pDestInstanceName
= bgp
->name
;
362 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
363 if (bi
->extra
&& bi
->extra
->parent
== parent
)
368 if (attrhash_cmp(bi
->attr
, new_attr
)
369 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
371 bgp_attr_unintern(&new_attr
);
374 "%s: ->%s: %s: Found route, no change",
375 __func__
, pDestInstanceName
,
380 /* attr is changed */
381 bgp_info_set_flag(bn
, bi
, BGP_INFO_ATTR_CHANGED
);
383 /* Rewrite BGP route information. */
384 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
385 bgp_info_restore(bn
, bi
);
387 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
388 bgp_attr_unintern(&bi
->attr
);
390 bi
->uptime
= bgp_clock();
392 /* Process change. */
393 bgp_aggregate_increment(bgp
, p
, bi
, afi
, safi
);
394 bgp_process(bgp
, bn
, afi
, safi
);
398 zlog_debug("%s: ->%s: %s Found route, changed attr",
399 __func__
, pDestInstanceName
, buf_prefix
);
404 new = info_make(type
, sub_type
, 0, bgp
->peer_self
, new_attr
, bn
);
405 SET_FLAG(new->flags
, BGP_INFO_VALID
);
407 bgp_info_extra_get(new);
411 for (i
= 0; i
< num_labels
; ++i
) {
412 new->extra
->label
[i
] = label
[i
];
413 if (!bgp_is_valid_label(&label
[i
])) {
416 "%s: %s: marking label %d valid",
417 __func__
, buf_prefix
, i
);
419 bgp_set_valid_label(&new->extra
->label
[i
]);
422 new->extra
->num_labels
= num_labels
;
424 new->extra
->parent
= parent
;
427 new->extra
->bgp_orig
= bgp_orig
;
429 new->extra
->nexthop_orig
= *nexthop_orig
;
431 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
432 bgp_info_add(bn
, new);
435 bgp_process(bgp
, bn
, afi
, safi
);
438 zlog_debug("%s: ->%s: %s: Added new route", __func__
,
439 pDestInstanceName
, buf_prefix
);
444 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
445 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
446 struct bgp
*bgp_vrf
, /* from */
447 struct bgp_info
*info_vrf
) /* route */
449 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
450 struct prefix
*p
= &info_vrf
->net
->p
;
451 afi_t afi
= family2afi(p
->family
);
452 struct attr static_attr
= {0};
453 struct attr
*new_attr
= NULL
;
454 safi_t safi
= SAFI_MPLS_VPN
;
455 mpls_label_t label_val
;
458 const char *debugmsg
;
460 if (debug
&& info_vrf
->attr
->ecommunity
) {
461 char *s
= ecommunity_ecom2str(info_vrf
->attr
->ecommunity
,
462 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
464 zlog_debug("%s: info_vrf->type=%d, EC{%s}", __func__
,
466 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
474 zlog_debug("%s: can't get afi of prefix", __func__
);
479 if (info_vrf
->extra
&& info_vrf
->extra
->bgp_orig
== bgp_vpn
)
483 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
485 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
489 bgp_attr_dup(&static_attr
, info_vrf
->attr
); /* shallow copy */
494 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
495 struct bgp_info info
;
496 route_map_result_t ret
;
498 memset(&info
, 0, sizeof(info
));
499 info
.peer
= bgp_vpn
->peer_self
;
500 info
.attr
= &static_attr
;
501 ret
= route_map_apply(
502 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
504 if (RMAP_DENYMATCH
== ret
) {
505 bgp_attr_flush(&static_attr
); /* free any added parts */
508 "%s: vrf %s route map \"%s\" says DENY, returning",
509 __func__
, bgp_vrf
->name
,
510 bgp_vrf
->vpn_policy
[afi
]
511 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
517 if (debug
&& static_attr
.ecommunity
) {
518 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
519 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
521 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
523 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
527 * Add the vpn-policy rt-list
529 struct ecommunity
*old_ecom
;
530 struct ecommunity
*new_ecom
;
532 old_ecom
= static_attr
.ecommunity
;
534 new_ecom
= ecommunity_merge(
535 ecommunity_dup(old_ecom
),
536 bgp_vrf
->vpn_policy
[afi
]
537 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
538 if (!old_ecom
->refcnt
)
539 ecommunity_free(&old_ecom
);
541 new_ecom
= ecommunity_dup(
542 bgp_vrf
->vpn_policy
[afi
]
543 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
545 static_attr
.ecommunity
= new_ecom
;
546 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
548 if (debug
&& static_attr
.ecommunity
) {
549 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
550 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
552 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
554 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
558 /* if policy nexthop not set, use 0 */
559 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
560 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
562 struct prefix
*nexthop
=
563 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
564 switch (nexthop
->family
) {
566 /* prevent mp_nexthop_global_in <- self in bgp_route.c
568 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
570 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
571 static_attr
.mp_nexthop_len
= 4;
575 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
576 static_attr
.mp_nexthop_len
= 16;
587 static_attr
.mp_nexthop_global_in
.s_addr
= 0;
588 static_attr
.mp_nexthop_len
= 4;
589 static_attr
.nexthop
.s_addr
= 0; /* self */
590 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
595 memset(&static_attr
.mp_nexthop_global
, 0,
596 sizeof(static_attr
.mp_nexthop_global
));
597 static_attr
.mp_nexthop_len
= 16; /* bytes */
602 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
603 if (label_val
== MPLS_LABEL_NONE
) {
604 /* TBD get from label manager */
605 label
= MPLS_LABEL_IMPLICIT_NULL
;
607 encode_label(label_val
, &label
);
610 /* Set originator ID to "me" */
611 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
612 static_attr
.originator_id
= bgp_vpn
->router_id
;
615 new_attr
= bgp_attr_intern(
616 &static_attr
); /* hashed refcounted everything */
617 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
619 if (debug
&& new_attr
->ecommunity
) {
620 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
621 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
623 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
624 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
627 /* Now new_attr is an allocated interned attr */
629 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
630 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
632 struct bgp_info
*new_info
;
634 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, info_vrf
,
635 ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, &label
, 1,
636 info_vrf
, bgp_vrf
, NULL
, debug
);
639 * Routes actually installed in the vpn RIB must also be
640 * offered to all vrfs (because now they originate from
643 * Acceptance into other vrfs depends on rt-lists.
644 * Originating vrf will not accept the looped back route
645 * because of loop checking.
648 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
651 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
652 struct bgp
*bgp_vrf
, /* from */
653 struct bgp_info
*info_vrf
) /* route */
655 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
656 struct prefix
*p
= &info_vrf
->net
->p
;
657 afi_t afi
= family2afi(p
->family
);
658 safi_t safi
= SAFI_MPLS_VPN
;
661 const char *debugmsg
;
663 if (info_vrf
->type
!= ZEBRA_ROUTE_BGP
) {
665 zlog_debug("%s: wrong type %d", __func__
,
669 if (info_vrf
->sub_type
!= BGP_ROUTE_NORMAL
670 && info_vrf
->sub_type
!= BGP_ROUTE_STATIC
) {
673 zlog_debug("%s: wrong sub_type %d", __func__
,
682 zlog_debug("%s: can't get afi of prefix", __func__
);
686 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
688 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
693 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__
, info_vrf
);
695 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
696 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
700 * match original bi imported from
702 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
703 if (bi
->extra
&& bi
->extra
->parent
== info_vrf
) {
709 /* withdraw from looped vrfs as well */
710 vpn_leak_to_vrf_withdraw(bgp_vpn
, bi
);
712 bgp_aggregate_decrement(bgp_vpn
, p
, bi
, afi
, safi
);
713 bgp_info_delete(bn
, bi
);
714 bgp_process(bgp_vpn
, bn
, afi
, safi
);
719 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
720 struct bgp
*bgp_vrf
, /* from */
723 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
724 struct bgp_node
*prn
;
725 safi_t safi
= SAFI_MPLS_VPN
;
728 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
730 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
731 prn
= bgp_route_next(prn
)) {
733 struct bgp_table
*table
;
737 /* This is the per-RD table of prefixes */
743 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
745 char buf
[PREFIX2STR_BUFFER
];
747 if (debug
&& bn
->info
) {
749 "%s: looking at prefix %s", __func__
,
750 prefix2str(&bn
->p
, buf
, sizeof(buf
)));
753 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
755 zlog_debug("%s: type %d, sub_type %d",
758 if (bi
->sub_type
!= BGP_ROUTE_IMPORTED
)
762 if ((struct bgp
*)bi
->extra
->bgp_orig
766 zlog_debug("%s: deleting it\n",
768 bgp_aggregate_decrement(bgp_vpn
, &bn
->p
,
770 bgp_info_delete(bn
, bi
);
771 bgp_process(bgp_vpn
, bn
, afi
, safi
);
778 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
779 struct bgp
*bgp_vrf
, /* from */
784 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
787 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
790 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
791 bn
= bgp_route_next(bn
)) {
794 zlog_debug("%s: node=%p", __func__
, bn
);
796 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
799 "%s: calling vpn_leak_from_vrf_update",
801 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bi
);
806 static void vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
807 struct bgp
*bgp_vpn
, /* from */
808 struct bgp_info
*info_vpn
) /* route */
810 struct prefix
*p
= &info_vpn
->net
->p
;
811 afi_t afi
= family2afi(p
->family
);
813 struct attr static_attr
= {0};
814 struct attr
*new_attr
= NULL
;
816 safi_t safi
= SAFI_UNICAST
;
817 const char *debugmsg
;
818 struct prefix nexthop_orig
;
819 mpls_label_t
*pLabels
= NULL
;
822 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
824 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
826 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
830 /* Check for intersection of route targets */
832 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
833 info_vpn
->attr
->ecommunity
)) {
839 zlog_debug("%s: updating to vrf %s", __func__
, bgp_vrf
->name
);
841 bgp_attr_dup(&static_attr
, info_vpn
->attr
); /* shallow copy */
844 * Nexthop: stash and clear
846 * Nexthop is valid in context of VPN core, but not in destination vrf.
847 * Stash it for later label resolution by vrf ingress path and then
848 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
850 uint8_t nhfamily
= NEXTHOP_FAMILY(info_vpn
->attr
->mp_nexthop_len
);
852 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
853 nexthop_orig
.family
= nhfamily
;
859 nexthop_orig
.u
.prefix4
= info_vpn
->attr
->mp_nexthop_global_in
;
860 nexthop_orig
.prefixlen
= 32;
862 static_attr
.nexthop
.s_addr
= 0; /* self */
863 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
869 nexthop_orig
.u
.prefix6
= info_vpn
->attr
->mp_nexthop_global
;
870 nexthop_orig
.prefixlen
= 128;
872 memset(&static_attr
.mp_nexthop_global
, 0,
873 sizeof(static_attr
.mp_nexthop_global
)); /* clear */
874 static_attr
.mp_nexthop_len
= 16; /* bytes */
882 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
883 struct bgp_info info
;
884 route_map_result_t ret
;
886 memset(&info
, 0, sizeof(info
));
887 info
.peer
= bgp_vrf
->peer_self
;
888 info
.attr
= &static_attr
;
889 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
890 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
892 if (RMAP_DENYMATCH
== ret
) {
893 bgp_attr_flush(&static_attr
); /* free any added parts */
896 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
897 __func__
, bgp_vrf
->name
,
898 bgp_vrf
->vpn_policy
[afi
]
899 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
905 new_attr
= bgp_attr_intern(&static_attr
);
906 bgp_attr_flush(&static_attr
);
908 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
911 * ensure labels are copied
913 if (info_vpn
->extra
&& info_vpn
->extra
->num_labels
) {
914 num_labels
= info_vpn
->extra
->num_labels
;
915 if (num_labels
> BGP_MAX_LABELS
)
916 num_labels
= BGP_MAX_LABELS
;
917 pLabels
= info_vpn
->extra
->label
;
920 char buf_prefix
[PREFIX_STRLEN
];
921 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
922 zlog_debug("%s: pfx %s: num_labels %d", __func__
, buf_prefix
,
926 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, info_vpn
, ZEBRA_ROUTE_BGP
,
927 BGP_ROUTE_IMPORTED
, pLabels
, num_labels
,
928 info_vpn
, /* parent */
929 bgp_vpn
, &nexthop_orig
, debug
);
932 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
933 struct bgp_info
*info_vpn
) /* route */
935 struct listnode
*mnode
, *mnnode
;
938 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
941 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
944 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
947 || info_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
948 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, info_vpn
);
953 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
954 struct bgp_info
*info_vpn
) /* route */
958 safi_t safi
= SAFI_UNICAST
;
960 struct listnode
*mnode
, *mnnode
;
963 const char *debugmsg
;
965 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
968 zlog_debug("%s: start (info_vpn=%p)", __func__
, info_vpn
);
970 if (!info_vpn
->net
) {
972 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
973 if (info_vpn
->type
== ZEBRA_ROUTE_BGP
&&
974 info_vpn
->sub_type
== BGP_ROUTE_RFP
) {
980 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
985 p
= &info_vpn
->net
->p
;
986 afi
= family2afi(p
->family
);
989 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
990 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
992 zlog_debug("%s: skipping: %s", __func__
,
997 /* Check for intersection of route targets */
998 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
999 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1000 info_vpn
->attr
->ecommunity
)) {
1006 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1009 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1010 for (bi
= (bn
? bn
->info
: NULL
); bi
; bi
= bi
->next
) {
1012 && (struct bgp_info
*)bi
->extra
->parent
1020 zlog_debug("%s: deleting bi %p", __func__
, bi
);
1021 bgp_aggregate_decrement(bgp
, p
, bi
, afi
, safi
);
1022 bgp_info_delete(bn
, bi
);
1023 bgp_process(bgp
, bn
, afi
, safi
);
1025 bgp_unlock_node(bn
);
1029 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1032 struct bgp_node
*bn
;
1033 struct bgp_info
*bi
;
1034 safi_t safi
= SAFI_UNICAST
;
1035 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1036 struct bgp
*bgp_vpn
= bgp_get_default();
1039 zlog_debug("%s: entry", __func__
);
1041 * Walk vrf table, delete bi with bgp_orig == bgp_vpn
1043 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1044 bn
= bgp_route_next(bn
)) {
1046 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1047 if (bi
->extra
&& bi
->extra
->bgp_orig
== bgp_vpn
) {
1050 bgp_aggregate_decrement(bgp_vrf
, &bn
->p
, bi
,
1052 bgp_info_delete(bn
, bi
);
1053 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1059 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1060 struct bgp
*bgp_vpn
, /* from */
1063 struct prefix_rd prd
;
1064 struct bgp_node
*prn
;
1065 safi_t safi
= SAFI_MPLS_VPN
;
1070 for (prn
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); prn
;
1071 prn
= bgp_route_next(prn
)) {
1073 struct bgp_table
*table
;
1074 struct bgp_node
*bn
;
1075 struct bgp_info
*bi
;
1077 memset(&prd
, 0, sizeof(prd
));
1078 prd
.family
= AF_UNSPEC
;
1080 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
1082 /* This is the per-RD table of prefixes */
1088 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1090 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1092 if (bi
->extra
&& bi
->extra
->bgp_orig
== bgp_vrf
)
1095 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1102 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1104 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1106 struct route_map
*rmap
;
1108 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1109 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1114 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1116 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1118 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)
1119 && bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1120 && !strcmp(rmap_name
,
1121 bgp
->vpn_policy
[afi
]
1122 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1126 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1127 __func__
, rmap_name
, bgp
->as
,
1130 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1131 bgp_get_default(), bgp
);
1133 zlog_debug("%s: after vpn_leak_prechange",
1137 bgp
->vpn_policy
[afi
]
1138 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
] = NULL
;
1140 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1141 bgp_get_default(), bgp
);
1143 zlog_debug("%s: after vpn_leak_postchange",
1147 char *mapname
= bgp
->vpn_policy
[afi
]
1148 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
];
1150 if (vpn_leak_from_vpn_active(bgp
, afi
, NULL
) &&
1152 !strcmp(rmap_name
, mapname
)) {
1155 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1156 __func__
, rmap_name
, bgp
->as
,
1160 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1161 bgp_get_default(), bgp
);
1164 bgp
->vpn_policy
[afi
]
1165 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1169 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1170 bgp_get_default(), bgp
);
1175 void vpn_policy_routemap_event(const char *rmap_name
)
1177 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1178 struct listnode
*mnode
, *mnnode
;
1182 zlog_debug("%s: entry", __func__
);
1184 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1187 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1188 vpn_policy_routemap_update(bgp
, rmap_name
);
1191 /* For testing purpose, static route of MPLS-VPN. */
1192 DEFUN (vpnv4_network
,
1194 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1195 "Specify a network to announce via BGP\n"
1197 "Specify Route Distinguisher\n"
1198 "VPN Route Distinguisher\n"
1199 "VPN NLRI label (tag)\n"
1200 "VPN NLRI label (tag)\n"
1203 int idx_ipv4_prefixlen
= 1;
1204 int idx_ext_community
= 3;
1206 return bgp_static_set_safi(
1207 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1208 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
1209 NULL
, NULL
, NULL
, NULL
);
1212 DEFUN (vpnv4_network_route_map
,
1213 vpnv4_network_route_map_cmd
,
1214 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1215 "Specify a network to announce via BGP\n"
1217 "Specify Route Distinguisher\n"
1218 "VPN Route Distinguisher\n"
1219 "VPN NLRI label (tag)\n"
1220 "VPN NLRI label (tag)\n"
1225 int idx_ipv4_prefixlen
= 1;
1226 int idx_ext_community
= 3;
1229 return bgp_static_set_safi(
1230 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1231 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1232 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1235 /* For testing purpose, static route of MPLS-VPN. */
1236 DEFUN (no_vpnv4_network
,
1237 no_vpnv4_network_cmd
,
1238 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1240 "Specify a network to announce via BGP\n"
1242 "Specify Route Distinguisher\n"
1243 "VPN Route Distinguisher\n"
1244 "VPN NLRI label (tag)\n"
1245 "VPN NLRI label (tag)\n"
1248 int idx_ipv4_prefixlen
= 2;
1249 int idx_ext_community
= 4;
1251 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
1252 argv
[idx_ipv4_prefixlen
]->arg
,
1253 argv
[idx_ext_community
]->arg
,
1254 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1257 DEFUN (vpnv6_network
,
1259 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1260 "Specify a network to announce via BGP\n"
1261 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1262 "Specify Route Distinguisher\n"
1263 "VPN Route Distinguisher\n"
1264 "VPN NLRI label (tag)\n"
1265 "VPN NLRI label (tag)\n"
1270 int idx_ipv6_prefix
= 1;
1271 int idx_ext_community
= 3;
1275 return bgp_static_set_safi(
1276 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1277 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1278 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
1280 return bgp_static_set_safi(
1281 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
1282 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1283 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1286 /* For testing purpose, static route of MPLS-VPN. */
1287 DEFUN (no_vpnv6_network
,
1288 no_vpnv6_network_cmd
,
1289 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1291 "Specify a network to announce via BGP\n"
1292 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1293 "Specify Route Distinguisher\n"
1294 "VPN Route Distinguisher\n"
1295 "VPN NLRI label (tag)\n"
1296 "VPN NLRI label (tag)\n"
1299 int idx_ipv6_prefix
= 2;
1300 int idx_ext_community
= 4;
1302 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
1303 argv
[idx_ipv6_prefix
]->arg
,
1304 argv
[idx_ext_community
]->arg
,
1305 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
1308 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
1309 enum bgp_show_type type
, void *output_arg
, int tags
,
1313 struct bgp_table
*table
;
1315 bgp
= bgp_get_default();
1318 vty_out(vty
, "No BGP process is configured\n");
1320 vty_out(vty
, "{}\n");
1323 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
1324 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
1325 output_arg
, use_json
);
1328 DEFUN (show_bgp_ip_vpn_all_rd
,
1329 show_bgp_ip_vpn_all_rd_cmd
,
1330 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1334 "Display VPN NLRI specific information\n"
1335 "Display VPN NLRI specific information\n"
1336 "Display information for a route distinguisher\n"
1337 "VPN Route Distinguisher\n"
1341 struct prefix_rd prd
;
1345 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
1346 if (argv_find(argv
, argc
, "rd", &idx
)) {
1347 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
1350 "%% Malformed Route Distinguisher\n");
1353 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
1354 bgp_show_type_normal
, NULL
, 0,
1355 use_json(argc
, argv
));
1357 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
1358 bgp_show_type_normal
, NULL
, 0,
1359 use_json(argc
, argv
));
1365 ALIAS(show_bgp_ip_vpn_all_rd
,
1366 show_bgp_ip_vpn_rd_cmd
,
1367 "show bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1371 "Display VPN NLRI specific information\n"
1372 "Display information for a route distinguisher\n"
1373 "VPN Route Distinguisher\n"
1376 #ifdef KEEP_OLD_VPN_COMMANDS
1377 DEFUN (show_ip_bgp_vpn_rd
,
1378 show_ip_bgp_vpn_rd_cmd
,
1379 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
1384 "Address Family modifier\n"
1385 "Display information for a route distinguisher\n"
1386 "VPN Route Distinguisher\n")
1388 int idx_ext_community
= argc
- 1;
1390 struct prefix_rd prd
;
1394 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1395 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1397 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1400 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1406 DEFUN (show_ip_bgp_vpn_all
,
1407 show_ip_bgp_vpn_all_cmd
,
1408 "show [ip] bgp <vpnv4|vpnv6>",
1417 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1418 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1423 DEFUN (show_ip_bgp_vpn_all_tags
,
1424 show_ip_bgp_vpn_all_tags_cmd
,
1425 "show [ip] bgp <vpnv4|vpnv6> all tags",
1430 "Display information about all VPNv4/VPNV6 NLRIs\n"
1431 "Display BGP tags for prefixes\n")
1436 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
1437 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
1442 DEFUN (show_ip_bgp_vpn_rd_tags
,
1443 show_ip_bgp_vpn_rd_tags_cmd
,
1444 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
1449 "Display information for a route distinguisher\n"
1450 "VPN Route Distinguisher\n"
1451 "Display BGP tags for prefixes\n")
1453 int idx_ext_community
= 5;
1455 struct prefix_rd prd
;
1459 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1460 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1462 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1465 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
1471 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1472 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1473 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1478 "Display information about all VPNv4/VPNv6 NLRIs\n"
1479 "Detailed information on TCP and BGP neighbor connections\n"
1480 "Neighbor to display information about\n"
1481 "Display routes learned from neighbor\n"
1488 u_char uj
= use_json(argc
, argv
);
1492 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1493 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1496 json_object
*json_no
= NULL
;
1497 json_no
= json_object_new_object();
1498 json_object_string_add(json_no
, "warning",
1499 "Malformed address");
1500 vty_out(vty
, "%s\n",
1501 json_object_to_json_string(json_no
));
1502 json_object_free(json_no
);
1504 vty_out(vty
, "Malformed address: %s\n",
1505 argv
[idx_ipv4
]->arg
);
1509 peer
= peer_lookup(NULL
, &su
);
1510 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1512 json_object
*json_no
= NULL
;
1513 json_no
= json_object_new_object();
1514 json_object_string_add(
1516 "No such neighbor or address family");
1517 vty_out(vty
, "%s\n",
1518 json_object_to_json_string(json_no
));
1519 json_object_free(json_no
);
1522 "%% No such neighbor or address family\n");
1526 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
1532 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
1533 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
1534 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
1539 "Display information for a route distinguisher\n"
1540 "VPN Route Distinguisher\n"
1541 "Detailed information on TCP and BGP neighbor connections\n"
1542 "Neighbor to display information about\n"
1543 "Display routes learned from neighbor\n"
1546 int idx_ext_community
= 5;
1551 struct prefix_rd prd
;
1552 u_char uj
= use_json(argc
, argv
);
1556 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1557 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1560 json_object
*json_no
= NULL
;
1561 json_no
= json_object_new_object();
1562 json_object_string_add(
1564 "Malformed Route Distinguisher");
1565 vty_out(vty
, "%s\n",
1566 json_object_to_json_string(json_no
));
1567 json_object_free(json_no
);
1570 "%% Malformed Route Distinguisher\n");
1574 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1577 json_object
*json_no
= NULL
;
1578 json_no
= json_object_new_object();
1579 json_object_string_add(json_no
, "warning",
1580 "Malformed address");
1581 vty_out(vty
, "%s\n",
1582 json_object_to_json_string(json_no
));
1583 json_object_free(json_no
);
1585 vty_out(vty
, "Malformed address: %s\n",
1586 argv
[idx_ext_community
]->arg
);
1590 peer
= peer_lookup(NULL
, &su
);
1591 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1593 json_object
*json_no
= NULL
;
1594 json_no
= json_object_new_object();
1595 json_object_string_add(
1597 "No such neighbor or address family");
1598 vty_out(vty
, "%s\n",
1599 json_object_to_json_string(json_no
));
1600 json_object_free(json_no
);
1603 "%% No such neighbor or address family\n");
1607 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
1613 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
1614 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
1615 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1620 "Display information about all VPNv4/VPNv6 NLRIs\n"
1621 "Detailed information on TCP and BGP neighbor connections\n"
1622 "Neighbor to display information about\n"
1623 "Display the routes advertised to a BGP neighbor\n"
1630 u_char uj
= use_json(argc
, argv
);
1634 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1635 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1638 json_object
*json_no
= NULL
;
1639 json_no
= json_object_new_object();
1640 json_object_string_add(json_no
, "warning",
1641 "Malformed address");
1642 vty_out(vty
, "%s\n",
1643 json_object_to_json_string(json_no
));
1644 json_object_free(json_no
);
1646 vty_out(vty
, "Malformed address: %s\n",
1647 argv
[idx_ipv4
]->arg
);
1650 peer
= peer_lookup(NULL
, &su
);
1651 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1653 json_object
*json_no
= NULL
;
1654 json_no
= json_object_new_object();
1655 json_object_string_add(
1657 "No such neighbor or address family");
1658 vty_out(vty
, "%s\n",
1659 json_object_to_json_string(json_no
));
1660 json_object_free(json_no
);
1663 "%% No such neighbor or address family\n");
1666 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
1672 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
1673 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
1674 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
1679 "Display information for a route distinguisher\n"
1680 "VPN Route Distinguisher\n"
1681 "Detailed information on TCP and BGP neighbor connections\n"
1682 "Neighbor to display information about\n"
1683 "Display the routes advertised to a BGP neighbor\n"
1686 int idx_ext_community
= 5;
1690 struct prefix_rd prd
;
1692 u_char uj
= use_json(argc
, argv
);
1696 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1697 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1700 json_object
*json_no
= NULL
;
1701 json_no
= json_object_new_object();
1702 json_object_string_add(json_no
, "warning",
1703 "Malformed address");
1704 vty_out(vty
, "%s\n",
1705 json_object_to_json_string(json_no
));
1706 json_object_free(json_no
);
1708 vty_out(vty
, "Malformed address: %s\n",
1709 argv
[idx_ext_community
]->arg
);
1712 peer
= peer_lookup(NULL
, &su
);
1713 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1715 json_object
*json_no
= NULL
;
1716 json_no
= json_object_new_object();
1717 json_object_string_add(
1719 "No such neighbor or address family");
1720 vty_out(vty
, "%s\n",
1721 json_object_to_json_string(json_no
));
1722 json_object_free(json_no
);
1725 "%% No such neighbor or address family\n");
1729 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1732 json_object
*json_no
= NULL
;
1733 json_no
= json_object_new_object();
1734 json_object_string_add(
1736 "Malformed Route Distinguisher");
1737 vty_out(vty
, "%s\n",
1738 json_object_to_json_string(json_no
));
1739 json_object_free(json_no
);
1742 "%% Malformed Route Distinguisher\n");
1746 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
1751 #endif /* KEEP_OLD_VPN_COMMANDS */
1753 void bgp_mplsvpn_init(void)
1755 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
1756 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
1757 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
1759 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
1760 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
1762 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
1763 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
1764 #ifdef KEEP_OLD_VPN_COMMANDS
1765 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
1766 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
1767 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
1768 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
1769 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
1770 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
1771 install_element(VIEW_NODE
,
1772 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
1773 install_element(VIEW_NODE
,
1774 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
1775 #endif /* KEEP_OLD_VPN_COMMANDS */