mirror_frr/bgpd/bgp_mplsvpn.h
ryndia cfc5c10160 bgpd: free bgp vpn policy
The bgp vpn policy had some attribute not free when the function bgp_free was called leading to memory leak as shown below.

./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251:Direct leak of 592 byte(s) in 2 object(s) allocated from:
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #0 0x7f4b7ae92037 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #1 0x7f4b7aa96e38 in qcalloc lib/memory.c:105
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #2 0x7f4b7aa9bec9 in srv6_locator_chunk_alloc lib/srv6.c:135
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #3 0x56396f8e56f8 in ensure_vrf_tovpn_sid_per_af bgpd/bgp_mplsvpn.c:752
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #4 0x56396f8e608a in ensure_vrf_tovpn_sid bgpd/bgp_mplsvpn.c:846
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #5 0x56396f8e075d in vpn_leak_postchange bgpd/bgp_mplsvpn.h:259
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #6 0x56396f8f3e5b in vpn_leak_postchange_all bgpd/bgp_mplsvpn.c:3397
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #7 0x56396fa920ef in bgp_zebra_process_srv6_locator_chunk bgpd/bgp_zebra.c:3238
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #8 0x7f4b7abb2913 in zclient_read lib/zclient.c:4134
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #9 0x7f4b7ab62010 in thread_call lib/thread.c:1991
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #10 0x7f4b7aa5a418 in frr_run lib/libfrr.c:1185
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #11 0x56396f7d756d in main bgpd/bgp_main.c:505
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #12 0x7f4b7a479d09 in __libc_start_main ../csu/libc-start.c:308
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251:Direct leak of 32 byte(s) in 2 object(s) allocated from:
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #0 0x7f4b7ae92037 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #1 0x7f4b7aa96e38 in qcalloc lib/memory.c:105
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #2 0x56396f8e31b8 in vpn_leak_zebra_vrf_sid_update_per_af bgpd/bgp_mplsvpn.c:386
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #3 0x56396f8e3ae8 in vpn_leak_zebra_vrf_sid_update bgpd/bgp_mplsvpn.c:448
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #4 0x56396f8e09b0 in vpn_leak_postchange bgpd/bgp_mplsvpn.h:271
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #5 0x56396f8f3e5b in vpn_leak_postchange_all bgpd/bgp_mplsvpn.c:3397
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #6 0x56396fa920ef in bgp_zebra_process_srv6_locator_chunk bgpd/bgp_zebra.c:3238
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #7 0x7f4b7abb2913 in zclient_read lib/zclient.c:4134
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #8 0x7f4b7ab62010 in thread_call lib/thread.c:1991
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #9 0x7f4b7aa5a418 in frr_run lib/libfrr.c:1185
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #10 0x56396f7d756d in main bgpd/bgp_main.c:505
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #11 0x7f4b7a479d09 in __libc_start_main ../csu/libc-start.c:308
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251:Direct leak of 32 byte(s) in 2 object(s) allocated from:
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #0 0x7f4b7ae92037 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #1 0x7f4b7aa96e38 in qcalloc lib/memory.c:105
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #2 0x56396f8e5730 in ensure_vrf_tovpn_sid_per_af bgpd/bgp_mplsvpn.c:753
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #3 0x56396f8e608a in ensure_vrf_tovpn_sid bgpd/bgp_mplsvpn.c:846
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #4 0x56396f8e075d in vpn_leak_postchange bgpd/bgp_mplsvpn.h:259
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #5 0x56396f8f3e5b in vpn_leak_postchange_all bgpd/bgp_mplsvpn.c:3397
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #6 0x56396fa920ef in bgp_zebra_process_srv6_locator_chunk bgpd/bgp_zebra.c:3238
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #7 0x7f4b7abb2913 in zclient_read lib/zclient.c:4134
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #8 0x7f4b7ab62010 in thread_call lib/thread.c:1991
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #9 0x7f4b7aa5a418 in frr_run lib/libfrr.c:1185
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #10 0x56396f7d756d in main bgpd/bgp_main.c:505
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-    #11 0x7f4b7a479d09 in __libc_start_main ../csu/libc-start.c:308
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-
./bgp_srv6l3vpn_to_bgp_vrf.test_bgp_srv6l3vpn_to_bgp_vrf/r2.bgpd.asan.603251-SUMMARY: AddressSanitizer: 656 byte(s) leaked in 6 allocation(s).

