2 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "bgpd/bgpd.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_table.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_attr.h"
40 #include "bgpd/bgp_label.h"
41 #include "bgpd/bgp_mplsvpn.h"
42 #include "bgpd/bgp_packet.h"
43 #include "bgpd/bgp_vty.h"
44 #include "bgpd/bgp_vpn.h"
45 #include "bgpd/bgp_ecommunity.h"
46 #include "bgpd/bgp_zebra.h"
47 #include "bgpd/bgp_nexthop.h"
48 #include "bgpd/bgp_nht.h"
49 #include "bgpd/bgp_evpn.h"
50 #include "bgpd/bgp_memory.h"
53 #include "bgpd/rfapi/rfapi_backend.h"
57 * Definitions and external declarations.
59 extern struct zclient
*zclient
;
61 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
62 int *index
, afi_t
*afi
)
65 if (argv_find(argv
, argc
, "vpnv4", index
)) {
69 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
77 uint32_t decode_label(mpls_label_t
*label_pnt
)
80 uint8_t *pnt
= (uint8_t *)label_pnt
;
82 l
= ((uint32_t)*pnt
++ << 12);
83 l
|= (uint32_t)*pnt
++ << 4;
84 l
|= (uint32_t)((*pnt
& 0xf0) >> 4);
88 void encode_label(mpls_label_t label
, mpls_label_t
*label_pnt
)
90 uint8_t *pnt
= (uint8_t *)label_pnt
;
93 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
) {
97 *pnt
++ = (label
>> 12) & 0xff;
98 *pnt
++ = (label
>> 4) & 0xff;
99 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
102 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
103 struct bgp_nlri
*packet
)
111 struct prefix_rd prd
= {0};
112 mpls_label_t label
= {0};
120 prd
.family
= AF_UNSPEC
;
123 struct stream
*data
= stream_new(packet
->length
);
124 stream_put(data
, packet
->nlri
, packet
->length
);
130 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
131 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
132 PEER_CAP_ADDPATH_AF_TX_RCV
));
134 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
135 while (STREAM_READABLE(data
) > 0) {
136 /* Clear prefix structure. */
137 memset(&p
, 0, sizeof(struct prefix
));
139 if (addpath_encoded
) {
140 STREAM_GET(&addpath_id
, data
, BGP_ADDPATH_ID_LEN
);
141 addpath_id
= ntohl(addpath_id
);
144 if (STREAM_READABLE(data
) < 1) {
147 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no prefix length)",
148 peer
->host
, packet
->length
);
149 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
153 /* Fetch prefix length. */
154 STREAM_GETC(data
, prefixlen
);
155 p
.family
= afi2family(packet
->afi
);
156 psize
= PSIZE(prefixlen
);
158 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
161 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
162 peer
->host
, prefixlen
);
163 ret
= BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH
;
167 /* sanity check against packet data */
168 if (STREAM_READABLE(data
) < psize
) {
171 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
172 peer
->host
, prefixlen
, packet
->length
);
173 ret
= BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
177 /* sanity check against storage for the IP address portion */
178 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
181 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
183 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
185 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
189 /* Sanity check against max bitlen of the address family */
190 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
193 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
195 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
196 p
.family
, prefix_blen(&p
));
197 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
201 /* Copy label to prefix. */
202 if (STREAM_READABLE(data
) < BGP_LABEL_BYTES
) {
205 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no label)",
206 peer
->host
, packet
->length
);
207 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
211 STREAM_GET(&label
, data
, BGP_LABEL_BYTES
);
212 bgp_set_valid_label(&label
);
214 /* Copy routing distinguisher to rd. */
215 if (STREAM_READABLE(data
) < 8) {
218 "%s [Error] Update packet error / VPN (truncated NLRI of size %u; no RD)",
219 peer
->host
, packet
->length
);
220 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
223 STREAM_GET(&prd
.val
, data
, 8);
225 /* Decode RD type. */
226 type
= decode_rd_type(prd
.val
);
230 decode_rd_as(&prd
.val
[2], &rd_as
);
234 decode_rd_as4(&prd
.val
[2], &rd_as
);
238 decode_rd_ip(&prd
.val
[2], &rd_ip
);
241 #ifdef ENABLE_BGP_VNC
242 case RD_TYPE_VNC_ETH
:
247 flog_err(EC_BGP_UPDATE_RCV
, "Unknown RD type %d", type
);
248 break; /* just report */
251 /* exclude label & RD */
252 p
.prefixlen
= prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8;
253 STREAM_GET(p
.u
.val
, data
, psize
- VPN_PREFIXLEN_MIN_BYTES
);
256 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
257 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
258 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, 0, NULL
);
260 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
261 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
262 BGP_ROUTE_NORMAL
, &prd
, &label
, 1, NULL
);
265 /* Packet length consistency check. */
266 if (STREAM_READABLE(data
) != 0) {
269 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
270 peer
->host
, STREAM_READABLE(data
));
271 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
279 "%s [Error] Update packet error / VPN (NLRI of size %u - length error)",
280 peer
->host
, packet
->length
);
281 ret
= BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
287 #undef VPN_PREFIXLEN_MIN_BYTES
291 * This function informs zebra of the label this vrf sets on routes
292 * leaked to VPN. Zebra should install this label in the kernel with
293 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
295 * Sending this vrf-label association is qualified by a) whether vrf->vpn
296 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
297 * are set) and b) whether vpn-policy label is set.
299 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
300 * for this vrf, which zebra interprets to mean "delete this vrf-label
303 void vpn_leak_zebra_vrf_label_update(struct bgp
*bgp
, afi_t afi
)
305 mpls_label_t label
= MPLS_LABEL_NONE
;
306 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
308 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
311 "%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
312 __func__
, bgp
->name_pretty
, afi2str(afi
));
317 if (vpn_leak_to_vpn_active(bgp
, afi
, NULL
)) {
318 label
= bgp
->vpn_policy
[afi
].tovpn_label
;
322 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
323 __func__
, bgp
->name_pretty
, afi2str(afi
), label
,
327 if (label
== BGP_PREVENT_VRF_2_VRF_LEAK
)
328 label
= MPLS_LABEL_NONE
;
329 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
330 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
334 * If zebra tells us vrf has become unconfigured, tell zebra not to
335 * use this label to forward to the vrf anymore
337 void vpn_leak_zebra_vrf_label_withdraw(struct bgp
*bgp
, afi_t afi
)
339 mpls_label_t label
= MPLS_LABEL_NONE
;
340 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
342 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
345 "%s: vrf_id not set, can't delete zebra vrf label",
352 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__
,
353 bgp
->name_pretty
, bgp
->vrf_id
);
356 zclient_send_vrf_label(zclient
, bgp
->vrf_id
, afi
, label
, ZEBRA_LSP_BGP
);
357 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
= label
;
361 * This function informs zebra of the srv6-function this vrf sets on routes
362 * leaked to VPN. Zebra should install this srv6-function in the kernel with
363 * an action of "End.DT4/6's IP FIB to route the PDU."
365 void vpn_leak_zebra_vrf_sid_update(struct bgp
*bgp
, afi_t afi
)
367 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
368 enum seg6local_action_t act
;
369 struct seg6local_context ctx
= {};
370 struct in6_addr
*tovpn_sid
= NULL
;
371 struct in6_addr
*tovpn_sid_ls
= NULL
;
375 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
377 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
378 __func__
, bgp
->name_pretty
, afi2str(afi
));
382 tovpn_sid
= bgp
->vpn_policy
[afi
].tovpn_sid
;
385 zlog_debug("%s: vrf %s: afi %s: sid not set", __func__
,
386 bgp
->name_pretty
, afi2str(afi
));
391 inet_ntop(AF_INET6
, tovpn_sid
, buf
, sizeof(buf
));
392 zlog_debug("%s: vrf %s: afi %s: setting sid %s for vrf id %d",
393 __func__
, bgp
->name_pretty
, afi2str(afi
), buf
,
397 vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
401 ctx
.table
= vrf
->data
.l
.table_id
;
402 act
= afi
== AFI_IP
? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
403 : ZEBRA_SEG6_LOCAL_ACTION_END_DT6
;
404 zclient_send_localsid(zclient
, tovpn_sid
, bgp
->vrf_id
, act
, &ctx
);
406 tovpn_sid_ls
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
407 *tovpn_sid_ls
= *tovpn_sid
;
408 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
= tovpn_sid_ls
;
412 * If zebra tells us vrf has become unconfigured, tell zebra not to
413 * use this srv6-function to forward to the vrf anymore
415 void vpn_leak_zebra_vrf_sid_withdraw(struct bgp
*bgp
, afi_t afi
)
417 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
419 if (bgp
->vrf_id
== VRF_UNKNOWN
) {
421 zlog_debug("%s: vrf %s: afi %s: vrf_id not set, can't set zebra vrf label",
422 __func__
, bgp
->name_pretty
, afi2str(afi
));
427 zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__
,
428 bgp
->name_pretty
, bgp
->vrf_id
);
430 zclient_send_localsid(zclient
,
431 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
,
432 bgp
->vrf_id
, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
, NULL
);
433 XFREE(MTYPE_BGP_SRV6_SID
,
434 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_sid_last_sent
);
437 int vpn_leak_label_callback(
442 struct vpn_policy
*vp
= (struct vpn_policy
*)labelid
;
443 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_LABEL
);
446 zlog_debug("%s: label=%u, allocated=%d",
447 __func__
, label
, allocated
);
451 * previously-allocated label is now invalid
453 if (CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
) &&
454 (vp
->tovpn_label
!= MPLS_LABEL_NONE
)) {
456 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
457 vp
->afi
, bgp_get_default(), vp
->bgp
);
458 vp
->tovpn_label
= MPLS_LABEL_NONE
;
459 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
460 vp
->afi
, bgp_get_default(), vp
->bgp
);
466 * New label allocation
468 if (!CHECK_FLAG(vp
->flags
, BGP_VPN_POLICY_TOVPN_LABEL_AUTO
)) {
471 * not currently configured for auto label, reject allocation
476 if (vp
->tovpn_label
!= MPLS_LABEL_NONE
) {
477 if (label
== vp
->tovpn_label
) {
478 /* already have same label, accept but do nothing */
481 /* Shouldn't happen: different label allocation */
482 flog_err(EC_BGP_LABEL
,
483 "%s: %s had label %u but got new assignment %u",
484 __func__
, vp
->bgp
->name_pretty
, vp
->tovpn_label
,
489 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
490 vp
->afi
, bgp_get_default(), vp
->bgp
);
491 vp
->tovpn_label
= label
;
492 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
493 vp
->afi
, bgp_get_default(), vp
->bgp
);
498 static void sid_register(struct bgp
*bgp
, const struct in6_addr
*sid
,
499 const char *locator_name
)
501 struct bgp_srv6_function
*func
;
502 func
= XCALLOC(MTYPE_BGP_SRV6_FUNCTION
,
503 sizeof(struct bgp_srv6_function
));
505 snprintf(func
->locator_name
, sizeof(func
->locator_name
),
507 listnode_add(bgp
->srv6_functions
, func
);
510 static bool sid_exist(struct bgp
*bgp
, const struct in6_addr
*sid
)
512 struct listnode
*node
;
513 struct bgp_srv6_function
*func
;
515 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_functions
, node
, func
))
516 if (sid_same(&func
->sid
, sid
))
522 * if index != 0: try to allocate as index-mode
523 * else: try to allocate as auto-mode
525 static bool alloc_new_sid(struct bgp
*bgp
, uint32_t index
,
526 struct in6_addr
*sid
)
528 struct listnode
*node
;
529 struct prefix_ipv6
*chunk
;
530 struct in6_addr sid_buf
;
531 bool alloced
= false;
536 for (ALL_LIST_ELEMENTS_RO(bgp
->srv6_locator_chunks
, node
, chunk
)) {
537 sid_buf
= chunk
->prefix
;
539 sid_buf
.s6_addr
[15] = index
;
540 if (sid_exist(bgp
, &sid_buf
))
546 for (size_t i
= 1; i
< 255; i
++) {
547 sid_buf
.s6_addr
[15] = (i
& 0xff00) >> 8;
548 sid_buf
.s6_addr
[14] = (i
& 0x00ff);
550 if (sid_exist(bgp
, &sid_buf
))
560 sid_register(bgp
, &sid_buf
, bgp
->srv6_locator_name
);
565 void ensure_vrf_tovpn_sid(struct bgp
*bgp_vpn
, struct bgp
*bgp_vrf
, afi_t afi
)
567 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
568 bool alloced
= false;
570 struct in6_addr
*sid
;
571 uint32_t tovpn_sid_index
= 0;
572 bool tovpn_sid_auto
= false;
575 zlog_debug("%s: try to allocate new SID for vrf %s: afi %s",
576 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
578 /* skip when tovpn sid is already allocated on vrf instance */
579 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
)
583 * skip when bgp vpn instance ins't allocated
584 * or srv6 locator chunk isn't allocated
586 if (!bgp_vpn
|| !bgp_vpn
->srv6_locator_chunks
)
589 tovpn_sid_index
= bgp_vrf
->vpn_policy
[afi
].tovpn_sid_index
;
590 tovpn_sid_auto
= CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
591 BGP_VPN_POLICY_TOVPN_SID_AUTO
);
593 /* skip when VPN isn't configured on vrf-instance */
594 if (tovpn_sid_index
== 0 && !tovpn_sid_auto
)
597 /* check invalid case both configured index and auto */
598 if (tovpn_sid_index
!= 0 && tovpn_sid_auto
) {
599 zlog_err("%s: index-mode and auto-mode both selected. ignored.",
604 sid
= XCALLOC(MTYPE_BGP_SRV6_SID
, sizeof(struct in6_addr
));
605 alloced
= alloc_new_sid(bgp_vpn
, tovpn_sid_index
, sid
);
607 zlog_debug("%s: not allocated new sid for vrf %s: afi %s",
608 __func__
, bgp_vrf
->name_pretty
, afi2str(afi
));
613 inet_ntop(AF_INET6
, sid
, buf
, sizeof(buf
));
614 zlog_debug("%s: new sid %s allocated for vrf %s: afi %s",
615 __func__
, buf
, bgp_vrf
->name_pretty
,
618 bgp_vrf
->vpn_policy
[afi
].tovpn_sid
= sid
;
621 static bool ecom_intersect(struct ecommunity
*e1
, struct ecommunity
*e2
)
627 for (i
= 0; i
< e1
->size
; ++i
) {
628 for (j
= 0; j
< e2
->size
; ++j
) {
629 if (!memcmp(e1
->val
+ (i
* e1
->unit_size
),
630 e2
->val
+ (j
* e2
->unit_size
),
640 static bool labels_same(struct bgp_path_info
*bpi
, mpls_label_t
*label
,
652 if (n
!= bpi
->extra
->num_labels
)
655 for (i
= 0; i
< n
; ++i
) {
656 if (label
[i
] != bpi
->extra
->label
[i
])
663 * make encoded route labels match specified encoded label set
665 static void setlabels(struct bgp_path_info
*bpi
,
666 mpls_label_t
*label
, /* array of labels */
671 assert(num_labels
<= BGP_MAX_LABELS
);
675 bpi
->extra
->num_labels
= 0;
679 struct bgp_path_info_extra
*extra
= bgp_path_info_extra_get(bpi
);
682 for (i
= 0; i
< num_labels
; ++i
) {
683 extra
->label
[i
] = label
[i
];
684 if (!bgp_is_valid_label(&label
[i
])) {
685 bgp_set_valid_label(&extra
->label
[i
]);
688 extra
->num_labels
= num_labels
;
692 * make encoded route SIDs match specified encoded sid set
694 static void setsids(struct bgp_path_info
*bpi
,
695 struct in6_addr
*sid
,
699 struct bgp_path_info_extra
*extra
;
703 assert(num_sids
<= BGP_MAX_SIDS
);
707 bpi
->extra
->num_sids
= 0;
711 extra
= bgp_path_info_extra_get(bpi
);
712 for (i
= 0; i
< num_sids
; i
++)
713 memcpy(&extra
->sid
[i
], &sid
[i
], sizeof(struct in6_addr
));
714 extra
->num_sids
= num_sids
;
717 static void unsetsids(struct bgp_path_info
*bpi
)
719 struct bgp_path_info_extra
*extra
;
721 extra
= bgp_path_info_extra_get(bpi
);
723 memset(extra
->sid
, 0, sizeof(extra
->sid
));
727 * returns pointer to new bgp_path_info upon success
729 static struct bgp_path_info
*
730 leak_update(struct bgp
*bgp
, /* destination bgp instance */
731 struct bgp_dest
*bn
, struct attr
*new_attr
, /* already interned */
732 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
733 mpls_label_t
*label
, uint32_t num_labels
, void *parent
,
734 struct bgp
*bgp_orig
, struct prefix
*nexthop_orig
,
735 int nexthop_self_flag
, int debug
)
737 const struct prefix
*p
= bgp_dest_get_prefix(bn
);
738 struct bgp_path_info
*bpi
;
739 struct bgp_path_info
*bpi_ultimate
;
740 struct bgp_path_info
*new;
741 uint32_t num_sids
= 0;
743 if (new_attr
->srv6_l3vpn
|| new_attr
->srv6_vpn
)
748 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
749 __func__
, bgp
->name_pretty
, bn
, source_bpi
->type
,
750 source_bpi
->sub_type
);
753 * Routes that are redistributed into BGP from zebra do not get
754 * nexthop tracking. However, if those routes are subsequently
755 * imported to other RIBs within BGP, the leaked routes do not
756 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
757 * in order to determine if the route we are currently leaking
758 * should have nexthop tracking, we must find the ultimate
759 * parent so we can check its sub_type.
761 * As of now, source_bpi may at most be a second-generation route
762 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
763 * Using a loop here supports more complex intra-bgp import-export
764 * schemes that could be implemented in the future.
767 for (bpi_ultimate
= source_bpi
;
768 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
769 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
775 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
776 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
781 bool labelssame
= labels_same(bpi
, label
, num_labels
);
783 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
784 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
787 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
788 __func__
, bgp
->name_pretty
,
789 source_bpi
->flags
, bpi
->flags
, p
);
794 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
795 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
797 bgp_attr_unintern(&new_attr
);
800 "%s: ->%s: %pBD: Found route, no change",
801 __func__
, bgp
->name_pretty
, bn
);
805 /* attr is changed */
806 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
808 /* Rewrite BGP route information. */
809 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
810 bgp_path_info_restore(bn
, bpi
);
812 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
813 bgp_attr_unintern(&bpi
->attr
);
814 bpi
->attr
= new_attr
;
815 bpi
->uptime
= bgp_clock();
821 setlabels(bpi
, label
, num_labels
);
827 if (new_attr
->srv6_l3vpn
)
828 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
830 else if (new_attr
->srv6_vpn
)
831 setsids(bpi
, &new_attr
->srv6_vpn
->sid
,
836 if (nexthop_self_flag
)
837 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
839 struct bgp
*bgp_nexthop
= bgp
;
842 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
843 bgp_nexthop
= bpi
->extra
->bgp_orig
;
846 * No nexthop tracking for redistributed routes or for
847 * EVPN-imported routes that get leaked.
849 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
850 is_pi_family_evpn(bpi_ultimate
))
854 * TBD do we need to do anything about the
855 * 'connected' parameter?
857 nh_valid
= bgp_find_or_add_nexthop(
858 bgp
, bgp_nexthop
, afi
, safi
, bpi
, NULL
, 0, p
);
861 * If you are using SRv6 VPN instead of MPLS, it need to check
862 * the SID allocation. If the sid is not allocated, the rib
865 if (bgp
->srv6_enabled
866 && (!new_attr
->srv6_l3vpn
&& !new_attr
->srv6_vpn
)) {
867 bgp_path_info_unset_flag(bn
, bpi
, BGP_PATH_VALID
);
872 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
873 __func__
, (nh_valid
? "" : "not "),
874 bgp_nexthop
->name_pretty
);
877 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
879 /* Process change. */
880 bgp_aggregate_increment(bgp
, p
, bpi
, afi
, safi
);
881 bgp_process(bgp
, bn
, afi
, safi
);
882 bgp_dest_unlock_node(bn
);
885 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
886 __func__
, bgp
->name_pretty
, bn
);
891 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
894 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
895 __func__
, bgp
->name_pretty
,
896 source_bpi
->flags
, p
);
901 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
902 bgp
->peer_self
, new_attr
, bn
);
904 if (nexthop_self_flag
)
905 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
907 bgp_path_info_extra_get(new);
913 if (new_attr
->srv6_l3vpn
)
914 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
915 else if (new_attr
->srv6_vpn
)
916 setsids(new, &new_attr
->srv6_vpn
->sid
, num_sids
);
921 setlabels(new, label
, num_labels
);
923 new->extra
->parent
= bgp_path_info_lock(parent
);
925 (struct bgp_dest
*)((struct bgp_path_info
*)parent
)->net
);
927 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
929 new->extra
->nexthop_orig
= *nexthop_orig
;
932 * nexthop tracking for unicast routes
934 struct bgp
*bgp_nexthop
= bgp
;
937 if (new->extra
->bgp_orig
)
938 bgp_nexthop
= new->extra
->bgp_orig
;
941 * No nexthop tracking for redistributed routes because
942 * their originating protocols will do the tracking and
943 * withdraw those routes if the nexthops become unreachable
944 * This also holds good for EVPN-imported routes that get
947 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
948 is_pi_family_evpn(bpi_ultimate
))
952 * TBD do we need to do anything about the
953 * 'connected' parameter?
955 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
, afi
, safi
,
959 * If you are using SRv6 VPN instead of MPLS, it need to check
960 * the SID allocation. If the sid is not allocated, the rib
963 if (bgp
->srv6_enabled
964 && (!new->attr
->srv6_l3vpn
&& !new->attr
->srv6_vpn
)) {
965 bgp_path_info_unset_flag(bn
, new, BGP_PATH_VALID
);
970 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
971 __func__
, (nh_valid
? "" : "not "),
972 bgp_nexthop
->name_pretty
);
974 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
976 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
977 bgp_path_info_add(bn
, new);
979 bgp_dest_unlock_node(bn
);
980 bgp_process(bgp
, bn
, afi
, safi
);
983 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
984 bgp
->name_pretty
, bn
);
989 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
990 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
991 struct bgp
*bgp_vrf
, /* from */
992 struct bgp_path_info
*path_vrf
) /* route */
994 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
995 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
996 afi_t afi
= family2afi(p
->family
);
997 struct attr static_attr
= {0};
998 struct attr
*new_attr
= NULL
;
999 safi_t safi
= SAFI_MPLS_VPN
;
1000 mpls_label_t label_val
;
1002 struct bgp_dest
*bn
;
1003 const char *debugmsg
;
1004 int nexthop_self_flag
= 0;
1007 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
1009 if (debug
&& path_vrf
->attr
->ecommunity
) {
1010 char *s
= ecommunity_ecom2str(path_vrf
->attr
->ecommunity
,
1011 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1013 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
1014 bgp_vrf
->name
, path_vrf
->type
, s
);
1015 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1023 zlog_debug("%s: can't get afi of prefix", __func__
);
1027 /* Is this route exportable into the VPN table? */
1028 if (!is_route_injectable_into_vpn(path_vrf
))
1031 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1033 zlog_debug("%s: %s skipping: %s", __func__
,
1034 bgp_vrf
->name
, debugmsg
);
1039 static_attr
= *path_vrf
->attr
;
1042 * route map handling
1044 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1045 struct bgp_path_info info
;
1046 route_map_result_t ret
;
1048 memset(&info
, 0, sizeof(info
));
1049 info
.peer
= bgp_vpn
->peer_self
;
1050 info
.attr
= &static_attr
;
1051 ret
= route_map_apply(
1052 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1054 if (RMAP_DENYMATCH
== ret
) {
1055 bgp_attr_flush(&static_attr
); /* free any added parts */
1058 "%s: vrf %s route map \"%s\" says DENY, returning",
1059 __func__
, bgp_vrf
->name_pretty
,
1060 bgp_vrf
->vpn_policy
[afi
]
1061 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
1067 if (debug
&& static_attr
.ecommunity
) {
1068 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
1069 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1071 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1073 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1077 * Add the vpn-policy rt-list
1079 struct ecommunity
*old_ecom
;
1080 struct ecommunity
*new_ecom
;
1082 /* Export with the 'from' instance's export RTs. */
1083 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1084 old_ecom
= static_attr
.ecommunity
;
1086 new_ecom
= ecommunity_dup(old_ecom
);
1087 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
1088 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1089 ecommunity_strip_rts(new_ecom
);
1090 new_ecom
= ecommunity_merge(new_ecom
,
1091 bgp_vrf
->vpn_policy
[afi
]
1092 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1093 if (!old_ecom
->refcnt
)
1094 ecommunity_free(&old_ecom
);
1096 new_ecom
= ecommunity_dup(
1097 bgp_vrf
->vpn_policy
[afi
]
1098 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1100 static_attr
.ecommunity
= new_ecom
;
1101 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
1103 if (debug
&& static_attr
.ecommunity
) {
1104 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
1105 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1107 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1109 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1113 /* if policy nexthop not set, use 0 */
1114 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
1115 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1116 struct prefix
*nexthop
=
1117 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
1119 switch (nexthop
->family
) {
1121 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1123 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1125 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1126 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1130 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1131 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1138 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
1139 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1140 if (afi
== AFI_IP
) {
1142 * For ipv4, copy to multiprotocol
1145 static_attr
.mp_nexthop_global_in
=
1146 static_attr
.nexthop
;
1147 static_attr
.mp_nexthop_len
=
1148 BGP_ATTR_NHLEN_IPV4
;
1150 * XXX Leave static_attr.nexthop
1154 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1157 /* Update based on next-hop family to account for
1158 * RFC 5549 (BGP unnumbered) scenario. Note that
1159 * specific action is only needed for the case of
1160 * IPv4 nexthops as the attr has been copied
1164 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1165 static_attr
.mp_nexthop_global_in
.s_addr
=
1166 static_attr
.nexthop
.s_addr
;
1167 static_attr
.mp_nexthop_len
=
1168 BGP_ATTR_NHLEN_IPV4
;
1170 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1173 nexthop_self_flag
= 1;
1176 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
1177 if (label_val
== MPLS_LABEL_NONE
) {
1178 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1180 encode_label(label_val
, &label
);
1183 /* Set originator ID to "me" */
1184 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1185 static_attr
.originator_id
= bgp_vpn
->router_id
;
1187 /* Set SID for SRv6 VPN */
1188 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
) {
1189 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1190 sizeof(struct bgp_attr_srv6_l3vpn
));
1191 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1192 static_attr
.srv6_l3vpn
->endpoint_behavior
= 0xffff;
1193 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1194 bgp_vrf
->vpn_policy
[afi
].tovpn_sid
,
1195 sizeof(static_attr
.srv6_l3vpn
->sid
));
1199 new_attr
= bgp_attr_intern(
1200 &static_attr
); /* hashed refcounted everything */
1201 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1203 if (debug
&& new_attr
->ecommunity
) {
1204 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
1205 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1207 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1208 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1211 /* Now new_attr is an allocated interned attr */
1213 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
1214 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
1216 struct bgp_path_info
*new_info
;
1218 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, path_vrf
,
1219 &label
, 1, path_vrf
, bgp_vrf
, NULL
,
1220 nexthop_self_flag
, debug
);
1223 * Routes actually installed in the vpn RIB must also be
1224 * offered to all vrfs (because now they originate from
1227 * Acceptance into other vrfs depends on rt-lists.
1228 * Originating vrf will not accept the looped back route
1229 * because of loop checking.
1232 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
1235 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
1236 struct bgp
*bgp_vrf
, /* from */
1237 struct bgp_path_info
*path_vrf
) /* route */
1239 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1240 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1241 afi_t afi
= family2afi(p
->family
);
1242 safi_t safi
= SAFI_MPLS_VPN
;
1243 struct bgp_path_info
*bpi
;
1244 struct bgp_dest
*bn
;
1245 const char *debugmsg
;
1249 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1250 __func__
, bgp_vrf
->name_pretty
, path_vrf
->net
,
1251 path_vrf
->type
, path_vrf
->sub_type
);
1259 zlog_debug("%s: can't get afi of prefix", __func__
);
1263 /* Is this route exportable into the VPN table? */
1264 if (!is_route_injectable_into_vpn(path_vrf
))
1267 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1269 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1274 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1276 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
1277 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
1283 * match original bpi imported from
1285 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1286 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1292 /* withdraw from looped vrfs as well */
1293 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
1295 bgp_aggregate_decrement(bgp_vpn
, p
, bpi
, afi
, safi
);
1296 bgp_path_info_delete(bn
, bpi
);
1297 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1299 bgp_dest_unlock_node(bn
);
1302 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
1303 struct bgp
*bgp_vrf
, /* from */
1306 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1307 struct bgp_dest
*pdest
;
1308 safi_t safi
= SAFI_MPLS_VPN
;
1311 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
1313 for (pdest
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); pdest
;
1314 pdest
= bgp_route_next(pdest
)) {
1316 struct bgp_table
*table
;
1317 struct bgp_dest
*bn
;
1318 struct bgp_path_info
*bpi
;
1320 /* This is the per-RD table of prefixes */
1321 table
= bgp_dest_get_bgp_table_info(pdest
);
1326 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1327 bpi
= bgp_dest_get_bgp_path_info(bn
);
1329 zlog_debug("%s: looking at prefix %pBD",
1333 for (; bpi
; bpi
= bpi
->next
) {
1335 zlog_debug("%s: type %d, sub_type %d",
1336 __func__
, bpi
->type
,
1338 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1342 if ((struct bgp
*)bpi
->extra
->bgp_orig
1346 zlog_debug("%s: deleting it",
1348 /* withdraw from leak-to vrfs as well */
1349 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
1350 bgp_aggregate_decrement(
1352 bgp_dest_get_prefix(bn
), bpi
,
1354 bgp_path_info_delete(bn
, bpi
);
1355 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1362 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
1363 struct bgp
*bgp_vrf
, /* from */
1366 struct bgp_dest
*bn
;
1367 struct bgp_path_info
*bpi
;
1368 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1371 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1372 bgp_vrf
->name_pretty
);
1374 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
1375 bn
= bgp_route_next(bn
)) {
1378 zlog_debug("%s: node=%p", __func__
, bn
);
1380 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1384 "%s: calling vpn_leak_from_vrf_update",
1386 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bpi
);
1392 vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1393 struct bgp
*bgp_vpn
, /* from */
1394 struct bgp_path_info
*path_vpn
) /* route */
1396 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1397 afi_t afi
= family2afi(p
->family
);
1399 struct attr static_attr
= {0};
1400 struct attr
*new_attr
= NULL
;
1401 struct bgp_dest
*bn
;
1402 safi_t safi
= SAFI_UNICAST
;
1403 const char *debugmsg
;
1404 struct prefix nexthop_orig
;
1405 mpls_label_t
*pLabels
= NULL
;
1406 uint32_t num_labels
= 0;
1407 int nexthop_self_flag
= 1;
1408 struct bgp_path_info
*bpi_ultimate
= NULL
;
1409 int origin_local
= 0;
1410 struct bgp
*src_vrf
;
1412 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1414 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1416 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1420 /* Check for intersection of route targets */
1421 if (!ecom_intersect(
1422 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1423 path_vpn
->attr
->ecommunity
)) {
1426 "from vpn to vrf %s, skipping after no intersection of route targets",
1427 bgp_vrf
->name_pretty
);
1432 zlog_debug("%s: updating %pFX to vrf %s", __func__
, p
,
1433 bgp_vrf
->name_pretty
);
1436 static_attr
= *path_vpn
->attr
;
1438 struct ecommunity
*old_ecom
;
1439 struct ecommunity
*new_ecom
;
1441 /* If doing VRF-to-VRF leaking, strip RTs. */
1442 old_ecom
= static_attr
.ecommunity
;
1443 if (old_ecom
&& CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1444 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1445 new_ecom
= ecommunity_dup(old_ecom
);
1446 ecommunity_strip_rts(new_ecom
);
1447 static_attr
.ecommunity
= new_ecom
;
1449 if (new_ecom
->size
== 0) {
1450 UNSET_FLAG(static_attr
.flag
,
1451 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
1452 ecommunity_free(&new_ecom
);
1453 static_attr
.ecommunity
= NULL
;
1456 if (!old_ecom
->refcnt
)
1457 ecommunity_free(&old_ecom
);
1461 * Nexthop: stash and clear
1463 * Nexthop is valid in context of VPN core, but not in destination vrf.
1464 * Stash it for later label resolution by vrf ingress path and then
1465 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1467 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1469 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1470 nexthop_orig
.family
= nhfamily
;
1475 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1476 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
1478 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1479 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1480 static_attr
.nexthop
.s_addr
=
1481 nexthop_orig
.u
.prefix4
.s_addr
;
1483 static_attr
.mp_nexthop_global_in
=
1484 path_vpn
->attr
->mp_nexthop_global_in
;
1485 static_attr
.mp_nexthop_len
=
1486 path_vpn
->attr
->mp_nexthop_len
;
1488 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1492 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1493 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
1495 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1496 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1497 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1503 * route map handling
1505 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1506 struct bgp_path_info info
;
1507 route_map_result_t ret
;
1509 memset(&info
, 0, sizeof(info
));
1510 info
.peer
= bgp_vrf
->peer_self
;
1511 info
.attr
= &static_attr
;
1512 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1513 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1514 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1516 if (RMAP_DENYMATCH
== ret
) {
1517 bgp_attr_flush(&static_attr
); /* free any added parts */
1520 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1521 __func__
, bgp_vrf
->name_pretty
,
1522 bgp_vrf
->vpn_policy
[afi
]
1523 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1528 * if route-map changed nexthop, don't nexthop-self on output
1530 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1531 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1532 nexthop_self_flag
= 0;
1535 new_attr
= bgp_attr_intern(&static_attr
);
1536 bgp_attr_flush(&static_attr
);
1538 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1541 * ensure labels are copied
1543 * However, there is a special case: if the route originated in
1544 * another local VRF (as opposed to arriving via VPN), then the
1545 * nexthop is reached by hairpinning through this router (me)
1546 * using IP forwarding only (no LSP). Therefore, the route
1547 * imported to the VRF should not have labels attached. Note
1548 * that nexthop tracking is also involved: eliminating the
1549 * labels for these routes enables the non-labeled nexthops
1550 * from the originating VRF to be considered valid for this route.
1552 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1553 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1554 /* work back to original route */
1555 for (bpi_ultimate
= path_vpn
;
1556 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
1557 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
1561 * if original route was unicast,
1562 * then it did not arrive over vpn
1564 if (bpi_ultimate
->net
) {
1565 struct bgp_table
*table
;
1567 table
= bgp_dest_table(bpi_ultimate
->net
);
1568 if (table
&& (table
->safi
== SAFI_UNICAST
))
1573 if (!origin_local
&& path_vpn
->extra
1574 && path_vpn
->extra
->num_labels
) {
1575 num_labels
= path_vpn
->extra
->num_labels
;
1576 if (num_labels
> BGP_MAX_LABELS
)
1577 num_labels
= BGP_MAX_LABELS
;
1578 pLabels
= path_vpn
->extra
->label
;
1583 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
1584 path_vpn
->net
, num_labels
);
1587 * For VRF-2-VRF route-leaking,
1588 * the source will be the originating VRF.
1590 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1591 src_vrf
= path_vpn
->extra
->bgp_orig
;
1595 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
1596 num_labels
, path_vpn
, /* parent */
1597 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1600 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1601 struct bgp_path_info
*path_vpn
) /* route */
1603 struct listnode
*mnode
, *mnnode
;
1606 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1609 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1611 /* Loop over VRFs */
1612 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1614 if (!path_vpn
->extra
1615 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1616 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, path_vpn
);
1621 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1622 struct bgp_path_info
*path_vpn
) /* route */
1624 const struct prefix
*p
;
1626 safi_t safi
= SAFI_UNICAST
;
1628 struct listnode
*mnode
, *mnnode
;
1629 struct bgp_dest
*bn
;
1630 struct bgp_path_info
*bpi
;
1631 const char *debugmsg
;
1633 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1636 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
1637 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
1640 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1642 if (!path_vpn
->net
) {
1643 #ifdef ENABLE_BGP_VNC
1644 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1645 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
1646 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1653 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1658 p
= bgp_dest_get_prefix(path_vpn
->net
);
1659 afi
= family2afi(p
->family
);
1661 /* Loop over VRFs */
1662 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1663 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1665 zlog_debug("%s: skipping: %s", __func__
,
1670 /* Check for intersection of route targets */
1671 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1672 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1673 path_vpn
->attr
->ecommunity
)) {
1679 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1682 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1684 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1687 && (struct bgp_path_info
*)bpi
->extra
->parent
1695 zlog_debug("%s: deleting bpi %p", __func__
,
1697 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
1698 bgp_path_info_delete(bn
, bpi
);
1699 bgp_process(bgp
, bn
, afi
, safi
);
1701 bgp_dest_unlock_node(bn
);
1705 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1708 struct bgp_dest
*bn
;
1709 struct bgp_path_info
*bpi
;
1710 safi_t safi
= SAFI_UNICAST
;
1711 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1714 zlog_debug("%s: entry", __func__
);
1716 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1718 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1719 bn
= bgp_route_next(bn
)) {
1721 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1724 && bpi
->extra
->bgp_orig
!= bgp_vrf
1725 && bpi
->extra
->parent
1726 && is_pi_family_vpn(bpi
->extra
->parent
)) {
1729 bgp_aggregate_decrement(bgp_vrf
,
1730 bgp_dest_get_prefix(bn
),
1732 bgp_path_info_delete(bn
, bpi
);
1733 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1739 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1740 struct bgp
*bgp_vpn
, /* from */
1743 struct bgp_dest
*pdest
;
1744 safi_t safi
= SAFI_MPLS_VPN
;
1751 for (pdest
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); pdest
;
1752 pdest
= bgp_route_next(pdest
)) {
1753 struct bgp_table
*table
;
1754 struct bgp_dest
*bn
;
1755 struct bgp_path_info
*bpi
;
1757 /* This is the per-RD table of prefixes */
1758 table
= bgp_dest_get_bgp_table_info(pdest
);
1763 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1765 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1769 && bpi
->extra
->bgp_orig
== bgp_vrf
)
1772 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1780 * This function is called for definition/deletion/change to a route-map
1782 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1784 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1786 struct route_map
*rmap
;
1788 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1789 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1794 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1796 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1798 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1799 && !strcmp(rmap_name
,
1800 bgp
->vpn_policy
[afi
]
1801 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1805 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1806 __func__
, rmap_name
, bgp
->as
,
1809 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1810 bgp_get_default(), bgp
);
1812 zlog_debug("%s: after vpn_leak_prechange",
1815 /* in case of definition/deletion */
1816 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1819 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1820 bgp_get_default(), bgp
);
1823 zlog_debug("%s: after vpn_leak_postchange",
1827 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1828 && !strcmp(rmap_name
,
1829 bgp
->vpn_policy
[afi
]
1830 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1833 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1834 __func__
, rmap_name
, bgp
->as
,
1838 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1839 bgp_get_default(), bgp
);
1841 /* in case of definition/deletion */
1842 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1845 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1846 bgp_get_default(), bgp
);
1851 /* This API is used during router-id change, reflect VPNs
1852 * auto RD and RT values and readvertise routes to VPN table.
1854 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
1858 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
1859 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1861 const char *export_name
;
1862 char buf
[RD_ADDRSTRLEN
];
1863 struct bgp
*bgp_import
;
1864 struct listnode
*node
;
1865 struct ecommunity
*ecom
;
1866 vpn_policy_direction_t idir
, edir
;
1869 * Router-id change that is not explicitly configured
1870 * (a change from zebra, frr restart for example)
1871 * should not replace a configured vpn RD/RT.
1875 zlog_debug("%s: skipping non explicit router-id change",
1880 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1881 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1884 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1885 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1886 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1888 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1889 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
1893 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
1894 afi
, bgp_get_default(), bgp
);
1896 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1897 __func__
, export_name
);
1899 /* Remove import RT from VRFs */
1900 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1901 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1902 export_vrf
, node
, vname
)) {
1903 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1904 bgp_import
= bgp_get_default();
1906 bgp_import
= bgp_lookup_by_name(vname
);
1911 bgp_import
->vpn_policy
[afi
]
1913 (struct ecommunity_val
*)ecom
->val
);
1916 /* New router-id derive auto RD and RT and export
1919 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
1920 &bgp
->vrf_prd_auto
);
1921 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
1922 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
1924 bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1925 ecommunity_str2com(buf
,
1926 ECOMMUNITY_ROUTE_TARGET
, 0);
1928 /* Update import_vrf rt_list */
1929 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1930 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1931 export_vrf
, node
, vname
)) {
1932 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1933 bgp_import
= bgp_get_default();
1935 bgp_import
= bgp_lookup_by_name(vname
);
1938 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
1939 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1941 bgp_import
->vpn_policy
[afi
]
1942 .rtlist
[idir
], ecom
);
1944 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1945 = ecommunity_dup(ecom
);
1948 /* Update routes to VPN */
1949 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
1950 afi
, bgp_get_default(),
1953 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
1954 __func__
, export_name
);
1959 void vpn_policy_routemap_event(const char *rmap_name
)
1961 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1962 struct listnode
*mnode
, *mnnode
;
1966 zlog_debug("%s: entry", __func__
);
1968 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1971 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1972 vpn_policy_routemap_update(bgp
, rmap_name
);
1975 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1976 afi_t afi
, safi_t safi
)
1978 const char *export_name
;
1979 vpn_policy_direction_t idir
, edir
;
1980 char *vname
, *tmp_name
;
1981 char buf
[RD_ADDRSTRLEN
];
1982 struct ecommunity
*ecom
;
1983 bool first_export
= false;
1985 struct listnode
*node
;
1986 bool is_inst_match
= false;
1988 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
1989 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1990 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1992 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1993 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1996 * Cross-ref both VRFs. Also, note if this is the first time
1997 * any VRF is importing from "import_vrf".
1999 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
2000 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
2002 /* Check the import_vrf list of destination vrf for the source vrf name,
2005 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
2007 if (strcmp(vname
, tmp_name
) == 0) {
2008 is_inst_match
= true;
2013 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2016 XFREE(MTYPE_TMP
, vname
);
2018 /* Check if the source vrf already exports to any vrf,
2019 * first time export requires to setup auto derived RD/RT values.
2020 * Add the destination vrf name to export vrf list if it is
2023 is_inst_match
= false;
2024 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
2025 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2026 first_export
= true;
2028 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2030 if (strcmp(vname
, tmp_name
) == 0) {
2031 is_inst_match
= true;
2037 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2040 XFREE(MTYPE_TMP
, vname
);
2042 /* Update import RT for current VRF using export RT of the VRF we're
2043 * importing from. First though, make sure "import_vrf" has that
2047 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2048 &from_bgp
->vrf_prd_auto
);
2049 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2050 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2051 BGP_VPN_POLICY_TOVPN_RD_SET
);
2052 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
2054 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2055 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2056 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2057 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2058 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2059 BGP_PREVENT_VRF_2_VRF_LEAK
;
2061 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2062 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2063 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2064 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2065 .rtlist
[idir
], ecom
);
2067 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2068 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2071 const char *from_name
;
2072 char *ecom1
, *ecom2
;
2074 from_name
= from_bgp
->name
? from_bgp
->name
:
2077 ecom1
= ecommunity_ecom2str(
2078 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2079 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2081 ecom2
= ecommunity_ecom2str(
2082 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2083 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2086 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2087 __func__
, from_name
, export_name
, first_export
, ecom1
,
2090 ecommunity_strfree(&ecom1
);
2091 ecommunity_strfree(&ecom2
);
2094 /* Does "import_vrf" first need to export its routes or that
2095 * is already done and we just need to import those routes
2096 * from the global table?
2099 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2101 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2104 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2105 afi_t afi
, safi_t safi
)
2107 const char *export_name
, *tmp_name
;
2108 vpn_policy_direction_t idir
, edir
;
2110 struct ecommunity
*ecom
= NULL
;
2111 struct listnode
*node
;
2114 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2115 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2116 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2117 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2119 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2120 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2122 /* Were we importing from "import_vrf"? */
2123 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2125 if (strcmp(vname
, tmp_name
) == 0)
2130 * We do not check in the cli if the passed in bgp
2131 * instance is actually imported into us before
2132 * we call this function. As such if we do not
2133 * find this in the import_vrf list than
2134 * we just need to return safely.
2140 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2142 /* Remove "import_vrf" from our import list. */
2143 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2144 XFREE(MTYPE_TMP
, vname
);
2146 /* Remove routes imported from "import_vrf". */
2147 /* TODO: In the current logic, we have to first remove all
2148 * imported routes and then (if needed) import back routes
2150 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2152 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2153 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2154 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2155 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2156 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2157 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2159 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2161 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2162 (struct ecommunity_val
*)ecom
->val
);
2163 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2168 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2169 * below is checking for NULL that export_vrf can be
2170 * NULL, consequently it is complaining( like a cabbage )
2171 * that we could dereference and crash in the listcount(..)
2173 * So make it happy, under protest, with liberty and justice
2176 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2178 /* Remove us from "import_vrf's" export list. If no other VRF
2179 * is importing from "import_vrf", cleanup appropriately.
2181 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2183 if (strcmp(vname
, export_name
) == 0)
2188 * If we have gotten to this point then the vname must
2189 * exist. If not, we are in a world of trouble and
2190 * have slag sitting around.
2192 * import_vrf and export_vrf must match in having
2193 * the in/out names as appropriate.
2194 * export_vrf list could have been cleaned up
2195 * as part of no router bgp source instnace.
2200 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2201 XFREE(MTYPE_TMP
, vname
);
2203 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2204 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2205 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2206 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2207 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2208 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2209 sizeof(struct prefix_rd
));
2210 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2211 BGP_VPN_POLICY_TOVPN_RD_SET
);
2212 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2217 /* For testing purpose, static route of MPLS-VPN. */
2218 DEFUN (vpnv4_network
,
2220 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2221 "Specify a network to announce via BGP\n"
2223 "Specify Route Distinguisher\n"
2224 "VPN Route Distinguisher\n"
2225 "VPN NLRI label (tag)\n"
2226 "VPN NLRI label (tag)\n"
2229 int idx_ipv4_prefixlen
= 1;
2230 int idx_ext_community
= 3;
2232 return bgp_static_set_safi(
2233 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2234 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
2235 NULL
, NULL
, NULL
, NULL
);
2238 DEFUN (vpnv4_network_route_map
,
2239 vpnv4_network_route_map_cmd
,
2240 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
2241 "Specify a network to announce via BGP\n"
2243 "Specify Route Distinguisher\n"
2244 "VPN Route Distinguisher\n"
2245 "VPN NLRI label (tag)\n"
2246 "VPN NLRI label (tag)\n"
2251 int idx_ipv4_prefixlen
= 1;
2252 int idx_ext_community
= 3;
2255 return bgp_static_set_safi(
2256 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2257 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2258 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2261 /* For testing purpose, static route of MPLS-VPN. */
2262 DEFUN (no_vpnv4_network
,
2263 no_vpnv4_network_cmd
,
2264 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2266 "Specify a network to announce via BGP\n"
2268 "Specify Route Distinguisher\n"
2269 "VPN Route Distinguisher\n"
2270 "VPN NLRI label (tag)\n"
2271 "VPN NLRI label (tag)\n"
2274 int idx_ipv4_prefixlen
= 2;
2275 int idx_ext_community
= 4;
2277 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
2278 argv
[idx_ipv4_prefixlen
]->arg
,
2279 argv
[idx_ext_community
]->arg
,
2280 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2283 DEFUN (vpnv6_network
,
2285 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
2286 "Specify a network to announce via BGP\n"
2287 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2288 "Specify Route Distinguisher\n"
2289 "VPN Route Distinguisher\n"
2290 "VPN NLRI label (tag)\n"
2291 "VPN NLRI label (tag)\n"
2296 int idx_ipv6_prefix
= 1;
2297 int idx_ext_community
= 3;
2301 return bgp_static_set_safi(
2302 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2303 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2304 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2306 return bgp_static_set_safi(
2307 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2308 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2309 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2312 /* For testing purpose, static route of MPLS-VPN. */
2313 DEFUN (no_vpnv6_network
,
2314 no_vpnv6_network_cmd
,
2315 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2317 "Specify a network to announce via BGP\n"
2318 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2319 "Specify Route Distinguisher\n"
2320 "VPN Route Distinguisher\n"
2321 "VPN NLRI label (tag)\n"
2322 "VPN NLRI label (tag)\n"
2325 int idx_ipv6_prefix
= 2;
2326 int idx_ext_community
= 4;
2328 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2329 argv
[idx_ipv6_prefix
]->arg
,
2330 argv
[idx_ext_community
]->arg
,
2331 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2334 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2335 enum bgp_show_type type
, void *output_arg
, int tags
,
2339 struct bgp_table
*table
;
2341 bgp
= bgp_get_default();
2344 vty_out(vty
, "No BGP process is configured\n");
2346 vty_out(vty
, "{}\n");
2349 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2350 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2351 output_arg
, use_json
);
2354 DEFUN (show_bgp_ip_vpn_all_rd
,
2355 show_bgp_ip_vpn_all_rd_cmd
,
2356 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2360 "Display VPN NLRI specific information\n"
2361 "Display VPN NLRI specific information\n"
2362 "Display information for a route distinguisher\n"
2363 "VPN Route Distinguisher\n"
2364 "All VPN Route Distinguishers\n"
2368 struct prefix_rd prd
;
2372 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2373 /* Constrain search if user supplies RD && RD != "all" */
2374 if (argv_find(argv
, argc
, "rd", &idx
)
2375 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
2376 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2379 "%% Malformed Route Distinguisher\n");
2382 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2383 bgp_show_type_normal
, NULL
, 0,
2384 use_json(argc
, argv
));
2386 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2387 bgp_show_type_normal
, NULL
, 0,
2388 use_json(argc
, argv
));
2394 ALIAS(show_bgp_ip_vpn_all_rd
,
2395 show_bgp_ip_vpn_rd_cmd
,
2396 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2400 "Display VPN NLRI specific information\n"
2401 "Display information for a route distinguisher\n"
2402 "VPN Route Distinguisher\n"
2403 "All VPN Route Distinguishers\n"
2406 #ifdef KEEP_OLD_VPN_COMMANDS
2407 DEFUN (show_ip_bgp_vpn_rd
,
2408 show_ip_bgp_vpn_rd_cmd
,
2409 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2414 "Address Family modifier\n"
2415 "Display information for a route distinguisher\n"
2416 "VPN Route Distinguisher\n"
2417 "All VPN Route Distinguishers\n")
2419 int idx_ext_community
= argc
- 1;
2421 struct prefix_rd prd
;
2425 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2426 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2427 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2428 bgp_show_type_normal
, NULL
, 0,
2430 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2432 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2435 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2441 DEFUN (show_ip_bgp_vpn_all
,
2442 show_ip_bgp_vpn_all_cmd
,
2443 "show [ip] bgp <vpnv4|vpnv6>",
2452 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2453 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2458 DEFUN (show_ip_bgp_vpn_all_tags
,
2459 show_ip_bgp_vpn_all_tags_cmd
,
2460 "show [ip] bgp <vpnv4|vpnv6> all tags",
2465 "Display information about all VPNv4/VPNV6 NLRIs\n"
2466 "Display BGP tags for prefixes\n")
2471 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2472 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2477 DEFUN (show_ip_bgp_vpn_rd_tags
,
2478 show_ip_bgp_vpn_rd_tags_cmd
,
2479 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2484 "Display information for a route distinguisher\n"
2485 "VPN Route Distinguisher\n"
2486 "All VPN Route Distinguishers\n"
2487 "Display BGP tags for prefixes\n")
2489 int idx_ext_community
= 5;
2491 struct prefix_rd prd
;
2495 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2496 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2497 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2498 bgp_show_type_normal
, NULL
, 1,
2500 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2502 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2505 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2511 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2512 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2513 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2518 "Display information about all VPNv4/VPNv6 NLRIs\n"
2519 "Detailed information on TCP and BGP neighbor connections\n"
2520 "Neighbor to display information about\n"
2521 "Display routes learned from neighbor\n"
2528 bool uj
= use_json(argc
, argv
);
2532 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2533 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2536 json_object
*json_no
= NULL
;
2537 json_no
= json_object_new_object();
2538 json_object_string_add(json_no
, "warning",
2539 "Malformed address");
2540 vty_out(vty
, "%s\n",
2541 json_object_to_json_string(json_no
));
2542 json_object_free(json_no
);
2544 vty_out(vty
, "Malformed address: %s\n",
2545 argv
[idx_ipv4
]->arg
);
2549 peer
= peer_lookup(NULL
, &su
);
2550 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2552 json_object
*json_no
= NULL
;
2553 json_no
= json_object_new_object();
2554 json_object_string_add(
2556 "No such neighbor or address family");
2557 vty_out(vty
, "%s\n",
2558 json_object_to_json_string(json_no
));
2559 json_object_free(json_no
);
2562 "%% No such neighbor or address family\n");
2566 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2572 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2573 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2574 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
2579 "Display information for a route distinguisher\n"
2580 "VPN Route Distinguisher\n"
2581 "All VPN Route Distinguishers\n"
2582 "Detailed information on TCP and BGP neighbor connections\n"
2583 "Neighbor to display information about\n"
2584 "Display routes learned from neighbor\n"
2587 int idx_ext_community
= 5;
2592 struct prefix_rd prd
;
2593 bool prefix_rd_all
= false;
2594 bool uj
= use_json(argc
, argv
);
2598 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2599 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2600 prefix_rd_all
= true;
2602 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2605 json_object
*json_no
= NULL
;
2606 json_no
= json_object_new_object();
2607 json_object_string_add(
2609 "Malformed Route Distinguisher");
2610 vty_out(vty
, "%s\n",
2611 json_object_to_json_string(
2613 json_object_free(json_no
);
2616 "%% Malformed Route Distinguisher\n");
2621 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2624 json_object
*json_no
= NULL
;
2625 json_no
= json_object_new_object();
2626 json_object_string_add(json_no
, "warning",
2627 "Malformed address");
2628 vty_out(vty
, "%s\n",
2629 json_object_to_json_string(json_no
));
2630 json_object_free(json_no
);
2632 vty_out(vty
, "Malformed address: %s\n",
2633 argv
[idx_ext_community
]->arg
);
2637 peer
= peer_lookup(NULL
, &su
);
2638 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2640 json_object
*json_no
= NULL
;
2641 json_no
= json_object_new_object();
2642 json_object_string_add(
2644 "No such neighbor or address family");
2645 vty_out(vty
, "%s\n",
2646 json_object_to_json_string(json_no
));
2647 json_object_free(json_no
);
2650 "%% No such neighbor or address family\n");
2655 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2656 bgp_show_type_neighbor
, &su
, 0,
2659 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2660 bgp_show_type_neighbor
, &su
, 0,
2666 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2667 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2668 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2673 "Display information about all VPNv4/VPNv6 NLRIs\n"
2674 "Detailed information on TCP and BGP neighbor connections\n"
2675 "Neighbor to display information about\n"
2676 "Display the routes advertised to a BGP neighbor\n"
2683 bool uj
= use_json(argc
, argv
);
2687 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2688 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2691 json_object
*json_no
= NULL
;
2692 json_no
= json_object_new_object();
2693 json_object_string_add(json_no
, "warning",
2694 "Malformed address");
2695 vty_out(vty
, "%s\n",
2696 json_object_to_json_string(json_no
));
2697 json_object_free(json_no
);
2699 vty_out(vty
, "Malformed address: %s\n",
2700 argv
[idx_ipv4
]->arg
);
2703 peer
= peer_lookup(NULL
, &su
);
2704 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2706 json_object
*json_no
= NULL
;
2707 json_no
= json_object_new_object();
2708 json_object_string_add(
2710 "No such neighbor or address family");
2711 vty_out(vty
, "%s\n",
2712 json_object_to_json_string(json_no
));
2713 json_object_free(json_no
);
2716 "%% No such neighbor or address family\n");
2719 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2725 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2726 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2727 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
2732 "Display information for a route distinguisher\n"
2733 "VPN Route Distinguisher\n"
2734 "All VPN Route Distinguishers\n"
2735 "Detailed information on TCP and BGP neighbor connections\n"
2736 "Neighbor to display information about\n"
2737 "Display the routes advertised to a BGP neighbor\n"
2740 int idx_ext_community
= 5;
2744 struct prefix_rd prd
;
2746 bool uj
= use_json(argc
, argv
);
2750 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2751 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2754 json_object
*json_no
= NULL
;
2755 json_no
= json_object_new_object();
2756 json_object_string_add(json_no
, "warning",
2757 "Malformed address");
2758 vty_out(vty
, "%s\n",
2759 json_object_to_json_string(json_no
));
2760 json_object_free(json_no
);
2762 vty_out(vty
, "Malformed address: %s\n",
2763 argv
[idx_ext_community
]->arg
);
2766 peer
= peer_lookup(NULL
, &su
);
2767 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2769 json_object
*json_no
= NULL
;
2770 json_no
= json_object_new_object();
2771 json_object_string_add(
2773 "No such neighbor or address family");
2774 vty_out(vty
, "%s\n",
2775 json_object_to_json_string(json_no
));
2776 json_object_free(json_no
);
2779 "%% No such neighbor or address family\n");
2783 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2784 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2786 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2789 json_object
*json_no
= NULL
;
2790 json_no
= json_object_new_object();
2791 json_object_string_add(
2793 "Malformed Route Distinguisher");
2794 vty_out(vty
, "%s\n",
2795 json_object_to_json_string(json_no
));
2796 json_object_free(json_no
);
2799 "%% Malformed Route Distinguisher\n");
2803 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2808 #endif /* KEEP_OLD_VPN_COMMANDS */
2810 void bgp_mplsvpn_init(void)
2812 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2813 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2814 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2816 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2817 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2819 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2820 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2821 #ifdef KEEP_OLD_VPN_COMMANDS
2822 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2823 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2824 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2825 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2826 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2827 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2828 install_element(VIEW_NODE
,
2829 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2830 install_element(VIEW_NODE
,
2831 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2832 #endif /* KEEP_OLD_VPN_COMMANDS */
2835 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2837 struct listnode
*mnode
, *mnnode
;
2841 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
2844 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2845 struct ecommunity
*ec
;
2847 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2850 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
2852 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
2855 if (ecom_intersect(ec
, eckey
))
2862 * The purpose of this function is to process leaks that were deferred
2863 * from earlier per-vrf configuration due to not-yet-existing default
2864 * vrf, in other words, configuration such as:
2866 * router bgp MMM vrf FOO
2867 * address-family ipv4 unicast
2869 * exit-address-family
2874 * This function gets called when the default instance ("router bgp NNN")
2877 void vpn_leak_postchange_all(void)
2879 struct listnode
*next
;
2881 struct bgp
*bgp_default
= bgp_get_default();
2883 assert(bgp_default
);
2885 /* First, do any exporting from VRFs to the single VPN RIB */
2886 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2888 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2891 vpn_leak_postchange(
2892 BGP_VPN_POLICY_DIR_TOVPN
,
2897 vpn_leak_postchange(
2898 BGP_VPN_POLICY_DIR_TOVPN
,
2904 /* Now, do any importing to VRFs from the single VPN RIB */
2905 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2907 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2910 vpn_leak_postchange(
2911 BGP_VPN_POLICY_DIR_FROMVPN
,
2916 vpn_leak_postchange(
2917 BGP_VPN_POLICY_DIR_FROMVPN
,
2924 /* When a bgp vrf instance is unconfigured, remove its routes
2925 * from the VPN table and this vrf could be importing routes from other
2926 * bgp vrf instnaces, unimport them.
2927 * VRF X and VRF Y are exporting routes to each other.
2928 * When VRF X is deleted, unimport its routes from all target vrfs,
2929 * also VRF Y should unimport its routes from VRF X table.
2930 * This will ensure VPN table is cleaned up appropriately.
2932 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
2935 const char *tmp_name
;
2937 struct listnode
*node
, *next
;
2938 safi_t safi
= SAFI_UNICAST
;
2940 bool is_vrf_leak_bind
;
2943 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2946 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2947 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2949 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2951 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2952 /* vrf leak is for IPv4 and IPv6 Unicast only */
2953 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
2956 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
2957 if (from_bgp
== to_bgp
)
2960 /* Unimport and remove source vrf from the
2961 * other vrfs import list.
2963 struct vpn_policy
*to_vpolicy
;
2965 is_vrf_leak_bind
= false;
2966 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
2967 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
2969 if (strcmp(vname
, tmp_name
) == 0) {
2970 is_vrf_leak_bind
= true;
2974 /* skip this bgp instance as there is no leak to this
2977 if (!is_vrf_leak_bind
)
2981 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
2982 __func__
, from_bgp
->name_pretty
,
2983 to_bgp
->name_pretty
, afi2str(afi
),
2984 to_vpolicy
->import_vrf
->count
);
2986 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
2988 /* readd vrf name as unimport removes import vrf name
2989 * from the destination vrf's import list where the
2990 * `import vrf` configuration still exist.
2992 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
2993 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2995 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2996 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2998 /* If to_bgp exports its routes to the bgp vrf
2999 * which is being deleted, un-import the
3000 * to_bgp routes from VPN.
3002 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
3005 if (strcmp(vname
, tmp_name
) == 0) {
3006 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
3016 /* When a router bgp is configured, there could be a bgp vrf
3017 * instance importing routes from this newly configured
3018 * bgp vrf instance. Export routes from configured
3020 * VRF Y has import from bgp vrf x,
3021 * when a bgp vrf x instance is created, export its routes
3022 * to VRF Y instance.
3024 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
3027 const char *export_name
;
3029 struct listnode
*node
, *next
;
3030 struct ecommunity
*ecom
;
3031 vpn_policy_direction_t idir
, edir
;
3032 safi_t safi
= SAFI_UNICAST
;
3036 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3037 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3039 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3040 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3042 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3044 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3045 /* vrf leak is for IPv4 and IPv6 Unicast only */
3046 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3049 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3050 if (from_bgp
== to_bgp
)
3053 /* bgp instance has import list, check to see if newly
3054 * configured bgp instance is the list.
3056 struct vpn_policy
*to_vpolicy
;
3058 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3059 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3061 if (strcmp(vname
, export_name
) != 0)
3065 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3067 export_name
, to_bgp
->name_pretty
);
3069 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3070 /* remove import rt, it will be readded
3071 * as part of import from vrf.
3075 to_vpolicy
->rtlist
[idir
],
3076 (struct ecommunity_val
*)
3078 vrf_import_from_vrf(to_bgp
, from_bgp
,