mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-17 02:22:17 +00:00
Merge branch 'master' into frr-bgp_cli
This commit is contained in:
commit
2531163802
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@
|
|||||||
/config.status
|
/config.status
|
||||||
/config.guess
|
/config.guess
|
||||||
/config.sub
|
/config.sub
|
||||||
|
/config.version
|
||||||
/ltmain.sh
|
/ltmain.sh
|
||||||
/stamp-h
|
/stamp-h
|
||||||
/stamp-h[0-9]*
|
/stamp-h[0-9]*
|
||||||
|
16
Makefile.am
16
Makefile.am
@ -4,6 +4,7 @@ AUTOMAKE_OPTIONS = subdir-objects 1.12
|
|||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
AM_CFLAGS = \
|
AM_CFLAGS = \
|
||||||
|
$(UNWIND_CFLAGS) \
|
||||||
$(SAN_FLAGS) \
|
$(SAN_FLAGS) \
|
||||||
$(WERROR) \
|
$(WERROR) \
|
||||||
# end
|
# end
|
||||||
@ -18,6 +19,10 @@ AM_LDFLAGS = \
|
|||||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
|
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
|
||||||
LIBCAP = @LIBCAP@
|
LIBCAP = @LIBCAP@
|
||||||
|
|
||||||
|
AR_FLAGS = @AR_FLAGS@
|
||||||
|
ARFLAGS = @ARFLAGS@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
|
||||||
# these two targets are provided to easily grab autoconf/Makefile variables
|
# these two targets are provided to easily grab autoconf/Makefile variables
|
||||||
# you can use either:
|
# you can use either:
|
||||||
# eval `make VARFD=3 shvar-CFLAGS 3>&1 1>&2`
|
# eval `make VARFD=3 shvar-CFLAGS 3>&1 1>&2`
|
||||||
@ -77,6 +82,7 @@ var-%:
|
|||||||
EXTRA_DIST =
|
EXTRA_DIST =
|
||||||
BUILT_SOURCES =
|
BUILT_SOURCES =
|
||||||
CLEANFILES =
|
CLEANFILES =
|
||||||
|
DISTCLEANFILES =
|
||||||
|
|
||||||
examplesdir = $(exampledir)
|
examplesdir = $(exampledir)
|
||||||
|
|
||||||
@ -156,6 +162,7 @@ EXTRA_DIST += \
|
|||||||
README.md \
|
README.md \
|
||||||
m4/README.txt \
|
m4/README.txt \
|
||||||
m4/libtool-whole-archive.patch \
|
m4/libtool-whole-archive.patch \
|
||||||
|
config.version \
|
||||||
\
|
\
|
||||||
python/clidef.py \
|
python/clidef.py \
|
||||||
python/clippy/__init__.py \
|
python/clippy/__init__.py \
|
||||||
@ -210,6 +217,15 @@ EXTRA_DIST += \
|
|||||||
|
|
||||||
noinst_HEADERS += defaults.h
|
noinst_HEADERS += defaults.h
|
||||||
|
|
||||||
|
clean-local: clean-python
|
||||||
|
.PHONY: clean-python
|
||||||
|
clean-python:
|
||||||
|
find -name __pycache__ -o -name .pytest_cache | xargs rm -rf
|
||||||
|
find -name "*.pyc" -o -name "*_clippy.c" | xargs rm -f
|
||||||
|
|
||||||
|
redistclean:
|
||||||
|
$(MAKE) distclean CONFIG_CLEAN_FILES="$(filter-out $(EXTRA_DIST), $(CONFIG_CLEAN_FILES))"
|
||||||
|
|
||||||
indent:
|
indent:
|
||||||
tools/indent.py `find sharpd bgpd eigrpd include isisd lib nhrpd ospf6d ospfd pimd qpb ripd vtysh zebra -name '*.[ch]' | grep -v include/linux`
|
tools/indent.py `find sharpd bgpd eigrpd include isisd lib nhrpd ospf6d ospfd pimd qpb ripd vtysh zebra -name '*.[ch]' | grep -v include/linux`
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ THE SOFTWARE.
|
|||||||
#define CONFIG_NO 1
|
#define CONFIG_NO 1
|
||||||
#define CONFIG_YES 2
|
#define CONFIG_YES 2
|
||||||
|
|
||||||
/* babeld interface informations */
|
/* babeld interface information */
|
||||||
struct babel_interface {
|
struct babel_interface {
|
||||||
unsigned short flags; /* see below */
|
unsigned short flags; /* see below */
|
||||||
unsigned short cost;
|
unsigned short cost;
|
||||||
|
@ -385,7 +385,7 @@ show_babel_main_configuration (struct vty *vty)
|
|||||||
vty_out (vty,
|
vty_out (vty,
|
||||||
"state file = %s\n"
|
"state file = %s\n"
|
||||||
"configuration file = %s\n"
|
"configuration file = %s\n"
|
||||||
"protocol informations:\n"
|
"protocol information:\n"
|
||||||
" multicast address = %s\n"
|
" multicast address = %s\n"
|
||||||
" port = %d\n"
|
" port = %d\n"
|
||||||
"vty address = %s\n"
|
"vty address = %s\n"
|
||||||
|
17
bfdd/bfd.c
17
bfdd/bfd.c
@ -861,15 +861,10 @@ static struct hash *bfd_vrf_hash;
|
|||||||
static struct hash *bfd_iface_hash;
|
static struct hash *bfd_iface_hash;
|
||||||
|
|
||||||
static unsigned int bfd_id_hash_do(void *p);
|
static unsigned int bfd_id_hash_do(void *p);
|
||||||
static int bfd_id_hash_cmp(const void *n1, const void *n2);
|
|
||||||
static unsigned int bfd_shop_hash_do(void *p);
|
static unsigned int bfd_shop_hash_do(void *p);
|
||||||
static int bfd_shop_hash_cmp(const void *n1, const void *n2);
|
|
||||||
static unsigned int bfd_mhop_hash_do(void *p);
|
static unsigned int bfd_mhop_hash_do(void *p);
|
||||||
static int bfd_mhop_hash_cmp(const void *n1, const void *n2);
|
|
||||||
static unsigned int bfd_vrf_hash_do(void *p);
|
static unsigned int bfd_vrf_hash_do(void *p);
|
||||||
static int bfd_vrf_hash_cmp(const void *n1, const void *n2);
|
|
||||||
static unsigned int bfd_iface_hash_do(void *p);
|
static unsigned int bfd_iface_hash_do(void *p);
|
||||||
static int bfd_iface_hash_cmp(const void *n1, const void *n2);
|
|
||||||
|
|
||||||
static void _shop_key(struct bfd_session *bs, const struct bfd_shop_key *shop);
|
static void _shop_key(struct bfd_session *bs, const struct bfd_shop_key *shop);
|
||||||
static void _shop_key2(struct bfd_session *bs, const struct bfd_shop_key *shop);
|
static void _shop_key2(struct bfd_session *bs, const struct bfd_shop_key *shop);
|
||||||
@ -889,7 +884,7 @@ static unsigned int bfd_id_hash_do(void *p)
|
|||||||
return jhash_1word(bs->discrs.my_discr, 0);
|
return jhash_1word(bs->discrs.my_discr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bfd_id_hash_cmp(const void *n1, const void *n2)
|
static bool bfd_id_hash_cmp(const void *n1, const void *n2)
|
||||||
{
|
{
|
||||||
const struct bfd_session *bs1 = n1, *bs2 = n2;
|
const struct bfd_session *bs1 = n1, *bs2 = n2;
|
||||||
|
|
||||||
@ -904,7 +899,7 @@ static unsigned int bfd_shop_hash_do(void *p)
|
|||||||
return jhash(&bs->shop, sizeof(bs->shop), 0);
|
return jhash(&bs->shop, sizeof(bs->shop), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bfd_shop_hash_cmp(const void *n1, const void *n2)
|
static bool bfd_shop_hash_cmp(const void *n1, const void *n2)
|
||||||
{
|
{
|
||||||
const struct bfd_session *bs1 = n1, *bs2 = n2;
|
const struct bfd_session *bs1 = n1, *bs2 = n2;
|
||||||
|
|
||||||
@ -919,7 +914,7 @@ static unsigned int bfd_mhop_hash_do(void *p)
|
|||||||
return jhash(&bs->mhop, sizeof(bs->mhop), 0);
|
return jhash(&bs->mhop, sizeof(bs->mhop), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bfd_mhop_hash_cmp(const void *n1, const void *n2)
|
static bool bfd_mhop_hash_cmp(const void *n1, const void *n2)
|
||||||
{
|
{
|
||||||
const struct bfd_session *bs1 = n1, *bs2 = n2;
|
const struct bfd_session *bs1 = n1, *bs2 = n2;
|
||||||
|
|
||||||
@ -934,7 +929,7 @@ static unsigned int bfd_vrf_hash_do(void *p)
|
|||||||
return jhash_1word(vrf->vrf_id, 0);
|
return jhash_1word(vrf->vrf_id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bfd_vrf_hash_cmp(const void *n1, const void *n2)
|
static bool bfd_vrf_hash_cmp(const void *n1, const void *n2)
|
||||||
{
|
{
|
||||||
const struct bfd_vrf *v1 = n1, *v2 = n2;
|
const struct bfd_vrf *v1 = n1, *v2 = n2;
|
||||||
|
|
||||||
@ -949,7 +944,7 @@ static unsigned int bfd_iface_hash_do(void *p)
|
|||||||
return string_hash_make(iface->ifname);
|
return string_hash_make(iface->ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bfd_iface_hash_cmp(const void *n1, const void *n2)
|
static bool bfd_iface_hash_cmp(const void *n1, const void *n2)
|
||||||
{
|
{
|
||||||
const struct bfd_iface *i1 = n1, *i2 = n2;
|
const struct bfd_iface *i1 = n1, *i2 = n2;
|
||||||
|
|
||||||
@ -1045,7 +1040,7 @@ struct bfd_session *bfd_mhop_lookup(struct bfd_mhop_key mhop)
|
|||||||
|
|
||||||
_mhop_key(&bs, &mhop);
|
_mhop_key(&bs, &mhop);
|
||||||
|
|
||||||
return hash_lookup(bfd_shop_hash, &bs);
|
return hash_lookup(bfd_mhop_hash, &bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bfd_vrf *bfd_vrf_lookup(int vrf_id)
|
struct bfd_vrf *bfd_vrf_lookup(int vrf_id)
|
||||||
|
@ -90,7 +90,7 @@ DEFUN_NOSH(bfd_enter, bfd_enter_cmd, "bfd", "Configure BFD peers\n")
|
|||||||
|
|
||||||
DEFUN_NOSH(
|
DEFUN_NOSH(
|
||||||
bfd_peer_enter, bfd_peer_enter_cmd,
|
bfd_peer_enter, bfd_peer_enter_cmd,
|
||||||
"peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
|
"peer <A.B.C.D|X:X::X:X> [{[multihop] local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
|
||||||
PEER_STR PEER_IPV4_STR PEER_IPV6_STR
|
PEER_STR PEER_IPV4_STR PEER_IPV6_STR
|
||||||
MHOP_STR
|
MHOP_STR
|
||||||
LOCAL_STR LOCAL_IPV4_STR LOCAL_IPV6_STR
|
LOCAL_STR LOCAL_IPV4_STR LOCAL_IPV6_STR
|
||||||
|
@ -104,8 +104,8 @@ bgp_route.[hc]:
|
|||||||
looking for data in hash table, and putting there if missing, refcnt
|
looking for data in hash table, and putting there if missing, refcnt
|
||||||
using pointer to existing data
|
using pointer to existing data
|
||||||
many validity checks
|
many validity checks
|
||||||
get new struct bgp_info (10 words/40 bytes)
|
get new struct bgp_path_info
|
||||||
call bgp_info_add with rn and bgp_info
|
call bgp_path_info_add with rn and bgp_path_info
|
||||||
call bgp_process
|
call bgp_process
|
||||||
|
|
||||||
bgp_routemap.c
|
bgp_routemap.c
|
||||||
@ -149,7 +149,7 @@ bgpd.c
|
|||||||
Question: How much memory does quagga's bgpd use as a function of
|
Question: How much memory does quagga's bgpd use as a function of
|
||||||
state received from peers?
|
state received from peers?
|
||||||
|
|
||||||
It seems that a struct bgp_info is kept for each prefix. The "struct
|
It seems that a struct bgp_path_info is kept for each prefix. The "struct
|
||||||
attr *" is interned, and variables within that are interned. So, 40
|
attr *" is interned, and variables within that are interned. So, 40
|
||||||
bytes are kept per received prefix, plus interned shared values. This
|
bytes are kept per received prefix, plus interned shared values. This
|
||||||
could be 36 if 'int suppress' where changed to a u_char and moved to
|
could be 36 if 'int suppress' where changed to a u_char and moved to
|
||||||
|
@ -71,7 +71,7 @@ unsigned int baa_hash_key(void *p)
|
|||||||
return attrhash_key_make(baa->attr);
|
return attrhash_key_make(baa->attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int baa_hash_cmp(const void *p1, const void *p2)
|
bool baa_hash_cmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct bgp_advertise_attr *baa1 = p1;
|
const struct bgp_advertise_attr *baa1 = p1;
|
||||||
const struct bgp_advertise_attr *baa2 = p2;
|
const struct bgp_advertise_attr *baa2 = p2;
|
||||||
@ -90,9 +90,9 @@ struct bgp_advertise *bgp_advertise_new(void)
|
|||||||
|
|
||||||
void bgp_advertise_free(struct bgp_advertise *adv)
|
void bgp_advertise_free(struct bgp_advertise *adv)
|
||||||
{
|
{
|
||||||
if (adv->binfo)
|
if (adv->pathi)
|
||||||
bgp_info_unlock(
|
/* bgp_advertise bgp_path_info reference */
|
||||||
adv->binfo); /* bgp_advertise bgp_info reference */
|
bgp_path_info_unlock(adv->pathi);
|
||||||
XFREE(MTYPE_BGP_ADVERTISE, adv);
|
XFREE(MTYPE_BGP_ADVERTISE, adv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ struct bgp_advertise {
|
|||||||
struct bgp_advertise_attr *baa;
|
struct bgp_advertise_attr *baa;
|
||||||
|
|
||||||
/* BGP info. */
|
/* BGP info. */
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *pathi;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BGP adjacency out. */
|
/* BGP adjacency out. */
|
||||||
@ -113,7 +113,7 @@ struct bgp_synchronize {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* BGP adjacency linked list. */
|
/* BGP adjacency linked list. */
|
||||||
#define BGP_INFO_ADD(N, A, TYPE) \
|
#define BGP_PATH_INFO_ADD(N, A, TYPE) \
|
||||||
do { \
|
do { \
|
||||||
(A)->prev = NULL; \
|
(A)->prev = NULL; \
|
||||||
(A)->next = (N)->TYPE; \
|
(A)->next = (N)->TYPE; \
|
||||||
@ -122,7 +122,7 @@ struct bgp_synchronize {
|
|||||||
(N)->TYPE = (A); \
|
(N)->TYPE = (A); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define BGP_INFO_DEL(N, A, TYPE) \
|
#define BGP_PATH_INFO_DEL(N, A, TYPE) \
|
||||||
do { \
|
do { \
|
||||||
if ((A)->next) \
|
if ((A)->next) \
|
||||||
(A)->next->prev = (A)->prev; \
|
(A)->next->prev = (A)->prev; \
|
||||||
@ -132,10 +132,10 @@ struct bgp_synchronize {
|
|||||||
(N)->TYPE = (A)->next; \
|
(N)->TYPE = (A)->next; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define BGP_ADJ_IN_ADD(N,A) BGP_INFO_ADD(N,A,adj_in)
|
#define BGP_ADJ_IN_ADD(N, A) BGP_PATH_INFO_ADD(N, A, adj_in)
|
||||||
#define BGP_ADJ_IN_DEL(N,A) BGP_INFO_DEL(N,A,adj_in)
|
#define BGP_ADJ_IN_DEL(N, A) BGP_PATH_INFO_DEL(N, A, adj_in)
|
||||||
#define BGP_ADJ_OUT_ADD(N,A) BGP_INFO_ADD(N,A,adj_out)
|
#define BGP_ADJ_OUT_ADD(N, A) BGP_PATH_INFO_ADD(N, A, adj_out)
|
||||||
#define BGP_ADJ_OUT_DEL(N,A) BGP_INFO_DEL(N,A,adj_out)
|
#define BGP_ADJ_OUT_DEL(N, A) BGP_PATH_INFO_DEL(N, A, adj_out)
|
||||||
|
|
||||||
#define BGP_ADV_FIFO_ADD(F, N) \
|
#define BGP_ADV_FIFO_ADD(F, N) \
|
||||||
do { \
|
do { \
|
||||||
@ -177,7 +177,7 @@ extern void bgp_adj_in_remove(struct bgp_node *, struct bgp_adj_in *);
|
|||||||
extern void bgp_sync_init(struct peer *);
|
extern void bgp_sync_init(struct peer *);
|
||||||
extern void bgp_sync_delete(struct peer *);
|
extern void bgp_sync_delete(struct peer *);
|
||||||
extern unsigned int baa_hash_key(void *p);
|
extern unsigned int baa_hash_key(void *p);
|
||||||
extern int baa_hash_cmp(const void *p1, const void *p2);
|
extern bool baa_hash_cmp(const void *p1, const void *p2);
|
||||||
extern void bgp_advertise_add(struct bgp_advertise_attr *baa,
|
extern void bgp_advertise_add(struct bgp_advertise_attr *baa,
|
||||||
struct bgp_advertise *adv);
|
struct bgp_advertise *adv);
|
||||||
extern struct bgp_advertise *bgp_advertise_new(void);
|
extern struct bgp_advertise *bgp_advertise_new(void);
|
||||||
|
@ -1726,23 +1726,23 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath,
|
|||||||
/* Compare leftmost AS value for MED check. If as1's leftmost AS and
|
/* Compare leftmost AS value for MED check. If as1's leftmost AS and
|
||||||
as2's leftmost AS is same return 1. (confederation as-path
|
as2's leftmost AS is same return 1. (confederation as-path
|
||||||
only). */
|
only). */
|
||||||
int aspath_cmp_left_confed(const struct aspath *aspath1,
|
bool aspath_cmp_left_confed(const struct aspath *aspath1,
|
||||||
const struct aspath *aspath2)
|
const struct aspath *aspath2)
|
||||||
{
|
{
|
||||||
if (!(aspath1 && aspath2))
|
if (!(aspath1 && aspath2))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (!(aspath1->segments && aspath2->segments))
|
if (!(aspath1->segments && aspath2->segments))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((aspath1->segments->type != AS_CONFED_SEQUENCE)
|
if ((aspath1->segments->type != AS_CONFED_SEQUENCE)
|
||||||
|| (aspath2->segments->type != AS_CONFED_SEQUENCE))
|
|| (aspath2->segments->type != AS_CONFED_SEQUENCE))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (aspath1->segments->as[0] == aspath2->segments->as[0])
|
if (aspath1->segments->as[0] == aspath2->segments->as[0])
|
||||||
return 1;
|
return true;
|
||||||
|
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete all AS_CONFED_SEQUENCE/SET segments from aspath.
|
/* Delete all AS_CONFED_SEQUENCE/SET segments from aspath.
|
||||||
@ -2008,7 +2008,7 @@ unsigned int aspath_key_make(void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If two aspath have same value then return 1 else return 0 */
|
/* If two aspath have same value then return 1 else return 0 */
|
||||||
int aspath_cmp(const void *arg1, const void *arg2)
|
bool aspath_cmp(const void *arg1, const void *arg2)
|
||||||
{
|
{
|
||||||
const struct assegment *seg1 = ((const struct aspath *)arg1)->segments;
|
const struct assegment *seg1 = ((const struct aspath *)arg1)->segments;
|
||||||
const struct assegment *seg2 = ((const struct aspath *)arg2)->segments;
|
const struct assegment *seg2 = ((const struct aspath *)arg2)->segments;
|
||||||
@ -2016,18 +2016,18 @@ int aspath_cmp(const void *arg1, const void *arg2)
|
|||||||
while (seg1 || seg2) {
|
while (seg1 || seg2) {
|
||||||
int i;
|
int i;
|
||||||
if ((!seg1 && seg2) || (seg1 && !seg2))
|
if ((!seg1 && seg2) || (seg1 && !seg2))
|
||||||
return 0;
|
return false;
|
||||||
if (seg1->type != seg2->type)
|
if (seg1->type != seg2->type)
|
||||||
return 0;
|
return false;
|
||||||
if (seg1->length != seg2->length)
|
if (seg1->length != seg2->length)
|
||||||
return 0;
|
return false;
|
||||||
for (i = 0; i < seg1->length; i++)
|
for (i = 0; i < seg1->length; i++)
|
||||||
if (seg1->as[i] != seg2->as[i])
|
if (seg1->as[i] != seg2->as[i])
|
||||||
return 0;
|
return false;
|
||||||
seg1 = seg1->next;
|
seg1 = seg1->next;
|
||||||
seg2 = seg2->next;
|
seg2 = seg2->next;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AS path hash initialize. */
|
/* AS path hash initialize. */
|
||||||
|
@ -85,9 +85,10 @@ extern struct aspath *aspath_filter_exclude(struct aspath *, struct aspath *);
|
|||||||
extern struct aspath *aspath_add_seq_n(struct aspath *, as_t, unsigned);
|
extern struct aspath *aspath_add_seq_n(struct aspath *, as_t, unsigned);
|
||||||
extern struct aspath *aspath_add_seq(struct aspath *, as_t);
|
extern struct aspath *aspath_add_seq(struct aspath *, as_t);
|
||||||
extern struct aspath *aspath_add_confed_seq(struct aspath *, as_t);
|
extern struct aspath *aspath_add_confed_seq(struct aspath *, as_t);
|
||||||
extern int aspath_cmp(const void *, const void *);
|
extern bool aspath_cmp(const void *as1, const void *as2);
|
||||||
extern int aspath_cmp_left(const struct aspath *, const struct aspath *);
|
extern int aspath_cmp_left(const struct aspath *, const struct aspath *);
|
||||||
extern int aspath_cmp_left_confed(const struct aspath *, const struct aspath *);
|
extern bool aspath_cmp_left_confed(const struct aspath *as1,
|
||||||
|
const struct aspath *as2xs);
|
||||||
extern struct aspath *aspath_delete_confed_seq(struct aspath *);
|
extern struct aspath *aspath_delete_confed_seq(struct aspath *);
|
||||||
extern struct aspath *aspath_empty(void);
|
extern struct aspath *aspath_empty(void);
|
||||||
extern struct aspath *aspath_empty_get(void);
|
extern struct aspath *aspath_empty_get(void);
|
||||||
|
@ -146,7 +146,7 @@ static unsigned int cluster_hash_key_make(void *p)
|
|||||||
return jhash(cluster->list, cluster->length, 0);
|
return jhash(cluster->list, cluster->length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cluster_hash_cmp(const void *p1, const void *p2)
|
static bool cluster_hash_cmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct cluster_list *cluster1 = p1;
|
const struct cluster_list *cluster1 = p1;
|
||||||
const struct cluster_list *cluster2 = p2;
|
const struct cluster_list *cluster2 = p2;
|
||||||
@ -355,7 +355,7 @@ static unsigned int encap_hash_key_make(void *p)
|
|||||||
return jhash(encap->value, encap->length, 0);
|
return jhash(encap->value, encap->length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encap_hash_cmp(const void *p1, const void *p2)
|
static bool encap_hash_cmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
return encap_same((const struct bgp_attr_encap_subtlv *)p1,
|
return encap_same((const struct bgp_attr_encap_subtlv *)p1,
|
||||||
(const struct bgp_attr_encap_subtlv *)p2);
|
(const struct bgp_attr_encap_subtlv *)p2);
|
||||||
@ -441,7 +441,7 @@ static unsigned int transit_hash_key_make(void *p)
|
|||||||
return jhash(transit->val, transit->length, 0);
|
return jhash(transit->val, transit->length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int transit_hash_cmp(const void *p1, const void *p2)
|
static bool transit_hash_cmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct transit *transit1 = p1;
|
const struct transit *transit1 = p1;
|
||||||
const struct transit *transit2 = p2;
|
const struct transit *transit2 = p2;
|
||||||
@ -527,7 +527,7 @@ unsigned int attrhash_key_make(void *p)
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int attrhash_cmp(const void *p1, const void *p2)
|
bool attrhash_cmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct attr *attr1 = p1;
|
const struct attr *attr1 = p1;
|
||||||
const struct attr *attr2 = p2;
|
const struct attr *attr2 = p2;
|
||||||
@ -565,10 +565,10 @@ int attrhash_cmp(const void *p1, const void *p2)
|
|||||||
&& overlay_index_same(attr1, attr2)
|
&& overlay_index_same(attr1, attr2)
|
||||||
&& attr1->nh_ifindex == attr2->nh_ifindex
|
&& attr1->nh_ifindex == attr2->nh_ifindex
|
||||||
&& attr1->nh_lla_ifindex == attr2->nh_lla_ifindex)
|
&& attr1->nh_lla_ifindex == attr2->nh_lla_ifindex)
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void attrhash_init(void)
|
static void attrhash_init(void)
|
||||||
@ -723,8 +723,10 @@ struct attr *bgp_attr_default_set(struct attr *attr, uint8_t origin)
|
|||||||
/* Create the attributes for an aggregate */
|
/* Create the attributes for an aggregate */
|
||||||
struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
|
struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
|
||||||
struct aspath *aspath,
|
struct aspath *aspath,
|
||||||
struct community *community, int as_set,
|
struct community *community,
|
||||||
uint8_t atomic_aggregate)
|
struct ecommunity *ecommunity,
|
||||||
|
struct lcommunity *lcommunity,
|
||||||
|
int as_set, uint8_t atomic_aggregate)
|
||||||
{
|
{
|
||||||
struct attr attr;
|
struct attr attr;
|
||||||
struct attr *new;
|
struct attr *new;
|
||||||
@ -760,6 +762,16 @@ struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
|
|||||||
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
|
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ecommunity) {
|
||||||
|
attr.ecommunity = ecommunity;
|
||||||
|
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcommunity) {
|
||||||
|
attr.lcommunity = lcommunity;
|
||||||
|
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
|
||||||
|
}
|
||||||
|
|
||||||
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||||
bgp_attr_add_gshut_community(&attr);
|
bgp_attr_add_gshut_community(&attr);
|
||||||
}
|
}
|
||||||
@ -837,7 +849,7 @@ void bgp_attr_undup(struct attr *new, struct attr *old)
|
|||||||
aspath_free(new->aspath);
|
aspath_free(new->aspath);
|
||||||
|
|
||||||
if (new->community != old->community)
|
if (new->community != old->community)
|
||||||
community_free(new->community);
|
community_free(&new->community);
|
||||||
|
|
||||||
if (new->ecommunity != old->ecommunity)
|
if (new->ecommunity != old->ecommunity)
|
||||||
ecommunity_free(&new->ecommunity);
|
ecommunity_free(&new->ecommunity);
|
||||||
@ -875,11 +887,8 @@ void bgp_attr_flush(struct attr *attr)
|
|||||||
aspath_free(attr->aspath);
|
aspath_free(attr->aspath);
|
||||||
attr->aspath = NULL;
|
attr->aspath = NULL;
|
||||||
}
|
}
|
||||||
if (attr->community && !attr->community->refcnt) {
|
if (attr->community && !attr->community->refcnt)
|
||||||
community_free(attr->community);
|
community_free(&attr->community);
|
||||||
attr->community = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attr->ecommunity && !attr->ecommunity->refcnt)
|
if (attr->ecommunity && !attr->ecommunity->refcnt)
|
||||||
ecommunity_free(&attr->ecommunity);
|
ecommunity_free(&attr->ecommunity);
|
||||||
if (attr->lcommunity && !attr->lcommunity->refcnt)
|
if (attr->lcommunity && !attr->lcommunity->refcnt)
|
||||||
@ -1688,7 +1697,7 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
|
|||||||
* - for consistency in rx processing
|
* - for consistency in rx processing
|
||||||
*
|
*
|
||||||
* The following comment is to signal GCC this intention
|
* The following comment is to signal GCC this intention
|
||||||
* and supress the warning
|
* and suppress the warning
|
||||||
*/
|
*/
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
case BGP_ATTR_NHLEN_IPV4:
|
case BGP_ATTR_NHLEN_IPV4:
|
||||||
@ -2615,7 +2624,7 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If hard error occured immediately return to the caller. */
|
/* If hard error occurred immediately return to the caller. */
|
||||||
if (ret == BGP_ATTR_PARSE_ERROR) {
|
if (ret == BGP_ATTR_PARSE_ERROR) {
|
||||||
flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
|
flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
|
||||||
"%s: Attribute %s, parse error", peer->host,
|
"%s: Attribute %s, parse error", peer->host,
|
||||||
|
@ -272,10 +272,13 @@ extern void bgp_attr_unintern_sub(struct attr *);
|
|||||||
extern void bgp_attr_unintern(struct attr **);
|
extern void bgp_attr_unintern(struct attr **);
|
||||||
extern void bgp_attr_flush(struct attr *);
|
extern void bgp_attr_flush(struct attr *);
|
||||||
extern struct attr *bgp_attr_default_set(struct attr *attr, uint8_t);
|
extern struct attr *bgp_attr_default_set(struct attr *attr, uint8_t);
|
||||||
extern struct attr *bgp_attr_aggregate_intern(struct bgp *, uint8_t,
|
extern struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
|
||||||
struct aspath *,
|
struct aspath *aspath,
|
||||||
struct community *, int as_set,
|
struct community *community,
|
||||||
uint8_t);
|
struct ecommunity *ecommunity,
|
||||||
|
struct lcommunity *lcommunity,
|
||||||
|
int as_set,
|
||||||
|
uint8_t atomic_aggregate);
|
||||||
extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
|
extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
|
||||||
struct stream *, struct attr *,
|
struct stream *, struct attr *,
|
||||||
struct bpacket_attr_vec_arr *vecarr,
|
struct bpacket_attr_vec_arr *vecarr,
|
||||||
@ -284,7 +287,7 @@ extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
|
|||||||
mpls_label_t *, uint32_t, int, uint32_t);
|
mpls_label_t *, uint32_t, int, uint32_t);
|
||||||
extern void bgp_dump_routes_attr(struct stream *, struct attr *,
|
extern void bgp_dump_routes_attr(struct stream *, struct attr *,
|
||||||
struct prefix *);
|
struct prefix *);
|
||||||
extern int attrhash_cmp(const void *, const void *);
|
extern bool attrhash_cmp(const void *arg1, const void *arg2);
|
||||||
extern unsigned int attrhash_key_make(void *);
|
extern unsigned int attrhash_key_make(void *);
|
||||||
extern void attr_show_all(struct vty *);
|
extern void attr_show_all(struct vty *);
|
||||||
extern unsigned long int attr_count(void);
|
extern unsigned long int attr_count(void);
|
||||||
|
@ -65,7 +65,7 @@ static void community_entry_free(struct community_entry *entry)
|
|||||||
switch (entry->style) {
|
switch (entry->style) {
|
||||||
case COMMUNITY_LIST_STANDARD:
|
case COMMUNITY_LIST_STANDARD:
|
||||||
if (entry->u.com)
|
if (entry->u.com)
|
||||||
community_free(entry->u.com);
|
community_free(&entry->u.com);
|
||||||
break;
|
break;
|
||||||
case LARGE_COMMUNITY_LIST_STANDARD:
|
case LARGE_COMMUNITY_LIST_STANDARD:
|
||||||
if (entry->u.lcom)
|
if (entry->u.lcom)
|
||||||
@ -903,7 +903,7 @@ int community_list_unset(struct community_list_handler *ch, const char *name,
|
|||||||
|
|
||||||
if (com) {
|
if (com) {
|
||||||
entry = community_list_entry_lookup(list, com, direct);
|
entry = community_list_entry_lookup(list, com, direct);
|
||||||
community_free(com);
|
community_free(&com);
|
||||||
} else
|
} else
|
||||||
entry = community_list_entry_lookup(list, str, direct);
|
entry = community_list_entry_lookup(list, str, direct);
|
||||||
|
|
||||||
|
@ -39,19 +39,19 @@ static struct community *community_new(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free communities value. */
|
/* Free communities value. */
|
||||||
void community_free(struct community *com)
|
void community_free(struct community **com)
|
||||||
{
|
{
|
||||||
if (com->val)
|
if ((*com)->val)
|
||||||
XFREE(MTYPE_COMMUNITY_VAL, com->val);
|
XFREE(MTYPE_COMMUNITY_VAL, (*com)->val);
|
||||||
if (com->str)
|
if ((*com)->str)
|
||||||
XFREE(MTYPE_COMMUNITY_STR, com->str);
|
XFREE(MTYPE_COMMUNITY_STR, (*com)->str);
|
||||||
|
|
||||||
if (com->json) {
|
if ((*com)->json) {
|
||||||
json_object_free(com->json);
|
json_object_free((*com)->json);
|
||||||
com->json = NULL;
|
(*com)->json = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFREE(MTYPE_COMMUNITY, com);
|
XFREE(MTYPE_COMMUNITY, (*com));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add one community value to the community. */
|
/* Add one community value to the community. */
|
||||||
@ -498,7 +498,7 @@ struct community *community_intern(struct community *com)
|
|||||||
/* Arguemnt com is allocated temporary. So when it is not used in
|
/* Arguemnt com is allocated temporary. So when it is not used in
|
||||||
hash, it should be freed. */
|
hash, it should be freed. */
|
||||||
if (find != com)
|
if (find != com)
|
||||||
community_free(com);
|
community_free(&com);
|
||||||
|
|
||||||
/* Increment refrence counter. */
|
/* Increment refrence counter. */
|
||||||
find->refcnt++;
|
find->refcnt++;
|
||||||
@ -524,8 +524,7 @@ void community_unintern(struct community **com)
|
|||||||
ret = (struct community *)hash_release(comhash, *com);
|
ret = (struct community *)hash_release(comhash, *com);
|
||||||
assert(ret != NULL);
|
assert(ret != NULL);
|
||||||
|
|
||||||
community_free(*com);
|
community_free(com);
|
||||||
*com = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,17 +613,17 @@ int community_match(const struct community *com1, const struct community *com2)
|
|||||||
|
|
||||||
/* If two aspath have same value then return 1 else return 0. This
|
/* If two aspath have same value then return 1 else return 0. This
|
||||||
function is used by hash package. */
|
function is used by hash package. */
|
||||||
int community_cmp(const struct community *com1, const struct community *com2)
|
bool community_cmp(const struct community *com1, const struct community *com2)
|
||||||
{
|
{
|
||||||
if (com1 == NULL && com2 == NULL)
|
if (com1 == NULL && com2 == NULL)
|
||||||
return 1;
|
return true;
|
||||||
if (com1 == NULL || com2 == NULL)
|
if (com1 == NULL || com2 == NULL)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (com1->size == com2->size)
|
if (com1->size == com2->size)
|
||||||
if (memcmp(com1->val, com2->val, com1->size * 4) == 0)
|
if (memcmp(com1->val, com2->val, com1->size * 4) == 0)
|
||||||
return 1;
|
return true;
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add com2 to the end of com1. */
|
/* Add com2 to the end of com1. */
|
||||||
@ -874,13 +873,13 @@ struct community *community_str2com(const char *str)
|
|||||||
break;
|
break;
|
||||||
case community_token_unknown:
|
case community_token_unknown:
|
||||||
if (com)
|
if (com)
|
||||||
community_free(com);
|
community_free(&com);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} while (str);
|
} while (str);
|
||||||
|
|
||||||
com_sort = community_uniq_sort(com);
|
com_sort = community_uniq_sort(com);
|
||||||
community_free(com);
|
community_free(&com);
|
||||||
|
|
||||||
return com_sort;
|
return com_sort;
|
||||||
}
|
}
|
||||||
@ -902,7 +901,7 @@ void community_init(void)
|
|||||||
{
|
{
|
||||||
comhash =
|
comhash =
|
||||||
hash_create((unsigned int (*)(void *))community_hash_make,
|
hash_create((unsigned int (*)(void *))community_hash_make,
|
||||||
(int (*)(const void *, const void *))community_cmp,
|
(bool (*)(const void *, const void *))community_cmp,
|
||||||
"BGP Community Hash");
|
"BGP Community Hash");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ struct community {
|
|||||||
/* Prototypes of communities attribute functions. */
|
/* Prototypes of communities attribute functions. */
|
||||||
extern void community_init(void);
|
extern void community_init(void);
|
||||||
extern void community_finish(void);
|
extern void community_finish(void);
|
||||||
extern void community_free(struct community *);
|
extern void community_free(struct community **comm);
|
||||||
extern struct community *community_uniq_sort(struct community *);
|
extern struct community *community_uniq_sort(struct community *);
|
||||||
extern struct community *community_parse(uint32_t *, unsigned short);
|
extern struct community *community_parse(uint32_t *, unsigned short);
|
||||||
extern struct community *community_intern(struct community *);
|
extern struct community *community_intern(struct community *);
|
||||||
@ -77,7 +77,8 @@ extern char *community_str(struct community *, bool make_json);
|
|||||||
extern unsigned int community_hash_make(struct community *);
|
extern unsigned int community_hash_make(struct community *);
|
||||||
extern struct community *community_str2com(const char *);
|
extern struct community *community_str2com(const char *);
|
||||||
extern int community_match(const struct community *, const struct community *);
|
extern int community_match(const struct community *, const struct community *);
|
||||||
extern int community_cmp(const struct community *, const struct community *);
|
extern bool community_cmp(const struct community *c1,
|
||||||
|
const struct community *c2);
|
||||||
extern struct community *community_merge(struct community *,
|
extern struct community *community_merge(struct community *,
|
||||||
struct community *);
|
struct community *);
|
||||||
extern struct community *community_delete(struct community *,
|
extern struct community *community_delete(struct community *,
|
||||||
|
101
bgpd/bgp_damp.c
101
bgpd/bgp_damp.c
@ -42,8 +42,8 @@ static struct bgp_damp_config *damp = &bgp_damp_cfg;
|
|||||||
|
|
||||||
/* Utility macro to add and delete BGP dampening information to no
|
/* Utility macro to add and delete BGP dampening information to no
|
||||||
used list. */
|
used list. */
|
||||||
#define BGP_DAMP_LIST_ADD(N,A) BGP_INFO_ADD(N,A,no_reuse_list)
|
#define BGP_DAMP_LIST_ADD(N, A) BGP_PATH_INFO_ADD(N, A, no_reuse_list)
|
||||||
#define BGP_DAMP_LIST_DEL(N,A) BGP_INFO_DEL(N,A,no_reuse_list)
|
#define BGP_DAMP_LIST_DEL(N, A) BGP_PATH_INFO_DEL(N, A, no_reuse_list)
|
||||||
|
|
||||||
/* Calculate reuse list index by penalty value. */
|
/* Calculate reuse list index by penalty value. */
|
||||||
static int bgp_reuse_index(int penalty)
|
static int bgp_reuse_index(int penalty)
|
||||||
@ -128,7 +128,7 @@ static int bgp_reuse_timer(struct thread *t)
|
|||||||
|
|
||||||
/* 3. if ( the saved list head pointer is non-empty ) */
|
/* 3. if ( the saved list head pointer is non-empty ) */
|
||||||
for (; bdi; bdi = next) {
|
for (; bdi; bdi = next) {
|
||||||
struct bgp *bgp = bdi->binfo->peer->bgp;
|
struct bgp *bgp = bdi->path->peer->bgp;
|
||||||
|
|
||||||
next = bdi->next;
|
next = bdi->next;
|
||||||
|
|
||||||
@ -145,15 +145,15 @@ static int bgp_reuse_timer(struct thread *t)
|
|||||||
/* if (figure-of-merit < reuse). */
|
/* if (figure-of-merit < reuse). */
|
||||||
if (bdi->penalty < damp->reuse_limit) {
|
if (bdi->penalty < damp->reuse_limit) {
|
||||||
/* Reuse the route. */
|
/* Reuse the route. */
|
||||||
bgp_info_unset_flag(bdi->rn, bdi->binfo,
|
bgp_path_info_unset_flag(bdi->rn, bdi->path,
|
||||||
BGP_INFO_DAMPED);
|
BGP_PATH_DAMPED);
|
||||||
bdi->suppress_time = 0;
|
bdi->suppress_time = 0;
|
||||||
|
|
||||||
if (bdi->lastrecord == BGP_RECORD_UPDATE) {
|
if (bdi->lastrecord == BGP_RECORD_UPDATE) {
|
||||||
bgp_info_unset_flag(bdi->rn, bdi->binfo,
|
bgp_path_info_unset_flag(bdi->rn, bdi->path,
|
||||||
BGP_INFO_HISTORY);
|
BGP_PATH_HISTORY);
|
||||||
bgp_aggregate_increment(bgp, &bdi->rn->p,
|
bgp_aggregate_increment(bgp, &bdi->rn->p,
|
||||||
bdi->binfo, bdi->afi,
|
bdi->path, bdi->afi,
|
||||||
bdi->safi);
|
bdi->safi);
|
||||||
bgp_process(bgp, bdi->rn, bdi->afi, bdi->safi);
|
bgp_process(bgp, bdi->rn, bdi->afi, bdi->safi);
|
||||||
}
|
}
|
||||||
@ -172,8 +172,8 @@ static int bgp_reuse_timer(struct thread *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* A route becomes unreachable (RFC2439 Section 4.8.2). */
|
/* A route becomes unreachable (RFC2439 Section 4.8.2). */
|
||||||
int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
|
||||||
safi_t safi, int attr_change)
|
afi_t afi, safi_t safi, int attr_change)
|
||||||
{
|
{
|
||||||
time_t t_now;
|
time_t t_now;
|
||||||
struct bgp_damp_info *bdi = NULL;
|
struct bgp_damp_info *bdi = NULL;
|
||||||
@ -182,8 +182,8 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
t_now = bgp_clock();
|
t_now = bgp_clock();
|
||||||
|
|
||||||
/* Processing Unreachable Messages. */
|
/* Processing Unreachable Messages. */
|
||||||
if (binfo->extra)
|
if (path->extra)
|
||||||
bdi = binfo->extra->damp_info;
|
bdi = path->extra->damp_info;
|
||||||
|
|
||||||
if (bdi == NULL) {
|
if (bdi == NULL) {
|
||||||
/* If there is no previous stability history. */
|
/* If there is no previous stability history. */
|
||||||
@ -195,7 +195,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
|
|
||||||
bdi = XCALLOC(MTYPE_BGP_DAMP_INFO,
|
bdi = XCALLOC(MTYPE_BGP_DAMP_INFO,
|
||||||
sizeof(struct bgp_damp_info));
|
sizeof(struct bgp_damp_info));
|
||||||
bdi->binfo = binfo;
|
bdi->path = path;
|
||||||
bdi->rn = rn;
|
bdi->rn = rn;
|
||||||
bdi->penalty =
|
bdi->penalty =
|
||||||
(attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
|
(attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
|
||||||
@ -205,7 +205,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
bdi->index = -1;
|
bdi->index = -1;
|
||||||
bdi->afi = afi;
|
bdi->afi = afi;
|
||||||
bdi->safi = safi;
|
bdi->safi = safi;
|
||||||
(bgp_info_extra_get(binfo))->damp_info = bdi;
|
(bgp_path_info_extra_get(path))->damp_info = bdi;
|
||||||
BGP_DAMP_LIST_ADD(damp, bdi);
|
BGP_DAMP_LIST_ADD(damp, bdi);
|
||||||
} else {
|
} else {
|
||||||
last_penalty = bdi->penalty;
|
last_penalty = bdi->penalty;
|
||||||
@ -222,16 +222,16 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
bdi->flap++;
|
bdi->flap++;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((rn == bdi->rn) && (binfo == bdi->binfo));
|
assert((rn == bdi->rn) && (path == bdi->path));
|
||||||
|
|
||||||
bdi->lastrecord = BGP_RECORD_WITHDRAW;
|
bdi->lastrecord = BGP_RECORD_WITHDRAW;
|
||||||
bdi->t_updated = t_now;
|
bdi->t_updated = t_now;
|
||||||
|
|
||||||
/* Make this route as historical status. */
|
/* Make this route as historical status. */
|
||||||
bgp_info_set_flag(rn, binfo, BGP_INFO_HISTORY);
|
bgp_path_info_set_flag(rn, path, BGP_PATH_HISTORY);
|
||||||
|
|
||||||
/* Remove the route from a reuse list if it is on one. */
|
/* Remove the route from a reuse list if it is on one. */
|
||||||
if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)) {
|
if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)) {
|
||||||
/* If decay rate isn't equal to 0, reinsert brn. */
|
/* If decay rate isn't equal to 0, reinsert brn. */
|
||||||
if (bdi->penalty != last_penalty && bdi->index >= 0) {
|
if (bdi->penalty != last_penalty && bdi->index >= 0) {
|
||||||
bgp_reuse_list_delete(bdi);
|
bgp_reuse_list_delete(bdi);
|
||||||
@ -243,7 +243,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
/* If not suppressed before, do annonunce this withdraw and
|
/* If not suppressed before, do annonunce this withdraw and
|
||||||
insert into reuse_list. */
|
insert into reuse_list. */
|
||||||
if (bdi->penalty >= damp->suppress_value) {
|
if (bdi->penalty >= damp->suppress_value) {
|
||||||
bgp_info_set_flag(rn, binfo, BGP_INFO_DAMPED);
|
bgp_path_info_set_flag(rn, path, BGP_PATH_DAMPED);
|
||||||
bdi->suppress_time = t_now;
|
bdi->suppress_time = t_now;
|
||||||
BGP_DAMP_LIST_DEL(damp, bdi);
|
BGP_DAMP_LIST_DEL(damp, bdi);
|
||||||
bgp_reuse_list_add(bdi);
|
bgp_reuse_list_add(bdi);
|
||||||
@ -252,28 +252,28 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
return BGP_DAMP_USED;
|
return BGP_DAMP_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
int bgp_damp_update(struct bgp_path_info *path, struct bgp_node *rn, afi_t afi,
|
||||||
safi_t safi)
|
safi_t safi)
|
||||||
{
|
{
|
||||||
time_t t_now;
|
time_t t_now;
|
||||||
struct bgp_damp_info *bdi;
|
struct bgp_damp_info *bdi;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!binfo->extra || !((bdi = binfo->extra->damp_info)))
|
if (!path->extra || !((bdi = path->extra->damp_info)))
|
||||||
return BGP_DAMP_USED;
|
return BGP_DAMP_USED;
|
||||||
|
|
||||||
t_now = bgp_clock();
|
t_now = bgp_clock();
|
||||||
bgp_info_unset_flag(rn, binfo, BGP_INFO_HISTORY);
|
bgp_path_info_unset_flag(rn, path, BGP_PATH_HISTORY);
|
||||||
|
|
||||||
bdi->lastrecord = BGP_RECORD_UPDATE;
|
bdi->lastrecord = BGP_RECORD_UPDATE;
|
||||||
bdi->penalty = bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty);
|
bdi->penalty = bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty);
|
||||||
|
|
||||||
if (!CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)
|
if (!CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
|
||||||
&& (bdi->penalty < damp->suppress_value))
|
&& (bdi->penalty < damp->suppress_value))
|
||||||
status = BGP_DAMP_USED;
|
status = BGP_DAMP_USED;
|
||||||
else if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)
|
else if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
|
||||||
&& (bdi->penalty < damp->reuse_limit)) {
|
&& (bdi->penalty < damp->reuse_limit)) {
|
||||||
bgp_info_unset_flag(rn, binfo, BGP_INFO_DAMPED);
|
bgp_path_info_unset_flag(rn, path, BGP_PATH_DAMPED);
|
||||||
bgp_reuse_list_delete(bdi);
|
bgp_reuse_list_delete(bdi);
|
||||||
BGP_DAMP_LIST_ADD(damp, bdi);
|
BGP_DAMP_LIST_ADD(damp, bdi);
|
||||||
bdi->suppress_time = 0;
|
bdi->suppress_time = 0;
|
||||||
@ -290,28 +290,29 @@ int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove dampening information and history route. */
|
/* Remove dampening information and history route. */
|
||||||
int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
|
int bgp_damp_scan(struct bgp_path_info *path, afi_t afi, safi_t safi)
|
||||||
{
|
{
|
||||||
time_t t_now, t_diff;
|
time_t t_now, t_diff;
|
||||||
struct bgp_damp_info *bdi;
|
struct bgp_damp_info *bdi;
|
||||||
|
|
||||||
assert(binfo->extra && binfo->extra->damp_info);
|
assert(path->extra && path->extra->damp_info);
|
||||||
|
|
||||||
t_now = bgp_clock();
|
t_now = bgp_clock();
|
||||||
bdi = binfo->extra->damp_info;
|
bdi = path->extra->damp_info;
|
||||||
|
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
|
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
|
||||||
t_diff = t_now - bdi->suppress_time;
|
t_diff = t_now - bdi->suppress_time;
|
||||||
|
|
||||||
if (t_diff >= damp->max_suppress_time) {
|
if (t_diff >= damp->max_suppress_time) {
|
||||||
bgp_info_unset_flag(bdi->rn, binfo, BGP_INFO_DAMPED);
|
bgp_path_info_unset_flag(bdi->rn, path,
|
||||||
|
BGP_PATH_DAMPED);
|
||||||
bgp_reuse_list_delete(bdi);
|
bgp_reuse_list_delete(bdi);
|
||||||
BGP_DAMP_LIST_ADD(damp, bdi);
|
BGP_DAMP_LIST_ADD(damp, bdi);
|
||||||
bdi->penalty = damp->reuse_limit;
|
bdi->penalty = damp->reuse_limit;
|
||||||
bdi->suppress_time = 0;
|
bdi->suppress_time = 0;
|
||||||
bdi->t_updated = t_now;
|
bdi->t_updated = t_now;
|
||||||
|
|
||||||
/* Need to announce UPDATE once this binfo is usable
|
/* Need to announce UPDATE once this path is usable
|
||||||
* again. */
|
* again. */
|
||||||
if (bdi->lastrecord == BGP_RECORD_UPDATE)
|
if (bdi->lastrecord == BGP_RECORD_UPDATE)
|
||||||
return 1;
|
return 1;
|
||||||
@ -323,7 +324,7 @@ int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
|
|||||||
bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty);
|
bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty);
|
||||||
|
|
||||||
if (bdi->penalty <= damp->reuse_limit / 2.0) {
|
if (bdi->penalty <= damp->reuse_limit / 2.0) {
|
||||||
/* release the bdi, bdi->binfo. */
|
/* release the bdi, bdi->path. */
|
||||||
bgp_damp_info_free(bdi, 1);
|
bgp_damp_info_free(bdi, 1);
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
@ -334,23 +335,24 @@ int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
|
|||||||
|
|
||||||
void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw)
|
void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw)
|
||||||
{
|
{
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *path;
|
||||||
|
|
||||||
if (!bdi)
|
if (!bdi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
binfo = bdi->binfo;
|
path = bdi->path;
|
||||||
binfo->extra->damp_info = NULL;
|
path->extra->damp_info = NULL;
|
||||||
|
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
|
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
|
||||||
bgp_reuse_list_delete(bdi);
|
bgp_reuse_list_delete(bdi);
|
||||||
else
|
else
|
||||||
BGP_DAMP_LIST_DEL(damp, bdi);
|
BGP_DAMP_LIST_DEL(damp, bdi);
|
||||||
|
|
||||||
bgp_info_unset_flag(bdi->rn, binfo, BGP_INFO_HISTORY | BGP_INFO_DAMPED);
|
bgp_path_info_unset_flag(bdi->rn, path,
|
||||||
|
BGP_PATH_HISTORY | BGP_PATH_DAMPED);
|
||||||
|
|
||||||
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
|
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
|
||||||
bgp_info_delete(bdi->rn, binfo);
|
bgp_path_info_delete(bdi->rn, path);
|
||||||
|
|
||||||
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
|
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
|
||||||
}
|
}
|
||||||
@ -446,12 +448,15 @@ static void bgp_damp_config_clean(struct bgp_damp_config *damp)
|
|||||||
{
|
{
|
||||||
/* Free decay array */
|
/* Free decay array */
|
||||||
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
|
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
|
||||||
|
damp->decay_array_size = 0;
|
||||||
|
|
||||||
/* Free reuse index array */
|
/* Free reuse index array */
|
||||||
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_index);
|
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_index);
|
||||||
|
damp->reuse_index_size = 0;
|
||||||
|
|
||||||
/* Free reuse list array. */
|
/* Free reuse list array. */
|
||||||
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_list);
|
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_list);
|
||||||
|
damp->reuse_list_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean all the bgp_damp_info stored in reuse_list. */
|
/* Clean all the bgp_damp_info stored in reuse_list. */
|
||||||
@ -588,7 +593,7 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
|
||||||
json_object *json_path)
|
json_object *json_path)
|
||||||
{
|
{
|
||||||
struct bgp_damp_info *bdi;
|
struct bgp_damp_info *bdi;
|
||||||
@ -596,11 +601,11 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
char timebuf[BGP_UPTIME_LEN];
|
char timebuf[BGP_UPTIME_LEN];
|
||||||
int penalty;
|
int penalty;
|
||||||
|
|
||||||
if (!binfo->extra)
|
if (!path->extra)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* BGP dampening information. */
|
/* BGP dampening information. */
|
||||||
bdi = binfo->extra->damp_info;
|
bdi = path->extra->damp_info;
|
||||||
|
|
||||||
/* If dampening is not enabled or there is no dampening information,
|
/* If dampening is not enabled or there is no dampening information,
|
||||||
return immediately. */
|
return immediately. */
|
||||||
@ -618,8 +623,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 1,
|
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 1,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
|
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
|
||||||
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
|
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
|
||||||
bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1,
|
bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1,
|
||||||
json_path);
|
json_path);
|
||||||
} else {
|
} else {
|
||||||
@ -629,8 +634,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0,
|
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0,
|
||||||
json_path));
|
json_path));
|
||||||
|
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
|
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
|
||||||
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
|
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
|
||||||
vty_out(vty, ", reuse in %s",
|
vty_out(vty, ", reuse in %s",
|
||||||
bgp_get_reuse_time(penalty, timebuf,
|
bgp_get_reuse_time(penalty, timebuf,
|
||||||
BGP_UPTIME_LEN, 0,
|
BGP_UPTIME_LEN, 0,
|
||||||
@ -640,7 +645,7 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo,
|
const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
|
||||||
char *timebuf, size_t len, bool use_json,
|
char *timebuf, size_t len, bool use_json,
|
||||||
json_object *json)
|
json_object *json)
|
||||||
{
|
{
|
||||||
@ -648,11 +653,11 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo,
|
|||||||
time_t t_now, t_diff;
|
time_t t_now, t_diff;
|
||||||
int penalty;
|
int penalty;
|
||||||
|
|
||||||
if (!binfo->extra)
|
if (!path->extra)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* BGP dampening information. */
|
/* BGP dampening information. */
|
||||||
bdi = binfo->extra->damp_info;
|
bdi = path->extra->damp_info;
|
||||||
|
|
||||||
/* If dampening is not enabled or there is no dampening information,
|
/* If dampening is not enabled or there is no dampening information,
|
||||||
return immediately. */
|
return immediately. */
|
||||||
@ -684,7 +689,7 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi)
|
|||||||
vty_out(vty, "Suppress penalty: %d\n", damp->suppress_value);
|
vty_out(vty, "Suppress penalty: %d\n", damp->suppress_value);
|
||||||
vty_out(vty, "Max suppress time: %lld min\n",
|
vty_out(vty, "Max suppress time: %lld min\n",
|
||||||
(long long)damp->max_suppress_time / 60);
|
(long long)damp->max_suppress_time / 60);
|
||||||
vty_out(vty, "Max supress penalty: %u\n", damp->ceiling);
|
vty_out(vty, "Max suppress penalty: %u\n", damp->ceiling);
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
} else
|
} else
|
||||||
vty_out(vty, "dampening not enabled for %s\n",
|
vty_out(vty, "dampening not enabled for %s\n",
|
||||||
|
@ -43,8 +43,8 @@ struct bgp_damp_info {
|
|||||||
/* Time of route start to be suppressed. */
|
/* Time of route start to be suppressed. */
|
||||||
time_t suppress_time;
|
time_t suppress_time;
|
||||||
|
|
||||||
/* Back reference to bgp_info. */
|
/* Back reference to bgp_path_info. */
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *path;
|
||||||
|
|
||||||
/* Back reference to bgp_node. */
|
/* Back reference to bgp_node. */
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
@ -130,18 +130,19 @@ struct bgp_damp_config {
|
|||||||
extern int bgp_damp_enable(struct bgp *, afi_t, safi_t, time_t, unsigned int,
|
extern int bgp_damp_enable(struct bgp *, afi_t, safi_t, time_t, unsigned int,
|
||||||
unsigned int, time_t);
|
unsigned int, time_t);
|
||||||
extern int bgp_damp_disable(struct bgp *, afi_t, safi_t);
|
extern int bgp_damp_disable(struct bgp *, afi_t, safi_t);
|
||||||
extern int bgp_damp_withdraw(struct bgp_info *, struct bgp_node *, afi_t,
|
extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
|
||||||
safi_t, int);
|
afi_t afi, safi_t safi, int attr_change);
|
||||||
extern int bgp_damp_update(struct bgp_info *, struct bgp_node *, afi_t, safi_t);
|
extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_node *rn,
|
||||||
extern int bgp_damp_scan(struct bgp_info *, afi_t, safi_t);
|
afi_t afi, safi_t saff);
|
||||||
extern void bgp_damp_info_free(struct bgp_damp_info *, int);
|
extern int bgp_damp_scan(struct bgp_path_info *path, afi_t afi, safi_t safi);
|
||||||
|
extern void bgp_damp_info_free(struct bgp_damp_info *path, int withdraw);
|
||||||
extern void bgp_damp_info_clean(void);
|
extern void bgp_damp_info_clean(void);
|
||||||
extern int bgp_damp_decay(time_t, int);
|
extern int bgp_damp_decay(time_t, int);
|
||||||
extern void bgp_config_write_damp(struct vty *);
|
extern void bgp_config_write_damp(struct vty *);
|
||||||
extern void bgp_damp_info_vty(struct vty *, struct bgp_info *,
|
extern void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
|
||||||
json_object *json_path);
|
json_object *json_path);
|
||||||
extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
|
extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path,
|
||||||
char *timebuf, size_t len,
|
char *timebuf, size_t len,
|
||||||
bool use_json, json_object *json);
|
bool use_json, json_object *json);
|
||||||
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t);
|
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t);
|
||||||
|
@ -1380,7 +1380,7 @@ DEFUN (no_debug_bgp_update_direct_peer,
|
|||||||
|
|
||||||
DEFPY (debug_bgp_update_prefix_afi_safi,
|
DEFPY (debug_bgp_update_prefix_afi_safi,
|
||||||
debug_bgp_update_prefix_afi_safi_cmd,
|
debug_bgp_update_prefix_afi_safi_cmd,
|
||||||
"debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <M:A:C|M:A:C/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>",
|
"debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>",
|
||||||
DEBUG_STR
|
DEBUG_STR
|
||||||
BGP_STR
|
BGP_STR
|
||||||
"BGP updates\n"
|
"BGP updates\n"
|
||||||
@ -1443,7 +1443,7 @@ DEFPY (debug_bgp_update_prefix_afi_safi,
|
|||||||
|
|
||||||
DEFPY (no_debug_bgp_update_prefix_afi_safi,
|
DEFPY (no_debug_bgp_update_prefix_afi_safi,
|
||||||
no_debug_bgp_update_prefix_afi_safi_cmd,
|
no_debug_bgp_update_prefix_afi_safi_cmd,
|
||||||
"no debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <M:A:C|M:A:C/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>",
|
"no debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>",
|
||||||
NO_STR
|
NO_STR
|
||||||
DEBUG_STR
|
DEBUG_STR
|
||||||
BGP_STR
|
BGP_STR
|
||||||
|
@ -299,9 +299,9 @@ static void bgp_dump_routes_index_table(struct bgp *bgp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
static struct bgp_path_info *
|
||||||
struct bgp_info *info,
|
bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
||||||
unsigned int seq)
|
struct bgp_path_info *path, unsigned int seq)
|
||||||
{
|
{
|
||||||
struct stream *obuf;
|
struct stream *obuf;
|
||||||
size_t sizep;
|
size_t sizep;
|
||||||
@ -349,18 +349,18 @@ static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
|||||||
stream_putw(obuf, 0);
|
stream_putw(obuf, 0);
|
||||||
|
|
||||||
endp = stream_get_endp(obuf);
|
endp = stream_get_endp(obuf);
|
||||||
for (; info; info = info->next) {
|
for (; path; path = path->next) {
|
||||||
size_t cur_endp;
|
size_t cur_endp;
|
||||||
|
|
||||||
/* Peer index */
|
/* Peer index */
|
||||||
stream_putw(obuf, info->peer->table_dump_index);
|
stream_putw(obuf, path->peer->table_dump_index);
|
||||||
|
|
||||||
/* Originated */
|
/* Originated */
|
||||||
stream_putl(obuf, time(NULL) - (bgp_clock() - info->uptime));
|
stream_putl(obuf, time(NULL) - (bgp_clock() - path->uptime));
|
||||||
|
|
||||||
/* Dump attribute. */
|
/* Dump attribute. */
|
||||||
/* Skip prefix & AFI/SAFI for MP_NLRI */
|
/* Skip prefix & AFI/SAFI for MP_NLRI */
|
||||||
bgp_dump_routes_attr(obuf, info->attr, &rn->p);
|
bgp_dump_routes_attr(obuf, path->attr, &rn->p);
|
||||||
|
|
||||||
cur_endp = stream_get_endp(obuf);
|
cur_endp = stream_get_endp(obuf);
|
||||||
if (cur_endp > BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
|
if (cur_endp > BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
|
||||||
@ -379,7 +379,7 @@ static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
|||||||
bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
|
bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
|
||||||
fwrite(STREAM_DATA(obuf), stream_get_endp(obuf), 1, bgp_dump_routes.fp);
|
fwrite(STREAM_DATA(obuf), stream_get_endp(obuf), 1, bgp_dump_routes.fp);
|
||||||
|
|
||||||
return info;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
|
|||||||
static unsigned int bgp_dump_routes_func(int afi, int first_run,
|
static unsigned int bgp_dump_routes_func(int afi, int first_run,
|
||||||
unsigned int seq)
|
unsigned int seq)
|
||||||
{
|
{
|
||||||
struct bgp_info *info;
|
struct bgp_path_info *path;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
@ -410,9 +410,9 @@ static unsigned int bgp_dump_routes_func(int afi, int first_run,
|
|||||||
table = bgp->rib[afi][SAFI_UNICAST];
|
table = bgp->rib[afi][SAFI_UNICAST];
|
||||||
|
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||||
info = rn->info;
|
path = rn->info;
|
||||||
while (info) {
|
while (path) {
|
||||||
info = bgp_dump_route_node_record(afi, rn, info, seq);
|
path = bgp_dump_route_node_record(afi, rn, path, seq);
|
||||||
seq++;
|
seq++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,16 +253,16 @@ unsigned int ecommunity_hash_make(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compare two Extended Communities Attribute structure. */
|
/* Compare two Extended Communities Attribute structure. */
|
||||||
int ecommunity_cmp(const void *arg1, const void *arg2)
|
bool ecommunity_cmp(const void *arg1, const void *arg2)
|
||||||
{
|
{
|
||||||
const struct ecommunity *ecom1 = arg1;
|
const struct ecommunity *ecom1 = arg1;
|
||||||
const struct ecommunity *ecom2 = arg2;
|
const struct ecommunity *ecom2 = arg2;
|
||||||
|
|
||||||
if (ecom1 == NULL && ecom2 == NULL)
|
if (ecom1 == NULL && ecom2 == NULL)
|
||||||
return 1;
|
return true;
|
||||||
|
|
||||||
if (ecom1 == NULL || ecom2 == NULL)
|
if (ecom1 == NULL || ecom2 == NULL)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
return (ecom1->size == ecom2->size
|
return (ecom1->size == ecom2->size
|
||||||
&& memcmp(ecom1->val, ecom2->val, ecom1->size * ECOMMUNITY_SIZE)
|
&& memcmp(ecom1->val, ecom2->val, ecom1->size * ECOMMUNITY_SIZE)
|
||||||
|
@ -154,7 +154,7 @@ extern struct ecommunity *ecommunity_merge(struct ecommunity *,
|
|||||||
struct ecommunity *);
|
struct ecommunity *);
|
||||||
extern struct ecommunity *ecommunity_uniq_sort(struct ecommunity *);
|
extern struct ecommunity *ecommunity_uniq_sort(struct ecommunity *);
|
||||||
extern struct ecommunity *ecommunity_intern(struct ecommunity *);
|
extern struct ecommunity *ecommunity_intern(struct ecommunity *);
|
||||||
extern int ecommunity_cmp(const void *, const void *);
|
extern bool ecommunity_cmp(const void *arg1, const void *arg2);
|
||||||
extern void ecommunity_unintern(struct ecommunity **);
|
extern void ecommunity_unintern(struct ecommunity **);
|
||||||
extern unsigned int ecommunity_hash_make(void *);
|
extern unsigned int ecommunity_hash_make(void *);
|
||||||
extern struct ecommunity *ecommunity_str2com(const char *, int, int);
|
extern struct ecommunity *ecommunity_str2com(const char *, int, int);
|
||||||
|
@ -171,7 +171,7 @@ static struct log_ref ferr_bgp_warn[] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_CAPABILITY_VENDOR,
|
.code = EC_BGP_CAPABILITY_VENDOR,
|
||||||
.title = "BGP has recieved capability data specific to a particular vendor",
|
.title = "BGP has received capability data specific to a particular vendor",
|
||||||
.description = "BGP has received a capability that is vendor specific and as such we have no knowledge of how to use this capability in FRR",
|
.description = "BGP has received a capability that is vendor specific and as such we have no knowledge of how to use this capability in FRR",
|
||||||
.suggestion = "On peer turn off this feature"
|
.suggestion = "On peer turn off this feature"
|
||||||
},
|
},
|
||||||
@ -197,43 +197,43 @@ static struct log_ref ferr_bgp_err[] = {
|
|||||||
.code = EC_BGP_ATTR_FLAG,
|
.code = EC_BGP_ATTR_FLAG,
|
||||||
.title = "BGP attribute flag is incorrect",
|
.title = "BGP attribute flag is incorrect",
|
||||||
.description = "BGP attribute flag is set to the wrong value (Optional/Transitive/Partial)",
|
.description = "BGP attribute flag is set to the wrong value (Optional/Transitive/Partial)",
|
||||||
.suggestion = "Determine the soure of the attribute and determine why the attribute flag has been set incorrectly"
|
.suggestion = "Determine the source of the attribute and determine why the attribute flag has been set incorrectly"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_ATTR_LEN,
|
.code = EC_BGP_ATTR_LEN,
|
||||||
.title = "BGP attribute length is incorrect",
|
.title = "BGP attribute length is incorrect",
|
||||||
.description = "BGP attribute length is incorrect",
|
.description = "BGP attribute length is incorrect",
|
||||||
.suggestion = "Determine the soure of the attribute and determine why the attribute length has been set incorrectly"
|
.suggestion = "Determine the source of the attribute and determine why the attribute length has been set incorrectly"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_ATTR_ORIGIN,
|
.code = EC_BGP_ATTR_ORIGIN,
|
||||||
.title = "BGP attribute origin value invalid",
|
.title = "BGP attribute origin value invalid",
|
||||||
.description = "BGP attribute origin value is invalid",
|
.description = "BGP attribute origin value is invalid",
|
||||||
.suggestion = "Determine the soure of the attribute and determine why the origin attribute has been set incorrectly"
|
.suggestion = "Determine the source of the attribute and determine why the origin attribute has been set incorrectly"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_ATTR_MAL_AS_PATH,
|
.code = EC_BGP_ATTR_MAL_AS_PATH,
|
||||||
.title = "BGP as path is invalid",
|
.title = "BGP as path is invalid",
|
||||||
.description = "BGP as path has been malformed",
|
.description = "BGP as path has been malformed",
|
||||||
.suggestion = "Determine the soure of the update and determine why the as path has been set incorrectly"
|
.suggestion = "Determine the source of the update and determine why the as path has been set incorrectly"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_ATTR_FIRST_AS,
|
.code = EC_BGP_ATTR_FIRST_AS,
|
||||||
.title = "BGP as path first as is invalid",
|
.title = "BGP as path first as is invalid",
|
||||||
.description = "BGP update has invalid first as in as path",
|
.description = "BGP update has invalid first as in as path",
|
||||||
.suggestion = "Determine the soure of the update and determine why the as path first as value has been set incorrectly"
|
.suggestion = "Determine the source of the update and determine why the as path first as value has been set incorrectly"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_ATTR_PMSI_TYPE,
|
.code = EC_BGP_ATTR_PMSI_TYPE,
|
||||||
.title = "BGP PMSI tunnel attribute type is invalid",
|
.title = "BGP PMSI tunnel attribute type is invalid",
|
||||||
.description = "BGP update has invalid type for PMSI tunnel",
|
.description = "BGP update has invalid type for PMSI tunnel",
|
||||||
.suggestion = "Determine the soure of the update and determine why the PMSI tunnel attribute type has been set incorrectly"
|
.suggestion = "Determine the source of the update and determine why the PMSI tunnel attribute type has been set incorrectly"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_ATTR_PMSI_LEN,
|
.code = EC_BGP_ATTR_PMSI_LEN,
|
||||||
.title = "BGP PMSI tunnel attribute length is invalid",
|
.title = "BGP PMSI tunnel attribute length is invalid",
|
||||||
.description = "BGP update has invalid length for PMSI tunnel",
|
.description = "BGP update has invalid length for PMSI tunnel",
|
||||||
.suggestion = "Determine the soure of the update and determine why the PMSI tunnel attribute length has been set incorrectly"
|
.suggestion = "Determine the source of the update and determine why the PMSI tunnel attribute length has been set incorrectly"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_PEER_GROUP,
|
.code = EC_BGP_PEER_GROUP,
|
||||||
@ -269,7 +269,7 @@ static struct log_ref ferr_bgp_err[] = {
|
|||||||
.code = EC_BGP_JSON_MEM_ERROR,
|
.code = EC_BGP_JSON_MEM_ERROR,
|
||||||
.title = "BGP unable to allocate memory for JSON output",
|
.title = "BGP unable to allocate memory for JSON output",
|
||||||
.description = "BGP attempted to generate JSON output and was unable to allocate the memory required",
|
.description = "BGP attempted to generate JSON output and was unable to allocate the memory required",
|
||||||
.suggestion = "Ensure that the device has adequate memory to suport the required functions"
|
.suggestion = "Ensure that the device has adequate memory to support the required functions"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = EC_BGP_UPDGRP_ATTR_LEN,
|
.code = EC_BGP_UPDGRP_ATTR_LEN,
|
||||||
|
1001
bgpd/bgp_evpn.c
1001
bgpd/bgp_evpn.c
File diff suppressed because it is too large
Load Diff
@ -76,9 +76,9 @@ static inline int advertise_type5_routes(struct bgp *bgp_vrf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Flag if the route's parent is a EVPN route. */
|
/* Flag if the route's parent is a EVPN route. */
|
||||||
static inline int is_route_parent_evpn(struct bgp_info *ri)
|
static inline int is_route_parent_evpn(struct bgp_path_info *ri)
|
||||||
{
|
{
|
||||||
struct bgp_info *parent_ri;
|
struct bgp_path_info *parent_ri;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ static inline int is_route_parent_evpn(struct bgp_info *ri)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* See if the parent is of family L2VPN/EVPN */
|
/* See if the parent is of family L2VPN/EVPN */
|
||||||
parent_ri = (struct bgp_info *)ri->extra->parent;
|
parent_ri = (struct bgp_path_info *)ri->extra->parent;
|
||||||
rn = parent_ri->net;
|
rn = parent_ri->net;
|
||||||
if (!rn)
|
if (!rn)
|
||||||
return 0;
|
return 0;
|
||||||
@ -124,9 +124,9 @@ extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
|
|||||||
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
|
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
|
||||||
struct bgp_nlri *packet, int withdraw);
|
struct bgp_nlri *packet, int withdraw);
|
||||||
extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct prefix *p, struct bgp_info *ri);
|
struct prefix *p, struct bgp_path_info *ri);
|
||||||
extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct prefix *p, struct bgp_info *ri);
|
struct prefix *p, struct bgp_path_info *ri);
|
||||||
extern int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp);
|
extern int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp);
|
||||||
extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
|
extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
|
||||||
struct ethaddr *mac, struct ipaddr *ip);
|
struct ethaddr *mac, struct ipaddr *ip);
|
||||||
@ -145,6 +145,7 @@ extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
|
|||||||
struct ipaddr *originator_ip);
|
struct ipaddr *originator_ip);
|
||||||
extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi,
|
extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi,
|
||||||
struct ipaddr *originator_ip);
|
struct ipaddr *originator_ip);
|
||||||
|
extern void bgp_evpn_flood_control_change(struct bgp *bgp);
|
||||||
extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);
|
extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);
|
||||||
extern void bgp_evpn_cleanup(struct bgp *bgp);
|
extern void bgp_evpn_cleanup(struct bgp *bgp);
|
||||||
extern void bgp_evpn_init(struct bgp *bgp);
|
extern void bgp_evpn_init(struct bgp *bgp);
|
||||||
|
@ -536,7 +536,7 @@ static void show_esi_routes(struct bgp *bgp,
|
|||||||
{
|
{
|
||||||
int header = 1;
|
int header = 1;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
uint32_t prefix_cnt, path_cnt;
|
uint32_t prefix_cnt, path_cnt;
|
||||||
uint64_t tbl_ver;
|
uint64_t tbl_ver;
|
||||||
|
|
||||||
@ -573,13 +573,13 @@ static void show_esi_routes(struct bgp *bgp,
|
|||||||
/* For EVPN, the prefix is displayed for each path (to fit in
|
/* For EVPN, the prefix is displayed for each path (to fit in
|
||||||
* with code that already exists).
|
* with code that already exists).
|
||||||
*/
|
*/
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out(vty, &rn->p, ri, 0, SAFI_EVPN, json_path);
|
route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN, json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_object_array_add(json_paths, json_path);
|
json_object_array_add(json_paths, json_path);
|
||||||
@ -616,7 +616,7 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
|
|||||||
json_object *json)
|
json_object *json)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
int header = 1;
|
int header = 1;
|
||||||
uint64_t tbl_ver;
|
uint64_t tbl_ver;
|
||||||
@ -660,18 +660,18 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
|
|||||||
/* For EVPN, the prefix is displayed for each path (to fit in
|
/* For EVPN, the prefix is displayed for each path (to fit in
|
||||||
* with code that already exists).
|
* with code that already exists).
|
||||||
*/
|
*/
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (vtep_ip.s_addr
|
if (vtep_ip.s_addr
|
||||||
&& !IPV4_ADDR_SAME(&(vtep_ip),
|
&& !IPV4_ADDR_SAME(&(vtep_ip),
|
||||||
&(ri->attr->nexthop)))
|
&(pi->attr->nexthop)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out(vty, &rn->p, ri, 0, SAFI_EVPN, json_path);
|
route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN, json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_object_array_add(json_paths, json_path);
|
json_object_array_add(json_paths, json_path);
|
||||||
@ -990,7 +990,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
|||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_node *rm;
|
struct bgp_node *rm;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
int rd_header;
|
int rd_header;
|
||||||
int header = 1;
|
int header = 1;
|
||||||
|
|
||||||
@ -1046,14 +1046,14 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
|||||||
tbl_ver = table->version;
|
tbl_ver = table->version;
|
||||||
|
|
||||||
for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm))
|
for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm))
|
||||||
for (ri = rm->info; ri; ri = ri->next) {
|
for (pi = rm->info; pi; pi = pi->next) {
|
||||||
total_count++;
|
total_count++;
|
||||||
if (type == bgp_show_type_neighbor) {
|
if (type == bgp_show_type_neighbor) {
|
||||||
union sockunion *su = output_arg;
|
union sockunion *su = output_arg;
|
||||||
|
|
||||||
if (ri->peer->su_remote == NULL
|
if (pi->peer->su_remote == NULL
|
||||||
|| !sockunion_same(
|
|| !sockunion_same(
|
||||||
ri->peer->su_remote, su))
|
pi->peer->su_remote, su))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (header == 0) {
|
if (header == 0) {
|
||||||
@ -1162,14 +1162,14 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
|||||||
else
|
else
|
||||||
json_array = NULL;
|
json_array = NULL;
|
||||||
if (option == SHOW_DISPLAY_TAGS)
|
if (option == SHOW_DISPLAY_TAGS)
|
||||||
route_vty_out_tag(vty, &rm->p, ri, 0,
|
route_vty_out_tag(vty, &rm->p, pi, 0,
|
||||||
SAFI_EVPN,
|
SAFI_EVPN,
|
||||||
json_array);
|
json_array);
|
||||||
else if (option == SHOW_DISPLAY_OVERLAY)
|
else if (option == SHOW_DISPLAY_OVERLAY)
|
||||||
route_vty_out_overlay(vty, &rm->p, ri,
|
route_vty_out_overlay(vty, &rm->p, pi,
|
||||||
0, json_array);
|
0, json_array);
|
||||||
else
|
else
|
||||||
route_vty_out(vty, &rm->p, ri, 0,
|
route_vty_out(vty, &rm->p, pi, 0,
|
||||||
SAFI_EVPN, json_array);
|
SAFI_EVPN, json_array);
|
||||||
output_count++;
|
output_count++;
|
||||||
}
|
}
|
||||||
@ -2017,7 +2017,7 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
|
|||||||
struct bgpevpn *vpn;
|
struct bgpevpn *vpn;
|
||||||
struct prefix_evpn p;
|
struct prefix_evpn p;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
uint32_t path_cnt = 0;
|
uint32_t path_cnt = 0;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
@ -2049,13 +2049,13 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
|
|||||||
route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
|
route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
|
||||||
|
|
||||||
/* Display each path for this prefix. */
|
/* Display each path for this prefix. */
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out_detail(vty, bgp, &rn->p, ri, afi, safi,
|
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2086,7 +2086,7 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
|
|||||||
struct bgpevpn *vpn;
|
struct bgpevpn *vpn;
|
||||||
struct prefix_evpn p;
|
struct prefix_evpn p;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
uint32_t path_cnt = 0;
|
uint32_t path_cnt = 0;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
@ -2119,13 +2119,13 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
|
|||||||
route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
|
route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
|
||||||
|
|
||||||
/* Display each path for this prefix. */
|
/* Display each path for this prefix. */
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out_detail(vty, bgp, &rn->p, ri, afi, safi,
|
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2196,7 +2196,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
|
|||||||
{
|
{
|
||||||
struct prefix_evpn p;
|
struct prefix_evpn p;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
uint32_t path_cnt = 0;
|
uint32_t path_cnt = 0;
|
||||||
@ -2226,13 +2226,13 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
|
|||||||
json_paths = json_object_new_array();
|
json_paths = json_object_new_array();
|
||||||
|
|
||||||
/* Display each path for this prefix. */
|
/* Display each path for this prefix. */
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out_detail(vty, bgp, &rn->p, ri, afi, safi,
|
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2262,7 +2262,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
|
|||||||
struct bgp_node *rd_rn;
|
struct bgp_node *rd_rn;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
int rd_header = 1;
|
int rd_header = 1;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
@ -2330,13 +2330,13 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
|
|||||||
json_paths = json_object_new_array();
|
json_paths = json_object_new_array();
|
||||||
|
|
||||||
/* Display each path for this prefix. */
|
/* Display each path for this prefix. */
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out_detail(vty, bgp, &rn->p, ri, afi, safi,
|
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2383,7 +2383,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
|
|||||||
struct bgp_node *rd_rn;
|
struct bgp_node *rd_rn;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
int header = 1;
|
int header = 1;
|
||||||
int rd_header;
|
int rd_header;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
@ -2467,7 +2467,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
|
|||||||
* fit in
|
* fit in
|
||||||
* with code that already exists).
|
* with code that already exists).
|
||||||
*/
|
*/
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
json_object *json_path = NULL;
|
json_object *json_path = NULL;
|
||||||
path_cnt++;
|
path_cnt++;
|
||||||
add_prefix_to_json = 1;
|
add_prefix_to_json = 1;
|
||||||
@ -2476,7 +2476,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
|
|||||||
if (json)
|
if (json)
|
||||||
json_path = json_object_new_array();
|
json_path = json_object_new_array();
|
||||||
|
|
||||||
route_vty_out(vty, &rn->p, ri, 0, SAFI_EVPN,
|
route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN,
|
||||||
json_path);
|
json_path);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
@ -2807,6 +2807,40 @@ static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef VTYSH_EXTRACT_PL
|
||||||
|
#include "bgpd/bgp_evpn_vty_clippy.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEFPY(bgp_evpn_flood_control,
|
||||||
|
bgp_evpn_flood_control_cmd,
|
||||||
|
"[no$no] flooding <disable$disable|head-end-replication$her>",
|
||||||
|
NO_STR
|
||||||
|
"Specify handling for BUM packets\n"
|
||||||
|
"Do not flood any BUM packets\n"
|
||||||
|
"Flood BUM packets using head-end replication\n")
|
||||||
|
{
|
||||||
|
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||||
|
enum vxlan_flood_control flood_ctrl;
|
||||||
|
|
||||||
|
if (!bgp)
|
||||||
|
return CMD_WARNING;
|
||||||
|
|
||||||
|
if (disable && !no)
|
||||||
|
flood_ctrl = VXLAN_FLOOD_DISABLED;
|
||||||
|
else if (her || no)
|
||||||
|
flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;
|
||||||
|
else
|
||||||
|
return CMD_WARNING;
|
||||||
|
|
||||||
|
if (bgp->vxlan_flood_ctrl == flood_ctrl)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
bgp->vxlan_flood_ctrl = flood_ctrl;
|
||||||
|
bgp_evpn_flood_control_change(bgp);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (bgp_evpn_advertise_default_gw_vni,
|
DEFUN (bgp_evpn_advertise_default_gw_vni,
|
||||||
bgp_evpn_advertise_default_gw_vni_cmd,
|
bgp_evpn_advertise_default_gw_vni_cmd,
|
||||||
"advertise-default-gw",
|
"advertise-default-gw",
|
||||||
@ -3210,6 +3244,12 @@ DEFUN(show_bgp_l2vpn_evpn_vni,
|
|||||||
json_object_string_add(json, "advertiseAllVnis",
|
json_object_string_add(json, "advertiseAllVnis",
|
||||||
is_evpn_enabled() ? "Enabled"
|
is_evpn_enabled() ? "Enabled"
|
||||||
: "Disabled");
|
: "Disabled");
|
||||||
|
json_object_string_add(
|
||||||
|
json, "flooding",
|
||||||
|
bgp_def->vxlan_flood_ctrl
|
||||||
|
== VXLAN_FLOOD_HEAD_END_REPL
|
||||||
|
? "Head-end replication"
|
||||||
|
: "Disabled");
|
||||||
json_object_int_add(json, "numVnis", num_vnis);
|
json_object_int_add(json, "numVnis", num_vnis);
|
||||||
json_object_int_add(json, "numL2Vnis", num_l2vnis);
|
json_object_int_add(json, "numL2Vnis", num_l2vnis);
|
||||||
json_object_int_add(json, "numL3Vnis", num_l3vnis);
|
json_object_int_add(json, "numL3Vnis", num_l3vnis);
|
||||||
@ -3219,6 +3259,11 @@ DEFUN(show_bgp_l2vpn_evpn_vni,
|
|||||||
: "Disabled");
|
: "Disabled");
|
||||||
vty_out(vty, "Advertise All VNI flag: %s\n",
|
vty_out(vty, "Advertise All VNI flag: %s\n",
|
||||||
is_evpn_enabled() ? "Enabled" : "Disabled");
|
is_evpn_enabled() ? "Enabled" : "Disabled");
|
||||||
|
vty_out(vty, "BUM flooding: %s\n",
|
||||||
|
bgp_def->vxlan_flood_ctrl
|
||||||
|
== VXLAN_FLOOD_HEAD_END_REPL
|
||||||
|
? "Head-end replication"
|
||||||
|
: "Disabled");
|
||||||
vty_out(vty, "Number of L2 VNIs: %u\n", num_l2vnis);
|
vty_out(vty, "Number of L2 VNIs: %u\n", num_l2vnis);
|
||||||
vty_out(vty, "Number of L3 VNIs: %u\n", num_l3vnis);
|
vty_out(vty, "Number of L3 VNIs: %u\n", num_l3vnis);
|
||||||
}
|
}
|
||||||
@ -3954,7 +3999,7 @@ DEFUN(test_withdraw_evpn_type4_route,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!bgp->peer_self) {
|
if (!bgp->peer_self) {
|
||||||
vty_out(vty, "%%BGP instance doesnt have self peer\n");
|
vty_out(vty, "%%BGP instance doesn't have self peer\n");
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4874,6 +4919,9 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
if (bgp->advertise_gw_macip)
|
if (bgp->advertise_gw_macip)
|
||||||
vty_out(vty, " advertise-default-gw\n");
|
vty_out(vty, " advertise-default-gw\n");
|
||||||
|
|
||||||
|
if (bgp->vxlan_flood_ctrl == VXLAN_FLOOD_DISABLED)
|
||||||
|
vty_out(vty, " flooding disable\n");
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
|
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) {
|
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) {
|
||||||
if (bgp->adv_cmd_rmap[AFI_IP][SAFI_UNICAST].name)
|
if (bgp->adv_cmd_rmap[AFI_IP][SAFI_UNICAST].name)
|
||||||
@ -4965,6 +5013,7 @@ void bgp_ethernetvpn_init(void)
|
|||||||
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
|
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
|
||||||
install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd);
|
install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd);
|
||||||
install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);
|
install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);
|
||||||
|
install_element(BGP_EVPN_NODE, &bgp_evpn_flood_control_cmd);
|
||||||
|
|
||||||
/* test commands */
|
/* test commands */
|
||||||
install_element(BGP_EVPN_NODE, &test_adv_evpn_type4_route_cmd);
|
install_element(BGP_EVPN_NODE, &test_adv_evpn_type4_route_cmd);
|
||||||
|
@ -77,7 +77,7 @@ struct as_list {
|
|||||||
struct as_filter *tail;
|
struct as_filter *tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ip as-path access-list 10 permit AS1. */
|
/* as-path access-list 10 permit AS1. */
|
||||||
|
|
||||||
static struct as_list_master as_list_master = {{NULL, NULL},
|
static struct as_list_master as_list_master = {{NULL, NULL},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
@ -401,9 +401,9 @@ static int config_bgp_aspath_validate(const char *regstr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN(ip_as_path, ip_as_path_cmd,
|
DEFUN(as_path, bgp_as_path_cmd,
|
||||||
"ip as-path access-list WORD <deny|permit> LINE...",
|
"bgp as-path access-list WORD <deny|permit> LINE...",
|
||||||
IP_STR
|
BGP_STR
|
||||||
"BGP autonomous system path filter\n"
|
"BGP autonomous system path filter\n"
|
||||||
"Specify an access list name\n"
|
"Specify an access list name\n"
|
||||||
"Regular expression access list name\n"
|
"Regular expression access list name\n"
|
||||||
@ -418,6 +418,13 @@ DEFUN(ip_as_path, ip_as_path_cmd,
|
|||||||
regex_t *regex;
|
regex_t *regex;
|
||||||
char *regstr;
|
char *regstr;
|
||||||
|
|
||||||
|
if (argv_find(argv, argc, "ip", &idx)) {
|
||||||
|
vty_out(vty, "This config option is deprecated and is scheduled for removal.\n");
|
||||||
|
vty_out(vty, "if you are using this please migrate to the below command\n");
|
||||||
|
vty_out(vty, "'bgp as-path access-list WORD <deny|permit> LINE'\n");
|
||||||
|
zlog_warn("Deprecated option: 'ip as-path access-list WORD <deny|permit> LINE' being used");
|
||||||
|
}
|
||||||
|
|
||||||
/* Retrieve access list name */
|
/* Retrieve access list name */
|
||||||
argv_find(argv, argc, "WORD", &idx);
|
argv_find(argv, argc, "WORD", &idx);
|
||||||
char *alname = argv[idx]->arg;
|
char *alname = argv[idx]->arg;
|
||||||
@ -459,9 +466,23 @@ DEFUN(ip_as_path, ip_as_path_cmd,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN(no_ip_as_path, no_ip_as_path_cmd,
|
#if CONFDATE > 20191005
|
||||||
"no ip as-path access-list WORD <deny|permit> LINE...",
|
CPP_NOTICE("bgpd: remove deprecated 'ip as-path access-list WORD <deny|permit> LINE' command")
|
||||||
NO_STR IP_STR
|
#endif
|
||||||
|
ALIAS(as_path, ip_as_path_cmd,
|
||||||
|
"ip as-path access-list WORD <deny|permit> LINE...",
|
||||||
|
IP_STR
|
||||||
|
"BGP autonomous system path filter\n"
|
||||||
|
"Specify an access list name\n"
|
||||||
|
"Regular expression access list name\n"
|
||||||
|
"Specify packets to reject\n"
|
||||||
|
"Specify packets to forward\n"
|
||||||
|
"A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n")
|
||||||
|
|
||||||
|
DEFUN(no_as_path, no_bgp_as_path_cmd,
|
||||||
|
"no bgp as-path access-list WORD <deny|permit> LINE...",
|
||||||
|
NO_STR
|
||||||
|
BGP_STR
|
||||||
"BGP autonomous system path filter\n"
|
"BGP autonomous system path filter\n"
|
||||||
"Specify an access list name\n"
|
"Specify an access list name\n"
|
||||||
"Regular expression access list name\n"
|
"Regular expression access list name\n"
|
||||||
@ -476,13 +497,19 @@ DEFUN(no_ip_as_path, no_ip_as_path_cmd,
|
|||||||
char *regstr;
|
char *regstr;
|
||||||
regex_t *regex;
|
regex_t *regex;
|
||||||
|
|
||||||
|
if (argv_find(argv, argc, "ip", &idx)) {
|
||||||
|
vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
|
||||||
|
vty_out(vty, "if you are using this please migrate to the below command\n");
|
||||||
|
vty_out(vty, "'no bgp as-path access-list WORD <deny|permit> LINE'\n");
|
||||||
|
zlog_warn("Deprecated option: 'no ip as-path access-list WORD <deny|permit> LINE' being used");
|
||||||
|
}
|
||||||
char *aslistname =
|
char *aslistname =
|
||||||
argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
|
argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
|
||||||
|
|
||||||
/* Lookup AS list from AS path list. */
|
/* Lookup AS list from AS path list. */
|
||||||
aslist = as_list_lookup(aslistname);
|
aslist = as_list_lookup(aslistname);
|
||||||
if (aslist == NULL) {
|
if (aslist == NULL) {
|
||||||
vty_out(vty, "ip as-path access-list %s doesn't exist\n",
|
vty_out(vty, "bgp as-path access-list %s doesn't exist\n",
|
||||||
aslistname);
|
aslistname);
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
}
|
}
|
||||||
@ -530,21 +557,39 @@ DEFUN(no_ip_as_path, no_ip_as_path_cmd,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (no_ip_as_path_all,
|
ALIAS(no_as_path, no_ip_as_path_cmd,
|
||||||
no_ip_as_path_all_cmd,
|
"no ip as-path access-list WORD <deny|permit> LINE...",
|
||||||
"no ip as-path access-list WORD",
|
NO_STR IP_STR
|
||||||
|
"BGP autonomous system path filter\n"
|
||||||
|
"Specify an access list name\n"
|
||||||
|
"Regular expression access list name\n"
|
||||||
|
"Specify packets to reject\n"
|
||||||
|
"Specify packets to forward\n"
|
||||||
|
"A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n")
|
||||||
|
|
||||||
|
DEFUN (no_as_path_all,
|
||||||
|
no_bgp_as_path_all_cmd,
|
||||||
|
"no bgp as-path access-list WORD",
|
||||||
NO_STR
|
NO_STR
|
||||||
IP_STR
|
BGP_STR
|
||||||
"BGP autonomous system path filter\n"
|
"BGP autonomous system path filter\n"
|
||||||
"Specify an access list name\n"
|
"Specify an access list name\n"
|
||||||
"Regular expression access list name\n")
|
"Regular expression access list name\n")
|
||||||
{
|
{
|
||||||
int idx_word = 4;
|
int idx_word = 4;
|
||||||
struct as_list *aslist;
|
struct as_list *aslist;
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
if (argv_find(argv, argc, "ip", &idx)) {
|
||||||
|
vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
|
||||||
|
vty_out(vty, "if you are using this please migrate to the below command\n");
|
||||||
|
vty_out(vty, "'no bgp as-path access-list WORD'\n");
|
||||||
|
zlog_warn("Deprecated option: `no ip as-path access-list WORD` being used");
|
||||||
|
}
|
||||||
|
|
||||||
aslist = as_list_lookup(argv[idx_word]->arg);
|
aslist = as_list_lookup(argv[idx_word]->arg);
|
||||||
if (aslist == NULL) {
|
if (aslist == NULL) {
|
||||||
vty_out(vty, "ip as-path access-list %s doesn't exist\n",
|
vty_out(vty, "bgp as-path access-list %s doesn't exist\n",
|
||||||
argv[idx_word]->arg);
|
argv[idx_word]->arg);
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
}
|
}
|
||||||
@ -558,6 +603,15 @@ DEFUN (no_ip_as_path_all,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS (no_as_path_all,
|
||||||
|
no_ip_as_path_all_cmd,
|
||||||
|
"no ip as-path access-list WORD",
|
||||||
|
NO_STR
|
||||||
|
IP_STR
|
||||||
|
"BGP autonomous system path filter\n"
|
||||||
|
"Specify an access list name\n"
|
||||||
|
"Regular expression access list name\n")
|
||||||
|
|
||||||
static void as_list_show(struct vty *vty, struct as_list *aslist)
|
static void as_list_show(struct vty *vty, struct as_list *aslist)
|
||||||
{
|
{
|
||||||
struct as_filter *asfilter;
|
struct as_filter *asfilter;
|
||||||
@ -598,17 +652,24 @@ static void as_list_show_all(struct vty *vty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (show_ip_as_path_access_list,
|
DEFUN (show_as_path_access_list,
|
||||||
show_ip_as_path_access_list_cmd,
|
show_bgp_as_path_access_list_cmd,
|
||||||
"show ip as-path-access-list WORD",
|
"show bgp as-path-access-list WORD",
|
||||||
SHOW_STR
|
SHOW_STR
|
||||||
IP_STR
|
BGP_STR
|
||||||
"List AS path access lists\n"
|
"List AS path access lists\n"
|
||||||
"AS path access list name\n")
|
"AS path access list name\n")
|
||||||
{
|
{
|
||||||
int idx_word = 3;
|
int idx_word = 3;
|
||||||
struct as_list *aslist;
|
struct as_list *aslist;
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
if (argv_find(argv, argc, "ip", &idx)) {
|
||||||
|
vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
|
||||||
|
vty_out(vty, "if you are using this please migrate to the below command\n");
|
||||||
|
vty_out(vty, "'show bgp as-path-access-list WORD'\n");
|
||||||
|
zlog_warn("Deprecated option: 'show ip as-path-access-list WORD' being used");
|
||||||
|
}
|
||||||
aslist = as_list_lookup(argv[idx_word]->arg);
|
aslist = as_list_lookup(argv[idx_word]->arg);
|
||||||
if (aslist)
|
if (aslist)
|
||||||
as_list_show(vty, aslist);
|
as_list_show(vty, aslist);
|
||||||
@ -616,16 +677,39 @@ DEFUN (show_ip_as_path_access_list,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (show_ip_as_path_access_list_all,
|
ALIAS (show_as_path_access_list,
|
||||||
|
show_ip_as_path_access_list_cmd,
|
||||||
|
"show ip as-path-access-list WORD",
|
||||||
|
SHOW_STR
|
||||||
|
IP_STR
|
||||||
|
"List AS path access lists\n"
|
||||||
|
"AS path access list name\n")
|
||||||
|
|
||||||
|
DEFUN (show_as_path_access_list_all,
|
||||||
|
show_bgp_as_path_access_list_all_cmd,
|
||||||
|
"show bgp as-path-access-list",
|
||||||
|
SHOW_STR
|
||||||
|
BGP_STR
|
||||||
|
"List AS path access lists\n")
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
if (argv_find(argv, argc, "ip", &idx)) {
|
||||||
|
vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
|
||||||
|
vty_out(vty, "if you are using this please migrate to the below command\n");
|
||||||
|
vty_out(vty, "'show bgp as-path-access-list'\n");
|
||||||
|
zlog_warn("Deprecated option: 'show ip as-path-access-list' being used");
|
||||||
|
}
|
||||||
|
as_list_show_all(vty);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIAS (show_as_path_access_list_all,
|
||||||
show_ip_as_path_access_list_all_cmd,
|
show_ip_as_path_access_list_all_cmd,
|
||||||
"show ip as-path-access-list",
|
"show ip as-path-access-list",
|
||||||
SHOW_STR
|
SHOW_STR
|
||||||
IP_STR
|
IP_STR
|
||||||
"List AS path access lists\n")
|
"List AS path access lists\n")
|
||||||
{
|
|
||||||
as_list_show_all(vty);
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int config_write_as_list(struct vty *vty)
|
static int config_write_as_list(struct vty *vty)
|
||||||
{
|
{
|
||||||
@ -636,7 +720,7 @@ static int config_write_as_list(struct vty *vty)
|
|||||||
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
|
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
|
||||||
for (asfilter = aslist->head; asfilter;
|
for (asfilter = aslist->head; asfilter;
|
||||||
asfilter = asfilter->next) {
|
asfilter = asfilter->next) {
|
||||||
vty_out(vty, "ip as-path access-list %s %s %s\n",
|
vty_out(vty, "bgp as-path access-list %s %s %s\n",
|
||||||
aslist->name, filter_type_str(asfilter->type),
|
aslist->name, filter_type_str(asfilter->type),
|
||||||
asfilter->reg_str);
|
asfilter->reg_str);
|
||||||
write++;
|
write++;
|
||||||
@ -645,7 +729,7 @@ static int config_write_as_list(struct vty *vty)
|
|||||||
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
|
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
|
||||||
for (asfilter = aslist->head; asfilter;
|
for (asfilter = aslist->head; asfilter;
|
||||||
asfilter = asfilter->next) {
|
asfilter = asfilter->next) {
|
||||||
vty_out(vty, "ip as-path access-list %s %s %s\n",
|
vty_out(vty, "bgp as-path access-list %s %s %s\n",
|
||||||
aslist->name, filter_type_str(asfilter->type),
|
aslist->name, filter_type_str(asfilter->type),
|
||||||
asfilter->reg_str);
|
asfilter->reg_str);
|
||||||
write++;
|
write++;
|
||||||
@ -660,11 +744,16 @@ void bgp_filter_init(void)
|
|||||||
{
|
{
|
||||||
install_node(&as_list_node, config_write_as_list);
|
install_node(&as_list_node, config_write_as_list);
|
||||||
|
|
||||||
|
install_element(CONFIG_NODE, &bgp_as_path_cmd);
|
||||||
install_element(CONFIG_NODE, &ip_as_path_cmd);
|
install_element(CONFIG_NODE, &ip_as_path_cmd);
|
||||||
|
install_element(CONFIG_NODE, &no_bgp_as_path_cmd);
|
||||||
install_element(CONFIG_NODE, &no_ip_as_path_cmd);
|
install_element(CONFIG_NODE, &no_ip_as_path_cmd);
|
||||||
|
install_element(CONFIG_NODE, &no_bgp_as_path_all_cmd);
|
||||||
install_element(CONFIG_NODE, &no_ip_as_path_all_cmd);
|
install_element(CONFIG_NODE, &no_ip_as_path_all_cmd);
|
||||||
|
|
||||||
|
install_element(VIEW_NODE, &show_bgp_as_path_access_list_cmd);
|
||||||
install_element(VIEW_NODE, &show_ip_as_path_access_list_cmd);
|
install_element(VIEW_NODE, &show_ip_as_path_access_list_cmd);
|
||||||
|
install_element(VIEW_NODE, &show_bgp_as_path_access_list_all_cmd);
|
||||||
install_element(VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
|
install_element(VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ extern void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
|
|||||||
json_object *json_path);
|
json_object *json_path);
|
||||||
|
|
||||||
extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path, int display,
|
||||||
int display, json_object *json_paths);
|
json_object *json_paths);
|
||||||
extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp,
|
extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp,
|
||||||
afi_t afi, safi_t safi);
|
afi_t afi, safi_t safi);
|
||||||
|
|
||||||
|
@ -253,8 +253,8 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path, int display,
|
||||||
int display, json_object *json_paths)
|
json_object *json_paths)
|
||||||
{
|
{
|
||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
char return_string[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
|
char return_string[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
|
||||||
@ -274,9 +274,9 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
|||||||
else
|
else
|
||||||
json_nlri_path = json_paths;
|
json_nlri_path = json_paths;
|
||||||
}
|
}
|
||||||
if (display == NLRI_STRING_FORMAT_LARGE && binfo)
|
if (display == NLRI_STRING_FORMAT_LARGE && path)
|
||||||
vty_out(vty, "BGP flowspec entry: (flags 0x%x)\n",
|
vty_out(vty, "BGP flowspec entry: (flags 0x%x)\n",
|
||||||
binfo->flags);
|
path->flags);
|
||||||
bgp_fs_nlri_get_string((unsigned char *)
|
bgp_fs_nlri_get_string((unsigned char *)
|
||||||
p->u.prefix_flowspec.ptr,
|
p->u.prefix_flowspec.ptr,
|
||||||
p->u.prefix_flowspec.prefixlen,
|
p->u.prefix_flowspec.prefixlen,
|
||||||
@ -292,11 +292,11 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
|||||||
else if (json_paths && display == NLRI_STRING_FORMAT_JSON)
|
else if (json_paths && display == NLRI_STRING_FORMAT_JSON)
|
||||||
json_object_array_add(json_paths, json_nlri_path);
|
json_object_array_add(json_paths, json_nlri_path);
|
||||||
}
|
}
|
||||||
if (!binfo)
|
if (!path)
|
||||||
return;
|
return;
|
||||||
if (binfo->attr && binfo->attr->ecommunity) {
|
if (path->attr && path->attr->ecommunity) {
|
||||||
/* Print attribute */
|
/* Print attribute */
|
||||||
attr = binfo->attr;
|
attr = path->attr;
|
||||||
s = ecommunity_ecom2str(attr->ecommunity,
|
s = ecommunity_ecom2str(attr->ecommunity,
|
||||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
if (!s)
|
if (!s)
|
||||||
@ -318,7 +318,7 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
|||||||
vty_out(vty, "\tNH %-16s\n", inet_ntoa(attr->nexthop));
|
vty_out(vty, "\tNH %-16s\n", inet_ntoa(attr->nexthop));
|
||||||
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
||||||
}
|
}
|
||||||
peer_uptime(binfo->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL);
|
peer_uptime(path->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL);
|
||||||
if (display == NLRI_STRING_FORMAT_LARGE) {
|
if (display == NLRI_STRING_FORMAT_LARGE) {
|
||||||
vty_out(vty, "\treceived for %8s\n", timebuf);
|
vty_out(vty, "\treceived for %8s\n", timebuf);
|
||||||
} else if (json_paths) {
|
} else if (json_paths) {
|
||||||
@ -329,7 +329,8 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
|
|||||||
json_object_array_add(json_paths, json_time_path);
|
json_object_array_add(json_paths, json_time_path);
|
||||||
}
|
}
|
||||||
if (display == NLRI_STRING_FORMAT_LARGE) {
|
if (display == NLRI_STRING_FORMAT_LARGE) {
|
||||||
struct bgp_info_extra *extra = bgp_info_extra_get(binfo);
|
struct bgp_path_info_extra *extra =
|
||||||
|
bgp_path_info_extra_get(path);
|
||||||
|
|
||||||
if (extra->bgp_fs_pbr) {
|
if (extra->bgp_fs_pbr) {
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
@ -368,7 +369,7 @@ int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
void *output_arg, bool use_json, int is_last,
|
void *output_arg, bool use_json, int is_last,
|
||||||
unsigned long *output_cum, unsigned long *total_cum)
|
unsigned long *output_cum, unsigned long *total_cum)
|
||||||
{
|
{
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
unsigned long total_count = 0;
|
unsigned long total_count = 0;
|
||||||
json_object *json_paths = NULL;
|
json_object *json_paths = NULL;
|
||||||
@ -384,12 +385,10 @@ int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
json_paths = json_object_new_array();
|
json_paths = json_object_new_array();
|
||||||
display = NLRI_STRING_FORMAT_JSON;
|
display = NLRI_STRING_FORMAT_JSON;
|
||||||
}
|
}
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
total_count++;
|
total_count++;
|
||||||
route_vty_out_flowspec(vty, &rn->p,
|
route_vty_out_flowspec(vty, &rn->p, pi, display,
|
||||||
ri, display,
|
|
||||||
json_paths);
|
json_paths);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
vty_out(vty, "%s\n",
|
vty_out(vty, "%s\n",
|
||||||
|
@ -931,7 +931,7 @@ static void bgp_update_delay_process_status_change(struct peer *peer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called after event occured, this function change status and reset
|
/* Called after event occurred, this function change status and reset
|
||||||
read/write and timer thread. */
|
read/write and timer thread. */
|
||||||
void bgp_fsm_change_status(struct peer *peer, int status)
|
void bgp_fsm_change_status(struct peer *peer, int status)
|
||||||
{
|
{
|
||||||
@ -1677,6 +1677,15 @@ static int bgp_establish(struct peer *peer)
|
|||||||
peer_delete(peer->doppelganger);
|
peer_delete(peer->doppelganger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are replacing the old peer for a doppelganger
|
||||||
|
* then switch it around in the bgp->peerhash
|
||||||
|
* the doppelgangers su and this peer's su are the same
|
||||||
|
* so the hash_release is the same for either.
|
||||||
|
*/
|
||||||
|
hash_release(peer->bgp->peerhash, peer);
|
||||||
|
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
|
||||||
|
|
||||||
bgp_bfd_register_peer(peer);
|
bgp_bfd_register_peer(peer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -123,10 +123,11 @@ static void peer_process(struct hash_backet *hb, void *arg)
|
|||||||
*next_update = diff;
|
*next_update = diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int peer_hash_cmp(const void *f, const void *s)
|
static bool peer_hash_cmp(const void *f, const void *s)
|
||||||
{
|
{
|
||||||
const struct pkat *p1 = f;
|
const struct pkat *p1 = f;
|
||||||
const struct pkat *p2 = s;
|
const struct pkat *p2 = s;
|
||||||
|
|
||||||
return p1->peer == p2->peer;
|
return p1->peer == p2->peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,18 +94,18 @@ int bgp_parse_fec_update(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
|
mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
struct peer *to, afi_t afi, safi_t safi)
|
struct peer *to, afi_t afi, safi_t safi)
|
||||||
{
|
{
|
||||||
struct peer *from;
|
struct peer *from;
|
||||||
mpls_label_t remote_label;
|
mpls_label_t remote_label;
|
||||||
int reflect;
|
int reflect;
|
||||||
|
|
||||||
if (!rn || !ri || !to)
|
if (!rn || !pi || !to)
|
||||||
return MPLS_INVALID_LABEL;
|
return MPLS_INVALID_LABEL;
|
||||||
|
|
||||||
remote_label = ri->extra ? ri->extra->label[0] : MPLS_INVALID_LABEL;
|
remote_label = pi->extra ? pi->extra->label[0] : MPLS_INVALID_LABEL;
|
||||||
from = ri->peer;
|
from = pi->peer;
|
||||||
reflect =
|
reflect =
|
||||||
((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
|
((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
|
||||||
|
|
||||||
@ -120,7 +120,8 @@ mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
|
|||||||
return rn->local_label;
|
return rn->local_label;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri, int reg)
|
void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
|
int reg)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
@ -142,11 +143,11 @@ void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri, int reg)
|
|||||||
stream_putw(s, PREFIX_FAMILY(p));
|
stream_putw(s, PREFIX_FAMILY(p));
|
||||||
stream_put_prefix(s, p);
|
stream_put_prefix(s, p);
|
||||||
if (reg) {
|
if (reg) {
|
||||||
assert(ri);
|
assert(pi);
|
||||||
if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
|
if (pi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
|
||||||
if (ri->attr->label_index != BGP_INVALID_LABEL_INDEX) {
|
if (pi->attr->label_index != BGP_INVALID_LABEL_INDEX) {
|
||||||
flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
|
flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
|
||||||
stream_putl(s, ri->attr->label_index);
|
stream_putl(s, pi->attr->label_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
|
SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
|
||||||
|
@ -27,13 +27,13 @@
|
|||||||
#define BGP_PREVENT_VRF_2_VRF_LEAK 0xFFFFFFFE
|
#define BGP_PREVENT_VRF_2_VRF_LEAK 0xFFFFFFFE
|
||||||
|
|
||||||
struct bgp_node;
|
struct bgp_node;
|
||||||
struct bgp_info;
|
struct bgp_path_info;
|
||||||
struct peer;
|
struct peer;
|
||||||
|
|
||||||
extern void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri,
|
extern void bgp_reg_dereg_for_label(struct bgp_node *rn,
|
||||||
int reg);
|
struct bgp_path_info *pi, int reg);
|
||||||
extern int bgp_parse_fec_update(void);
|
extern int bgp_parse_fec_update(void);
|
||||||
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
|
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
struct peer *to, afi_t afi, safi_t safi);
|
struct peer *to, afi_t afi, safi_t safi);
|
||||||
|
|
||||||
extern int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
|
extern int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
|
||||||
@ -85,9 +85,9 @@ static inline void bgp_unset_valid_label(mpls_label_t *label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void bgp_register_for_label(struct bgp_node *rn,
|
static inline void bgp_register_for_label(struct bgp_node *rn,
|
||||||
struct bgp_info *ri)
|
struct bgp_path_info *pi)
|
||||||
{
|
{
|
||||||
bgp_reg_dereg_for_label(rn, ri, 1);
|
bgp_reg_dereg_for_label(rn, pi, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bgp_unregister_for_label(struct bgp_node *rn)
|
static inline void bgp_unregister_for_label(struct bgp_node *rn)
|
||||||
|
@ -313,11 +313,17 @@ unsigned int lcommunity_hash_make(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compare two Large Communities Attribute structure. */
|
/* Compare two Large Communities Attribute structure. */
|
||||||
int lcommunity_cmp(const void *arg1, const void *arg2)
|
bool lcommunity_cmp(const void *arg1, const void *arg2)
|
||||||
{
|
{
|
||||||
const struct lcommunity *lcom1 = arg1;
|
const struct lcommunity *lcom1 = arg1;
|
||||||
const struct lcommunity *lcom2 = arg2;
|
const struct lcommunity *lcom2 = arg2;
|
||||||
|
|
||||||
|
if (lcom1 == NULL && lcom2 == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (lcom1 == NULL || lcom2 == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return (lcom1->size == lcom2->size
|
return (lcom1->size == lcom2->size
|
||||||
&& memcmp(lcom1->val, lcom2->val, lcom_length(lcom1)) == 0);
|
&& memcmp(lcom1->val, lcom2->val, lcom_length(lcom1)) == 0);
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ extern struct lcommunity *lcommunity_merge(struct lcommunity *,
|
|||||||
struct lcommunity *);
|
struct lcommunity *);
|
||||||
extern struct lcommunity *lcommunity_uniq_sort(struct lcommunity *);
|
extern struct lcommunity *lcommunity_uniq_sort(struct lcommunity *);
|
||||||
extern struct lcommunity *lcommunity_intern(struct lcommunity *);
|
extern struct lcommunity *lcommunity_intern(struct lcommunity *);
|
||||||
extern int lcommunity_cmp(const void *, const void *);
|
extern bool lcommunity_cmp(const void *arg1, const void *arg2);
|
||||||
extern void lcommunity_unintern(struct lcommunity **);
|
extern void lcommunity_unintern(struct lcommunity **);
|
||||||
extern unsigned int lcommunity_hash_make(void *);
|
extern unsigned int lcommunity_hash_make(void *);
|
||||||
extern struct hash *lcommunity_hash(void);
|
extern struct hash *lcommunity_hash(void);
|
||||||
|
318
bgpd/bgp_mpath.c
318
bgpd/bgp_mpath.c
@ -113,45 +113,47 @@ static int bgp_interface_same(struct interface *ifp1, struct interface *ifp2)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_nexthop_cmp
|
* bgp_path_info_nexthop_cmp
|
||||||
*
|
*
|
||||||
* Compare the nexthops of two paths. Return value is less than, equal to,
|
* Compare the nexthops of two paths. Return value is less than, equal to,
|
||||||
* or greater than zero if bi1 is respectively less than, equal to,
|
* or greater than zero if bpi1 is respectively less than, equal to,
|
||||||
* or greater than bi2.
|
* or greater than bpi2.
|
||||||
*/
|
*/
|
||||||
int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1,
|
||||||
|
struct bgp_path_info *bpi2)
|
||||||
{
|
{
|
||||||
int compare;
|
int compare;
|
||||||
struct in6_addr addr1, addr2;
|
struct in6_addr addr1, addr2;
|
||||||
|
|
||||||
compare = IPV4_ADDR_CMP(&bi1->attr->nexthop, &bi2->attr->nexthop);
|
compare = IPV4_ADDR_CMP(&bpi1->attr->nexthop, &bpi2->attr->nexthop);
|
||||||
if (!compare) {
|
if (!compare) {
|
||||||
if (bi1->attr->mp_nexthop_len == bi2->attr->mp_nexthop_len) {
|
if (bpi1->attr->mp_nexthop_len == bpi2->attr->mp_nexthop_len) {
|
||||||
switch (bi1->attr->mp_nexthop_len) {
|
switch (bpi1->attr->mp_nexthop_len) {
|
||||||
case BGP_ATTR_NHLEN_IPV4:
|
case BGP_ATTR_NHLEN_IPV4:
|
||||||
case BGP_ATTR_NHLEN_VPNV4:
|
case BGP_ATTR_NHLEN_VPNV4:
|
||||||
compare = IPV4_ADDR_CMP(
|
compare = IPV4_ADDR_CMP(
|
||||||
&bi1->attr->mp_nexthop_global_in,
|
&bpi1->attr->mp_nexthop_global_in,
|
||||||
&bi2->attr->mp_nexthop_global_in);
|
&bpi2->attr->mp_nexthop_global_in);
|
||||||
break;
|
break;
|
||||||
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
|
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
|
||||||
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
|
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
|
||||||
compare = IPV6_ADDR_CMP(
|
compare = IPV6_ADDR_CMP(
|
||||||
&bi1->attr->mp_nexthop_global,
|
&bpi1->attr->mp_nexthop_global,
|
||||||
&bi2->attr->mp_nexthop_global);
|
&bpi2->attr->mp_nexthop_global);
|
||||||
break;
|
break;
|
||||||
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
|
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
|
||||||
addr1 = (bi1->attr->mp_nexthop_prefer_global)
|
addr1 = (bpi1->attr->mp_nexthop_prefer_global)
|
||||||
? bi1->attr->mp_nexthop_global
|
? bpi1->attr->mp_nexthop_global
|
||||||
: bi1->attr->mp_nexthop_local;
|
: bpi1->attr->mp_nexthop_local;
|
||||||
addr2 = (bi2->attr->mp_nexthop_prefer_global)
|
addr2 = (bpi2->attr->mp_nexthop_prefer_global)
|
||||||
? bi2->attr->mp_nexthop_global
|
? bpi2->attr->mp_nexthop_global
|
||||||
: bi2->attr->mp_nexthop_local;
|
: bpi2->attr->mp_nexthop_local;
|
||||||
|
|
||||||
if (!bi1->attr->mp_nexthop_prefer_global
|
if (!bpi1->attr->mp_nexthop_prefer_global
|
||||||
&& !bi2->attr->mp_nexthop_prefer_global)
|
&& !bpi2->attr->mp_nexthop_prefer_global)
|
||||||
compare = !bgp_interface_same(
|
compare = !bgp_interface_same(
|
||||||
bi1->peer->ifp, bi2->peer->ifp);
|
bpi1->peer->ifp,
|
||||||
|
bpi2->peer->ifp);
|
||||||
|
|
||||||
if (!compare)
|
if (!compare)
|
||||||
compare = IPV6_ADDR_CMP(&addr1, &addr2);
|
compare = IPV6_ADDR_CMP(&addr1, &addr2);
|
||||||
@ -163,14 +165,15 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
|||||||
* link-local
|
* link-local
|
||||||
* nexthops but another IPv6 peer only sends you global
|
* nexthops but another IPv6 peer only sends you global
|
||||||
*/
|
*/
|
||||||
else if (bi1->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
|
else if (bpi1->attr->mp_nexthop_len
|
||||||
|| bi1->attr->mp_nexthop_len
|
== BGP_ATTR_NHLEN_IPV6_GLOBAL
|
||||||
|
|| bpi1->attr->mp_nexthop_len
|
||||||
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
||||||
compare = IPV6_ADDR_CMP(&bi1->attr->mp_nexthop_global,
|
compare = IPV6_ADDR_CMP(&bpi1->attr->mp_nexthop_global,
|
||||||
&bi2->attr->mp_nexthop_global);
|
&bpi2->attr->mp_nexthop_global);
|
||||||
if (!compare) {
|
if (!compare) {
|
||||||
if (bi1->attr->mp_nexthop_len
|
if (bpi1->attr->mp_nexthop_len
|
||||||
< bi2->attr->mp_nexthop_len)
|
< bpi2->attr->mp_nexthop_len)
|
||||||
compare = -1;
|
compare = -1;
|
||||||
else
|
else
|
||||||
compare = 1;
|
compare = 1;
|
||||||
@ -182,7 +185,7 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_cmp
|
* bgp_path_info_mpath_cmp
|
||||||
*
|
*
|
||||||
* This function determines our multipath list ordering. By ordering
|
* This function determines our multipath list ordering. By ordering
|
||||||
* the list we can deterministically select which paths are included
|
* the list we can deterministically select which paths are included
|
||||||
@ -193,26 +196,26 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
|||||||
* The order of paths is determined first by received nexthop, and then
|
* The order of paths is determined first by received nexthop, and then
|
||||||
* by peer address if the nexthops are the same.
|
* by peer address if the nexthops are the same.
|
||||||
*/
|
*/
|
||||||
static int bgp_info_mpath_cmp(void *val1, void *val2)
|
static int bgp_path_info_mpath_cmp(void *val1, void *val2)
|
||||||
{
|
{
|
||||||
struct bgp_info *bi1, *bi2;
|
struct bgp_path_info *bpi1, *bpi2;
|
||||||
int compare;
|
int compare;
|
||||||
|
|
||||||
bi1 = val1;
|
bpi1 = val1;
|
||||||
bi2 = val2;
|
bpi2 = val2;
|
||||||
|
|
||||||
compare = bgp_info_nexthop_cmp(bi1, bi2);
|
compare = bgp_path_info_nexthop_cmp(bpi1, bpi2);
|
||||||
|
|
||||||
if (!compare) {
|
if (!compare) {
|
||||||
if (!bi1->peer->su_remote && !bi2->peer->su_remote)
|
if (!bpi1->peer->su_remote && !bpi2->peer->su_remote)
|
||||||
compare = 0;
|
compare = 0;
|
||||||
else if (!bi1->peer->su_remote)
|
else if (!bpi1->peer->su_remote)
|
||||||
compare = 1;
|
compare = 1;
|
||||||
else if (!bi2->peer->su_remote)
|
else if (!bpi2->peer->su_remote)
|
||||||
compare = -1;
|
compare = -1;
|
||||||
else
|
else
|
||||||
compare = sockunion_cmp(bi1->peer->su_remote,
|
compare = sockunion_cmp(bpi1->peer->su_remote,
|
||||||
bi2->peer->su_remote);
|
bpi2->peer->su_remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
return compare;
|
return compare;
|
||||||
@ -228,7 +231,7 @@ void bgp_mp_list_init(struct list *mp_list)
|
|||||||
{
|
{
|
||||||
assert(mp_list);
|
assert(mp_list);
|
||||||
memset(mp_list, 0, sizeof(struct list));
|
memset(mp_list, 0, sizeof(struct list));
|
||||||
mp_list->cmp = bgp_info_mpath_cmp;
|
mp_list->cmp = bgp_path_info_mpath_cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -247,31 +250,31 @@ void bgp_mp_list_clear(struct list *mp_list)
|
|||||||
*
|
*
|
||||||
* Adds a multipath entry to the mp_list
|
* Adds a multipath entry to the mp_list
|
||||||
*/
|
*/
|
||||||
void bgp_mp_list_add(struct list *mp_list, struct bgp_info *mpinfo)
|
void bgp_mp_list_add(struct list *mp_list, struct bgp_path_info *mpinfo)
|
||||||
{
|
{
|
||||||
assert(mp_list && mpinfo);
|
assert(mp_list && mpinfo);
|
||||||
listnode_add_sort(mp_list, mpinfo);
|
listnode_add_sort(mp_list, mpinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_new
|
* bgp_path_info_mpath_new
|
||||||
*
|
*
|
||||||
* Allocate and zero memory for a new bgp_info_mpath element
|
* Allocate and zero memory for a new bgp_path_info_mpath element
|
||||||
*/
|
*/
|
||||||
static struct bgp_info_mpath *bgp_info_mpath_new(void)
|
static struct bgp_path_info_mpath *bgp_path_info_mpath_new(void)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *new_mpath;
|
struct bgp_path_info_mpath *new_mpath;
|
||||||
new_mpath =
|
new_mpath = XCALLOC(MTYPE_BGP_MPATH_INFO,
|
||||||
XCALLOC(MTYPE_BGP_MPATH_INFO, sizeof(struct bgp_info_mpath));
|
sizeof(struct bgp_path_info_mpath));
|
||||||
return new_mpath;
|
return new_mpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_free
|
* bgp_path_info_mpath_free
|
||||||
*
|
*
|
||||||
* Release resources for a bgp_info_mpath element and zero out pointer
|
* Release resources for a bgp_path_info_mpath element and zero out pointer
|
||||||
*/
|
*/
|
||||||
void bgp_info_mpath_free(struct bgp_info_mpath **mpath)
|
void bgp_path_info_mpath_free(struct bgp_path_info_mpath **mpath)
|
||||||
{
|
{
|
||||||
if (mpath && *mpath) {
|
if (mpath && *mpath) {
|
||||||
if ((*mpath)->mp_attr)
|
if ((*mpath)->mp_attr)
|
||||||
@ -282,37 +285,38 @@ void bgp_info_mpath_free(struct bgp_info_mpath **mpath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_get
|
* bgp_path_info_mpath_get
|
||||||
*
|
*
|
||||||
* Fetch the mpath element for the given bgp_info. Used for
|
* Fetch the mpath element for the given bgp_path_info. Used for
|
||||||
* doing lazy allocation.
|
* doing lazy allocation.
|
||||||
*/
|
*/
|
||||||
static struct bgp_info_mpath *bgp_info_mpath_get(struct bgp_info *binfo)
|
static struct bgp_path_info_mpath *
|
||||||
|
bgp_path_info_mpath_get(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *mpath;
|
struct bgp_path_info_mpath *mpath;
|
||||||
if (!binfo->mpath) {
|
if (!path->mpath) {
|
||||||
mpath = bgp_info_mpath_new();
|
mpath = bgp_path_info_mpath_new();
|
||||||
if (!mpath)
|
if (!mpath)
|
||||||
return NULL;
|
return NULL;
|
||||||
binfo->mpath = mpath;
|
path->mpath = mpath;
|
||||||
mpath->mp_info = binfo;
|
mpath->mp_info = path;
|
||||||
}
|
}
|
||||||
return binfo->mpath;
|
return path->mpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_enqueue
|
* bgp_path_info_mpath_enqueue
|
||||||
*
|
*
|
||||||
* Enqueue a path onto the multipath list given the previous multipath
|
* Enqueue a path onto the multipath list given the previous multipath
|
||||||
* list entry
|
* list entry
|
||||||
*/
|
*/
|
||||||
static void bgp_info_mpath_enqueue(struct bgp_info *prev_info,
|
static void bgp_path_info_mpath_enqueue(struct bgp_path_info *prev_info,
|
||||||
struct bgp_info *binfo)
|
struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *prev, *mpath;
|
struct bgp_path_info_mpath *prev, *mpath;
|
||||||
|
|
||||||
prev = bgp_info_mpath_get(prev_info);
|
prev = bgp_path_info_mpath_get(prev_info);
|
||||||
mpath = bgp_info_mpath_get(binfo);
|
mpath = bgp_path_info_mpath_get(path);
|
||||||
if (!prev || !mpath)
|
if (!prev || !mpath)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -322,17 +326,17 @@ static void bgp_info_mpath_enqueue(struct bgp_info *prev_info,
|
|||||||
prev->mp_next->mp_prev = mpath;
|
prev->mp_next->mp_prev = mpath;
|
||||||
prev->mp_next = mpath;
|
prev->mp_next = mpath;
|
||||||
|
|
||||||
SET_FLAG(binfo->flags, BGP_INFO_MULTIPATH);
|
SET_FLAG(path->flags, BGP_PATH_MULTIPATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_dequeue
|
* bgp_path_info_mpath_dequeue
|
||||||
*
|
*
|
||||||
* Remove a path from the multipath list
|
* Remove a path from the multipath list
|
||||||
*/
|
*/
|
||||||
void bgp_info_mpath_dequeue(struct bgp_info *binfo)
|
void bgp_path_info_mpath_dequeue(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *mpath = binfo->mpath;
|
struct bgp_path_info_mpath *mpath = path->mpath;
|
||||||
if (!mpath)
|
if (!mpath)
|
||||||
return;
|
return;
|
||||||
if (mpath->mp_prev)
|
if (mpath->mp_prev)
|
||||||
@ -340,101 +344,105 @@ void bgp_info_mpath_dequeue(struct bgp_info *binfo)
|
|||||||
if (mpath->mp_next)
|
if (mpath->mp_next)
|
||||||
mpath->mp_next->mp_prev = mpath->mp_prev;
|
mpath->mp_next->mp_prev = mpath->mp_prev;
|
||||||
mpath->mp_next = mpath->mp_prev = NULL;
|
mpath->mp_next = mpath->mp_prev = NULL;
|
||||||
UNSET_FLAG(binfo->flags, BGP_INFO_MULTIPATH);
|
UNSET_FLAG(path->flags, BGP_PATH_MULTIPATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_next
|
* bgp_path_info_mpath_next
|
||||||
*
|
*
|
||||||
* Given a bgp_info, return the next multipath entry
|
* Given a bgp_path_info, return the next multipath entry
|
||||||
*/
|
*/
|
||||||
struct bgp_info *bgp_info_mpath_next(struct bgp_info *binfo)
|
struct bgp_path_info *bgp_path_info_mpath_next(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
if (!binfo->mpath || !binfo->mpath->mp_next)
|
if (!path->mpath || !path->mpath->mp_next)
|
||||||
return NULL;
|
return NULL;
|
||||||
return binfo->mpath->mp_next->mp_info;
|
return path->mpath->mp_next->mp_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_first
|
* bgp_path_info_mpath_first
|
||||||
*
|
*
|
||||||
* Given bestpath bgp_info, return the first multipath entry.
|
* Given bestpath bgp_path_info, return the first multipath entry.
|
||||||
*/
|
*/
|
||||||
struct bgp_info *bgp_info_mpath_first(struct bgp_info *binfo)
|
struct bgp_path_info *bgp_path_info_mpath_first(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
return bgp_info_mpath_next(binfo);
|
return bgp_path_info_mpath_next(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_count
|
* bgp_path_info_mpath_count
|
||||||
*
|
*
|
||||||
* Given the bestpath bgp_info, return the number of multipath entries
|
* Given the bestpath bgp_path_info, return the number of multipath entries
|
||||||
*/
|
*/
|
||||||
uint32_t bgp_info_mpath_count(struct bgp_info *binfo)
|
uint32_t bgp_path_info_mpath_count(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
if (!binfo->mpath)
|
if (!path->mpath)
|
||||||
return 0;
|
return 0;
|
||||||
return binfo->mpath->mp_count;
|
return path->mpath->mp_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_count_set
|
* bgp_path_info_mpath_count_set
|
||||||
*
|
*
|
||||||
* Sets the count of multipaths into bestpath's mpath element
|
* Sets the count of multipaths into bestpath's mpath element
|
||||||
*/
|
*/
|
||||||
static void bgp_info_mpath_count_set(struct bgp_info *binfo, uint32_t count)
|
static void bgp_path_info_mpath_count_set(struct bgp_path_info *path,
|
||||||
|
uint32_t count)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *mpath;
|
struct bgp_path_info_mpath *mpath;
|
||||||
if (!count && !binfo->mpath)
|
if (!count && !path->mpath)
|
||||||
return;
|
return;
|
||||||
mpath = bgp_info_mpath_get(binfo);
|
mpath = bgp_path_info_mpath_get(path);
|
||||||
if (!mpath)
|
if (!mpath)
|
||||||
return;
|
return;
|
||||||
mpath->mp_count = count;
|
mpath->mp_count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_attr
|
* bgp_path_info_mpath_attr
|
||||||
*
|
*
|
||||||
* Given bestpath bgp_info, return aggregated attribute set used
|
* Given bestpath bgp_path_info, return aggregated attribute set used
|
||||||
* for advertising the multipath route
|
* for advertising the multipath route
|
||||||
*/
|
*/
|
||||||
struct attr *bgp_info_mpath_attr(struct bgp_info *binfo)
|
struct attr *bgp_path_info_mpath_attr(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
if (!binfo->mpath)
|
if (!path->mpath)
|
||||||
return NULL;
|
return NULL;
|
||||||
return binfo->mpath->mp_attr;
|
return path->mpath->mp_attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_attr_set
|
* bgp_path_info_mpath_attr_set
|
||||||
*
|
*
|
||||||
* Sets the aggregated attribute into bestpath's mpath element
|
* Sets the aggregated attribute into bestpath's mpath element
|
||||||
*/
|
*/
|
||||||
static void bgp_info_mpath_attr_set(struct bgp_info *binfo, struct attr *attr)
|
static void bgp_path_info_mpath_attr_set(struct bgp_path_info *path,
|
||||||
|
struct attr *attr)
|
||||||
{
|
{
|
||||||
struct bgp_info_mpath *mpath;
|
struct bgp_path_info_mpath *mpath;
|
||||||
if (!attr && !binfo->mpath)
|
if (!attr && !path->mpath)
|
||||||
return;
|
return;
|
||||||
mpath = bgp_info_mpath_get(binfo);
|
mpath = bgp_path_info_mpath_get(path);
|
||||||
if (!mpath)
|
if (!mpath)
|
||||||
return;
|
return;
|
||||||
mpath->mp_attr = attr;
|
mpath->mp_attr = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_update
|
* bgp_path_info_mpath_update
|
||||||
*
|
*
|
||||||
* Compare and sync up the multipath list with the mp_list generated by
|
* Compare and sync up the multipath list with the mp_list generated by
|
||||||
* bgp_best_selection
|
* bgp_best_selection
|
||||||
*/
|
*/
|
||||||
void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||||
struct bgp_info *old_best, struct list *mp_list,
|
struct bgp_path_info *new_best,
|
||||||
struct bgp_maxpaths_cfg *mpath_cfg)
|
struct bgp_path_info *old_best,
|
||||||
|
struct list *mp_list,
|
||||||
|
struct bgp_maxpaths_cfg *mpath_cfg)
|
||||||
{
|
{
|
||||||
uint16_t maxpaths, mpath_count, old_mpath_count;
|
uint16_t maxpaths, mpath_count, old_mpath_count;
|
||||||
struct listnode *mp_node, *mp_next_node;
|
struct listnode *mp_node, *mp_next_node;
|
||||||
struct bgp_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath;
|
struct bgp_path_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath;
|
||||||
int mpath_changed, debug;
|
int mpath_changed, debug;
|
||||||
char pfx_buf[PREFIX2STR_BUFFER], nh_buf[2][INET6_ADDRSTRLEN];
|
char pfx_buf[PREFIX2STR_BUFFER], nh_buf[2][INET6_ADDRSTRLEN];
|
||||||
char path_buf[PATH_ADDPATH_STR_BUFFER];
|
char path_buf[PATH_ADDPATH_STR_BUFFER];
|
||||||
@ -454,17 +462,17 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
if (new_best) {
|
if (new_best) {
|
||||||
mpath_count++;
|
mpath_count++;
|
||||||
if (new_best != old_best)
|
if (new_best != old_best)
|
||||||
bgp_info_mpath_dequeue(new_best);
|
bgp_path_info_mpath_dequeue(new_best);
|
||||||
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP)
|
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP)
|
||||||
? mpath_cfg->maxpaths_ibgp
|
? mpath_cfg->maxpaths_ibgp
|
||||||
: mpath_cfg->maxpaths_ebgp;
|
: mpath_cfg->maxpaths_ebgp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_best) {
|
if (old_best) {
|
||||||
cur_mpath = bgp_info_mpath_first(old_best);
|
cur_mpath = bgp_path_info_mpath_first(old_best);
|
||||||
old_mpath_count = bgp_info_mpath_count(old_best);
|
old_mpath_count = bgp_path_info_mpath_count(old_best);
|
||||||
bgp_info_mpath_count_set(old_best, 0);
|
bgp_path_info_mpath_count_set(old_best, 0);
|
||||||
bgp_info_mpath_dequeue(old_best);
|
bgp_path_info_mpath_dequeue(old_best);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -485,7 +493,7 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
* to skip over it
|
* to skip over it
|
||||||
*/
|
*/
|
||||||
while (mp_node || cur_mpath) {
|
while (mp_node || cur_mpath) {
|
||||||
struct bgp_info *tmp_info;
|
struct bgp_path_info *tmp_info;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can bail out of this loop if all existing paths on the
|
* We can bail out of this loop if all existing paths on the
|
||||||
@ -496,7 +504,8 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
mp_next_node = mp_node ? listnextnode(mp_node) : NULL;
|
mp_next_node = mp_node ? listnextnode(mp_node) : NULL;
|
||||||
next_mpath = cur_mpath ? bgp_info_mpath_next(cur_mpath) : NULL;
|
next_mpath =
|
||||||
|
cur_mpath ? bgp_path_info_mpath_next(cur_mpath) : NULL;
|
||||||
tmp_info = mp_node ? listgetdata(mp_node) : NULL;
|
tmp_info = mp_node ? listgetdata(mp_node) : NULL;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -512,14 +521,16 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
*/
|
*/
|
||||||
if (mp_node && (listgetdata(mp_node) == cur_mpath)) {
|
if (mp_node && (listgetdata(mp_node) == cur_mpath)) {
|
||||||
list_delete_node(mp_list, mp_node);
|
list_delete_node(mp_list, mp_node);
|
||||||
bgp_info_mpath_dequeue(cur_mpath);
|
bgp_path_info_mpath_dequeue(cur_mpath);
|
||||||
if ((mpath_count < maxpaths)
|
if ((mpath_count < maxpaths)
|
||||||
&& bgp_info_nexthop_cmp(prev_mpath, cur_mpath)) {
|
&& bgp_path_info_nexthop_cmp(prev_mpath,
|
||||||
bgp_info_mpath_enqueue(prev_mpath, cur_mpath);
|
cur_mpath)) {
|
||||||
|
bgp_path_info_mpath_enqueue(prev_mpath,
|
||||||
|
cur_mpath);
|
||||||
prev_mpath = cur_mpath;
|
prev_mpath = cur_mpath;
|
||||||
mpath_count++;
|
mpath_count++;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
bgp_info_path_with_addpath_rx_str(
|
bgp_path_info_path_with_addpath_rx_str(
|
||||||
cur_mpath, path_buf);
|
cur_mpath, path_buf);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: %s is still multipath, cur count %d",
|
"%s: %s is still multipath, cur count %d",
|
||||||
@ -528,7 +539,7 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
} else {
|
} else {
|
||||||
mpath_changed = 1;
|
mpath_changed = 1;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
bgp_info_path_with_addpath_rx_str(
|
bgp_path_info_path_with_addpath_rx_str(
|
||||||
cur_mpath, path_buf);
|
cur_mpath, path_buf);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: remove mpath %s nexthop %s, cur count %d",
|
"%s: remove mpath %s nexthop %s, cur count %d",
|
||||||
@ -548,7 +559,8 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
|
|
||||||
if (cur_mpath
|
if (cur_mpath
|
||||||
&& (!mp_node
|
&& (!mp_node
|
||||||
|| (bgp_info_mpath_cmp(cur_mpath, listgetdata(mp_node))
|
|| (bgp_path_info_mpath_cmp(cur_mpath,
|
||||||
|
listgetdata(mp_node))
|
||||||
< 0))) {
|
< 0))) {
|
||||||
/*
|
/*
|
||||||
* If here, we have an old multipath and either the
|
* If here, we have an old multipath and either the
|
||||||
@ -557,11 +569,11 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
* multipath, so we need to purge this path from the
|
* multipath, so we need to purge this path from the
|
||||||
* multipath list
|
* multipath list
|
||||||
*/
|
*/
|
||||||
bgp_info_mpath_dequeue(cur_mpath);
|
bgp_path_info_mpath_dequeue(cur_mpath);
|
||||||
mpath_changed = 1;
|
mpath_changed = 1;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
bgp_info_path_with_addpath_rx_str(cur_mpath,
|
bgp_path_info_path_with_addpath_rx_str(
|
||||||
path_buf);
|
cur_mpath, path_buf);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: remove mpath %s nexthop %s, cur count %d",
|
"%s: remove mpath %s nexthop %s, cur count %d",
|
||||||
pfx_buf, path_buf,
|
pfx_buf, path_buf,
|
||||||
@ -595,17 +607,19 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
assert(new_mpath);
|
assert(new_mpath);
|
||||||
assert(prev_mpath);
|
assert(prev_mpath);
|
||||||
if ((mpath_count < maxpaths) && (new_mpath != new_best)
|
if ((mpath_count < maxpaths) && (new_mpath != new_best)
|
||||||
&& bgp_info_nexthop_cmp(prev_mpath, new_mpath)) {
|
&& bgp_path_info_nexthop_cmp(prev_mpath,
|
||||||
|
new_mpath)) {
|
||||||
if (new_mpath == next_mpath)
|
if (new_mpath == next_mpath)
|
||||||
bgp_info_mpath_next(new_mpath);
|
bgp_path_info_mpath_next(new_mpath);
|
||||||
bgp_info_mpath_dequeue(new_mpath);
|
bgp_path_info_mpath_dequeue(new_mpath);
|
||||||
|
|
||||||
bgp_info_mpath_enqueue(prev_mpath, new_mpath);
|
bgp_path_info_mpath_enqueue(prev_mpath,
|
||||||
|
new_mpath);
|
||||||
prev_mpath = new_mpath;
|
prev_mpath = new_mpath;
|
||||||
mpath_changed = 1;
|
mpath_changed = 1;
|
||||||
mpath_count++;
|
mpath_count++;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
bgp_info_path_with_addpath_rx_str(
|
bgp_path_info_path_with_addpath_rx_str(
|
||||||
new_mpath, path_buf);
|
new_mpath, path_buf);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: add mpath %s nexthop %s, cur count %d",
|
"%s: add mpath %s nexthop %s, cur count %d",
|
||||||
@ -629,39 +643,39 @@ void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
|
|||||||
pfx_buf, mpath_count,
|
pfx_buf, mpath_count,
|
||||||
mpath_changed ? "YES" : "NO");
|
mpath_changed ? "YES" : "NO");
|
||||||
|
|
||||||
bgp_info_mpath_count_set(new_best, mpath_count - 1);
|
bgp_path_info_mpath_count_set(new_best, mpath_count - 1);
|
||||||
if (mpath_changed
|
if (mpath_changed
|
||||||
|| (bgp_info_mpath_count(new_best) != old_mpath_count))
|
|| (bgp_path_info_mpath_count(new_best) != old_mpath_count))
|
||||||
SET_FLAG(new_best->flags, BGP_INFO_MULTIPATH_CHG);
|
SET_FLAG(new_best->flags, BGP_PATH_MULTIPATH_CHG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_mp_dmed_deselect
|
* bgp_mp_dmed_deselect
|
||||||
*
|
*
|
||||||
* Clean up multipath information for BGP_INFO_DMED_SELECTED path that
|
* Clean up multipath information for BGP_PATH_DMED_SELECTED path that
|
||||||
* is not selected as best path
|
* is not selected as best path
|
||||||
*/
|
*/
|
||||||
void bgp_mp_dmed_deselect(struct bgp_info *dmed_best)
|
void bgp_mp_dmed_deselect(struct bgp_path_info *dmed_best)
|
||||||
{
|
{
|
||||||
struct bgp_info *mpinfo, *mpnext;
|
struct bgp_path_info *mpinfo, *mpnext;
|
||||||
|
|
||||||
if (!dmed_best)
|
if (!dmed_best)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (mpinfo = bgp_info_mpath_first(dmed_best); mpinfo;
|
for (mpinfo = bgp_path_info_mpath_first(dmed_best); mpinfo;
|
||||||
mpinfo = mpnext) {
|
mpinfo = mpnext) {
|
||||||
mpnext = bgp_info_mpath_next(mpinfo);
|
mpnext = bgp_path_info_mpath_next(mpinfo);
|
||||||
bgp_info_mpath_dequeue(mpinfo);
|
bgp_path_info_mpath_dequeue(mpinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_info_mpath_count_set(dmed_best, 0);
|
bgp_path_info_mpath_count_set(dmed_best, 0);
|
||||||
UNSET_FLAG(dmed_best->flags, BGP_INFO_MULTIPATH_CHG);
|
UNSET_FLAG(dmed_best->flags, BGP_PATH_MULTIPATH_CHG);
|
||||||
assert(bgp_info_mpath_first(dmed_best) == 0);
|
assert(bgp_path_info_mpath_first(dmed_best) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgp_info_mpath_aggregate_update
|
* bgp_path_info_mpath_aggregate_update
|
||||||
*
|
*
|
||||||
* Set the multipath aggregate attribute. We need to see if the
|
* Set the multipath aggregate attribute. We need to see if the
|
||||||
* aggregate has changed and then set the ATTR_CHANGED flag on the
|
* aggregate has changed and then set the ATTR_CHANGED flag on the
|
||||||
@ -672,10 +686,10 @@ void bgp_mp_dmed_deselect(struct bgp_info *dmed_best)
|
|||||||
* is no change in multipath selection and no attribute change in
|
* is no change in multipath selection and no attribute change in
|
||||||
* any multipath.
|
* any multipath.
|
||||||
*/
|
*/
|
||||||
void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
void bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
|
||||||
struct bgp_info *old_best)
|
struct bgp_path_info *old_best)
|
||||||
{
|
{
|
||||||
struct bgp_info *mpinfo;
|
struct bgp_path_info *mpinfo;
|
||||||
struct aspath *aspath;
|
struct aspath *aspath;
|
||||||
struct aspath *asmerge;
|
struct aspath *asmerge;
|
||||||
struct attr *new_attr, *old_attr;
|
struct attr *new_attr, *old_attr;
|
||||||
@ -686,19 +700,19 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
|||||||
struct attr attr = {0};
|
struct attr attr = {0};
|
||||||
|
|
||||||
if (old_best && (old_best != new_best)
|
if (old_best && (old_best != new_best)
|
||||||
&& (old_attr = bgp_info_mpath_attr(old_best))) {
|
&& (old_attr = bgp_path_info_mpath_attr(old_best))) {
|
||||||
bgp_attr_unintern(&old_attr);
|
bgp_attr_unintern(&old_attr);
|
||||||
bgp_info_mpath_attr_set(old_best, NULL);
|
bgp_path_info_mpath_attr_set(old_best, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new_best)
|
if (!new_best)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bgp_info_mpath_count(new_best)) {
|
if (!bgp_path_info_mpath_count(new_best)) {
|
||||||
if ((new_attr = bgp_info_mpath_attr(new_best))) {
|
if ((new_attr = bgp_path_info_mpath_attr(new_best))) {
|
||||||
bgp_attr_unintern(&new_attr);
|
bgp_attr_unintern(&new_attr);
|
||||||
bgp_info_mpath_attr_set(new_best, NULL);
|
bgp_path_info_mpath_attr_set(new_best, NULL);
|
||||||
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
|
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -718,8 +732,8 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
|||||||
lcomm = (attr.lcommunity) ? lcommunity_dup(attr.lcommunity)
|
lcomm = (attr.lcommunity) ? lcommunity_dup(attr.lcommunity)
|
||||||
: NULL;
|
: NULL;
|
||||||
|
|
||||||
for (mpinfo = bgp_info_mpath_first(new_best); mpinfo;
|
for (mpinfo = bgp_path_info_mpath_first(new_best); mpinfo;
|
||||||
mpinfo = bgp_info_mpath_next(mpinfo)) {
|
mpinfo = bgp_path_info_mpath_next(mpinfo)) {
|
||||||
asmerge =
|
asmerge =
|
||||||
aspath_aggregate(aspath, mpinfo->attr->aspath);
|
aspath_aggregate(aspath, mpinfo->attr->aspath);
|
||||||
aspath_free(aspath);
|
aspath_free(aspath);
|
||||||
@ -735,7 +749,7 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
|||||||
mpinfo->attr->community);
|
mpinfo->attr->community);
|
||||||
community =
|
community =
|
||||||
community_uniq_sort(commerge);
|
community_uniq_sort(commerge);
|
||||||
community_free(commerge);
|
community_free(&commerge);
|
||||||
} else
|
} else
|
||||||
community = community_dup(
|
community = community_dup(
|
||||||
mpinfo->attr->community);
|
mpinfo->attr->community);
|
||||||
@ -789,11 +803,11 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
|
|||||||
|
|
||||||
new_attr = bgp_attr_intern(&attr);
|
new_attr = bgp_attr_intern(&attr);
|
||||||
|
|
||||||
if (new_attr != bgp_info_mpath_attr(new_best)) {
|
if (new_attr != bgp_path_info_mpath_attr(new_best)) {
|
||||||
if ((old_attr = bgp_info_mpath_attr(new_best)))
|
if ((old_attr = bgp_path_info_mpath_attr(new_best)))
|
||||||
bgp_attr_unintern(&old_attr);
|
bgp_attr_unintern(&old_attr);
|
||||||
bgp_info_mpath_attr_set(new_best, new_attr);
|
bgp_path_info_mpath_attr_set(new_best, new_attr);
|
||||||
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
|
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
|
||||||
} else
|
} else
|
||||||
bgp_attr_unintern(&new_attr);
|
bgp_attr_unintern(&new_attr);
|
||||||
}
|
}
|
||||||
|
@ -22,18 +22,18 @@
|
|||||||
#ifndef _QUAGGA_BGP_MPATH_H
|
#ifndef _QUAGGA_BGP_MPATH_H
|
||||||
#define _QUAGGA_BGP_MPATH_H
|
#define _QUAGGA_BGP_MPATH_H
|
||||||
|
|
||||||
/* Supplemental information linked to bgp_info for keeping track of
|
/* Supplemental information linked to bgp_path_info for keeping track of
|
||||||
* multipath selections, lazily allocated to save memory
|
* multipath selections, lazily allocated to save memory
|
||||||
*/
|
*/
|
||||||
struct bgp_info_mpath {
|
struct bgp_path_info_mpath {
|
||||||
/* Points to the first multipath (on bestpath) or the next multipath */
|
/* Points to the first multipath (on bestpath) or the next multipath */
|
||||||
struct bgp_info_mpath *mp_next;
|
struct bgp_path_info_mpath *mp_next;
|
||||||
|
|
||||||
/* Points to the previous multipath or NULL on bestpath */
|
/* Points to the previous multipath or NULL on bestpath */
|
||||||
struct bgp_info_mpath *mp_prev;
|
struct bgp_path_info_mpath *mp_prev;
|
||||||
|
|
||||||
/* Points to bgp_info associated with this multipath info */
|
/* Points to bgp_path_info associated with this multipath info */
|
||||||
struct bgp_info *mp_info;
|
struct bgp_path_info *mp_info;
|
||||||
|
|
||||||
/* When attached to best path, the number of selected multipaths */
|
/* When attached to best path, the number of selected multipaths */
|
||||||
uint32_t mp_count;
|
uint32_t mp_count;
|
||||||
@ -50,27 +50,33 @@ extern int bgp_maximum_paths_unset(struct bgp *, afi_t, safi_t, int);
|
|||||||
/* Functions used by bgp_best_selection to record current
|
/* Functions used by bgp_best_selection to record current
|
||||||
* multipath selections
|
* multipath selections
|
||||||
*/
|
*/
|
||||||
extern int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2);
|
extern int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1,
|
||||||
|
struct bgp_path_info *bpi2);
|
||||||
extern void bgp_mp_list_init(struct list *);
|
extern void bgp_mp_list_init(struct list *);
|
||||||
extern void bgp_mp_list_clear(struct list *);
|
extern void bgp_mp_list_clear(struct list *);
|
||||||
extern void bgp_mp_list_add(struct list *, struct bgp_info *);
|
extern void bgp_mp_list_add(struct list *mp_list, struct bgp_path_info *mpinfo);
|
||||||
extern void bgp_mp_dmed_deselect(struct bgp_info *);
|
extern void bgp_mp_dmed_deselect(struct bgp_path_info *dmed_best);
|
||||||
extern void bgp_info_mpath_update(struct bgp_node *, struct bgp_info *,
|
extern void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||||
struct bgp_info *, struct list *,
|
struct bgp_path_info *new_best,
|
||||||
struct bgp_maxpaths_cfg *);
|
struct bgp_path_info *old_best,
|
||||||
extern void bgp_info_mpath_aggregate_update(struct bgp_info *,
|
struct list *mp_list,
|
||||||
struct bgp_info *);
|
struct bgp_maxpaths_cfg *mpath_cfg);
|
||||||
|
extern void
|
||||||
|
bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
|
||||||
|
struct bgp_path_info *old_best);
|
||||||
|
|
||||||
/* Unlink and free multipath information associated with a bgp_info */
|
/* Unlink and free multipath information associated with a bgp_path_info */
|
||||||
extern void bgp_info_mpath_dequeue(struct bgp_info *);
|
extern void bgp_path_info_mpath_dequeue(struct bgp_path_info *path);
|
||||||
extern void bgp_info_mpath_free(struct bgp_info_mpath **);
|
extern void bgp_path_info_mpath_free(struct bgp_path_info_mpath **mpath);
|
||||||
|
|
||||||
/* Walk list of multipaths associated with a best path */
|
/* Walk list of multipaths associated with a best path */
|
||||||
extern struct bgp_info *bgp_info_mpath_first(struct bgp_info *);
|
extern struct bgp_path_info *
|
||||||
extern struct bgp_info *bgp_info_mpath_next(struct bgp_info *);
|
bgp_path_info_mpath_first(struct bgp_path_info *path);
|
||||||
|
extern struct bgp_path_info *
|
||||||
|
bgp_path_info_mpath_next(struct bgp_path_info *path);
|
||||||
|
|
||||||
/* Accessors for multipath information */
|
/* Accessors for multipath information */
|
||||||
extern uint32_t bgp_info_mpath_count(struct bgp_info *);
|
extern uint32_t bgp_path_info_mpath_count(struct bgp_path_info *path);
|
||||||
extern struct attr *bgp_info_mpath_attr(struct bgp_info *);
|
extern struct attr *bgp_path_info_mpath_attr(struct bgp_path_info *path);
|
||||||
|
|
||||||
#endif /* _QUAGGA_BGP_MPATH_H */
|
#endif /* _QUAGGA_BGP_MPATH_H */
|
||||||
|
@ -402,22 +402,23 @@ static int ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool labels_same(struct bgp_info *bi, mpls_label_t *label, uint32_t n)
|
static bool labels_same(struct bgp_path_info *bpi, mpls_label_t *label,
|
||||||
|
uint32_t n)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
if (!bi->extra) {
|
if (!bpi->extra) {
|
||||||
if (!n)
|
if (!n)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n != bi->extra->num_labels)
|
if (n != bpi->extra->num_labels)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
if (label[i] != bi->extra->label[i])
|
if (label[i] != bpi->extra->label[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -426,22 +427,21 @@ static bool labels_same(struct bgp_info *bi, mpls_label_t *label, uint32_t n)
|
|||||||
/*
|
/*
|
||||||
* make encoded route labels match specified encoded label set
|
* make encoded route labels match specified encoded label set
|
||||||
*/
|
*/
|
||||||
static void setlabels(
|
static void setlabels(struct bgp_path_info *bpi,
|
||||||
struct bgp_info *bi,
|
mpls_label_t *label, /* array of labels */
|
||||||
mpls_label_t *label, /* array of labels */
|
uint32_t num_labels)
|
||||||
uint32_t num_labels)
|
|
||||||
{
|
{
|
||||||
if (num_labels)
|
if (num_labels)
|
||||||
assert(label);
|
assert(label);
|
||||||
assert(num_labels <= BGP_MAX_LABELS);
|
assert(num_labels <= BGP_MAX_LABELS);
|
||||||
|
|
||||||
if (!num_labels) {
|
if (!num_labels) {
|
||||||
if (bi->extra)
|
if (bpi->extra)
|
||||||
bi->extra->num_labels = 0;
|
bpi->extra->num_labels = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bgp_info_extra *extra = bgp_info_extra_get(bi);
|
struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi);
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < num_labels; ++i) {
|
for (i = 0; i < num_labels; ++i) {
|
||||||
@ -454,35 +454,27 @@ static void setlabels(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns pointer to new bgp_info upon success
|
* returns pointer to new bgp_path_info upon success
|
||||||
*/
|
*/
|
||||||
static struct bgp_info *
|
static struct bgp_path_info *
|
||||||
leak_update(
|
leak_update(struct bgp *bgp, /* destination bgp instance */
|
||||||
struct bgp *bgp, /* destination bgp instance */
|
struct bgp_node *bn, struct attr *new_attr, /* already interned */
|
||||||
struct bgp_node *bn,
|
afi_t afi, safi_t safi, struct bgp_path_info *source_bpi,
|
||||||
struct attr *new_attr, /* already interned */
|
mpls_label_t *label, uint32_t num_labels, void *parent,
|
||||||
afi_t afi,
|
struct bgp *bgp_orig, struct prefix *nexthop_orig,
|
||||||
safi_t safi,
|
int nexthop_self_flag, int debug)
|
||||||
struct bgp_info *source_bi,
|
|
||||||
mpls_label_t *label,
|
|
||||||
uint32_t num_labels,
|
|
||||||
void *parent,
|
|
||||||
struct bgp *bgp_orig,
|
|
||||||
struct prefix *nexthop_orig,
|
|
||||||
int nexthop_self_flag,
|
|
||||||
int debug)
|
|
||||||
{
|
{
|
||||||
struct prefix *p = &bn->p;
|
struct prefix *p = &bn->p;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct bgp_info *bi_ultimate;
|
struct bgp_path_info *bpi_ultimate;
|
||||||
struct bgp_info *new;
|
struct bgp_path_info *new;
|
||||||
char buf_prefix[PREFIX_STRLEN];
|
char buf_prefix[PREFIX_STRLEN];
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
|
prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
|
||||||
zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
|
zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
|
||||||
__func__, bgp->name_pretty, buf_prefix,
|
__func__, bgp->name_pretty, buf_prefix,
|
||||||
source_bi->type, source_bi->sub_type);
|
source_bpi->type, source_bpi->sub_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -494,31 +486,30 @@ leak_update(
|
|||||||
* should have nexthop tracking, we must find the ultimate
|
* should have nexthop tracking, we must find the ultimate
|
||||||
* parent so we can check its sub_type.
|
* parent so we can check its sub_type.
|
||||||
*
|
*
|
||||||
* As of now, source_bi may at most be a second-generation route
|
* As of now, source_bpi may at most be a second-generation route
|
||||||
* (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
|
* (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
|
||||||
* Using a loop here supports more complex intra-bgp import-export
|
* Using a loop here supports more complex intra-bgp import-export
|
||||||
* schemes that could be implemented in the future.
|
* schemes that could be implemented in the future.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
for (bi_ultimate = source_bi;
|
for (bpi_ultimate = source_bpi;
|
||||||
bi_ultimate->extra && bi_ultimate->extra->parent;
|
bpi_ultimate->extra && bpi_ultimate->extra->parent;
|
||||||
bi_ultimate = bi_ultimate->extra->parent)
|
bpi_ultimate = bpi_ultimate->extra->parent)
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* match parent
|
* match parent
|
||||||
*/
|
*/
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (bi->extra && bi->extra->parent == parent)
|
if (bpi->extra && bpi->extra->parent == parent)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
bool labelssame = labels_same(bi, label, num_labels);
|
bool labelssame = labels_same(bpi, label, num_labels);
|
||||||
|
|
||||||
if (attrhash_cmp(bi->attr, new_attr)
|
if (attrhash_cmp(bpi->attr, new_attr) && labelssame
|
||||||
&& labelssame
|
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
|
||||||
|
|
||||||
bgp_attr_unintern(&new_attr);
|
bgp_attr_unintern(&new_attr);
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -530,43 +521,42 @@ leak_update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* attr is changed */
|
/* attr is changed */
|
||||||
bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
|
||||||
|
|
||||||
/* Rewrite BGP route information. */
|
/* Rewrite BGP route information. */
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||||
bgp_info_restore(bn, bi);
|
bgp_path_info_restore(bn, bpi);
|
||||||
else
|
else
|
||||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||||
bgp_attr_unintern(&bi->attr);
|
bgp_attr_unintern(&bpi->attr);
|
||||||
bi->attr = new_attr;
|
bpi->attr = new_attr;
|
||||||
bi->uptime = bgp_clock();
|
bpi->uptime = bgp_clock();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rewrite labels
|
* rewrite labels
|
||||||
*/
|
*/
|
||||||
if (!labelssame)
|
if (!labelssame)
|
||||||
setlabels(bi, label, num_labels);
|
setlabels(bpi, label, num_labels);
|
||||||
|
|
||||||
if (nexthop_self_flag)
|
if (nexthop_self_flag)
|
||||||
bgp_info_set_flag(bn, bi, BGP_INFO_ANNC_NH_SELF);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
|
||||||
|
|
||||||
struct bgp *bgp_nexthop = bgp;
|
struct bgp *bgp_nexthop = bgp;
|
||||||
int nh_valid;
|
int nh_valid;
|
||||||
|
|
||||||
if (bi->extra && bi->extra->bgp_orig)
|
if (bpi->extra && bpi->extra->bgp_orig)
|
||||||
bgp_nexthop = bi->extra->bgp_orig;
|
bgp_nexthop = bpi->extra->bgp_orig;
|
||||||
|
|
||||||
/* No nexthop tracking for redistributed routes */
|
/* No nexthop tracking for redistributed routes */
|
||||||
if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
|
if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
|
||||||
nh_valid = 1;
|
nh_valid = 1;
|
||||||
else
|
else
|
||||||
/*
|
/*
|
||||||
* TBD do we need to do anything about the
|
* TBD do we need to do anything about the
|
||||||
* 'connected' parameter?
|
* 'connected' parameter?
|
||||||
*/
|
*/
|
||||||
nh_valid = bgp_find_or_add_nexthop(
|
nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop,
|
||||||
bgp, bgp_nexthop,
|
afi, bpi, NULL, 0);
|
||||||
afi, bi, NULL, 0);
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
zlog_debug("%s: nexthop is %svalid (in vrf %s)",
|
||||||
@ -574,10 +564,10 @@ leak_update(
|
|||||||
bgp_nexthop->name_pretty);
|
bgp_nexthop->name_pretty);
|
||||||
|
|
||||||
if (nh_valid)
|
if (nh_valid)
|
||||||
bgp_info_set_flag(bn, bi, BGP_INFO_VALID);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_VALID);
|
||||||
|
|
||||||
/* Process change. */
|
/* Process change. */
|
||||||
bgp_aggregate_increment(bgp, p, bi, afi, safi);
|
bgp_aggregate_increment(bgp, p, bpi, afi, safi);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
|
|
||||||
@ -585,22 +575,22 @@ leak_update(
|
|||||||
zlog_debug("%s: ->%s: %s Found route, changed attr",
|
zlog_debug("%s: ->%s: %s Found route, changed attr",
|
||||||
__func__, bgp->name_pretty, buf_prefix);
|
__func__, bgp->name_pretty, buf_prefix);
|
||||||
|
|
||||||
return bi;
|
return bpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
|
||||||
bgp->peer_self, new_attr, bn);
|
bgp->peer_self, new_attr, bn);
|
||||||
|
|
||||||
if (nexthop_self_flag)
|
if (nexthop_self_flag)
|
||||||
bgp_info_set_flag(bn, new, BGP_INFO_ANNC_NH_SELF);
|
bgp_path_info_set_flag(bn, new, BGP_PATH_ANNC_NH_SELF);
|
||||||
|
|
||||||
bgp_info_extra_get(new);
|
bgp_path_info_extra_get(new);
|
||||||
|
|
||||||
if (num_labels)
|
if (num_labels)
|
||||||
setlabels(new, label, num_labels);
|
setlabels(new, label, num_labels);
|
||||||
|
|
||||||
new->extra->parent = bgp_info_lock(parent);
|
new->extra->parent = bgp_path_info_lock(parent);
|
||||||
bgp_lock_node((struct bgp_node *)((struct bgp_info *)parent)->net);
|
bgp_lock_node((struct bgp_node *)((struct bgp_path_info *)parent)->net);
|
||||||
if (bgp_orig)
|
if (bgp_orig)
|
||||||
new->extra->bgp_orig = bgp_lock(bgp_orig);
|
new->extra->bgp_orig = bgp_lock(bgp_orig);
|
||||||
if (nexthop_orig)
|
if (nexthop_orig)
|
||||||
@ -620,7 +610,7 @@ leak_update(
|
|||||||
* their originating protocols will do the tracking and
|
* their originating protocols will do the tracking and
|
||||||
* withdraw those routes if the nexthops become unreachable
|
* withdraw those routes if the nexthops become unreachable
|
||||||
*/
|
*/
|
||||||
if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
|
if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
|
||||||
nh_valid = 1;
|
nh_valid = 1;
|
||||||
else
|
else
|
||||||
/*
|
/*
|
||||||
@ -635,10 +625,10 @@ leak_update(
|
|||||||
__func__, (nh_valid ? "" : "not "),
|
__func__, (nh_valid ? "" : "not "),
|
||||||
bgp_nexthop->name_pretty);
|
bgp_nexthop->name_pretty);
|
||||||
if (nh_valid)
|
if (nh_valid)
|
||||||
bgp_info_set_flag(bn, new, BGP_INFO_VALID);
|
bgp_path_info_set_flag(bn, new, BGP_PATH_VALID);
|
||||||
|
|
||||||
bgp_aggregate_increment(bgp, p, new, afi, safi);
|
bgp_aggregate_increment(bgp, p, new, afi, safi);
|
||||||
bgp_info_add(bn, new);
|
bgp_path_info_add(bn, new);
|
||||||
|
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
@ -651,12 +641,12 @@ leak_update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
|
/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
|
||||||
void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
||||||
struct bgp *bgp_vrf, /* from */
|
struct bgp *bgp_vrf, /* from */
|
||||||
struct bgp_info *info_vrf) /* route */
|
struct bgp_path_info *path_vrf) /* route */
|
||||||
{
|
{
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
||||||
struct prefix *p = &info_vrf->net->p;
|
struct prefix *p = &path_vrf->net->p;
|
||||||
afi_t afi = family2afi(p->family);
|
afi_t afi = family2afi(p->family);
|
||||||
struct attr static_attr = {0};
|
struct attr static_attr = {0};
|
||||||
struct attr *new_attr = NULL;
|
struct attr *new_attr = NULL;
|
||||||
@ -670,12 +660,12 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
|
zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
|
||||||
|
|
||||||
if (debug && info_vrf->attr->ecommunity) {
|
if (debug && path_vrf->attr->ecommunity) {
|
||||||
char *s = ecommunity_ecom2str(info_vrf->attr->ecommunity,
|
char *s = ecommunity_ecom2str(path_vrf->attr->ecommunity,
|
||||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
|
|
||||||
zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__,
|
zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__,
|
||||||
bgp_vrf->name, info_vrf->type, s);
|
bgp_vrf->name, path_vrf->type, s);
|
||||||
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,7 +679,7 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* loop check - should not be an imported route. */
|
/* loop check - should not be an imported route. */
|
||||||
if (info_vrf->extra && info_vrf->extra->bgp_orig)
|
if (path_vrf->extra && path_vrf->extra->bgp_orig)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
@ -700,13 +690,13 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_attr_dup(&static_attr, info_vrf->attr); /* shallow copy */
|
bgp_attr_dup(&static_attr, path_vrf->attr); /* shallow copy */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* route map handling
|
* route map handling
|
||||||
*/
|
*/
|
||||||
if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
|
if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -818,8 +808,8 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
* IPv4 nexthops as the attr has been copied
|
* IPv4 nexthops as the attr has been copied
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
if (afi == AFI_IP &&
|
if (afi == AFI_IP
|
||||||
!BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf->attr)) {
|
&& !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
|
||||||
static_attr.mp_nexthop_global_in.s_addr =
|
static_attr.mp_nexthop_global_in.s_addr =
|
||||||
static_attr.nexthop.s_addr;
|
static_attr.nexthop.s_addr;
|
||||||
static_attr.mp_nexthop_len = 4;
|
static_attr.mp_nexthop_len = 4;
|
||||||
@ -859,10 +849,10 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
|
bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
|
||||||
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
||||||
|
|
||||||
struct bgp_info *new_info;
|
struct bgp_path_info *new_info;
|
||||||
|
|
||||||
new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, info_vrf,
|
new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, path_vrf,
|
||||||
&label, 1, info_vrf, bgp_vrf, NULL,
|
&label, 1, path_vrf, bgp_vrf, NULL,
|
||||||
nexthop_self_flag, debug);
|
nexthop_self_flag, debug);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -878,15 +868,15 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
|
|||||||
vpn_leak_to_vrf_update(bgp_vrf, new_info);
|
vpn_leak_to_vrf_update(bgp_vrf, new_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
||||||
struct bgp *bgp_vrf, /* from */
|
struct bgp *bgp_vrf, /* from */
|
||||||
struct bgp_info *info_vrf) /* route */
|
struct bgp_path_info *path_vrf) /* route */
|
||||||
{
|
{
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
||||||
struct prefix *p = &info_vrf->net->p;
|
struct prefix *p = &path_vrf->net->p;
|
||||||
afi_t afi = family2afi(p->family);
|
afi_t afi = family2afi(p->family);
|
||||||
safi_t safi = SAFI_MPLS_VPN;
|
safi_t safi = SAFI_MPLS_VPN;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
const char *debugmsg;
|
const char *debugmsg;
|
||||||
char buf_prefix[PREFIX_STRLEN];
|
char buf_prefix[PREFIX_STRLEN];
|
||||||
@ -896,16 +886,16 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
|
"%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
|
||||||
__func__, bgp_vrf->name_pretty, buf_prefix,
|
__func__, bgp_vrf->name_pretty, buf_prefix,
|
||||||
info_vrf->type, info_vrf->sub_type);
|
path_vrf->type, path_vrf->sub_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info_vrf->sub_type != BGP_ROUTE_NORMAL
|
if (path_vrf->sub_type != BGP_ROUTE_NORMAL
|
||||||
&& info_vrf->sub_type != BGP_ROUTE_STATIC
|
&& path_vrf->sub_type != BGP_ROUTE_STATIC
|
||||||
&& info_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
|
&& path_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: wrong sub_type %d", __func__,
|
zlog_debug("%s: wrong sub_type %d", __func__,
|
||||||
info_vrf->sub_type);
|
path_vrf->sub_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!bgp_vpn)
|
if (!bgp_vpn)
|
||||||
@ -924,27 +914,27 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: withdrawing (info_vrf=%p)", __func__, info_vrf);
|
zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
|
||||||
|
|
||||||
bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
|
bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
|
||||||
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
&(bgp_vrf->vpn_policy[afi].tovpn_rd));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vrf -> vpn
|
* vrf -> vpn
|
||||||
* match original bi imported from
|
* match original bpi imported from
|
||||||
*/
|
*/
|
||||||
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
|
for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
|
||||||
if (bi->extra && bi->extra->parent == info_vrf) {
|
if (bpi->extra && bpi->extra->parent == path_vrf) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
/* withdraw from looped vrfs as well */
|
/* withdraw from looped vrfs as well */
|
||||||
vpn_leak_to_vrf_withdraw(bgp_vpn, bi);
|
vpn_leak_to_vrf_withdraw(bgp_vpn, bpi);
|
||||||
|
|
||||||
bgp_aggregate_decrement(bgp_vpn, p, bi, afi, safi);
|
bgp_aggregate_decrement(bgp_vpn, p, bpi, afi, safi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp_vpn, bn, afi, safi);
|
bgp_process(bgp_vpn, bn, afi, safi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
@ -959,14 +949,14 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
|
|||||||
safi_t safi = SAFI_MPLS_VPN;
|
safi_t safi = SAFI_MPLS_VPN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Walk vpn table, delete bi with bgp_orig == bgp_vrf
|
* Walk vpn table, delete bpi with bgp_orig == bgp_vrf
|
||||||
*/
|
*/
|
||||||
for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
|
for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
|
||||||
prn = bgp_route_next(prn)) {
|
prn = bgp_route_next(prn)) {
|
||||||
|
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
/* This is the per-RD table of prefixes */
|
/* This is the per-RD table of prefixes */
|
||||||
table = prn->info;
|
table = prn->info;
|
||||||
@ -984,24 +974,24 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
|
|||||||
prefix2str(&bn->p, buf, sizeof(buf)));
|
prefix2str(&bn->p, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: type %d, sub_type %d",
|
zlog_debug("%s: type %d, sub_type %d",
|
||||||
__func__, bi->type,
|
__func__, bpi->type,
|
||||||
bi->sub_type);
|
bpi->sub_type);
|
||||||
if (bi->sub_type != BGP_ROUTE_IMPORTED)
|
if (bpi->sub_type != BGP_ROUTE_IMPORTED)
|
||||||
continue;
|
continue;
|
||||||
if (!bi->extra)
|
if (!bpi->extra)
|
||||||
continue;
|
continue;
|
||||||
if ((struct bgp *)bi->extra->bgp_orig
|
if ((struct bgp *)bpi->extra->bgp_orig
|
||||||
== bgp_vrf) {
|
== bgp_vrf) {
|
||||||
/* delete route */
|
/* delete route */
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: deleting it\n",
|
zlog_debug("%s: deleting it\n",
|
||||||
__func__);
|
__func__);
|
||||||
bgp_aggregate_decrement(bgp_vpn, &bn->p,
|
bgp_aggregate_decrement(bgp_vpn, &bn->p,
|
||||||
bi, afi, safi);
|
bpi, afi, safi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp_vpn, bn, afi, safi);
|
bgp_process(bgp_vpn, bn, afi, safi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1014,7 +1004,7 @@ void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
|
|||||||
afi_t afi)
|
afi_t afi)
|
||||||
{
|
{
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -1027,21 +1017,22 @@ void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
|
|||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: node=%p", __func__, bn);
|
zlog_debug("%s: node=%p", __func__, bn);
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: calling vpn_leak_from_vrf_update",
|
"%s: calling vpn_leak_from_vrf_update",
|
||||||
__func__);
|
__func__);
|
||||||
vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bi);
|
vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bpi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
static void
|
||||||
struct bgp *bgp_vpn, /* from */
|
vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
||||||
struct bgp_info *info_vpn) /* route */
|
struct bgp *bgp_vpn, /* from */
|
||||||
|
struct bgp_path_info *path_vpn) /* route */
|
||||||
{
|
{
|
||||||
struct prefix *p = &info_vpn->net->p;
|
struct prefix *p = &path_vpn->net->p;
|
||||||
afi_t afi = family2afi(p->family);
|
afi_t afi = family2afi(p->family);
|
||||||
|
|
||||||
struct attr static_attr = {0};
|
struct attr static_attr = {0};
|
||||||
@ -1053,7 +1044,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
mpls_label_t *pLabels = NULL;
|
mpls_label_t *pLabels = NULL;
|
||||||
uint32_t num_labels = 0;
|
uint32_t num_labels = 0;
|
||||||
int nexthop_self_flag = 1;
|
int nexthop_self_flag = 1;
|
||||||
struct bgp_info *bi_ultimate = NULL;
|
struct bgp_path_info *bpi_ultimate = NULL;
|
||||||
int origin_local = 0;
|
int origin_local = 0;
|
||||||
struct bgp *src_vrf;
|
struct bgp *src_vrf;
|
||||||
|
|
||||||
@ -1068,7 +1059,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
/* Check for intersection of route targets */
|
/* Check for intersection of route targets */
|
||||||
if (!ecom_intersect(
|
if (!ecom_intersect(
|
||||||
bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
||||||
info_vpn->attr->ecommunity)) {
|
path_vpn->attr->ecommunity)) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1077,7 +1068,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
zlog_debug("%s: updating to vrf %s", __func__,
|
zlog_debug("%s: updating to vrf %s", __func__,
|
||||||
bgp_vrf->name_pretty);
|
bgp_vrf->name_pretty);
|
||||||
|
|
||||||
bgp_attr_dup(&static_attr, info_vpn->attr); /* shallow copy */
|
bgp_attr_dup(&static_attr, path_vpn->attr); /* shallow copy */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Nexthop: stash and clear
|
* Nexthop: stash and clear
|
||||||
@ -1086,15 +1077,17 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
* Stash it for later label resolution by vrf ingress path and then
|
* Stash it for later label resolution by vrf ingress path and then
|
||||||
* overwrite with 0, i.e., "me", for the sake of vrf advertisement.
|
* overwrite with 0, i.e., "me", for the sake of vrf advertisement.
|
||||||
*/
|
*/
|
||||||
uint8_t nhfamily = NEXTHOP_FAMILY(info_vpn->attr->mp_nexthop_len);
|
uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
|
||||||
|
|
||||||
|
if (nhfamily != AF_UNSPEC)
|
||||||
|
static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
|
||||||
memset(&nexthop_orig, 0, sizeof(nexthop_orig));
|
memset(&nexthop_orig, 0, sizeof(nexthop_orig));
|
||||||
nexthop_orig.family = nhfamily;
|
nexthop_orig.family = nhfamily;
|
||||||
|
|
||||||
switch (nhfamily) {
|
switch (nhfamily) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
/* save */
|
/* save */
|
||||||
nexthop_orig.u.prefix4 = info_vpn->attr->mp_nexthop_global_in;
|
nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
|
||||||
nexthop_orig.prefixlen = 32;
|
nexthop_orig.prefixlen = 32;
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
||||||
@ -1103,15 +1096,14 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
nexthop_orig.u.prefix4.s_addr;
|
nexthop_orig.u.prefix4.s_addr;
|
||||||
|
|
||||||
static_attr.mp_nexthop_global_in =
|
static_attr.mp_nexthop_global_in =
|
||||||
info_vpn->attr->mp_nexthop_global_in;
|
path_vpn->attr->mp_nexthop_global_in;
|
||||||
static_attr.mp_nexthop_len =
|
static_attr.mp_nexthop_len =
|
||||||
info_vpn->attr->mp_nexthop_len;
|
path_vpn->attr->mp_nexthop_len;
|
||||||
}
|
}
|
||||||
static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
|
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
/* save */
|
/* save */
|
||||||
nexthop_orig.u.prefix6 = info_vpn->attr->mp_nexthop_global;
|
nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
|
||||||
nexthop_orig.prefixlen = 128;
|
nexthop_orig.prefixlen = 128;
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
||||||
@ -1125,7 +1117,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
* route map handling
|
* route map handling
|
||||||
*/
|
*/
|
||||||
if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
|
if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -1173,30 +1165,30 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
|
||||||
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
|
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
|
||||||
/* work back to original route */
|
/* work back to original route */
|
||||||
for (bi_ultimate = info_vpn;
|
for (bpi_ultimate = path_vpn;
|
||||||
bi_ultimate->extra && bi_ultimate->extra->parent;
|
bpi_ultimate->extra && bpi_ultimate->extra->parent;
|
||||||
bi_ultimate = bi_ultimate->extra->parent)
|
bpi_ultimate = bpi_ultimate->extra->parent)
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if original route was unicast,
|
* if original route was unicast,
|
||||||
* then it did not arrive over vpn
|
* then it did not arrive over vpn
|
||||||
*/
|
*/
|
||||||
if (bi_ultimate->net) {
|
if (bpi_ultimate->net) {
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
|
|
||||||
table = bgp_node_table(bi_ultimate->net);
|
table = bgp_node_table(bpi_ultimate->net);
|
||||||
if (table && (table->safi == SAFI_UNICAST))
|
if (table && (table->safi == SAFI_UNICAST))
|
||||||
origin_local = 1;
|
origin_local = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy labels */
|
/* copy labels */
|
||||||
if (!origin_local &&
|
if (!origin_local && path_vpn->extra
|
||||||
info_vpn->extra && info_vpn->extra->num_labels) {
|
&& path_vpn->extra->num_labels) {
|
||||||
num_labels = info_vpn->extra->num_labels;
|
num_labels = path_vpn->extra->num_labels;
|
||||||
if (num_labels > BGP_MAX_LABELS)
|
if (num_labels > BGP_MAX_LABELS)
|
||||||
num_labels = BGP_MAX_LABELS;
|
num_labels = BGP_MAX_LABELS;
|
||||||
pLabels = info_vpn->extra->label;
|
pLabels = path_vpn->extra->label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1211,19 +1203,18 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
|
|||||||
* For VRF-2-VRF route-leaking,
|
* For VRF-2-VRF route-leaking,
|
||||||
* the source will be the originating VRF.
|
* the source will be the originating VRF.
|
||||||
*/
|
*/
|
||||||
if (info_vpn->extra && info_vpn->extra->bgp_orig)
|
if (path_vpn->extra && path_vpn->extra->bgp_orig)
|
||||||
src_vrf = info_vpn->extra->bgp_orig;
|
src_vrf = path_vpn->extra->bgp_orig;
|
||||||
else
|
else
|
||||||
src_vrf = bgp_vpn;
|
src_vrf = bgp_vpn;
|
||||||
|
|
||||||
leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
|
leak_update(bgp_vrf, bn, new_attr, afi, safi, path_vpn, pLabels,
|
||||||
pLabels, num_labels,
|
num_labels, path_vpn, /* parent */
|
||||||
info_vpn, /* parent */
|
src_vrf, &nexthop_orig, nexthop_self_flag, debug);
|
||||||
src_vrf, &nexthop_orig, nexthop_self_flag, debug);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
|
void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
|
||||||
struct bgp_info *info_vpn) /* route */
|
struct bgp_path_info *path_vpn) /* route */
|
||||||
{
|
{
|
||||||
struct listnode *mnode, *mnnode;
|
struct listnode *mnode, *mnnode;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
@ -1231,20 +1222,20 @@ void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
|
|||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
|
zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
|
||||||
|
|
||||||
/* Loop over VRFs */
|
/* Loop over VRFs */
|
||||||
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
||||||
|
|
||||||
if (!info_vpn->extra
|
if (!path_vpn->extra
|
||||||
|| info_vpn->extra->bgp_orig != bgp) { /* no loop */
|
|| path_vpn->extra->bgp_orig != bgp) { /* no loop */
|
||||||
vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
|
vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, path_vpn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
||||||
struct bgp_info *info_vpn) /* route */
|
struct bgp_path_info *path_vpn) /* route */
|
||||||
{
|
{
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
@ -1252,38 +1243,38 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
|||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct listnode *mnode, *mnnode;
|
struct listnode *mnode, *mnnode;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
const char *debugmsg;
|
const char *debugmsg;
|
||||||
char buf_prefix[PREFIX_STRLEN];
|
char buf_prefix[PREFIX_STRLEN];
|
||||||
|
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
|
prefix2str(&path_vpn->net->p, buf_prefix, sizeof(buf_prefix));
|
||||||
zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
|
zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d", __func__,
|
||||||
__func__, buf_prefix,
|
buf_prefix, path_vpn->type, path_vpn->sub_type);
|
||||||
info_vpn->type, info_vpn->sub_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
|
zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
|
||||||
|
|
||||||
if (!info_vpn->net) {
|
if (!path_vpn->net) {
|
||||||
#if ENABLE_BGP_VNC
|
#if ENABLE_BGP_VNC
|
||||||
/* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
|
/* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
|
||||||
if (info_vpn->type == ZEBRA_ROUTE_BGP &&
|
if (path_vpn->type == ZEBRA_ROUTE_BGP
|
||||||
info_vpn->sub_type == BGP_ROUTE_RFP) {
|
&& path_vpn->sub_type == BGP_ROUTE_RFP) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
|
zlog_debug(
|
||||||
|
"%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
|
||||||
__func__);
|
__func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = &info_vpn->net->p;
|
p = &path_vpn->net->p;
|
||||||
afi = family2afi(p->family);
|
afi = family2afi(p->family);
|
||||||
|
|
||||||
/* Loop over VRFs */
|
/* Loop over VRFs */
|
||||||
@ -1298,7 +1289,7 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
|||||||
/* Check for intersection of route targets */
|
/* Check for intersection of route targets */
|
||||||
if (!ecom_intersect(bgp->vpn_policy[afi]
|
if (!ecom_intersect(bgp->vpn_policy[afi]
|
||||||
.rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
.rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
|
||||||
info_vpn->attr->ecommunity)) {
|
path_vpn->attr->ecommunity)) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1308,19 +1299,20 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
|
|||||||
bgp->name_pretty);
|
bgp->name_pretty);
|
||||||
|
|
||||||
bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
|
bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
|
||||||
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
|
for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
|
||||||
if (bi->extra
|
if (bpi->extra
|
||||||
&& (struct bgp_info *)bi->extra->parent
|
&& (struct bgp_path_info *)bpi->extra->parent
|
||||||
== info_vpn) {
|
== path_vpn) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: deleting bi %p", __func__, bi);
|
zlog_debug("%s: deleting bpi %p", __func__,
|
||||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
bpi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||||
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
@ -1331,25 +1323,25 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
|
|||||||
afi_t afi)
|
afi_t afi)
|
||||||
{
|
{
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
safi_t safi = SAFI_UNICAST;
|
safi_t safi = SAFI_UNICAST;
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug("%s: entry", __func__);
|
zlog_debug("%s: entry", __func__);
|
||||||
/*
|
/*
|
||||||
* Walk vrf table, delete bi with bgp_orig in a different vrf
|
* Walk vrf table, delete bpi with bgp_orig in a different vrf
|
||||||
*/
|
*/
|
||||||
for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
|
for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
|
||||||
bn = bgp_route_next(bn)) {
|
bn = bgp_route_next(bn)) {
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (bi->extra && bi->extra->bgp_orig != bgp_vrf) {
|
if (bpi->extra && bpi->extra->bgp_orig != bgp_vrf) {
|
||||||
|
|
||||||
/* delete route */
|
/* delete route */
|
||||||
bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
|
bgp_aggregate_decrement(bgp_vrf, &bn->p, bpi,
|
||||||
afi, safi);
|
afi, safi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp_vrf, bn, afi, safi);
|
bgp_process(bgp_vrf, bn, afi, safi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1374,7 +1366,7 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
|
|||||||
|
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
memset(&prd, 0, sizeof(prd));
|
memset(&prd, 0, sizeof(prd));
|
||||||
prd.family = AF_UNSPEC;
|
prd.family = AF_UNSPEC;
|
||||||
@ -1389,13 +1381,14 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
|
|||||||
|
|
||||||
for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
|
for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
|
if (bpi->extra
|
||||||
|
&& bpi->extra->bgp_orig == bgp_vrf)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
|
vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
|
||||||
bi);
|
bpi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,10 @@ extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
|
|||||||
int tags, bool use_json);
|
int tags, bool use_json);
|
||||||
|
|
||||||
extern void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
extern void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
||||||
struct bgp_info *info_vrf);
|
struct bgp_path_info *path_vrf);
|
||||||
|
|
||||||
extern void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
extern void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
||||||
struct bgp_info *info_vrf);
|
struct bgp_path_info *path_vrf);
|
||||||
|
|
||||||
extern void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn,
|
extern void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn,
|
||||||
struct bgp *bgp_vrf, afi_t afi);
|
struct bgp *bgp_vrf, afi_t afi);
|
||||||
@ -70,10 +70,10 @@ extern void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, struct bgp *bgp_vpn,
|
|||||||
afi_t afi);
|
afi_t afi);
|
||||||
|
|
||||||
extern void vpn_leak_to_vrf_update(struct bgp *bgp_vpn,
|
extern void vpn_leak_to_vrf_update(struct bgp *bgp_vpn,
|
||||||
struct bgp_info *info_vpn);
|
struct bgp_path_info *path_vpn);
|
||||||
|
|
||||||
extern void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn,
|
extern void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn,
|
||||||
struct bgp_info *info_vpn);
|
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_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_label_withdraw(struct bgp *bgp, afi_t afi);
|
||||||
|
@ -406,7 +406,6 @@ static int bgp_accept(struct thread *thread)
|
|||||||
|
|
||||||
peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
|
peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
|
||||||
peer1->as, peer1->as_type, 0, 0, NULL);
|
peer1->as, peer1->as_type, 0, 0, NULL);
|
||||||
peer->su = su;
|
|
||||||
hash_release(peer->bgp->peerhash, peer);
|
hash_release(peer->bgp->peerhash, peer);
|
||||||
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
|
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@
|
|||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
|
#include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
|
||||||
|
|
||||||
|
DEFINE_MTYPE_STATIC(BGPD, MARTIAN_STRING, "BGP Martian Address Intf String");
|
||||||
|
|
||||||
char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size)
|
char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size)
|
||||||
{
|
{
|
||||||
prefix2str(&(bnc->node->p), buf, size);
|
prefix2str(&(bnc->node->p), buf, size);
|
||||||
@ -82,11 +84,18 @@ static void bgp_nexthop_cache_reset(struct bgp_table *table)
|
|||||||
|
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||||
bnc = bgp_nexthop_get_node_info(rn);
|
bnc = bgp_nexthop_get_node_info(rn);
|
||||||
if (bnc != NULL) {
|
if (!bnc)
|
||||||
bnc_free(bnc);
|
continue;
|
||||||
bgp_nexthop_set_node_info(rn, NULL);
|
|
||||||
bgp_unlock_node(rn);
|
while (!LIST_EMPTY(&(bnc->paths))) {
|
||||||
|
struct bgp_path_info *path = LIST_FIRST(&(bnc->paths));
|
||||||
|
|
||||||
|
path_nh_map(path, bnc, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bnc_free(bnc);
|
||||||
|
bgp_nexthop_set_node_info(rn, NULL);
|
||||||
|
bgp_unlock_node(rn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +123,7 @@ static unsigned int bgp_tip_hash_key_make(void *p)
|
|||||||
return jhash_1word(addr->addr.s_addr, 0);
|
return jhash_1word(addr->addr.s_addr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bgp_tip_hash_cmp(const void *p1, const void *p2)
|
static bool bgp_tip_hash_cmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct tip_addr *addr1 = p1;
|
const struct tip_addr *addr1 = p1;
|
||||||
const struct tip_addr *addr2 = p2;
|
const struct tip_addr *addr2 = p2;
|
||||||
@ -205,7 +214,7 @@ static void bgp_address_hash_string_del(void *val)
|
|||||||
{
|
{
|
||||||
char *data = val;
|
char *data = val;
|
||||||
|
|
||||||
XFREE(MTYPE_TMP, data);
|
XFREE(MTYPE_MARTIAN_STRING, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *bgp_address_hash_alloc(void *p)
|
static void *bgp_address_hash_alloc(void *p)
|
||||||
@ -237,7 +246,7 @@ static unsigned int bgp_address_hash_key_make(void *p)
|
|||||||
return jhash_1word(addr->addr.s_addr, 0);
|
return jhash_1word(addr->addr.s_addr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bgp_address_hash_cmp(const void *p1, const void *p2)
|
static bool bgp_address_hash_cmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct bgp_addr *addr1 = p1;
|
const struct bgp_addr *addr1 = p1;
|
||||||
const struct bgp_addr *addr2 = p2;
|
const struct bgp_addr *addr2 = p2;
|
||||||
@ -278,7 +287,7 @@ static void bgp_address_add(struct bgp *bgp, struct connected *ifc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!node) {
|
if (!node) {
|
||||||
name = XSTRDUP(MTYPE_TMP, ifc->ifp->name);
|
name = XSTRDUP(MTYPE_MARTIAN_STRING, ifc->ifp->name);
|
||||||
listnode_add(addr->ifp_name_list, name);
|
listnode_add(addr->ifp_name_list, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,8 +312,10 @@ static void bgp_address_del(struct bgp *bgp, struct connected *ifc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node)
|
if (node) {
|
||||||
list_delete_node(addr->ifp_name_list, node);
|
list_delete_node(addr->ifp_name_list, node);
|
||||||
|
XFREE(MTYPE_MARTIAN_STRING, name);
|
||||||
|
}
|
||||||
|
|
||||||
if (addr->ifp_name_list->count == 0) {
|
if (addr->ifp_name_list->count == 0) {
|
||||||
hash_release(bgp->address_hash, addr);
|
hash_release(bgp->address_hash, addr);
|
||||||
|
@ -63,7 +63,7 @@ struct bgp_nexthop_cache {
|
|||||||
|
|
||||||
struct bgp_node *node;
|
struct bgp_node *node;
|
||||||
void *nht_info; /* In BGP, peer session */
|
void *nht_info; /* In BGP, peer session */
|
||||||
LIST_HEAD(path_list, bgp_info) paths;
|
LIST_HEAD(path_list, bgp_path_info) paths;
|
||||||
unsigned int path_count;
|
unsigned int path_count;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
};
|
};
|
||||||
@ -74,8 +74,6 @@ struct tip_addr {
|
|||||||
int refcnt;
|
int refcnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int bgp_nexthop_lookup(afi_t, struct peer *peer, struct bgp_info *,
|
|
||||||
int *, int *);
|
|
||||||
extern void bgp_connected_add(struct bgp *bgp, struct connected *c);
|
extern void bgp_connected_add(struct bgp *bgp, struct connected *c);
|
||||||
extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
|
extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
|
||||||
extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
|
extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
|
||||||
|
@ -50,9 +50,7 @@ static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
|||||||
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
||||||
int is_bgp_static_route);
|
int is_bgp_static_route);
|
||||||
static void evaluate_paths(struct bgp_nexthop_cache *bnc);
|
static void evaluate_paths(struct bgp_nexthop_cache *bnc);
|
||||||
static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p);
|
static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p);
|
||||||
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
|
|
||||||
int keep);
|
|
||||||
|
|
||||||
static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
|
static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
|
||||||
{
|
{
|
||||||
@ -66,7 +64,7 @@ static int bgp_isvalid_labeled_nexthop(struct bgp_nexthop_cache *bnc)
|
|||||||
|| (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID)));
|
|| (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_find_nexthop(struct bgp_info *path, int connected)
|
int bgp_find_nexthop(struct bgp_path_info *path, int connected)
|
||||||
{
|
{
|
||||||
struct bgp_nexthop_cache *bnc = path->nexthop;
|
struct bgp_nexthop_cache *bnc = path->nexthop;
|
||||||
|
|
||||||
@ -104,14 +102,14 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_unlink_nexthop(struct bgp_info *path)
|
void bgp_unlink_nexthop(struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_nexthop_cache *bnc = path->nexthop;
|
struct bgp_nexthop_cache *bnc = path->nexthop;
|
||||||
|
|
||||||
if (!bnc)
|
if (!bnc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
path_nh_map(path, NULL, 0);
|
path_nh_map(path, NULL, false);
|
||||||
|
|
||||||
bgp_unlink_nexthop_check(bnc);
|
bgp_unlink_nexthop_check(bnc);
|
||||||
}
|
}
|
||||||
@ -143,7 +141,7 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer)
|
|||||||
* we need both the bgp_route and bgp_nexthop pointers.
|
* we need both the bgp_route and bgp_nexthop pointers.
|
||||||
*/
|
*/
|
||||||
int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
||||||
afi_t afi, struct bgp_info *ri,
|
afi_t afi, struct bgp_path_info *pi,
|
||||||
struct peer *peer, int connected)
|
struct peer *peer, int connected)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
@ -151,9 +149,9 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
|||||||
struct prefix p;
|
struct prefix p;
|
||||||
int is_bgp_static_route = 0;
|
int is_bgp_static_route = 0;
|
||||||
|
|
||||||
if (ri) {
|
if (pi) {
|
||||||
is_bgp_static_route = ((ri->type == ZEBRA_ROUTE_BGP)
|
is_bgp_static_route = ((pi->type == ZEBRA_ROUTE_BGP)
|
||||||
&& (ri->sub_type == BGP_ROUTE_STATIC))
|
&& (pi->sub_type == BGP_ROUTE_STATIC))
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
@ -161,19 +159,14 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
|||||||
to derive
|
to derive
|
||||||
address-family from the next-hop. */
|
address-family from the next-hop. */
|
||||||
if (!is_bgp_static_route)
|
if (!is_bgp_static_route)
|
||||||
afi = BGP_ATTR_NEXTHOP_AFI_IP6(ri->attr) ? AFI_IP6
|
afi = BGP_ATTR_NEXTHOP_AFI_IP6(pi->attr) ? AFI_IP6
|
||||||
: AFI_IP;
|
: AFI_IP;
|
||||||
|
|
||||||
/* This will return TRUE if the global IPv6 NH is a link local
|
/* This will return TRUE if the global IPv6 NH is a link local
|
||||||
* addr */
|
* addr */
|
||||||
if (make_prefix(afi, ri, &p) < 0)
|
if (make_prefix(afi, pi, &p) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (peer) {
|
} else if (peer) {
|
||||||
/* Don't register link local NH */
|
|
||||||
if (afi == AFI_IP6
|
|
||||||
&& IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (!sockunion2hostprefix(&peer->su, &p)) {
|
if (!sockunion2hostprefix(&peer->su, &p)) {
|
||||||
if (BGP_DEBUG(nht, NHT)) {
|
if (BGP_DEBUG(nht, NHT)) {
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -251,19 +244,20 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
|
|||||||
bnc->flags |= BGP_NEXTHOP_VALID;
|
bnc->flags |= BGP_NEXTHOP_VALID;
|
||||||
} else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
|
} else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
|
||||||
register_zebra_rnh(bnc, is_bgp_static_route);
|
register_zebra_rnh(bnc, is_bgp_static_route);
|
||||||
if (ri && ri->nexthop != bnc) {
|
if (pi && pi->nexthop != bnc) {
|
||||||
/* Unlink from existing nexthop cache, if any. This will also
|
/* Unlink from existing nexthop cache, if any. This will also
|
||||||
* free
|
* free
|
||||||
* the nexthop cache entry, if appropriate.
|
* the nexthop cache entry, if appropriate.
|
||||||
*/
|
*/
|
||||||
bgp_unlink_nexthop(ri);
|
bgp_unlink_nexthop(pi);
|
||||||
|
|
||||||
path_nh_map(ri, bnc, 1); /* updates NHT ri list reference */
|
/* updates NHT pi list reference */
|
||||||
|
path_nh_map(pi, bnc, true);
|
||||||
|
|
||||||
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
|
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
|
||||||
(bgp_info_extra_get(ri))->igpmetric = bnc->metric;
|
(bgp_path_info_extra_get(pi))->igpmetric = bnc->metric;
|
||||||
else if (ri->extra)
|
else if (pi->extra)
|
||||||
ri->extra->igpmetric = 0;
|
pi->extra->igpmetric = 0;
|
||||||
} else if (peer)
|
} else if (peer)
|
||||||
bnc->nht_info = (void *)peer; /* NHT peer reference */
|
bnc->nht_info = (void *)peer; /* NHT peer reference */
|
||||||
|
|
||||||
@ -287,10 +281,6 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
|
|||||||
if (!peer)
|
if (!peer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* We don't register link local address for NHT */
|
|
||||||
if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!sockunion2hostprefix(&peer->su, &p))
|
if (!sockunion2hostprefix(&peer->su, &p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -437,8 +427,9 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
|
|||||||
* we receive from bgp. This is to allow us
|
* we receive from bgp. This is to allow us
|
||||||
* to work with v4 routing over v6 nexthops
|
* to work with v4 routing over v6 nexthops
|
||||||
*/
|
*/
|
||||||
if (peer &&
|
if (peer && !peer->ifp
|
||||||
CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
|
&& CHECK_FLAG(peer->flags,
|
||||||
|
PEER_FLAG_CAPABILITY_ENHE)
|
||||||
&& nhr.prefix.family == AF_INET6) {
|
&& nhr.prefix.family == AF_INET6) {
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
@ -535,11 +526,11 @@ void bgp_cleanup_nexthops(struct bgp *bgp)
|
|||||||
* make_prefix - make a prefix structure from the path (essentially
|
* make_prefix - make a prefix structure from the path (essentially
|
||||||
* path's node.
|
* path's node.
|
||||||
*/
|
*/
|
||||||
static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
|
static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
int is_bgp_static = ((ri->type == ZEBRA_ROUTE_BGP)
|
int is_bgp_static = ((pi->type == ZEBRA_ROUTE_BGP)
|
||||||
&& (ri->sub_type == BGP_ROUTE_STATIC))
|
&& (pi->sub_type == BGP_ROUTE_STATIC))
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
@ -548,26 +539,21 @@ static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
|
|||||||
case AFI_IP:
|
case AFI_IP:
|
||||||
p->family = AF_INET;
|
p->family = AF_INET;
|
||||||
if (is_bgp_static) {
|
if (is_bgp_static) {
|
||||||
p->u.prefix4 = ri->net->p.u.prefix4;
|
p->u.prefix4 = pi->net->p.u.prefix4;
|
||||||
p->prefixlen = ri->net->p.prefixlen;
|
p->prefixlen = pi->net->p.prefixlen;
|
||||||
} else {
|
} else {
|
||||||
p->u.prefix4 = ri->attr->nexthop;
|
p->u.prefix4 = pi->attr->nexthop;
|
||||||
p->prefixlen = IPV4_MAX_BITLEN;
|
p->prefixlen = IPV4_MAX_BITLEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AFI_IP6:
|
case AFI_IP6:
|
||||||
/* We don't register link local NH */
|
|
||||||
if (ri->attr->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL
|
|
||||||
|| IN6_IS_ADDR_LINKLOCAL(&ri->attr->mp_nexthop_global))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
p->family = AF_INET6;
|
p->family = AF_INET6;
|
||||||
|
|
||||||
if (is_bgp_static) {
|
if (is_bgp_static) {
|
||||||
p->u.prefix6 = ri->net->p.u.prefix6;
|
p->u.prefix6 = pi->net->p.u.prefix6;
|
||||||
p->prefixlen = ri->net->p.prefixlen;
|
p->prefixlen = pi->net->p.prefixlen;
|
||||||
} else {
|
} else {
|
||||||
p->u.prefix6 = ri->attr->mp_nexthop_global;
|
p->u.prefix6 = pi->attr->mp_nexthop_global;
|
||||||
p->prefixlen = IPV6_MAX_BITLEN;
|
p->prefixlen = IPV6_MAX_BITLEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -686,7 +672,7 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
|
|||||||
static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *path;
|
struct bgp_path_info *path;
|
||||||
int afi;
|
int afi;
|
||||||
struct peer *peer = (struct peer *)bnc->nht_info;
|
struct peer *peer = (struct peer *)bnc->nht_info;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
@ -753,14 +739,16 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
|||||||
(bnc_is_valid_nexthop ? "" : "not "));
|
(bnc_is_valid_nexthop ? "" : "not "));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((CHECK_FLAG(path->flags, BGP_INFO_VALID) ? 1 : 0)
|
if ((CHECK_FLAG(path->flags, BGP_PATH_VALID) ? 1 : 0)
|
||||||
!= bnc_is_valid_nexthop) {
|
!= bnc_is_valid_nexthop) {
|
||||||
if (CHECK_FLAG(path->flags, BGP_INFO_VALID)) {
|
if (CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
|
||||||
bgp_aggregate_decrement(bgp_path, &rn->p,
|
bgp_aggregate_decrement(bgp_path, &rn->p,
|
||||||
path, afi, safi);
|
path, afi, safi);
|
||||||
bgp_info_unset_flag(rn, path, BGP_INFO_VALID);
|
bgp_path_info_unset_flag(rn, path,
|
||||||
|
BGP_PATH_VALID);
|
||||||
} else {
|
} else {
|
||||||
bgp_info_set_flag(rn, path, BGP_INFO_VALID);
|
bgp_path_info_set_flag(rn, path,
|
||||||
|
BGP_PATH_VALID);
|
||||||
bgp_aggregate_increment(bgp_path, &rn->p,
|
bgp_aggregate_increment(bgp_path, &rn->p,
|
||||||
path, afi, safi);
|
path, afi, safi);
|
||||||
}
|
}
|
||||||
@ -769,13 +757,14 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
|||||||
/* Copy the metric to the path. Will be used for bestpath
|
/* Copy the metric to the path. Will be used for bestpath
|
||||||
* computation */
|
* computation */
|
||||||
if (bgp_isvalid_nexthop(bnc) && bnc->metric)
|
if (bgp_isvalid_nexthop(bnc) && bnc->metric)
|
||||||
(bgp_info_extra_get(path))->igpmetric = bnc->metric;
|
(bgp_path_info_extra_get(path))->igpmetric =
|
||||||
|
bnc->metric;
|
||||||
else if (path->extra)
|
else if (path->extra)
|
||||||
path->extra->igpmetric = 0;
|
path->extra->igpmetric = 0;
|
||||||
|
|
||||||
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED)
|
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED)
|
||||||
|| CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
|
|| CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
|
||||||
SET_FLAG(path->flags, BGP_INFO_IGP_CHANGED);
|
SET_FLAG(path->flags, BGP_PATH_IGP_CHANGED);
|
||||||
|
|
||||||
bgp_process(bgp_path, rn, afi, safi);
|
bgp_process(bgp_path, rn, afi, safi);
|
||||||
}
|
}
|
||||||
@ -799,8 +788,8 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
|
|||||||
* make - if set, make the association. if unset, just break the existing
|
* make - if set, make the association. if unset, just break the existing
|
||||||
* association.
|
* association.
|
||||||
*/
|
*/
|
||||||
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
|
void path_nh_map(struct bgp_path_info *path, struct bgp_nexthop_cache *bnc,
|
||||||
int make)
|
bool make)
|
||||||
{
|
{
|
||||||
if (path->nexthop) {
|
if (path->nexthop) {
|
||||||
LIST_REMOVE(path, nh_thread);
|
LIST_REMOVE(path, nh_thread);
|
||||||
|
@ -32,7 +32,7 @@ extern void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id);
|
|||||||
* p - path for which the nexthop object is being looked up
|
* p - path for which the nexthop object is being looked up
|
||||||
* connected - True if NH MUST be a connected route
|
* connected - True if NH MUST be a connected route
|
||||||
*/
|
*/
|
||||||
extern int bgp_find_nexthop(struct bgp_info *p, int connected);
|
extern int bgp_find_nexthop(struct bgp_path_info *p, int connected);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
|
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
|
||||||
@ -47,16 +47,17 @@ extern int bgp_find_nexthop(struct bgp_info *p, int connected);
|
|||||||
* connected - True if NH MUST be a connected route
|
* connected - True if NH MUST be a connected route
|
||||||
*/
|
*/
|
||||||
extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
|
extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
|
||||||
struct bgp *bgp_nexthop, afi_t a, struct bgp_info *p,
|
struct bgp *bgp_nexthop, afi_t a,
|
||||||
struct peer *peer, int connected);
|
struct bgp_path_info *p, struct peer *peer,
|
||||||
|
int connected);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
|
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* p - path structure.
|
* p - path structure.
|
||||||
*/
|
*/
|
||||||
extern void bgp_unlink_nexthop(struct bgp_info *p);
|
extern void bgp_unlink_nexthop(struct bgp_path_info *p);
|
||||||
void bgp_unlink_nexthop_by_peer(struct peer *);
|
void bgp_unlink_nexthop_by_peer(struct peer *peer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
|
* bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
|
||||||
@ -74,4 +75,11 @@ extern void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer);
|
|||||||
*/
|
*/
|
||||||
extern void bgp_cleanup_nexthops(struct bgp *bgp);
|
extern void bgp_cleanup_nexthops(struct bgp *bgp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add or remove the tracking of the bgp_path_info that
|
||||||
|
* uses this nexthop
|
||||||
|
*/
|
||||||
|
extern void path_nh_map(struct bgp_path_info *path,
|
||||||
|
struct bgp_nexthop_cache *bnc, bool make);
|
||||||
|
|
||||||
#endif /* _BGP_NHT_H */
|
#endif /* _BGP_NHT_H */
|
||||||
|
@ -272,7 +272,7 @@ static void bgp_update_explicit_eors(struct peer *peer)
|
|||||||
PEER_STATUS_EOR_RECEIVED)) {
|
PEER_STATUS_EOR_RECEIVED)) {
|
||||||
if (bgp_debug_neighbor_events(peer))
|
if (bgp_debug_neighbor_events(peer))
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
" afi %d safi %d didnt receive EOR",
|
" afi %d safi %d didn't receive EOR",
|
||||||
afi, safi);
|
afi, safi);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
300
bgpd/bgp_pbr.c
300
bgpd/bgp_pbr.c
@ -227,7 +227,7 @@ struct bgp_pbr_or_filter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_filter *bpf,
|
||||||
struct nexthop *nh,
|
struct nexthop *nh,
|
||||||
float *rate);
|
float *rate);
|
||||||
@ -627,7 +627,7 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api)
|
|||||||
|
|
||||||
/* return -1 if build or validation failed */
|
/* return -1 if build or validation failed */
|
||||||
static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
||||||
struct bgp_info *info,
|
struct bgp_path_info *path,
|
||||||
struct bgp_pbr_entry_main *api)
|
struct bgp_pbr_entry_main *api)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -645,8 +645,8 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
/* extract actiosn from flowspec ecom list */
|
/* extract actiosn from flowspec ecom list */
|
||||||
if (info && info->attr && info->attr->ecommunity) {
|
if (path && path->attr && path->attr->ecommunity) {
|
||||||
ecom = info->attr->ecommunity;
|
ecom = path->attr->ecommunity;
|
||||||
for (i = 0; i < ecom->size; i++) {
|
for (i = 0; i < ecom->size; i++) {
|
||||||
ecom_eval = (struct ecommunity_val *)
|
ecom_eval = (struct ecommunity_val *)
|
||||||
(ecom->val + (i * ECOMMUNITY_SIZE));
|
(ecom->val + (i * ECOMMUNITY_SIZE));
|
||||||
@ -690,7 +690,7 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
|||||||
(char)ECOMMUNITY_REDIRECT_IP_NH)) {
|
(char)ECOMMUNITY_REDIRECT_IP_NH)) {
|
||||||
api_action->action = ACTION_REDIRECT_IP;
|
api_action->action = ACTION_REDIRECT_IP;
|
||||||
api_action->u.zr.redirect_ip_v4.s_addr =
|
api_action->u.zr.redirect_ip_v4.s_addr =
|
||||||
info->attr->nexthop.s_addr;
|
path->attr->nexthop.s_addr;
|
||||||
api_action->u.zr.duplicate = ecom_eval->val[7];
|
api_action->u.zr.duplicate = ecom_eval->val[7];
|
||||||
} else {
|
} else {
|
||||||
if (ecom_eval->val[0] !=
|
if (ecom_eval->val[0] !=
|
||||||
@ -847,7 +847,7 @@ uint32_t bgp_pbr_match_hash_key(void *arg)
|
|||||||
return jhash_1word(pbm->type, key);
|
return jhash_1word(pbm->type, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
|
bool bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
|
||||||
{
|
{
|
||||||
const struct bgp_pbr_match *r1, *r2;
|
const struct bgp_pbr_match *r1, *r2;
|
||||||
|
|
||||||
@ -855,35 +855,35 @@ int bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
|
|||||||
r2 = (const struct bgp_pbr_match *)arg2;
|
r2 = (const struct bgp_pbr_match *)arg2;
|
||||||
|
|
||||||
if (r1->vrf_id != r2->vrf_id)
|
if (r1->vrf_id != r2->vrf_id)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->type != r2->type)
|
if (r1->type != r2->type)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->flags != r2->flags)
|
if (r1->flags != r2->flags)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->action != r2->action)
|
if (r1->action != r2->action)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->pkt_len_min != r2->pkt_len_min)
|
if (r1->pkt_len_min != r2->pkt_len_min)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->pkt_len_max != r2->pkt_len_max)
|
if (r1->pkt_len_max != r2->pkt_len_max)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->tcp_flags != r2->tcp_flags)
|
if (r1->tcp_flags != r2->tcp_flags)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
|
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->dscp_value != r2->dscp_value)
|
if (r1->dscp_value != r2->dscp_value)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->fragment != r2->fragment)
|
if (r1->fragment != r2->fragment)
|
||||||
return 0;
|
return false;
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bgp_pbr_match_entry_hash_key(void *arg)
|
uint32_t bgp_pbr_match_entry_hash_key(void *arg)
|
||||||
@ -903,45 +903,41 @@ uint32_t bgp_pbr_match_entry_hash_key(void *arg)
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_pbr_match_entry_hash_equal(const void *arg1, const void *arg2)
|
bool bgp_pbr_match_entry_hash_equal(const void *arg1, const void *arg2)
|
||||||
{
|
{
|
||||||
const struct bgp_pbr_match_entry *r1, *r2;
|
const struct bgp_pbr_match_entry *r1, *r2;
|
||||||
|
|
||||||
r1 = (const struct bgp_pbr_match_entry *)arg1;
|
r1 = (const struct bgp_pbr_match_entry *)arg1;
|
||||||
r2 = (const struct bgp_pbr_match_entry *)arg2;
|
r2 = (const struct bgp_pbr_match_entry *)arg2;
|
||||||
|
|
||||||
/* on updates, comparing
|
/*
|
||||||
* backpointer is not necessary
|
* on updates, comparing backpointer is not necessary
|
||||||
*/
|
* unique value is self calculated
|
||||||
|
* rate is ignored for now
|
||||||
/* unique value is self calculated
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* rate is ignored for now
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!prefix_same(&r1->src, &r2->src))
|
if (!prefix_same(&r1->src, &r2->src))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (!prefix_same(&r1->dst, &r2->dst))
|
if (!prefix_same(&r1->dst, &r2->dst))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->src_port_min != r2->src_port_min)
|
if (r1->src_port_min != r2->src_port_min)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->dst_port_min != r2->dst_port_min)
|
if (r1->dst_port_min != r2->dst_port_min)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->src_port_max != r2->src_port_max)
|
if (r1->src_port_max != r2->src_port_max)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->dst_port_max != r2->dst_port_max)
|
if (r1->dst_port_max != r2->dst_port_max)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (r1->proto != r2->proto)
|
if (r1->proto != r2->proto)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bgp_pbr_action_hash_key(void *arg)
|
uint32_t bgp_pbr_action_hash_key(void *arg)
|
||||||
@ -955,7 +951,7 @@ uint32_t bgp_pbr_action_hash_key(void *arg)
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
|
bool bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
|
||||||
{
|
{
|
||||||
const struct bgp_pbr_action *r1, *r2;
|
const struct bgp_pbr_action *r1, *r2;
|
||||||
|
|
||||||
@ -967,11 +963,12 @@ int bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
|
|||||||
* rate is ignored
|
* rate is ignored
|
||||||
*/
|
*/
|
||||||
if (r1->vrf_id != r2->vrf_id)
|
if (r1->vrf_id != r2->vrf_id)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (memcmp(&r1->nh, &r2->nh, sizeof(struct nexthop)))
|
if (memcmp(&r1->nh, &r2->nh, sizeof(struct nexthop)))
|
||||||
return 0;
|
return false;
|
||||||
return 1;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bgp_pbr_action *bgp_pbr_action_rule_lookup(vrf_id_t vrf_id,
|
struct bgp_pbr_action *bgp_pbr_action_rule_lookup(vrf_id_t vrf_id,
|
||||||
@ -1223,16 +1220,16 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
|
|||||||
bgp_send_pbr_ipset_entry_match(bpme, false);
|
bgp_send_pbr_ipset_entry_match(bpme, false);
|
||||||
bpme->installed = false;
|
bpme->installed = false;
|
||||||
bpme->backpointer = NULL;
|
bpme->backpointer = NULL;
|
||||||
if (bpme->bgp_info) {
|
if (bpme->path) {
|
||||||
struct bgp_info *bgp_info;
|
struct bgp_path_info *path;
|
||||||
struct bgp_info_extra *extra;
|
struct bgp_path_info_extra *extra;
|
||||||
|
|
||||||
/* unlink bgp_info to bpme */
|
/* unlink bgp_path_info to bpme */
|
||||||
bgp_info = (struct bgp_info *)bpme->bgp_info;
|
path = (struct bgp_path_info *)bpme->path;
|
||||||
extra = bgp_info_extra_get(bgp_info);
|
extra = bgp_path_info_extra_get(path);
|
||||||
if (extra->bgp_fs_pbr)
|
if (extra->bgp_fs_pbr)
|
||||||
listnode_delete(extra->bgp_fs_pbr, bpme);
|
listnode_delete(extra->bgp_fs_pbr, bpme);
|
||||||
bpme->bgp_info = NULL;
|
bpme->path = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash_release(bpm->entry_hash, bpme);
|
hash_release(bpm->entry_hash, bpme);
|
||||||
@ -1304,9 +1301,8 @@ static int bgp_pbr_get_remaining_entry(struct hash_backet *backet, void *arg)
|
|||||||
return HASHWALK_ABORT;
|
return HASHWALK_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
|
static void bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||||
struct bgp_info *binfo,
|
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf)
|
||||||
struct bgp_pbr_filter *bpf)
|
|
||||||
{
|
{
|
||||||
struct bgp_pbr_match temp;
|
struct bgp_pbr_match temp;
|
||||||
struct bgp_pbr_match_entry temp2;
|
struct bgp_pbr_match_entry temp2;
|
||||||
@ -1438,13 +1434,10 @@ static uint8_t bgp_pbr_next_type_entry(uint8_t type_entry)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_icmp_action(struct bgp *bgp,
|
static void bgp_pbr_icmp_action(struct bgp *bgp, struct bgp_path_info *path,
|
||||||
struct bgp_info *binfo,
|
struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_or_filter *bpof, bool add,
|
||||||
struct bgp_pbr_or_filter *bpof,
|
struct nexthop *nh, float *rate)
|
||||||
bool add,
|
|
||||||
struct nexthop *nh,
|
|
||||||
float *rate)
|
|
||||||
{
|
{
|
||||||
struct bgp_pbr_range_port srcp, dstp;
|
struct bgp_pbr_range_port srcp, dstp;
|
||||||
struct bgp_pbr_val_mask *icmp_type, *icmp_code;
|
struct bgp_pbr_val_mask *icmp_type, *icmp_code;
|
||||||
@ -1466,11 +1459,11 @@ static void bgp_pbr_icmp_action(struct bgp *bgp,
|
|||||||
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
||||||
dstp.min_port = icmp_code->val;
|
dstp.min_port = icmp_code->val;
|
||||||
if (add)
|
if (add)
|
||||||
bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||||
bpf, nh, rate);
|
bgp, path, bpf, nh, rate);
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_remove_from_zebra_unit(
|
bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||||
bgp, binfo, bpf);
|
bgp, path, bpf);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1487,31 +1480,27 @@ static void bgp_pbr_icmp_action(struct bgp *bgp,
|
|||||||
dstp.max_port = 255;
|
dstp.max_port = 255;
|
||||||
if (add)
|
if (add)
|
||||||
bgp_pbr_policyroute_add_to_zebra_unit(
|
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||||
bgp, binfo,
|
bgp, path, bpf, nh, rate);
|
||||||
bpf, nh, rate);
|
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||||
binfo, bpf);
|
bgp, path, bpf);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
for (ALL_LIST_ELEMENTS_RO(bpof->icmp_code, cnode, icmp_code)) {
|
||||||
dstp.min_port = icmp_code->val;
|
dstp.min_port = icmp_code->val;
|
||||||
if (add)
|
if (add)
|
||||||
bgp_pbr_policyroute_add_to_zebra_unit(
|
bgp_pbr_policyroute_add_to_zebra_unit(
|
||||||
bgp, binfo,
|
bgp, path, bpf, nh, rate);
|
||||||
bpf, nh, rate);
|
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_remove_from_zebra_unit(
|
bgp_pbr_policyroute_remove_from_zebra_unit(
|
||||||
bgp, binfo, bpf);
|
bgp, path, bpf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_remove_from_zebra_recursive(struct bgp *bgp,
|
static void bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
struct bgp_info *binfo,
|
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_or_filter *bpof, uint8_t type_entry)
|
||||||
struct bgp_pbr_or_filter *bpof,
|
|
||||||
uint8_t type_entry)
|
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct bgp_pbr_val_mask *valmask;
|
struct bgp_pbr_val_mask *valmask;
|
||||||
@ -1520,8 +1509,8 @@ static void bgp_pbr_policyroute_remove_from_zebra_recursive(struct bgp *bgp,
|
|||||||
struct bgp_pbr_val_mask **target_val;
|
struct bgp_pbr_val_mask **target_val;
|
||||||
|
|
||||||
if (type_entry == 0)
|
if (type_entry == 0)
|
||||||
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path,
|
||||||
binfo, bpf);
|
bpf);
|
||||||
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
||||||
if (type_entry == FLOWSPEC_TCP_FLAGS && bpof->tcpflags) {
|
if (type_entry == FLOWSPEC_TCP_FLAGS && bpof->tcpflags) {
|
||||||
orig_list = bpof->tcpflags;
|
orig_list = bpof->tcpflags;
|
||||||
@ -1538,53 +1527,43 @@ static void bgp_pbr_policyroute_remove_from_zebra_recursive(struct bgp *bgp,
|
|||||||
} else if (type_entry == FLOWSPEC_ICMP_TYPE &&
|
} else if (type_entry == FLOWSPEC_ICMP_TYPE &&
|
||||||
(bpof->icmp_type || bpof->icmp_code)) {
|
(bpof->icmp_type || bpof->icmp_code)) {
|
||||||
/* enumerate list for icmp - must be last one */
|
/* enumerate list for icmp - must be last one */
|
||||||
bgp_pbr_icmp_action(bgp, binfo, bpf, bpof, false, NULL, NULL);
|
bgp_pbr_icmp_action(bgp, path, bpf, bpof, false, NULL, NULL);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return bgp_pbr_policyroute_remove_from_zebra_recursive(bgp,
|
return bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
binfo,
|
bgp, path, bpf, bpof, next_type_entry);
|
||||||
bpf, bpof,
|
|
||||||
next_type_entry);
|
|
||||||
}
|
}
|
||||||
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
||||||
*target_val = valmask;
|
*target_val = valmask;
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, next_type_entry);
|
||||||
next_type_entry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_remove_from_zebra(struct bgp *bgp,
|
static void bgp_pbr_policyroute_remove_from_zebra(
|
||||||
struct bgp_info *binfo,
|
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_or_filter *bpof)
|
||||||
struct bgp_pbr_or_filter *bpof)
|
|
||||||
{
|
{
|
||||||
if (!bpof)
|
if (!bpof)
|
||||||
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp,
|
return bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path,
|
||||||
binfo,
|
|
||||||
bpf);
|
bpf);
|
||||||
if (bpof->tcpflags)
|
if (bpof->tcpflags)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_TCP_FLAGS);
|
||||||
FLOWSPEC_TCP_FLAGS);
|
|
||||||
else if (bpof->dscp)
|
else if (bpof->dscp)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_DSCP);
|
||||||
FLOWSPEC_DSCP);
|
|
||||||
else if (bpof->pkt_len)
|
else if (bpof->pkt_len)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_PKT_LEN);
|
||||||
FLOWSPEC_PKT_LEN);
|
|
||||||
else if (bpof->fragment)
|
else if (bpof->fragment)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_FRAGMENT);
|
||||||
FLOWSPEC_FRAGMENT);
|
|
||||||
else if (bpof->icmp_type || bpof->icmp_code)
|
else if (bpof->icmp_type || bpof->icmp_code)
|
||||||
bgp_pbr_policyroute_remove_from_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_remove_from_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, FLOWSPEC_ICMP_TYPE);
|
||||||
FLOWSPEC_ICMP_TYPE);
|
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_remove_from_zebra_unit(bgp, binfo, bpf);
|
bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path, bpf);
|
||||||
/* flush bpof */
|
/* flush bpof */
|
||||||
if (bpof->tcpflags)
|
if (bpof->tcpflags)
|
||||||
list_delete_all_node(bpof->tcpflags);
|
list_delete_all_node(bpof->tcpflags);
|
||||||
@ -1692,10 +1671,10 @@ static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_filter *bpf,
|
||||||
struct nexthop *nh,
|
struct nexthop *nh,
|
||||||
float *rate)
|
float *rate)
|
||||||
{
|
{
|
||||||
struct bgp_pbr_match temp;
|
struct bgp_pbr_match temp;
|
||||||
struct bgp_pbr_match_entry temp2;
|
struct bgp_pbr_match_entry temp2;
|
||||||
@ -1848,19 +1827,21 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
|||||||
bpme->installed = false;
|
bpme->installed = false;
|
||||||
bpme->install_in_progress = false;
|
bpme->install_in_progress = false;
|
||||||
/* link bgp info to bpme */
|
/* link bgp info to bpme */
|
||||||
bpme->bgp_info = (void *)binfo;
|
bpme->path = (void *)path;
|
||||||
} else
|
} else
|
||||||
bpme_found = true;
|
bpme_found = true;
|
||||||
|
|
||||||
/* already installed */
|
/* already installed */
|
||||||
if (bpme_found) {
|
if (bpme_found) {
|
||||||
struct bgp_info_extra *extra = bgp_info_extra_get(binfo);
|
struct bgp_path_info_extra *extra =
|
||||||
|
bgp_path_info_extra_get(path);
|
||||||
|
|
||||||
if (extra && extra->bgp_fs_pbr &&
|
if (extra && extra->bgp_fs_pbr &&
|
||||||
listnode_lookup(extra->bgp_fs_pbr, bpme)) {
|
listnode_lookup(extra->bgp_fs_pbr, bpme)) {
|
||||||
if (BGP_DEBUG(pbr, PBR_ERROR))
|
if (BGP_DEBUG(pbr, PBR_ERROR))
|
||||||
zlog_err("%s: entry %p/%p already installed in bgp pbr",
|
zlog_err(
|
||||||
__func__, binfo, bpme);
|
"%s: entry %p/%p already installed in bgp pbr",
|
||||||
|
__func__, path, bpme);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1911,13 +1892,10 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_add_to_zebra_recursive(struct bgp *bgp,
|
static void bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
struct bgp_info *binfo,
|
struct bgp *bgp, struct bgp_path_info *path, struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_or_filter *bpof, struct nexthop *nh, float *rate,
|
||||||
struct bgp_pbr_or_filter *bpof,
|
uint8_t type_entry)
|
||||||
struct nexthop *nh,
|
|
||||||
float *rate,
|
|
||||||
uint8_t type_entry)
|
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct bgp_pbr_val_mask *valmask;
|
struct bgp_pbr_val_mask *valmask;
|
||||||
@ -1926,8 +1904,8 @@ static void bgp_pbr_policyroute_add_to_zebra_recursive(struct bgp *bgp,
|
|||||||
struct bgp_pbr_val_mask **target_val;
|
struct bgp_pbr_val_mask **target_val;
|
||||||
|
|
||||||
if (type_entry == 0)
|
if (type_entry == 0)
|
||||||
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo, bpf,
|
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh,
|
||||||
nh, rate);
|
rate);
|
||||||
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
next_type_entry = bgp_pbr_next_type_entry(type_entry);
|
||||||
if (type_entry == FLOWSPEC_TCP_FLAGS && bpof->tcpflags) {
|
if (type_entry == FLOWSPEC_TCP_FLAGS && bpof->tcpflags) {
|
||||||
orig_list = bpof->tcpflags;
|
orig_list = bpof->tcpflags;
|
||||||
@ -1944,59 +1922,45 @@ static void bgp_pbr_policyroute_add_to_zebra_recursive(struct bgp *bgp,
|
|||||||
} else if (type_entry == FLOWSPEC_ICMP_TYPE &&
|
} else if (type_entry == FLOWSPEC_ICMP_TYPE &&
|
||||||
(bpof->icmp_type || bpof->icmp_code)) {
|
(bpof->icmp_type || bpof->icmp_code)) {
|
||||||
/* enumerate list for icmp - must be last one */
|
/* enumerate list for icmp - must be last one */
|
||||||
bgp_pbr_icmp_action(bgp, binfo, bpf, bpof, true, nh, rate);
|
bgp_pbr_icmp_action(bgp, path, bpf, bpof, true, nh, rate);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
return bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof, nh, rate,
|
bgp, path, bpf, bpof, nh, rate, next_type_entry);
|
||||||
next_type_entry);
|
|
||||||
}
|
}
|
||||||
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
for (ALL_LIST_ELEMENTS(orig_list, node, nnode, valmask)) {
|
||||||
*target_val = valmask;
|
*target_val = valmask;
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, next_type_entry);
|
||||||
nh, rate,
|
|
||||||
next_type_entry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
|
static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
|
||||||
struct bgp_info *binfo,
|
struct bgp_path_info *path,
|
||||||
struct bgp_pbr_filter *bpf,
|
struct bgp_pbr_filter *bpf,
|
||||||
struct bgp_pbr_or_filter *bpof,
|
struct bgp_pbr_or_filter *bpof,
|
||||||
struct nexthop *nh,
|
struct nexthop *nh, float *rate)
|
||||||
float *rate)
|
|
||||||
{
|
{
|
||||||
if (!bpof)
|
if (!bpof)
|
||||||
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo,
|
return bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh,
|
||||||
bpf, nh, rate);
|
rate);
|
||||||
if (bpof->tcpflags)
|
if (bpof->tcpflags)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_TCP_FLAGS);
|
||||||
nh, rate,
|
|
||||||
FLOWSPEC_TCP_FLAGS);
|
|
||||||
else if (bpof->dscp)
|
else if (bpof->dscp)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_DSCP);
|
||||||
nh, rate,
|
|
||||||
FLOWSPEC_DSCP);
|
|
||||||
else if (bpof->pkt_len)
|
else if (bpof->pkt_len)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_PKT_LEN);
|
||||||
nh, rate,
|
|
||||||
FLOWSPEC_PKT_LEN);
|
|
||||||
else if (bpof->fragment)
|
else if (bpof->fragment)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_FRAGMENT);
|
||||||
nh, rate,
|
|
||||||
FLOWSPEC_FRAGMENT);
|
|
||||||
else if (bpof->icmp_type || bpof->icmp_code)
|
else if (bpof->icmp_type || bpof->icmp_code)
|
||||||
bgp_pbr_policyroute_add_to_zebra_recursive(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra_recursive(
|
||||||
bpf, bpof, nh, rate,
|
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_ICMP_TYPE);
|
||||||
FLOWSPEC_ICMP_TYPE);
|
|
||||||
else
|
else
|
||||||
bgp_pbr_policyroute_add_to_zebra_unit(bgp, binfo, bpf,
|
bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh, rate);
|
||||||
nh, rate);
|
|
||||||
/* flush bpof */
|
/* flush bpof */
|
||||||
if (bpof->tcpflags)
|
if (bpof->tcpflags)
|
||||||
list_delete_all_node(bpof->tcpflags);
|
list_delete_all_node(bpof->tcpflags);
|
||||||
@ -2012,10 +1976,8 @@ static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
|
|||||||
list_delete_all_node(bpof->icmp_code);
|
list_delete_all_node(bpof->icmp_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_pbr_handle_entry(struct bgp *bgp,
|
static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
|
||||||
struct bgp_info *binfo,
|
struct bgp_pbr_entry_main *api, bool add)
|
||||||
struct bgp_pbr_entry_main *api,
|
|
||||||
bool add)
|
|
||||||
{
|
{
|
||||||
struct nexthop nh;
|
struct nexthop nh;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -2151,9 +2113,8 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
bpf.src_port = srcp;
|
bpf.src_port = srcp;
|
||||||
bpf.dst_port = dstp;
|
bpf.dst_port = dstp;
|
||||||
if (!add)
|
if (!add)
|
||||||
return bgp_pbr_policyroute_remove_from_zebra(bgp,
|
return bgp_pbr_policyroute_remove_from_zebra(bgp, path, &bpf,
|
||||||
binfo,
|
&bpof);
|
||||||
&bpf, &bpof);
|
|
||||||
/* no action for add = true */
|
/* no action for add = true */
|
||||||
for (i = 0; i < api->action_num; i++) {
|
for (i = 0; i < api->action_num; i++) {
|
||||||
switch (api->actions[i].action) {
|
switch (api->actions[i].action) {
|
||||||
@ -2162,9 +2123,8 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
if (api->actions[i].u.r.rate == 0) {
|
if (api->actions[i].u.r.rate == 0) {
|
||||||
nh.vrf_id = api->vrf_id;
|
nh.vrf_id = api->vrf_id;
|
||||||
nh.type = NEXTHOP_TYPE_BLACKHOLE;
|
nh.type = NEXTHOP_TYPE_BLACKHOLE;
|
||||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra(
|
||||||
&bpf, &bpof,
|
bgp, path, &bpf, &bpof, &nh, &rate);
|
||||||
&nh, &rate);
|
|
||||||
} else {
|
} else {
|
||||||
/* update rate. can be reentrant */
|
/* update rate. can be reentrant */
|
||||||
rate = api->actions[i].u.r.rate;
|
rate = api->actions[i].u.r.rate;
|
||||||
@ -2204,8 +2164,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
nh.gate.ipv4.s_addr =
|
nh.gate.ipv4.s_addr =
|
||||||
api->actions[i].u.zr.redirect_ip_v4.s_addr;
|
api->actions[i].u.zr.redirect_ip_v4.s_addr;
|
||||||
nh.vrf_id = api->vrf_id;
|
nh.vrf_id = api->vrf_id;
|
||||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra(bgp, path, &bpf, &bpof,
|
||||||
&bpf, &bpof,
|
|
||||||
&nh, &rate);
|
&nh, &rate);
|
||||||
/* XXX combination with REDIRECT_VRF
|
/* XXX combination with REDIRECT_VRF
|
||||||
* + REDIRECT_NH_IP not done
|
* + REDIRECT_NH_IP not done
|
||||||
@ -2215,8 +2174,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
case ACTION_REDIRECT:
|
case ACTION_REDIRECT:
|
||||||
nh.vrf_id = api->actions[i].u.redirect_vrf;
|
nh.vrf_id = api->actions[i].u.redirect_vrf;
|
||||||
nh.type = NEXTHOP_TYPE_IPV4;
|
nh.type = NEXTHOP_TYPE_IPV4;
|
||||||
bgp_pbr_policyroute_add_to_zebra(bgp, binfo,
|
bgp_pbr_policyroute_add_to_zebra(bgp, path, &bpf, &bpof,
|
||||||
&bpf, &bpof,
|
|
||||||
&nh, &rate);
|
&nh, &rate);
|
||||||
continue_loop = 0;
|
continue_loop = 0;
|
||||||
break;
|
break;
|
||||||
@ -2236,8 +2194,8 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
||||||
struct bgp_info *info, afi_t afi, safi_t safi,
|
struct bgp_path_info *info, afi_t afi, safi_t safi,
|
||||||
bool nlri_update)
|
bool nlri_update)
|
||||||
{
|
{
|
||||||
struct bgp_pbr_entry_main api;
|
struct bgp_pbr_entry_main api;
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ struct bgp_pbr_match_entry {
|
|||||||
uint16_t dst_port_max;
|
uint16_t dst_port_max;
|
||||||
uint8_t proto;
|
uint8_t proto;
|
||||||
|
|
||||||
void *bgp_info;
|
void *path;
|
||||||
|
|
||||||
bool installed;
|
bool installed;
|
||||||
bool install_in_progress;
|
bool install_in_progress;
|
||||||
@ -267,23 +267,22 @@ extern void bgp_pbr_cleanup(struct bgp *bgp);
|
|||||||
extern void bgp_pbr_init(struct bgp *bgp);
|
extern void bgp_pbr_init(struct bgp *bgp);
|
||||||
|
|
||||||
extern uint32_t bgp_pbr_action_hash_key(void *arg);
|
extern uint32_t bgp_pbr_action_hash_key(void *arg);
|
||||||
extern int bgp_pbr_action_hash_equal(const void *arg1,
|
extern bool bgp_pbr_action_hash_equal(const void *arg1,
|
||||||
const void *arg2);
|
const void *arg2);
|
||||||
extern uint32_t bgp_pbr_match_entry_hash_key(void *arg);
|
extern uint32_t bgp_pbr_match_entry_hash_key(void *arg);
|
||||||
extern int bgp_pbr_match_entry_hash_equal(const void *arg1,
|
extern bool bgp_pbr_match_entry_hash_equal(const void *arg1,
|
||||||
const void *arg2);
|
const void *arg2);
|
||||||
extern uint32_t bgp_pbr_match_hash_key(void *arg);
|
extern uint32_t bgp_pbr_match_hash_key(void *arg);
|
||||||
extern int bgp_pbr_match_hash_equal(const void *arg1,
|
extern bool bgp_pbr_match_hash_equal(const void *arg1,
|
||||||
const void *arg2);
|
const void *arg2);
|
||||||
|
|
||||||
void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api);
|
void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api);
|
||||||
|
|
||||||
struct bgp_node;
|
struct bgp_node;
|
||||||
struct bgp_info;
|
struct bgp_path_info;
|
||||||
extern void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
extern void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
|
||||||
struct bgp_info *new_select,
|
struct bgp_path_info *new_select, afi_t afi,
|
||||||
afi_t afi, safi_t safi,
|
safi_t safi, bool nlri_update);
|
||||||
bool nlri_update);
|
|
||||||
|
|
||||||
/* bgp pbr utilities */
|
/* bgp pbr utilities */
|
||||||
extern struct bgp_pbr_interface *pbr_interface_lookup(const char *name);
|
extern struct bgp_pbr_interface *pbr_interface_lookup(const char *name);
|
||||||
|
2108
bgpd/bgp_route.c
2108
bgpd/bgp_route.c
File diff suppressed because it is too large
Load Diff
154
bgpd/bgp_route.h
154
bgpd/bgp_route.h
@ -72,11 +72,11 @@ enum bgp_show_adj_route_type {
|
|||||||
*/
|
*/
|
||||||
#define BGP_MAX_LABELS 2
|
#define BGP_MAX_LABELS 2
|
||||||
|
|
||||||
/* Ancillary information to struct bgp_info,
|
/* Ancillary information to struct bgp_path_info,
|
||||||
* used for uncommonly used data (aggregation, MPLS, etc.)
|
* used for uncommonly used data (aggregation, MPLS, etc.)
|
||||||
* and lazily allocated to save memory.
|
* and lazily allocated to save memory.
|
||||||
*/
|
*/
|
||||||
struct bgp_info_extra {
|
struct bgp_path_info_extra {
|
||||||
/* Pointer to dampening structure. */
|
/* Pointer to dampening structure. */
|
||||||
struct bgp_damp_info *damp_info;
|
struct bgp_damp_info *damp_info;
|
||||||
|
|
||||||
@ -150,13 +150,13 @@ struct bgp_info_extra {
|
|||||||
struct list *bgp_fs_pbr;
|
struct list *bgp_fs_pbr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bgp_info {
|
struct bgp_path_info {
|
||||||
/* For linked list. */
|
/* For linked list. */
|
||||||
struct bgp_info *next;
|
struct bgp_path_info *next;
|
||||||
struct bgp_info *prev;
|
struct bgp_path_info *prev;
|
||||||
|
|
||||||
/* For nexthop linked list */
|
/* For nexthop linked list */
|
||||||
LIST_ENTRY(bgp_info) nh_thread;
|
LIST_ENTRY(bgp_path_info) nh_thread;
|
||||||
|
|
||||||
/* Back pointer to the prefix node */
|
/* Back pointer to the prefix node */
|
||||||
struct bgp_node *net;
|
struct bgp_node *net;
|
||||||
@ -171,11 +171,11 @@ struct bgp_info {
|
|||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
|
|
||||||
/* Extra information */
|
/* Extra information */
|
||||||
struct bgp_info_extra *extra;
|
struct bgp_path_info_extra *extra;
|
||||||
|
|
||||||
|
|
||||||
/* Multipath information */
|
/* Multipath information */
|
||||||
struct bgp_info_mpath *mpath;
|
struct bgp_path_info_mpath *mpath;
|
||||||
|
|
||||||
/* Uptime. */
|
/* Uptime. */
|
||||||
time_t uptime;
|
time_t uptime;
|
||||||
@ -185,21 +185,21 @@ struct bgp_info {
|
|||||||
|
|
||||||
/* BGP information status. */
|
/* BGP information status. */
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
#define BGP_INFO_IGP_CHANGED (1 << 0)
|
#define BGP_PATH_IGP_CHANGED (1 << 0)
|
||||||
#define BGP_INFO_DAMPED (1 << 1)
|
#define BGP_PATH_DAMPED (1 << 1)
|
||||||
#define BGP_INFO_HISTORY (1 << 2)
|
#define BGP_PATH_HISTORY (1 << 2)
|
||||||
#define BGP_INFO_SELECTED (1 << 3)
|
#define BGP_PATH_SELECTED (1 << 3)
|
||||||
#define BGP_INFO_VALID (1 << 4)
|
#define BGP_PATH_VALID (1 << 4)
|
||||||
#define BGP_INFO_ATTR_CHANGED (1 << 5)
|
#define BGP_PATH_ATTR_CHANGED (1 << 5)
|
||||||
#define BGP_INFO_DMED_CHECK (1 << 6)
|
#define BGP_PATH_DMED_CHECK (1 << 6)
|
||||||
#define BGP_INFO_DMED_SELECTED (1 << 7)
|
#define BGP_PATH_DMED_SELECTED (1 << 7)
|
||||||
#define BGP_INFO_STALE (1 << 8)
|
#define BGP_PATH_STALE (1 << 8)
|
||||||
#define BGP_INFO_REMOVED (1 << 9)
|
#define BGP_PATH_REMOVED (1 << 9)
|
||||||
#define BGP_INFO_COUNTED (1 << 10)
|
#define BGP_PATH_COUNTED (1 << 10)
|
||||||
#define BGP_INFO_MULTIPATH (1 << 11)
|
#define BGP_PATH_MULTIPATH (1 << 11)
|
||||||
#define BGP_INFO_MULTIPATH_CHG (1 << 12)
|
#define BGP_PATH_MULTIPATH_CHG (1 << 12)
|
||||||
#define BGP_INFO_RIB_ATTR_CHG (1 << 13)
|
#define BGP_PATH_RIB_ATTR_CHG (1 << 13)
|
||||||
#define BGP_INFO_ANNC_NH_SELF (1 << 14)
|
#define BGP_PATH_ANNC_NH_SELF (1 << 14)
|
||||||
|
|
||||||
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
|
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
@ -224,9 +224,9 @@ struct bgp_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Structure used in BGP path selection */
|
/* Structure used in BGP path selection */
|
||||||
struct bgp_info_pair {
|
struct bgp_path_info_pair {
|
||||||
struct bgp_info *old;
|
struct bgp_path_info *old;
|
||||||
struct bgp_info *new;
|
struct bgp_path_info *new;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BGP static route configuration. */
|
/* BGP static route configuration. */
|
||||||
@ -277,20 +277,20 @@ struct bgp_static {
|
|||||||
#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
|
#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
|
||||||
(!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) \
|
(!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) \
|
||||||
&& ((attr)->mp_nexthop_len == 16 || (attr)->mp_nexthop_len == 32))
|
&& ((attr)->mp_nexthop_len == 16 || (attr)->mp_nexthop_len == 32))
|
||||||
#define BGP_INFO_COUNTABLE(BI) \
|
#define BGP_PATH_COUNTABLE(BI) \
|
||||||
(!CHECK_FLAG((BI)->flags, BGP_INFO_HISTORY) \
|
(!CHECK_FLAG((BI)->flags, BGP_PATH_HISTORY) \
|
||||||
&& !CHECK_FLAG((BI)->flags, BGP_INFO_REMOVED))
|
&& !CHECK_FLAG((BI)->flags, BGP_PATH_REMOVED))
|
||||||
|
|
||||||
/* Flags which indicate a route is unuseable in some form */
|
/* Flags which indicate a route is unuseable in some form */
|
||||||
#define BGP_INFO_UNUSEABLE \
|
#define BGP_PATH_UNUSEABLE \
|
||||||
(BGP_INFO_HISTORY | BGP_INFO_DAMPED | BGP_INFO_REMOVED)
|
(BGP_PATH_HISTORY | BGP_PATH_DAMPED | BGP_PATH_REMOVED)
|
||||||
/* Macro to check BGP information is alive or not. Sadly,
|
/* Macro to check BGP information is alive or not. Sadly,
|
||||||
* not equivalent to just checking previous, because of the
|
* not equivalent to just checking previous, because of the
|
||||||
* sense of the additional VALID flag.
|
* sense of the additional VALID flag.
|
||||||
*/
|
*/
|
||||||
#define BGP_INFO_HOLDDOWN(BI) \
|
#define BGP_PATH_HOLDDOWN(BI) \
|
||||||
(!CHECK_FLAG((BI)->flags, BGP_INFO_VALID) \
|
(!CHECK_FLAG((BI)->flags, BGP_PATH_VALID) \
|
||||||
|| CHECK_FLAG((BI)->flags, BGP_INFO_UNUSEABLE))
|
|| CHECK_FLAG((BI)->flags, BGP_PATH_UNUSEABLE))
|
||||||
|
|
||||||
#define DISTRIBUTE_IN_NAME(F) ((F)->dlist[FILTER_IN].name)
|
#define DISTRIBUTE_IN_NAME(F) ((F)->dlist[FILTER_IN].name)
|
||||||
#define DISTRIBUTE_IN(F) ((F)->dlist[FILTER_IN].alist)
|
#define DISTRIBUTE_IN(F) ((F)->dlist[FILTER_IN].alist)
|
||||||
@ -318,7 +318,11 @@ struct bgp_static {
|
|||||||
/* path PREFIX (addpath rxid NUMBER) */
|
/* path PREFIX (addpath rxid NUMBER) */
|
||||||
#define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32
|
#define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32
|
||||||
|
|
||||||
enum bgp_path_type { BGP_PATH_ALL, BGP_PATH_BESTPATH, BGP_PATH_MULTIPATH };
|
enum bgp_path_type {
|
||||||
|
BGP_PATH_SHOW_ALL,
|
||||||
|
BGP_PATH_SHOW_BESTPATH,
|
||||||
|
BGP_PATH_SHOW_MULTIPATH
|
||||||
|
};
|
||||||
|
|
||||||
static inline void bgp_bump_version(struct bgp_node *node)
|
static inline void bgp_bump_version(struct bgp_node *node)
|
||||||
{
|
{
|
||||||
@ -335,7 +339,7 @@ static inline int bgp_fibupd_safi(safi_t safi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
extern void bgp_rib_remove(struct bgp_node *rn, struct bgp_info *ri,
|
extern void bgp_rib_remove(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
struct peer *peer, afi_t afi, safi_t safi);
|
struct peer *peer, afi_t afi, safi_t safi);
|
||||||
extern void bgp_process_queue_init(void);
|
extern void bgp_process_queue_init(void);
|
||||||
extern void bgp_route_init(void);
|
extern void bgp_route_init(void);
|
||||||
@ -354,15 +358,19 @@ extern void bgp_clear_stale_route(struct peer *, afi_t, safi_t);
|
|||||||
extern struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
|
extern struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
|
||||||
safi_t safi, struct prefix *p,
|
safi_t safi, struct prefix *p,
|
||||||
struct prefix_rd *prd);
|
struct prefix_rd *prd);
|
||||||
extern struct bgp_info *bgp_info_lock(struct bgp_info *);
|
extern struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path);
|
||||||
extern struct bgp_info *bgp_info_unlock(struct bgp_info *);
|
extern struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path);
|
||||||
extern void bgp_info_add(struct bgp_node *rn, struct bgp_info *ri);
|
extern void bgp_path_info_add(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||||
extern void bgp_info_reap(struct bgp_node *rn, struct bgp_info *ri);
|
extern void bgp_path_info_reap(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||||
extern void bgp_info_delete(struct bgp_node *rn, struct bgp_info *ri);
|
extern void bgp_path_info_delete(struct bgp_node *rn, struct bgp_path_info *pi);
|
||||||
extern struct bgp_info_extra *bgp_info_extra_get(struct bgp_info *);
|
extern struct bgp_path_info_extra *
|
||||||
extern void bgp_info_set_flag(struct bgp_node *, struct bgp_info *, uint32_t);
|
bgp_path_info_extra_get(struct bgp_path_info *path);
|
||||||
extern void bgp_info_unset_flag(struct bgp_node *, struct bgp_info *, uint32_t);
|
extern void bgp_path_info_set_flag(struct bgp_node *rn,
|
||||||
extern void bgp_info_path_with_addpath_rx_str(struct bgp_info *ri, char *buf);
|
struct bgp_path_info *path, uint32_t flag);
|
||||||
|
extern void bgp_path_info_unset_flag(struct bgp_node *rn,
|
||||||
|
struct bgp_path_info *path, uint32_t flag);
|
||||||
|
extern void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi,
|
||||||
|
char *buf);
|
||||||
|
|
||||||
extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *);
|
extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *);
|
||||||
|
|
||||||
@ -416,38 +424,44 @@ extern void bgp_config_write_network(struct vty *, struct bgp *, afi_t, safi_t);
|
|||||||
extern void bgp_config_write_distance(struct vty *, struct bgp *, afi_t,
|
extern void bgp_config_write_distance(struct vty *, struct bgp *, afi_t,
|
||||||
safi_t);
|
safi_t);
|
||||||
|
|
||||||
extern void bgp_aggregate_increment(struct bgp *, struct prefix *,
|
extern void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
|
||||||
struct bgp_info *, afi_t, safi_t);
|
struct bgp_path_info *path, afi_t afi,
|
||||||
extern void bgp_aggregate_decrement(struct bgp *, struct prefix *,
|
safi_t safi);
|
||||||
struct bgp_info *, afi_t, safi_t);
|
extern void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
|
||||||
|
struct bgp_path_info *path, afi_t afi,
|
||||||
|
safi_t safi);
|
||||||
|
|
||||||
extern uint8_t bgp_distance_apply(struct prefix *, struct bgp_info *, afi_t,
|
extern uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *path,
|
||||||
safi_t, struct bgp *);
|
afi_t afi, safi_t safi, struct bgp *bgp);
|
||||||
|
|
||||||
extern afi_t bgp_node_afi(struct vty *);
|
extern afi_t bgp_node_afi(struct vty *);
|
||||||
extern safi_t bgp_node_safi(struct vty *);
|
extern safi_t bgp_node_safi(struct vty *);
|
||||||
|
|
||||||
extern struct bgp_info *info_make(int type, int sub_type,
|
extern struct bgp_path_info *info_make(int type, int sub_type,
|
||||||
unsigned short instance, struct peer *peer,
|
unsigned short instance,
|
||||||
struct attr *attr, struct bgp_node *rn);
|
struct peer *peer, struct attr *attr,
|
||||||
|
struct bgp_node *rn);
|
||||||
|
|
||||||
extern void route_vty_out(struct vty *, struct prefix *, struct bgp_info *, int,
|
extern void route_vty_out(struct vty *vty, struct prefix *p,
|
||||||
safi_t, json_object *);
|
struct bgp_path_info *path, int display, safi_t safi,
|
||||||
extern void route_vty_out_tag(struct vty *, struct prefix *, struct bgp_info *,
|
json_object *json_paths);
|
||||||
int, safi_t, json_object *);
|
extern void route_vty_out_tag(struct vty *vty, struct prefix *p,
|
||||||
|
struct bgp_path_info *path, int display,
|
||||||
|
safi_t safi, json_object *json);
|
||||||
extern void route_vty_out_tmp(struct vty *vty, struct prefix *p,
|
extern void route_vty_out_tmp(struct vty *vty, struct prefix *p,
|
||||||
struct attr *attr, safi_t safi, bool use_json,
|
struct attr *attr, safi_t safi, bool use_json,
|
||||||
json_object *json_ar);
|
json_object *json_ar);
|
||||||
extern void route_vty_out_overlay(struct vty *vty, struct prefix *p,
|
extern void route_vty_out_overlay(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *binfo, int display,
|
struct bgp_path_info *path, int display,
|
||||||
json_object *json);
|
json_object *json);
|
||||||
|
|
||||||
extern int subgroup_process_announce_selected(struct update_subgroup *subgrp,
|
extern int subgroup_process_announce_selected(struct update_subgroup *subgrp,
|
||||||
struct bgp_info *selected,
|
struct bgp_path_info *selected,
|
||||||
struct bgp_node *rn,
|
struct bgp_node *rn,
|
||||||
uint32_t addpath_tx_id);
|
uint32_t addpath_tx_id);
|
||||||
|
|
||||||
extern int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
|
extern int subgroup_announce_check(struct bgp_node *rn,
|
||||||
|
struct bgp_path_info *pi,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
struct prefix *p, struct attr *attr);
|
struct prefix *p, struct attr *attr);
|
||||||
|
|
||||||
@ -458,28 +472,30 @@ extern void bgp_process_queues_drain_immediate(void);
|
|||||||
extern struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
|
extern struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
|
||||||
safi_t safi, struct prefix *p,
|
safi_t safi, struct prefix *p,
|
||||||
struct prefix_rd *prd);
|
struct prefix_rd *prd);
|
||||||
extern struct bgp_info *bgp_info_new(void);
|
extern struct bgp_path_info *bgp_path_info_new(void);
|
||||||
extern void bgp_info_restore(struct bgp_node *, struct bgp_info *);
|
extern void bgp_path_info_restore(struct bgp_node *rn,
|
||||||
|
struct bgp_path_info *path);
|
||||||
|
|
||||||
extern int bgp_info_cmp_compatible(struct bgp *, struct bgp_info *,
|
extern int bgp_path_info_cmp_compatible(struct bgp *bgp,
|
||||||
struct bgp_info *, char *pfx_buf, afi_t afi,
|
struct bgp_path_info *new,
|
||||||
safi_t safi);
|
struct bgp_path_info *exist,
|
||||||
|
char *pfx_buf, afi_t afi, safi_t safi);
|
||||||
extern void bgp_attr_add_gshut_community(struct attr *attr);
|
extern void bgp_attr_add_gshut_community(struct attr *attr);
|
||||||
|
|
||||||
extern void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
|
extern void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
|
||||||
struct bgp_maxpaths_cfg *mpath_cfg,
|
struct bgp_maxpaths_cfg *mpath_cfg,
|
||||||
struct bgp_info_pair *result, afi_t afi,
|
struct bgp_path_info_pair *result, afi_t afi,
|
||||||
safi_t safi);
|
safi_t safi);
|
||||||
extern void bgp_zebra_clear_route_change_flags(struct bgp_node *rn);
|
extern void bgp_zebra_clear_route_change_flags(struct bgp_node *rn);
|
||||||
extern int bgp_zebra_has_route_changed(struct bgp_node *rn,
|
extern int bgp_zebra_has_route_changed(struct bgp_node *rn,
|
||||||
struct bgp_info *selected);
|
struct bgp_path_info *selected);
|
||||||
|
|
||||||
extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
|
extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
|
||||||
struct bgp_node *rn,
|
struct bgp_node *rn,
|
||||||
struct prefix_rd *prd, afi_t afi,
|
struct prefix_rd *prd, afi_t afi,
|
||||||
safi_t safi, json_object *json);
|
safi_t safi, json_object *json);
|
||||||
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
|
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
|
||||||
struct prefix *p, struct bgp_info *binfo,
|
struct prefix *p, struct bgp_path_info *path,
|
||||||
afi_t afi, safi_t safi,
|
afi_t afi, safi_t safi,
|
||||||
json_object *json_paths);
|
json_object *json_paths);
|
||||||
extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
|
extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -217,12 +217,12 @@ static route_map_result_t route_match(void *rule, const struct prefix *prefix,
|
|||||||
route_map_object_t type, void *object)
|
route_map_object_t type, void *object)
|
||||||
{
|
{
|
||||||
int *rpki_status = rule;
|
int *rpki_status = rule;
|
||||||
struct bgp_info *bgp_info;
|
struct bgp_path_info *path;
|
||||||
|
|
||||||
if (type == RMAP_BGP) {
|
if (type == RMAP_BGP) {
|
||||||
bgp_info = object;
|
path = object;
|
||||||
|
|
||||||
if (rpki_validate_prefix(bgp_info->peer, bgp_info->attr, prefix)
|
if (rpki_validate_prefix(path->peer, path->attr, prefix)
|
||||||
== *rpki_status) {
|
== *rpki_status) {
|
||||||
return RMAP_MATCH;
|
return RMAP_MATCH;
|
||||||
}
|
}
|
||||||
@ -418,13 +418,13 @@ static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
|
|||||||
|
|
||||||
for (ain = bgp_node->adj_in; ain; ain = ain->next) {
|
for (ain = bgp_node->adj_in; ain; ain = ain->next) {
|
||||||
int ret;
|
int ret;
|
||||||
struct bgp_info *bgp_info = bgp_node->info;
|
struct bgp_path_info *path = bgp_node->info;
|
||||||
mpls_label_t *label = NULL;
|
mpls_label_t *label = NULL;
|
||||||
uint32_t num_labels = 0;
|
uint32_t num_labels = 0;
|
||||||
|
|
||||||
if (bgp_info && bgp_info->extra) {
|
if (path && path->extra) {
|
||||||
label = bgp_info->extra->label;
|
label = path->extra->label;
|
||||||
num_labels = bgp_info->extra->num_labels;
|
num_labels = path->extra->num_labels;
|
||||||
}
|
}
|
||||||
ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id,
|
ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id,
|
||||||
ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
|
ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
|
||||||
|
@ -674,14 +674,15 @@ static uint8_t *bgpRcvdPathAttrTable(struct variable *v, oid name[],
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
||||||
size_t *length, struct bgp *bgp,
|
size_t *length, struct bgp *bgp,
|
||||||
struct prefix_ipv4 *addr, int exact)
|
struct prefix_ipv4 *addr,
|
||||||
|
int exact)
|
||||||
{
|
{
|
||||||
oid *offset;
|
oid *offset;
|
||||||
int offsetlen;
|
int offsetlen;
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *path;
|
||||||
struct bgp_info *min;
|
struct bgp_path_info *min;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
union sockunion su;
|
union sockunion su;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@ -714,9 +715,9 @@ static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
|||||||
if (rn) {
|
if (rn) {
|
||||||
bgp_unlock_node(rn);
|
bgp_unlock_node(rn);
|
||||||
|
|
||||||
for (binfo = rn->info; binfo; binfo = binfo->next)
|
for (path = rn->info; path; path = path->next)
|
||||||
if (sockunion_same(&binfo->peer->su, &su))
|
if (sockunion_same(&path->peer->su, &su))
|
||||||
return binfo;
|
return path;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offset = name + v->namelen;
|
offset = name + v->namelen;
|
||||||
@ -761,22 +762,22 @@ static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
|
|||||||
do {
|
do {
|
||||||
min = NULL;
|
min = NULL;
|
||||||
|
|
||||||
for (binfo = rn->info; binfo; binfo = binfo->next) {
|
for (path = rn->info; path; path = path->next) {
|
||||||
if (binfo->peer->su.sin.sin_family == AF_INET
|
if (path->peer->su.sin.sin_family == AF_INET
|
||||||
&& ntohl(paddr.s_addr)
|
&& ntohl(paddr.s_addr)
|
||||||
< ntohl(binfo->peer->su.sin
|
< ntohl(path->peer->su.sin
|
||||||
.sin_addr
|
.sin_addr
|
||||||
.s_addr)) {
|
.s_addr)) {
|
||||||
if (min) {
|
if (min) {
|
||||||
if (ntohl(binfo->peer->su.sin
|
if (ntohl(path->peer->su.sin
|
||||||
.sin_addr
|
.sin_addr
|
||||||
.s_addr)
|
.s_addr)
|
||||||
< ntohl(min->peer->su.sin
|
< ntohl(min->peer->su.sin
|
||||||
.sin_addr
|
.sin_addr
|
||||||
.s_addr))
|
.s_addr))
|
||||||
min = binfo;
|
min = path;
|
||||||
} else
|
} else
|
||||||
min = binfo;
|
min = path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,7 +813,7 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
|||||||
WriteMethod **write_method)
|
WriteMethod **write_method)
|
||||||
{
|
{
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct bgp_info *binfo;
|
struct bgp_path_info *path;
|
||||||
struct prefix_ipv4 addr;
|
struct prefix_ipv4 addr;
|
||||||
|
|
||||||
bgp = bgp_get_default();
|
bgp = bgp_get_default();
|
||||||
@ -824,13 +825,13 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
|||||||
return NULL;
|
return NULL;
|
||||||
memset(&addr, 0, sizeof(struct prefix_ipv4));
|
memset(&addr, 0, sizeof(struct prefix_ipv4));
|
||||||
|
|
||||||
binfo = bgp4PathAttrLookup(v, name, length, bgp, &addr, exact);
|
path = bgp4PathAttrLookup(v, name, length, bgp, &addr, exact);
|
||||||
if (!binfo)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch (v->magic) {
|
switch (v->magic) {
|
||||||
case BGP4PATHATTRPEER: /* 1 */
|
case BGP4PATHATTRPEER: /* 1 */
|
||||||
return SNMP_IPADDRESS(binfo->peer->su.sin.sin_addr);
|
return SNMP_IPADDRESS(path->peer->su.sin.sin_addr);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
|
case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
|
||||||
return SNMP_INTEGER(addr.prefixlen);
|
return SNMP_INTEGER(addr.prefixlen);
|
||||||
@ -839,28 +840,28 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
|||||||
return SNMP_IPADDRESS(addr.prefix);
|
return SNMP_IPADDRESS(addr.prefix);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRORIGIN: /* 4 */
|
case BGP4PATHATTRORIGIN: /* 4 */
|
||||||
return SNMP_INTEGER(binfo->attr->origin);
|
return SNMP_INTEGER(path->attr->origin);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRASPATHSEGMENT: /* 5 */
|
case BGP4PATHATTRASPATHSEGMENT: /* 5 */
|
||||||
return aspath_snmp_pathseg(binfo->attr->aspath, var_len);
|
return aspath_snmp_pathseg(path->attr->aspath, var_len);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRNEXTHOP: /* 6 */
|
case BGP4PATHATTRNEXTHOP: /* 6 */
|
||||||
return SNMP_IPADDRESS(binfo->attr->nexthop);
|
return SNMP_IPADDRESS(path->attr->nexthop);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRMULTIEXITDISC: /* 7 */
|
case BGP4PATHATTRMULTIEXITDISC: /* 7 */
|
||||||
return SNMP_INTEGER(binfo->attr->med);
|
return SNMP_INTEGER(path->attr->med);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRLOCALPREF: /* 8 */
|
case BGP4PATHATTRLOCALPREF: /* 8 */
|
||||||
return SNMP_INTEGER(binfo->attr->local_pref);
|
return SNMP_INTEGER(path->attr->local_pref);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
|
case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
|
||||||
return SNMP_INTEGER(1);
|
return SNMP_INTEGER(1);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRAGGREGATORAS: /* 10 */
|
case BGP4PATHATTRAGGREGATORAS: /* 10 */
|
||||||
return SNMP_INTEGER(binfo->attr->aggregator_as);
|
return SNMP_INTEGER(path->attr->aggregator_as);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRAGGREGATORADDR: /* 11 */
|
case BGP4PATHATTRAGGREGATORADDR: /* 11 */
|
||||||
return SNMP_IPADDRESS(binfo->attr->aggregator_addr);
|
return SNMP_IPADDRESS(path->attr->aggregator_addr);
|
||||||
break;
|
break;
|
||||||
case BGP4PATHATTRCALCLOCALPREF: /* 12 */
|
case BGP4PATHATTRCALCLOCALPREF: /* 12 */
|
||||||
return SNMP_INTEGER(-1);
|
return SNMP_INTEGER(-1);
|
||||||
@ -868,7 +869,7 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[],
|
|||||||
case BGP4PATHATTRBEST: /* 13 */
|
case BGP4PATHATTRBEST: /* 13 */
|
||||||
#define BGP4_PathAttrBest_false 1
|
#define BGP4_PathAttrBest_false 1
|
||||||
#define BGP4_PathAttrBest_true 2
|
#define BGP4_PathAttrBest_true 2
|
||||||
if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
|
if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
|
||||||
return SNMP_INTEGER(BGP4_PathAttrBest_true);
|
return SNMP_INTEGER(BGP4_PathAttrBest_true);
|
||||||
else
|
else
|
||||||
return SNMP_INTEGER(BGP4_PathAttrBest_false);
|
return SNMP_INTEGER(BGP4_PathAttrBest_false);
|
||||||
|
@ -104,7 +104,7 @@ struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t afi, safi_t safi)
|
|||||||
route_table_set_info(rt->route_table, rt);
|
route_table_set_info(rt->route_table, rt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pointer to bgp instance allows working back from bgp_info to bgp
|
* pointer to bgp instance allows working back from bgp_path_info to bgp
|
||||||
*/
|
*/
|
||||||
rt->bgp = bgp;
|
rt->bgp = bgp;
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ static unsigned int updgrp_hash_key_make(void *p)
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int updgrp_hash_cmp(const void *p1, const void *p2)
|
static bool updgrp_hash_cmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct update_group *grp1;
|
const struct update_group *grp1;
|
||||||
const struct update_group *grp2;
|
const struct update_group *grp2;
|
||||||
@ -407,7 +407,7 @@ static int updgrp_hash_cmp(const void *p1, const void *p2)
|
|||||||
safi_t safi;
|
safi_t safi;
|
||||||
|
|
||||||
if (!p1 || !p2)
|
if (!p1 || !p2)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
grp1 = p1;
|
grp1 = p1;
|
||||||
grp2 = p2;
|
grp2 = p2;
|
||||||
@ -422,68 +422,68 @@ static int updgrp_hash_cmp(const void *p1, const void *p2)
|
|||||||
|
|
||||||
/* put EBGP and IBGP peers in different update groups */
|
/* put EBGP and IBGP peers in different update groups */
|
||||||
if (pe1->sort != pe2->sort)
|
if (pe1->sort != pe2->sort)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
/* check peer flags */
|
/* check peer flags */
|
||||||
if ((pe1->flags & PEER_UPDGRP_FLAGS)
|
if ((pe1->flags & PEER_UPDGRP_FLAGS)
|
||||||
!= (pe2->flags & PEER_UPDGRP_FLAGS))
|
!= (pe2->flags & PEER_UPDGRP_FLAGS))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
/* If there is 'local-as' configured, it should match. */
|
/* If there is 'local-as' configured, it should match. */
|
||||||
if (pe1->change_local_as != pe2->change_local_as)
|
if (pe1->change_local_as != pe2->change_local_as)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
/* flags like route reflector client */
|
/* flags like route reflector client */
|
||||||
if ((flags1 & PEER_UPDGRP_AF_FLAGS) != (flags2 & PEER_UPDGRP_AF_FLAGS))
|
if ((flags1 & PEER_UPDGRP_AF_FLAGS) != (flags2 & PEER_UPDGRP_AF_FLAGS))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((pe1->cap & PEER_UPDGRP_CAP_FLAGS)
|
if ((pe1->cap & PEER_UPDGRP_CAP_FLAGS)
|
||||||
!= (pe2->cap & PEER_UPDGRP_CAP_FLAGS))
|
!= (pe2->cap & PEER_UPDGRP_CAP_FLAGS))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((pe1->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS)
|
if ((pe1->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS)
|
||||||
!= (pe2->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS))
|
!= (pe2->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (pe1->v_routeadv != pe2->v_routeadv)
|
if (pe1->v_routeadv != pe2->v_routeadv)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (pe1->group != pe2->group)
|
if (pe1->group != pe2->group)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
/* route-map names should be the same */
|
/* route-map names should be the same */
|
||||||
if ((fl1->map[RMAP_OUT].name && !fl2->map[RMAP_OUT].name)
|
if ((fl1->map[RMAP_OUT].name && !fl2->map[RMAP_OUT].name)
|
||||||
|| (!fl1->map[RMAP_OUT].name && fl2->map[RMAP_OUT].name)
|
|| (!fl1->map[RMAP_OUT].name && fl2->map[RMAP_OUT].name)
|
||||||
|| (fl1->map[RMAP_OUT].name && fl2->map[RMAP_OUT].name
|
|| (fl1->map[RMAP_OUT].name && fl2->map[RMAP_OUT].name
|
||||||
&& strcmp(fl1->map[RMAP_OUT].name, fl2->map[RMAP_OUT].name)))
|
&& strcmp(fl1->map[RMAP_OUT].name, fl2->map[RMAP_OUT].name)))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((fl1->dlist[FILTER_OUT].name && !fl2->dlist[FILTER_OUT].name)
|
if ((fl1->dlist[FILTER_OUT].name && !fl2->dlist[FILTER_OUT].name)
|
||||||
|| (!fl1->dlist[FILTER_OUT].name && fl2->dlist[FILTER_OUT].name)
|
|| (!fl1->dlist[FILTER_OUT].name && fl2->dlist[FILTER_OUT].name)
|
||||||
|| (fl1->dlist[FILTER_OUT].name && fl2->dlist[FILTER_OUT].name
|
|| (fl1->dlist[FILTER_OUT].name && fl2->dlist[FILTER_OUT].name
|
||||||
&& strcmp(fl1->dlist[FILTER_OUT].name,
|
&& strcmp(fl1->dlist[FILTER_OUT].name,
|
||||||
fl2->dlist[FILTER_OUT].name)))
|
fl2->dlist[FILTER_OUT].name)))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((fl1->plist[FILTER_OUT].name && !fl2->plist[FILTER_OUT].name)
|
if ((fl1->plist[FILTER_OUT].name && !fl2->plist[FILTER_OUT].name)
|
||||||
|| (!fl1->plist[FILTER_OUT].name && fl2->plist[FILTER_OUT].name)
|
|| (!fl1->plist[FILTER_OUT].name && fl2->plist[FILTER_OUT].name)
|
||||||
|| (fl1->plist[FILTER_OUT].name && fl2->plist[FILTER_OUT].name
|
|| (fl1->plist[FILTER_OUT].name && fl2->plist[FILTER_OUT].name
|
||||||
&& strcmp(fl1->plist[FILTER_OUT].name,
|
&& strcmp(fl1->plist[FILTER_OUT].name,
|
||||||
fl2->plist[FILTER_OUT].name)))
|
fl2->plist[FILTER_OUT].name)))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((fl1->aslist[FILTER_OUT].name && !fl2->aslist[FILTER_OUT].name)
|
if ((fl1->aslist[FILTER_OUT].name && !fl2->aslist[FILTER_OUT].name)
|
||||||
|| (!fl1->aslist[FILTER_OUT].name && fl2->aslist[FILTER_OUT].name)
|
|| (!fl1->aslist[FILTER_OUT].name && fl2->aslist[FILTER_OUT].name)
|
||||||
|| (fl1->aslist[FILTER_OUT].name && fl2->aslist[FILTER_OUT].name
|
|| (fl1->aslist[FILTER_OUT].name && fl2->aslist[FILTER_OUT].name
|
||||||
&& strcmp(fl1->aslist[FILTER_OUT].name,
|
&& strcmp(fl1->aslist[FILTER_OUT].name,
|
||||||
fl2->aslist[FILTER_OUT].name)))
|
fl2->aslist[FILTER_OUT].name)))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((fl1->usmap.name && !fl2->usmap.name)
|
if ((fl1->usmap.name && !fl2->usmap.name)
|
||||||
|| (!fl1->usmap.name && fl2->usmap.name)
|
|| (!fl1->usmap.name && fl2->usmap.name)
|
||||||
|| (fl1->usmap.name && fl2->usmap.name
|
|| (fl1->usmap.name && fl2->usmap.name
|
||||||
&& strcmp(fl1->usmap.name, fl2->usmap.name)))
|
&& strcmp(fl1->usmap.name, fl2->usmap.name)))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((pe1->default_rmap[afi][safi].name
|
if ((pe1->default_rmap[afi][safi].name
|
||||||
&& !pe2->default_rmap[afi][safi].name)
|
&& !pe2->default_rmap[afi][safi].name)
|
||||||
@ -493,19 +493,19 @@ static int updgrp_hash_cmp(const void *p1, const void *p2)
|
|||||||
&& pe2->default_rmap[afi][safi].name
|
&& pe2->default_rmap[afi][safi].name
|
||||||
&& strcmp(pe1->default_rmap[afi][safi].name,
|
&& strcmp(pe1->default_rmap[afi][safi].name,
|
||||||
pe2->default_rmap[afi][safi].name)))
|
pe2->default_rmap[afi][safi].name)))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((afi == AFI_IP6) && (pe1->shared_network != pe2->shared_network))
|
if ((afi == AFI_IP6) && (pe1->shared_network != pe2->shared_network))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if ((CHECK_FLAG(pe1->flags, PEER_FLAG_LONESOUL)
|
if ((CHECK_FLAG(pe1->flags, PEER_FLAG_LONESOUL)
|
||||||
|| CHECK_FLAG(pe1->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
|
|| CHECK_FLAG(pe1->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
|
||||||
|| CHECK_FLAG(pe1->af_cap[afi][safi],
|
|| CHECK_FLAG(pe1->af_cap[afi][safi],
|
||||||
PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
|
PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
|
||||||
&& !sockunion_same(&pe1->su, &pe2->su))
|
&& !sockunion_same(&pe1->su, &pe2->su))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void peer_lonesoul_or_not(struct peer *peer, int set)
|
static void peer_lonesoul_or_not(struct peer *peer, int set)
|
||||||
@ -1906,7 +1906,7 @@ int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi)
|
|||||||
* configured addpath-tx knob
|
* configured addpath-tx knob
|
||||||
*/
|
*/
|
||||||
int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
struct bgp_info *ri)
|
struct bgp_path_info *pi)
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
||||||
PEER_FLAG_ADDPATH_TX_ALL_PATHS))
|
PEER_FLAG_ADDPATH_TX_ALL_PATHS))
|
||||||
@ -1914,7 +1914,7 @@ int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
|
|
||||||
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
||||||
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)
|
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)
|
||||||
&& CHECK_FLAG(ri->flags, BGP_INFO_DMED_SELECTED))
|
&& CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -293,7 +293,7 @@ typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
|
|||||||
struct updwalk_context {
|
struct updwalk_context {
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
uint64_t updgrp_id;
|
uint64_t updgrp_id;
|
||||||
uint64_t subgrp_id;
|
uint64_t subgrp_id;
|
||||||
bgp_policy_type_e policy_type;
|
bgp_policy_type_e policy_type;
|
||||||
@ -442,7 +442,7 @@ extern void subgroup_announce_all(struct update_subgroup *subgrp);
|
|||||||
extern void subgroup_default_originate(struct update_subgroup *subgrp,
|
extern void subgroup_default_originate(struct update_subgroup *subgrp,
|
||||||
int withdraw);
|
int withdraw);
|
||||||
extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct bgp_node *rn, struct bgp_info *ri);
|
struct bgp_node *rn, struct bgp_path_info *pi);
|
||||||
extern void subgroup_clear_table(struct update_subgroup *subgrp);
|
extern void subgroup_clear_table(struct update_subgroup *subgrp);
|
||||||
extern void update_group_announce(struct bgp *bgp);
|
extern void update_group_announce(struct bgp *bgp);
|
||||||
extern void update_group_announce_rrclients(struct bgp *bgp);
|
extern void update_group_announce_rrclients(struct bgp *bgp);
|
||||||
@ -455,7 +455,8 @@ extern void bgp_adj_out_remove_subgroup(struct bgp_node *rn,
|
|||||||
struct update_subgroup *subgrp);
|
struct update_subgroup *subgrp);
|
||||||
extern void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
extern void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
struct attr *attr, struct bgp_info *binfo);
|
struct attr *attr,
|
||||||
|
struct bgp_path_info *path);
|
||||||
extern void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
|
extern void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
|
||||||
struct update_subgroup *subgrp,
|
struct update_subgroup *subgrp,
|
||||||
char withdraw, uint32_t addpath_tx_id);
|
char withdraw, uint32_t addpath_tx_id);
|
||||||
@ -469,7 +470,7 @@ extern int update_group_clear_update_dbg(struct update_group *updgrp,
|
|||||||
extern void update_bgp_group_free(struct bgp *bgp);
|
extern void update_bgp_group_free(struct bgp *bgp);
|
||||||
extern int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi);
|
extern int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi);
|
||||||
extern int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
extern int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
struct bgp_info *ri);
|
struct bgp_path_info *pi);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inline functions
|
* Inline functions
|
||||||
|
@ -101,7 +101,7 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
|||||||
{
|
{
|
||||||
struct updwalk_context *ctx = arg;
|
struct updwalk_context *ctx = arg;
|
||||||
struct update_subgroup *subgrp;
|
struct update_subgroup *subgrp;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
@ -140,15 +140,15 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
|||||||
adj_next = adj->next;
|
adj_next = adj->next;
|
||||||
|
|
||||||
if (adj->subgroup == subgrp) {
|
if (adj->subgroup == subgrp) {
|
||||||
for (ri = ctx->rn->info; ri;
|
for (pi = ctx->rn->info; pi;
|
||||||
ri = ri->next) {
|
pi = pi->next) {
|
||||||
if (ri->addpath_tx_id
|
if (pi->addpath_tx_id
|
||||||
== adj->addpath_tx_id) {
|
== adj->addpath_tx_id) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ri) {
|
if (!pi) {
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, NULL,
|
subgrp, NULL,
|
||||||
ctx->rn,
|
ctx->rn,
|
||||||
@ -157,32 +157,32 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ri = ctx->rn->info; ri; ri = ri->next) {
|
for (pi = ctx->rn->info; pi; pi = pi->next) {
|
||||||
/* Skip the bestpath for now */
|
/* Skip the bestpath for now */
|
||||||
if (ri == ctx->ri)
|
if (pi == ctx->pi)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, ri, ctx->rn,
|
subgrp, pi, ctx->rn,
|
||||||
ri->addpath_tx_id);
|
pi->addpath_tx_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the bestpath last so the "show [ip]
|
/* Process the bestpath last so the "show [ip]
|
||||||
* bgp neighbor x.x.x.x advertised"
|
* bgp neighbor x.x.x.x advertised"
|
||||||
* output shows the attributes from the bestpath
|
* output shows the attributes from the bestpath
|
||||||
*/
|
*/
|
||||||
if (ctx->ri)
|
if (ctx->pi)
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, ctx->ri, ctx->rn,
|
subgrp, ctx->pi, ctx->rn,
|
||||||
ctx->ri->addpath_tx_id);
|
ctx->pi->addpath_tx_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* An update-group that does not use addpath */
|
/* An update-group that does not use addpath */
|
||||||
else {
|
else {
|
||||||
if (ctx->ri) {
|
if (ctx->pi) {
|
||||||
subgroup_process_announce_selected(
|
subgroup_process_announce_selected(
|
||||||
subgrp, ctx->ri, ctx->rn,
|
subgrp, ctx->pi, ctx->rn,
|
||||||
ctx->ri->addpath_tx_id);
|
ctx->pi->addpath_tx_id);
|
||||||
} else {
|
} else {
|
||||||
/* Find the addpath_tx_id of the path we
|
/* Find the addpath_tx_id of the path we
|
||||||
* had advertised and
|
* had advertised and
|
||||||
@ -429,7 +429,7 @@ bgp_advertise_clean_subgroup(struct update_subgroup *subgrp,
|
|||||||
|
|
||||||
void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
||||||
struct update_subgroup *subgrp, struct attr *attr,
|
struct update_subgroup *subgrp, struct attr *attr,
|
||||||
struct bgp_info *binfo)
|
struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
struct bgp_adj_out *adj = NULL;
|
struct bgp_adj_out *adj = NULL;
|
||||||
struct bgp_advertise *adv;
|
struct bgp_advertise *adv;
|
||||||
@ -438,10 +438,10 @@ void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Look for adjacency information. */
|
/* Look for adjacency information. */
|
||||||
adj = adj_lookup(rn, subgrp, binfo->addpath_tx_id);
|
adj = adj_lookup(rn, subgrp, path->addpath_tx_id);
|
||||||
|
|
||||||
if (!adj) {
|
if (!adj) {
|
||||||
adj = bgp_adj_out_alloc(subgrp, rn, binfo->addpath_tx_id);
|
adj = bgp_adj_out_alloc(subgrp, rn, path->addpath_tx_id);
|
||||||
if (!adj)
|
if (!adj)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -452,8 +452,9 @@ void bgp_adj_out_set_subgroup(struct bgp_node *rn,
|
|||||||
|
|
||||||
adv = adj->adv;
|
adv = adj->adv;
|
||||||
adv->rn = rn;
|
adv->rn = rn;
|
||||||
assert(adv->binfo == NULL);
|
assert(adv->pathi == NULL);
|
||||||
adv->binfo = bgp_info_lock(binfo); /* bgp_info adj_out reference */
|
/* bgp_path_info adj_out reference */
|
||||||
|
adv->pathi = bgp_path_info_lock(path);
|
||||||
|
|
||||||
if (attr)
|
if (attr)
|
||||||
adv->baa = bgp_advertise_intern(subgrp->hash, attr);
|
adv->baa = bgp_advertise_intern(subgrp->hash, attr);
|
||||||
@ -568,7 +569,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp,
|
|||||||
struct bgp_table *table)
|
struct bgp_table *table)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
struct attr attr;
|
struct attr attr;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
@ -594,7 +595,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp,
|
|||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
|
|
||||||
if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
|
if (CHECK_FLAG(ri->flags, BGP_PATH_SELECTED)
|
||||||
|| (addpath_capable
|
|| (addpath_capable
|
||||||
&& bgp_addpath_tx_path(peer, afi, safi, ri))) {
|
&& bgp_addpath_tx_path(peer, afi, safi, ri))) {
|
||||||
if (subgroup_announce_check(rn, ri, subgrp,
|
if (subgroup_announce_check(rn, ri, subgrp,
|
||||||
@ -663,11 +664,12 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
|||||||
{
|
{
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct attr attr;
|
struct attr attr;
|
||||||
struct bgp_info *info, init_info, tmp_info;
|
struct aspath *aspath;
|
||||||
|
struct bgp_path_info tmp_info;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct peer *from;
|
struct peer *from;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
int ret = RMAP_DENYMATCH;
|
int ret = RMAP_DENYMATCH;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
@ -687,59 +689,46 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
|||||||
from = bgp->peer_self;
|
from = bgp->peer_self;
|
||||||
|
|
||||||
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
|
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
|
||||||
|
aspath = attr.aspath;
|
||||||
|
|
||||||
attr.local_pref = bgp->default_local_pref;
|
attr.local_pref = bgp->default_local_pref;
|
||||||
|
|
||||||
if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) {
|
|
||||||
/* IPv6 global nexthop must be included.
|
|
||||||
*/
|
|
||||||
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
|
|
||||||
|
|
||||||
/* If the peer is on shared nextwork and
|
|
||||||
* we have link-local nexthop set it. */
|
|
||||||
if (peer->shared_network
|
|
||||||
&& !IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_local))
|
|
||||||
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
|
|
||||||
}
|
|
||||||
init_info.attr = &attr;
|
|
||||||
info = &init_info;
|
|
||||||
bgp_attr_intern(info->attr);
|
|
||||||
|
|
||||||
memset(&p, 0, sizeof(p));
|
memset(&p, 0, sizeof(p));
|
||||||
p.family = afi2family(afi);
|
p.family = afi2family(afi);
|
||||||
p.prefixlen = 0;
|
p.prefixlen = 0;
|
||||||
|
|
||||||
|
if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) {
|
||||||
|
/* IPv6 global nexthop must be included. */
|
||||||
|
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
|
||||||
|
|
||||||
|
/* If the peer is on shared nextwork and we have link-local
|
||||||
|
nexthop set it. */
|
||||||
|
if (peer->shared_network
|
||||||
|
&& !IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_local))
|
||||||
|
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
|
||||||
|
}
|
||||||
|
|
||||||
if (peer->default_rmap[afi][safi].name) {
|
if (peer->default_rmap[afi][safi].name) {
|
||||||
SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
|
SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
|
||||||
for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
|
for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
|
||||||
rn = bgp_route_next(rn)) {
|
rn = bgp_route_next(rn)) {
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (ri = rn->info; ri; ri = ri->next) {
|
||||||
|
struct attr dummy_attr;
|
||||||
|
|
||||||
|
/* Provide dummy so the route-map can't modify
|
||||||
|
* the attributes */
|
||||||
|
bgp_attr_dup(&dummy_attr, ri->attr);
|
||||||
tmp_info.peer = ri->peer;
|
tmp_info.peer = ri->peer;
|
||||||
tmp_info.attr = ri->attr;
|
tmp_info.attr = &dummy_attr;
|
||||||
|
|
||||||
/* Reset attributes every time to avoid \
|
|
||||||
* unexpected as-path prepends */
|
|
||||||
bgp_attr_default_set(tmp_info.attr,
|
|
||||||
BGP_ORIGIN_IGP);
|
|
||||||
|
|
||||||
if ((afi == AFI_IP6)
|
|
||||||
|| peer_cap_enhe(peer, afi, safi)) {
|
|
||||||
tmp_info.attr->mp_nexthop_len =
|
|
||||||
BGP_ATTR_NHLEN_IPV6_GLOBAL;
|
|
||||||
|
|
||||||
if (peer->shared_network
|
|
||||||
&& !IN6_IS_ADDR_UNSPECIFIED(
|
|
||||||
&peer->nexthop.v6_local))
|
|
||||||
tmp_info.attr->mp_nexthop_len =
|
|
||||||
BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = route_map_apply(
|
ret = route_map_apply(
|
||||||
peer->default_rmap[afi][safi].map,
|
peer->default_rmap[afi][safi].map,
|
||||||
&rn->p, RMAP_BGP, &tmp_info);
|
&rn->p, RMAP_BGP, &tmp_info);
|
||||||
|
|
||||||
info = &tmp_info;
|
/* The route map might have set attributes. If
|
||||||
bgp_attr_intern(info->attr);
|
* we don't flush them
|
||||||
|
* here, they will be leaked. */
|
||||||
|
bgp_attr_flush(&dummy_attr);
|
||||||
if (ret != RMAP_DENYMATCH)
|
if (ret != RMAP_DENYMATCH)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -761,13 +750,12 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
|||||||
SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
|
SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
|
||||||
|
|
||||||
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||||
bgp_attr_add_gshut_community(info->attr);
|
bgp_attr_add_gshut_community(&attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_FLAG(subgrp->sflags,
|
SET_FLAG(subgrp->sflags,
|
||||||
SUBGRP_STATUS_DEFAULT_ORIGINATE);
|
SUBGRP_STATUS_DEFAULT_ORIGINATE);
|
||||||
subgroup_default_update_packet(subgrp, info->attr,
|
subgroup_default_update_packet(subgrp, &attr, from);
|
||||||
from);
|
|
||||||
|
|
||||||
/* The 'neighbor x.x.x.x default-originate' default will
|
/* The 'neighbor x.x.x.x default-originate' default will
|
||||||
* act as an
|
* act as an
|
||||||
@ -787,7 +775,8 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
|
|||||||
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aspath_unintern(&info->attr->aspath);
|
|
||||||
|
aspath_unintern(&aspath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -830,10 +819,10 @@ void subgroup_announce_all(struct update_subgroup *subgrp)
|
|||||||
* input route.
|
* input route.
|
||||||
*/
|
*/
|
||||||
void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct bgp_node *rn, struct bgp_info *ri)
|
struct bgp_node *rn, struct bgp_path_info *pi)
|
||||||
{
|
{
|
||||||
struct updwalk_context ctx;
|
struct updwalk_context ctx;
|
||||||
ctx.ri = ri;
|
ctx.pi = pi;
|
||||||
ctx.rn = rn;
|
ctx.rn = rn;
|
||||||
update_group_af_walk(bgp, afi, safi, group_announce_route_walkcb, &ctx);
|
update_group_af_walk(bgp, afi, safi, group_announce_route_walkcb, &ctx);
|
||||||
}
|
}
|
||||||
|
@ -687,7 +687,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
struct bgp_adj_out *adj;
|
struct bgp_adj_out *adj;
|
||||||
struct bgp_advertise *adv;
|
struct bgp_advertise *adv;
|
||||||
struct bgp_node *rn = NULL;
|
struct bgp_node *rn = NULL;
|
||||||
struct bgp_info *binfo = NULL;
|
struct bgp_path_info *path = NULL;
|
||||||
bgp_size_t total_attr_len = 0;
|
bgp_size_t total_attr_len = 0;
|
||||||
unsigned long attrlen_pos = 0;
|
unsigned long attrlen_pos = 0;
|
||||||
size_t mpattrlen_pos = 0;
|
size_t mpattrlen_pos = 0;
|
||||||
@ -731,7 +731,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
rn = adv->rn;
|
rn = adv->rn;
|
||||||
adj = adv->adj;
|
adj = adv->adj;
|
||||||
addpath_tx_id = adj->addpath_tx_id;
|
addpath_tx_id = adj->addpath_tx_id;
|
||||||
binfo = adv->binfo;
|
path = adv->pathi;
|
||||||
|
|
||||||
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
||||||
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||||
@ -747,8 +747,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
if (stream_empty(s)) {
|
if (stream_empty(s)) {
|
||||||
struct peer *from = NULL;
|
struct peer *from = NULL;
|
||||||
|
|
||||||
if (binfo)
|
if (path)
|
||||||
from = binfo->peer;
|
from = path->peer;
|
||||||
|
|
||||||
/* 1: Write the BGP message header - 16 bytes marker, 2
|
/* 1: Write the BGP message header - 16 bytes marker, 2
|
||||||
* bytes length,
|
* bytes length,
|
||||||
@ -821,13 +821,13 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
prd = (struct prefix_rd *)&rn->prn->p;
|
prd = (struct prefix_rd *)&rn->prn->p;
|
||||||
|
|
||||||
if (safi == SAFI_LABELED_UNICAST) {
|
if (safi == SAFI_LABELED_UNICAST) {
|
||||||
label = bgp_adv_label(rn, binfo, peer, afi,
|
label = bgp_adv_label(rn, path, peer, afi,
|
||||||
safi);
|
safi);
|
||||||
label_pnt = &label;
|
label_pnt = &label;
|
||||||
num_labels = 1;
|
num_labels = 1;
|
||||||
} else if (binfo && binfo->extra) {
|
} else if (path && path->extra) {
|
||||||
label_pnt = &binfo->extra->label[0];
|
label_pnt = &path->extra->label[0];
|
||||||
num_labels = binfo->extra->num_labels;
|
num_labels = path->extra->num_labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream_empty(snlri))
|
if (stream_empty(snlri))
|
||||||
@ -1123,6 +1123,8 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
|
|||||||
snprintf(tx_id_buf, sizeof(tx_id_buf),
|
snprintf(tx_id_buf, sizeof(tx_id_buf),
|
||||||
" with addpath ID %u",
|
" with addpath ID %u",
|
||||||
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
|
||||||
|
else
|
||||||
|
tx_id_buf[0] = '\0';
|
||||||
|
|
||||||
zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s %s",
|
zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s %s",
|
||||||
(SUBGRP_UPDGRP(subgrp))->id, subgrp->id,
|
(SUBGRP_UPDGRP(subgrp))->id, subgrp->id,
|
||||||
|
833
bgpd/bgp_vty.c
833
bgpd/bgp_vty.c
File diff suppressed because it is too large
Load Diff
194
bgpd/bgp_zebra.c
194
bgpd/bgp_zebra.c
@ -925,41 +925,40 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
|
static struct in6_addr *
|
||||||
ifindex_t *ifindex)
|
bgp_path_info_to_ipv6_nexthop(struct bgp_path_info *path, ifindex_t *ifindex)
|
||||||
{
|
{
|
||||||
struct in6_addr *nexthop = NULL;
|
struct in6_addr *nexthop = NULL;
|
||||||
|
|
||||||
/* Only global address nexthop exists. */
|
/* Only global address nexthop exists. */
|
||||||
if (info->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
|
if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
|
||||||
nexthop = &info->attr->mp_nexthop_global;
|
nexthop = &path->attr->mp_nexthop_global;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||||
*ifindex = info->attr->nh_ifindex;
|
*ifindex = path->attr->nh_ifindex;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If both global and link-local address present. */
|
/* If both global and link-local address present. */
|
||||||
if (info->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
||||||
/* Check if route-map is set to prefer global over link-local */
|
/* Check if route-map is set to prefer global over link-local */
|
||||||
if (info->attr->mp_nexthop_prefer_global) {
|
if (path->attr->mp_nexthop_prefer_global) {
|
||||||
nexthop = &info->attr->mp_nexthop_global;
|
nexthop = &path->attr->mp_nexthop_global;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||||
*ifindex = info->attr->nh_ifindex;
|
*ifindex = path->attr->nh_ifindex;
|
||||||
} else {
|
} else {
|
||||||
/* Workaround for Cisco's nexthop bug. */
|
/* Workaround for Cisco's nexthop bug. */
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED(
|
if (IN6_IS_ADDR_UNSPECIFIED(
|
||||||
&info->attr->mp_nexthop_global)
|
&path->attr->mp_nexthop_global)
|
||||||
&& info->peer->su_remote->sa.sa_family
|
&& path->peer->su_remote->sa.sa_family
|
||||||
== AF_INET6) {
|
== AF_INET6) {
|
||||||
nexthop =
|
nexthop =
|
||||||
&info->peer->su_remote->sin6.sin6_addr;
|
&path->peer->su_remote->sin6.sin6_addr;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||||
*ifindex = info->peer->nexthop.ifp
|
*ifindex = path->peer->nexthop.ifp
|
||||||
->ifindex;
|
->ifindex;
|
||||||
} else {
|
} else {
|
||||||
nexthop = &info->attr->mp_nexthop_local;
|
nexthop = &path->attr->mp_nexthop_local;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop))
|
||||||
*ifindex = info->attr->nh_lla_ifindex;
|
*ifindex = path->attr->nh_lla_ifindex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -968,12 +967,12 @@ static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
|
static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
|
||||||
struct bgp_info *info)
|
struct bgp_path_info *path)
|
||||||
{
|
{
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
ret = route_map_apply(map, p, RMAP_BGP, info);
|
ret = route_map_apply(map, p, RMAP_BGP, path);
|
||||||
bgp_attr_flush(info->attr);
|
bgp_attr_flush(path->attr);
|
||||||
|
|
||||||
if (ret != RMAP_DENYMATCH)
|
if (ret != RMAP_DENYMATCH)
|
||||||
return 1;
|
return 1;
|
||||||
@ -986,7 +985,7 @@ static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
|
|||||||
inet_ntop(AF_INET, &p->u.prefix4, buf[0],
|
inet_ntop(AF_INET, &p->u.prefix4, buf[0],
|
||||||
sizeof(buf[0])),
|
sizeof(buf[0])),
|
||||||
p->prefixlen,
|
p->prefixlen,
|
||||||
inet_ntop(AF_INET, &info->attr->nexthop, buf[1],
|
inet_ntop(AF_INET, &path->attr->nexthop, buf[1],
|
||||||
sizeof(buf[1])));
|
sizeof(buf[1])));
|
||||||
}
|
}
|
||||||
if (p->family == AF_INET6) {
|
if (p->family == AF_INET6) {
|
||||||
@ -994,7 +993,7 @@ static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
|
|||||||
ifindex_t ifindex;
|
ifindex_t ifindex;
|
||||||
struct in6_addr *nexthop;
|
struct in6_addr *nexthop;
|
||||||
|
|
||||||
nexthop = bgp_info_to_ipv6_nexthop(info, &ifindex);
|
nexthop = bgp_path_info_to_ipv6_nexthop(path, &ifindex);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"Zebra rmap deny: IPv6 route %s/%d nexthop %s",
|
"Zebra rmap deny: IPv6 route %s/%d nexthop %s",
|
||||||
inet_ntop(AF_INET6, &p->u.prefix6, buf[0],
|
inet_ntop(AF_INET6, &p->u.prefix6, buf[0],
|
||||||
@ -1121,17 +1120,15 @@ static int update_ipv4nh_for_route_install(int nh_othervrf,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_ipv6nh_for_route_install(int nh_othervrf,
|
static int
|
||||||
struct in6_addr *nexthop,
|
update_ipv6nh_for_route_install(int nh_othervrf, struct in6_addr *nexthop,
|
||||||
ifindex_t ifindex,
|
ifindex_t ifindex, struct bgp_path_info *pi,
|
||||||
struct bgp_info *ri,
|
struct bgp_path_info *best_pi, bool is_evpn,
|
||||||
struct bgp_info *best_ri,
|
struct zapi_nexthop *api_nh)
|
||||||
bool is_evpn,
|
|
||||||
struct zapi_nexthop *api_nh)
|
|
||||||
{
|
{
|
||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
|
|
||||||
attr = ri->attr;
|
attr = pi->attr;
|
||||||
|
|
||||||
if (is_evpn)
|
if (is_evpn)
|
||||||
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||||
@ -1150,22 +1147,22 @@ static int update_ipv6nh_for_route_install(int nh_othervrf,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
|
if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
|
||||||
if (ri == best_ri &&
|
if (pi == best_pi
|
||||||
attr->mp_nexthop_len
|
&& attr->mp_nexthop_len
|
||||||
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
||||||
if (ri->peer->nexthop.ifp)
|
if (pi->peer->nexthop.ifp)
|
||||||
ifindex = ri->peer->nexthop.ifp
|
ifindex =
|
||||||
->ifindex;
|
pi->peer->nexthop.ifp->ifindex;
|
||||||
if (!ifindex) {
|
if (!ifindex) {
|
||||||
if (ri->peer->conf_if)
|
if (pi->peer->conf_if)
|
||||||
ifindex = ri->peer->ifp->ifindex;
|
ifindex = pi->peer->ifp->ifindex;
|
||||||
else if (ri->peer->ifname)
|
else if (pi->peer->ifname)
|
||||||
ifindex = ifname2ifindex(
|
ifindex = ifname2ifindex(
|
||||||
ri->peer->ifname,
|
pi->peer->ifname,
|
||||||
ri->peer->bgp->vrf_id);
|
pi->peer->bgp->vrf_id);
|
||||||
else if (ri->peer->nexthop.ifp)
|
else if (pi->peer->nexthop.ifp)
|
||||||
ifindex = ri->peer->nexthop.ifp
|
ifindex =
|
||||||
->ifindex;
|
pi->peer->nexthop.ifp->ifindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifindex == 0)
|
if (ifindex == 0)
|
||||||
@ -1183,7 +1180,7 @@ static int update_ipv6nh_for_route_install(int nh_othervrf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||||
struct bgp_info *info, struct bgp *bgp, afi_t afi,
|
struct bgp_path_info *info, struct bgp *bgp, afi_t afi,
|
||||||
safi_t safi)
|
safi_t safi)
|
||||||
{
|
{
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
@ -1193,11 +1190,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
|||||||
int has_valid_label = 0;
|
int has_valid_label = 0;
|
||||||
uint8_t distance;
|
uint8_t distance;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
struct bgp_info *mpinfo;
|
struct bgp_path_info *mpinfo;
|
||||||
uint32_t metric;
|
uint32_t metric;
|
||||||
struct attr local_attr;
|
struct attr local_attr;
|
||||||
struct bgp_info local_info;
|
struct bgp_path_info local_info;
|
||||||
struct bgp_info *mpinfo_cp = &local_info;
|
struct bgp_path_info *mpinfo_cp = &local_info;
|
||||||
route_tag_t tag;
|
route_tag_t tag;
|
||||||
mpls_label_t label;
|
mpls_label_t label;
|
||||||
int nh_othervrf = 0;
|
int nh_othervrf = 0;
|
||||||
@ -1242,7 +1239,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
|||||||
|
|
||||||
/* Obtain peer from parent */
|
/* Obtain peer from parent */
|
||||||
if (info->extra && info->extra->parent)
|
if (info->extra && info->extra->parent)
|
||||||
peer = ((struct bgp_info *)(info->extra->parent))->peer;
|
peer = ((struct bgp_path_info *)(info->extra->parent))
|
||||||
|
->peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
tag = info->attr->tag;
|
tag = info->attr->tag;
|
||||||
@ -1266,7 +1264,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
|||||||
|
|
||||||
/* Metric is currently based on the best-path only */
|
/* Metric is currently based on the best-path only */
|
||||||
metric = info->attr->med;
|
metric = info->attr->med;
|
||||||
for (mpinfo = info; mpinfo; mpinfo = bgp_info_mpath_next(mpinfo)) {
|
for (mpinfo = info; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
|
||||||
if (valid_nh_count >= multipath_num)
|
if (valid_nh_count >= multipath_num)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1356,8 +1354,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
|||||||
tag = mpinfo_cp->attr->tag;
|
tag = mpinfo_cp->attr->tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nexthop = bgp_info_to_ipv6_nexthop(mpinfo_cp,
|
nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp,
|
||||||
&ifindex);
|
&ifindex);
|
||||||
nh_updated = update_ipv6nh_for_route_install(
|
nh_updated = update_ipv6nh_for_route_install(
|
||||||
nh_othervrf, nexthop, ifindex,
|
nh_othervrf, nexthop, ifindex,
|
||||||
mpinfo, info, is_evpn, api_nh);
|
mpinfo, info, is_evpn, api_nh);
|
||||||
@ -1466,7 +1464,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
|
|||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
|
|
||||||
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
|
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
|
||||||
* know of this instance.
|
* know of this instance.
|
||||||
@ -1479,18 +1477,18 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (pi = rn->info; pi; pi = pi->next)
|
||||||
if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) &&
|
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
|
||||||
|
|
||||||
(ri->type == ZEBRA_ROUTE_BGP
|
(pi->type == ZEBRA_ROUTE_BGP
|
||||||
&& (ri->sub_type == BGP_ROUTE_NORMAL
|
&& (pi->sub_type == BGP_ROUTE_NORMAL
|
||||||
|| ri->sub_type == BGP_ROUTE_IMPORTED)))
|
|| pi->sub_type == BGP_ROUTE_IMPORTED)))
|
||||||
|
|
||||||
bgp_zebra_announce(rn, &rn->p, ri, bgp, afi,
|
bgp_zebra_announce(rn, &rn->p, pi, bgp, afi,
|
||||||
safi);
|
safi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info,
|
void bgp_zebra_withdraw(struct prefix *p, struct bgp_path_info *info,
|
||||||
struct bgp *bgp, safi_t safi)
|
struct bgp *bgp, safi_t safi)
|
||||||
{
|
{
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
@ -1662,7 +1660,8 @@ int bgp_redistribute_resend(struct bgp *bgp, afi_t afi, int type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Redistribute with route-map specification. */
|
/* Redistribute with route-map specification. */
|
||||||
int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name)
|
int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name,
|
||||||
|
struct route_map *route_map)
|
||||||
{
|
{
|
||||||
if (red->rmap.name && (strcmp(red->rmap.name, name) == 0))
|
if (red->rmap.name && (strcmp(red->rmap.name, name) == 0))
|
||||||
return 0;
|
return 0;
|
||||||
@ -1670,7 +1669,7 @@ int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name)
|
|||||||
if (red->rmap.name)
|
if (red->rmap.name)
|
||||||
XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
|
XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
|
||||||
red->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
|
red->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
|
||||||
red->rmap.map = route_map_lookup_by_name(name);
|
red->rmap.map = route_map;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1680,7 +1679,7 @@ int bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
|
|||||||
afi_t afi, int type, uint32_t metric)
|
afi_t afi, int type, uint32_t metric)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *pi;
|
||||||
|
|
||||||
if (red->redist_metric_flag && red->redist_metric == metric)
|
if (red->redist_metric_flag && red->redist_metric == metric)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1690,21 +1689,21 @@ int bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
|
|||||||
|
|
||||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
||||||
rn = bgp_route_next(rn)) {
|
rn = bgp_route_next(rn)) {
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE
|
if (pi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
||||||
&& ri->type == type
|
&& pi->type == type
|
||||||
&& ri->instance == red->instance) {
|
&& pi->instance == red->instance) {
|
||||||
struct attr *old_attr;
|
struct attr *old_attr;
|
||||||
struct attr new_attr;
|
struct attr new_attr;
|
||||||
|
|
||||||
bgp_attr_dup(&new_attr, ri->attr);
|
bgp_attr_dup(&new_attr, pi->attr);
|
||||||
new_attr.med = red->redist_metric;
|
new_attr.med = red->redist_metric;
|
||||||
old_attr = ri->attr;
|
old_attr = pi->attr;
|
||||||
ri->attr = bgp_attr_intern(&new_attr);
|
pi->attr = bgp_attr_intern(&new_attr);
|
||||||
bgp_attr_unintern(&old_attr);
|
bgp_attr_unintern(&old_attr);
|
||||||
|
|
||||||
bgp_info_set_flag(rn, ri,
|
bgp_path_info_set_flag(rn, pi,
|
||||||
BGP_INFO_ATTR_CHANGED);
|
BGP_PATH_ATTR_CHANGED);
|
||||||
bgp_process(bgp, rn, afi, SAFI_UNICAST);
|
bgp_process(bgp, rn, afi, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1933,6 +1932,29 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
|
|||||||
return zclient_send_message(zclient);
|
return zclient_send_message(zclient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bgp_zebra_vxlan_flood_control(struct bgp *bgp,
|
||||||
|
enum vxlan_flood_control flood_ctrl)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
|
||||||
|
/* Check socket. */
|
||||||
|
if (!zclient || zclient->sock < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Don't try to register if Zebra doesn't know of this instance. */
|
||||||
|
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
s = zclient->obuf;
|
||||||
|
stream_reset(s);
|
||||||
|
|
||||||
|
zclient_create_header(s, ZEBRA_VXLAN_FLOOD_CONTROL, bgp->vrf_id);
|
||||||
|
stream_putc(s, flood_ctrl);
|
||||||
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
|
||||||
|
return zclient_send_message(zclient);
|
||||||
|
}
|
||||||
|
|
||||||
int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
|
int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
@ -1950,6 +1972,10 @@ int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
|
|||||||
|
|
||||||
zclient_create_header(s, ZEBRA_ADVERTISE_ALL_VNI, bgp->vrf_id);
|
zclient_create_header(s, ZEBRA_ADVERTISE_ALL_VNI, bgp->vrf_id);
|
||||||
stream_putc(s, advertise);
|
stream_putc(s, advertise);
|
||||||
|
/* Also inform current BUM handling setting. This is really
|
||||||
|
* relevant only when 'advertise' is set.
|
||||||
|
*/
|
||||||
|
stream_putc(s, bgp->vxlan_flood_ctrl);
|
||||||
stream_putw_at(s, 0, stream_get_endp(s));
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
|
||||||
return zclient_send_message(zclient);
|
return zclient_send_message(zclient);
|
||||||
@ -2081,20 +2107,20 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
|
|||||||
break;
|
break;
|
||||||
case ZAPI_IPSET_ENTRY_INSTALLED:
|
case ZAPI_IPSET_ENTRY_INSTALLED:
|
||||||
{
|
{
|
||||||
struct bgp_info *bgp_info;
|
struct bgp_path_info *path;
|
||||||
struct bgp_info_extra *extra;
|
struct bgp_path_info_extra *extra;
|
||||||
|
|
||||||
bgp_pbime->installed = true;
|
bgp_pbime->installed = true;
|
||||||
bgp_pbime->install_in_progress = false;
|
bgp_pbime->install_in_progress = false;
|
||||||
if (BGP_DEBUG(zebra, ZEBRA))
|
if (BGP_DEBUG(zebra, ZEBRA))
|
||||||
zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
|
zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
|
||||||
__PRETTY_FUNCTION__);
|
__PRETTY_FUNCTION__);
|
||||||
/* link bgp_info to bpme */
|
/* link bgp_path_info to bpme */
|
||||||
bgp_info = (struct bgp_info *)bgp_pbime->bgp_info;
|
path = (struct bgp_path_info *)bgp_pbime->path;
|
||||||
extra = bgp_info_extra_get(bgp_info);
|
extra = bgp_path_info_extra_get(path);
|
||||||
if (extra->bgp_fs_pbr == NULL)
|
if (extra->bgp_fs_pbr == NULL)
|
||||||
extra->bgp_fs_pbr = list_new();
|
extra->bgp_fs_pbr = list_new();
|
||||||
listnode_add(extra->bgp_fs_pbr, bgp_pbime);
|
listnode_add(extra->bgp_fs_pbr, bgp_pbime);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
|
case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
|
||||||
|
@ -36,11 +36,12 @@ extern void bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t,
|
|||||||
safi_t);
|
safi_t);
|
||||||
extern void bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
|
extern void bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
|
||||||
safi_t);
|
safi_t);
|
||||||
extern void bgp_zebra_announce(struct bgp_node *, struct prefix *,
|
extern void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||||
struct bgp_info *, struct bgp *, afi_t, safi_t);
|
struct bgp_path_info *path, struct bgp *bgp,
|
||||||
|
afi_t afi, safi_t safi);
|
||||||
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
|
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
|
||||||
extern void bgp_zebra_withdraw(struct prefix *, struct bgp_info *,
|
extern void bgp_zebra_withdraw(struct prefix *p, struct bgp_path_info *path,
|
||||||
struct bgp *, safi_t);
|
struct bgp *bgp, safi_t safi);
|
||||||
|
|
||||||
extern void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer);
|
extern void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer);
|
||||||
extern void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer);
|
extern void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer);
|
||||||
@ -55,7 +56,8 @@ extern struct bgp_redist *bgp_redist_add(struct bgp *, afi_t, uint8_t,
|
|||||||
extern int bgp_redistribute_set(struct bgp *, afi_t, int, unsigned short,
|
extern int bgp_redistribute_set(struct bgp *, afi_t, int, unsigned short,
|
||||||
bool changed);
|
bool changed);
|
||||||
extern int bgp_redistribute_resend(struct bgp *, afi_t, int, unsigned short);
|
extern int bgp_redistribute_resend(struct bgp *, afi_t, int, unsigned short);
|
||||||
extern int bgp_redistribute_rmap_set(struct bgp_redist *, const char *);
|
extern int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name,
|
||||||
|
struct route_map *route_map);
|
||||||
extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *, afi_t,
|
extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *, afi_t,
|
||||||
int, uint32_t);
|
int, uint32_t);
|
||||||
extern int bgp_redistribute_unset(struct bgp *, afi_t, int, unsigned short);
|
extern int bgp_redistribute_unset(struct bgp *, afi_t, int, unsigned short);
|
||||||
@ -71,6 +73,8 @@ extern int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise,
|
|||||||
vni_t vni);
|
vni_t vni);
|
||||||
extern int bgp_zebra_advertise_gw_macip(struct bgp *, int, vni_t);
|
extern int bgp_zebra_advertise_gw_macip(struct bgp *, int, vni_t);
|
||||||
extern int bgp_zebra_advertise_all_vni(struct bgp *, int);
|
extern int bgp_zebra_advertise_all_vni(struct bgp *, int);
|
||||||
|
extern int bgp_zebra_vxlan_flood_control(struct bgp *bgp,
|
||||||
|
enum vxlan_flood_control flood_ctrl);
|
||||||
|
|
||||||
extern int bgp_zebra_num_connects(void);
|
extern int bgp_zebra_num_connects(void);
|
||||||
|
|
||||||
|
71
bgpd/bgpd.c
71
bgpd/bgpd.c
@ -769,7 +769,7 @@ static unsigned int peer_hash_key_make(void *p)
|
|||||||
return sockunion_hash(&peer->su);
|
return sockunion_hash(&peer->su);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int peer_hash_same(const void *p1, const void *p2)
|
static bool peer_hash_same(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct peer *peer1 = p1;
|
const struct peer *peer1 = p1;
|
||||||
const struct peer *peer2 = p2;
|
const struct peer *peer2 = p2;
|
||||||
@ -1422,7 +1422,15 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create new BGP peer. */
|
/*
|
||||||
|
* Create new BGP peer.
|
||||||
|
*
|
||||||
|
* conf_if and su are mutually exclusive if configuring from the cli.
|
||||||
|
* If we are handing a doppelganger, then we *must* pass in both
|
||||||
|
* the original peer's su and conf_if, so that we can appropriately
|
||||||
|
* track the bgp->peerhash( ie we don't want to remove the current
|
||||||
|
* one from the config ).
|
||||||
|
*/
|
||||||
struct peer *peer_create(union sockunion *su, const char *conf_if,
|
struct peer *peer_create(union sockunion *su, const char *conf_if,
|
||||||
struct bgp *bgp, as_t local_as, as_t remote_as,
|
struct bgp *bgp, as_t local_as, as_t remote_as,
|
||||||
int as_type, afi_t afi, safi_t safi,
|
int as_type, afi_t afi, safi_t safi,
|
||||||
@ -1435,7 +1443,10 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
|
|||||||
peer = peer_new(bgp);
|
peer = peer_new(bgp);
|
||||||
if (conf_if) {
|
if (conf_if) {
|
||||||
peer->conf_if = XSTRDUP(MTYPE_PEER_CONF_IF, conf_if);
|
peer->conf_if = XSTRDUP(MTYPE_PEER_CONF_IF, conf_if);
|
||||||
bgp_peer_conf_if_to_su_update(peer);
|
if (su)
|
||||||
|
peer->su = *su;
|
||||||
|
else
|
||||||
|
bgp_peer_conf_if_to_su_update(peer);
|
||||||
if (peer->host)
|
if (peer->host)
|
||||||
XFREE(MTYPE_BGP_PEER_HOST, peer->host);
|
XFREE(MTYPE_BGP_PEER_HOST, peer->host);
|
||||||
peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, conf_if);
|
peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, conf_if);
|
||||||
@ -4485,7 +4496,7 @@ int peer_update_source_unset(struct peer *peer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
|
int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
const char *rmap)
|
const char *rmap, struct route_map *route_map)
|
||||||
{
|
{
|
||||||
struct peer *member;
|
struct peer *member;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
@ -4501,8 +4512,7 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
|
|
||||||
peer->default_rmap[afi][safi].name =
|
peer->default_rmap[afi][safi].name =
|
||||||
XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
|
XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
|
||||||
peer->default_rmap[afi][safi].map =
|
peer->default_rmap[afi][safi].map = route_map;
|
||||||
route_map_lookup_by_name(rmap);
|
|
||||||
}
|
}
|
||||||
} else if (!rmap) {
|
} else if (!rmap) {
|
||||||
if (peer->default_rmap[afi][safi].name)
|
if (peer->default_rmap[afi][safi].name)
|
||||||
@ -4546,8 +4556,7 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
|
|
||||||
member->default_rmap[afi][safi].name =
|
member->default_rmap[afi][safi].name =
|
||||||
XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
|
XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
|
||||||
member->default_rmap[afi][safi].map =
|
member->default_rmap[afi][safi].map = route_map;
|
||||||
route_map_lookup_by_name(rmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update peer route announcements. */
|
/* Update peer route announcements. */
|
||||||
@ -6012,7 +6021,7 @@ static void peer_aslist_del(const char *aslist_name)
|
|||||||
|
|
||||||
|
|
||||||
int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
|
int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
|
||||||
const char *name)
|
const char *name, struct route_map *route_map)
|
||||||
{
|
{
|
||||||
struct peer *member;
|
struct peer *member;
|
||||||
struct bgp_filter *filter;
|
struct bgp_filter *filter;
|
||||||
@ -6026,7 +6035,7 @@ int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
|
|||||||
if (filter->map[direct].name)
|
if (filter->map[direct].name)
|
||||||
XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
|
XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
|
||||||
filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
|
filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
|
||||||
filter->map[direct].map = route_map_lookup_by_name(name);
|
filter->map[direct].map = route_map;
|
||||||
|
|
||||||
/* Check if handling a regular peer. */
|
/* Check if handling a regular peer. */
|
||||||
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
|
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
|
||||||
@ -6055,7 +6064,7 @@ int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
|
|||||||
if (filter->map[direct].name)
|
if (filter->map[direct].name)
|
||||||
XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
|
XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
|
||||||
filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
|
filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
|
||||||
filter->map[direct].map = route_map_lookup_by_name(name);
|
filter->map[direct].map = route_map;
|
||||||
|
|
||||||
/* Process peer route updates. */
|
/* Process peer route updates. */
|
||||||
peer_on_policy_change(member, afi, safi,
|
peer_on_policy_change(member, afi, safi,
|
||||||
@ -6130,7 +6139,7 @@ int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
|
|||||||
|
|
||||||
/* Set unsuppress-map to the peer. */
|
/* Set unsuppress-map to the peer. */
|
||||||
int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
|
int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
const char *name)
|
const char *name, struct route_map *route_map)
|
||||||
{
|
{
|
||||||
struct peer *member;
|
struct peer *member;
|
||||||
struct bgp_filter *filter;
|
struct bgp_filter *filter;
|
||||||
@ -6141,7 +6150,7 @@ int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
if (filter->usmap.name)
|
if (filter->usmap.name)
|
||||||
XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
|
XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
|
||||||
filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
|
filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
|
||||||
filter->usmap.map = route_map_lookup_by_name(name);
|
filter->usmap.map = route_map;
|
||||||
|
|
||||||
/* Check if handling a regular peer. */
|
/* Check if handling a regular peer. */
|
||||||
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
|
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
|
||||||
@ -6169,7 +6178,7 @@ int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
if (filter->usmap.name)
|
if (filter->usmap.name)
|
||||||
XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
|
XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
|
||||||
filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
|
filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
|
||||||
filter->usmap.map = route_map_lookup_by_name(name);
|
filter->usmap.map = route_map;
|
||||||
|
|
||||||
/* Process peer route updates. */
|
/* Process peer route updates. */
|
||||||
peer_on_policy_change(member, afi, safi, 1);
|
peer_on_policy_change(member, afi, safi, 1);
|
||||||
@ -6297,9 +6306,6 @@ int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
|
|
||||||
int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
|
int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
|
||||||
{
|
{
|
||||||
struct peer *member;
|
|
||||||
struct listnode *node, *nnode;
|
|
||||||
|
|
||||||
/* Inherit configuration from peer-group if peer is member. */
|
/* Inherit configuration from peer-group if peer is member. */
|
||||||
if (peer_group_active(peer)) {
|
if (peer_group_active(peer)) {
|
||||||
peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
|
peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
|
||||||
@ -6323,19 +6329,26 @@ int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
|
|||||||
* Remove flags and configuration from all peer-group members, unless
|
* Remove flags and configuration from all peer-group members, unless
|
||||||
* they are explicitely overriding peer-group configuration.
|
* they are explicitely overriding peer-group configuration.
|
||||||
*/
|
*/
|
||||||
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
|
||||||
/* Skip peers with overridden configuration. */
|
struct peer *member;
|
||||||
if (CHECK_FLAG(member->af_flags_override[afi][safi],
|
struct listnode *node;
|
||||||
PEER_FLAG_MAX_PREFIX))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Remove flag and configuration on peer-group member. */
|
for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
|
||||||
UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
|
/* Skip peers with overridden configuration. */
|
||||||
UNSET_FLAG(member->af_flags[afi][safi],
|
if (CHECK_FLAG(member->af_flags_override[afi][safi],
|
||||||
PEER_FLAG_MAX_PREFIX_WARNING);
|
PEER_FLAG_MAX_PREFIX))
|
||||||
member->pmax[afi][safi] = 0;
|
continue;
|
||||||
member->pmax_threshold[afi][safi] = 0;
|
|
||||||
member->pmax_restart[afi][safi] = 0;
|
/* Remove flag and configuration on peer-group member.
|
||||||
|
*/
|
||||||
|
UNSET_FLAG(member->af_flags[afi][safi],
|
||||||
|
PEER_FLAG_MAX_PREFIX);
|
||||||
|
UNSET_FLAG(member->af_flags[afi][safi],
|
||||||
|
PEER_FLAG_MAX_PREFIX_WARNING);
|
||||||
|
member->pmax[afi][safi] = 0;
|
||||||
|
member->pmax_threshold[afi][safi] = 0;
|
||||||
|
member->pmax_restart[afi][safi] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
17
bgpd/bgpd.h
17
bgpd/bgpd.h
@ -485,6 +485,11 @@ struct bgp {
|
|||||||
/* EVPN - use RFC 8365 to auto-derive RT */
|
/* EVPN - use RFC 8365 to auto-derive RT */
|
||||||
int advertise_autort_rfc8365;
|
int advertise_autort_rfc8365;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flooding mechanism for BUM packets for VxLAN-EVPN.
|
||||||
|
*/
|
||||||
|
enum vxlan_flood_control vxlan_flood_ctrl;
|
||||||
|
|
||||||
/* Hash table of Import RTs to EVIs */
|
/* Hash table of Import RTs to EVIs */
|
||||||
struct hash *import_rt_hash;
|
struct hash *import_rt_hash;
|
||||||
|
|
||||||
@ -1605,8 +1610,9 @@ extern int peer_update_source_if_set(struct peer *, const char *);
|
|||||||
extern int peer_update_source_addr_set(struct peer *, const union sockunion *);
|
extern int peer_update_source_addr_set(struct peer *, const union sockunion *);
|
||||||
extern int peer_update_source_unset(struct peer *);
|
extern int peer_update_source_unset(struct peer *);
|
||||||
|
|
||||||
extern int peer_default_originate_set(struct peer *, afi_t, safi_t,
|
extern int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
const char *);
|
const char *rmap,
|
||||||
|
struct route_map *route_map);
|
||||||
extern int peer_default_originate_unset(struct peer *, afi_t, safi_t);
|
extern int peer_default_originate_unset(struct peer *, afi_t, safi_t);
|
||||||
|
|
||||||
extern int peer_port_set(struct peer *, uint16_t);
|
extern int peer_port_set(struct peer *, uint16_t);
|
||||||
@ -1644,10 +1650,13 @@ extern int peer_prefix_list_unset(struct peer *, afi_t, safi_t, int);
|
|||||||
extern int peer_aslist_set(struct peer *, afi_t, safi_t, int, const char *);
|
extern int peer_aslist_set(struct peer *, afi_t, safi_t, int, const char *);
|
||||||
extern int peer_aslist_unset(struct peer *, afi_t, safi_t, int);
|
extern int peer_aslist_unset(struct peer *, afi_t, safi_t, int);
|
||||||
|
|
||||||
extern int peer_route_map_set(struct peer *, afi_t, safi_t, int, const char *);
|
extern int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int,
|
||||||
|
const char *name, struct route_map *route_map);
|
||||||
extern int peer_route_map_unset(struct peer *, afi_t, safi_t, int);
|
extern int peer_route_map_unset(struct peer *, afi_t, safi_t, int);
|
||||||
|
|
||||||
extern int peer_unsuppress_map_set(struct peer *, afi_t, safi_t, const char *);
|
extern int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
|
const char *name,
|
||||||
|
struct route_map *route_map);
|
||||||
|
|
||||||
extern int peer_password_set(struct peer *, const char *);
|
extern int peer_password_set(struct peer *, const char *);
|
||||||
extern int peer_password_unset(struct peer *);
|
extern int peer_password_unset(struct peer *);
|
||||||
|
@ -1601,8 +1601,10 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
|
|||||||
idx += 2; /* skip afi and keyword */
|
idx += 2; /* skip afi and keyword */
|
||||||
|
|
||||||
if (is_bgp) {
|
if (is_bgp) {
|
||||||
if (idx == argc || strmatch(argv[idx]->arg,
|
if (idx == argc
|
||||||
rfg->plist_export_bgp_name[afi])) {
|
|| (rfg->plist_export_bgp_name[afi]
|
||||||
|
&& strmatch(argv[idx]->arg,
|
||||||
|
rfg->plist_export_bgp_name[afi]))) {
|
||||||
if (rfg->plist_export_bgp_name[afi])
|
if (rfg->plist_export_bgp_name[afi])
|
||||||
free(rfg->plist_export_bgp_name[afi]);
|
free(rfg->plist_export_bgp_name[afi]);
|
||||||
rfg->plist_export_bgp_name[afi] = NULL;
|
rfg->plist_export_bgp_name[afi] = NULL;
|
||||||
@ -1612,8 +1614,9 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (idx == argc
|
if (idx == argc
|
||||||
|| strmatch(argv[idx]->arg,
|
|| (rfg->plist_export_zebra_name[afi]
|
||||||
rfg->plist_export_zebra_name[afi])) {
|
&& strmatch(argv[idx]->arg,
|
||||||
|
rfg->plist_export_zebra_name[afi]))) {
|
||||||
if (rfg->plist_export_zebra_name[afi])
|
if (rfg->plist_export_zebra_name[afi])
|
||||||
free(rfg->plist_export_zebra_name[afi]);
|
free(rfg->plist_export_zebra_name[afi]);
|
||||||
rfg->plist_export_zebra_name[afi] = NULL;
|
rfg->plist_export_zebra_name[afi] = NULL;
|
||||||
@ -1732,8 +1735,10 @@ DEFUN (vnc_nve_group_export_no_routemap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_bgp) {
|
if (is_bgp) {
|
||||||
if (idx == argc || strmatch(argv[idx]->arg,
|
if (idx == argc
|
||||||
rfg->routemap_export_bgp_name)) {
|
|| (rfg->routemap_export_bgp_name
|
||||||
|
&& strmatch(argv[idx]->arg,
|
||||||
|
rfg->routemap_export_bgp_name))) {
|
||||||
if (rfg->routemap_export_bgp_name)
|
if (rfg->routemap_export_bgp_name)
|
||||||
free(rfg->routemap_export_bgp_name);
|
free(rfg->routemap_export_bgp_name);
|
||||||
rfg->routemap_export_bgp_name = NULL;
|
rfg->routemap_export_bgp_name = NULL;
|
||||||
@ -1743,8 +1748,10 @@ DEFUN (vnc_nve_group_export_no_routemap,
|
|||||||
vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
|
vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (idx == argc || strmatch(argv[idx]->arg,
|
if (idx == argc
|
||||||
rfg->routemap_export_zebra_name)) {
|
|| (rfg->routemap_export_zebra_name
|
||||||
|
&& strmatch(argv[idx]->arg,
|
||||||
|
rfg->routemap_export_zebra_name))) {
|
||||||
if (rfg->routemap_export_zebra_name)
|
if (rfg->routemap_export_zebra_name)
|
||||||
free(rfg->routemap_export_zebra_name);
|
free(rfg->routemap_export_zebra_name);
|
||||||
rfg->routemap_export_zebra_name = NULL;
|
rfg->routemap_export_zebra_name = NULL;
|
||||||
@ -3468,7 +3475,7 @@ DEFUN (vnc_l2_group_lni,
|
|||||||
|
|
||||||
DEFUN (vnc_l2_group_labels,
|
DEFUN (vnc_l2_group_labels,
|
||||||
vnc_l2_group_labels_cmd,
|
vnc_l2_group_labels_cmd,
|
||||||
"labels LABELLIST...",
|
"labels (0-1048575)...",
|
||||||
"Specify label values associated with group\n"
|
"Specify label values associated with group\n"
|
||||||
"Space separated list of label values <0-1048575>\n")
|
"Space separated list of label values <0-1048575>\n")
|
||||||
{
|
{
|
||||||
@ -3502,7 +3509,7 @@ DEFUN (vnc_l2_group_labels,
|
|||||||
|
|
||||||
DEFUN (vnc_l2_group_no_labels,
|
DEFUN (vnc_l2_group_no_labels,
|
||||||
vnc_l2_group_no_labels_cmd,
|
vnc_l2_group_no_labels_cmd,
|
||||||
"no labels LABELLIST...",
|
"no labels (0-1048575)...",
|
||||||
NO_STR
|
NO_STR
|
||||||
"Specify label values associated with L2 group\n"
|
"Specify label values associated with L2 group\n"
|
||||||
"Space separated list of label values <0-1048575>\n")
|
"Space separated list of label values <0-1048575>\n")
|
||||||
|
@ -361,7 +361,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
{
|
{
|
||||||
afi_t afi; /* of the VN address */
|
afi_t afi; /* of the VN address */
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
char buf[PREFIX_STRLEN];
|
char buf[PREFIX_STRLEN];
|
||||||
char buf2[RD_ADDRSTRLEN];
|
char buf2[RD_ADDRSTRLEN];
|
||||||
struct prefix_rd prd0;
|
struct prefix_rd prd0;
|
||||||
@ -384,21 +384,22 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
__func__, peer, buf, prefix_rd2str(prd, buf2, sizeof(buf2)),
|
__func__, peer, buf, prefix_rd2str(prd, buf2, sizeof(buf2)),
|
||||||
afi, safi, bn, (bn ? bn->info : NULL));
|
afi, safi, bn, (bn ? bn->info : NULL));
|
||||||
|
|
||||||
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
|
for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
"%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u",
|
"%s: trying bpi=%p, bpi->peer=%p, bpi->type=%d, bpi->sub_type=%d, bpi->extra->vnc.export.rfapi_handle=%p, local_pref=%u",
|
||||||
__func__, bi, bi->peer, bi->type, bi->sub_type,
|
__func__, bpi, bpi->peer, bpi->type, bpi->sub_type,
|
||||||
(bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL),
|
(bpi->extra ? bpi->extra->vnc.export.rfapi_handle
|
||||||
((bi->attr
|
: NULL),
|
||||||
&& CHECK_FLAG(bi->attr->flag,
|
((bpi->attr
|
||||||
|
&& CHECK_FLAG(bpi->attr->flag,
|
||||||
ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
|
ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
|
||||||
? bi->attr->local_pref
|
? bpi->attr->local_pref
|
||||||
: 0));
|
: 0));
|
||||||
|
|
||||||
if (bi->peer == peer && bi->type == type
|
if (bpi->peer == peer && bpi->type == type
|
||||||
&& bi->sub_type == sub_type && bi->extra
|
&& bpi->sub_type == sub_type && bpi->extra
|
||||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||||
|
|
||||||
vnc_zlog_debug_verbose("%s: matched it", __func__);
|
vnc_zlog_debug_verbose("%s: matched it", __func__);
|
||||||
|
|
||||||
@ -412,8 +413,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
* route. Leave the route itself in place.
|
* route. Leave the route itself in place.
|
||||||
* TBD add return code reporting of success/failure
|
* TBD add return code reporting of success/failure
|
||||||
*/
|
*/
|
||||||
if (!bi || !bi->extra
|
if (!bpi || !bpi->extra
|
||||||
|| !bi->extra->vnc.export.local_nexthops) {
|
|| !bpi->extra->vnc.export.local_nexthops) {
|
||||||
/*
|
/*
|
||||||
* no local nexthops
|
* no local nexthops
|
||||||
*/
|
*/
|
||||||
@ -429,7 +430,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct rfapi_nexthop *pLnh = NULL;
|
struct rfapi_nexthop *pLnh = NULL;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(bi->extra->vnc.export.local_nexthops,
|
for (ALL_LIST_ELEMENTS_RO(bpi->extra->vnc.export.local_nexthops,
|
||||||
node, pLnh)) {
|
node, pLnh)) {
|
||||||
|
|
||||||
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
||||||
@ -438,7 +439,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pLnh) {
|
if (pLnh) {
|
||||||
listnode_delete(bi->extra->vnc.export.local_nexthops,
|
listnode_delete(bpi->extra->vnc.export.local_nexthops,
|
||||||
pLnh);
|
pLnh);
|
||||||
|
|
||||||
/* silly rabbit, listnode_delete doesn't invoke
|
/* silly rabbit, listnode_delete doesn't invoke
|
||||||
@ -458,7 +459,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
*/
|
*/
|
||||||
rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill);
|
rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill);
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
prefix2str(p, buf, sizeof(buf));
|
prefix2str(p, buf, sizeof(buf));
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
"%s: Found route (safi=%d) to delete at prefix %s",
|
"%s: Found route (safi=%d) to delete at prefix %s",
|
||||||
@ -474,7 +475,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
table = (struct bgp_table *)(prn->info);
|
table = (struct bgp_table *)(prn->info);
|
||||||
|
|
||||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||||
bgp, prd, table, p, bi);
|
bgp, prd, table, p, bpi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(prn);
|
bgp_unlock_node(prn);
|
||||||
}
|
}
|
||||||
@ -482,13 +483,11 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
|
|||||||
/*
|
/*
|
||||||
* Delete local_nexthops list
|
* Delete local_nexthops list
|
||||||
*/
|
*/
|
||||||
if (bi->extra && bi->extra->vnc.export.local_nexthops) {
|
if (bpi->extra && bpi->extra->vnc.export.local_nexthops)
|
||||||
list_delete(
|
list_delete(&bpi->extra->vnc.export.local_nexthops);
|
||||||
&bi->extra->vnc.export.local_nexthops);
|
|
||||||
}
|
|
||||||
|
|
||||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||||
bgp_info_delete(bn, bi);
|
bgp_path_info_delete(bn, bpi);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
} else {
|
} else {
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
@ -575,8 +574,8 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
afi_t afi; /* of the VN address */
|
afi_t afi; /* of the VN address */
|
||||||
struct bgp_info *new;
|
struct bgp_path_info *new;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
|
|
||||||
struct attr attr = {0};
|
struct attr attr = {0};
|
||||||
@ -946,29 +945,29 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
* ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr
|
* ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr
|
||||||
* aspath: POINTS TO interned/refcounted hashed block
|
* aspath: POINTS TO interned/refcounted hashed block
|
||||||
*/
|
*/
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
/* probably only need to check
|
/* probably only need to check
|
||||||
* bi->extra->vnc.export.rfapi_handle */
|
* bpi->extra->vnc.export.rfapi_handle */
|
||||||
if (bi->peer == rfd->peer && bi->type == type
|
if (bpi->peer == rfd->peer && bpi->type == type
|
||||||
&& bi->sub_type == sub_type && bi->extra
|
&& bpi->sub_type == sub_type && bpi->extra
|
||||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi) {
|
if (bpi) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adding new local_nexthop, which does not by itself change
|
* Adding new local_nexthop, which does not by itself change
|
||||||
* what is advertised via BGP
|
* what is advertised via BGP
|
||||||
*/
|
*/
|
||||||
if (lnh) {
|
if (lnh) {
|
||||||
if (!bi->extra->vnc.export.local_nexthops) {
|
if (!bpi->extra->vnc.export.local_nexthops) {
|
||||||
/* TBD make arrangements to free when needed */
|
/* TBD make arrangements to free when needed */
|
||||||
bi->extra->vnc.export.local_nexthops =
|
bpi->extra->vnc.export.local_nexthops =
|
||||||
list_new();
|
list_new();
|
||||||
bi->extra->vnc.export.local_nexthops->del =
|
bpi->extra->vnc.export.local_nexthops->del =
|
||||||
rfapi_nexthop_free;
|
rfapi_nexthop_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,8 +978,8 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
struct rfapi_nexthop *pLnh = NULL;
|
struct rfapi_nexthop *pLnh = NULL;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(
|
for (ALL_LIST_ELEMENTS_RO(
|
||||||
bi->extra->vnc.export.local_nexthops, node,
|
bpi->extra->vnc.export.local_nexthops,
|
||||||
pLnh)) {
|
node, pLnh)) {
|
||||||
|
|
||||||
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
if (prefix_same(&pLnh->addr, &lnh->addr)) {
|
||||||
break;
|
break;
|
||||||
@ -993,13 +992,13 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
if (!pLnh) {
|
if (!pLnh) {
|
||||||
pLnh = rfapi_nexthop_new(lnh);
|
pLnh = rfapi_nexthop_new(lnh);
|
||||||
listnode_add(
|
listnode_add(
|
||||||
bi->extra->vnc.export.local_nexthops,
|
bpi->extra->vnc.export.local_nexthops,
|
||||||
pLnh);
|
pLnh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrhash_cmp(bi->attr, new_attr)
|
if (attrhash_cmp(bpi->attr, new_attr)
|
||||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||||
bgp_attr_unintern(&new_attr);
|
bgp_attr_unintern(&new_attr);
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
|
|
||||||
@ -1010,7 +1009,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
/* The attribute is changed. */
|
/* The attribute is changed. */
|
||||||
bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
|
bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
|
||||||
|
|
||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
struct bgp_node *prn = NULL;
|
struct bgp_node *prn = NULL;
|
||||||
@ -1022,19 +1021,19 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
table = (struct bgp_table *)(prn->info);
|
table = (struct bgp_table *)(prn->info);
|
||||||
|
|
||||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||||
bgp, prd, table, p, bi);
|
bgp, prd, table, p, bpi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(prn);
|
bgp_unlock_node(prn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rewrite BGP route information. */
|
/* Rewrite BGP route information. */
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||||
bgp_info_restore(bn, bi);
|
bgp_path_info_restore(bn, bpi);
|
||||||
else
|
else
|
||||||
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
|
bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
|
||||||
bgp_attr_unintern(&bi->attr);
|
bgp_attr_unintern(&bpi->attr);
|
||||||
bi->attr = new_attr;
|
bpi->attr = new_attr;
|
||||||
bi->uptime = bgp_clock();
|
bpi->uptime = bgp_clock();
|
||||||
|
|
||||||
|
|
||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
@ -1047,13 +1046,13 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
table = (struct bgp_table *)(prn->info);
|
table = (struct bgp_table *)(prn->info);
|
||||||
|
|
||||||
vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
||||||
bgp, prd, table, p, bi);
|
bgp, prd, table, p, bpi);
|
||||||
}
|
}
|
||||||
bgp_unlock_node(prn);
|
bgp_unlock_node(prn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process change. */
|
/* Process change. */
|
||||||
bgp_aggregate_increment(bgp, p, bi, afi, safi);
|
bgp_aggregate_increment(bgp, p, bpi, afi, safi);
|
||||||
bgp_process(bgp, bn, afi, safi);
|
bgp_process(bgp, bn, afi, safi);
|
||||||
bgp_unlock_node(bn);
|
bgp_unlock_node(bn);
|
||||||
|
|
||||||
@ -1066,16 +1065,16 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
new = bgp_info_new();
|
new = bgp_path_info_new();
|
||||||
new->type = type;
|
new->type = type;
|
||||||
new->sub_type = sub_type;
|
new->sub_type = sub_type;
|
||||||
new->peer = rfd->peer;
|
new->peer = rfd->peer;
|
||||||
SET_FLAG(new->flags, BGP_INFO_VALID);
|
SET_FLAG(new->flags, BGP_PATH_VALID);
|
||||||
new->attr = new_attr;
|
new->attr = new_attr;
|
||||||
new->uptime = bgp_clock();
|
new->uptime = bgp_clock();
|
||||||
|
|
||||||
/* save backref to rfapi handle */
|
/* save backref to rfapi handle */
|
||||||
assert(bgp_info_extra_get(new));
|
assert(bgp_path_info_extra_get(new));
|
||||||
new->extra->vnc.export.rfapi_handle = (void *)rfd;
|
new->extra->vnc.export.rfapi_handle = (void *)rfd;
|
||||||
encode_label(label_val, &new->extra->label[0]);
|
encode_label(label_val, &new->extra->label[0]);
|
||||||
|
|
||||||
@ -1087,7 +1086,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
|
|||||||
}
|
}
|
||||||
|
|
||||||
bgp_aggregate_increment(bgp, p, new, afi, safi);
|
bgp_aggregate_increment(bgp, p, new, afi, safi);
|
||||||
bgp_info_add(bn, new);
|
bgp_path_info_add(bn, new);
|
||||||
|
|
||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
struct bgp_node *prn = NULL;
|
struct bgp_node *prn = NULL;
|
||||||
@ -3690,7 +3689,7 @@ static void rfapi_print_exported(struct bgp *bgp)
|
|||||||
{
|
{
|
||||||
struct bgp_node *rdn;
|
struct bgp_node *rdn;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
if (!bgp)
|
if (!bgp)
|
||||||
return;
|
return;
|
||||||
@ -3705,8 +3704,8 @@ static void rfapi_print_exported(struct bgp *bgp)
|
|||||||
if (!rn->info)
|
if (!rn->info)
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
rfapiPrintBi((void *)2, bi); /* 2 => stderr */
|
rfapiPrintBi((void *)2, bpi); /* 2 => stderr */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3720,8 +3719,8 @@ static void rfapi_print_exported(struct bgp *bgp)
|
|||||||
if (!rn->info)
|
if (!rn->info)
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
fprintf(stderr, "%s: rn=%p\n", __func__, rn);
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
rfapiPrintBi((void *)2, bi); /* 2 => stderr */
|
rfapiPrintBi((void *)2, bpi); /* 2 => stderr */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,16 @@ extern void rfapiProcessWithdraw(struct peer *peer, void *rfd, struct prefix *p,
|
|||||||
|
|
||||||
extern void rfapiProcessPeerDown(struct peer *peer);
|
extern void rfapiProcessPeerDown(struct peer *peer);
|
||||||
|
|
||||||
extern void vnc_zebra_announce(struct prefix *p, struct bgp_info *new_select,
|
extern void vnc_zebra_announce(struct prefix *p,
|
||||||
|
struct bgp_path_info *new_select,
|
||||||
struct bgp *bgp);
|
struct bgp *bgp);
|
||||||
|
|
||||||
extern void vnc_zebra_withdraw(struct prefix *p, struct bgp_info *old_select);
|
extern void vnc_zebra_withdraw(struct prefix *p,
|
||||||
|
struct bgp_path_info *old_select);
|
||||||
|
|
||||||
|
|
||||||
extern void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
extern void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *bi, safi_t safi);
|
struct bgp_path_info *bpi, safi_t safi);
|
||||||
|
|
||||||
|
|
||||||
extern void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi);
|
extern void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,7 @@
|
|||||||
/*
|
/*
|
||||||
* These are per-rt-import-list
|
* These are per-rt-import-list
|
||||||
*
|
*
|
||||||
* routes are not segregated by RD - the RD is stored in bgp_info_extra
|
* routes are not segregated by RD - the RD is stored in bgp_path_info_extra
|
||||||
* and is needed to determine if two prefixes are the same.
|
* and is needed to determine if two prefixes are the same.
|
||||||
*/
|
*/
|
||||||
struct rfapi_import_table {
|
struct rfapi_import_table {
|
||||||
@ -51,18 +51,18 @@ struct rfapi_import_table {
|
|||||||
int imported_count[AFI_MAX];
|
int imported_count[AFI_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RFAPI_LOCAL_BI(bi) \
|
#define RFAPI_LOCAL_BI(bpi) \
|
||||||
(((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP))
|
(((bpi)->type == ZEBRA_ROUTE_BGP) && ((bpi)->sub_type == BGP_ROUTE_RFP))
|
||||||
|
|
||||||
#define RFAPI_DIRECT_IMPORT_BI(bi) \
|
#define RFAPI_DIRECT_IMPORT_BI(bpi) \
|
||||||
(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) \
|
(((bpi)->type == ZEBRA_ROUTE_BGP_DIRECT) \
|
||||||
|| ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
|
|| ((bpi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
|
||||||
|
|
||||||
#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \
|
#define RFAPI_UPDATE_ITABLE_COUNT(bpi, itable, afi, cnt) \
|
||||||
if (RFAPI_LOCAL_BI(bi)) { \
|
if (RFAPI_LOCAL_BI(bpi)) { \
|
||||||
(itable)->local_count[(afi)] += (cnt); \
|
(itable)->local_count[(afi)] += (cnt); \
|
||||||
} else { \
|
} else { \
|
||||||
if (RFAPI_DIRECT_IMPORT_BI(bi)) \
|
if (RFAPI_DIRECT_IMPORT_BI(bpi)) \
|
||||||
(itable)->imported_count[(afi)] += (cnt); \
|
(itable)->imported_count[(afi)] += (cnt); \
|
||||||
else \
|
else \
|
||||||
(itable)->remote_count[(afi)] += (cnt); \
|
(itable)->remote_count[(afi)] += (cnt); \
|
||||||
@ -75,9 +75,9 @@ extern void rfapiDebugBacktrace(void);
|
|||||||
extern void rfapiCheckRouteCount(void);
|
extern void rfapiCheckRouteCount(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print BI in an Import Table
|
* Print BPI in an Import Table
|
||||||
*/
|
*/
|
||||||
extern void rfapiPrintBi(void *stream, struct bgp_info *bi);
|
extern void rfapiPrintBi(void *stream, struct bgp_path_info *bpi);
|
||||||
|
|
||||||
extern void rfapiShowImportTable(void *stream, const char *label,
|
extern void rfapiShowImportTable(void *stream, const char *label,
|
||||||
struct agg_table *rt, int isvpn);
|
struct agg_table *rt, int isvpn);
|
||||||
@ -94,7 +94,7 @@ extern void rfapiImportTableRefDelByIt(struct bgp *bgp,
|
|||||||
* Construct an rfapi nexthop list based on the routes attached to
|
* Construct an rfapi nexthop list based on the routes attached to
|
||||||
* the specified node.
|
* the specified node.
|
||||||
*
|
*
|
||||||
* If there are any routes that do NOT have BGP_INFO_REMOVED set,
|
* If there are any routes that do NOT have BGP_PATH_REMOVED set,
|
||||||
* return those only. If there are ONLY routes with BGP_INFO_REMOVED,
|
* return those only. If there are ONLY routes with BGP_INFO_REMOVED,
|
||||||
* then return those, and also include all the non-removed routes from the
|
* then return those, and also include all the non-removed routes from the
|
||||||
* next less-specific node (i.e., this node's parent) at the end.
|
* next less-specific node (i.e., this node's parent) at the end.
|
||||||
@ -128,7 +128,7 @@ extern int rfapiHasNonRemovedRoutes(struct agg_node *rn);
|
|||||||
|
|
||||||
extern int rfapiProcessDeferredClose(struct thread *t);
|
extern int rfapiProcessDeferredClose(struct thread *t);
|
||||||
|
|
||||||
extern int rfapiGetUnAddrOfVpnBi(struct bgp_info *bi, struct prefix *p);
|
extern int rfapiGetUnAddrOfVpnBi(struct bgp_path_info *bpi, struct prefix *p);
|
||||||
|
|
||||||
extern void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p);
|
extern void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p);
|
||||||
|
|
||||||
@ -146,10 +146,10 @@ extern void rfapiBgpInfoFilteredImportVPN(
|
|||||||
struct prefix *p,
|
struct prefix *p,
|
||||||
struct prefix *aux_prefix, /* AFI_ETHER: optional IP */
|
struct prefix *aux_prefix, /* AFI_ETHER: optional IP */
|
||||||
afi_t afi, struct prefix_rd *prd,
|
afi_t afi, struct prefix_rd *prd,
|
||||||
struct attr *attr, /* part of bgp_info */
|
struct attr *attr, /* part of bgp_path_info */
|
||||||
uint8_t type, /* part of bgp_info */
|
uint8_t type, /* part of bgp_path_info */
|
||||||
uint8_t sub_type, /* part of bgp_info */
|
uint8_t sub_type, /* part of bgp_path_info */
|
||||||
uint32_t *label); /* part of bgp_info */
|
uint32_t *label); /* part of bgp_path_info */
|
||||||
|
|
||||||
extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
|
extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
|
||||||
struct agg_node *rn, struct rfapi_ip_prefix *rprefix,
|
struct agg_node *rn, struct rfapi_ip_prefix *rprefix,
|
||||||
|
@ -226,7 +226,7 @@ void rfapiMonitorExtraFlush(safi_t safi, struct agg_node *rn)
|
|||||||
agg_unlock_node(rn);
|
agg_unlock_node(rn);
|
||||||
}
|
}
|
||||||
if (hie->u.vpn.idx_rd) {
|
if (hie->u.vpn.idx_rd) {
|
||||||
/* looping through bi->extra->vnc.import.rd is tbd */
|
/* looping through bpi->extra->vnc.import.rd is tbd */
|
||||||
while (!skiplist_delete_first(hie->u.vpn.idx_rd)) {
|
while (!skiplist_delete_first(hie->u.vpn.idx_rd)) {
|
||||||
agg_unlock_node(rn);
|
agg_unlock_node(rn);
|
||||||
}
|
}
|
||||||
@ -346,16 +346,16 @@ struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
|
|||||||
for (rn = agg_node_match(rfd->import_table->imported_vpn[afi], p);
|
for (rn = agg_node_match(rfd->import_table->imported_vpn[afi], p);
|
||||||
rn;) {
|
rn;) {
|
||||||
|
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct prefix pfx_dummy;
|
struct prefix pfx_dummy;
|
||||||
|
|
||||||
/* TBD update this code to use new valid_interior_count */
|
/* TBD update this code to use new valid_interior_count */
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
/*
|
/*
|
||||||
* If there is a cached ENCAP UN address, it's a usable
|
* If there is a cached ENCAP UN address, it's a usable
|
||||||
* VPN route
|
* VPN route
|
||||||
*/
|
*/
|
||||||
if (bi->extra && bi->extra->vnc.import.un_family) {
|
if (bpi->extra && bpi->extra->vnc.import.un_family) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,11 +364,11 @@ struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
|
|||||||
* address,
|
* address,
|
||||||
* it's a usable VPN route.
|
* it's a usable VPN route.
|
||||||
*/
|
*/
|
||||||
if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_dummy)) {
|
if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_dummy)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bi)
|
if (bpi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
agg_unlock_node(rn);
|
agg_unlock_node(rn);
|
||||||
|
@ -45,7 +45,7 @@ struct rfapi_monitor_encap {
|
|||||||
struct rfapi_monitor_encap *next;
|
struct rfapi_monitor_encap *next;
|
||||||
struct rfapi_monitor_encap *prev;
|
struct rfapi_monitor_encap *prev;
|
||||||
struct agg_node *node; /* VPN node */
|
struct agg_node *node; /* VPN node */
|
||||||
struct bgp_info *bi; /* VPN bi */
|
struct bgp_path_info *bpi; /* VPN bpi */
|
||||||
struct agg_node *rn; /* parent node */
|
struct agg_node *rn; /* parent node */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ struct rfapi_it_extra {
|
|||||||
* Encap TLV */
|
* Encap TLV */
|
||||||
int valid_interior_count;
|
int valid_interior_count;
|
||||||
|
|
||||||
/* unicast exterior routes, key=bi,
|
/* unicast exterior routes, key=bpi,
|
||||||
* val=allocated prefix */
|
* val=allocated prefix */
|
||||||
struct skiplist *source;
|
struct skiplist *source;
|
||||||
} e;
|
} e;
|
||||||
|
@ -212,7 +212,7 @@ struct rfapi {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* when importing bgp-direct routes in resolve-nve mode,
|
* when importing bgp-direct routes in resolve-nve mode,
|
||||||
* this list maps unicast route nexthops to their bgp_infos
|
* this list maps unicast route nexthops to their bgp_path_infos
|
||||||
* in the unicast table
|
* in the unicast table
|
||||||
*/
|
*/
|
||||||
struct skiplist *resolve_nve_nexthop;
|
struct skiplist *resolve_nve_nexthop;
|
||||||
|
@ -616,18 +616,18 @@ void rfapiRibFree(struct rfapi_descriptor *rfd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copies struct bgp_info to struct rfapi_info, except for rk fields and un
|
* Copies struct bgp_path_info to struct rfapi_info, except for rk fields and un
|
||||||
*/
|
*/
|
||||||
static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
static void rfapiRibBi2Ri(struct bgp_path_info *bpi, struct rfapi_info *ri,
|
||||||
uint32_t lifetime)
|
uint32_t lifetime)
|
||||||
{
|
{
|
||||||
struct bgp_attr_encap_subtlv *pEncap;
|
struct bgp_attr_encap_subtlv *pEncap;
|
||||||
|
|
||||||
ri->cost = rfapiRfpCost(bi->attr);
|
ri->cost = rfapiRfpCost(bpi->attr);
|
||||||
ri->lifetime = lifetime;
|
ri->lifetime = lifetime;
|
||||||
|
|
||||||
/* This loop based on rfapiRouteInfo2NextHopEntry() */
|
/* This loop based on rfapiRouteInfo2NextHopEntry() */
|
||||||
for (pEncap = bi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) {
|
for (pEncap = bpi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) {
|
||||||
struct bgp_tea_options *hop;
|
struct bgp_tea_options *hop;
|
||||||
|
|
||||||
switch (pEncap->type) {
|
switch (pEncap->type) {
|
||||||
@ -665,13 +665,13 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rfapi_un_options_free(ri->un_options); /* maybe free old version */
|
rfapi_un_options_free(ri->un_options); /* maybe free old version */
|
||||||
ri->un_options = rfapi_encap_tlv_to_un_option(bi->attr);
|
ri->un_options = rfapi_encap_tlv_to_un_option(bpi->attr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VN options
|
* VN options
|
||||||
*/
|
*/
|
||||||
if (bi->extra
|
if (bpi->extra
|
||||||
&& decode_rd_type(bi->extra->vnc.import.rd.val)
|
&& decode_rd_type(bpi->extra->vnc.import.rd.val)
|
||||||
== RD_TYPE_VNC_ETH) {
|
== RD_TYPE_VNC_ETH) {
|
||||||
/* ethernet route */
|
/* ethernet route */
|
||||||
|
|
||||||
@ -683,21 +683,21 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
|||||||
|
|
||||||
vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
|
vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
|
||||||
|
|
||||||
/* copy from RD already stored in bi, so we don't need it_node
|
/* copy from RD already stored in bpi, so we don't need it_node
|
||||||
*/
|
*/
|
||||||
memcpy(&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val + 2,
|
memcpy(&vo->v.l2addr.macaddr, bpi->extra->vnc.import.rd.val + 2,
|
||||||
ETH_ALEN);
|
ETH_ALEN);
|
||||||
|
|
||||||
(void)rfapiEcommunityGetLNI(bi->attr->ecommunity,
|
(void)rfapiEcommunityGetLNI(bpi->attr->ecommunity,
|
||||||
&vo->v.l2addr.logical_net_id);
|
&vo->v.l2addr.logical_net_id);
|
||||||
(void)rfapiEcommunityGetEthernetTag(bi->attr->ecommunity,
|
(void)rfapiEcommunityGetEthernetTag(bpi->attr->ecommunity,
|
||||||
&vo->v.l2addr.tag_id);
|
&vo->v.l2addr.tag_id);
|
||||||
|
|
||||||
/* local_nve_id comes from RD */
|
/* local_nve_id comes from RD */
|
||||||
vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1];
|
vo->v.l2addr.local_nve_id = bpi->extra->vnc.import.rd.val[1];
|
||||||
|
|
||||||
/* label comes from MP_REACH_NLRI label */
|
/* label comes from MP_REACH_NLRI label */
|
||||||
vo->v.l2addr.label = decode_label(&bi->extra->label[0]);
|
vo->v.l2addr.label = decode_label(&bpi->extra->label[0]);
|
||||||
|
|
||||||
rfapi_vn_options_free(
|
rfapi_vn_options_free(
|
||||||
ri->vn_options); /* maybe free old version */
|
ri->vn_options); /* maybe free old version */
|
||||||
@ -707,8 +707,8 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
|||||||
/*
|
/*
|
||||||
* If there is an auxiliary IP address (L2 can have it), copy it
|
* If there is an auxiliary IP address (L2 can have it), copy it
|
||||||
*/
|
*/
|
||||||
if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
ri->rk.aux_prefix = bpi->extra->vnc.import.aux_prefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,7 +733,7 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
|
|||||||
int rfapiRibPreloadBi(
|
int rfapiRibPreloadBi(
|
||||||
struct agg_node *rfd_rib_node, /* NULL = don't preload or filter */
|
struct agg_node *rfd_rib_node, /* NULL = don't preload or filter */
|
||||||
struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime,
|
struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime,
|
||||||
struct bgp_info *bi)
|
struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
struct rfapi_descriptor *rfd;
|
struct rfapi_descriptor *rfd;
|
||||||
struct skiplist *slRibPt = NULL;
|
struct skiplist *slRibPt = NULL;
|
||||||
@ -751,13 +751,13 @@ int rfapiRibPreloadBi(
|
|||||||
|
|
||||||
memset((void *)&rk, 0, sizeof(rk));
|
memset((void *)&rk, 0, sizeof(rk));
|
||||||
rk.vn = *pfx_vn;
|
rk.vn = *pfx_vn;
|
||||||
rk.rd = bi->extra->vnc.import.rd;
|
rk.rd = bpi->extra->vnc.import.rd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is an auxiliary IP address (L2 can have it), copy it
|
* If there is an auxiliary IP address (L2 can have it), copy it
|
||||||
*/
|
*/
|
||||||
if (bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
rk.aux_prefix = bpi->extra->vnc.import.aux_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -774,13 +774,13 @@ int rfapiRibPreloadBi(
|
|||||||
|
|
||||||
/* found: update contents of existing route in RIB */
|
/* found: update contents of existing route in RIB */
|
||||||
ori->un = *pfx_un;
|
ori->un = *pfx_un;
|
||||||
rfapiRibBi2Ri(bi, ori, lifetime);
|
rfapiRibBi2Ri(bpi, ori, lifetime);
|
||||||
} else {
|
} else {
|
||||||
/* not found: add new route to RIB */
|
/* not found: add new route to RIB */
|
||||||
ori = rfapi_info_new();
|
ori = rfapi_info_new();
|
||||||
ori->rk = rk;
|
ori->rk = rk;
|
||||||
ori->un = *pfx_un;
|
ori->un = *pfx_un;
|
||||||
rfapiRibBi2Ri(bi, ori, lifetime);
|
rfapiRibBi2Ri(bpi, ori, lifetime);
|
||||||
|
|
||||||
if (!slRibPt) {
|
if (!slRibPt) {
|
||||||
slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL);
|
slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL);
|
||||||
@ -1590,7 +1590,7 @@ void rfapiRibUpdatePendingNode(
|
|||||||
struct agg_node *it_node, uint32_t lifetime)
|
struct agg_node *it_node, uint32_t lifetime)
|
||||||
{
|
{
|
||||||
struct prefix *prefix;
|
struct prefix *prefix;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
struct agg_node *pn;
|
struct agg_node *pn;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
uint32_t queued_flag;
|
uint32_t queued_flag;
|
||||||
@ -1640,25 +1640,25 @@ void rfapiRibUpdatePendingNode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The BIs in the import table are already sorted by cost
|
* The BPIs in the import table are already sorted by cost
|
||||||
*/
|
*/
|
||||||
for (bi = it_node->info; bi; bi = bi->next) {
|
for (bpi = it_node->info; bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
struct rfapi_info *ri;
|
struct rfapi_info *ri;
|
||||||
struct prefix pfx_nh;
|
struct prefix pfx_nh;
|
||||||
|
|
||||||
if (!bi->attr) {
|
if (!bpi->attr) {
|
||||||
/* shouldn't happen */
|
/* shouldn't happen */
|
||||||
/* TBD increment error stats counter */
|
/* TBD increment error stats counter */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!bi->extra) {
|
if (!bpi->extra) {
|
||||||
/* shouldn't happen */
|
/* shouldn't happen */
|
||||||
/* TBD increment error stats counter */
|
/* TBD increment error stats counter */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rfapiNexthop2Prefix(bi->attr, &pfx_nh);
|
rfapiNexthop2Prefix(bpi->attr, &pfx_nh);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Omit route if nexthop is self
|
* Omit route if nexthop is self
|
||||||
@ -1675,15 +1675,15 @@ void rfapiRibUpdatePendingNode(
|
|||||||
|
|
||||||
ri = rfapi_info_new();
|
ri = rfapi_info_new();
|
||||||
ri->rk.vn = pfx_nh;
|
ri->rk.vn = pfx_nh;
|
||||||
ri->rk.rd = bi->extra->vnc.import.rd;
|
ri->rk.rd = bpi->extra->vnc.import.rd;
|
||||||
/*
|
/*
|
||||||
* If there is an auxiliary IP address (L2 can have it), copy it
|
* If there is an auxiliary IP address (L2 can have it), copy it
|
||||||
*/
|
*/
|
||||||
if (bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix;
|
ri->rk.aux_prefix = bpi->extra->vnc.import.aux_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rfapiGetUnAddrOfVpnBi(bi, &ri->un)) {
|
if (rfapiGetUnAddrOfVpnBi(bpi, &ri->un)) {
|
||||||
rfapi_info_free(ri);
|
rfapi_info_free(ri);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1711,7 +1711,7 @@ void rfapiRibUpdatePendingNode(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rfapiRibBi2Ri(bi, ri, lifetime);
|
rfapiRibBi2Ri(bpi, ri, lifetime);
|
||||||
|
|
||||||
if (!pn->info) {
|
if (!pn->info) {
|
||||||
pn->info = list_new();
|
pn->info = list_new();
|
||||||
|
@ -105,7 +105,7 @@ extern void rfapiRibUpdatePendingNodeSubtree(struct bgp *bgp,
|
|||||||
|
|
||||||
extern int rfapiRibPreloadBi(struct agg_node *rfd_rib_node,
|
extern int rfapiRibPreloadBi(struct agg_node *rfd_rib_node,
|
||||||
struct prefix *pfx_vn, struct prefix *pfx_un,
|
struct prefix *pfx_vn, struct prefix *pfx_un,
|
||||||
uint32_t lifetime, struct bgp_info *bi);
|
uint32_t lifetime, struct bgp_path_info *bpi);
|
||||||
|
|
||||||
extern struct rfapi_next_hop_entry *
|
extern struct rfapi_next_hop_entry *
|
||||||
rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
|
rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
|
||||||
|
@ -394,7 +394,7 @@ int rfapiStream2Vty(void *stream, /* input */
|
|||||||
|
|
||||||
/* called from bgpd/bgp_vty.c'route_vty_out() */
|
/* called from bgpd/bgp_vty.c'route_vty_out() */
|
||||||
void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
||||||
struct bgp_info *bi, safi_t safi)
|
struct bgp_path_info *bpi, safi_t safi)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
uint32_t lifetime;
|
uint32_t lifetime;
|
||||||
@ -410,7 +410,7 @@ void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
|||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
struct prefix pfx_un;
|
struct prefix pfx_un;
|
||||||
|
|
||||||
if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) {
|
if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) {
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
vty_out(vty, "UN=%s",
|
vty_out(vty, "UN=%s",
|
||||||
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
||||||
@ -418,27 +418,27 @@ void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->attr && bi->attr->ecommunity) {
|
if (bpi->attr && bpi->attr->ecommunity) {
|
||||||
s = ecommunity_ecom2str(bi->attr->ecommunity,
|
s = ecommunity_ecom2str(bpi->attr->ecommunity,
|
||||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
vty_out(vty, " EC{%s}", s);
|
vty_out(vty, " EC{%s}", s);
|
||||||
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
XFREE(MTYPE_ECOMMUNITY_STR, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->extra != NULL) {
|
if (bpi->extra != NULL) {
|
||||||
if (bi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
|
if (bpi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
|
||||||
vty_out(vty, " label=VRF2VRF");
|
vty_out(vty, " label=VRF2VRF");
|
||||||
else
|
else
|
||||||
vty_out(vty, " label=%u",
|
vty_out(vty, " label=%u",
|
||||||
decode_label(&bi->extra->label[0]));
|
decode_label(&bpi->extra->label[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rfapiGetVncLifetime(bi->attr, &lifetime)) {
|
if (!rfapiGetVncLifetime(bpi->attr, &lifetime)) {
|
||||||
vty_out(vty, " life=%d", lifetime);
|
vty_out(vty, " life=%d", lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
vty_out(vty, " type=%s, subtype=%d", zebra_route_string(bi->type),
|
vty_out(vty, " type=%s, subtype=%d", zebra_route_string(bpi->type),
|
||||||
bi->sub_type);
|
bpi->sub_type);
|
||||||
|
|
||||||
vty_out(vty, "%s", HVTYNL);
|
vty_out(vty, "%s", HVTYNL);
|
||||||
}
|
}
|
||||||
@ -477,9 +477,9 @@ void rfapiPrintAttrPtrs(void *stream, struct attr *attr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print BI in an Import Table
|
* Print BPI in an Import Table
|
||||||
*/
|
*/
|
||||||
void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
void rfapiPrintBi(void *stream, struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
char *s;
|
char *s;
|
||||||
@ -503,12 +503,13 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bi)
|
if (!bpi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
|
||||||
&& bi->extra->vnc.import.timer) {
|
&& bpi->extra->vnc.import.timer) {
|
||||||
struct thread *t = (struct thread *)bi->extra->vnc.import.timer;
|
struct thread *t =
|
||||||
|
(struct thread *)bpi->extra->vnc.import.timer;
|
||||||
r = snprintf(p, REMAIN, " [%4lu] ",
|
r = snprintf(p, REMAIN, " [%4lu] ",
|
||||||
thread_timer_remain_second(t));
|
thread_timer_remain_second(t));
|
||||||
INCP;
|
INCP;
|
||||||
@ -518,14 +519,14 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
INCP;
|
INCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->extra) {
|
if (bpi->extra) {
|
||||||
/* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
|
/* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
|
||||||
if (decode_rd_type(bi->extra->vnc.import.rd.val)
|
if (decode_rd_type(bpi->extra->vnc.import.rd.val)
|
||||||
== RD_TYPE_VNC_ETH) {
|
== RD_TYPE_VNC_ETH) {
|
||||||
has_macaddr = 1;
|
has_macaddr = 1;
|
||||||
memcpy(macaddr.octet, bi->extra->vnc.import.rd.val + 2,
|
memcpy(macaddr.octet, bpi->extra->vnc.import.rd.val + 2,
|
||||||
6);
|
6);
|
||||||
l2hid = bi->extra->vnc.import.rd.val[1];
|
l2hid = bpi->extra->vnc.import.rd.val[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,24 +538,24 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
* RFP option sizes (they are opaque values)
|
* RFP option sizes (they are opaque values)
|
||||||
* extended communities (RTs)
|
* extended communities (RTs)
|
||||||
*/
|
*/
|
||||||
if (bi->attr) {
|
if (bpi->attr) {
|
||||||
uint32_t lifetime;
|
uint32_t lifetime;
|
||||||
int printed_1st_gol = 0;
|
int printed_1st_gol = 0;
|
||||||
struct bgp_attr_encap_subtlv *pEncap;
|
struct bgp_attr_encap_subtlv *pEncap;
|
||||||
struct prefix pfx_un;
|
struct prefix pfx_un;
|
||||||
int af = BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len);
|
int af = BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len);
|
||||||
|
|
||||||
/* Nexthop */
|
/* Nexthop */
|
||||||
if (af == AF_INET) {
|
if (af == AF_INET) {
|
||||||
r = snprintf(p, REMAIN, "%s",
|
r = snprintf(p, REMAIN, "%s",
|
||||||
inet_ntop(AF_INET,
|
inet_ntop(AF_INET,
|
||||||
&bi->attr->mp_nexthop_global_in,
|
&bpi->attr->mp_nexthop_global_in,
|
||||||
buf, BUFSIZ));
|
buf, BUFSIZ));
|
||||||
INCP;
|
INCP;
|
||||||
} else if (af == AF_INET6) {
|
} else if (af == AF_INET6) {
|
||||||
r = snprintf(p, REMAIN, "%s",
|
r = snprintf(p, REMAIN, "%s",
|
||||||
inet_ntop(AF_INET6,
|
inet_ntop(AF_INET6,
|
||||||
&bi->attr->mp_nexthop_global,
|
&bpi->attr->mp_nexthop_global,
|
||||||
buf, BUFSIZ));
|
buf, BUFSIZ));
|
||||||
INCP;
|
INCP;
|
||||||
} else {
|
} else {
|
||||||
@ -565,7 +566,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
/*
|
/*
|
||||||
* VNC tunnel subtlv, if present, contains UN address
|
* VNC tunnel subtlv, if present, contains UN address
|
||||||
*/
|
*/
|
||||||
if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) {
|
if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) {
|
||||||
r = snprintf(p, REMAIN, " un=%s",
|
r = snprintf(p, REMAIN, " un=%s",
|
||||||
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
inet_ntop(pfx_un.family, pfx_un.u.val, buf,
|
||||||
BUFSIZ));
|
BUFSIZ));
|
||||||
@ -573,7 +574,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Lifetime */
|
/* Lifetime */
|
||||||
if (rfapiGetVncLifetime(bi->attr, &lifetime)) {
|
if (rfapiGetVncLifetime(bpi->attr, &lifetime)) {
|
||||||
r = snprintf(p, REMAIN, " nolife");
|
r = snprintf(p, REMAIN, " nolife");
|
||||||
INCP;
|
INCP;
|
||||||
} else {
|
} else {
|
||||||
@ -585,7 +586,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* RFP option lengths */
|
/* RFP option lengths */
|
||||||
for (pEncap = bi->attr->vnc_subtlvs; pEncap;
|
for (pEncap = bpi->attr->vnc_subtlvs; pEncap;
|
||||||
pEncap = pEncap->next) {
|
pEncap = pEncap->next) {
|
||||||
|
|
||||||
if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) {
|
if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) {
|
||||||
@ -604,8 +605,8 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* RT list */
|
/* RT list */
|
||||||
if (bi->attr->ecommunity) {
|
if (bpi->attr->ecommunity) {
|
||||||
s = ecommunity_ecom2str(bi->attr->ecommunity,
|
s = ecommunity_ecom2str(bpi->attr->ecommunity,
|
||||||
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
r = snprintf(p, REMAIN, " %s", s);
|
r = snprintf(p, REMAIN, " %s", s);
|
||||||
INCP;
|
INCP;
|
||||||
@ -613,13 +614,13 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = snprintf(p, REMAIN, " bi@%p", bi);
|
r = snprintf(p, REMAIN, " bpi@%p", bpi);
|
||||||
INCP;
|
INCP;
|
||||||
|
|
||||||
r = snprintf(p, REMAIN, " p@%p", bi->peer);
|
r = snprintf(p, REMAIN, " p@%p", bpi->peer);
|
||||||
INCP;
|
INCP;
|
||||||
|
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
|
||||||
r = snprintf(p, REMAIN, " HD=yes");
|
r = snprintf(p, REMAIN, " HD=yes");
|
||||||
INCP;
|
INCP;
|
||||||
} else {
|
} else {
|
||||||
@ -627,15 +628,16 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
INCP;
|
INCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->attr) {
|
if (bpi->attr) {
|
||||||
|
|
||||||
if (bi->attr->weight) {
|
if (bpi->attr->weight) {
|
||||||
r = snprintf(p, REMAIN, " W=%d", bi->attr->weight);
|
r = snprintf(p, REMAIN, " W=%d", bpi->attr->weight);
|
||||||
INCP;
|
INCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
|
if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
|
||||||
r = snprintf(p, REMAIN, " LP=%d", bi->attr->local_pref);
|
r = snprintf(p, REMAIN, " LP=%d",
|
||||||
|
bpi->attr->local_pref);
|
||||||
INCP;
|
INCP;
|
||||||
} else {
|
} else {
|
||||||
r = snprintf(p, REMAIN, " LP=unset");
|
r = snprintf(p, REMAIN, " LP=unset");
|
||||||
@ -643,8 +645,8 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bi->type),
|
r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bpi->type),
|
||||||
bi->sub_type);
|
bpi->sub_type);
|
||||||
INCP;
|
INCP;
|
||||||
|
|
||||||
fp(out, "%s%s", line, HVTYNL);
|
fp(out, "%s%s", line, HVTYNL);
|
||||||
@ -656,7 +658,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
HVTYNL);
|
HVTYNL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rfapiGetL2o(bi->attr, &l2o_buf)) {
|
if (!rfapiGetL2o(bpi->attr, &l2o_buf)) {
|
||||||
fp(out,
|
fp(out,
|
||||||
" L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
|
" L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
|
||||||
l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1],
|
l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1],
|
||||||
@ -665,12 +667,12 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
l2o_buf.label, l2o_buf.logical_net_id, l2o_buf.local_nve_id,
|
l2o_buf.label, l2o_buf.logical_net_id, l2o_buf.local_nve_id,
|
||||||
HVTYNL);
|
HVTYNL);
|
||||||
}
|
}
|
||||||
if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
const char *sp;
|
const char *sp;
|
||||||
|
|
||||||
sp = rfapi_ntop(bi->extra->vnc.import.aux_prefix.family,
|
sp = rfapi_ntop(bpi->extra->vnc.import.aux_prefix.family,
|
||||||
&bi->extra->vnc.import.aux_prefix.u.prefix, buf,
|
&bpi->extra->vnc.import.aux_prefix.u.prefix,
|
||||||
BUFSIZ);
|
buf, BUFSIZ);
|
||||||
buf[BUFSIZ - 1] = 0;
|
buf[BUFSIZ - 1] = 0;
|
||||||
if (sp) {
|
if (sp) {
|
||||||
fp(out, " IP: %s%s", sp, HVTYNL);
|
fp(out, " IP: %s%s", sp, HVTYNL);
|
||||||
@ -678,7 +680,7 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
struct rfapi_un_option *uo =
|
struct rfapi_un_option *uo =
|
||||||
rfapi_encap_tlv_to_un_option(bi->attr);
|
rfapi_encap_tlv_to_un_option(bpi->attr);
|
||||||
if (uo) {
|
if (uo) {
|
||||||
rfapi_print_tunneltype_option(stream, 8, &uo->v.tunnel);
|
rfapi_print_tunneltype_option(stream, 8, &uo->v.tunnel);
|
||||||
rfapi_un_options_free(uo);
|
rfapi_un_options_free(uo);
|
||||||
@ -734,13 +736,13 @@ static void rfapiDebugPrintMonitorEncap(void *stream,
|
|||||||
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fp(out, " Mon m=%p, next=%p, node=%p, bi=%p%s", m, m->next, m->node,
|
fp(out, " Mon m=%p, next=%p, node=%p, bpi=%p%s", m, m->next, m->node,
|
||||||
m->bi, HVTYNL);
|
m->bpi, HVTYNL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rfapiShowItNode(void *stream, struct agg_node *rn)
|
void rfapiShowItNode(void *stream, struct agg_node *rn)
|
||||||
{
|
{
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
int (*fp)(void *, const char *, ...);
|
int (*fp)(void *, const char *, ...);
|
||||||
@ -755,8 +757,8 @@ void rfapiShowItNode(void *stream, struct agg_node *rn)
|
|||||||
rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
|
rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
|
||||||
rn->p.prefixlen, rn, rn->lock, HVTYNL);
|
rn->p.prefixlen, rn, rn->lock, HVTYNL);
|
||||||
|
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
rfapiPrintBi(stream, bi);
|
rfapiPrintBi(stream, bpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* doesn't show montors */
|
/* doesn't show montors */
|
||||||
@ -779,7 +781,7 @@ void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt,
|
|||||||
fp(out, "Import Table [%s]%s", label, HVTYNL);
|
fp(out, "Import Table [%s]%s", label, HVTYNL);
|
||||||
|
|
||||||
for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
|
for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
if (rn->p.family == AF_ETHERNET) {
|
if (rn->p.family == AF_ETHERNET) {
|
||||||
rfapiEthAddr2Str(&rn->p.u.prefix_eth, buf, BUFSIZ);
|
rfapiEthAddr2Str(&rn->p.u.prefix_eth, buf, BUFSIZ);
|
||||||
@ -791,8 +793,8 @@ void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt,
|
|||||||
rn->lock - 1, /* account for loop iterator locking */
|
rn->lock - 1, /* account for loop iterator locking */
|
||||||
HVTYNL);
|
HVTYNL);
|
||||||
|
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
rfapiPrintBi(stream, bi);
|
rfapiPrintBi(stream, bpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isvpn) {
|
if (isvpn) {
|
||||||
@ -1008,7 +1010,7 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
||||||
struct agg_node *rn, struct bgp_info *bi)
|
struct agg_node *rn, struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
int (*fp)(void *, const char *, ...);
|
int (*fp)(void *, const char *, ...);
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
@ -1047,26 +1049,26 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
* UN addr
|
* UN addr
|
||||||
*/
|
*/
|
||||||
buf_un[0] = 0;
|
buf_un[0] = 0;
|
||||||
if (!rfapiGetUnAddrOfVpnBi(bi, &pfx_un)) {
|
if (!rfapiGetUnAddrOfVpnBi(bpi, &pfx_un)) {
|
||||||
snprintf(buf_un, BUFSIZ, "%s",
|
snprintf(buf_un, BUFSIZ, "%s",
|
||||||
inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop,
|
inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop,
|
||||||
BUFSIZ));
|
BUFSIZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
rfapiGetTunnelType(bi->attr, &tun_type);
|
rfapiGetTunnelType(bpi->attr, &tun_type);
|
||||||
/*
|
/*
|
||||||
* VN addr
|
* VN addr
|
||||||
*/
|
*/
|
||||||
buf_vn[0] = 0;
|
buf_vn[0] = 0;
|
||||||
rfapiNexthop2Prefix(bi->attr, &pfx_vn);
|
rfapiNexthop2Prefix(bpi->attr, &pfx_vn);
|
||||||
if (tun_type == BGP_ENCAP_TYPE_MPLS) {
|
if (tun_type == BGP_ENCAP_TYPE_MPLS) {
|
||||||
/* MPLS carries un in nrli next hop (same as vn for IP tunnels)
|
/* MPLS carries un in nrli next hop (same as vn for IP tunnels)
|
||||||
*/
|
*/
|
||||||
snprintf(buf_un, BUFSIZ, "%s",
|
snprintf(buf_un, BUFSIZ, "%s",
|
||||||
inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop,
|
inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop,
|
||||||
BUFSIZ));
|
BUFSIZ));
|
||||||
if (bi->extra) {
|
if (bpi->extra) {
|
||||||
uint32_t l = decode_label(&bi->extra->label[0]);
|
uint32_t l = decode_label(&bpi->extra->label[0]);
|
||||||
snprintf(buf_vn, BUFSIZ, "Label: %d", l);
|
snprintf(buf_vn, BUFSIZ, "Label: %d", l);
|
||||||
} else /* should never happen */
|
} else /* should never happen */
|
||||||
{
|
{
|
||||||
@ -1085,10 +1087,10 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
* See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
|
* See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
|
||||||
* back to cost.
|
* back to cost.
|
||||||
*/
|
*/
|
||||||
if (bi->attr) {
|
if (bpi->attr) {
|
||||||
uint32_t local_pref;
|
uint32_t local_pref;
|
||||||
if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
|
if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
|
||||||
local_pref = bi->attr->local_pref;
|
local_pref = bpi->attr->local_pref;
|
||||||
else
|
else
|
||||||
local_pref = 0;
|
local_pref = 0;
|
||||||
cost = (local_pref > 255) ? 0 : 255 - local_pref;
|
cost = (local_pref > 255) ? 0 : 255 - local_pref;
|
||||||
@ -1103,7 +1105,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
|
|
||||||
/* Lifetime */
|
/* Lifetime */
|
||||||
/* NB rfapiGetVncLifetime sets infinite value when returning !0 */
|
/* NB rfapiGetVncLifetime sets infinite value when returning !0 */
|
||||||
if (rfapiGetVncLifetime(bi->attr, &lifetime)
|
if (rfapiGetVncLifetime(bpi->attr, &lifetime)
|
||||||
|| (lifetime == RFAPI_INFINITE_LIFETIME)) {
|
|| (lifetime == RFAPI_INFINITE_LIFETIME)) {
|
||||||
|
|
||||||
fp(out, "%-10s ", "infinite");
|
fp(out, "%-10s ", "infinite");
|
||||||
@ -1113,20 +1115,21 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
fp(out, "%-10s ", buf_lifetime);
|
fp(out, "%-10s ", buf_lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra
|
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
|
||||||
&& bi->extra->vnc.import.timer) {
|
&& bpi->extra->vnc.import.timer) {
|
||||||
|
|
||||||
uint32_t remaining;
|
uint32_t remaining;
|
||||||
time_t age;
|
time_t age;
|
||||||
char buf_age[BUFSIZ];
|
char buf_age[BUFSIZ];
|
||||||
|
|
||||||
struct thread *t = (struct thread *)bi->extra->vnc.import.timer;
|
struct thread *t =
|
||||||
|
(struct thread *)bpi->extra->vnc.import.timer;
|
||||||
remaining = thread_timer_remain_second(t);
|
remaining = thread_timer_remain_second(t);
|
||||||
|
|
||||||
#if RFAPI_REGISTRATIONS_REPORT_AGE
|
#if RFAPI_REGISTRATIONS_REPORT_AGE
|
||||||
/*
|
/*
|
||||||
* Calculate when the timer started. Doing so here saves
|
* Calculate when the timer started. Doing so here saves
|
||||||
* us a timestamp field in "struct bgp_info".
|
* us a timestamp field in "struct bgp_path_info".
|
||||||
*
|
*
|
||||||
* See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
|
* See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
|
||||||
* original calculation.
|
* original calculation.
|
||||||
@ -1140,12 +1143,12 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
|
|
||||||
fp(out, "%-10s ", buf_age);
|
fp(out, "%-10s ", buf_age);
|
||||||
|
|
||||||
} else if (RFAPI_LOCAL_BI(bi)) {
|
} else if (RFAPI_LOCAL_BI(bpi)) {
|
||||||
|
|
||||||
char buf_age[BUFSIZ];
|
char buf_age[BUFSIZ];
|
||||||
|
|
||||||
if (bi->extra && bi->extra->vnc.import.create_time) {
|
if (bpi->extra && bpi->extra->vnc.import.create_time) {
|
||||||
rfapiFormatAge(bi->extra->vnc.import.create_time,
|
rfapiFormatAge(bpi->extra->vnc.import.create_time,
|
||||||
buf_age, BUFSIZ);
|
buf_age, BUFSIZ);
|
||||||
} else {
|
} else {
|
||||||
buf_age[0] = '?';
|
buf_age[0] = '?';
|
||||||
@ -1161,12 +1164,12 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
* print that on the next line
|
* print that on the next line
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
|
if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
|
||||||
const char *sp;
|
const char *sp;
|
||||||
|
|
||||||
sp = rfapi_ntop(
|
sp = rfapi_ntop(
|
||||||
bi->extra->vnc.import.aux_prefix.family,
|
bpi->extra->vnc.import.aux_prefix.family,
|
||||||
&bi->extra->vnc.import.aux_prefix.u.prefix,
|
&bpi->extra->vnc.import.aux_prefix.u.prefix,
|
||||||
buf_ntop, BUFSIZ);
|
buf_ntop, BUFSIZ);
|
||||||
buf_ntop[BUFSIZ - 1] = 0;
|
buf_ntop[BUFSIZ - 1] = 0;
|
||||||
|
|
||||||
@ -1177,8 +1180,8 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra) {
|
if (tun_type != BGP_ENCAP_TYPE_MPLS && bpi->extra) {
|
||||||
uint32_t l = decode_label(&bi->extra->label[0]);
|
uint32_t l = decode_label(&bpi->extra->label[0]);
|
||||||
if (!MPLS_LABEL_IS_NULL(l)) {
|
if (!MPLS_LABEL_IS_NULL(l)) {
|
||||||
fp(out, " Label: %d", l);
|
fp(out, " Label: %d", l);
|
||||||
if (nlines == 1)
|
if (nlines == 1)
|
||||||
@ -1222,7 +1225,7 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
|||||||
for (rn = agg_route_top(it->imported_vpn[afi]); rn;
|
for (rn = agg_route_top(it->imported_vpn[afi]); rn;
|
||||||
rn = agg_route_next(rn)) {
|
rn = agg_route_next(rn)) {
|
||||||
|
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
int count_only;
|
int count_only;
|
||||||
|
|
||||||
/* allow for wider or more narrow mask from user */
|
/* allow for wider or more narrow mask from user */
|
||||||
@ -1232,30 +1235,32 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
|||||||
else
|
else
|
||||||
count_only = 0;
|
count_only = 0;
|
||||||
|
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
if (!show_local && RFAPI_LOCAL_BI(bi)) {
|
if (!show_local && RFAPI_LOCAL_BI(bpi)) {
|
||||||
|
|
||||||
/* local route from RFP */
|
/* local route from RFP */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!show_remote && !RFAPI_LOCAL_BI(bi)) {
|
if (!show_remote && !RFAPI_LOCAL_BI(bpi)) {
|
||||||
|
|
||||||
/* remote route */
|
/* remote route */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_expiring
|
if (show_expiring
|
||||||
&& !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
&& !CHECK_FLAG(bpi->flags,
|
||||||
|
BGP_PATH_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!show_expiring
|
if (!show_expiring
|
||||||
&& CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
|
&& CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (bi->type == ZEBRA_ROUTE_BGP_DIRECT
|
if (bpi->type == ZEBRA_ROUTE_BGP_DIRECT
|
||||||
|| bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
|
|| bpi->type
|
||||||
|
== ZEBRA_ROUTE_BGP_DIRECT_EXT) {
|
||||||
if (!show_imported)
|
if (!show_imported)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@ -1277,7 +1282,7 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
|||||||
type = "Holddown";
|
type = "Holddown";
|
||||||
} else {
|
} else {
|
||||||
if (RFAPI_LOCAL_BI(
|
if (RFAPI_LOCAL_BI(
|
||||||
bi)) {
|
bpi)) {
|
||||||
type = "Local";
|
type = "Local";
|
||||||
} else {
|
} else {
|
||||||
type = "Remote";
|
type = "Remote";
|
||||||
@ -1327,7 +1332,7 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
|
|||||||
"Lifetime", agetype, HVTYNL);
|
"Lifetime", agetype, HVTYNL);
|
||||||
}
|
}
|
||||||
printed += rfapiPrintRemoteRegBi(bgp, stream,
|
printed += rfapiPrintRemoteRegBi(bgp, stream,
|
||||||
rn, bi);
|
rn, bpi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1535,7 +1540,7 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
|
|||||||
{
|
{
|
||||||
afi_t afi; /* of the VN address */
|
afi_t afi; /* of the VN address */
|
||||||
struct bgp_node *bn;
|
struct bgp_node *bn;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
uint8_t type = ZEBRA_ROUTE_BGP;
|
uint8_t type = ZEBRA_ROUTE_BGP;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
int printed = 0;
|
int printed = 0;
|
||||||
@ -1543,7 +1548,7 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
|
|||||||
struct prefix_rd *prd;
|
struct prefix_rd *prd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the bgp_info in the RIB corresponding to this
|
* Find the bgp_path in the RIB corresponding to this
|
||||||
* prefix and rfd
|
* prefix and rfd
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1565,12 +1570,12 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
|
|||||||
|
|
||||||
vty_out(vty, " bn=%p%s", bn, HVTYNL);
|
vty_out(vty, " bn=%p%s", bn, HVTYNL);
|
||||||
|
|
||||||
for (bi = bn->info; bi; bi = bi->next) {
|
for (bpi = bn->info; bpi; bpi = bpi->next) {
|
||||||
if (bi->peer == rfd->peer && bi->type == type
|
if (bpi->peer == rfd->peer && bpi->type == type
|
||||||
&& bi->sub_type == BGP_ROUTE_RFP && bi->extra
|
&& bpi->sub_type == BGP_ROUTE_RFP && bpi->extra
|
||||||
&& bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
&& bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
|
||||||
|
|
||||||
rfapiPrintBi(vty, bi);
|
rfapiPrintBi(vty, bpi);
|
||||||
printed = 1;
|
printed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4840,6 +4845,10 @@ DEFUN (add_vrf_prefix_rd_label_pref,
|
|||||||
static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg)
|
static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
if (rfg->rfapi_import_table == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
afi_t afi = AFI_MAX;
|
afi_t afi = AFI_MAX;
|
||||||
while (afi-- > 0) {
|
while (afi-- > 0) {
|
||||||
count += rfg->rfapi_import_table->local_count[afi];
|
count += rfg->rfapi_import_table->local_count[afi];
|
||||||
|
@ -173,14 +173,14 @@ static int getce(struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce)
|
|||||||
|
|
||||||
|
|
||||||
void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||||
struct bgp_info *bi)
|
struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
struct attr *attr = bi->attr;
|
struct attr *attr = bpi->attr;
|
||||||
struct peer *peer = bi->peer;
|
struct peer *peer = bpi->peer;
|
||||||
struct prefix *prefix = &rn->p;
|
struct prefix *prefix = &rn->p;
|
||||||
afi_t afi = family2afi(prefix->family);
|
afi_t afi = family2afi(prefix->family);
|
||||||
struct bgp_node *urn;
|
struct bgp_node *urn;
|
||||||
struct bgp_info *ubi;
|
struct bgp_path_info *ubpi;
|
||||||
struct attr hattr;
|
struct attr hattr;
|
||||||
struct attr *iattr;
|
struct attr *iattr;
|
||||||
struct prefix ce_nexthop;
|
struct prefix ce_nexthop;
|
||||||
@ -193,10 +193,10 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bi->type != ZEBRA_ROUTE_BGP)
|
if ((bpi->type != ZEBRA_ROUTE_BGP)
|
||||||
|| (bi->sub_type != BGP_ROUTE_NORMAL
|
|| (bpi->sub_type != BGP_ROUTE_NORMAL
|
||||||
&& bi->sub_type != BGP_ROUTE_RFP
|
&& bpi->sub_type != BGP_ROUTE_RFP
|
||||||
&& bi->sub_type != BGP_ROUTE_STATIC)) {
|
&& bpi->sub_type != BGP_ROUTE_STATIC)) {
|
||||||
|
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
"%s: wrong route type/sub_type for export, skipping",
|
"%s: wrong route type/sub_type for export, skipping",
|
||||||
@ -256,17 +256,17 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
*/
|
*/
|
||||||
urn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST,
|
urn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST,
|
||||||
prefix, NULL);
|
prefix, NULL);
|
||||||
for (ubi = urn->info; ubi; ubi = ubi->next) {
|
for (ubpi = urn->info; ubpi; ubpi = ubpi->next) {
|
||||||
struct prefix unicast_nexthop;
|
struct prefix unicast_nexthop;
|
||||||
|
|
||||||
if (CHECK_FLAG(ubi->flags, BGP_INFO_REMOVED))
|
if (CHECK_FLAG(ubpi->flags, BGP_PATH_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rfapiUnicastNexthop2Prefix(afi, ubi->attr, &unicast_nexthop);
|
rfapiUnicastNexthop2Prefix(afi, ubpi->attr, &unicast_nexthop);
|
||||||
|
|
||||||
if (ubi->type == ZEBRA_ROUTE_VNC_DIRECT
|
if (ubpi->type == ZEBRA_ROUTE_VNC_DIRECT
|
||||||
&& ubi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
&& ubpi->sub_type == BGP_ROUTE_REDISTRIBUTE
|
||||||
&& ubi->peer == peer
|
&& ubpi->peer == peer
|
||||||
&& prefix_same(&unicast_nexthop, &ce_nexthop)) {
|
&& prefix_same(&unicast_nexthop, &ce_nexthop)) {
|
||||||
|
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
@ -282,7 +282,7 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
*/
|
*/
|
||||||
encap_attr_export_ce(&hattr, attr, &ce_nexthop);
|
encap_attr_export_ce(&hattr, attr, &ce_nexthop);
|
||||||
if (bgp->rfapi_cfg->routemap_export_bgp) {
|
if (bgp->rfapi_cfg->routemap_export_bgp) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -328,10 +328,10 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
* "Withdrawing a Route" export process
|
* "Withdrawing a Route" export process
|
||||||
*/
|
*/
|
||||||
void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||||
struct bgp_info *bi)
|
struct bgp_path_info *bpi)
|
||||||
{
|
{
|
||||||
afi_t afi = family2afi(rn->p.family);
|
afi_t afi = family2afi(rn->p.family);
|
||||||
struct bgp_info *vbi;
|
struct bgp_path_info *vbpi;
|
||||||
struct prefix ce_nexthop;
|
struct prefix ce_nexthop;
|
||||||
|
|
||||||
if (!afi) {
|
if (!afi) {
|
||||||
@ -364,7 +364,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
* This works only for IPv4 because IPv6 addresses are too big
|
* This works only for IPv4 because IPv6 addresses are too big
|
||||||
* to fit in an extended community
|
* to fit in an extended community
|
||||||
*/
|
*/
|
||||||
if (getce(bgp, bi->attr, &ce_nexthop)) {
|
if (getce(bgp, bpi->attr, &ce_nexthop)) {
|
||||||
vnc_zlog_debug_verbose("%s: EC has no encoded CE, skipping",
|
vnc_zlog_debug_verbose("%s: EC has no encoded CE, skipping",
|
||||||
__func__);
|
__func__);
|
||||||
return;
|
return;
|
||||||
@ -376,13 +376,13 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
* route from the unicast RIB
|
* route from the unicast RIB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (vbi = rn->info; vbi; vbi = vbi->next) {
|
for (vbpi = rn->info; vbpi; vbpi = vbpi->next) {
|
||||||
struct prefix ce;
|
struct prefix ce;
|
||||||
if (bi == vbi)
|
if (bpi == vbpi)
|
||||||
continue;
|
continue;
|
||||||
if (bi->peer != vbi->peer)
|
if (bpi->peer != vbpi->peer)
|
||||||
continue;
|
continue;
|
||||||
if (getce(bgp, vbi->attr, &ce))
|
if (getce(bgp, vbpi->attr, &ce))
|
||||||
continue;
|
continue;
|
||||||
if (prefix_same(&ce, &ce_nexthop)) {
|
if (prefix_same(&ce, &ce_nexthop)) {
|
||||||
vnc_zlog_debug_verbose(
|
vnc_zlog_debug_verbose(
|
||||||
@ -395,8 +395,8 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
/*
|
/*
|
||||||
* withdraw the route
|
* withdraw the route
|
||||||
*/
|
*/
|
||||||
bgp_withdraw(bi->peer, &rn->p, 0, /* addpath_id */
|
bgp_withdraw(bpi->peer, &rn->p, 0, /* addpath_id */
|
||||||
NULL, /* attr, ignored */
|
NULL, /* attr, ignored */
|
||||||
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
|
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
|
||||||
BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
|
BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
|
||||||
NULL, 0, NULL); /* tag not used for unicast */
|
NULL, 0, NULL); /* tag not used for unicast */
|
||||||
@ -405,7 +405,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
|||||||
static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
|
static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
|
||||||
{
|
{
|
||||||
struct agg_node *rn;
|
struct agg_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
|
|
||||||
vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi);
|
vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi);
|
||||||
|
|
||||||
@ -480,8 +480,8 @@ static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi)
|
|||||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
||||||
rn = bgp_route_next(rn)) {
|
rn = bgp_route_next(rn)) {
|
||||||
|
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
struct bgp_info *next;
|
struct bgp_path_info *next;
|
||||||
|
|
||||||
for (ri = rn->info, next = NULL; ri; ri = next) {
|
for (ri = rn->info, next = NULL; ri; ri = next) {
|
||||||
|
|
||||||
@ -516,24 +516,24 @@ static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi)
|
|||||||
static struct ecommunity *vnc_route_origin_ecom(struct agg_node *rn)
|
static struct ecommunity *vnc_route_origin_ecom(struct agg_node *rn)
|
||||||
{
|
{
|
||||||
struct ecommunity *new;
|
struct ecommunity *new;
|
||||||
struct bgp_info *bi;
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
if (!rn->info)
|
if (!rn->info)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
new = ecommunity_new();
|
new = ecommunity_new();
|
||||||
|
|
||||||
for (bi = rn->info; bi; bi = bi->next) {
|
for (bpi = rn->info; bpi; bpi = bpi->next) {
|
||||||
|
|
||||||
struct ecommunity_val roec;
|
struct ecommunity_val roec;
|
||||||
|
|
||||||
switch (BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len)) {
|
switch (BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len)) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
memset(&roec, 0, sizeof(roec));
|
memset(&roec, 0, sizeof(roec));
|
||||||
roec.val[0] = 0x01;
|
roec.val[0] = 0x01;
|
||||||
roec.val[1] = 0x03;
|
roec.val[1] = 0x03;
|
||||||
memcpy(roec.val + 2,
|
memcpy(roec.val + 2,
|
||||||
&bi->attr->mp_nexthop_global_in.s_addr, 4);
|
&bpi->attr->mp_nexthop_global_in.s_addr, 4);
|
||||||
roec.val[6] = 0;
|
roec.val[6] = 0;
|
||||||
roec.val[7] = 0;
|
roec.val[7] = 0;
|
||||||
ecommunity_add_val(new, &roec);
|
ecommunity_add_val(new, &roec);
|
||||||
@ -996,7 +996,7 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
|
|||||||
struct rfapi_descriptor *irfd = rfd;
|
struct rfapi_descriptor *irfd = rfd;
|
||||||
struct attr hattr;
|
struct attr hattr;
|
||||||
struct attr *iattr;
|
struct attr *iattr;
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
|
|
||||||
if (rfapiRaddr2Qprefix(&irfd->vn_addr,
|
if (rfapiRaddr2Qprefix(&irfd->vn_addr,
|
||||||
&nhp))
|
&nhp))
|
||||||
@ -1165,7 +1165,7 @@ static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
|
|||||||
afi_t afi, struct rfapi_descriptor *irfd)
|
afi_t afi, struct rfapi_descriptor *irfd)
|
||||||
{
|
{
|
||||||
struct prefix nhp;
|
struct prefix nhp;
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
struct attr hattr;
|
struct attr hattr;
|
||||||
struct attr *iattr;
|
struct attr *iattr;
|
||||||
|
|
||||||
@ -1403,7 +1403,6 @@ static void vnc_direct_bgp_del_group_afi(struct bgp *bgp,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(afi == AFI_IP || afi == AFI_IP6);
|
|
||||||
rt = import_table->imported_vpn[afi];
|
rt = import_table->imported_vpn[afi];
|
||||||
|
|
||||||
if (!rfg->nves && rfg->type != RFAPI_GROUP_CFG_VRF) {
|
if (!rfg->nves && rfg->type != RFAPI_GROUP_CFG_VRF) {
|
||||||
@ -1629,7 +1628,7 @@ void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* "Adding a Route" export process
|
* "Adding a Route" export process
|
||||||
* TBD do we need to check bi->type and bi->sub_type here, or does
|
* TBD do we need to check bpi->type and bpi->sub_type here, or does
|
||||||
* caller do it?
|
* caller do it?
|
||||||
*/
|
*/
|
||||||
void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi,
|
void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi,
|
||||||
@ -1684,7 +1683,7 @@ void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi,
|
|||||||
if (encap_attr_export(&hattr, attr, NULL, NULL))
|
if (encap_attr_export(&hattr, attr, NULL, NULL))
|
||||||
return;
|
return;
|
||||||
if (hc->routemap_export_bgp) {
|
if (hc->routemap_export_bgp) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -1753,7 +1752,7 @@ static int vncExportWithdrawTimer(struct thread *t)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* "Withdrawing a Route" export process
|
* "Withdrawing a Route" export process
|
||||||
* TBD do we need to check bi->type and bi->sub_type here, or does
|
* TBD do we need to check bpi->type and bpi->sub_type here, or does
|
||||||
* caller do it?
|
* caller do it?
|
||||||
*/
|
*/
|
||||||
void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi,
|
void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi,
|
||||||
@ -1839,7 +1838,7 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
|
|||||||
|
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
|
|
||||||
memset(&prd, 0, sizeof(prd));
|
memset(&prd, 0, sizeof(prd));
|
||||||
prd.family = AF_UNSPEC;
|
prd.family = AF_UNSPEC;
|
||||||
@ -1910,7 +1909,7 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hc->routemap_export_bgp) {
|
if (hc->routemap_export_bgp) {
|
||||||
struct bgp_info info;
|
struct bgp_path_info info;
|
||||||
route_map_result_t ret;
|
route_map_result_t ret;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
@ -2001,8 +2000,8 @@ void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi)
|
|||||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
|
||||||
rn = bgp_route_next(rn)) {
|
rn = bgp_route_next(rn)) {
|
||||||
|
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
struct bgp_info *next;
|
struct bgp_path_info *next;
|
||||||
|
|
||||||
for (ri = rn->info, next = NULL; ri; ri = next) {
|
for (ri = rn->info, next = NULL; ri; ri = next) {
|
||||||
|
|
||||||
|
@ -30,10 +30,10 @@
|
|||||||
#include "rfapi_private.h"
|
#include "rfapi_private.h"
|
||||||
|
|
||||||
extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||||
struct bgp_info *bi);
|
struct bgp_path_info *bpi);
|
||||||
|
|
||||||
extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
|
||||||
struct bgp_info *bi);
|
struct bgp_path_info *bpi);
|
||||||
|
|
||||||
extern void vnc_direct_bgp_add_prefix(struct bgp *bgp,
|
extern void vnc_direct_bgp_add_prefix(struct bgp *bgp,
|
||||||
struct rfapi_import_table *import_table,
|
struct rfapi_import_table *import_table,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -35,10 +35,10 @@ extern uint32_t calc_local_pref(struct attr *attr, struct peer *peer);
|
|||||||
extern int vnc_prefix_cmp(void *pfx1, void *pfx2);
|
extern int vnc_prefix_cmp(void *pfx1, void *pfx2);
|
||||||
|
|
||||||
extern void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix,
|
extern void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix,
|
||||||
struct bgp_info *info);
|
struct bgp_path_info *info);
|
||||||
|
|
||||||
extern void vnc_import_bgp_del_route(struct bgp *bgp, struct prefix *prefix,
|
extern void vnc_import_bgp_del_route(struct bgp *bgp, struct prefix *prefix,
|
||||||
struct bgp_info *info);
|
struct bgp_path_info *info);
|
||||||
|
|
||||||
extern void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi);
|
extern void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi);
|
||||||
|
|
||||||
@ -50,25 +50,24 @@ extern void vnc_import_bgp_exterior_redist_disable(struct bgp *bgp, afi_t afi);
|
|||||||
|
|
||||||
|
|
||||||
extern void vnc_import_bgp_exterior_add_route(
|
extern void vnc_import_bgp_exterior_add_route(
|
||||||
struct bgp *bgp, /* exterior instance, we hope */
|
struct bgp *bgp, /* exterior instance, we hope */
|
||||||
struct prefix *prefix, /* unicast prefix */
|
struct prefix *prefix, /* unicast prefix */
|
||||||
struct bgp_info *info); /* unicast info */
|
struct bgp_path_info *info); /* unicast info */
|
||||||
|
|
||||||
extern void
|
extern void vnc_import_bgp_exterior_del_route(
|
||||||
vnc_import_bgp_exterior_del_route(struct bgp *bgp,
|
struct bgp *bgp, struct prefix *prefix, /* unicast prefix */
|
||||||
struct prefix *prefix, /* unicast prefix */
|
struct bgp_path_info *info); /* unicast info */
|
||||||
struct bgp_info *info); /* unicast info */
|
|
||||||
|
|
||||||
extern void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
extern void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
||||||
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
||||||
struct bgp_table *table_rd, /* per-rd VPN route table */
|
struct bgp_table *table_rd, /* per-rd VPN route table */
|
||||||
struct prefix *prefix, /* VPN prefix */
|
struct prefix *prefix, /* VPN prefix */
|
||||||
struct bgp_info *bi); /* new VPN host route */
|
struct bgp_path_info *bpi); /* new VPN host route */
|
||||||
|
|
||||||
extern void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
extern void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||||
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
struct bgp *bgp, struct prefix_rd *prd, /* RD */
|
||||||
struct bgp_table *table_rd, /* per-rd VPN route table */
|
struct bgp_table *table_rd, /* per-rd VPN route table */
|
||||||
struct prefix *prefix, /* VPN prefix */
|
struct prefix *prefix, /* VPN prefix */
|
||||||
struct bgp_info *bi); /* old VPN host route */
|
struct bgp_path_info *bpi); /* old VPN host route */
|
||||||
|
|
||||||
#endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_ */
|
#endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_ */
|
||||||
|
@ -29,13 +29,13 @@
|
|||||||
|
|
||||||
extern void vnc_import_bgp_exterior_add_route_interior(
|
extern void vnc_import_bgp_exterior_add_route_interior(
|
||||||
struct bgp *bgp, struct rfapi_import_table *it,
|
struct bgp *bgp, struct rfapi_import_table *it,
|
||||||
struct agg_node *rn_interior, /* VPN IT node */
|
struct agg_node *rn_interior, /* VPN IT node */
|
||||||
struct bgp_info *bi_interior); /* VPN IT route */
|
struct bgp_path_info *bpi_interior); /* VPN IT route */
|
||||||
|
|
||||||
extern void vnc_import_bgp_exterior_del_route_interior(
|
extern void vnc_import_bgp_exterior_del_route_interior(
|
||||||
struct bgp *bgp, struct rfapi_import_table *it,
|
struct bgp *bgp, struct rfapi_import_table *it,
|
||||||
struct agg_node *rn_interior, /* VPN IT node */
|
struct agg_node *rn_interior, /* VPN IT node */
|
||||||
struct bgp_info *bi_interior); /* VPN IT route */
|
struct bgp_path_info *bpi_interior); /* VPN IT route */
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
vnc_import_bgp_exterior_redist_enable_it(struct bgp *bgp, afi_t afi,
|
vnc_import_bgp_exterior_redist_enable_it(struct bgp *bgp, afi_t afi,
|
||||||
|
@ -313,10 +313,12 @@ static void vnc_redistribute_withdraw(struct bgp *bgp, afi_t afi, uint8_t type)
|
|||||||
|
|
||||||
/* This is the per-RD table of prefixes */
|
/* This is the per-RD table of prefixes */
|
||||||
table = prn->info;
|
table = prn->info;
|
||||||
|
if (!table)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||||
|
|
||||||
struct bgp_info *ri;
|
struct bgp_path_info *ri;
|
||||||
|
|
||||||
for (ri = rn->info; ri; ri = ri->next) {
|
for (ri = rn->info; ri; ri = ri->next) {
|
||||||
if (ri->type
|
if (ri->type
|
||||||
@ -576,7 +578,9 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zclient_vnc->redist[family2afi(rn->p.family)][ZEBRA_ROUTE_VNC])
|
if (!vrf_bitmap_check(zclient_vnc->redist[family2afi(rn->p.family)]
|
||||||
|
[ZEBRA_ROUTE_VNC],
|
||||||
|
VRF_DEFAULT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bgp->rfapi_cfg) {
|
if (!bgp->rfapi_cfg) {
|
||||||
@ -640,7 +644,8 @@ static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd,
|
|||||||
if (zclient_vnc->sock < 0)
|
if (zclient_vnc->sock < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!zclient_vnc->redist[afi][ZEBRA_ROUTE_VNC])
|
if (!vrf_bitmap_check(zclient_vnc->redist[afi][ZEBRA_ROUTE_VNC],
|
||||||
|
VRF_DEFAULT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (afi != AFI_IP && afi != AFI_IP6) {
|
if (afi != AFI_IP && afi != AFI_IP6) {
|
||||||
@ -839,12 +844,12 @@ int vnc_redistribute_set(struct bgp *bgp, afi_t afi, int type)
|
|||||||
// bgp->redist[afi][type] = 1;
|
// bgp->redist[afi][type] = 1;
|
||||||
|
|
||||||
/* Return if already redistribute flag is set. */
|
/* Return if already redistribute flag is set. */
|
||||||
if (zclient_vnc->redist[afi][type])
|
if (vrf_bitmap_check(zclient_vnc->redist[afi][type], VRF_DEFAULT))
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
|
||||||
vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT);
|
vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT);
|
||||||
|
|
||||||
// zclient_vnc->redist[afi][type] = 1;
|
// vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT);
|
||||||
|
|
||||||
/* Return if zebra connection is not established. */
|
/* Return if zebra connection is not established. */
|
||||||
if (zclient_vnc->sock < 0)
|
if (zclient_vnc->sock < 0)
|
||||||
@ -875,9 +880,9 @@ int vnc_redistribute_unset(struct bgp *bgp, afi_t afi, int type)
|
|||||||
bgp->rfapi_cfg->redist[afi][type] = 0;
|
bgp->rfapi_cfg->redist[afi][type] = 0;
|
||||||
|
|
||||||
/* Return if zebra connection is disabled. */
|
/* Return if zebra connection is disabled. */
|
||||||
if (!zclient_vnc->redist[afi][type])
|
if (!vrf_bitmap_check(zclient_vnc->redist[afi][type], VRF_DEFAULT))
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
zclient_vnc->redist[afi][type] = 0;
|
vrf_bitmap_unset(zclient_vnc->redist[afi][type], VRF_DEFAULT);
|
||||||
|
|
||||||
if (bgp->rfapi_cfg->redist[AFI_IP][type] == 0
|
if (bgp->rfapi_cfg->redist[AFI_IP][type] == 0
|
||||||
&& bgp->rfapi_cfg->redist[AFI_IP6][type] == 0
|
&& bgp->rfapi_cfg->redist[AFI_IP6][type] == 0
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
if ENABLE_BGP_VNC
|
if ENABLE_BGP_VNC
|
||||||
sbin_PROGRAMS += bgpd/rfp-example/rfptest/rfptest
|
noinst_PROGRAMS += bgpd/rfp-example/rfptest/rfptest
|
||||||
endif
|
endif
|
||||||
|
|
||||||
bgpd_rfp_example_rfptest_rfptest_CFLAGS = -I$(top_srcdir)/bgpd/rfapi
|
bgpd_rfp_example_rfptest_rfptest_CFLAGS = -I$(top_srcdir)/bgpd/rfapi
|
||||||
|
@ -208,6 +208,8 @@ bgpd_bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS)
|
|||||||
bgpd_bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
bgpd_bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
||||||
bgpd_bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS)
|
bgpd_bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS)
|
||||||
|
|
||||||
|
bgpd/bgp_evpn_vty_clippy.c: $(CLIPPY_DEPS)
|
||||||
|
bgpd/bgp_evpn_vty.$(OBJEXT): bgpd/bgp_evpn_vty_clippy.c
|
||||||
bgpd/bgp_vty_clippy.c: $(CLIPPY_DEPS)
|
bgpd/bgp_vty_clippy.c: $(CLIPPY_DEPS)
|
||||||
bgpd/bgp_vty.$(OBJEXT): bgpd/bgp_vty_clippy.c
|
bgpd/bgp_vty.$(OBJEXT): bgpd/bgp_vty_clippy.c
|
||||||
bgpd/bgp_route_clippy.c: $(CLIPPY_DEPS)
|
bgpd/bgp_route_clippy.c: $(CLIPPY_DEPS)
|
||||||
|
4
config.version.in
Normal file
4
config.version.in
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# this file is used to carry --with-pkg-extra-version into tarballs
|
||||||
|
EXTRAVERSION="@EXTRAVERSION@"
|
||||||
|
# for easy access by scripts before ./configure is run
|
||||||
|
DIST_PACKAGE_VERSION="@PACKAGE_VERSION@"
|
162
configure.ac
162
configure.ac
@ -323,12 +323,48 @@ fi
|
|||||||
AC_SUBST(AC_LDFLAGS)
|
AC_SUBST(AC_LDFLAGS)
|
||||||
AM_CONDITIONAL([STATIC_BIN], [test "x$enable_static_bin" = "xyes"])
|
AM_CONDITIONAL([STATIC_BIN], [test "x$enable_static_bin" = "xyes"])
|
||||||
|
|
||||||
|
dnl $AR and $RANLIB are set by LT_INIT above
|
||||||
|
AC_MSG_CHECKING([whether $AR supports D option])
|
||||||
|
if $AR crD conftest.a; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
dnl ARFLAGS is for automake, AR_FLAGS for libtool m-(
|
||||||
|
ARFLAGS="crD"
|
||||||
|
AR_FLAGS="crD"
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
ARFLAGS="cru"
|
||||||
|
AR_FLAGS="cru"
|
||||||
|
fi
|
||||||
|
AC_SUBST(ARFLAGS)
|
||||||
|
AC_SUBST(AR_FLAGS)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether $RANLIB supports D option])
|
||||||
|
if $RANLIB -D conftest.a; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
RANLIB="$RANLIB -D"
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
AC_SUBST(RANLIB)
|
||||||
|
|
||||||
|
test -f conftest.a && rm conftest.a
|
||||||
|
|
||||||
dnl ----------------------
|
dnl ----------------------
|
||||||
dnl Packages configuration
|
dnl Packages configuration
|
||||||
dnl ----------------------
|
dnl ----------------------
|
||||||
|
if test -f config.version; then
|
||||||
|
. ./config.version
|
||||||
|
elif test -f "${srcdir}/config.version"; then
|
||||||
|
. "${srcdir}/config.version"
|
||||||
|
fi
|
||||||
AC_ARG_WITH(pkg-extra-version,
|
AC_ARG_WITH(pkg-extra-version,
|
||||||
AS_HELP_STRING([--with-pkg-extra-version=VER], [add extra version field, for packagers/distributions]),
|
AS_HELP_STRING([--with-pkg-extra-version=VER], [add extra version field, for packagers/distributions]), [
|
||||||
[EXTRAVERSION=$withval],)
|
if test "$withval" = "no"; then
|
||||||
|
EXTRAVERSION=
|
||||||
|
else
|
||||||
|
EXTRAVERSION=$withval
|
||||||
|
fi
|
||||||
|
], [])
|
||||||
AC_ARG_WITH(pkg-git-version,
|
AC_ARG_WITH(pkg-git-version,
|
||||||
AS_HELP_STRING([--with-pkg-git-version], [add git information to MOTD and build version string]),
|
AS_HELP_STRING([--with-pkg-git-version], [add git information to MOTD and build version string]),
|
||||||
[ test "x$withval" != "xno" && with_pkg_git_version="yes" ])
|
[ test "x$withval" != "xno" && with_pkg_git_version="yes" ])
|
||||||
@ -462,9 +498,9 @@ AC_ARG_ENABLE([memory-sanitizer],
|
|||||||
AS_IF([test "${enable_clippy_only}" != "yes"], [
|
AS_IF([test "${enable_clippy_only}" != "yes"], [
|
||||||
AC_CHECK_HEADERS(json-c/json.h)
|
AC_CHECK_HEADERS(json-c/json.h)
|
||||||
AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c", [], [-lm])
|
AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c", [], [-lm])
|
||||||
if test $ac_cv_lib_json_c_json_object_get = no; then
|
if test "$ac_cv_lib_json_c_json_object_get" = no; then
|
||||||
AC_CHECK_LIB(json, json_object_get, LIBS="$LIBS -ljson")
|
AC_CHECK_LIB(json, json_object_get, LIBS="$LIBS -ljson")
|
||||||
if test $ac_cv_lib_json_json_object_get = no; then
|
if test "$ac_cv_lib_json_json_object_get" = no; then
|
||||||
AC_MSG_ERROR([lib json is needed to compile])
|
AC_MSG_ERROR([lib json is needed to compile])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -742,6 +778,7 @@ if test "x${EXTRAVERSION}" != "x" ; then
|
|||||||
AC_SUBST(PACKAGE_EXTRAVERSION, ["${EXTRAVERSION}"])
|
AC_SUBST(PACKAGE_EXTRAVERSION, ["${EXTRAVERSION}"])
|
||||||
PACKAGE_STRING="${PACKAGE_STRING}${EXTRAVERSION}"
|
PACKAGE_STRING="${PACKAGE_STRING}${EXTRAVERSION}"
|
||||||
fi
|
fi
|
||||||
|
AC_SUBST(EXTRAVERSION)
|
||||||
|
|
||||||
if test "x$with_pkg_git_version" = "xyes"; then
|
if test "x$with_pkg_git_version" = "xyes"; then
|
||||||
if test -d "${srcdir}/.git"; then
|
if test -d "${srcdir}/.git"; then
|
||||||
@ -958,11 +995,6 @@ case "$host_os" in
|
|||||||
AC_CHECK_LIB(socket, main)
|
AC_CHECK_LIB(socket, main)
|
||||||
AC_CHECK_LIB(nsl, main)
|
AC_CHECK_LIB(nsl, main)
|
||||||
AC_CHECK_LIB(umem, main)
|
AC_CHECK_LIB(umem, main)
|
||||||
AC_CHECK_FUNCS([printstack], [
|
|
||||||
AC_DEFINE([HAVE_PRINTSTACK],1,[Solaris printstack])
|
|
||||||
AC_DEFINE([HAVE_STACK_TRACE],1,[Stack symbols decode functionality])
|
|
||||||
])
|
|
||||||
CURSES=-lcurses
|
|
||||||
SOLARIS="solaris"
|
SOLARIS="solaris"
|
||||||
;;
|
;;
|
||||||
linux*)
|
linux*)
|
||||||
@ -1028,40 +1060,47 @@ dnl ---------------------
|
|||||||
dnl Integrated VTY option
|
dnl Integrated VTY option
|
||||||
dnl ---------------------
|
dnl ---------------------
|
||||||
case "${enable_vtysh}" in
|
case "${enable_vtysh}" in
|
||||||
"no") VTYSH="";;
|
"no")
|
||||||
*) VTYSH="vtysh";
|
VTYSH="";;
|
||||||
AC_DEFINE(VTYSH,,VTY shell)
|
*)
|
||||||
dnl Vtysh uses libreadline, which looks for termcap functions at
|
VTYSH="vtysh";
|
||||||
dnl configure time. We follow readlines search order.
|
AC_DEFINE(VTYSH,,VTY shell)
|
||||||
dnl The required procedures are in libtermcap on NetBSD, in
|
|
||||||
dnl [TODO] on Linux, and in [TODO] on Solaris.
|
prev_libs="$LIBS"
|
||||||
AC_CHECK_LIB(termcap, tputs, LIBREADLINE="$LIBREADLINE -ltermcap",
|
AC_CHECK_LIB(readline, main, [
|
||||||
[AC_CHECK_LIB(tinfo, tputs, LIBREADLINE="$LIBREADLINE -ltinfo",
|
LIBREADLINE="-lreadline"
|
||||||
[AC_CHECK_LIB(curses, tputs, LIBREADLINE="$LIBREADLINE -lcurses",
|
], [
|
||||||
[AC_CHECK_LIB(ncurses, tputs,
|
dnl readline failed - it might be incorrectly linked and missing its
|
||||||
LIBREADLINE="$LIBREADLINE -lncurses")]
|
dnl termcap/tinfo/curses dependency. see if we can fix that...
|
||||||
)]
|
AC_SEARCH_LIBS(tputs, [termcap tinfo curses ncurses], [
|
||||||
)]
|
LIBREADLINE="$ac_cv_search_tputs"
|
||||||
)
|
], [
|
||||||
AC_CHECK_LIB(readline, main, LIBREADLINE="-lreadline $LIBREADLINE",,
|
AC_MSG_ERROR([libreadline (needed for vtysh) not found and/or missing dependencies])
|
||||||
"$LIBREADLINE")
|
])
|
||||||
if test $ac_cv_lib_readline_main = no; then
|
|
||||||
AC_MSG_ERROR([vtysh needs libreadline but was not found and usable on your system.])
|
dnl re-try with the lib we found above
|
||||||
fi
|
unset ac_cv_lib_readline_main
|
||||||
AC_CHECK_HEADER(readline/history.h)
|
AC_CHECK_LIB(readline, main, [
|
||||||
if test $ac_cv_header_readline_history_h = no;then
|
LIBREADLINE="-lreadline $LIBREADLINE"
|
||||||
AC_MSG_ERROR([readline is too old to have readline/history.h, please update to the latest readline library.])
|
], [
|
||||||
fi
|
AC_MSG_ERROR([libreadline (needed for vtysh) not found and/or missing dependencies])
|
||||||
AC_CHECK_LIB(readline, rl_completion_matches,
|
], [$LIBREADLINE])
|
||||||
LIBREADLINE="$LIBREADLINE",, "$LIBREADLINE")
|
], [])
|
||||||
if test $ac_cv_lib_readline_rl_completion_matches = no; then
|
LIBS="$prev_libs"
|
||||||
AC_DEFINE(rl_completion_matches,completion_matches,Old readline)
|
|
||||||
fi
|
AC_CHECK_HEADER(readline/history.h)
|
||||||
AC_SEARCH_LIBS([append_history], [readline], [frr_cv_append_history=yes], [frr_cv_append_history=no])
|
if test $ac_cv_header_readline_history_h = no;then
|
||||||
if test "$frr_cv_append_history" = yes; then
|
AC_MSG_ERROR([readline is too old to have readline/history.h, please update to the latest readline library.])
|
||||||
AC_DEFINE(HAVE_APPEND_HISTORY, 1, [Have history.h append_history])
|
fi
|
||||||
fi
|
AC_CHECK_LIB(readline, rl_completion_matches, [true], [], [$LIBREADLINE])
|
||||||
;;
|
if test $ac_cv_lib_readline_rl_completion_matches = no; then
|
||||||
|
AC_DEFINE(rl_completion_matches,completion_matches,Old readline)
|
||||||
|
fi
|
||||||
|
AC_CHECK_LIB(readline, [append_history], [frr_cv_append_history=yes], [frr_cv_append_history=no], [$LIBREADLINE])
|
||||||
|
if test "$frr_cv_append_history" = yes; then
|
||||||
|
AC_DEFINE(HAVE_APPEND_HISTORY, 1, [Have history.h append_history])
|
||||||
|
fi
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
AC_SUBST(LIBREADLINE)
|
AC_SUBST(LIBREADLINE)
|
||||||
AM_CONDITIONAL(VTYSH, test "x$VTYSH" = "xvtysh")
|
AM_CONDITIONAL(VTYSH, test "x$VTYSH" = "xvtysh")
|
||||||
@ -1402,7 +1441,7 @@ fi
|
|||||||
|
|
||||||
AM_CONDITIONAL(BFDD, [test "x$BFDD" = "xbfdd"])
|
AM_CONDITIONAL(BFDD, [test "x$BFDD" = "xbfdd"])
|
||||||
|
|
||||||
if test $ac_cv_lib_json_c_json_object_get = no -a "x$BFDD" = "xbfdd"; then
|
if test "$ac_cv_lib_json_c_json_object_get" = no -a "x$BFDD" = "xbfdd"; then
|
||||||
AC_MSG_ERROR(["you must use json-c library to use bfdd"])
|
AC_MSG_ERROR(["you must use json-c library to use bfdd"])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -1462,7 +1501,6 @@ fi
|
|||||||
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno])
|
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno])
|
||||||
|
|
||||||
AC_SUBST(SOLARIS)
|
AC_SUBST(SOLARIS)
|
||||||
AC_SUBST(CURSES)
|
|
||||||
AC_CHECK_LIB(crypt, crypt, [],
|
AC_CHECK_LIB(crypt, crypt, [],
|
||||||
[AC_CHECK_LIB(crypto, DES_crypt)])
|
[AC_CHECK_LIB(crypto, DES_crypt)])
|
||||||
AC_CHECK_LIB(resolv, res_init)
|
AC_CHECK_LIB(resolv, res_init)
|
||||||
@ -1497,6 +1535,11 @@ if test "${enable_snmp}" != "" -a "${enable_snmp}" != "no"; then
|
|||||||
fi
|
fi
|
||||||
SNMP_LIBS="`${NETSNMP_CONFIG} --agent-libs`"
|
SNMP_LIBS="`${NETSNMP_CONFIG} --agent-libs`"
|
||||||
SNMP_CFLAGS="`${NETSNMP_CONFIG} --base-cflags`"
|
SNMP_CFLAGS="`${NETSNMP_CONFIG} --base-cflags`"
|
||||||
|
# net-snmp lists all of its own dependencies. we absolutely do not want that
|
||||||
|
# among other things we avoid a GPL vs. OpenSSL license conflict here
|
||||||
|
for removelib in crypto ssl sensors pci wrap; do
|
||||||
|
SNMP_LIBS="`echo $SNMP_LIBS | sed -e 's/\(^\|\s\)-l'$removelib'\b/ /g' -e 's/\(^\|\s\)\([^\s]*\/\)\?lib'$removelib'\.[^\s]\+\b/ /g'`"
|
||||||
|
done
|
||||||
AC_MSG_CHECKING([whether we can link to Net-SNMP])
|
AC_MSG_CHECKING([whether we can link to Net-SNMP])
|
||||||
AC_LINK_IFELSE_FLAGS([$SNMP_CFLAGS], [$SNMP_LIBS], [AC_LANG_PROGRAM([
|
AC_LINK_IFELSE_FLAGS([$SNMP_CFLAGS], [$SNMP_LIBS], [AC_LANG_PROGRAM([
|
||||||
int main(void);
|
int main(void);
|
||||||
@ -1811,17 +1854,31 @@ dnl check for glibc 'backtrace'
|
|||||||
dnl ---------------------------
|
dnl ---------------------------
|
||||||
if test x"${enable_backtrace}" != x"no" ; then
|
if test x"${enable_backtrace}" != x"no" ; then
|
||||||
backtrace_ok=no
|
backtrace_ok=no
|
||||||
AC_CHECK_HEADER([execinfo.h], [
|
PKG_CHECK_MODULES([UNWIND], [libunwind], [
|
||||||
AC_SEARCH_LIBS([backtrace], [execinfo], [
|
AC_DEFINE(HAVE_LIBUNWIND, 1, [libunwind])
|
||||||
AC_DEFINE(HAVE_GLIBC_BACKTRACE,,[Glibc backtrace])
|
backtrace_ok=yes
|
||||||
AC_DEFINE(HAVE_STACK_TRACE,,[Stack symbol decoding])
|
], [
|
||||||
backtrace_ok=yes
|
case "$host_os" in
|
||||||
],, [-lm])
|
sunos* | solaris2*)
|
||||||
|
AC_CHECK_FUNCS([printstack], [
|
||||||
|
AC_DEFINE([HAVE_PRINTSTACK], 1, [Solaris printstack])
|
||||||
|
backtrace_ok=yes
|
||||||
|
])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if test "$backtrace_ok" = no; then
|
||||||
|
AC_CHECK_HEADER([execinfo.h], [
|
||||||
|
AC_SEARCH_LIBS([backtrace], [execinfo], [
|
||||||
|
AC_DEFINE(HAVE_GLIBC_BACKTRACE, 1, [Glibc backtrace])
|
||||||
|
backtrace_ok=yes
|
||||||
|
],, [-lm])
|
||||||
|
])
|
||||||
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
if test x"${enable_backtrace}" = x"yes" -a x"${backtrace_ok}" = x"no"; then
|
if test x"${enable_backtrace}" = x"yes" -a x"${backtrace_ok}" = x"no"; then
|
||||||
dnl user explicitly requested backtrace but we failed to find support
|
dnl user explicitly requested backtrace but we failed to find support
|
||||||
AC_MSG_FAILURE([failed to find backtrace support])
|
AC_MSG_FAILURE([failed to find backtrace or libunwind support])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -2018,6 +2075,7 @@ AC_MSG_RESULT($ac_cv_htonl_works)
|
|||||||
AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile])
|
AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile])
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
|
config.version
|
||||||
redhat/frr.spec
|
redhat/frr.spec
|
||||||
solaris/Makefile
|
solaris/Makefile
|
||||||
debianpkg/changelog
|
debianpkg/changelog
|
||||||
|
@ -4,7 +4,7 @@ Priority: optional
|
|||||||
Maintainer: Nobody <nobody@frrouting.org>
|
Maintainer: Nobody <nobody@frrouting.org>
|
||||||
Uploaders: Nobody <nobody@frrouting.org>
|
Uploaders: Nobody <nobody@frrouting.org>
|
||||||
XSBC-Original-Maintainer: <maintainers@frrouting.org>
|
XSBC-Original-Maintainer: <maintainers@frrouting.org>
|
||||||
Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddr, python-sphinx, libpython-dev, install-info
|
Build-Depends: debhelper (>= 7.0.50~), libreadline-dev, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7) | python3, python-sphinx | python3-sphinx, libpython-dev | libpython3-dev, install-info
|
||||||
Standards-Version: 3.9.6
|
Standards-Version: 3.9.6
|
||||||
Homepage: http://www.frrouting.org/
|
Homepage: http://www.frrouting.org/
|
||||||
|
|
||||||
|
@ -4,5 +4,4 @@ etc/iproute2/rt_protos.d/
|
|||||||
usr/share/doc/frr/
|
usr/share/doc/frr/
|
||||||
usr/share/doc/frr/examples/
|
usr/share/doc/frr/examples/
|
||||||
usr/share/lintian/overrides/
|
usr/share/lintian/overrides/
|
||||||
usr/share/snmp/mibs/
|
|
||||||
var/log/frr/
|
var/log/frr/
|
||||||
|
@ -5,7 +5,6 @@ usr/include/frr/
|
|||||||
usr/lib/
|
usr/lib/
|
||||||
tools/frr usr/lib/frr
|
tools/frr usr/lib/frr
|
||||||
usr/share/doc/frr/
|
usr/share/doc/frr/
|
||||||
usr/share/snmp/mibs/
|
|
||||||
tools/etc/* etc/
|
tools/etc/* etc/
|
||||||
tools/*.service lib/systemd/system
|
tools/*.service lib/systemd/system
|
||||||
tools/frr-reload usr/lib/frr/
|
tools/frr-reload usr/lib/frr/
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
# open, as well as the daemons, so always signal the daemons.
|
# open, as well as the daemons, so always signal the daemons.
|
||||||
# It's safe, a NOP if (only) syslog is being used.
|
# It's safe, a NOP if (only) syslog is being used.
|
||||||
for i in babeld bgpd eigrpd isisd ldpd nhrpd ospf6d ospfd \
|
for i in babeld bgpd eigrpd isisd ldpd nhrpd ospf6d ospfd \
|
||||||
pimd ripd ripngd zebra staticd ; do
|
pimd ripd ripngd zebra staticd fabricd; do
|
||||||
if [ -e /var/run/frr/$i.pid ] ; then
|
if [ -e /var/run/frr/$i.pid ] ; then
|
||||||
pids="$pids $(cat /var/run/frr/$i.pid)"
|
pids="$pids $(cat /var/run/frr/$i.pid)"
|
||||||
fi
|
fi
|
||||||
|
@ -13,3 +13,4 @@ doc/manpages/_build/man/zebra.8
|
|||||||
doc/manpages/_build/man/isisd.8
|
doc/manpages/_build/man/isisd.8
|
||||||
doc/manpages/_build/man/watchfrr.8
|
doc/manpages/_build/man/watchfrr.8
|
||||||
doc/manpages/_build/man/mtracebis.8
|
doc/manpages/_build/man/mtracebis.8
|
||||||
|
doc/manpages/_build/man/fabricd.8
|
||||||
|
@ -7,15 +7,15 @@
|
|||||||
# The following are the defaults. They can be overridden by setting a
|
# The following are the defaults. They can be overridden by setting a
|
||||||
# env variable to a different value
|
# env variable to a different value
|
||||||
|
|
||||||
WANT_LDP ?= 1
|
# -Werror - don't enable this unless you're doing a dev package build
|
||||||
WANT_PIM ?= 1
|
WANT_WERROR ?= 0
|
||||||
|
|
||||||
WANT_OSPFAPI ?= 1
|
WANT_OSPFAPI ?= 1
|
||||||
WANT_BGP_VNC ?= 1
|
WANT_BGP_VNC ?= 1
|
||||||
WANT_CUMULUS_MODE ?= 0
|
WANT_CUMULUS_MODE ?= 0
|
||||||
WANT_MULTIPATH ?= 1
|
WANT_MULTIPATH ?= 1
|
||||||
WANT_SNMP ?= 0
|
WANT_SNMP ?= 0
|
||||||
WANT_RPKI ?= 0
|
WANT_RPKI ?= 0
|
||||||
WANT_BFD ?= 1
|
|
||||||
|
|
||||||
# NOTES:
|
# NOTES:
|
||||||
#
|
#
|
||||||
@ -39,6 +39,7 @@ WANT_FRR_USER ?= frr
|
|||||||
WANT_FRR_VTY_GROUP ?= frrvty
|
WANT_FRR_VTY_GROUP ?= frrvty
|
||||||
|
|
||||||
# Don't build PDF docs by default
|
# Don't build PDF docs by default
|
||||||
|
# add build deps: texlive-latex-base, texlive-generic-recommended
|
||||||
GENERATE_PDF ?= 0
|
GENERATE_PDF ?= 0
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -56,18 +57,6 @@ else
|
|||||||
$(warning "DEBIAN: SNMP disabled, see README.Debian")
|
$(warning "DEBIAN: SNMP disabled, see README.Debian")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(WANT_LDP), 1)
|
|
||||||
USE_LDP=--enable-ldpd
|
|
||||||
else
|
|
||||||
USE_LDP=--disable-ldpd
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(WANT_PIM), 1)
|
|
||||||
USE_PIM=--enable-pimd
|
|
||||||
else
|
|
||||||
USE_PIM=--disable-pimd
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(WANT_OSPFAPI), 1)
|
ifeq ($(WANT_OSPFAPI), 1)
|
||||||
USE_OSPFAPI=--enable-ospfapi=yes
|
USE_OSPFAPI=--enable-ospfapi=yes
|
||||||
else
|
else
|
||||||
@ -102,10 +91,10 @@ else
|
|||||||
USE_RPKI=--disable-rpki
|
USE_RPKI=--disable-rpki
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(WANT_BFD), 1)
|
ifeq ($(WANT_WERROR), 1)
|
||||||
USE_BFD=--enable-bfdd
|
USE_WERROR=--enable-werror
|
||||||
else
|
else
|
||||||
USE_BFD=--disable-bfdd
|
USE_WERROR=--disable-werror
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
|
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
|
||||||
@ -127,14 +116,6 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
override_dh_auto_configure:
|
override_dh_auto_configure:
|
||||||
# Frr needs /proc to check some BSD vs Linux specific stuff.
|
|
||||||
# Else it fails with an obscure error message pointing out that
|
|
||||||
# IPCTL_FORWARDING is an undefined symbol which is not very helpful.
|
|
||||||
@if ! [ -d /proc/1 ]; then \
|
|
||||||
echo "./configure needs a mounted /proc"; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! [ -e config.status ]; then \
|
if ! [ -e config.status ]; then \
|
||||||
dh_auto_configure -- \
|
dh_auto_configure -- \
|
||||||
--enable-exampledir=/usr/share/doc/frr/examples/ \
|
--enable-exampledir=/usr/share/doc/frr/examples/ \
|
||||||
@ -144,32 +125,23 @@ override_dh_auto_configure:
|
|||||||
$(USE_SNMP) \
|
$(USE_SNMP) \
|
||||||
$(USE_OSPFAPI) \
|
$(USE_OSPFAPI) \
|
||||||
$(USE_MULTIPATH) \
|
$(USE_MULTIPATH) \
|
||||||
$(USE_LDP) \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
$(USE_FRR_USER) $(USE_FRR_GROUP) \
|
$(USE_FRR_USER) $(USE_FRR_GROUP) \
|
||||||
$(USE_FRR_VTY_GROUP) \
|
$(USE_FRR_VTY_GROUP) \
|
||||||
--enable-configfile-mask=0640 \
|
--enable-configfile-mask=0640 \
|
||||||
--enable-logfile-mask=0640 \
|
--enable-logfile-mask=0640 \
|
||||||
--enable-werror \
|
$(USE_WERROR) \
|
||||||
--with-libpam \
|
--with-libpam \
|
||||||
--enable-systemd=yes \
|
--enable-systemd=yes \
|
||||||
--enable-poll=yes \
|
|
||||||
$(USE_CUMULUS) \
|
$(USE_CUMULUS) \
|
||||||
$(USE_PIM) \
|
--disable-dependency-tracking \
|
||||||
--enable-dependency-tracking \
|
|
||||||
$(USE_BGP_VNC) \
|
$(USE_BGP_VNC) \
|
||||||
$(USE_RPKI) \
|
$(USE_RPKI) \
|
||||||
$(USE_BFD) \
|
|
||||||
$(shell dpkg-buildflags --export=configure); \
|
$(shell dpkg-buildflags --export=configure); \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
override_dh_auto_build:
|
override_dh_auto_build:
|
||||||
# doc/ is a bit crazy
|
dh_auto_build
|
||||||
ifeq ($(GENERATE_PDF), 1)
|
|
||||||
dh_auto_build -- -C doc pdf
|
|
||||||
endif
|
|
||||||
rm -vf doc/user/_build/texinfo/frr.info
|
|
||||||
dh_auto_build -- -C doc info
|
|
||||||
|
|
||||||
override_dh_auto_test:
|
override_dh_auto_test:
|
||||||
|
|
||||||
@ -186,12 +158,9 @@ override_dh_auto_install:
|
|||||||
mkdir -p debian/tmp/etc/frr/
|
mkdir -p debian/tmp/etc/frr/
|
||||||
perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample*
|
perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample*
|
||||||
|
|
||||||
# leftover from previously shipping SMUX client OID MIB
|
# we don't need .la files
|
||||||
mkdir -p debian/tmp/usr/share/snmp/mibs/
|
rm debian/tmp/usr/lib/*.la
|
||||||
|
rm debian/tmp/usr/lib/frr/modules/*.la
|
||||||
# cleaning .la files
|
|
||||||
sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la
|
|
||||||
sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/frr/modules/*.la
|
|
||||||
|
|
||||||
override_dh_systemd_start:
|
override_dh_systemd_start:
|
||||||
dh_systemd_start frr.service
|
dh_systemd_start frr.service
|
||||||
|
@ -6,7 +6,7 @@ set -e
|
|||||||
|
|
||||||
# modify config file to enable all daemons and copy config files
|
# modify config file to enable all daemons and copy config files
|
||||||
CONFIG_FILE=/etc/frr/daemons
|
CONFIG_FILE=/etc/frr/daemons
|
||||||
DAEMONS=("zebra" "bgpd" "ospfd" "ospf6d" "ripd" "ripngd" "isisd" "pimd")
|
DAEMONS=("zebra" "bgpd" "ospfd" "ospf6d" "ripd" "ripngd" "isisd" "pimd" "fabricd")
|
||||||
|
|
||||||
for daemon in "${DAEMONS[@]}"
|
for daemon in "${DAEMONS[@]}"
|
||||||
do
|
do
|
||||||
|
@ -44,8 +44,7 @@ Add packages:
|
|||||||
|
|
||||||
sudo yum install git autoconf automake libtool make gawk \
|
sudo yum install git autoconf automake libtool make gawk \
|
||||||
readline-devel texinfo net-snmp-devel groff pkgconfig \
|
readline-devel texinfo net-snmp-devel groff pkgconfig \
|
||||||
json-c-devel pam-devel flex epel-release perl-XML-LibXML \
|
json-c-devel pam-devel flex epel-release c-ares-devel
|
||||||
c-ares-devel
|
|
||||||
|
|
||||||
Install newer version of bison (CentOS 6 package source is too old) from CentOS
|
Install newer version of bison (CentOS 6 package source is too old) from CentOS
|
||||||
7:
|
7:
|
||||||
@ -154,19 +153,12 @@ an example.)
|
|||||||
--disable-pimd \
|
--disable-pimd \
|
||||||
--enable-snmp=agentx \
|
--enable-snmp=agentx \
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-rtadv \
|
|
||||||
--disable-exampledir \
|
--disable-exampledir \
|
||||||
--enable-watchfrr \
|
|
||||||
--disable-ldpd \
|
--disable-ldpd \
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--enable-nhrpd \
|
|
||||||
--enable-eigrpd \
|
|
||||||
--enable-babeld \
|
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion \
|
--with-pkg-extra-version=-MyOwnFRRVersion \
|
||||||
SPHINXBUILD=sphinx-build2.7
|
SPHINXBUILD=sphinx-build2.7
|
||||||
|
@ -22,7 +22,7 @@ Add packages:
|
|||||||
sudo yum install git autoconf automake libtool make gawk \
|
sudo yum install git autoconf automake libtool make gawk \
|
||||||
readline-devel texinfo net-snmp-devel groff pkgconfig \
|
readline-devel texinfo net-snmp-devel groff pkgconfig \
|
||||||
json-c-devel pam-devel bison flex pytest c-ares-devel \
|
json-c-devel pam-devel bison flex pytest c-ares-devel \
|
||||||
perl-XML-LibXML python-devel systemd-devel python-sphinx
|
python-devel systemd-devel python-sphinx
|
||||||
|
|
||||||
Get FRR, compile it and install it (from Git)
|
Get FRR, compile it and install it (from Git)
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
@ -59,23 +59,15 @@ an example.)
|
|||||||
--libexecdir=/usr/lib/frr \
|
--libexecdir=/usr/lib/frr \
|
||||||
--localstatedir=/var/run/frr \
|
--localstatedir=/var/run/frr \
|
||||||
--with-moduledir=/usr/lib/frr/modules \
|
--with-moduledir=/usr/lib/frr/modules \
|
||||||
--enable-pimd \
|
|
||||||
--enable-snmp=agentx \
|
--enable-snmp=agentx \
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-rtadv \
|
|
||||||
--enable-systemd=yes \
|
--enable-systemd=yes \
|
||||||
--disable-exampledir \
|
--disable-exampledir \
|
||||||
--enable-watchfrr \
|
|
||||||
--disable-ldpd \
|
--disable-ldpd \
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--enable-nhrpd \
|
|
||||||
--enable-eigrpd \
|
|
||||||
--enable-babeld \
|
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
make
|
make
|
||||||
|
@ -58,21 +58,13 @@ an example.)
|
|||||||
--localstatedir=/var/run/frr \
|
--localstatedir=/var/run/frr \
|
||||||
--sbindir=/usr/lib/frr \
|
--sbindir=/usr/lib/frr \
|
||||||
--sysconfdir=/etc/frr \
|
--sysconfdir=/etc/frr \
|
||||||
--enable-vtysh \
|
|
||||||
--enable-isisd \
|
|
||||||
--enable-pimd \
|
|
||||||
--enable-watchfrr \
|
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-configfile-mask=0640 \
|
--enable-configfile-mask=0640 \
|
||||||
--enable-logfile-mask=0640 \
|
--enable-logfile-mask=0640 \
|
||||||
--enable-rtadv \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--enable-ldpd \
|
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
make
|
make
|
||||||
|
@ -39,28 +39,19 @@ an example.)
|
|||||||
|
|
||||||
git clone https://github.com/frrouting/frr.git frr
|
git clone https://github.com/frrouting/frr.git frr
|
||||||
cd frr
|
cd frr
|
||||||
git checkout stable/3.0
|
|
||||||
./bootstrap.sh
|
./bootstrap.sh
|
||||||
./configure \
|
./configure \
|
||||||
--enable-exampledir=/usr/share/doc/frr/examples/ \
|
--enable-exampledir=/usr/share/doc/frr/examples/ \
|
||||||
--localstatedir=/var/opt/frr \
|
--localstatedir=/var/opt/frr \
|
||||||
--sbindir=/usr/lib/frr \
|
--sbindir=/usr/lib/frr \
|
||||||
--sysconfdir=/etc/frr \
|
--sysconfdir=/etc/frr \
|
||||||
--enable-vtysh \
|
|
||||||
--enable-isisd \
|
|
||||||
--enable-pimd \
|
|
||||||
--enable-watchfrr \
|
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-configfile-mask=0640 \
|
--enable-configfile-mask=0640 \
|
||||||
--enable-logfile-mask=0640 \
|
--enable-logfile-mask=0640 \
|
||||||
--enable-rtadv \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--enable-ldpd \
|
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
make
|
make
|
||||||
|
@ -14,8 +14,8 @@ Add packages:
|
|||||||
|
|
||||||
sudo dnf install git autoconf automake libtool make gawk \
|
sudo dnf install git autoconf automake libtool make gawk \
|
||||||
readline-devel texinfo net-snmp-devel groff pkgconfig \
|
readline-devel texinfo net-snmp-devel groff pkgconfig \
|
||||||
json-c-devel pam-devel perl-XML-LibXML pytest bison flex \
|
json-c-devel pam-devel pytest bison flex c-ares-devel \
|
||||||
c-ares-devel python3-devel python3-sphinx
|
python3-devel python3-sphinx
|
||||||
|
|
||||||
Get FRR, compile it and install it (from Git)
|
Get FRR, compile it and install it (from Git)
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
@ -52,22 +52,13 @@ an example.)
|
|||||||
--libexecdir=/usr/lib/frr \
|
--libexecdir=/usr/lib/frr \
|
||||||
--localstatedir=/var/run/frr \
|
--localstatedir=/var/run/frr \
|
||||||
--with-moduledir=/usr/lib/frr/modules \
|
--with-moduledir=/usr/lib/frr/modules \
|
||||||
--enable-pimd \
|
|
||||||
--enable-snmp=agentx \
|
--enable-snmp=agentx \
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-rtadv \
|
|
||||||
--disable-exampledir \
|
--disable-exampledir \
|
||||||
--enable-watchfrr \
|
|
||||||
--enable-ldpd \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--enable-nhrpd \
|
|
||||||
--enable-eigrpd \
|
|
||||||
--enable-babeld \
|
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
make
|
make
|
||||||
|
@ -59,15 +59,12 @@ an example)
|
|||||||
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
||||||
--localstatedir=/var/run/frr \
|
--localstatedir=/var/run/frr \
|
||||||
--prefix=/usr/local \
|
--prefix=/usr/local \
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-configfile-mask=0640 \
|
--enable-configfile-mask=0640 \
|
||||||
--enable-logfile-mask=0640 \
|
--enable-logfile-mask=0640 \
|
||||||
--enable-rtadv \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
|
@ -64,15 +64,12 @@ an example)
|
|||||||
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
||||||
--localstatedir=/var/run/frr \
|
--localstatedir=/var/run/frr \
|
||||||
--prefix=/usr/local \
|
--prefix=/usr/local \
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-configfile-mask=0640 \
|
--enable-configfile-mask=0640 \
|
||||||
--enable-logfile-mask=0640 \
|
--enable-logfile-mask=0640 \
|
||||||
--enable-rtadv \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
|
@ -72,15 +72,12 @@ an example)
|
|||||||
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
||||||
--localstatedir=/var/run/frr \
|
--localstatedir=/var/run/frr \
|
||||||
--prefix=/usr/local \
|
--prefix=/usr/local \
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-configfile-mask=0640 \
|
--enable-configfile-mask=0640 \
|
||||||
--enable-logfile-mask=0640 \
|
--enable-logfile-mask=0640 \
|
||||||
--enable-rtadv \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
|
@ -72,15 +72,12 @@ an example)
|
|||||||
--enable-exampledir=/usr/pkg/share/examples/frr \
|
--enable-exampledir=/usr/pkg/share/examples/frr \
|
||||||
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
||||||
--localstatedir=/var/run/frr \
|
--localstatedir=/var/run/frr \
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-configfile-mask=0640 \
|
--enable-configfile-mask=0640 \
|
||||||
--enable-logfile-mask=0640 \
|
--enable-logfile-mask=0640 \
|
||||||
--enable-rtadv \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
|
@ -63,15 +63,12 @@ an example)
|
|||||||
--enable-exampledir=/usr/pkg/share/examples/frr \
|
--enable-exampledir=/usr/pkg/share/examples/frr \
|
||||||
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
|
||||||
--localstatedir=/var/run/frr \
|
--localstatedir=/var/run/frr \
|
||||||
--enable-ospfclient=yes \
|
|
||||||
--enable-ospfapi=yes \
|
|
||||||
--enable-multipath=64 \
|
--enable-multipath=64 \
|
||||||
--enable-user=frr \
|
--enable-user=frr \
|
||||||
--enable-group=frr \
|
--enable-group=frr \
|
||||||
--enable-vty-group=frrvty \
|
--enable-vty-group=frrvty \
|
||||||
--enable-configfile-mask=0640 \
|
--enable-configfile-mask=0640 \
|
||||||
--enable-logfile-mask=0640 \
|
--enable-logfile-mask=0640 \
|
||||||
--enable-rtadv \
|
|
||||||
--enable-fpm \
|
--enable-fpm \
|
||||||
--with-pkg-git-version \
|
--with-pkg-git-version \
|
||||||
--with-pkg-extra-version=-MyOwnFRRVersion
|
--with-pkg-extra-version=-MyOwnFRRVersion
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user