Signed-off-by: ryndia <dindyalsarvesh@gmail.com>
2023-07-04 14:59:02 +04:00

404 lines
13 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/* MPLS-VPN
* Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
*
* This file is part of GxNU Zebra.
*/
#ifndef _QUAGGA_BGP_MPLSVPN_H
#define _QUAGGA_BGP_MPLSVPN_H
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_rd.h"
#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_vty.h"
#define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
#define MPLS_LABEL_IS_NULL(label) \
((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \
|| (label) == MPLS_LABEL_IPV6_EXPLICIT_NULL \
|| (label) == MPLS_LABEL_IMPLICIT_NULL)
#define BGP_VPNVX_HELP_STR BGP_AF_STR BGP_AF_STR
#define V4_HEADER \
" Network Next Hop Metric LocPrf Weight Path\n"
#define V4_HEADER_TAG " Network Next Hop In tag/Out tag\n"
#define V4_HEADER_OVERLAY \
" Network Next Hop EthTag Overlay Index RouterMac\n"
#define BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH 20
extern void bgp_mplsvpn_init(void);
extern void bgp_mplsvpn_path_nh_label_unlink(struct bgp_path_info *pi);
extern int bgp_nlri_parse_vpn(struct peer *, struct attr *, struct bgp_nlri *);
extern uint32_t decode_label(mpls_label_t *);
extern void encode_label(mpls_label_t, mpls_label_t *);
extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
int *index, afi_t *afi);
extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
enum bgp_show_type type, void *output_arg,
int tags, bool use_json);
extern void vpn_leak_from_vrf_update(struct bgp *to_bgp, struct bgp *from_bgp,
struct bgp_path_info *path_vrf);
extern void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, struct bgp *from_bgp,
struct bgp_path_info *path_vrf);
extern void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp,
struct bgp *from_bgp, afi_t afi);
extern void vpn_leak_from_vrf_update_all(struct bgp *to_bgp,
struct bgp *from_bgp, afi_t afi);
extern void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi);
extern void vpn_leak_no_retain(struct bgp *to_bgp, struct bgp *vpn_from,
afi_t afi);
extern void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
afi_t afi);
extern bool vpn_leak_to_vrf_no_retain_filter_check(struct bgp *from_bgp,
struct attr *attr,
afi_t afi);
extern void vpn_leak_to_vrf_update(struct bgp *from_bgp,
struct bgp_path_info *path_vpn,
struct prefix_rd *prd);
extern void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn);
extern void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi);
extern void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi);
extern void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi);
extern void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi);
extern void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp);
extern void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi);
extern void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi);
extern void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp);
extern int vpn_leak_label_callback(mpls_label_t label, void *lblid, bool alloc);
extern void ensure_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
extern void delete_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
extern void delete_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
afi_t afi);
extern void delete_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
extern void ensure_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
afi_t afi);
extern void ensure_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
extern void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
uint8_t size);
extern void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
afi_t afi, safi_t safi);
void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
afi_t afi, safi_t safi);
static inline bool is_bgp_vrf_mplsvpn(struct bgp *bgp)
{
afi_t afi;
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
for (afi = 0; afi < AFI_MAX; ++afi) {
if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
|| CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT))
return true;
}
return false;
}
static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
const char **pmsg)
{
if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
&& bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
if (pmsg)
*pmsg = "source bgp instance neither vrf nor default";
return 0;
}
/* Is vrf configured to export to vpn? */
if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
&& !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
if (pmsg)
*pmsg = "export not set";
return 0;
}
/* Is there an RT list set? */
if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
if (pmsg)
*pmsg = "rtlist tovpn not defined";
return 0;
}
/* Is there an RD set? */
if (!CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_RD_SET)) {
if (pmsg)
*pmsg = "rd not defined";
return 0;
}
/* Is a route-map specified, but not defined? */
if (bgp_vrf->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN] &&
!bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
if (pmsg)
*pmsg = "route-map tovpn named but not defined";
return 0;
}
/* Is there an "auto" export label that isn't allocated yet? */
if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
(bgp_vrf->vpn_policy[afi].tovpn_label == MPLS_LABEL_NONE)) {
if (pmsg)
*pmsg = "auto label not allocated";
return 0;
}
return 1;
}
static inline int vpn_leak_from_vpn_active(struct bgp *bgp_vrf, afi_t afi,
const char **pmsg)
{
if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
&& bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
if (pmsg)
*pmsg = "destination bgp instance neither vrf nor default";
return 0;
}
if (bgp_vrf->vrf_id == VRF_UNKNOWN) {
if (pmsg)
*pmsg = "destination bgp instance vrf is VRF_UNKNOWN";
return 0;
}
/* Is vrf configured to import from vpn? */
if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)
&& !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
if (pmsg)
*pmsg = "import not set";
return 0;
}
/* Is there an RT list set? */
if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) {
if (pmsg)
*pmsg = "rtlist fromvpn not defined";
return 0;
}
/* Is a route-map specified, but not defined? */
if (bgp_vrf->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN] &&
!bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
if (pmsg)
*pmsg = "route-map fromvpn named but not defined";
return 0;
}
return 1;
}
static inline void vpn_leak_prechange(enum vpn_policy_direction direction,
afi_t afi, struct bgp *bgp_vpn,
struct bgp *bgp_vrf)
{
/* Detect when default bgp instance is not (yet) defined by config */
if (!bgp_vpn)
return;
if ((direction == BGP_VPN_POLICY_DIR_FROMVPN) &&
vpn_leak_from_vpn_active(bgp_vrf, afi, NULL)) {
vpn_leak_to_vrf_withdraw_all(bgp_vrf, afi);
}
if ((direction == BGP_VPN_POLICY_DIR_TOVPN) &&
vpn_leak_to_vpn_active(bgp_vrf, afi, NULL)) {
vpn_leak_from_vrf_withdraw_all(bgp_vpn, bgp_vrf, afi);
}
}
static inline void vpn_leak_postchange(enum vpn_policy_direction direction,
afi_t afi, struct bgp *bgp_vpn,
struct bgp *bgp_vrf)
{
/* Detect when default bgp instance is not (yet) defined by config */
if (!bgp_vpn)
return;
if (direction == BGP_VPN_POLICY_DIR_FROMVPN) {
/* trigger a flush to re-sync with ADJ-RIB-in */
if (!CHECK_FLAG(bgp_vpn->af_flags[afi][SAFI_MPLS_VPN],
BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL))
bgp_clear_soft_in(bgp_vpn, afi, SAFI_MPLS_VPN);
else
vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi);
}
if (direction == BGP_VPN_POLICY_DIR_TOVPN) {
if (bgp_vrf->vpn_policy[afi].tovpn_label !=
bgp_vrf->vpn_policy[afi]
.tovpn_zebra_vrf_label_last_sent) {
vpn_leak_zebra_vrf_label_update(bgp_vrf, afi);
}
if (bgp_vrf->vpn_policy[afi].tovpn_sid_index == 0 &&
!CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_SID_AUTO) &&
bgp_vrf->tovpn_sid_index == 0 &&
!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_AUTO))
delete_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
if (!bgp_vrf->vpn_policy[afi].tovpn_sid && !bgp_vrf->tovpn_sid)
ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
if ((!bgp_vrf->vpn_policy[afi].tovpn_sid &&
bgp_vrf->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent) ||
(!bgp_vrf->tovpn_sid &&
bgp_vrf->tovpn_zebra_vrf_sid_last_sent))
vpn_leak_zebra_vrf_sid_withdraw(bgp_vrf, afi);
if (bgp_vrf->vpn_policy[afi].tovpn_sid) {
if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
bgp_vrf->vpn_policy[afi]
.tovpn_zebra_vrf_sid_last_sent)) {
vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
}
} else if (bgp_vrf->tovpn_sid) {
if (sid_diff(bgp_vrf->tovpn_sid,
bgp_vrf->tovpn_zebra_vrf_sid_last_sent)) {
vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
}
}
vpn_leak_from_vrf_update_all(bgp_vpn, bgp_vrf, afi);
}
}
/* Flag if the route is injectable into VPN. This would be either a
* non-imported route or a non-VPN imported route.
*/
static inline bool is_route_injectable_into_vpn(struct bgp_path_info *pi)
{
struct bgp_path_info *parent_pi;
struct bgp_table *table;
struct bgp_dest *dest;
if (pi->sub_type != BGP_ROUTE_IMPORTED ||
!pi->extra ||
!pi->extra->parent)
return true;
parent_pi = (struct bgp_path_info *)pi->extra->parent;
dest = parent_pi->net;
if (!dest)
return true;
table = bgp_dest_table(dest);
if (table &&
(table->afi == AFI_IP || table->afi == AFI_IP6) &&
table->safi == SAFI_MPLS_VPN)
return false;
return true;
}
/* Flag if the route path's family is VPN. */
static inline bool is_pi_family_vpn(struct bgp_path_info *pi)
{
return (is_pi_family_matching(pi, AFI_IP, SAFI_MPLS_VPN) ||
is_pi_family_matching(pi, AFI_IP6, SAFI_MPLS_VPN));
}
extern void vpn_policy_routemap_event(const char *rmap_name);
extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
extern void vpn_leak_postchange_all(void);
extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
bool is_config);
extern void bgp_vpn_leak_unimport(struct bgp *from_bgp);
extern void bgp_vpn_leak_export(struct bgp *from_bgp);
extern bool bgp_mplsvpn_path_uses_valid_mpls_label(struct bgp_path_info *pi);
extern int
bgp_mplsvpn_nh_label_bind_cmp(const struct bgp_mplsvpn_nh_label_bind_cache *a,
const struct bgp_mplsvpn_nh_label_bind_cache *b);
extern void bgp_mplsvpn_path_nh_label_bind_unlink(struct bgp_path_info *pi);
extern void bgp_mplsvpn_nh_label_bind_register_local_label(
struct bgp *bgp, struct bgp_dest *dest, struct bgp_path_info *pi);
mpls_label_t bgp_mplsvpn_nh_label_bind_get_label(struct bgp_path_info *pi);
/* used to bind a local label to the (label, nexthop) values
* from an incoming BGP mplsvpn update
*/
struct bgp_mplsvpn_nh_label_bind_cache {
/* RB-tree entry. */
struct bgp_mplsvpn_nh_label_bind_cache_item entry;
/* The nexthop and the vpn label are the key of the list.
* Only received BGP MPLSVPN updates may use that structure.
* orig_label is the original label received from the BGP Update.
*/
struct prefix nexthop;
mpls_label_t orig_label;
/* resolved interface for the paths */
struct nexthop *nh;
/* number of mplsvpn path */
unsigned int path_count;
/* back pointer to bgp instance */
struct bgp *bgp_vpn;
/* MPLS label allocated value.
* When the next-hop is changed because of 'next-hop-self' or
* because it is an eBGP peer, the redistributed orig_label value
* is unmodified, unless the 'l3vpn-multi-domain-switching'
* is enabled: a new_label value is allocated:
* - The new_label value is sent in the advertised BGP update,
* instead of the label value.
* - An MPLS entry is set to swap <new_label> with <orig_label>.
*/
mpls_label_t new_label;
/* list of path_vrfs using it */
LIST_HEAD(mplsvpn_nh_label_bind_path_lists, bgp_path_info) paths;
time_t last_update;
bool allocation_in_progress;
};
DECLARE_RBTREE_UNIQ(bgp_mplsvpn_nh_label_bind_cache,
struct bgp_mplsvpn_nh_label_bind_cache, entry,
bgp_mplsvpn_nh_label_bind_cmp);
void bgp_mplsvpn_nh_label_bind_free(
struct bgp_mplsvpn_nh_label_bind_cache *bmnc);
struct bgp_mplsvpn_nh_label_bind_cache *
bgp_mplsvpn_nh_label_bind_new(struct bgp_mplsvpn_nh_label_bind_cache_head *tree,
struct prefix *p, mpls_label_t orig_label);
struct bgp_mplsvpn_nh_label_bind_cache *bgp_mplsvpn_nh_label_bind_find(
struct bgp_mplsvpn_nh_label_bind_cache_head *tree, struct prefix *p,
mpls_label_t orig_label);
void bgp_mplsvpn_nexthop_init(void);
extern void sid_unregister(struct bgp *bgp, const struct in6_addr *sid);
#endif /* _QUAGGA_BGP_MPLSVPN_H */