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_index
) {
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
;
718 * returns pointer to new bgp_path_info upon success
720 static struct bgp_path_info
*
721 leak_update(struct bgp
*bgp
, /* destination bgp instance */
722 struct bgp_dest
*bn
, struct attr
*new_attr
, /* already interned */
723 afi_t afi
, safi_t safi
, struct bgp_path_info
*source_bpi
,
724 mpls_label_t
*label
, uint32_t num_labels
, void *parent
,
725 struct bgp
*bgp_orig
, struct prefix
*nexthop_orig
,
726 int nexthop_self_flag
, int debug
)
728 const struct prefix
*p
= bgp_dest_get_prefix(bn
);
729 struct bgp_path_info
*bpi
;
730 struct bgp_path_info
*bpi_ultimate
;
731 struct bgp_path_info
*new;
732 uint32_t num_sids
= 0;
734 if (new_attr
->srv6_l3vpn
|| new_attr
->srv6_vpn
)
739 "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
740 __func__
, bgp
->name_pretty
, bn
, source_bpi
->type
,
741 source_bpi
->sub_type
);
744 * Routes that are redistributed into BGP from zebra do not get
745 * nexthop tracking. However, if those routes are subsequently
746 * imported to other RIBs within BGP, the leaked routes do not
747 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
748 * in order to determine if the route we are currently leaking
749 * should have nexthop tracking, we must find the ultimate
750 * parent so we can check its sub_type.
752 * As of now, source_bpi may at most be a second-generation route
753 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
754 * Using a loop here supports more complex intra-bgp import-export
755 * schemes that could be implemented in the future.
758 for (bpi_ultimate
= source_bpi
;
759 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
760 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
766 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
767 if (bpi
->extra
&& bpi
->extra
->parent
== parent
)
772 bool labelssame
= labels_same(bpi
, label
, num_labels
);
774 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)
775 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
778 "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
779 __func__
, bgp
->name_pretty
,
780 source_bpi
->flags
, bpi
->flags
, p
);
785 if (attrhash_cmp(bpi
->attr
, new_attr
) && labelssame
786 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
788 bgp_attr_unintern(&new_attr
);
791 "%s: ->%s: %pBD: Found route, no change",
792 __func__
, bgp
->name_pretty
, bn
);
796 /* attr is changed */
797 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ATTR_CHANGED
);
799 /* Rewrite BGP route information. */
800 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
801 bgp_path_info_restore(bn
, bpi
);
803 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
804 bgp_attr_unintern(&bpi
->attr
);
805 bpi
->attr
= new_attr
;
806 bpi
->uptime
= bgp_clock();
812 setlabels(bpi
, label
, num_labels
);
818 if (new_attr
->srv6_l3vpn
)
819 setsids(bpi
, &new_attr
->srv6_l3vpn
->sid
,
821 else if (new_attr
->srv6_vpn
)
822 setsids(bpi
, &new_attr
->srv6_vpn
->sid
,
826 if (nexthop_self_flag
)
827 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_ANNC_NH_SELF
);
829 struct bgp
*bgp_nexthop
= bgp
;
832 if (bpi
->extra
&& bpi
->extra
->bgp_orig
)
833 bgp_nexthop
= bpi
->extra
->bgp_orig
;
836 * No nexthop tracking for redistributed routes or for
837 * EVPN-imported routes that get leaked.
839 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
840 is_pi_family_evpn(bpi_ultimate
))
844 * TBD do we need to do anything about the
845 * 'connected' parameter?
847 nh_valid
= bgp_find_or_add_nexthop(
848 bgp
, bgp_nexthop
, afi
, safi
, bpi
, NULL
, 0, p
);
851 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
852 __func__
, (nh_valid
? "" : "not "),
853 bgp_nexthop
->name_pretty
);
856 bgp_path_info_set_flag(bn
, bpi
, BGP_PATH_VALID
);
858 /* Process change. */
859 bgp_aggregate_increment(bgp
, p
, bpi
, afi
, safi
);
860 bgp_process(bgp
, bn
, afi
, safi
);
861 bgp_dest_unlock_node(bn
);
864 zlog_debug("%s: ->%s: %pBD Found route, changed attr",
865 __func__
, bgp
->name_pretty
, bn
);
870 if (CHECK_FLAG(source_bpi
->flags
, BGP_PATH_REMOVED
)) {
873 "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
874 __func__
, bgp
->name_pretty
,
875 source_bpi
->flags
, p
);
880 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_IMPORTED
, 0,
881 bgp
->peer_self
, new_attr
, bn
);
883 if (nexthop_self_flag
)
884 bgp_path_info_set_flag(bn
, new, BGP_PATH_ANNC_NH_SELF
);
886 bgp_path_info_extra_get(new);
892 if (new_attr
->srv6_l3vpn
)
893 setsids(new, &new_attr
->srv6_l3vpn
->sid
, num_sids
);
894 else if (new_attr
->srv6_vpn
)
895 setsids(new, &new_attr
->srv6_vpn
->sid
, num_sids
);
899 setlabels(new, label
, num_labels
);
901 new->extra
->parent
= bgp_path_info_lock(parent
);
903 (struct bgp_dest
*)((struct bgp_path_info
*)parent
)->net
);
905 new->extra
->bgp_orig
= bgp_lock(bgp_orig
);
907 new->extra
->nexthop_orig
= *nexthop_orig
;
910 * nexthop tracking for unicast routes
912 struct bgp
*bgp_nexthop
= bgp
;
915 if (new->extra
->bgp_orig
)
916 bgp_nexthop
= new->extra
->bgp_orig
;
919 * No nexthop tracking for redistributed routes because
920 * their originating protocols will do the tracking and
921 * withdraw those routes if the nexthops become unreachable
922 * This also holds good for EVPN-imported routes that get
925 if (bpi_ultimate
->sub_type
== BGP_ROUTE_REDISTRIBUTE
||
926 is_pi_family_evpn(bpi_ultimate
))
930 * TBD do we need to do anything about the
931 * 'connected' parameter?
933 nh_valid
= bgp_find_or_add_nexthop(bgp
, bgp_nexthop
, afi
, safi
,
937 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
938 __func__
, (nh_valid
? "" : "not "),
939 bgp_nexthop
->name_pretty
);
941 bgp_path_info_set_flag(bn
, new, BGP_PATH_VALID
);
943 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
944 bgp_path_info_add(bn
, new);
946 bgp_dest_unlock_node(bn
);
947 bgp_process(bgp
, bn
, afi
, safi
);
950 zlog_debug("%s: ->%s: %pBD: Added new route", __func__
,
951 bgp
->name_pretty
, bn
);
956 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
957 void vpn_leak_from_vrf_update(struct bgp
*bgp_vpn
, /* to */
958 struct bgp
*bgp_vrf
, /* from */
959 struct bgp_path_info
*path_vrf
) /* route */
961 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
962 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
963 afi_t afi
= family2afi(p
->family
);
964 struct attr static_attr
= {0};
965 struct attr
*new_attr
= NULL
;
966 safi_t safi
= SAFI_MPLS_VPN
;
967 mpls_label_t label_val
;
970 const char *debugmsg
;
971 int nexthop_self_flag
= 0;
974 zlog_debug("%s: from vrf %s", __func__
, bgp_vrf
->name_pretty
);
976 if (debug
&& path_vrf
->attr
->ecommunity
) {
977 char *s
= ecommunity_ecom2str(path_vrf
->attr
->ecommunity
,
978 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
980 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__
,
981 bgp_vrf
->name
, path_vrf
->type
, s
);
982 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
990 zlog_debug("%s: can't get afi of prefix", __func__
);
994 /* Is this route exportable into the VPN table? */
995 if (!is_route_injectable_into_vpn(path_vrf
))
998 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1000 zlog_debug("%s: %s skipping: %s", __func__
,
1001 bgp_vrf
->name
, debugmsg
);
1006 static_attr
= *path_vrf
->attr
;
1009 * route map handling
1011 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
]) {
1012 struct bgp_path_info info
;
1013 route_map_result_t ret
;
1015 memset(&info
, 0, sizeof(info
));
1016 info
.peer
= bgp_vpn
->peer_self
;
1017 info
.attr
= &static_attr
;
1018 ret
= route_map_apply(
1019 bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
],
1021 if (RMAP_DENYMATCH
== ret
) {
1022 bgp_attr_flush(&static_attr
); /* free any added parts */
1025 "%s: vrf %s route map \"%s\" says DENY, returning",
1026 __func__
, bgp_vrf
->name_pretty
,
1027 bgp_vrf
->vpn_policy
[afi
]
1028 .rmap
[BGP_VPN_POLICY_DIR_TOVPN
]
1034 if (debug
&& static_attr
.ecommunity
) {
1035 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
1036 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1038 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
1040 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1044 * Add the vpn-policy rt-list
1046 struct ecommunity
*old_ecom
;
1047 struct ecommunity
*new_ecom
;
1049 /* Export with the 'from' instance's export RTs. */
1050 /* If doing VRF-to-VRF leaking, strip existing RTs first. */
1051 old_ecom
= static_attr
.ecommunity
;
1053 new_ecom
= ecommunity_dup(old_ecom
);
1054 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
1055 BGP_CONFIG_VRF_TO_VRF_EXPORT
))
1056 ecommunity_strip_rts(new_ecom
);
1057 new_ecom
= ecommunity_merge(new_ecom
,
1058 bgp_vrf
->vpn_policy
[afi
]
1059 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1060 if (!old_ecom
->refcnt
)
1061 ecommunity_free(&old_ecom
);
1063 new_ecom
= ecommunity_dup(
1064 bgp_vrf
->vpn_policy
[afi
]
1065 .rtlist
[BGP_VPN_POLICY_DIR_TOVPN
]);
1067 static_attr
.ecommunity
= new_ecom
;
1068 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
1070 if (debug
&& static_attr
.ecommunity
) {
1071 char *s
= ecommunity_ecom2str(static_attr
.ecommunity
,
1072 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1074 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
1076 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1080 /* if policy nexthop not set, use 0 */
1081 if (CHECK_FLAG(bgp_vrf
->vpn_policy
[afi
].flags
,
1082 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET
)) {
1083 struct prefix
*nexthop
=
1084 &bgp_vrf
->vpn_policy
[afi
].tovpn_nexthop
;
1086 switch (nexthop
->family
) {
1088 /* prevent mp_nexthop_global_in <- self in bgp_route.c
1090 static_attr
.nexthop
.s_addr
= nexthop
->u
.prefix4
.s_addr
;
1092 static_attr
.mp_nexthop_global_in
= nexthop
->u
.prefix4
;
1093 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1097 static_attr
.mp_nexthop_global
= nexthop
->u
.prefix6
;
1098 static_attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1105 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][SAFI_UNICAST
],
1106 BGP_CONFIG_VRF_TO_VRF_EXPORT
)) {
1107 if (afi
== AFI_IP
) {
1109 * For ipv4, copy to multiprotocol
1112 static_attr
.mp_nexthop_global_in
=
1113 static_attr
.nexthop
;
1114 static_attr
.mp_nexthop_len
=
1115 BGP_ATTR_NHLEN_IPV4
;
1117 * XXX Leave static_attr.nexthop
1121 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1124 /* Update based on next-hop family to account for
1125 * RFC 5549 (BGP unnumbered) scenario. Note that
1126 * specific action is only needed for the case of
1127 * IPv4 nexthops as the attr has been copied
1131 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf
->attr
)) {
1132 static_attr
.mp_nexthop_global_in
.s_addr
=
1133 static_attr
.nexthop
.s_addr
;
1134 static_attr
.mp_nexthop_len
=
1135 BGP_ATTR_NHLEN_IPV4
;
1137 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1140 nexthop_self_flag
= 1;
1143 label_val
= bgp_vrf
->vpn_policy
[afi
].tovpn_label
;
1144 if (label_val
== MPLS_LABEL_NONE
) {
1145 encode_label(MPLS_LABEL_IMPLICIT_NULL
, &label
);
1147 encode_label(label_val
, &label
);
1150 /* Set originator ID to "me" */
1151 SET_FLAG(static_attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
));
1152 static_attr
.originator_id
= bgp_vpn
->router_id
;
1154 /* Set SID for SRv6 VPN */
1155 if (bgp_vrf
->vpn_policy
[afi
].tovpn_sid
) {
1156 static_attr
.srv6_l3vpn
= XCALLOC(MTYPE_BGP_SRV6_L3VPN
,
1157 sizeof(struct bgp_attr_srv6_l3vpn
));
1158 static_attr
.srv6_l3vpn
->sid_flags
= 0x00;
1159 static_attr
.srv6_l3vpn
->endpoint_behavior
= 0xffff;
1160 memcpy(&static_attr
.srv6_l3vpn
->sid
,
1161 bgp_vrf
->vpn_policy
[afi
].tovpn_sid
,
1162 sizeof(static_attr
.srv6_l3vpn
->sid
));
1166 new_attr
= bgp_attr_intern(
1167 &static_attr
); /* hashed refcounted everything */
1168 bgp_attr_flush(&static_attr
); /* free locally-allocated parts */
1170 if (debug
&& new_attr
->ecommunity
) {
1171 char *s
= ecommunity_ecom2str(new_attr
->ecommunity
,
1172 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1174 zlog_debug("%s: new_attr->ecommunity{%s}", __func__
, s
);
1175 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1178 /* Now new_attr is an allocated interned attr */
1180 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
1181 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
1183 struct bgp_path_info
*new_info
;
1185 new_info
= leak_update(bgp_vpn
, bn
, new_attr
, afi
, safi
, path_vrf
,
1186 &label
, 1, path_vrf
, bgp_vrf
, NULL
,
1187 nexthop_self_flag
, debug
);
1190 * Routes actually installed in the vpn RIB must also be
1191 * offered to all vrfs (because now they originate from
1194 * Acceptance into other vrfs depends on rt-lists.
1195 * Originating vrf will not accept the looped back route
1196 * because of loop checking.
1199 vpn_leak_to_vrf_update(bgp_vrf
, new_info
);
1202 void vpn_leak_from_vrf_withdraw(struct bgp
*bgp_vpn
, /* to */
1203 struct bgp
*bgp_vrf
, /* from */
1204 struct bgp_path_info
*path_vrf
) /* route */
1206 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1207 const struct prefix
*p
= bgp_dest_get_prefix(path_vrf
->net
);
1208 afi_t afi
= family2afi(p
->family
);
1209 safi_t safi
= SAFI_MPLS_VPN
;
1210 struct bgp_path_info
*bpi
;
1211 struct bgp_dest
*bn
;
1212 const char *debugmsg
;
1216 "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
1217 __func__
, bgp_vrf
->name_pretty
, path_vrf
->net
,
1218 path_vrf
->type
, path_vrf
->sub_type
);
1226 zlog_debug("%s: can't get afi of prefix", __func__
);
1230 /* Is this route exportable into the VPN table? */
1231 if (!is_route_injectable_into_vpn(path_vrf
))
1234 if (!vpn_leak_to_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1236 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1241 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__
, path_vrf
);
1243 bn
= bgp_afi_node_get(bgp_vpn
->rib
[afi
][safi
], afi
, safi
, p
,
1244 &(bgp_vrf
->vpn_policy
[afi
].tovpn_rd
));
1250 * match original bpi imported from
1252 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1253 if (bpi
->extra
&& bpi
->extra
->parent
== path_vrf
) {
1259 /* withdraw from looped vrfs as well */
1260 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
1262 bgp_aggregate_decrement(bgp_vpn
, p
, bpi
, afi
, safi
);
1263 bgp_path_info_delete(bn
, bpi
);
1264 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1266 bgp_dest_unlock_node(bn
);
1269 void vpn_leak_from_vrf_withdraw_all(struct bgp
*bgp_vpn
, /* to */
1270 struct bgp
*bgp_vrf
, /* from */
1273 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1274 struct bgp_dest
*pdest
;
1275 safi_t safi
= SAFI_MPLS_VPN
;
1278 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
1280 for (pdest
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); pdest
;
1281 pdest
= bgp_route_next(pdest
)) {
1283 struct bgp_table
*table
;
1284 struct bgp_dest
*bn
;
1285 struct bgp_path_info
*bpi
;
1287 /* This is the per-RD table of prefixes */
1288 table
= bgp_dest_get_bgp_table_info(pdest
);
1293 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1294 bpi
= bgp_dest_get_bgp_path_info(bn
);
1296 zlog_debug("%s: looking at prefix %pBD",
1300 for (; bpi
; bpi
= bpi
->next
) {
1302 zlog_debug("%s: type %d, sub_type %d",
1303 __func__
, bpi
->type
,
1305 if (bpi
->sub_type
!= BGP_ROUTE_IMPORTED
)
1309 if ((struct bgp
*)bpi
->extra
->bgp_orig
1313 zlog_debug("%s: deleting it",
1315 /* withdraw from leak-to vrfs as well */
1316 vpn_leak_to_vrf_withdraw(bgp_vpn
, bpi
);
1317 bgp_aggregate_decrement(
1319 bgp_dest_get_prefix(bn
), bpi
,
1321 bgp_path_info_delete(bn
, bpi
);
1322 bgp_process(bgp_vpn
, bn
, afi
, safi
);
1329 void vpn_leak_from_vrf_update_all(struct bgp
*bgp_vpn
, /* to */
1330 struct bgp
*bgp_vrf
, /* from */
1333 struct bgp_dest
*bn
;
1334 struct bgp_path_info
*bpi
;
1335 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
);
1338 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__
, afi
,
1339 bgp_vrf
->name_pretty
);
1341 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][SAFI_UNICAST
]); bn
;
1342 bn
= bgp_route_next(bn
)) {
1345 zlog_debug("%s: node=%p", __func__
, bn
);
1347 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1351 "%s: calling vpn_leak_from_vrf_update",
1353 vpn_leak_from_vrf_update(bgp_vpn
, bgp_vrf
, bpi
);
1359 vpn_leak_to_vrf_update_onevrf(struct bgp
*bgp_vrf
, /* to */
1360 struct bgp
*bgp_vpn
, /* from */
1361 struct bgp_path_info
*path_vpn
) /* route */
1363 const struct prefix
*p
= bgp_dest_get_prefix(path_vpn
->net
);
1364 afi_t afi
= family2afi(p
->family
);
1366 struct attr static_attr
= {0};
1367 struct attr
*new_attr
= NULL
;
1368 struct bgp_dest
*bn
;
1369 safi_t safi
= SAFI_UNICAST
;
1370 const char *debugmsg
;
1371 struct prefix nexthop_orig
;
1372 mpls_label_t
*pLabels
= NULL
;
1373 uint32_t num_labels
= 0;
1374 int nexthop_self_flag
= 1;
1375 struct bgp_path_info
*bpi_ultimate
= NULL
;
1376 int origin_local
= 0;
1377 struct bgp
*src_vrf
;
1379 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1381 if (!vpn_leak_from_vpn_active(bgp_vrf
, afi
, &debugmsg
)) {
1383 zlog_debug("%s: skipping: %s", __func__
, debugmsg
);
1387 /* Check for intersection of route targets */
1388 if (!ecom_intersect(
1389 bgp_vrf
->vpn_policy
[afi
].rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1390 path_vpn
->attr
->ecommunity
)) {
1393 "from vpn to vrf %s, skipping after no intersection of route targets",
1394 bgp_vrf
->name_pretty
);
1399 zlog_debug("%s: updating %pFX to vrf %s", __func__
, p
,
1400 bgp_vrf
->name_pretty
);
1403 static_attr
= *path_vpn
->attr
;
1405 struct ecommunity
*old_ecom
;
1406 struct ecommunity
*new_ecom
;
1408 /* If doing VRF-to-VRF leaking, strip RTs. */
1409 old_ecom
= static_attr
.ecommunity
;
1410 if (old_ecom
&& CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1411 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1412 new_ecom
= ecommunity_dup(old_ecom
);
1413 ecommunity_strip_rts(new_ecom
);
1414 static_attr
.ecommunity
= new_ecom
;
1416 if (new_ecom
->size
== 0) {
1417 UNSET_FLAG(static_attr
.flag
,
1418 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
1419 ecommunity_free(&new_ecom
);
1420 static_attr
.ecommunity
= NULL
;
1423 if (!old_ecom
->refcnt
)
1424 ecommunity_free(&old_ecom
);
1428 * Nexthop: stash and clear
1430 * Nexthop is valid in context of VPN core, but not in destination vrf.
1431 * Stash it for later label resolution by vrf ingress path and then
1432 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1434 uint8_t nhfamily
= NEXTHOP_FAMILY(path_vpn
->attr
->mp_nexthop_len
);
1436 memset(&nexthop_orig
, 0, sizeof(nexthop_orig
));
1437 nexthop_orig
.family
= nhfamily
;
1442 nexthop_orig
.u
.prefix4
= path_vpn
->attr
->mp_nexthop_global_in
;
1443 nexthop_orig
.prefixlen
= IPV4_MAX_BITLEN
;
1445 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1446 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1447 static_attr
.nexthop
.s_addr
=
1448 nexthop_orig
.u
.prefix4
.s_addr
;
1450 static_attr
.mp_nexthop_global_in
=
1451 path_vpn
->attr
->mp_nexthop_global_in
;
1452 static_attr
.mp_nexthop_len
=
1453 path_vpn
->attr
->mp_nexthop_len
;
1455 static_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1459 nexthop_orig
.u
.prefix6
= path_vpn
->attr
->mp_nexthop_global
;
1460 nexthop_orig
.prefixlen
= IPV6_MAX_BITLEN
;
1462 if (CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1463 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1464 static_attr
.mp_nexthop_global
= nexthop_orig
.u
.prefix6
;
1470 * route map handling
1472 if (bgp_vrf
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]) {
1473 struct bgp_path_info info
;
1474 route_map_result_t ret
;
1476 memset(&info
, 0, sizeof(info
));
1477 info
.peer
= bgp_vrf
->peer_self
;
1478 info
.attr
= &static_attr
;
1479 info
.extra
= path_vpn
->extra
; /* Used for source-vrf filter */
1480 ret
= route_map_apply(bgp_vrf
->vpn_policy
[afi
]
1481 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
],
1483 if (RMAP_DENYMATCH
== ret
) {
1484 bgp_attr_flush(&static_attr
); /* free any added parts */
1487 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1488 __func__
, bgp_vrf
->name_pretty
,
1489 bgp_vrf
->vpn_policy
[afi
]
1490 .rmap
[BGP_VPN_POLICY_DIR_FROMVPN
]
1495 * if route-map changed nexthop, don't nexthop-self on output
1497 if (!CHECK_FLAG(static_attr
.rmap_change_flags
,
1498 BATTR_RMAP_NEXTHOP_UNCHANGED
))
1499 nexthop_self_flag
= 0;
1502 new_attr
= bgp_attr_intern(&static_attr
);
1503 bgp_attr_flush(&static_attr
);
1505 bn
= bgp_afi_node_get(bgp_vrf
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1508 * ensure labels are copied
1510 * However, there is a special case: if the route originated in
1511 * another local VRF (as opposed to arriving via VPN), then the
1512 * nexthop is reached by hairpinning through this router (me)
1513 * using IP forwarding only (no LSP). Therefore, the route
1514 * imported to the VRF should not have labels attached. Note
1515 * that nexthop tracking is also involved: eliminating the
1516 * labels for these routes enables the non-labeled nexthops
1517 * from the originating VRF to be considered valid for this route.
1519 if (!CHECK_FLAG(bgp_vrf
->af_flags
[afi
][safi
],
1520 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
1521 /* work back to original route */
1522 for (bpi_ultimate
= path_vpn
;
1523 bpi_ultimate
->extra
&& bpi_ultimate
->extra
->parent
;
1524 bpi_ultimate
= bpi_ultimate
->extra
->parent
)
1528 * if original route was unicast,
1529 * then it did not arrive over vpn
1531 if (bpi_ultimate
->net
) {
1532 struct bgp_table
*table
;
1534 table
= bgp_dest_table(bpi_ultimate
->net
);
1535 if (table
&& (table
->safi
== SAFI_UNICAST
))
1540 if (!origin_local
&& path_vpn
->extra
1541 && path_vpn
->extra
->num_labels
) {
1542 num_labels
= path_vpn
->extra
->num_labels
;
1543 if (num_labels
> BGP_MAX_LABELS
)
1544 num_labels
= BGP_MAX_LABELS
;
1545 pLabels
= path_vpn
->extra
->label
;
1550 zlog_debug("%s: pfx %pBD: num_labels %d", __func__
,
1551 path_vpn
->net
, num_labels
);
1554 * For VRF-2-VRF route-leaking,
1555 * the source will be the originating VRF.
1557 if (path_vpn
->extra
&& path_vpn
->extra
->bgp_orig
)
1558 src_vrf
= path_vpn
->extra
->bgp_orig
;
1562 leak_update(bgp_vrf
, bn
, new_attr
, afi
, safi
, path_vpn
, pLabels
,
1563 num_labels
, path_vpn
, /* parent */
1564 src_vrf
, &nexthop_orig
, nexthop_self_flag
, debug
);
1567 void vpn_leak_to_vrf_update(struct bgp
*bgp_vpn
, /* from */
1568 struct bgp_path_info
*path_vpn
) /* route */
1570 struct listnode
*mnode
, *mnnode
;
1573 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1576 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1578 /* Loop over VRFs */
1579 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1581 if (!path_vpn
->extra
1582 || path_vpn
->extra
->bgp_orig
!= bgp
) { /* no loop */
1583 vpn_leak_to_vrf_update_onevrf(bgp
, bgp_vpn
, path_vpn
);
1588 void vpn_leak_to_vrf_withdraw(struct bgp
*bgp_vpn
, /* from */
1589 struct bgp_path_info
*path_vpn
) /* route */
1591 const struct prefix
*p
;
1593 safi_t safi
= SAFI_UNICAST
;
1595 struct listnode
*mnode
, *mnnode
;
1596 struct bgp_dest
*bn
;
1597 struct bgp_path_info
*bpi
;
1598 const char *debugmsg
;
1600 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1603 zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__
,
1604 path_vpn
->net
, path_vpn
->type
, path_vpn
->sub_type
);
1607 zlog_debug("%s: start (path_vpn=%p)", __func__
, path_vpn
);
1609 if (!path_vpn
->net
) {
1610 #ifdef ENABLE_BGP_VNC
1611 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1612 if (path_vpn
->type
== ZEBRA_ROUTE_BGP
1613 && path_vpn
->sub_type
== BGP_ROUTE_RFP
) {
1620 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1625 p
= bgp_dest_get_prefix(path_vpn
->net
);
1626 afi
= family2afi(p
->family
);
1628 /* Loop over VRFs */
1629 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
1630 if (!vpn_leak_from_vpn_active(bgp
, afi
, &debugmsg
)) {
1632 zlog_debug("%s: skipping: %s", __func__
,
1637 /* Check for intersection of route targets */
1638 if (!ecom_intersect(bgp
->vpn_policy
[afi
]
1639 .rtlist
[BGP_VPN_POLICY_DIR_FROMVPN
],
1640 path_vpn
->attr
->ecommunity
)) {
1646 zlog_debug("%s: withdrawing from vrf %s", __func__
,
1649 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
1651 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1654 && (struct bgp_path_info
*)bpi
->extra
->parent
1662 zlog_debug("%s: deleting bpi %p", __func__
,
1664 bgp_aggregate_decrement(bgp
, p
, bpi
, afi
, safi
);
1665 bgp_path_info_delete(bn
, bpi
);
1666 bgp_process(bgp
, bn
, afi
, safi
);
1668 bgp_dest_unlock_node(bn
);
1672 void vpn_leak_to_vrf_withdraw_all(struct bgp
*bgp_vrf
, /* to */
1675 struct bgp_dest
*bn
;
1676 struct bgp_path_info
*bpi
;
1677 safi_t safi
= SAFI_UNICAST
;
1678 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
);
1681 zlog_debug("%s: entry", __func__
);
1683 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1685 for (bn
= bgp_table_top(bgp_vrf
->rib
[afi
][safi
]); bn
;
1686 bn
= bgp_route_next(bn
)) {
1688 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1691 && bpi
->extra
->bgp_orig
!= bgp_vrf
1692 && bpi
->extra
->parent
1693 && is_pi_family_vpn(bpi
->extra
->parent
)) {
1696 bgp_aggregate_decrement(bgp_vrf
,
1697 bgp_dest_get_prefix(bn
),
1699 bgp_path_info_delete(bn
, bpi
);
1700 bgp_process(bgp_vrf
, bn
, afi
, safi
);
1706 void vpn_leak_to_vrf_update_all(struct bgp
*bgp_vrf
, /* to */
1707 struct bgp
*bgp_vpn
, /* from */
1710 struct bgp_dest
*pdest
;
1711 safi_t safi
= SAFI_MPLS_VPN
;
1718 for (pdest
= bgp_table_top(bgp_vpn
->rib
[afi
][safi
]); pdest
;
1719 pdest
= bgp_route_next(pdest
)) {
1720 struct bgp_table
*table
;
1721 struct bgp_dest
*bn
;
1722 struct bgp_path_info
*bpi
;
1724 /* This is the per-RD table of prefixes */
1725 table
= bgp_dest_get_bgp_table_info(pdest
);
1730 for (bn
= bgp_table_top(table
); bn
; bn
= bgp_route_next(bn
)) {
1732 for (bpi
= bgp_dest_get_bgp_path_info(bn
); bpi
;
1736 && bpi
->extra
->bgp_orig
== bgp_vrf
)
1739 vpn_leak_to_vrf_update_onevrf(bgp_vrf
, bgp_vpn
,
1747 * This function is called for definition/deletion/change to a route-map
1749 static void vpn_policy_routemap_update(struct bgp
*bgp
, const char *rmap_name
)
1751 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1753 struct route_map
*rmap
;
1755 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1756 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
1761 rmap
= route_map_lookup_by_name(rmap_name
); /* NULL if deleted */
1763 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1765 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
]
1766 && !strcmp(rmap_name
,
1767 bgp
->vpn_policy
[afi
]
1768 .rmap_name
[BGP_VPN_POLICY_DIR_TOVPN
])) {
1772 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1773 __func__
, rmap_name
, bgp
->as
,
1776 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1777 bgp_get_default(), bgp
);
1779 zlog_debug("%s: after vpn_leak_prechange",
1782 /* in case of definition/deletion */
1783 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_TOVPN
] =
1786 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, afi
,
1787 bgp_get_default(), bgp
);
1790 zlog_debug("%s: after vpn_leak_postchange",
1794 if (bgp
->vpn_policy
[afi
].rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
]
1795 && !strcmp(rmap_name
,
1796 bgp
->vpn_policy
[afi
]
1797 .rmap_name
[BGP_VPN_POLICY_DIR_FROMVPN
])) {
1800 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1801 __func__
, rmap_name
, bgp
->as
,
1805 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1806 bgp_get_default(), bgp
);
1808 /* in case of definition/deletion */
1809 bgp
->vpn_policy
[afi
].rmap
[BGP_VPN_POLICY_DIR_FROMVPN
] =
1812 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, afi
,
1813 bgp_get_default(), bgp
);
1818 /* This API is used during router-id change, reflect VPNs
1819 * auto RD and RT values and readvertise routes to VPN table.
1821 void vpn_handle_router_id_update(struct bgp
*bgp
, bool withdraw
,
1825 int debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
)
1826 | BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1828 const char *export_name
;
1829 char buf
[RD_ADDRSTRLEN
];
1830 struct bgp
*bgp_import
;
1831 struct listnode
*node
;
1832 struct ecommunity
*ecom
;
1833 vpn_policy_direction_t idir
, edir
;
1836 * Router-id change that is not explicitly configured
1837 * (a change from zebra, frr restart for example)
1838 * should not replace a configured vpn RD/RT.
1842 zlog_debug("%s: skipping non explicit router-id change",
1847 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_DEFAULT
1848 && bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
1851 export_name
= bgp
->name
? bgp
->name
: VRF_DEFAULT_NAME
;
1852 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1853 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1855 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
1856 if (!vpn_leak_to_vpn_active(bgp
, afi
, NULL
))
1860 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
,
1861 afi
, bgp_get_default(), bgp
);
1863 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1864 __func__
, export_name
);
1866 /* Remove import RT from VRFs */
1867 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1868 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1869 export_vrf
, node
, vname
)) {
1870 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1871 bgp_import
= bgp_get_default();
1873 bgp_import
= bgp_lookup_by_name(vname
);
1878 bgp_import
->vpn_policy
[afi
]
1880 (struct ecommunity_val
*)ecom
->val
);
1883 /* New router-id derive auto RD and RT and export
1886 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
,
1887 &bgp
->vrf_prd_auto
);
1888 bgp
->vpn_policy
[afi
].tovpn_rd
= bgp
->vrf_prd_auto
;
1889 prefix_rd2str(&bgp
->vpn_policy
[afi
].tovpn_rd
, buf
,
1891 bgp
->vpn_policy
[afi
].rtlist
[edir
] =
1892 ecommunity_str2com(buf
,
1893 ECOMMUNITY_ROUTE_TARGET
, 0);
1895 /* Update import_vrf rt_list */
1896 ecom
= bgp
->vpn_policy
[afi
].rtlist
[edir
];
1897 for (ALL_LIST_ELEMENTS_RO(bgp
->vpn_policy
[afi
].
1898 export_vrf
, node
, vname
)) {
1899 if (strcmp(vname
, VRF_DEFAULT_NAME
) == 0)
1900 bgp_import
= bgp_get_default();
1902 bgp_import
= bgp_lookup_by_name(vname
);
1905 if (bgp_import
->vpn_policy
[afi
].rtlist
[idir
])
1906 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1908 bgp_import
->vpn_policy
[afi
]
1909 .rtlist
[idir
], ecom
);
1911 bgp_import
->vpn_policy
[afi
].rtlist
[idir
]
1912 = ecommunity_dup(ecom
);
1915 /* Update routes to VPN */
1916 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
,
1917 afi
, bgp_get_default(),
1920 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
1921 __func__
, export_name
);
1926 void vpn_policy_routemap_event(const char *rmap_name
)
1928 int debug
= BGP_DEBUG(vpn
, VPN_LEAK_RMAP_EVENT
);
1929 struct listnode
*mnode
, *mnnode
;
1933 zlog_debug("%s: entry", __func__
);
1935 if (bm
->bgp
== NULL
) /* may be called during cleanup */
1938 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
1939 vpn_policy_routemap_update(bgp
, rmap_name
);
1942 void vrf_import_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
1943 afi_t afi
, safi_t safi
)
1945 const char *export_name
;
1946 vpn_policy_direction_t idir
, edir
;
1947 char *vname
, *tmp_name
;
1948 char buf
[RD_ADDRSTRLEN
];
1949 struct ecommunity
*ecom
;
1950 bool first_export
= false;
1952 struct listnode
*node
;
1953 bool is_inst_match
= false;
1955 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
1956 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
1957 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
1959 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
1960 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
1963 * Cross-ref both VRFs. Also, note if this is the first time
1964 * any VRF is importing from "import_vrf".
1966 vname
= (from_bgp
->name
? XSTRDUP(MTYPE_TMP
, from_bgp
->name
)
1967 : XSTRDUP(MTYPE_TMP
, VRF_DEFAULT_NAME
));
1969 /* Check the import_vrf list of destination vrf for the source vrf name,
1972 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
,
1974 if (strcmp(vname
, tmp_name
) == 0) {
1975 is_inst_match
= true;
1980 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
1983 XFREE(MTYPE_TMP
, vname
);
1985 /* Check if the source vrf already exports to any vrf,
1986 * first time export requires to setup auto derived RD/RT values.
1987 * Add the destination vrf name to export vrf list if it is
1990 is_inst_match
= false;
1991 vname
= XSTRDUP(MTYPE_TMP
, export_name
);
1992 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
1993 first_export
= true;
1995 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
1997 if (strcmp(vname
, tmp_name
) == 0) {
1998 is_inst_match
= true;
2004 listnode_add(from_bgp
->vpn_policy
[afi
].export_vrf
,
2007 XFREE(MTYPE_TMP
, vname
);
2009 /* Update import RT for current VRF using export RT of the VRF we're
2010 * importing from. First though, make sure "import_vrf" has that
2014 form_auto_rd(from_bgp
->router_id
, from_bgp
->vrf_rd_id
,
2015 &from_bgp
->vrf_prd_auto
);
2016 from_bgp
->vpn_policy
[afi
].tovpn_rd
= from_bgp
->vrf_prd_auto
;
2017 SET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2018 BGP_VPN_POLICY_TOVPN_RD_SET
);
2019 prefix_rd2str(&from_bgp
->vpn_policy
[afi
].tovpn_rd
,
2021 from_bgp
->vpn_policy
[afi
].rtlist
[edir
] =
2022 ecommunity_str2com(buf
, ECOMMUNITY_ROUTE_TARGET
, 0);
2023 SET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2024 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2025 from_bgp
->vpn_policy
[afi
].tovpn_label
=
2026 BGP_PREVENT_VRF_2_VRF_LEAK
;
2028 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2029 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2030 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] =
2031 ecommunity_merge(to_bgp
->vpn_policy
[afi
]
2032 .rtlist
[idir
], ecom
);
2034 to_bgp
->vpn_policy
[afi
].rtlist
[idir
] = ecommunity_dup(ecom
);
2035 SET_FLAG(to_bgp
->af_flags
[afi
][safi
], BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2038 const char *from_name
;
2039 char *ecom1
, *ecom2
;
2041 from_name
= from_bgp
->name
? from_bgp
->name
:
2044 ecom1
= ecommunity_ecom2str(
2045 to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2046 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2048 ecom2
= ecommunity_ecom2str(
2049 to_bgp
->vpn_policy
[afi
].rtlist
[edir
],
2050 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2053 "%s from %s to %s first_export %u import-rt %s export-rt %s",
2054 __func__
, from_name
, export_name
, first_export
, ecom1
,
2057 ecommunity_strfree(&ecom1
);
2058 ecommunity_strfree(&ecom2
);
2061 /* Does "import_vrf" first need to export its routes or that
2062 * is already done and we just need to import those routes
2063 * from the global table?
2066 vpn_leak_postchange(edir
, afi
, bgp_get_default(), from_bgp
);
2068 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2071 void vrf_unimport_from_vrf(struct bgp
*to_bgp
, struct bgp
*from_bgp
,
2072 afi_t afi
, safi_t safi
)
2074 const char *export_name
, *tmp_name
;
2075 vpn_policy_direction_t idir
, edir
;
2077 struct ecommunity
*ecom
= NULL
;
2078 struct listnode
*node
;
2081 export_name
= to_bgp
->name
? to_bgp
->name
: VRF_DEFAULT_NAME
;
2082 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2083 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
2084 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
2086 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2087 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2089 /* Were we importing from "import_vrf"? */
2090 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
].import_vrf
, node
,
2092 if (strcmp(vname
, tmp_name
) == 0)
2097 * We do not check in the cli if the passed in bgp
2098 * instance is actually imported into us before
2099 * we call this function. As such if we do not
2100 * find this in the import_vrf list than
2101 * we just need to return safely.
2107 zlog_debug("%s from %s to %s", __func__
, tmp_name
, export_name
);
2109 /* Remove "import_vrf" from our import list. */
2110 listnode_delete(to_bgp
->vpn_policy
[afi
].import_vrf
, vname
);
2111 XFREE(MTYPE_TMP
, vname
);
2113 /* Remove routes imported from "import_vrf". */
2114 /* TODO: In the current logic, we have to first remove all
2115 * imported routes and then (if needed) import back routes
2117 vpn_leak_prechange(idir
, afi
, bgp_get_default(), to_bgp
);
2119 if (to_bgp
->vpn_policy
[afi
].import_vrf
->count
== 0) {
2120 if (!to_bgp
->vpn_policy
[afi
].rmap
[idir
])
2121 UNSET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2122 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2123 if (to_bgp
->vpn_policy
[afi
].rtlist
[idir
])
2124 ecommunity_free(&to_bgp
->vpn_policy
[afi
].rtlist
[idir
]);
2126 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
2128 ecommunity_del_val(to_bgp
->vpn_policy
[afi
].rtlist
[idir
],
2129 (struct ecommunity_val
*)ecom
->val
);
2130 vpn_leak_postchange(idir
, afi
, bgp_get_default(), to_bgp
);
2135 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
2136 * below is checking for NULL that export_vrf can be
2137 * NULL, consequently it is complaining( like a cabbage )
2138 * that we could dereference and crash in the listcount(..)
2140 * So make it happy, under protest, with liberty and justice
2143 assert(from_bgp
->vpn_policy
[afi
].export_vrf
);
2145 /* Remove us from "import_vrf's" export list. If no other VRF
2146 * is importing from "import_vrf", cleanup appropriately.
2148 for (ALL_LIST_ELEMENTS_RO(from_bgp
->vpn_policy
[afi
].export_vrf
,
2150 if (strcmp(vname
, export_name
) == 0)
2155 * If we have gotten to this point then the vname must
2156 * exist. If not, we are in a world of trouble and
2157 * have slag sitting around.
2159 * import_vrf and export_vrf must match in having
2160 * the in/out names as appropriate.
2161 * export_vrf list could have been cleaned up
2162 * as part of no router bgp source instnace.
2167 listnode_delete(from_bgp
->vpn_policy
[afi
].export_vrf
, vname
);
2168 XFREE(MTYPE_TMP
, vname
);
2170 if (!listcount(from_bgp
->vpn_policy
[afi
].export_vrf
)) {
2171 vpn_leak_prechange(edir
, afi
, bgp_get_default(), from_bgp
);
2172 ecommunity_free(&from_bgp
->vpn_policy
[afi
].rtlist
[edir
]);
2173 UNSET_FLAG(from_bgp
->af_flags
[afi
][safi
],
2174 BGP_CONFIG_VRF_TO_VRF_EXPORT
);
2175 memset(&from_bgp
->vpn_policy
[afi
].tovpn_rd
, 0,
2176 sizeof(struct prefix_rd
));
2177 UNSET_FLAG(from_bgp
->vpn_policy
[afi
].flags
,
2178 BGP_VPN_POLICY_TOVPN_RD_SET
);
2179 from_bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2184 /* For testing purpose, static route of MPLS-VPN. */
2185 DEFUN (vpnv4_network
,
2187 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2188 "Specify a network to announce via BGP\n"
2190 "Specify Route Distinguisher\n"
2191 "VPN Route Distinguisher\n"
2192 "VPN NLRI label (tag)\n"
2193 "VPN NLRI label (tag)\n"
2196 int idx_ipv4_prefixlen
= 1;
2197 int idx_ext_community
= 3;
2199 return bgp_static_set_safi(
2200 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2201 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
2202 NULL
, NULL
, NULL
, NULL
);
2205 DEFUN (vpnv4_network_route_map
,
2206 vpnv4_network_route_map_cmd
,
2207 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
2208 "Specify a network to announce via BGP\n"
2210 "Specify Route Distinguisher\n"
2211 "VPN Route Distinguisher\n"
2212 "VPN NLRI label (tag)\n"
2213 "VPN NLRI label (tag)\n"
2218 int idx_ipv4_prefixlen
= 1;
2219 int idx_ext_community
= 3;
2222 return bgp_static_set_safi(
2223 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
2224 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2225 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2228 /* For testing purpose, static route of MPLS-VPN. */
2229 DEFUN (no_vpnv4_network
,
2230 no_vpnv4_network_cmd
,
2231 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2233 "Specify a network to announce via BGP\n"
2235 "Specify Route Distinguisher\n"
2236 "VPN Route Distinguisher\n"
2237 "VPN NLRI label (tag)\n"
2238 "VPN NLRI label (tag)\n"
2241 int idx_ipv4_prefixlen
= 2;
2242 int idx_ext_community
= 4;
2244 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
2245 argv
[idx_ipv4_prefixlen
]->arg
,
2246 argv
[idx_ext_community
]->arg
,
2247 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2250 DEFUN (vpnv6_network
,
2252 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
2253 "Specify a network to announce via BGP\n"
2254 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2255 "Specify Route Distinguisher\n"
2256 "VPN Route Distinguisher\n"
2257 "VPN NLRI label (tag)\n"
2258 "VPN NLRI label (tag)\n"
2263 int idx_ipv6_prefix
= 1;
2264 int idx_ext_community
= 3;
2268 return bgp_static_set_safi(
2269 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2270 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2271 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
2273 return bgp_static_set_safi(
2274 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
2275 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
2276 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2279 /* For testing purpose, static route of MPLS-VPN. */
2280 DEFUN (no_vpnv6_network
,
2281 no_vpnv6_network_cmd
,
2282 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
2284 "Specify a network to announce via BGP\n"
2285 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
2286 "Specify Route Distinguisher\n"
2287 "VPN Route Distinguisher\n"
2288 "VPN NLRI label (tag)\n"
2289 "VPN NLRI label (tag)\n"
2292 int idx_ipv6_prefix
= 2;
2293 int idx_ext_community
= 4;
2295 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
2296 argv
[idx_ipv6_prefix
]->arg
,
2297 argv
[idx_ext_community
]->arg
,
2298 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
2301 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
2302 enum bgp_show_type type
, void *output_arg
, int tags
,
2306 struct bgp_table
*table
;
2308 bgp
= bgp_get_default();
2311 vty_out(vty
, "No BGP process is configured\n");
2313 vty_out(vty
, "{}\n");
2316 table
= bgp
->rib
[afi
][SAFI_MPLS_VPN
];
2317 return bgp_show_table_rd(vty
, bgp
, SAFI_MPLS_VPN
, table
, prd
, type
,
2318 output_arg
, use_json
);
2321 DEFUN (show_bgp_ip_vpn_all_rd
,
2322 show_bgp_ip_vpn_all_rd_cmd
,
2323 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
2327 "Display VPN NLRI specific information\n"
2328 "Display VPN NLRI specific information\n"
2329 "Display information for a route distinguisher\n"
2330 "VPN Route Distinguisher\n"
2331 "All VPN Route Distinguishers\n"
2335 struct prefix_rd prd
;
2339 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
2340 /* Constrain search if user supplies RD && RD != "all" */
2341 if (argv_find(argv
, argc
, "rd", &idx
)
2342 && strcmp(argv
[idx
+ 1]->arg
, "all")) {
2343 ret
= str2prefix_rd(argv
[idx
+ 1]->arg
, &prd
);
2346 "%% Malformed Route Distinguisher\n");
2349 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2350 bgp_show_type_normal
, NULL
, 0,
2351 use_json(argc
, argv
));
2353 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2354 bgp_show_type_normal
, NULL
, 0,
2355 use_json(argc
, argv
));
2361 ALIAS(show_bgp_ip_vpn_all_rd
,
2362 show_bgp_ip_vpn_rd_cmd
,
2363 "show bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
2367 "Display VPN NLRI specific information\n"
2368 "Display information for a route distinguisher\n"
2369 "VPN Route Distinguisher\n"
2370 "All VPN Route Distinguishers\n"
2373 #ifdef KEEP_OLD_VPN_COMMANDS
2374 DEFUN (show_ip_bgp_vpn_rd
,
2375 show_ip_bgp_vpn_rd_cmd
,
2376 "show ip bgp "BGP_AFI_CMD_STR
" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
2381 "Address Family modifier\n"
2382 "Display information for a route distinguisher\n"
2383 "VPN Route Distinguisher\n"
2384 "All VPN Route Distinguishers\n")
2386 int idx_ext_community
= argc
- 1;
2388 struct prefix_rd prd
;
2392 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2393 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2394 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2395 bgp_show_type_normal
, NULL
, 0,
2397 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2399 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2402 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2408 DEFUN (show_ip_bgp_vpn_all
,
2409 show_ip_bgp_vpn_all_cmd
,
2410 "show [ip] bgp <vpnv4|vpnv6>",
2419 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2420 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2425 DEFUN (show_ip_bgp_vpn_all_tags
,
2426 show_ip_bgp_vpn_all_tags_cmd
,
2427 "show [ip] bgp <vpnv4|vpnv6> all tags",
2432 "Display information about all VPNv4/VPNV6 NLRIs\n"
2433 "Display BGP tags for prefixes\n")
2438 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
2439 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
2444 DEFUN (show_ip_bgp_vpn_rd_tags
,
2445 show_ip_bgp_vpn_rd_tags_cmd
,
2446 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
2451 "Display information for a route distinguisher\n"
2452 "VPN Route Distinguisher\n"
2453 "All VPN Route Distinguishers\n"
2454 "Display BGP tags for prefixes\n")
2456 int idx_ext_community
= 5;
2458 struct prefix_rd prd
;
2462 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2463 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2464 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2465 bgp_show_type_normal
, NULL
, 1,
2467 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2469 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2472 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
2478 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
2479 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
2480 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2485 "Display information about all VPNv4/VPNv6 NLRIs\n"
2486 "Detailed information on TCP and BGP neighbor connections\n"
2487 "Neighbor to display information about\n"
2488 "Display routes learned from neighbor\n"
2495 bool uj
= use_json(argc
, argv
);
2499 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2500 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2503 json_object
*json_no
= NULL
;
2504 json_no
= json_object_new_object();
2505 json_object_string_add(json_no
, "warning",
2506 "Malformed address");
2507 vty_out(vty
, "%s\n",
2508 json_object_to_json_string(json_no
));
2509 json_object_free(json_no
);
2511 vty_out(vty
, "Malformed address: %s\n",
2512 argv
[idx_ipv4
]->arg
);
2516 peer
= peer_lookup(NULL
, &su
);
2517 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2519 json_object
*json_no
= NULL
;
2520 json_no
= json_object_new_object();
2521 json_object_string_add(
2523 "No such neighbor or address family");
2524 vty_out(vty
, "%s\n",
2525 json_object_to_json_string(json_no
));
2526 json_object_free(json_no
);
2529 "%% No such neighbor or address family\n");
2533 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
2539 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
2540 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
2541 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
2546 "Display information for a route distinguisher\n"
2547 "VPN Route Distinguisher\n"
2548 "All VPN Route Distinguishers\n"
2549 "Detailed information on TCP and BGP neighbor connections\n"
2550 "Neighbor to display information about\n"
2551 "Display routes learned from neighbor\n"
2554 int idx_ext_community
= 5;
2559 struct prefix_rd prd
;
2560 bool prefix_rd_all
= false;
2561 bool uj
= use_json(argc
, argv
);
2565 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2566 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2567 prefix_rd_all
= true;
2569 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2572 json_object
*json_no
= NULL
;
2573 json_no
= json_object_new_object();
2574 json_object_string_add(
2576 "Malformed Route Distinguisher");
2577 vty_out(vty
, "%s\n",
2578 json_object_to_json_string(
2580 json_object_free(json_no
);
2583 "%% Malformed Route Distinguisher\n");
2588 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2591 json_object
*json_no
= NULL
;
2592 json_no
= json_object_new_object();
2593 json_object_string_add(json_no
, "warning",
2594 "Malformed address");
2595 vty_out(vty
, "%s\n",
2596 json_object_to_json_string(json_no
));
2597 json_object_free(json_no
);
2599 vty_out(vty
, "Malformed address: %s\n",
2600 argv
[idx_ext_community
]->arg
);
2604 peer
= peer_lookup(NULL
, &su
);
2605 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2607 json_object
*json_no
= NULL
;
2608 json_no
= json_object_new_object();
2609 json_object_string_add(
2611 "No such neighbor or address family");
2612 vty_out(vty
, "%s\n",
2613 json_object_to_json_string(json_no
));
2614 json_object_free(json_no
);
2617 "%% No such neighbor or address family\n");
2622 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
2623 bgp_show_type_neighbor
, &su
, 0,
2626 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
2627 bgp_show_type_neighbor
, &su
, 0,
2633 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
2634 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
2635 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2640 "Display information about all VPNv4/VPNv6 NLRIs\n"
2641 "Detailed information on TCP and BGP neighbor connections\n"
2642 "Neighbor to display information about\n"
2643 "Display the routes advertised to a BGP neighbor\n"
2650 bool uj
= use_json(argc
, argv
);
2654 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2655 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2658 json_object
*json_no
= NULL
;
2659 json_no
= json_object_new_object();
2660 json_object_string_add(json_no
, "warning",
2661 "Malformed address");
2662 vty_out(vty
, "%s\n",
2663 json_object_to_json_string(json_no
));
2664 json_object_free(json_no
);
2666 vty_out(vty
, "Malformed address: %s\n",
2667 argv
[idx_ipv4
]->arg
);
2670 peer
= peer_lookup(NULL
, &su
);
2671 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2673 json_object
*json_no
= NULL
;
2674 json_no
= json_object_new_object();
2675 json_object_string_add(
2677 "No such neighbor or address family");
2678 vty_out(vty
, "%s\n",
2679 json_object_to_json_string(json_no
));
2680 json_object_free(json_no
);
2683 "%% No such neighbor or address family\n");
2686 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2692 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
2693 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
2694 "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
2699 "Display information for a route distinguisher\n"
2700 "VPN Route Distinguisher\n"
2701 "All VPN Route Distinguishers\n"
2702 "Detailed information on TCP and BGP neighbor connections\n"
2703 "Neighbor to display information about\n"
2704 "Display the routes advertised to a BGP neighbor\n"
2707 int idx_ext_community
= 5;
2711 struct prefix_rd prd
;
2713 bool uj
= use_json(argc
, argv
);
2717 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
2718 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
2721 json_object
*json_no
= NULL
;
2722 json_no
= json_object_new_object();
2723 json_object_string_add(json_no
, "warning",
2724 "Malformed address");
2725 vty_out(vty
, "%s\n",
2726 json_object_to_json_string(json_no
));
2727 json_object_free(json_no
);
2729 vty_out(vty
, "Malformed address: %s\n",
2730 argv
[idx_ext_community
]->arg
);
2733 peer
= peer_lookup(NULL
, &su
);
2734 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
2736 json_object
*json_no
= NULL
;
2737 json_no
= json_object_new_object();
2738 json_object_string_add(
2740 "No such neighbor or address family");
2741 vty_out(vty
, "%s\n",
2742 json_object_to_json_string(json_no
));
2743 json_object_free(json_no
);
2746 "%% No such neighbor or address family\n");
2750 if (!strcmp(argv
[idx_ext_community
]->arg
, "all"))
2751 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
2753 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
2756 json_object
*json_no
= NULL
;
2757 json_no
= json_object_new_object();
2758 json_object_string_add(
2760 "Malformed Route Distinguisher");
2761 vty_out(vty
, "%s\n",
2762 json_object_to_json_string(json_no
));
2763 json_object_free(json_no
);
2766 "%% Malformed Route Distinguisher\n");
2770 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
2775 #endif /* KEEP_OLD_VPN_COMMANDS */
2777 void bgp_mplsvpn_init(void)
2779 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
2780 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
2781 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
2783 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
2784 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
2786 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
2787 install_element(VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
2788 #ifdef KEEP_OLD_VPN_COMMANDS
2789 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
2790 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
2791 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
2792 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
2793 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
2794 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
2795 install_element(VIEW_NODE
,
2796 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
2797 install_element(VIEW_NODE
,
2798 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
2799 #endif /* KEEP_OLD_VPN_COMMANDS */
2802 vrf_id_t
get_first_vrf_for_redirect_with_rt(struct ecommunity
*eckey
)
2804 struct listnode
*mnode
, *mnnode
;
2808 if (eckey
->unit_size
== IPV6_ECOMMUNITY_SIZE
)
2811 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
2812 struct ecommunity
*ec
;
2814 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2817 ec
= bgp
->vpn_policy
[afi
].import_redirect_rtlist
;
2819 if (ec
&& eckey
->unit_size
!= ec
->unit_size
)
2822 if (ecom_intersect(ec
, eckey
))
2829 * The purpose of this function is to process leaks that were deferred
2830 * from earlier per-vrf configuration due to not-yet-existing default
2831 * vrf, in other words, configuration such as:
2833 * router bgp MMM vrf FOO
2834 * address-family ipv4 unicast
2836 * exit-address-family
2841 * This function gets called when the default instance ("router bgp NNN")
2844 void vpn_leak_postchange_all(void)
2846 struct listnode
*next
;
2848 struct bgp
*bgp_default
= bgp_get_default();
2850 assert(bgp_default
);
2852 /* First, do any exporting from VRFs to the single VPN RIB */
2853 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2855 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2858 vpn_leak_postchange(
2859 BGP_VPN_POLICY_DIR_TOVPN
,
2864 vpn_leak_postchange(
2865 BGP_VPN_POLICY_DIR_TOVPN
,
2871 /* Now, do any importing to VRFs from the single VPN RIB */
2872 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
2874 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2877 vpn_leak_postchange(
2878 BGP_VPN_POLICY_DIR_FROMVPN
,
2883 vpn_leak_postchange(
2884 BGP_VPN_POLICY_DIR_FROMVPN
,
2891 /* When a bgp vrf instance is unconfigured, remove its routes
2892 * from the VPN table and this vrf could be importing routes from other
2893 * bgp vrf instnaces, unimport them.
2894 * VRF X and VRF Y are exporting routes to each other.
2895 * When VRF X is deleted, unimport its routes from all target vrfs,
2896 * also VRF Y should unimport its routes from VRF X table.
2897 * This will ensure VPN table is cleaned up appropriately.
2899 void bgp_vpn_leak_unimport(struct bgp
*from_bgp
)
2902 const char *tmp_name
;
2904 struct listnode
*node
, *next
;
2905 safi_t safi
= SAFI_UNICAST
;
2907 bool is_vrf_leak_bind
;
2910 if (from_bgp
->inst_type
!= BGP_INSTANCE_TYPE_VRF
)
2913 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
2914 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
2916 tmp_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
2918 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
2919 /* vrf leak is for IPv4 and IPv6 Unicast only */
2920 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
2923 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
2924 if (from_bgp
== to_bgp
)
2927 /* Unimport and remove source vrf from the
2928 * other vrfs import list.
2930 struct vpn_policy
*to_vpolicy
;
2932 is_vrf_leak_bind
= false;
2933 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
2934 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
, node
,
2936 if (strcmp(vname
, tmp_name
) == 0) {
2937 is_vrf_leak_bind
= true;
2941 /* skip this bgp instance as there is no leak to this
2944 if (!is_vrf_leak_bind
)
2948 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
2949 __func__
, from_bgp
->name_pretty
,
2950 to_bgp
->name_pretty
, afi2str(afi
),
2951 to_vpolicy
->import_vrf
->count
);
2953 vrf_unimport_from_vrf(to_bgp
, from_bgp
, afi
, safi
);
2955 /* readd vrf name as unimport removes import vrf name
2956 * from the destination vrf's import list where the
2957 * `import vrf` configuration still exist.
2959 vname
= XSTRDUP(MTYPE_TMP
, tmp_name
);
2960 listnode_add(to_bgp
->vpn_policy
[afi
].import_vrf
,
2962 SET_FLAG(to_bgp
->af_flags
[afi
][safi
],
2963 BGP_CONFIG_VRF_TO_VRF_IMPORT
);
2965 /* If to_bgp exports its routes to the bgp vrf
2966 * which is being deleted, un-import the
2967 * to_bgp routes from VPN.
2969 for (ALL_LIST_ELEMENTS_RO(to_bgp
->vpn_policy
[afi
]
2972 if (strcmp(vname
, tmp_name
) == 0) {
2973 vrf_unimport_from_vrf(from_bgp
, to_bgp
,
2983 /* When a router bgp is configured, there could be a bgp vrf
2984 * instance importing routes from this newly configured
2985 * bgp vrf instance. Export routes from configured
2987 * VRF Y has import from bgp vrf x,
2988 * when a bgp vrf x instance is created, export its routes
2989 * to VRF Y instance.
2991 void bgp_vpn_leak_export(struct bgp
*from_bgp
)
2994 const char *export_name
;
2996 struct listnode
*node
, *next
;
2997 struct ecommunity
*ecom
;
2998 vpn_policy_direction_t idir
, edir
;
2999 safi_t safi
= SAFI_UNICAST
;
3003 debug
= (BGP_DEBUG(vpn
, VPN_LEAK_TO_VRF
) |
3004 BGP_DEBUG(vpn
, VPN_LEAK_FROM_VRF
));
3006 idir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3007 edir
= BGP_VPN_POLICY_DIR_TOVPN
;
3009 export_name
= from_bgp
->name
? from_bgp
->name
: VRF_DEFAULT_NAME
;
3011 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3012 /* vrf leak is for IPv4 and IPv6 Unicast only */
3013 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
3016 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, to_bgp
)) {
3017 if (from_bgp
== to_bgp
)
3020 /* bgp instance has import list, check to see if newly
3021 * configured bgp instance is the list.
3023 struct vpn_policy
*to_vpolicy
;
3025 to_vpolicy
= &(to_bgp
->vpn_policy
[afi
]);
3026 for (ALL_LIST_ELEMENTS_RO(to_vpolicy
->import_vrf
,
3028 if (strcmp(vname
, export_name
) != 0)
3032 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
3034 export_name
, to_bgp
->name_pretty
);
3036 ecom
= from_bgp
->vpn_policy
[afi
].rtlist
[edir
];
3037 /* remove import rt, it will be readded
3038 * as part of import from vrf.
3042 to_vpolicy
->rtlist
[idir
],
3043 (struct ecommunity_val
*)
3045 vrf_import_from_vrf(to_bgp
, from_bgp
,