*: reindent

indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
whitespace / reindent 2017-07-17 14:03:14 +02:00
parent 888ac268a0
commit d62a17aede
687 changed files with 263964 additions and 273853 deletions

View File

@ -43,67 +43,60 @@
/* BGP advertise attribute is used for pack same attribute update into
one packet. To do that we maintain attribute hash in struct
peer. */
struct bgp_advertise_attr *
baa_new (void)
struct bgp_advertise_attr *baa_new(void)
{
return (struct bgp_advertise_attr *)
XCALLOC (MTYPE_BGP_ADVERTISE_ATTR, sizeof (struct bgp_advertise_attr));
return (struct bgp_advertise_attr *)XCALLOC(
MTYPE_BGP_ADVERTISE_ATTR, sizeof(struct bgp_advertise_attr));
}
static void
baa_free (struct bgp_advertise_attr *baa)
static void baa_free(struct bgp_advertise_attr *baa)
{
XFREE (MTYPE_BGP_ADVERTISE_ATTR, baa);
XFREE(MTYPE_BGP_ADVERTISE_ATTR, baa);
}
static void *
baa_hash_alloc (void *p)
static void *baa_hash_alloc(void *p)
{
struct bgp_advertise_attr * ref = (struct bgp_advertise_attr *) p;
struct bgp_advertise_attr *ref = (struct bgp_advertise_attr *)p;
struct bgp_advertise_attr *baa;
baa = baa_new ();
baa = baa_new();
baa->attr = ref->attr;
return baa;
}
unsigned int
baa_hash_key (void *p)
unsigned int baa_hash_key(void *p)
{
struct bgp_advertise_attr * baa = (struct bgp_advertise_attr *) p;
struct bgp_advertise_attr *baa = (struct bgp_advertise_attr *)p;
return attrhash_key_make (baa->attr);
return attrhash_key_make(baa->attr);
}
int
baa_hash_cmp (const void *p1, const void *p2)
int baa_hash_cmp(const void *p1, const void *p2)
{
const struct bgp_advertise_attr * baa1 = p1;
const struct bgp_advertise_attr * baa2 = p2;
const struct bgp_advertise_attr *baa1 = p1;
const struct bgp_advertise_attr *baa2 = p2;
return attrhash_cmp (baa1->attr, baa2->attr);
return attrhash_cmp(baa1->attr, baa2->attr);
}
/* BGP update and withdraw information is stored in BGP advertise
structure. This structure is referred from BGP adjacency
information. */
struct bgp_advertise *
bgp_advertise_new (void)
struct bgp_advertise *bgp_advertise_new(void)
{
return (struct bgp_advertise *)
XCALLOC (MTYPE_BGP_ADVERTISE, sizeof (struct bgp_advertise));
return (struct bgp_advertise *)XCALLOC(MTYPE_BGP_ADVERTISE,
sizeof(struct bgp_advertise));
}
void
bgp_advertise_free (struct bgp_advertise *adv)
void bgp_advertise_free(struct bgp_advertise *adv)
{
if (adv->binfo)
bgp_info_unlock (adv->binfo); /* bgp_advertise bgp_info reference */
XFREE (MTYPE_BGP_ADVERTISE, adv);
bgp_info_unlock(
adv->binfo); /* bgp_advertise bgp_info reference */
XFREE(MTYPE_BGP_ADVERTISE, adv);
}
void
bgp_advertise_add (struct bgp_advertise_attr *baa,
void bgp_advertise_add(struct bgp_advertise_attr *baa,
struct bgp_advertise *adv)
{
adv->next = baa->adv;
@ -112,8 +105,7 @@ bgp_advertise_add (struct bgp_advertise_attr *baa,
baa->adv = adv;
}
void
bgp_advertise_delete (struct bgp_advertise_attr *baa,
void bgp_advertise_delete(struct bgp_advertise_attr *baa,
struct bgp_advertise *adv)
{
if (adv->next)
@ -124,40 +116,36 @@ bgp_advertise_delete (struct bgp_advertise_attr *baa,
baa->adv = adv->next;
}
struct bgp_advertise_attr *
bgp_advertise_intern (struct hash *hash, struct attr *attr)
struct bgp_advertise_attr *bgp_advertise_intern(struct hash *hash,
struct attr *attr)
{
struct bgp_advertise_attr ref;
struct bgp_advertise_attr *baa;
ref.attr = bgp_attr_intern (attr);
baa = (struct bgp_advertise_attr *) hash_get (hash, &ref, baa_hash_alloc);
ref.attr = bgp_attr_intern(attr);
baa = (struct bgp_advertise_attr *)hash_get(hash, &ref, baa_hash_alloc);
baa->refcnt++;
return baa;
}
void
bgp_advertise_unintern (struct hash *hash, struct bgp_advertise_attr *baa)
void bgp_advertise_unintern(struct hash *hash, struct bgp_advertise_attr *baa)
{
if (baa->refcnt)
baa->refcnt--;
if (baa->refcnt && baa->attr)
bgp_attr_unintern (&baa->attr);
else
{
if (baa->attr)
{
hash_release (hash, baa);
bgp_attr_unintern (&baa->attr);
bgp_attr_unintern(&baa->attr);
else {
if (baa->attr) {
hash_release(hash, baa);
bgp_attr_unintern(&baa->attr);
}
baa_free (baa);
baa_free(baa);
}
}
int
bgp_adj_out_lookup (struct peer *peer, struct bgp_node *rn,
int bgp_adj_out_lookup(struct peer *peer, struct bgp_node *rn,
u_int32_t addpath_tx_id)
{
struct bgp_adj_out *adj;
@ -168,19 +156,19 @@ bgp_adj_out_lookup (struct peer *peer, struct bgp_node *rn,
for (adj = rn->adj_out; adj; adj = adj->next)
SUBGRP_FOREACH_PEER(adj->subgroup, paf)
if (paf->peer == peer)
{
afi = SUBGRP_AFI (adj->subgroup);
safi = SUBGRP_SAFI (adj->subgroup);
addpath_capable = bgp_addpath_encode_tx (peer, afi, safi);
if (paf->peer == peer) {
afi = SUBGRP_AFI(adj->subgroup);
safi = SUBGRP_SAFI(adj->subgroup);
addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
/* Match on a specific addpath_tx_id if we are using addpath for this
/* Match on a specific addpath_tx_id if we are using addpath for
* this
* peer and if an addpath_tx_id was specified */
if (addpath_capable && addpath_tx_id && adj->addpath_tx_id != addpath_tx_id)
if (addpath_capable && addpath_tx_id
&& adj->addpath_tx_id != addpath_tx_id)
continue;
return (adj->adv
? (adj->adv->baa ? 1 : 0)
return (adj->adv ? (adj->adv->baa ? 1 : 0)
: (adj->attr ? 1 : 0));
}
@ -188,43 +176,37 @@ bgp_adj_out_lookup (struct peer *peer, struct bgp_node *rn,
}
void
bgp_adj_in_set (struct bgp_node *rn, struct peer *peer, struct attr *attr,
void bgp_adj_in_set(struct bgp_node *rn, struct peer *peer, struct attr *attr,
u_int32_t addpath_id)
{
struct bgp_adj_in *adj;
for (adj = rn->adj_in; adj; adj = adj->next)
{
if (adj->peer == peer && adj->addpath_rx_id == addpath_id)
{
if (adj->attr != attr)
{
bgp_attr_unintern (&adj->attr);
adj->attr = bgp_attr_intern (attr);
for (adj = rn->adj_in; adj; adj = adj->next) {
if (adj->peer == peer && adj->addpath_rx_id == addpath_id) {
if (adj->attr != attr) {
bgp_attr_unintern(&adj->attr);
adj->attr = bgp_attr_intern(attr);
}
return;
}
}
adj = XCALLOC (MTYPE_BGP_ADJ_IN, sizeof (struct bgp_adj_in));
adj->peer = peer_lock (peer); /* adj_in peer reference */
adj->attr = bgp_attr_intern (attr);
adj = XCALLOC(MTYPE_BGP_ADJ_IN, sizeof(struct bgp_adj_in));
adj->peer = peer_lock(peer); /* adj_in peer reference */
adj->attr = bgp_attr_intern(attr);
adj->addpath_rx_id = addpath_id;
BGP_ADJ_IN_ADD (rn, adj);
bgp_lock_node (rn);
BGP_ADJ_IN_ADD(rn, adj);
bgp_lock_node(rn);
}
void
bgp_adj_in_remove (struct bgp_node *rn, struct bgp_adj_in *bai)
void bgp_adj_in_remove(struct bgp_node *rn, struct bgp_adj_in *bai)
{
bgp_attr_unintern (&bai->attr);
BGP_ADJ_IN_DEL (rn, bai);
peer_unlock (bai->peer); /* adj_in peer reference */
XFREE (MTYPE_BGP_ADJ_IN, bai);
bgp_attr_unintern(&bai->attr);
BGP_ADJ_IN_DEL(rn, bai);
peer_unlock(bai->peer); /* adj_in peer reference */
XFREE(MTYPE_BGP_ADJ_IN, bai);
}
int
bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer,
int bgp_adj_in_unset(struct bgp_node *rn, struct peer *peer,
u_int32_t addpath_id)
{
struct bgp_adj_in *adj;
@ -235,14 +217,12 @@ bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer,
if (!adj)
return 0;
while (adj)
{
while (adj) {
adj_next = adj->next;
if (adj->peer == peer && adj->addpath_rx_id == addpath_id)
{
bgp_adj_in_remove (rn, adj);
bgp_unlock_node (rn);
if (adj->peer == peer && adj->addpath_rx_id == addpath_id) {
bgp_adj_in_remove(rn, adj);
bgp_unlock_node(rn);
}
adj = adj_next;
@ -251,41 +231,39 @@ bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer,
return 1;
}
void
bgp_sync_init (struct peer *peer)
void bgp_sync_init(struct peer *peer)
{
afi_t afi;
safi_t safi;
struct bgp_synchronize *sync;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
sync = XCALLOC (MTYPE_BGP_SYNCHRONISE,
sizeof (struct bgp_synchronize));
BGP_ADV_FIFO_INIT (&sync->update);
BGP_ADV_FIFO_INIT (&sync->withdraw);
BGP_ADV_FIFO_INIT (&sync->withdraw_low);
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
sync = XCALLOC(MTYPE_BGP_SYNCHRONISE,
sizeof(struct bgp_synchronize));
BGP_ADV_FIFO_INIT(&sync->update);
BGP_ADV_FIFO_INIT(&sync->withdraw);
BGP_ADV_FIFO_INIT(&sync->withdraw_low);
peer->sync[afi][safi] = sync;
peer->hash[afi][safi] = hash_create (baa_hash_key, baa_hash_cmp, NULL);
peer->hash[afi][safi] =
hash_create(baa_hash_key, baa_hash_cmp, NULL);
}
}
void
bgp_sync_delete (struct peer *peer)
void bgp_sync_delete(struct peer *peer)
{
afi_t afi;
safi_t safi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
if (peer->sync[afi][safi])
XFREE (MTYPE_BGP_SYNCHRONISE, peer->sync[afi][safi]);
XFREE(MTYPE_BGP_SYNCHRONISE,
peer->sync[afi][safi]);
peer->sync[afi][safi] = NULL;
if (peer->hash[afi][safi])
hash_free (peer->hash[afi][safi]);
hash_free(peer->hash[afi][safi]);
peer->hash[afi][safi] = NULL;
}
}

View File

@ -26,16 +26,14 @@
struct update_subgroup;
/* BGP advertise FIFO. */
struct bgp_advertise_fifo
{
struct bgp_advertise_fifo {
struct bgp_advertise *next;
struct bgp_advertise *prev;
u_int32_t count;
};
/* BGP advertise attribute. */
struct bgp_advertise_attr
{
struct bgp_advertise_attr {
/* Head of advertisement pointer. */
struct bgp_advertise *adv;
@ -46,8 +44,7 @@ struct bgp_advertise_attr
struct attr *attr;
};
struct bgp_advertise
{
struct bgp_advertise {
/* FIFO for advertisement. */
struct bgp_advertise_fifo fifo;
@ -69,8 +66,7 @@ struct bgp_advertise
};
/* BGP adjacency out. */
struct bgp_adj_out
{
struct bgp_adj_out {
/* Lined list pointer. */
struct bgp_adj_out *next;
struct bgp_adj_out *prev;
@ -94,8 +90,7 @@ struct bgp_adj_out
};
/* BGP adjacency in. */
struct bgp_adj_in
{
struct bgp_adj_in {
/* Linked list pointer. */
struct bgp_adj_in *next;
struct bgp_adj_in *prev;
@ -111,15 +106,14 @@ struct bgp_adj_in
};
/* BGP advertisement list. */
struct bgp_synchronize
{
struct bgp_synchronize {
struct bgp_advertise_fifo update;
struct bgp_advertise_fifo withdraw;
struct bgp_advertise_fifo withdraw_low;
};
/* BGP adjacency linked list. */
#define BGP_INFO_ADD(N,A,TYPE) \
#define BGP_INFO_ADD(N, A, TYPE) \
do { \
(A)->prev = NULL; \
(A)->next = (N)->TYPE; \
@ -128,7 +122,7 @@ struct bgp_synchronize
(N)->TYPE = (A); \
} while (0)
#define BGP_INFO_DEL(N,A,TYPE) \
#define BGP_INFO_DEL(N, A, TYPE) \
do { \
if ((A)->next) \
(A)->next->prev = (A)->prev; \
@ -161,37 +155,39 @@ struct bgp_synchronize
(F)->count = 0; \
} while (0)
#define BGP_ADV_FIFO_COUNT(F) \
(F)->count
#define BGP_ADV_FIFO_COUNT(F) (F)->count
#define BGP_ADV_FIFO_EMPTY(F) \
(((struct bgp_advertise_fifo *)(F))->next == (struct bgp_advertise *)(F))
(((struct bgp_advertise_fifo *)(F))->next \
== (struct bgp_advertise *)(F))
#define BGP_ADV_FIFO_HEAD(F) \
((((struct bgp_advertise_fifo *)(F))->next == (struct bgp_advertise *)(F)) \
? NULL : (F)->next)
((((struct bgp_advertise_fifo *)(F))->next \
== (struct bgp_advertise *)(F)) \
? NULL \
: (F)->next)
/* Prototypes. */
extern int bgp_adj_out_lookup (struct peer *, struct bgp_node *, u_int32_t);
extern void bgp_adj_in_set (struct bgp_node *, struct peer *, struct attr *, u_int32_t);
extern int bgp_adj_in_unset (struct bgp_node *, struct peer *, u_int32_t);
extern void bgp_adj_in_remove (struct bgp_node *, struct bgp_adj_in *);
extern int bgp_adj_out_lookup(struct peer *, struct bgp_node *, u_int32_t);
extern void bgp_adj_in_set(struct bgp_node *, struct peer *, struct attr *,
u_int32_t);
extern int bgp_adj_in_unset(struct bgp_node *, struct peer *, u_int32_t);
extern void bgp_adj_in_remove(struct bgp_node *, struct bgp_adj_in *);
extern void bgp_sync_init (struct peer *);
extern void bgp_sync_delete (struct peer *);
extern unsigned int baa_hash_key (void *p);
extern int baa_hash_cmp (const void *p1, const void *p2);
extern void bgp_advertise_add (struct bgp_advertise_attr *baa,
extern void bgp_sync_init(struct peer *);
extern void bgp_sync_delete(struct peer *);
extern unsigned int baa_hash_key(void *p);
extern int baa_hash_cmp(const void *p1, const void *p2);
extern void bgp_advertise_add(struct bgp_advertise_attr *baa,
struct bgp_advertise *adv);
extern struct bgp_advertise *bgp_advertise_new (void);
extern void bgp_advertise_free (struct bgp_advertise *adv);
extern struct bgp_advertise_attr *
bgp_advertise_intern (struct hash *hash, struct attr *attr);
extern struct bgp_advertise_attr *baa_new (void);
extern void
bgp_advertise_delete (struct bgp_advertise_attr *baa,
extern struct bgp_advertise *bgp_advertise_new(void);
extern void bgp_advertise_free(struct bgp_advertise *adv);
extern struct bgp_advertise_attr *bgp_advertise_intern(struct hash *hash,
struct attr *attr);
extern struct bgp_advertise_attr *baa_new(void);
extern void bgp_advertise_delete(struct bgp_advertise_attr *baa,
struct bgp_advertise *adv);
extern void
bgp_advertise_unintern (struct hash *hash, struct bgp_advertise_attr *baa);
extern void bgp_advertise_unintern(struct hash *hash,
struct bgp_advertise_attr *baa);
#endif /* _QUAGGA_BGP_ADVERTISE_H */

File diff suppressed because it is too large Load Diff

View File

@ -44,12 +44,11 @@
#define BGP_AS_TRANS 23456U
#define BGP_AS_IS_PRIVATE(ASN) \
(((ASN) >= BGP_PRIVATE_AS_MIN && (ASN) <= BGP_PRIVATE_AS_MAX) || \
((ASN) >= BGP_PRIVATE_AS4_MIN && (ASN) <= BGP_PRIVATE_AS4_MAX))
(((ASN) >= BGP_PRIVATE_AS_MIN && (ASN) <= BGP_PRIVATE_AS_MAX) \
|| ((ASN) >= BGP_PRIVATE_AS4_MIN && (ASN) <= BGP_PRIVATE_AS4_MAX))
/* AS_PATH segment data in abstracted form, no limit is placed on length */
struct assegment
{
struct assegment {
struct assegment *next;
as_t *as;
u_short length;
@ -57,8 +56,7 @@ struct assegment
};
/* AS path may be include some AsSegments. */
struct aspath
{
struct aspath {
/* Reference count to this aspath. */
unsigned long refcnt;
@ -77,53 +75,57 @@ struct aspath
#define ASPATH_STR_DEFAULT_LEN 32
/* Prototypes. */
extern void aspath_init (void);
extern void aspath_finish (void);
extern struct aspath *aspath_parse (struct stream *, size_t, int);
extern struct aspath *aspath_dup (struct aspath *);
extern struct aspath *aspath_aggregate (struct aspath *, struct aspath *);
extern struct aspath *aspath_prepend (struct aspath *, struct aspath *);
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 (struct aspath *, as_t);
extern struct aspath *aspath_add_confed_seq (struct aspath *, as_t);
extern int aspath_cmp (const void *, const void *);
extern int aspath_cmp_left (const struct aspath *, const struct aspath *);
extern int aspath_cmp_left_confed (const struct aspath *, const struct aspath *);
extern struct aspath *aspath_delete_confed_seq (struct aspath *);
extern struct aspath *aspath_empty (void);
extern struct aspath *aspath_empty_get (void);
extern struct aspath *aspath_str2aspath (const char *);
extern void aspath_free (struct aspath *);
extern struct aspath *aspath_intern (struct aspath *);
extern void aspath_unintern (struct aspath **);
extern const char *aspath_print (struct aspath *);
extern void aspath_print_vty (struct vty *, const char *, struct aspath *, const char *);
extern void aspath_print_all_vty (struct vty *);
extern unsigned int aspath_key_make (void *);
extern unsigned int aspath_get_first_as (struct aspath *);
extern unsigned int aspath_get_last_as (struct aspath *);
extern int aspath_loop_check (struct aspath *, as_t);
extern int aspath_private_as_check (struct aspath *);
extern int aspath_single_asn_check (struct aspath *, as_t asn);
extern struct aspath *aspath_replace_specific_asn (struct aspath *aspath, as_t target_asn, as_t our_asn);
extern struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn);
extern struct aspath *aspath_remove_private_asns (struct aspath *aspath);
extern int aspath_firstas_check (struct aspath *, as_t);
extern int aspath_confed_check (struct aspath *);
extern int aspath_left_confed_check (struct aspath *);
extern unsigned long aspath_count (void);
extern unsigned int aspath_count_hops (const struct aspath *);
extern unsigned int aspath_count_confeds (struct aspath *);
extern unsigned int aspath_size (struct aspath *);
extern as_t aspath_highest (struct aspath *);
extern as_t aspath_leftmost (struct aspath *);
extern size_t aspath_put (struct stream *, struct aspath *, int);
extern void aspath_init(void);
extern void aspath_finish(void);
extern struct aspath *aspath_parse(struct stream *, size_t, int);
extern struct aspath *aspath_dup(struct aspath *);
extern struct aspath *aspath_aggregate(struct aspath *, struct aspath *);
extern struct aspath *aspath_prepend(struct aspath *, struct aspath *);
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(struct aspath *, as_t);
extern struct aspath *aspath_add_confed_seq(struct aspath *, as_t);
extern int aspath_cmp(const void *, const void *);
extern int aspath_cmp_left(const struct aspath *, const struct aspath *);
extern int aspath_cmp_left_confed(const struct aspath *, const struct aspath *);
extern struct aspath *aspath_delete_confed_seq(struct aspath *);
extern struct aspath *aspath_empty(void);
extern struct aspath *aspath_empty_get(void);
extern struct aspath *aspath_str2aspath(const char *);
extern void aspath_free(struct aspath *);
extern struct aspath *aspath_intern(struct aspath *);
extern void aspath_unintern(struct aspath **);
extern const char *aspath_print(struct aspath *);
extern void aspath_print_vty(struct vty *, const char *, struct aspath *,
const char *);
extern void aspath_print_all_vty(struct vty *);
extern unsigned int aspath_key_make(void *);
extern unsigned int aspath_get_first_as(struct aspath *);
extern unsigned int aspath_get_last_as(struct aspath *);
extern int aspath_loop_check(struct aspath *, as_t);
extern int aspath_private_as_check(struct aspath *);
extern int aspath_single_asn_check(struct aspath *, as_t asn);
extern struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
as_t target_asn,
as_t our_asn);
extern struct aspath *aspath_replace_private_asns(struct aspath *aspath,
as_t asn);
extern struct aspath *aspath_remove_private_asns(struct aspath *aspath);
extern int aspath_firstas_check(struct aspath *, as_t);
extern int aspath_confed_check(struct aspath *);
extern int aspath_left_confed_check(struct aspath *);
extern unsigned long aspath_count(void);
extern unsigned int aspath_count_hops(const struct aspath *);
extern unsigned int aspath_count_confeds(struct aspath *);
extern unsigned int aspath_size(struct aspath *);
extern as_t aspath_highest(struct aspath *);
extern as_t aspath_leftmost(struct aspath *);
extern size_t aspath_put(struct stream *, struct aspath *, int);
extern struct aspath *aspath_reconcile_as4 (struct aspath *, struct aspath *);
extern unsigned int aspath_has_as4 (struct aspath *);
extern struct aspath *aspath_reconcile_as4(struct aspath *, struct aspath *);
extern unsigned int aspath_has_as4(struct aspath *);
/* For SNMP BGP4PATHATTRASPATHSEGMENT, might be useful for debug */
extern u_char *aspath_snmp_pathseg (struct aspath *, size_t *);
extern u_char *aspath_snmp_pathseg(struct aspath *, size_t *);
#endif /* _QUAGGA_BGP_ASPATH_H */

File diff suppressed because it is too large Load Diff

View File

@ -28,14 +28,13 @@
#define BITMAP_NBBY 8
#define SET_BITMAP(MAP, NUM) \
SET_FLAG (MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY))
SET_FLAG(MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY))
#define CHECK_BITMAP(MAP, NUM) \
CHECK_FLAG (MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY))
CHECK_FLAG(MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY))
#define BGP_MED_MAX UINT32_MAX
/* BGP Attribute type range. */
#define BGP_ATTR_TYPE_RANGE 256
#define BGP_ATTR_BITMAP_SIZE (BGP_ATTR_TYPE_RANGE / BITMAP_NBBY)
@ -92,15 +91,13 @@ struct bgp_tea_options {
#endif
/* Overlay Index Info */
struct overlay_index
{
struct overlay_index {
struct eth_segment_id eth_s_id;
union gw_addr gw_ip;
};
/* BGP core attribute structure. */
struct attr
{
struct attr {
/* AS Path structure */
struct aspath *aspath;
@ -197,16 +194,14 @@ struct attr
#define BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED (1 << 6)
/* Router Reflector related structure. */
struct cluster_list
{
struct cluster_list {
unsigned long refcnt;
int length;
struct in_addr *list;
};
/* Unknown transit attribute. */
struct transit
{
struct transit {
unsigned long refcnt;
int length;
u_char *val;
@ -215,58 +210,61 @@ struct transit
#define ATTR_FLAG_BIT(X) (1ULL << ((X) - 1))
#define BGP_CLUSTER_LIST_LENGTH(attr) \
(((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) ? \
(attr)->cluster->length : 0)
(((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) \
? (attr)->cluster->length \
: 0)
typedef enum {
BGP_ATTR_PARSE_PROCEED = 0,
BGP_ATTR_PARSE_ERROR = -1,
BGP_ATTR_PARSE_WITHDRAW = -2,
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR */
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR
*/
BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3,
} bgp_attr_parse_ret_t;
struct bpacket_attr_vec_arr;
/* Prototypes. */
extern void bgp_attr_init (void);
extern void bgp_attr_finish (void);
extern bgp_attr_parse_ret_t bgp_attr_parse (struct peer *, struct attr *,
extern void bgp_attr_init(void);
extern void bgp_attr_finish(void);
extern bgp_attr_parse_ret_t bgp_attr_parse(struct peer *, struct attr *,
bgp_size_t, struct bgp_nlri *,
struct bgp_nlri *);
extern void bgp_attr_dup (struct attr *, struct attr *);
extern void bgp_attr_deep_dup (struct attr *, struct attr *);
extern void bgp_attr_deep_free (struct attr *);
extern struct attr *bgp_attr_intern (struct attr *attr);
extern struct attr *bgp_attr_refcount (struct attr *attr);
extern void bgp_attr_unintern_sub (struct attr *);
extern void bgp_attr_unintern (struct attr **);
extern void bgp_attr_flush (struct attr *);
extern struct attr *bgp_attr_default_set (struct attr *attr, u_char);
extern struct attr *bgp_attr_aggregate_intern (struct bgp *, u_char,
extern void bgp_attr_dup(struct attr *, struct attr *);
extern void bgp_attr_deep_dup(struct attr *, struct attr *);
extern void bgp_attr_deep_free(struct attr *);
extern struct attr *bgp_attr_intern(struct attr *attr);
extern struct attr *bgp_attr_refcount(struct attr *attr);
extern void bgp_attr_unintern_sub(struct attr *);
extern void bgp_attr_unintern(struct attr **);
extern void bgp_attr_flush(struct attr *);
extern struct attr *bgp_attr_default_set(struct attr *attr, u_char);
extern struct attr *bgp_attr_aggregate_intern(struct bgp *, u_char,
struct aspath *,
struct community *, int as_set, u_char);
extern bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *,
struct community *, int as_set,
u_char);
extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
struct stream *, struct attr *,
struct bpacket_attr_vec_arr *vecarr,
struct prefix *, afi_t, safi_t,
struct peer *, struct prefix_rd *,
mpls_label_t *, int, u_int32_t);
extern void bgp_dump_routes_attr (struct stream *, struct attr *,
extern void bgp_dump_routes_attr(struct stream *, struct attr *,
struct prefix *);
extern int attrhash_cmp (const void *, const void *);
extern unsigned int attrhash_key_make (void *);
extern void attr_show_all (struct vty *);
extern unsigned long int attr_count (void);
extern unsigned long int attr_unknown_count (void);
extern int attrhash_cmp(const void *, const void *);
extern unsigned int attrhash_key_make(void *);
extern void attr_show_all(struct vty *);
extern unsigned long int attr_count(void);
extern unsigned long int attr_unknown_count(void);
/* Cluster list prototypes. */
extern int cluster_loop_check (struct cluster_list *, struct in_addr);
extern void cluster_unintern (struct cluster_list *);
extern int cluster_loop_check(struct cluster_list *, struct in_addr);
extern void cluster_unintern(struct cluster_list *);
/* Transit attribute prototypes. */
void transit_unintern (struct transit *);
void transit_unintern(struct transit *);
/* Below exported for unit-test purposes only */
struct bgp_attr_parser_args {
@ -278,16 +276,15 @@ struct bgp_attr_parser_args {
u_int8_t flags;
u_char *startp;
};
extern int bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
extern int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
struct bgp_nlri *);
extern int bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
extern int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
struct bgp_nlri *);
extern struct bgp_attr_encap_subtlv *
encap_tlv_dup(struct bgp_attr_encap_subtlv *orig);
extern void
bgp_attr_flush_encap(struct attr *attr);
extern void bgp_attr_flush_encap(struct attr *attr);
/**
* Set of functions to encode MP_REACH_NLRI and MP_UNREACH_NLRI attributes.
@ -302,33 +299,36 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer,
extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
struct prefix *p, struct prefix_rd *prd,
mpls_label_t *label, int addpath_encode,
u_int32_t addpath_tx_id,
struct attr *);
u_int32_t addpath_tx_id, struct attr *);
extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
struct prefix *p);
extern void bgp_packet_mpattr_end(struct stream *s, size_t sizep);
extern size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi,
extern size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi,
safi_t safi);
extern void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
afi_t afi, safi_t safi, struct prefix_rd *prd,
mpls_label_t *, int, u_int32_t, struct attr *);
extern void bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt);
extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p,
afi_t afi, safi_t safi,
struct prefix_rd *prd, mpls_label_t *,
int, u_int32_t, struct attr *);
extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt);
static inline int
bgp_rmap_nhop_changed(u_int32_t out_rmap_flags, u_int32_t in_rmap_flags)
static inline int bgp_rmap_nhop_changed(u_int32_t out_rmap_flags,
u_int32_t in_rmap_flags)
{
return ((CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_PEER_ADDRESS) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV4_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_LL_NHOP_CHANGED) ||
CHECK_FLAG(in_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED)) ? 1 : 0);
return ((CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_PEER_ADDRESS)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV4_NHOP_CHANGED)
|| CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED)
|| CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_LL_NHOP_CHANGED)
|| CHECK_FLAG(in_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED))
? 1
: 0);
}
static inline u_int32_t
mac_mobility_seqnum (struct attr *attr)
static inline u_int32_t mac_mobility_seqnum(struct attr *attr)
{
return (attr) ? attr->mm_seqnum : 0;
}

View File

@ -46,7 +46,7 @@ void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac)
if (!attr->ecommunity)
attr->ecommunity = ecommunity_new();
ecommunity_add_val(attr->ecommunity, &routermac_ecom);
ecommunity_str (attr->ecommunity);
ecommunity_str(attr->ecommunity);
}
/* converts to an esi
@ -61,10 +61,9 @@ int str2esi(const char *str, struct eth_segment_id *id)
if (!str)
return 0;
if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x",
a + 0, a + 1, a + 2, a + 3, a + 4, a + 5,
a + 6, a + 7, a + 8, a + 9) != ESI_LEN)
{
if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1,
a + 2, a + 3, a + 4, a + 5, a + 6, a + 7, a + 8, a + 9)
!= ESI_LEN) {
/* error in incoming str length */
return 0;
}
@ -85,12 +84,13 @@ char *esi2str(struct eth_segment_id *id)
return NULL;
val = id->val;
ptr = (char *)XMALLOC(MTYPE_TMP, (ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char));
ptr = (char *)XMALLOC(MTYPE_TMP,
(ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char));
snprintf(ptr, (ESI_LEN * 2 + ESI_LEN - 1 + 1),
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
val[0], val[1], val[2], val[3], val[4],
val[5], val[6], val[7], val[8], val[9]);
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", val[0],
val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8],
val[9]);
return ptr;
}
@ -109,8 +109,7 @@ char *ecom_mac2str(char *ecom_mac)
* Fetch and return the sequence number from MAC Mobility extended
* community, if present, else 0.
*/
u_int32_t
bgp_attr_mac_mobility_seqnum (struct attr *attr, u_char *sticky)
u_int32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, u_char *sticky)
{
struct ecommunity *ecom;
int i;
@ -126,8 +125,7 @@ bgp_attr_mac_mobility_seqnum (struct attr *attr, u_char *sticky)
* communities for the same route. We will bail out upon the first
* one.
*/
for (i = 0; i < ecom->size; i++)
{
for (i = 0; i < ecom->size; i++) {
u_char *pnt;
u_char type, sub_type;
u_int32_t seq_num;
@ -135,8 +133,8 @@ bgp_attr_mac_mobility_seqnum (struct attr *attr, u_char *sticky)
pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
type = *pnt++;
sub_type = *pnt++;
if (!(type == ECOMMUNITY_ENCODE_EVPN &&
sub_type == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY))
if (!(type == ECOMMUNITY_ENCODE_EVPN
&& sub_type == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY))
continue;
flags = *pnt++;
@ -158,8 +156,8 @@ bgp_attr_mac_mobility_seqnum (struct attr *attr, u_char *sticky)
}
/* dst prefix must be AF_INET or AF_INET6 prefix, to forge EVPN prefix */
extern int
bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst)
extern int bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag,
struct prefix *dst)
{
struct evpn_addr *p_evpn_p;
struct prefix p2;
@ -177,15 +175,15 @@ bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst)
p_evpn_p->eth_tag = eth_tag;
p_evpn_p->ip_prefix_length = p2.prefixlen;
if (src->family == AF_INET) {
SET_IPADDR_V4 (&p_evpn_p->ip);
SET_IPADDR_V4(&p_evpn_p->ip);
memcpy(&p_evpn_p->ip.ipaddr_v4, &src->u.prefix4,
sizeof(struct in_addr));
dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4;
dst->prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV4;
} else {
SET_IPADDR_V6 (&p_evpn_p->ip);
SET_IPADDR_V6(&p_evpn_p->ip);
memcpy(&p_evpn_p->ip.ipaddr_v6, &src->u.prefix6,
sizeof(struct in6_addr));
dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV6;
dst->prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV6;
}
} else
return -1;

View File

@ -29,7 +29,6 @@
#define ESI_TYPE_ROUTER 4 /* <RouterId-4B>:<Local Discriminator Value-4B> */
#define ESI_TYPE_AS 5 /* <AS-4B>:<Local Discriminator Value-4B> */
#define MAX_ESI {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}
#define ESI_LEN 10
@ -38,19 +37,16 @@
u_long eth_tag_id;
struct attr;
struct eth_segment_id
{
struct eth_segment_id {
u_char val[ESI_LEN];
};
union gw_addr
{
union gw_addr {
struct in_addr ipv4;
struct in6_addr ipv6;
};
struct bgp_route_evpn
{
struct bgp_route_evpn {
struct eth_segment_id eth_s_id;
union gw_addr gw_ip;
};
@ -59,11 +55,12 @@ extern int str2esi(const char *str, struct eth_segment_id *id);
extern char *esi2str(struct eth_segment_id *id);
extern char *ecom_mac2str(char *ecom_mac);
extern void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac);
extern void bgp_add_routermac_ecom(struct attr *attr,
struct ethaddr *routermac);
extern int bgp_build_evpn_prefix(int type, uint32_t eth_tag,
struct prefix *dst);
extern u_int32_t
bgp_attr_mac_mobility_seqnum (struct attr *attr, u_char *sticky);
extern u_int32_t bgp_attr_mac_mobility_seqnum(struct attr *attr,
u_char *sticky);
#endif /* _QUAGGA_BGP_ATTR_EVPN_H */

View File

@ -43,11 +43,11 @@
extern struct zclient *zclient;
/*
* bgp_bfd_peer_group2peer_copy - Copy the BFD information from peer group template
* bgp_bfd_peer_group2peer_copy - Copy the BFD information from peer group
* template
* to peer.
*/
void
bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
void bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
{
struct bfd_info *bfd_info;
struct bfd_info *conf_bfd_info;
@ -69,10 +69,10 @@ bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
}
/*
* bgp_bfd_is_peer_multihop - returns whether BFD peer is multi-hop or single hop.
* bgp_bfd_is_peer_multihop - returns whether BFD peer is multi-hop or single
* hop.
*/
int
bgp_bfd_is_peer_multihop(struct peer *peer)
int bgp_bfd_is_peer_multihop(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -81,9 +81,9 @@ bgp_bfd_is_peer_multihop(struct peer *peer)
if (!bfd_info)
return 0;
if((bfd_info->type == BFD_TYPE_MULTIHOP) ||
((peer->sort == BGP_PEER_IBGP) && !peer->shared_network) ||
is_ebgp_multihop_configured(peer))
if ((bfd_info->type == BFD_TYPE_MULTIHOP)
|| ((peer->sort == BGP_PEER_IBGP) && !peer->shared_network)
|| is_ebgp_multihop_configured(peer))
return 1;
else
return 0;
@ -93,8 +93,7 @@ bgp_bfd_is_peer_multihop(struct peer *peer)
* bgp_bfd_peer_sendmsg - Format and send a Peer register/Unregister
* command to Zebra to be forwarded to BFD
*/
static void
bgp_bfd_peer_sendmsg (struct peer *peer, int command)
static void bgp_bfd_peer_sendmsg(struct peer *peer, int command)
{
struct bfd_info *bfd_info;
vrf_id_t vrf_id = VRF_DEFAULT;
@ -105,28 +104,27 @@ bgp_bfd_peer_sendmsg (struct peer *peer, int command)
if (peer->bgp && (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VRF))
vrf_id = peer->bgp->vrf_id;
if (command == ZEBRA_BFD_DEST_DEREGISTER)
{
multihop = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
if (command == ZEBRA_BFD_DEST_DEREGISTER) {
multihop =
CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
UNSET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
}
else
{
} else {
multihop = bgp_bfd_is_peer_multihop(peer);
if ((command == ZEBRA_BFD_DEST_REGISTER) && multihop)
SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
}
if (peer->su.sa.sa_family == AF_INET)
bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
&peer->su.sin.sin_addr,
bfd_peer_sendmsg(
zclient, bfd_info, AF_INET, &peer->su.sin.sin_addr,
(peer->su_local) ? &peer->su_local->sin.sin_addr : NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
peer->ttl, multihop, command, 1, vrf_id);
else if (peer->su.sa.sa_family == AF_INET6)
bfd_peer_sendmsg (zclient, bfd_info, AF_INET6,
&peer->su.sin6.sin6_addr,
(peer->su_local) ? &peer->su_local->sin6.sin6_addr : NULL,
bfd_peer_sendmsg(
zclient, bfd_info, AF_INET6, &peer->su.sin6.sin6_addr,
(peer->su_local) ? &peer->su_local->sin6.sin6_addr
: NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
peer->ttl, multihop, command, 1, vrf_id);
}
@ -135,8 +133,7 @@ bgp_bfd_peer_sendmsg (struct peer *peer, int command)
* bgp_bfd_register_peer - register a peer with BFD through zebra
* for monitoring the peer rechahability.
*/
void
bgp_bfd_register_peer (struct peer *peer)
void bgp_bfd_register_peer(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -144,7 +141,8 @@ bgp_bfd_register_peer (struct peer *peer)
return;
bfd_info = (struct bfd_info *)peer->bfd_info;
/* Check if BFD is enabled and peer has already been registered with BFD */
/* Check if BFD is enabled and peer has already been registered with BFD
*/
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
return;
@ -156,8 +154,7 @@ bgp_bfd_register_peer (struct peer *peer)
* for stopping the monitoring of the peer
* rechahability.
*/
void
bgp_bfd_deregister_peer (struct peer *peer)
void bgp_bfd_deregister_peer(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -179,8 +176,7 @@ bgp_bfd_deregister_peer (struct peer *peer)
* bgp_bfd_update_peer - update peer with BFD with new BFD paramters
* through zebra.
*/
static void
bgp_bfd_update_peer (struct peer *peer)
static void bgp_bfd_update_peer(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -198,8 +194,7 @@ bgp_bfd_update_peer (struct peer *peer)
/*
* bgp_bfd_update_type - update session type with BFD through zebra.
*/
static void
bgp_bfd_update_type (struct peer *peer)
static void bgp_bfd_update_type(struct peer *peer)
{
struct bfd_info *bfd_info;
int multihop;
@ -212,23 +207,23 @@ bgp_bfd_update_type (struct peer *peer)
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
return;
if (bfd_info->type == BFD_TYPE_NOT_CONFIGURED)
{
if (bfd_info->type == BFD_TYPE_NOT_CONFIGURED) {
multihop = bgp_bfd_is_peer_multihop(peer);
if ((multihop && !CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)) ||
(!multihop && CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)))
{
if ((multihop
&& !CHECK_FLAG(bfd_info->flags,
BFD_FLAG_BFD_TYPE_MULTIHOP))
|| (!multihop && CHECK_FLAG(bfd_info->flags,
BFD_FLAG_BFD_TYPE_MULTIHOP))) {
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
}
}
else
{
if ((bfd_info->type == BFD_TYPE_MULTIHOP &&
!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)) ||
(bfd_info->type == BFD_TYPE_SINGLEHOP &&
CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)))
{
} else {
if ((bfd_info->type == BFD_TYPE_MULTIHOP
&& !CHECK_FLAG(bfd_info->flags,
BFD_FLAG_BFD_TYPE_MULTIHOP))
|| (bfd_info->type == BFD_TYPE_SINGLEHOP
&& CHECK_FLAG(bfd_info->flags,
BFD_FLAG_BFD_TYPE_MULTIHOP))) {
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
}
@ -239,15 +234,14 @@ bgp_bfd_update_type (struct peer *peer)
* bgp_bfd_dest_replay - Replay all the peers that have BFD enabled
* to zebra
*/
static int
bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length,
vrf_id_t vrf_id)
static int bgp_bfd_dest_replay(int command, struct zclient *client,
zebra_size_t length, vrf_id_t vrf_id)
{
struct listnode *mnode, *node, *nnode;
struct bgp *bgp;
struct peer *peer;
if (BGP_DEBUG (zebra, ZEBRA))
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Zebra: BFD Dest replay request");
/* Send the client registration */
@ -255,9 +249,8 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length,
/* Replay the peer, if BFD is enabled in BGP */
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
for (ALL_LIST_ELEMENTS_RO(bm->bgp, mnode, bgp))
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
bgp_bfd_update_peer(peer);
}
@ -266,10 +259,10 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length,
/*
* bgp_bfd_peer_status_update - Update the BFD status if it has changed. Bring
* down the peer if the BFD session went down from * up.
* down the peer if the BFD session went down from
* * up.
*/
static void
bgp_bfd_peer_status_update (struct peer *peer, int status)
static void bgp_bfd_peer_status_update(struct peer *peer, int status)
{
struct bfd_info *bfd_info;
int old_status;
@ -283,10 +276,9 @@ bgp_bfd_peer_status_update (struct peer *peer, int status)
bfd_info->status = status;
bfd_info->last_update = bgp_clock();
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
{
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP)) {
peer->last_reset = PEER_DOWN_BFD_DOWN;
BGP_EVENT_ADD (peer, BGP_Stop);
BGP_EVENT_ADD(peer, BGP_Stop);
}
}
@ -295,8 +287,7 @@ bgp_bfd_peer_status_update (struct peer *peer, int status)
* has changed and bring down the peer
* connectivity if the BFD session went down.
*/
static int
bgp_bfd_dest_update (int command, struct zclient *zclient,
static int bgp_bfd_dest_update(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp;
@ -304,22 +295,22 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
struct prefix sp;
int status;
ifp = bfd_get_peer_info (zclient->ibuf, &dp, &sp, &status, vrf_id);
ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status, vrf_id);
if (BGP_DEBUG (zebra, ZEBRA))
{
if (BGP_DEBUG(zebra, ZEBRA)) {
char buf[2][PREFIX2STR_BUFFER];
prefix2str(&dp, buf[0], sizeof(buf[0]));
if (ifp)
{
zlog_debug("Zebra: vrf %d interface %s bfd destination %s %s",
vrf_id, ifp->name, buf[0], bfd_get_status_str(status));
}
else
{
if (ifp) {
zlog_debug(
"Zebra: vrf %d interface %s bfd destination %s %s",
vrf_id, ifp->name, buf[0],
bfd_get_status_str(status));
} else {
prefix2str(&sp, buf[1], sizeof(buf[1]));
zlog_debug("Zebra: vrf %d source %s bfd destination %s %s",
vrf_id, buf[1], buf[0], bfd_get_status_str(status));
zlog_debug(
"Zebra: vrf %d source %s bfd destination %s %s",
vrf_id, buf[1], buf[0],
bfd_get_status_str(status));
}
}
@ -329,56 +320,59 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
struct bgp *bgp;
struct peer *peer;
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
for (ALL_LIST_ELEMENTS_RO(bm->bgp, mnode, bgp))
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (!peer->bfd_info)
continue;
if ((dp.family == AF_INET) && (peer->su.sa.sa_family == AF_INET))
{
if (dp.u.prefix4.s_addr != peer->su.sin.sin_addr.s_addr)
if ((dp.family == AF_INET)
&& (peer->su.sa.sa_family == AF_INET)) {
if (dp.u.prefix4.s_addr
!= peer->su.sin.sin_addr.s_addr)
continue;
}
else if ((dp.family == AF_INET6) &&
(peer->su.sa.sa_family == AF_INET6))
{
if (memcmp(&dp.u.prefix6, &peer->su.sin6.sin6_addr,
sizeof (struct in6_addr)))
} else if ((dp.family == AF_INET6)
&& (peer->su.sa.sa_family
== AF_INET6)) {
if (memcmp(&dp.u.prefix6,
&peer->su.sin6.sin6_addr,
sizeof(struct in6_addr)))
continue;
}
else
} else
continue;
if (ifp && (ifp == peer->nexthop.ifp))
{
bgp_bfd_peer_status_update(peer, status);
}
else
{
if (ifp && (ifp == peer->nexthop.ifp)) {
bgp_bfd_peer_status_update(peer,
status);
} else {
if (!peer->su_local)
continue;
if ((sp.family == AF_INET) &&
(peer->su_local->sa.sa_family == AF_INET))
{
if (sp.u.prefix4.s_addr != peer->su_local->sin.sin_addr.s_addr)
if ((sp.family == AF_INET)
&& (peer->su_local->sa.sa_family
== AF_INET)) {
if (sp.u.prefix4.s_addr
!= peer->su_local->sin
.sin_addr.s_addr)
continue;
}
else if ((sp.family == AF_INET6) &&
(peer->su_local->sa.sa_family == AF_INET6))
{
if (memcmp(&sp.u.prefix6, &peer->su_local->sin6.sin6_addr,
sizeof (struct in6_addr)))
} else if ((sp.family == AF_INET6)
&& (peer->su_local->sa
.sa_family
== AF_INET6)) {
if (memcmp(&sp.u.prefix6,
&peer->su_local->sin6
.sin6_addr,
sizeof(struct
in6_addr)))
continue;
}
else
} else
continue;
if ((vrf_id != VRF_DEFAULT) && (peer->bgp->vrf_id != vrf_id))
if ((vrf_id != VRF_DEFAULT)
&& (peer->bgp->vrf_id != vrf_id))
continue;
bgp_bfd_peer_status_update(peer, status);
bgp_bfd_peer_status_update(peer,
status);
}
}
}
@ -389,9 +383,9 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
/*
* bgp_bfd_peer_param_set - Set the configured BFD paramter values for peer.
*/
static int
bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
u_int8_t detect_mult, int defaults)
static int bgp_bfd_peer_param_set(struct peer *peer, u_int32_t min_rx,
u_int32_t min_tx, u_int8_t detect_mult,
int defaults)
{
struct peer_group *group;
struct listnode *node, *nnode;
@ -400,26 +394,23 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx,
detect_mult, defaults, &command);
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
command = 0;
bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx,
detect_mult, defaults, &command);
bfd_set_param((struct bfd_info **)&(peer->bfd_info),
min_rx, min_tx, detect_mult, defaults,
&command);
if ((peer->status == Established) &&
(command == ZEBRA_BFD_DEST_REGISTER))
if ((peer->status == Established)
&& (command == ZEBRA_BFD_DEST_REGISTER))
bgp_bfd_register_peer(peer);
else if (command == ZEBRA_BFD_DEST_UPDATE)
bgp_bfd_update_peer(peer);
}
}
else
{
if ((peer->status == Established) &&
(command == ZEBRA_BFD_DEST_REGISTER))
} else {
if ((peer->status == Established)
&& (command == ZEBRA_BFD_DEST_REGISTER))
bgp_bfd_register_peer(peer);
else if (command == ZEBRA_BFD_DEST_UPDATE)
bgp_bfd_update_peer(peer);
@ -428,10 +419,10 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
}
/*
* bgp_bfd_peer_param_unset - Delete the configured BFD paramter values for peer.
* bgp_bfd_peer_param_unset - Delete the configured BFD paramter values for
* peer.
*/
static int
bgp_bfd_peer_param_unset (struct peer *peer)
static int bgp_bfd_peer_param_unset(struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
@ -439,18 +430,14 @@ bgp_bfd_peer_param_unset (struct peer *peer)
if (!peer->bfd_info)
return 0;
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
bfd_info_free(&(peer->bfd_info));
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
bgp_bfd_deregister_peer(peer);
bfd_info_free(&(peer->bfd_info));
}
}
else
{
} else {
bgp_bfd_deregister_peer(peer);
bfd_info_free(&(peer->bfd_info));
}
@ -458,29 +445,17 @@ bgp_bfd_peer_param_unset (struct peer *peer)
}
/*
* bgp_bfd_peer_param_type_set - set the BFD session type (multihop or singlehop)
* bgp_bfd_peer_param_type_set - set the BFD session type (multihop or
* singlehop)
*/
static int
bgp_bfd_peer_param_type_set (struct peer *peer, enum bfd_sess_type type)
static int bgp_bfd_peer_param_type_set(struct peer *peer,
enum bfd_sess_type type)
{
struct peer_group *group;
struct listnode *node, *nnode;
int command = 0;
struct bfd_info *bfd_info;
if (!peer->bfd_info)
bfd_set_param((struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX,
BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, 1, &command);
bfd_info = (struct bfd_info *)peer->bfd_info;
bfd_info->type = type;
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
command = 0;
if (!peer->bfd_info)
bfd_set_param((struct bfd_info **)&(peer->bfd_info),
BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
@ -489,19 +464,28 @@ bgp_bfd_peer_param_type_set (struct peer *peer, enum bfd_sess_type type)
bfd_info = (struct bfd_info *)peer->bfd_info;
bfd_info->type = type;
if (peer->status == Established)
{
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
group = peer->group;
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
command = 0;
if (!peer->bfd_info)
bfd_set_param(
(struct bfd_info **)&(peer->bfd_info),
BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
BFD_DEF_DETECT_MULT, 1, &command);
bfd_info = (struct bfd_info *)peer->bfd_info;
bfd_info->type = type;
if (peer->status == Established) {
if (command == ZEBRA_BFD_DEST_REGISTER)
bgp_bfd_register_peer(peer);
else
bgp_bfd_update_type(peer);
}
}
}
else
{
if (peer->status == Established)
{
} else {
if (peer->status == Established) {
if (command == ZEBRA_BFD_DEST_REGISTER)
bgp_bfd_register_peer(peer);
else
@ -515,8 +499,7 @@ bgp_bfd_peer_param_type_set (struct peer *peer, enum bfd_sess_type type)
/*
* bgp_bfd_peer_config_write - Write the peer BFD configuration.
*/
void
bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
{
struct bfd_info *bfd_info;
@ -525,25 +508,26 @@ bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
bfd_info = (struct bfd_info *)peer->bfd_info;
if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
vty_out (vty, " neighbor %s bfd %d %d %d\n", addr,
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
vty_out(vty, " neighbor %s bfd %d %d %d\n", addr,
bfd_info->detect_mult, bfd_info->required_min_rx,
bfd_info->desired_min_tx);
if (bfd_info->type != BFD_TYPE_NOT_CONFIGURED)
vty_out (vty, " neighbor %s bfd %s\n", addr,
(bfd_info->type == BFD_TYPE_MULTIHOP) ? "multihop" : "singlehop");
vty_out(vty, " neighbor %s bfd %s\n", addr,
(bfd_info->type == BFD_TYPE_MULTIHOP) ? "multihop"
: "singlehop");
if (!CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG) &&
(bfd_info->type == BFD_TYPE_NOT_CONFIGURED))
vty_out (vty, " neighbor %s bfd\n", addr);
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)
&& (bfd_info->type == BFD_TYPE_NOT_CONFIGURED))
vty_out(vty, " neighbor %s bfd\n", addr);
}
/*
* bgp_bfd_show_info - Show the peer BFD information.
*/
void
bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh)
void bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json,
json_object *json_neigh)
{
bfd_show_info(vty, (struct bfd_info *)peer->bfd_info,
bgp_bfd_is_peer_multihop(peer), 0, use_json, json_neigh);
@ -560,17 +544,16 @@ DEFUN (neighbor_bfd,
struct peer *peer;
int ret;
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
ret = bgp_bfd_peer_param_set (peer, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
ret = bgp_bfd_peer_param_set(peer, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
BFD_DEF_DETECT_MULT, 1);
if (ret != 0)
return bgp_vty_return (vty, ret);
return bgp_vty_return(vty, ret);
return CMD_SUCCESS;
}
DEFUN (neighbor_bfd_param,
@ -593,20 +576,21 @@ DEFUN (neighbor_bfd_param,
u_int8_t dm_val;
int ret;
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if ((ret = bfd_validate_param (vty, argv[idx_number_1]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg, &dm_val,
&rx_val, &tx_val)) != CMD_SUCCESS)
if ((ret = bfd_validate_param(
vty, argv[idx_number_1]->arg, argv[idx_number_2]->arg,
argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
!= CMD_SUCCESS)
return ret;
ret = bgp_bfd_peer_param_set (peer, rx_val, tx_val, dm_val, 0);
ret = bgp_bfd_peer_param_set(peer, rx_val, tx_val, dm_val, 0);
if (ret != 0)
return bgp_vty_return (vty, ret);
return bgp_vty_return(vty, ret);
return CMD_SUCCESS;
}
DEFUN_HIDDEN (neighbor_bfd_type,
@ -624,7 +608,7 @@ DEFUN_HIDDEN (neighbor_bfd_type,
enum bfd_sess_type type;
int ret;
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
@ -635,9 +619,9 @@ DEFUN_HIDDEN (neighbor_bfd_type,
else
return CMD_WARNING_CONFIG_FAILED;
ret = bgp_bfd_peer_param_type_set (peer, type);
ret = bgp_bfd_peer_param_type_set(peer, type);
if (ret != 0)
return bgp_vty_return (vty, ret);
return bgp_vty_return(vty, ret);
return CMD_SUCCESS;
}
@ -657,13 +641,13 @@ DEFUN (no_neighbor_bfd,
struct peer *peer;
int ret;
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
ret = bgp_bfd_peer_param_unset(peer);
if (ret != 0)
return bgp_vty_return (vty, ret);
return bgp_vty_return(vty, ret);
return CMD_SUCCESS;
}
@ -683,8 +667,8 @@ DEFUN_HIDDEN (no_neighbor_bfd_type,
struct peer *peer;
int ret;
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (!peer->bfd_info)
@ -692,13 +676,12 @@ DEFUN_HIDDEN (no_neighbor_bfd_type,
ret = bgp_bfd_peer_param_type_set(peer, BFD_TYPE_NOT_CONFIGURED);
if (ret != 0)
return bgp_vty_return (vty, ret);
return bgp_vty_return(vty, ret);
return CMD_SUCCESS;
}
void
bgp_bfd_init(void)
void bgp_bfd_init(void)
{
bfd_gbl_init();
@ -707,9 +690,9 @@ bgp_bfd_init(void)
zclient->bfd_dest_replay = bgp_bfd_dest_replay;
/* "neighbor bfd" commands. */
install_element (BGP_NODE, &neighbor_bfd_cmd);
install_element (BGP_NODE, &neighbor_bfd_param_cmd);
install_element (BGP_NODE, &neighbor_bfd_type_cmd);
install_element (BGP_NODE, &no_neighbor_bfd_cmd);
install_element (BGP_NODE, &no_neighbor_bfd_type_cmd);
install_element(BGP_NODE, &neighbor_bfd_cmd);
install_element(BGP_NODE, &neighbor_bfd_param_cmd);
install_element(BGP_NODE, &neighbor_bfd_type_cmd);
install_element(BGP_NODE, &no_neighbor_bfd_cmd);
install_element(BGP_NODE, &no_neighbor_bfd_type_cmd);
}

View File

@ -23,25 +23,20 @@
#ifndef _QUAGGA_BGP_BFD_H
#define _QUAGGA_BGP_BFD_H
extern void
bgp_bfd_init(void);
extern void bgp_bfd_init(void);
extern void
bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer);
extern void bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer);
extern void
bgp_bfd_register_peer (struct peer *peer);
extern void bgp_bfd_register_peer(struct peer *peer);
extern void
bgp_bfd_deregister_peer (struct peer *peer);
extern void bgp_bfd_deregister_peer(struct peer *peer);
extern void
bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr);
extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer,
char *addr);
extern void
bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh);
extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer,
u_char use_json, json_object *json_neigh);
extern int
bgp_bfd_is_peer_multihop(struct peer *peer);
extern int bgp_bfd_is_peer_multihop(struct peer *peer);
#endif /* _QUAGGA_BGP_BFD_H */

View File

@ -35,15 +35,11 @@
#include "bgpd/bgp_aspath.h"
/* privileges */
static zebra_capabilities_t _caps_p [] =
{
ZCAP_BIND,
ZCAP_NET_RAW,
ZCAP_NET_ADMIN,
static zebra_capabilities_t _caps_p[] = {
ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN,
};
struct zebra_privs_t bgpd_privs =
{
struct zebra_privs_t bgpd_privs = {
#if defined(FRR_USER) && defined(FRR_GROUP)
.user = FRR_USER,
.group = FRR_GROUP,
@ -72,8 +68,7 @@ enum MRT_MSG_TYPES {
MSG_TABLE_DUMP /* routing table dump */
};
static int
attr_parse (struct stream *s, u_int16_t len)
static int attr_parse(struct stream *s, u_int16_t len)
{
u_int flag;
u_int type;
@ -82,49 +77,41 @@ attr_parse (struct stream *s, u_int16_t len)
lim = s->getp + len;
printf ("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim);
printf("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim);
while (s->getp < lim)
{
flag = stream_getc (s);
type = stream_getc (s);
while (s->getp < lim) {
flag = stream_getc(s);
type = stream_getc(s);
if (flag & BGP_ATTR_FLAG_EXTLEN)
length = stream_getw (s);
length = stream_getw(s);
else
length = stream_getc (s);
length = stream_getc(s);
printf ("FLAG: %d\n", flag);
printf ("TYPE: %d\n", type);
printf ("Len: %d\n", length);
printf("FLAG: %d\n", flag);
printf("TYPE: %d\n", type);
printf("Len: %d\n", length);
switch (type)
{
case BGP_ATTR_ORIGIN:
{
switch (type) {
case BGP_ATTR_ORIGIN: {
u_char origin;
origin = stream_getc (s);
printf ("ORIGIN: %d\n", origin);
}
break;
case BGP_ATTR_AS_PATH:
{
origin = stream_getc(s);
printf("ORIGIN: %d\n", origin);
} break;
case BGP_ATTR_AS_PATH: {
struct aspath *aspath;
aspath = aspath_parse (s, length, 1);
printf ("ASPATH: %s\n", aspath->str);
aspath = aspath_parse(s, length, 1);
printf("ASPATH: %s\n", aspath->str);
aspath_free(aspath);
}
break;
case BGP_ATTR_NEXT_HOP:
{
} break;
case BGP_ATTR_NEXT_HOP: {
struct in_addr nexthop;
nexthop.s_addr = stream_get_ipv4 (s);
printf ("NEXTHOP: %s\n", inet_ntoa (nexthop));
}
break;
nexthop.s_addr = stream_get_ipv4(s);
printf("NEXTHOP: %s\n", inet_ntoa(nexthop));
} break;
default:
stream_getw_from (s, length);
stream_getw_from(s, length);
break;
}
}
@ -132,8 +119,7 @@ attr_parse (struct stream *s, u_int16_t len)
return 0;
}
int
main (int argc, char **argv)
int main(int argc, char **argv)
{
int ret;
FILE *fp;
@ -151,164 +137,153 @@ main (int argc, char **argv)
u_int16_t viewno, seq_num;
struct prefix_ipv4 p;
s = stream_new (10000);
s = stream_new(10000);
if (argc != 2)
{
fprintf (stderr, "Usage: %s FILENAME\n", argv[0]);
exit (1);
if (argc != 2) {
fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
exit(1);
}
fp = fopen (argv[1], "r");
if (!fp)
{
fprintf (stdout,"%% Can't open configuration file %s due to '%s'.\n",
fp = fopen(argv[1], "r");
if (!fp) {
fprintf(stdout,
"%% Can't open configuration file %s due to '%s'.\n",
argv[1], safe_strerror(errno));
exit (1);
exit(1);
}
while (1)
{
stream_reset (s);
while (1) {
stream_reset(s);
ret = fread (s->data, 12, 1, fp);
if (!ret || feof (fp))
{
printf ("END OF FILE\n");
ret = fread(s->data, 12, 1, fp);
if (!ret || feof(fp)) {
printf("END OF FILE\n");
break;
}
if (ferror (fp))
{
printf ("ERROR OF FREAD\n");
if (ferror(fp)) {
printf("ERROR OF FREAD\n");
break;
}
/* Extract header. */
now = stream_getl (s);
type = stream_getw (s);
subtype = stream_getw (s);
len = stream_getl (s);
now = stream_getl(s);
type = stream_getw(s);
subtype = stream_getw(s);
len = stream_getl(s);
printf ("TIME: %s", ctime (&now));
printf("TIME: %s", ctime(&now));
/* printf ("TYPE: %d/%d\n", type, subtype); */
if (type == MSG_PROTOCOL_BGP4MP)
printf ("TYPE: BGP4MP");
printf("TYPE: BGP4MP");
else if (type == MSG_PROTOCOL_BGP4MP_ET)
printf ("TYPE: BGP4MP_ET");
printf("TYPE: BGP4MP_ET");
else if (type == MSG_TABLE_DUMP)
printf ("TYPE: MSG_TABLE_DUMP");
printf("TYPE: MSG_TABLE_DUMP");
else
printf ("TYPE: Unknown %d", type);
printf("TYPE: Unknown %d", type);
if (type == MSG_TABLE_DUMP)
switch (subtype)
{
switch (subtype) {
case AFI_IP:
printf ("/AFI_IP\n");
printf("/AFI_IP\n");
break;
case AFI_IP6:
printf ("/AFI_IP6\n");
printf("/AFI_IP6\n");
break;
default:
printf ("/UNKNOWN %d", subtype);
printf("/UNKNOWN %d", subtype);
break;
}
else
{
switch (subtype)
{
else {
switch (subtype) {
case BGP4MP_STATE_CHANGE:
printf ("/CHANGE\n");
printf("/CHANGE\n");
break;
case BGP4MP_MESSAGE:
printf ("/MESSAGE\n");
printf("/MESSAGE\n");
break;
case BGP4MP_ENTRY:
printf ("/ENTRY\n");
printf("/ENTRY\n");
break;
case BGP4MP_SNAPSHOT:
printf ("/SNAPSHOT\n");
printf("/SNAPSHOT\n");
break;
default:
printf ("/UNKNOWN %d", subtype);
printf("/UNKNOWN %d", subtype);
break;
}
}
printf ("len: %zd\n", len);
printf("len: %zd\n", len);
fread (s->data + 12, len, 1, fp);
if (feof (fp))
{
printf ("ENDOF FILE 2\n");
fread(s->data + 12, len, 1, fp);
if (feof(fp)) {
printf("ENDOF FILE 2\n");
break;
}
if (ferror (fp))
{
printf ("ERROR OF FREAD 2\n");
if (ferror(fp)) {
printf("ERROR OF FREAD 2\n");
break;
}
/* printf ("now read %d\n", len); */
if (type == MSG_TABLE_DUMP)
{
if (type == MSG_TABLE_DUMP) {
u_char status;
time_t originated;
struct in_addr peer;
u_int16_t attrlen;
viewno = stream_getw (s);
seq_num = stream_getw (s);
printf ("VIEW: %d\n", viewno);
printf ("SEQUENCE: %d\n", seq_num);
viewno = stream_getw(s);
seq_num = stream_getw(s);
printf("VIEW: %d\n", viewno);
printf("SEQUENCE: %d\n", seq_num);
/* start */
while (s->getp < len - 16)
{
p.prefix.s_addr = stream_get_ipv4 (s);
p.prefixlen = stream_getc (s);
printf ("PREFIX: %s/%d\n", inet_ntoa (p.prefix), p.prefixlen);
while (s->getp < len - 16) {
p.prefix.s_addr = stream_get_ipv4(s);
p.prefixlen = stream_getc(s);
printf("PREFIX: %s/%d\n", inet_ntoa(p.prefix),
p.prefixlen);
status = stream_getc (s);
originated = stream_getl (s);
peer.s_addr = stream_get_ipv4 (s);
status = stream_getc(s);
originated = stream_getl(s);
peer.s_addr = stream_get_ipv4(s);
source_as = stream_getw(s);
printf ("FROM: %s AS%d\n", inet_ntoa (peer), source_as);
printf ("ORIGINATED: %s", ctime (&originated));
printf("FROM: %s AS%d\n", inet_ntoa(peer),
source_as);
printf("ORIGINATED: %s", ctime(&originated));
attrlen = stream_getw (s);
printf ("ATTRLEN: %d\n", attrlen);
attrlen = stream_getw(s);
printf("ATTRLEN: %d\n", attrlen);
attr_parse (s, attrlen);
attr_parse(s, attrlen);
printf ("STATUS: 0x%x\n", status);
printf("STATUS: 0x%x\n", status);
}
} else {
source_as = stream_getw(s);
dest_as = stream_getw(s);
printf("source_as: %d\n", source_as);
printf("dest_as: %d\n", dest_as);
ifindex = stream_getw(s);
family = stream_getw(s);
printf("ifindex: %d\n", ifindex);
printf("family: %d\n", family);
sip.s_addr = stream_get_ipv4(s);
dip.s_addr = stream_get_ipv4(s);
printf("saddr: %s\n", inet_ntoa(sip));
printf("daddr: %s\n", inet_ntoa(dip));
printf("\n");
}
}
else
{
source_as = stream_getw (s);
dest_as = stream_getw (s);
printf ("source_as: %d\n", source_as);
printf ("dest_as: %d\n", dest_as);
ifindex = stream_getw (s);
family = stream_getw (s);
printf ("ifindex: %d\n", ifindex);
printf ("family: %d\n", family);
sip.s_addr = stream_get_ipv4 (s);
dip.s_addr = stream_get_ipv4 (s);
printf ("saddr: %s\n", inet_ntoa (sip));
printf ("daddr: %s\n", inet_ntoa (dip));
printf ("\n");
}
}
fclose (fp);
fclose(fp);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -43,8 +43,7 @@
#define LARGE_COMMUNITY_LIST_EXPANDED 5 /* Expanded Large community-list. */
/* Community-list. */
struct community_list
{
struct community_list {
/* Name of the community-list. */
char *name;
@ -64,8 +63,7 @@ struct community_list
};
/* Each entry in community-list. */
struct community_entry
{
struct community_entry {
struct community_entry *next;
struct community_entry *prev;
@ -79,8 +77,7 @@ struct community_entry
u_char any;
/* Community structure. */
union
{
union {
struct community *com;
struct ecommunity *ecom;
struct lcommunity *lcom;
@ -94,23 +91,20 @@ struct community_entry
};
/* Linked list of community-list. */
struct community_list_list
{
struct community_list_list {
struct community_list *head;
struct community_list *tail;
};
/* Master structure of community-list and extcommunity-list. */
struct community_list_master
{
struct community_list_master {
struct community_list_list num;
struct community_list_list str;
};
/* Community-list handler. community_list_init() returns this
structure as handler. */
struct community_list_handler
{
struct community_list_handler {
/* Community-list. */
struct community_list_master community_list;
@ -131,42 +125,42 @@ struct community_list_handler
extern struct community_list_handler *bgp_clist;
/* Prototypes. */
extern struct community_list_handler *community_list_init (void);
extern void community_list_terminate (struct community_list_handler *);
extern struct community_list_handler *community_list_init(void);
extern void community_list_terminate(struct community_list_handler *);
extern int community_list_set (struct community_list_handler *ch,
extern int community_list_set(struct community_list_handler *ch,
const char *name, const char *str, int direct,
int style);
extern int community_list_unset (struct community_list_handler *ch,
extern int community_list_unset(struct community_list_handler *ch,
const char *name, const char *str, int direct,
int style, int delete_all);
extern int extcommunity_list_set(struct community_list_handler *ch,
const char *name, const char *str, int direct,
int style);
extern int extcommunity_list_unset(struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style, int delete_all);
extern int extcommunity_list_set (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style);
extern int extcommunity_list_unset (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style, int delete_all);
extern int lcommunity_list_set (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style);
extern int lcommunity_list_unset (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style);
extern int lcommunity_list_set(struct community_list_handler *ch,
const char *name, const char *str, int direct,
int style);
extern int lcommunity_list_unset(struct community_list_handler *ch,
const char *name, const char *str, int direct,
int style);
extern struct community_list_master *
community_list_master_lookup (struct community_list_handler *, int);
community_list_master_lookup(struct community_list_handler *, int);
extern struct community_list *
community_list_lookup (struct community_list_handler *, const char *, int);
community_list_lookup(struct community_list_handler *, const char *, int);
extern int community_list_match (struct community *, struct community_list *);
extern int ecommunity_list_match (struct ecommunity *, struct community_list *);
extern int lcommunity_list_match (struct lcommunity *, struct community_list *);
extern int community_list_exact_match (struct community *,
extern int community_list_match(struct community *, struct community_list *);
extern int ecommunity_list_match(struct ecommunity *, struct community_list *);
extern int lcommunity_list_match(struct lcommunity *, struct community_list *);
extern int community_list_exact_match(struct community *,
struct community_list *);
extern struct community *community_list_match_delete(struct community *,
struct community_list *);
extern struct community *
community_list_match_delete (struct community *, struct community_list *);
extern struct lcommunity *
lcommunity_list_match_delete (struct lcommunity *lcom,
lcommunity_list_match_delete(struct lcommunity *lcom,
struct community_list *list);
#endif /* _QUAGGA_BGP_CLIST_H */

View File

@ -31,72 +31,66 @@
static struct hash *comhash;
/* Allocate a new communities value. */
static struct community *
community_new (void)
static struct community *community_new(void)
{
return (struct community *) XCALLOC (MTYPE_COMMUNITY,
sizeof (struct community));
return (struct community *)XCALLOC(MTYPE_COMMUNITY,
sizeof(struct community));
}
/* Free communities value. */
void
community_free (struct community *com)
void community_free(struct community *com)
{
if (com->val)
XFREE (MTYPE_COMMUNITY_VAL, com->val);
XFREE(MTYPE_COMMUNITY_VAL, com->val);
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);
com->json = NULL;
}
XFREE (MTYPE_COMMUNITY, com);
XFREE(MTYPE_COMMUNITY, com);
}
/* Add one community value to the community. */
static void
community_add_val (struct community *com, u_int32_t val)
static void community_add_val(struct community *com, u_int32_t val)
{
com->size++;
if (com->val)
com->val = XREALLOC (MTYPE_COMMUNITY_VAL, com->val, com_length (com));
com->val = XREALLOC(MTYPE_COMMUNITY_VAL, com->val,
com_length(com));
else
com->val = XMALLOC (MTYPE_COMMUNITY_VAL, com_length (com));
com->val = XMALLOC(MTYPE_COMMUNITY_VAL, com_length(com));
val = htonl (val);
memcpy (com_lastval (com), &val, sizeof (u_int32_t));
val = htonl(val);
memcpy(com_lastval(com), &val, sizeof(u_int32_t));
}
/* Delete one community. */
void
community_del_val (struct community *com, u_int32_t *val)
void community_del_val(struct community *com, u_int32_t *val)
{
int i = 0;
int c = 0;
if (! com->val)
if (!com->val)
return;
while (i < com->size)
{
if (memcmp (com->val + i, val, sizeof (u_int32_t)) == 0)
{
c = com->size -i -1;
while (i < com->size) {
if (memcmp(com->val + i, val, sizeof(u_int32_t)) == 0) {
c = com->size - i - 1;
if (c > 0)
memmove (com->val + i, com->val + (i + 1), c * sizeof (*val));
memmove(com->val + i, com->val + (i + 1),
c * sizeof(*val));
com->size--;
if (com->size > 0)
com->val = XREALLOC (MTYPE_COMMUNITY_VAL, com->val,
com_length (com));
else
{
XFREE (MTYPE_COMMUNITY_VAL, com->val);
com->val = XREALLOC(MTYPE_COMMUNITY_VAL,
com->val, com_length(com));
else {
XFREE(MTYPE_COMMUNITY_VAL, com->val);
com->val = NULL;
}
return;
@ -106,14 +100,13 @@ community_del_val (struct community *com, u_int32_t *val)
}
/* Delete all communities listed in com2 from com1 */
struct community *
community_delete (struct community *com1, struct community *com2)
struct community *community_delete(struct community *com1,
struct community *com2)
{
int i = 0;
while(i < com2->size)
{
community_del_val (com1, com2->val + i);
while (i < com2->size) {
community_del_val(com1, com2->val + i);
i++;
}
@ -121,16 +114,15 @@ community_delete (struct community *com1, struct community *com2)
}
/* Callback function from qsort(). */
static int
community_compare (const void *a1, const void *a2)
static int community_compare(const void *a1, const void *a2)
{
u_int32_t v1;
u_int32_t v2;
memcpy (&v1, a1, sizeof (u_int32_t));
memcpy (&v2, a2, sizeof (u_int32_t));
v1 = ntohl (v1);
v2 = ntohl (v2);
memcpy(&v1, a1, sizeof(u_int32_t));
memcpy(&v2, a2, sizeof(u_int32_t));
v1 = ntohl(v1);
v2 = ntohl(v2);
if (v1 < v2)
return -1;
@ -139,57 +131,54 @@ community_compare (const void *a1, const void *a2)
return 0;
}
int
community_include (struct community *com, u_int32_t val)
int community_include(struct community *com, u_int32_t val)
{
int i;
val = htonl (val);
val = htonl(val);
for (i = 0; i < com->size; i++)
if (memcmp (&val, com_nthval (com, i), sizeof (u_int32_t)) == 0)
if (memcmp(&val, com_nthval(com, i), sizeof(u_int32_t)) == 0)
return 1;
return 0;
}
u_int32_t
community_val_get (struct community *com, int i)
u_int32_t community_val_get(struct community *com, int i)
{
u_char *p;
u_int32_t val;
p = (u_char *) com->val;
p = (u_char *)com->val;
p += (i * 4);
memcpy (&val, p, sizeof (u_int32_t));
memcpy(&val, p, sizeof(u_int32_t));
return ntohl (val);
return ntohl(val);
}
/* Sort and uniq given community. */
struct community *
community_uniq_sort (struct community *com)
struct community *community_uniq_sort(struct community *com)
{
int i;
struct community *new;
u_int32_t val;
if (! com)
if (!com)
return NULL;
new = community_new ();;
new = community_new();
;
new->json = NULL;
for (i = 0; i < com->size; i++)
{
val = community_val_get (com, i);
for (i = 0; i < com->size; i++) {
val = community_val_get(com, i);
if (! community_include (new, val))
community_add_val (new, val);
if (!community_include(new, val))
community_add_val(new, val);
}
qsort (new->val, new->size, sizeof (u_int32_t), community_compare);
qsort(new->val, new->size, sizeof(u_int32_t), community_compare);
return new;
}
@ -204,8 +193,7 @@ community_uniq_sort (struct community *com)
0xFFFFFF03 "local-AS"
For other values, "AS:VAL" format is used. */
static void
set_community_string (struct community *com)
static void set_community_string(struct community *com)
{
int i;
char *str;
@ -225,9 +213,8 @@ set_community_string (struct community *com)
json_community_list = json_object_new_array();
/* When communities attribute is empty. */
if (com->size == 0)
{
str = XMALLOC (MTYPE_COMMUNITY_STR, 1);
if (com->size == 0) {
str = XMALLOC(MTYPE_COMMUNITY_STR, 1);
str[0] = '\0';
json_object_string_add(com->json, "string", "");
@ -240,79 +227,75 @@ set_community_string (struct community *com)
required string length first. */
len = 0;
for (i = 0; i < com->size; i++)
{
memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t));
comval = ntohl (comval);
for (i = 0; i < com->size; i++) {
memcpy(&comval, com_nthval(com, i), sizeof(u_int32_t));
comval = ntohl(comval);
switch (comval)
{
switch (comval) {
case COMMUNITY_INTERNET:
len += strlen (" internet");
len += strlen(" internet");
break;
case COMMUNITY_NO_EXPORT:
len += strlen (" no-export");
len += strlen(" no-export");
break;
case COMMUNITY_NO_ADVERTISE:
len += strlen (" no-advertise");
len += strlen(" no-advertise");
break;
case COMMUNITY_LOCAL_AS:
len += strlen (" local-AS");
len += strlen(" local-AS");
break;
default:
len += strlen (" 65536:65535");
len += strlen(" 65536:65535");
break;
}
}
/* Allocate memory. */
str = pnt = XMALLOC (MTYPE_COMMUNITY_STR, len);
str = pnt = XMALLOC(MTYPE_COMMUNITY_STR, len);
first = 1;
/* Fill in string. */
for (i = 0; i < com->size; i++)
{
memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t));
comval = ntohl (comval);
for (i = 0; i < com->size; i++) {
memcpy(&comval, com_nthval(com, i), sizeof(u_int32_t));
comval = ntohl(comval);
if (first)
first = 0;
else
*pnt++ = ' ';
switch (comval)
{
switch (comval) {
case COMMUNITY_INTERNET:
strcpy (pnt, "internet");
pnt += strlen ("internet");
strcpy(pnt, "internet");
pnt += strlen("internet");
json_string = json_object_new_string("internet");
json_object_array_add(json_community_list, json_string);
break;
case COMMUNITY_NO_EXPORT:
strcpy (pnt, "no-export");
pnt += strlen ("no-export");
strcpy(pnt, "no-export");
pnt += strlen("no-export");
json_string = json_object_new_string("noExport");
json_object_array_add(json_community_list, json_string);
break;
case COMMUNITY_NO_ADVERTISE:
strcpy (pnt, "no-advertise");
pnt += strlen ("no-advertise");
strcpy(pnt, "no-advertise");
pnt += strlen("no-advertise");
json_string = json_object_new_string("noAdvertise");
json_object_array_add(json_community_list, json_string);
break;
case COMMUNITY_LOCAL_AS:
strcpy (pnt, "local-AS");
pnt += strlen ("local-AS");
strcpy(pnt, "local-AS");
pnt += strlen("local-AS");
json_string = json_object_new_string("localAs");
json_object_array_add(json_community_list, json_string);
break;
default:
as = (comval >> 16) & 0xFFFF;
val = comval & 0xFFFF;
sprintf (pnt, "%u:%d", as, val);
sprintf(pnt, "%u:%d", as, val);
json_string = json_object_new_string(pnt);
json_object_array_add(json_community_list, json_string);
pnt += strlen (pnt);
pnt += strlen(pnt);
break;
}
}
@ -324,35 +307,33 @@ set_community_string (struct community *com)
}
/* Intern communities attribute. */
struct community *
community_intern (struct community *com)
struct community *community_intern(struct community *com)
{
struct community *find;
/* Assert this community structure is not interned. */
assert (com->refcnt == 0);
assert(com->refcnt == 0);
/* Lookup community hash. */
find = (struct community *) hash_get (comhash, com, hash_alloc_intern);
find = (struct community *)hash_get(comhash, com, hash_alloc_intern);
/* Arguemnt com is allocated temporary. So when it is not used in
hash, it should be freed. */
if (find != com)
community_free (com);
community_free(com);
/* Increment refrence counter. */
find->refcnt++;
/* Make string. */
if (! find->str)
set_community_string (find);
if (!find->str)
set_community_string(find);
return find;
}
/* Free community attribute. */
void
community_unintern (struct community **com)
void community_unintern(struct community **com)
{
struct community *ret;
@ -360,20 +341,18 @@ community_unintern (struct community **com)
(*com)->refcnt--;
/* Pull off from hash. */
if ((*com)->refcnt == 0)
{
if ((*com)->refcnt == 0) {
/* Community value com must exist in hash. */
ret = (struct community *) hash_release (comhash, *com);
assert (ret != NULL);
ret = (struct community *)hash_release(comhash, *com);
assert(ret != NULL);
community_free (*com);
community_free(*com);
*com = NULL;
}
}
/* Create new community attribute. */
struct community *
community_parse (u_int32_t *pnt, u_short length)
struct community *community_parse(u_int32_t *pnt, u_short length)
{
struct community tmp;
struct community *new;
@ -386,52 +365,46 @@ community_parse (u_int32_t *pnt, u_short length)
tmp.size = length / 4;
tmp.val = pnt;
new = community_uniq_sort (&tmp);
new = community_uniq_sort(&tmp);
return community_intern (new);
return community_intern(new);
}
struct community *
community_dup (struct community *com)
struct community *community_dup(struct community *com)
{
struct community *new;
new = XCALLOC (MTYPE_COMMUNITY, sizeof (struct community));
new = XCALLOC(MTYPE_COMMUNITY, sizeof(struct community));
new->size = com->size;
if (new->size)
{
new->val = XMALLOC (MTYPE_COMMUNITY_VAL, com->size * 4);
memcpy (new->val, com->val, com->size * 4);
}
else
if (new->size) {
new->val = XMALLOC(MTYPE_COMMUNITY_VAL, com->size * 4);
memcpy(new->val, com->val, com->size * 4);
} else
new->val = NULL;
return new;
}
/* Retrun string representation of communities attribute. */
char *
community_str (struct community *com)
char *community_str(struct community *com)
{
if (!com)
return NULL;
if (! com->str)
set_community_string (com);
if (!com->str)
set_community_string(com);
return com->str;
}
/* Make hash value of community attribute. This function is used by
hash package.*/
unsigned int
community_hash_make (struct community *com)
unsigned int community_hash_make(struct community *com)
{
unsigned char *pnt = (unsigned char *)com->val;
int size = com->size * 4;
unsigned int key = 0;
int c;
for (c = 0; c < size; c += 4)
{
for (c = 0; c < size; c += 4) {
key += pnt[c];
key += pnt[c + 1];
key += pnt[c + 2];
@ -441,8 +414,7 @@ community_hash_make (struct community *com)
return key;
}
int
community_match (const struct community *com1, const struct community *com2)
int community_match(const struct community *com1, const struct community *com2)
{
int i = 0;
int j = 0;
@ -457,9 +429,9 @@ community_match (const struct community *com1, const struct community *com2)
return 0;
/* Every community on com2 needs to be on com1 for this to match */
while (i < com1->size && j < com2->size)
{
if (memcmp (com1->val + i, com2->val + j, sizeof (u_int32_t)) == 0)
while (i < com1->size && j < com2->size) {
if (memcmp(com1->val + i, com2->val + j, sizeof(u_int32_t))
== 0)
j++;
i++;
}
@ -472,8 +444,7 @@ community_match (const struct community *com1, const struct community *com2)
/* If two aspath have same value then return 1 else return 0. This
function is used by hash package. */
int
community_cmp (const struct community *com1, const struct community *com2)
int community_cmp(const struct community *com1, const struct community *com2)
{
if (com1 == NULL && com2 == NULL)
return 1;
@ -481,30 +452,30 @@ community_cmp (const struct community *com1, const struct community *com2)
return 0;
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 0;
}
/* Add com2 to the end of com1. */
struct community *
community_merge (struct community *com1, struct community *com2)
struct community *community_merge(struct community *com1,
struct community *com2)
{
if (com1->val)
com1->val = XREALLOC (MTYPE_COMMUNITY_VAL, com1->val,
com1->val = XREALLOC(MTYPE_COMMUNITY_VAL, com1->val,
(com1->size + com2->size) * 4);
else
com1->val = XMALLOC (MTYPE_COMMUNITY_VAL, (com1->size + com2->size) * 4);
com1->val = XMALLOC(MTYPE_COMMUNITY_VAL,
(com1->size + com2->size) * 4);
memcpy (com1->val + com1->size, com2->val, com2->size * 4);
memcpy(com1->val + com1->size, com2->val, com2->size * 4);
com1->size += com2->size;
return com1;
}
/* Community token enum. */
enum community_token
{
enum community_token {
community_token_val,
community_token_no_export,
community_token_no_advertise,
@ -514,13 +485,12 @@ enum community_token
/* Get next community token from string. */
static const char *
community_gettoken (const char *buf, enum community_token *token,
u_int32_t *val)
community_gettoken(const char *buf, enum community_token *token, u_int32_t *val)
{
const char *p = buf;
/* Skip white space. */
while (isspace ((int) *p))
while (isspace((int)*p))
p++;
/* Check the end of the line. */
@ -528,34 +498,29 @@ community_gettoken (const char *buf, enum community_token *token,
return NULL;
/* Well known community string check. */
if (isalpha ((int) *p))
{
if (strncmp (p, "internet", strlen ("internet")) == 0)
{
if (isalpha((int)*p)) {
if (strncmp(p, "internet", strlen("internet")) == 0) {
*val = COMMUNITY_INTERNET;
*token = community_token_no_export;
p += strlen ("internet");
p += strlen("internet");
return p;
}
if (strncmp (p, "no-export", strlen ("no-export")) == 0)
{
if (strncmp(p, "no-export", strlen("no-export")) == 0) {
*val = COMMUNITY_NO_EXPORT;
*token = community_token_no_export;
p += strlen ("no-export");
p += strlen("no-export");
return p;
}
if (strncmp (p, "no-advertise", strlen ("no-advertise")) == 0)
{
if (strncmp(p, "no-advertise", strlen("no-advertise")) == 0) {
*val = COMMUNITY_NO_ADVERTISE;
*token = community_token_no_advertise;
p += strlen ("no-advertise");
p += strlen("no-advertise");
return p;
}
if (strncmp (p, "local-AS", strlen ("local-AS")) == 0)
{
if (strncmp(p, "local-AS", strlen("local-AS")) == 0) {
*val = COMMUNITY_LOCAL_AS;
*token = community_token_local_as;
p += strlen ("local-AS");
p += strlen("local-AS");
return p;
}
@ -565,53 +530,43 @@ community_gettoken (const char *buf, enum community_token *token,
}
/* Community value. */
if (isdigit ((int) *p))
{
if (isdigit((int)*p)) {
int separator = 0;
int digit = 0;
u_int32_t community_low = 0;
u_int32_t community_high = 0;
while (isdigit ((int) *p) || *p == ':')
{
if (*p == ':')
{
if (separator)
{
while (isdigit((int)*p) || *p == ':') {
if (*p == ':') {
if (separator) {
*token = community_token_unknown;
return NULL;
}
else
{
} else {
separator = 1;
digit = 0;
if (community_low > UINT16_MAX)
{
*token = community_token_unknown;
if (community_low > UINT16_MAX) {
*token =
community_token_unknown;
return NULL;
}
community_high = community_low << 16;
community_low = 0;
}
}
else
{
} else {
digit = 1;
community_low *= 10;
community_low += (*p - '0');
}
p++;
}
if (! digit)
{
if (!digit) {
*token = community_token_unknown;
return NULL;
}
if (community_low > UINT16_MAX)
{
if (community_low > UINT16_MAX) {
*token = community_token_unknown;
return NULL;
}
@ -625,73 +580,66 @@ community_gettoken (const char *buf, enum community_token *token,
}
/* convert string to community structure */
struct community *
community_str2com (const char *str)
struct community *community_str2com(const char *str)
{
struct community *com = NULL;
struct community *com_sort = NULL;
u_int32_t val = 0;
enum community_token token = community_token_unknown;
do
{
str = community_gettoken (str, &token, &val);
do {
str = community_gettoken(str, &token, &val);
switch (token)
{
switch (token) {
case community_token_val:
case community_token_no_export:
case community_token_no_advertise:
case community_token_local_as:
if (com == NULL)
{
if (com == NULL) {
com = community_new();
com->json = NULL;
}
community_add_val (com, val);
community_add_val(com, val);
break;
case community_token_unknown:
default:
if (com)
community_free (com);
community_free(com);
return NULL;
}
} while (str);
if (! com)
if (!com)
return NULL;
com_sort = community_uniq_sort (com);
community_free (com);
com_sort = community_uniq_sort(com);
community_free(com);
return com_sort;
}
/* Return communities hash entry count. */
unsigned long
community_count (void)
unsigned long community_count(void)
{
return comhash->count;
}
/* Return communities hash. */
struct hash *
community_hash (void)
struct hash *community_hash(void)
{
return comhash;
}
/* Initialize comminity related hash. */
void
community_init (void)
void community_init(void)
{
comhash = hash_create ((unsigned int (*) (void *))community_hash_make,
(int (*) (const void *, const void *))community_cmp, NULL);
comhash = hash_create(
(unsigned int (*)(void *))community_hash_make,
(int (*)(const void *, const void *))community_cmp, NULL);
}
void
community_finish (void)
void community_finish(void)
{
hash_free (comhash);
hash_free(comhash);
comhash = NULL;
}

View File

@ -24,8 +24,7 @@
#include "lib/json.h"
/* Communities attribute. */
struct community
{
struct community {
/* Reference count of communities value. */
unsigned long refcnt;
@ -56,25 +55,27 @@ struct community
#define com_nthval(X,n) ((X)->val + (n))
/* Prototypes of communities attribute functions. */
extern void community_init (void);
extern void community_finish (void);
extern void community_free (struct community *);
extern struct community *community_uniq_sort (struct community *);
extern struct community *community_parse (u_int32_t *, u_short);
extern struct community *community_intern (struct community *);
extern void community_unintern (struct community **);
extern char *community_str (struct community *);
extern unsigned int community_hash_make (struct community *);
extern struct community *community_str2com (const char *);
extern int community_match (const struct community *, const struct community *);
extern int community_cmp (const struct community *, const struct community *);
extern struct community *community_merge (struct community *, struct community *);
extern struct community *community_delete (struct community *, struct community *);
extern struct community *community_dup (struct community *);
extern int community_include (struct community *, u_int32_t);
extern void community_del_val (struct community *, u_int32_t *);
extern unsigned long community_count (void);
extern struct hash *community_hash (void);
extern u_int32_t community_val_get (struct community *com, int i);
extern void community_init(void);
extern void community_finish(void);
extern void community_free(struct community *);
extern struct community *community_uniq_sort(struct community *);
extern struct community *community_parse(u_int32_t *, u_short);
extern struct community *community_intern(struct community *);
extern void community_unintern(struct community **);
extern char *community_str(struct community *);
extern unsigned int community_hash_make(struct community *);
extern struct community *community_str2com(const char *);
extern int community_match(const struct community *, const struct community *);
extern int community_cmp(const struct community *, const struct community *);
extern struct community *community_merge(struct community *,
struct community *);
extern struct community *community_delete(struct community *,
struct community *);
extern struct community *community_dup(struct community *);
extern int community_include(struct community *, u_int32_t);
extern void community_del_val(struct community *, u_int32_t *);
extern unsigned long community_count(void);
extern struct hash *community_hash(void);
extern u_int32_t community_val_get(struct community *com, int i);
#endif /* _QUAGGA_BGP_COMMUNITY_H */

View File

@ -46,15 +46,15 @@ static struct bgp_damp_config *damp = &bgp_damp_cfg;
#define BGP_DAMP_LIST_DEL(N,A) BGP_INFO_DEL(N,A,no_reuse_list)
/* Calculate reuse list index by penalty value. */
static int
bgp_reuse_index (int penalty)
static int bgp_reuse_index(int penalty)
{
unsigned int i;
int index;
i = (int)(((double) penalty / damp->reuse_limit - 1.0) * damp->scale_factor);
i = (int)(((double)penalty / damp->reuse_limit - 1.0)
* damp->scale_factor);
if ( i >= damp->reuse_index_size )
if (i >= damp->reuse_index_size)
i = damp->reuse_index_size - 1;
index = damp->reuse_index[i] - damp->reuse_index[0];
@ -63,12 +63,11 @@ bgp_reuse_index (int penalty)
}
/* Add BGP dampening information to reuse list. */
static void
bgp_reuse_list_add (struct bgp_damp_info *bdi)
static void bgp_reuse_list_add(struct bgp_damp_info *bdi)
{
int index;
index = bdi->index = bgp_reuse_index (bdi->penalty);
index = bdi->index = bgp_reuse_index(bdi->penalty);
bdi->prev = NULL;
bdi->next = damp->reuse_list[index];
@ -78,8 +77,7 @@ bgp_reuse_list_add (struct bgp_damp_info *bdi)
}
/* Delete BGP dampening information from reuse list. */
static void
bgp_reuse_list_delete (struct bgp_damp_info *bdi)
static void bgp_reuse_list_delete(struct bgp_damp_info *bdi)
{
if (bdi->next)
bdi->next->prev = bdi->prev;
@ -90,12 +88,11 @@ bgp_reuse_list_delete (struct bgp_damp_info *bdi)
}
/* Return decayed penalty value. */
int
bgp_damp_decay (time_t tdiff, int penalty)
int bgp_damp_decay(time_t tdiff, int penalty)
{
unsigned int i;
i = (int) ((double) tdiff / DELTA_T);
i = (int)((double)tdiff / DELTA_T);
if (i == 0)
return penalty;
@ -103,13 +100,12 @@ bgp_damp_decay (time_t tdiff, int penalty)
if (i >= damp->decay_array_size)
return 0;
return (int) (penalty * damp->decay_array[i]);
return (int)(penalty * damp->decay_array[i]);
}
/* Handler of reuse timer event. Each route in the current reuse-list
is evaluated. RFC2439 Section 4.8.7. */
static int
bgp_reuse_timer (struct thread *t)
static int bgp_reuse_timer(struct thread *t)
{
struct bgp_damp_info *bdi;
struct bgp_damp_info *next;
@ -119,7 +115,7 @@ bgp_reuse_timer (struct thread *t)
thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE,
&damp->t_reuse);
t_now = bgp_clock ();
t_now = bgp_clock();
/* 1. save a pointer to the current zeroth queue head and zero the
list head entry. */
@ -131,8 +127,7 @@ bgp_reuse_timer (struct thread *t)
damp->reuse_offset = (damp->reuse_offset + 1) % damp->reuse_list_size;
/* 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;
next = bdi->next;
@ -140,57 +135,57 @@ bgp_reuse_timer (struct thread *t)
/* Set t-diff = t-now - t-updated. */
t_diff = t_now - bdi->t_updated;
/* Set figure-of-merit = figure-of-merit * decay-array-ok [t-diff] */
bdi->penalty = bgp_damp_decay (t_diff, bdi->penalty);
/* Set figure-of-merit = figure-of-merit * decay-array-ok
* [t-diff] */
bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty);
/* Set t-updated = t-now. */
bdi->t_updated = t_now;
/* if (figure-of-merit < reuse). */
if (bdi->penalty < damp->reuse_limit)
{
if (bdi->penalty < damp->reuse_limit) {
/* Reuse the route. */
bgp_info_unset_flag (bdi->rn, bdi->binfo, BGP_INFO_DAMPED);
bgp_info_unset_flag(bdi->rn, bdi->binfo,
BGP_INFO_DAMPED);
bdi->suppress_time = 0;
if (bdi->lastrecord == BGP_RECORD_UPDATE)
{
bgp_info_unset_flag (bdi->rn, bdi->binfo, BGP_INFO_HISTORY);
bgp_aggregate_increment (bgp, &bdi->rn->p, bdi->binfo,
bdi->afi, bdi->safi);
bgp_process (bgp, bdi->rn, bdi->afi, bdi->safi);
if (bdi->lastrecord == BGP_RECORD_UPDATE) {
bgp_info_unset_flag(bdi->rn, bdi->binfo,
BGP_INFO_HISTORY);
bgp_aggregate_increment(bgp, &bdi->rn->p,
bdi->binfo, bdi->afi,
bdi->safi);
bgp_process(bgp, bdi->rn, bdi->afi, bdi->safi);
}
if (bdi->penalty <= damp->reuse_limit / 2.0)
bgp_damp_info_free (bdi, 1);
bgp_damp_info_free(bdi, 1);
else
BGP_DAMP_LIST_ADD (damp, bdi);
}
else
/* Re-insert into another list (See RFC2439 Section 4.8.6). */
bgp_reuse_list_add (bdi);
BGP_DAMP_LIST_ADD(damp, bdi);
} else
/* Re-insert into another list (See RFC2439 Section
* 4.8.6). */
bgp_reuse_list_add(bdi);
}
return 0;
}
/* A route becomes unreachable (RFC2439 Section 4.8.2). */
int
bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
afi_t afi, safi_t safi, int attr_change)
int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
safi_t safi, int attr_change)
{
time_t t_now;
struct bgp_damp_info *bdi = NULL;
double last_penalty = 0;
t_now = bgp_clock ();
t_now = bgp_clock();
/* Processing Unreachable Messages. */
if (binfo->extra)
bdi = binfo->extra->damp_info;
if (bdi == NULL)
{
if (bdi == NULL) {
/* If there is no previous stability history. */
/* RFC2439 said:
@ -198,27 +193,28 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
2. set figure-of-merit = 1.
3. withdraw the route. */
bdi = XCALLOC (MTYPE_BGP_DAMP_INFO, sizeof (struct bgp_damp_info));
bdi = XCALLOC(MTYPE_BGP_DAMP_INFO,
sizeof(struct bgp_damp_info));
bdi->binfo = binfo;
bdi->rn = rn;
bdi->penalty = (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
bdi->penalty =
(attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
bdi->flap = 1;
bdi->start_time = t_now;
bdi->suppress_time = 0;
bdi->index = -1;
bdi->afi = afi;
bdi->safi = safi;
(bgp_info_extra_get (binfo))->damp_info = bdi;
BGP_DAMP_LIST_ADD (damp, bdi);
}
else
{
(bgp_info_extra_get(binfo))->damp_info = bdi;
BGP_DAMP_LIST_ADD(damp, bdi);
} else {
last_penalty = bdi->penalty;
/* 1. Set t-diff = t-now - t-updated. */
bdi->penalty =
(bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty)
+ (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY));
(bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty)
+ (attr_change ? DEFAULT_PENALTY / 2
: DEFAULT_PENALTY));
if (bdi->penalty > damp->ceiling)
bdi->penalty = damp->ceiling;
@ -226,42 +222,38 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
bdi->flap++;
}
assert ((rn == bdi->rn) && (binfo == bdi->binfo));
assert((rn == bdi->rn) && (binfo == bdi->binfo));
bdi->lastrecord = BGP_RECORD_WITHDRAW;
bdi->t_updated = t_now;
/* Make this route as historical status. */
bgp_info_set_flag (rn, binfo, BGP_INFO_HISTORY);
bgp_info_set_flag(rn, binfo, BGP_INFO_HISTORY);
/* 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->binfo->flags, BGP_INFO_DAMPED)) {
/* If decay rate isn't equal to 0, reinsert brn. */
if (bdi->penalty != last_penalty)
{
bgp_reuse_list_delete (bdi);
bgp_reuse_list_add (bdi);
if (bdi->penalty != last_penalty) {
bgp_reuse_list_delete(bdi);
bgp_reuse_list_add(bdi);
}
return BGP_DAMP_SUPPRESSED;
}
/* If not suppressed before, do annonunce this withdraw and
insert into reuse_list. */
if (bdi->penalty >= damp->suppress_value)
{
bgp_info_set_flag (rn, binfo, BGP_INFO_DAMPED);
if (bdi->penalty >= damp->suppress_value) {
bgp_info_set_flag(rn, binfo, BGP_INFO_DAMPED);
bdi->suppress_time = t_now;
BGP_DAMP_LIST_DEL (damp, bdi);
bgp_reuse_list_add (bdi);
BGP_DAMP_LIST_DEL(damp, bdi);
bgp_reuse_list_add(bdi);
}
return BGP_DAMP_USED;
}
int
bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
afi_t afi, safi_t safi)
int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
safi_t safi)
{
time_t t_now;
struct bgp_damp_info *bdi;
@ -270,110 +262,100 @@ bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
if (!binfo->extra || !((bdi = binfo->extra->damp_info)))
return BGP_DAMP_USED;
t_now = bgp_clock ();
bgp_info_unset_flag (rn, binfo, BGP_INFO_HISTORY);
t_now = bgp_clock();
bgp_info_unset_flag(rn, binfo, BGP_INFO_HISTORY);
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->binfo->flags, BGP_INFO_DAMPED)
&& (bdi->penalty < damp->suppress_value))
status = BGP_DAMP_USED;
else if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED)
&& (bdi->penalty < damp->reuse_limit) )
{
bgp_info_unset_flag (rn, binfo, BGP_INFO_DAMPED);
bgp_reuse_list_delete (bdi);
BGP_DAMP_LIST_ADD (damp, bdi);
else if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)
&& (bdi->penalty < damp->reuse_limit)) {
bgp_info_unset_flag(rn, binfo, BGP_INFO_DAMPED);
bgp_reuse_list_delete(bdi);
BGP_DAMP_LIST_ADD(damp, bdi);
bdi->suppress_time = 0;
status = BGP_DAMP_USED;
}
else
} else
status = BGP_DAMP_SUPPRESSED;
if (bdi->penalty > damp->reuse_limit / 2.0)
bdi->t_updated = t_now;
else
bgp_damp_info_free (bdi, 0);
bgp_damp_info_free(bdi, 0);
return status;
}
/* 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_info *binfo, afi_t afi, safi_t safi)
{
time_t t_now, t_diff;
struct bgp_damp_info *bdi;
assert (binfo->extra && binfo->extra->damp_info);
assert(binfo->extra && binfo->extra->damp_info);
t_now = bgp_clock ();
t_now = bgp_clock();
bdi = binfo->extra->damp_info;
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
{
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
t_diff = t_now - bdi->suppress_time;
if (t_diff >= damp->max_suppress_time)
{
bgp_info_unset_flag (bdi->rn, binfo, BGP_INFO_DAMPED);
bgp_reuse_list_delete (bdi);
BGP_DAMP_LIST_ADD (damp, bdi);
if (t_diff >= damp->max_suppress_time) {
bgp_info_unset_flag(bdi->rn, binfo, BGP_INFO_DAMPED);
bgp_reuse_list_delete(bdi);
BGP_DAMP_LIST_ADD(damp, bdi);
bdi->penalty = damp->reuse_limit;
bdi->suppress_time = 0;
bdi->t_updated = t_now;
/* Need to announce UPDATE once this binfo is usable again. */
/* Need to announce UPDATE once this binfo is usable
* again. */
if (bdi->lastrecord == BGP_RECORD_UPDATE)
return 1;
else
return 0;
}
}
else
{
} else {
t_diff = t_now - bdi->t_updated;
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. */
bgp_damp_info_free (bdi, 1);
bgp_damp_info_free(bdi, 1);
return 0;
}
else
} else
bdi->t_updated = t_now;
}
return 0;
}
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;
if (! bdi)
if (!bdi)
return;
binfo = bdi->binfo;
binfo->extra->damp_info = NULL;
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
bgp_reuse_list_delete (bdi);
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
bgp_reuse_list_delete(bdi);
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_info_unset_flag(bdi->rn, binfo, BGP_INFO_HISTORY | BGP_INFO_DAMPED);
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
bgp_info_delete (bdi->rn, binfo);
bgp_info_delete(bdi->rn, binfo);
XFREE (MTYPE_BGP_DAMP_INFO, bdi);
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
}
static void
bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup)
{
double reuse_max_ratio;
unsigned int i;
@ -387,64 +369,71 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
/* Initialize params per bgp_damp_config. */
damp->reuse_index_size = REUSE_ARRAY_SIZE;
damp->ceiling = (int)(damp->reuse_limit * (pow(2, (double)damp->max_suppress_time/damp->half_life)));
damp->ceiling =
(int)(damp->reuse_limit * (pow(2,
(double)damp->max_suppress_time
/ damp->half_life)));
/* Decay-array computations */
damp->decay_array_size = ceil ((double) damp->max_suppress_time / DELTA_T);
damp->decay_array = XMALLOC (MTYPE_BGP_DAMP_ARRAY,
damp->decay_array_size =
ceil((double)damp->max_suppress_time / DELTA_T);
damp->decay_array = XMALLOC(MTYPE_BGP_DAMP_ARRAY,
sizeof(double) * (damp->decay_array_size));
damp->decay_array[0] = 1.0;
damp->decay_array[1] = exp ((1.0/((double)damp->half_life/DELTA_T)) * log(0.5));
damp->decay_array[1] =
exp((1.0 / ((double)damp->half_life / DELTA_T)) * log(0.5));
/* Calculate decay values for all possible times */
for (i = 2; i < damp->decay_array_size; i++)
damp->decay_array[i] = damp->decay_array[i-1] * damp->decay_array[1];
damp->decay_array[i] =
damp->decay_array[i - 1] * damp->decay_array[1];
/* Reuse-list computations */
i = ceil ((double)damp->max_suppress_time / DELTA_REUSE) + 1;
i = ceil((double)damp->max_suppress_time / DELTA_REUSE) + 1;
if (i > REUSE_LIST_SIZE || i == 0)
i = REUSE_LIST_SIZE;
damp->reuse_list_size = i;
damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
damp->reuse_list = XCALLOC(MTYPE_BGP_DAMP_ARRAY,
damp->reuse_list_size
* sizeof (struct bgp_reuse_node *));
* sizeof(struct bgp_reuse_node *));
/* Reuse-array computations */
damp->reuse_index = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
damp->reuse_index = XCALLOC(MTYPE_BGP_DAMP_ARRAY,
sizeof(int) * damp->reuse_index_size);
reuse_max_ratio = (double)damp->ceiling/damp->reuse_limit;
j = (exp((double)damp->max_suppress_time/damp->half_life) * log10(2.0));
if ( reuse_max_ratio > j && j != 0 )
reuse_max_ratio = (double)damp->ceiling / damp->reuse_limit;
j = (exp((double)damp->max_suppress_time / damp->half_life)
* log10(2.0));
if (reuse_max_ratio > j && j != 0)
reuse_max_ratio = j;
damp->scale_factor = (double)damp->reuse_index_size/(reuse_max_ratio - 1);
damp->scale_factor =
(double)damp->reuse_index_size / (reuse_max_ratio - 1);
for (i = 0; i < damp->reuse_index_size; i++)
{
for (i = 0; i < damp->reuse_index_size; i++) {
damp->reuse_index[i] =
(int)(((double)damp->half_life / DELTA_REUSE)
* log10 (1.0 / (damp->reuse_limit * ( 1.0 + ((double)i/damp->scale_factor)))) / log10(0.5));
* log10(1.0 / (damp->reuse_limit
* (1.0 + ((double)i
/ damp->scale_factor))))
/ log10(0.5));
}
}
int
bgp_damp_enable (struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
unsigned int reuse, unsigned int suppress, time_t max)
{
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
{
if (damp->half_life == half
&& damp->reuse_limit == reuse
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) {
if (damp->half_life == half && damp->reuse_limit == reuse
&& damp->suppress_value == suppress
&& damp->max_suppress_time == max)
return 0;
bgp_damp_disable (bgp, afi, safi);
bgp_damp_disable(bgp, afi, safi);
}
SET_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
bgp_damp_parameter_set (half, reuse, suppress, max);
SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
bgp_damp_parameter_set(half, reuse, suppress, max);
/* Register reuse timer. */
thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE,
@ -453,161 +442,155 @@ bgp_damp_enable (struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
return 0;
}
static void
bgp_damp_config_clean (struct bgp_damp_config *damp)
static void bgp_damp_config_clean(struct bgp_damp_config *damp)
{
/* Free decay array */
XFREE (MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
/* Free reuse index array */
XFREE (MTYPE_BGP_DAMP_ARRAY, damp->reuse_index);
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_index);
/* Free reuse list array. */
XFREE (MTYPE_BGP_DAMP_ARRAY, damp->reuse_list);
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_list);
}
/* Clean all the bgp_damp_info stored in reuse_list. */
void
bgp_damp_info_clean (void)
void bgp_damp_info_clean(void)
{
unsigned int i;
struct bgp_damp_info *bdi, *next;
damp->reuse_offset = 0;
for (i = 0; i < damp->reuse_list_size; i++)
{
if (! damp->reuse_list[i])
for (i = 0; i < damp->reuse_list_size; i++) {
if (!damp->reuse_list[i])
continue;
for (bdi = damp->reuse_list[i]; bdi; bdi = next)
{
for (bdi = damp->reuse_list[i]; bdi; bdi = next) {
next = bdi->next;
bgp_damp_info_free (bdi, 1);
bgp_damp_info_free(bdi, 1);
}
damp->reuse_list[i] = NULL;
}
for (bdi = damp->no_reuse_list; bdi; bdi = next)
{
for (bdi = damp->no_reuse_list; bdi; bdi = next) {
next = bdi->next;
bgp_damp_info_free (bdi, 1);
bgp_damp_info_free(bdi, 1);
}
damp->no_reuse_list = NULL;
}
int
bgp_damp_disable (struct bgp *bgp, afi_t afi, safi_t safi)
int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi)
{
/* If it wasn't enabled, there's nothing to do. */
if (! CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
return 0;
/* Cancel reuse thread. */
if (damp->t_reuse )
thread_cancel (damp->t_reuse);
if (damp->t_reuse)
thread_cancel(damp->t_reuse);
damp->t_reuse = NULL;
/* Clean BGP dampening information. */
bgp_damp_info_clean ();
bgp_damp_info_clean();
/* Clear configuration */
bgp_damp_config_clean (&bgp_damp_cfg);
bgp_damp_config_clean(&bgp_damp_cfg);
UNSET_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
UNSET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
return 0;
}
void
bgp_config_write_damp (struct vty *vty)
void bgp_config_write_damp(struct vty *vty)
{
if (bgp_damp_cfg.half_life == DEFAULT_HALF_LIFE*60
if (bgp_damp_cfg.half_life == DEFAULT_HALF_LIFE * 60
&& bgp_damp_cfg.reuse_limit == DEFAULT_REUSE
&& bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS
&& bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life*4)
vty_out (vty, " bgp dampening\n");
else if (bgp_damp_cfg.half_life != DEFAULT_HALF_LIFE*60
&& bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life * 4)
vty_out(vty, " bgp dampening\n");
else if (bgp_damp_cfg.half_life != DEFAULT_HALF_LIFE * 60
&& bgp_damp_cfg.reuse_limit == DEFAULT_REUSE
&& bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS
&& bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life*4)
vty_out (vty, " bgp dampening %lld\n",
&& bgp_damp_cfg.max_suppress_time
== bgp_damp_cfg.half_life * 4)
vty_out(vty, " bgp dampening %lld\n",
bgp_damp_cfg.half_life / 60LL);
else
vty_out (vty, " bgp dampening %lld %d %d %lld\n",
bgp_damp_cfg.half_life/60LL,
bgp_damp_cfg.reuse_limit,
vty_out(vty, " bgp dampening %lld %d %d %lld\n",
bgp_damp_cfg.half_life / 60LL, bgp_damp_cfg.reuse_limit,
bgp_damp_cfg.suppress_value,
bgp_damp_cfg.max_suppress_time / 60LL);
}
static const char *
bgp_get_reuse_time (unsigned int penalty, char *buf, size_t len, u_char use_json, json_object *json)
static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
size_t len, u_char use_json,
json_object *json)
{
time_t reuse_time = 0;
struct tm *tm = NULL;
int time_store = 0;
if (penalty > damp->reuse_limit)
{
reuse_time = (int) (DELTA_T * ((log((double)damp->reuse_limit/penalty))/(log(damp->decay_array[1]))));
if (penalty > damp->reuse_limit) {
reuse_time = (int)(DELTA_T
* ((log((double)damp->reuse_limit / penalty))
/ (log(damp->decay_array[1]))));
if (reuse_time > damp->max_suppress_time)
reuse_time = damp->max_suppress_time;
tm = gmtime (&reuse_time);
}
else
tm = gmtime(&reuse_time);
} else
reuse_time = 0;
/* Making formatted timer strings. */
/* Making formatted timer strings. */
#define ONE_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7
if (reuse_time == 0)
{
if (reuse_time == 0) {
if (use_json)
json_object_int_add(json, "reuseTimerMsecs", 0);
else
snprintf (buf, len, "00:00:00");
}
else if (reuse_time < ONE_DAY_SECOND)
{
if (use_json)
{
time_store = (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs", time_store);
}
else
snprintf (buf, len, "%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
else if (reuse_time < ONE_WEEK_SECOND)
{
if (use_json)
{
time_store = (86400000 * tm->tm_yday) + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs", time_store);
}
else
snprintf (buf, len, "%dd%02dh%02dm",
tm->tm_yday, tm->tm_hour, tm->tm_min);
}
else
{
if (use_json)
{
time_store = (604800000 * tm->tm_yday/7) + (86400000 * (tm->tm_yday - ((tm->tm_yday/7) * 7))) + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs", time_store);
}
else
snprintf (buf, len, "%02dw%dd%02dh",
tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
snprintf(buf, len, "00:00:00");
} else if (reuse_time < ONE_DAY_SECOND) {
if (use_json) {
time_store = (3600000 * tm->tm_hour)
+ (60000 * tm->tm_min)
+ (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs",
time_store);
} else
snprintf(buf, len, "%02d:%02d:%02d", tm->tm_hour,
tm->tm_min, tm->tm_sec);
} else if (reuse_time < ONE_WEEK_SECOND) {
if (use_json) {
time_store = (86400000 * tm->tm_yday)
+ (3600000 * tm->tm_hour)
+ (60000 * tm->tm_min)
+ (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs",
time_store);
} else
snprintf(buf, len, "%dd%02dh%02dm", tm->tm_yday,
tm->tm_hour, tm->tm_min);
} else {
if (use_json) {
time_store =
(604800000 * tm->tm_yday / 7)
+ (86400000
* (tm->tm_yday - ((tm->tm_yday / 7) * 7)))
+ (3600000 * tm->tm_hour) + (60000 * tm->tm_min)
+ (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs",
time_store);
} else
snprintf(buf, len, "%02dw%dd%02dh", tm->tm_yday / 7,
tm->tm_yday - ((tm->tm_yday / 7) * 7),
tm->tm_hour);
}
return buf;
}
void
bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo,
void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
json_object *json_path)
{
struct bgp_damp_info *bdi;
@ -623,42 +606,45 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo,
/* If dampening is not enabled or there is no dampening information,
return immediately. */
if (! damp || ! bdi)
if (!damp || !bdi)
return;
/* Calculate new penalty. */
t_now = bgp_clock ();
t_now = bgp_clock();
t_diff = t_now - bdi->t_updated;
penalty = bgp_damp_decay (t_diff, bdi->penalty);
penalty = bgp_damp_decay(t_diff, bdi->penalty);
if (json_path)
{
if (json_path) {
json_object_int_add(json_path, "dampeningPenalty", penalty);
json_object_int_add(json_path, "dampeningFlapCount", bdi->flap);
peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, 1, json_path);
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 1,
json_path);
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
&& ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 1, json_path);
}
else
{
vty_out (vty, " Dampinfo: penalty %d, flapped %d times in %s",
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1,
json_path);
} else {
vty_out(vty,
" Dampinfo: penalty %d, flapped %d times in %s",
penalty, bdi->flap,
peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, 0, json_path));
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0,
json_path));
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
&& ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
vty_out (vty, ", reuse in %s",
bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 0, json_path));
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
vty_out(vty, ", reuse in %s",
bgp_get_reuse_time(penalty, timebuf,
BGP_UPTIME_LEN, 0,
json_path));
vty_out (vty, "\n");
vty_out(vty, "\n");
}
}
const char *
bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo,
char *timebuf, size_t len, u_char use_json, json_object *json)
const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo,
char *timebuf, size_t len, u_char use_json,
json_object *json)
{
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
@ -672,45 +658,38 @@ bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo,
/* If dampening is not enabled or there is no dampening information,
return immediately. */
if (! damp || ! bdi)
if (!damp || !bdi)
return NULL;
/* Calculate new penalty. */
t_now = bgp_clock ();
t_now = bgp_clock();
t_diff = t_now - bdi->t_updated;
penalty = bgp_damp_decay (t_diff, bdi->penalty);
penalty = bgp_damp_decay(t_diff, bdi->penalty);
return bgp_get_reuse_time (penalty, timebuf, len, use_json, json);
return bgp_get_reuse_time(penalty, timebuf, len, use_json, json);
}
int
bgp_show_dampening_parameters (struct vty *vty, afi_t afi, safi_t safi)
int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi)
{
struct bgp *bgp;
bgp = bgp_get_default();
if (bgp == NULL)
{
vty_out (vty, "No BGP process is configured\n");
if (bgp == NULL) {
vty_out(vty, "No BGP process is configured\n");
return CMD_WARNING;
}
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
{
vty_out (vty, "Half-life time: %lld min\n",
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) {
vty_out(vty, "Half-life time: %lld min\n",
(long long)damp->half_life / 60);
vty_out (vty, "Reuse penalty: %d\n",
damp->reuse_limit);
vty_out (vty, "Suppress penalty: %d\n",
damp->suppress_value);
vty_out (vty, "Max suppress time: %lld min\n",
vty_out(vty, "Reuse penalty: %d\n", damp->reuse_limit);
vty_out(vty, "Suppress penalty: %d\n", damp->suppress_value);
vty_out(vty, "Max suppress time: %lld min\n",
(long long)damp->max_suppress_time / 60);
vty_out (vty, "Max supress penalty: %u\n",
damp->ceiling);
vty_out (vty, "\n");
}
else
vty_out (vty, "dampening not enabled for %s\n",
vty_out(vty, "Max supress penalty: %u\n", damp->ceiling);
vty_out(vty, "\n");
} else
vty_out(vty, "dampening not enabled for %s\n",
afi == AFI_IP ? "IPv4" : "IPv6");
return CMD_SUCCESS;

View File

@ -22,8 +22,7 @@
#define _QUAGGA_BGP_DAMP_H
/* Structure maintained on a per-route basis. */
struct bgp_damp_info
{
struct bgp_damp_info {
/* Doubly linked list. This information must be linked to
reuse_list or no_reuse_list. */
struct bgp_damp_info *next;
@ -63,8 +62,7 @@ struct bgp_damp_info
};
/* Specified parameter set configuration. */
struct bgp_damp_config
{
struct bgp_damp_config {
/* Value over which routes suppressed. */
unsigned int suppress_value;
@ -107,7 +105,7 @@ struct bgp_damp_config
struct bgp_damp_info *no_reuse_list;
/* Reuse timer thread per-set base. */
struct thread* t_reuse;
struct thread *t_reuse;
};
#define BGP_DAMP_NONE 0
@ -129,20 +127,22 @@ struct bgp_damp_config
#define REUSE_LIST_SIZE 256
#define REUSE_ARRAY_SIZE 1024
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);
extern int bgp_damp_disable (struct bgp *, afi_t, safi_t);
extern int bgp_damp_withdraw (struct bgp_info *, struct bgp_node *,
afi_t, safi_t, int);
extern int bgp_damp_update (struct bgp_info *, struct bgp_node *, afi_t, safi_t);
extern int bgp_damp_scan (struct bgp_info *, afi_t, safi_t);
extern void bgp_damp_info_free (struct bgp_damp_info *, int);
extern void bgp_damp_info_clean (void);
extern int bgp_damp_decay (time_t, int);
extern void bgp_config_write_damp (struct vty *);
extern void bgp_damp_info_vty (struct vty *, struct bgp_info *, json_object *json_path);
extern const char * bgp_damp_reuse_time_vty (struct vty *, struct bgp_info *,
char *, size_t, u_char, json_object *);
extern int bgp_show_dampening_parameters (struct vty *vty, 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,
safi_t, int);
extern int bgp_damp_update(struct bgp_info *, struct bgp_node *, afi_t, safi_t);
extern int bgp_damp_scan(struct bgp_info *, afi_t, safi_t);
extern void bgp_damp_info_free(struct bgp_damp_info *, int);
extern void bgp_damp_info_clean(void);
extern int bgp_damp_decay(time_t, int);
extern void bgp_config_write_damp(struct vty *);
extern void bgp_damp_info_vty(struct vty *, struct bgp_info *,
json_object *json_path);
extern const char *bgp_damp_reuse_time_vty(struct vty *, struct bgp_info *,
char *, size_t, u_char,
json_object *);
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t);
#endif /* _QUAGGA_BGP_DAMP_H */

File diff suppressed because it is too large Load Diff

View File

@ -57,10 +57,10 @@ extern int Debug_Radix;
#define DETAIL 6
/* Prototypes. */
extern void bgp_debug_init (void);
extern void bgp_packet_dump (struct stream *);
extern void bgp_debug_init(void);
extern void bgp_packet_dump(struct stream *);
extern int debug (unsigned int option);
extern int debug(unsigned int option);
extern unsigned long conf_bgp_debug_as4;
extern unsigned long conf_bgp_debug_neighbor_events;
@ -92,8 +92,7 @@ extern struct list *bgp_debug_update_prefixes;
extern struct list *bgp_debug_bestpath_prefixes;
extern struct list *bgp_debug_zebra_prefixes;
struct bgp_debug_filter
{
struct bgp_debug_filter {
char *host;
struct prefix *p;
};
@ -138,11 +137,11 @@ struct bgp_debug_filter
extern const char *bgp_type_str[];
extern int bgp_dump_attr (struct attr *, char *, size_t);
extern int bgp_dump_attr(struct attr *, char *, size_t);
extern int bgp_debug_peer_updout_enabled(char *host);
extern const char *bgp_notify_code_str(char);
extern const char *bgp_notify_subcode_str(char, char);
extern void bgp_notify_print (struct peer *, struct bgp_notify *, const char *);
extern void bgp_notify_print(struct peer *, struct bgp_notify *, const char *);
extern const struct message bgp_status_msg[];
extern int bgp_debug_neighbor_events(struct peer *peer);
@ -153,9 +152,10 @@ extern int bgp_debug_bestpath(struct prefix *p);
extern int bgp_debug_zebra(struct prefix *p);
extern int bgp_debug_count(void);
extern const char *bgp_debug_rdpfxpath2str (afi_t, safi_t, struct prefix_rd *,
extern const char *bgp_debug_rdpfxpath2str(afi_t, safi_t, struct prefix_rd *,
union prefixconstptr, mpls_label_t *,
int, u_int32_t, char *, int);
const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data, size_t datalen);
const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data,
size_t datalen);
#endif /* _QUAGGA_BGP_DEBUG_H */

View File

@ -37,8 +37,7 @@
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_dump.h"
enum bgp_dump_type
{
enum bgp_dump_type {
BGP_DUMP_ALL,
BGP_DUMP_ALL_ET,
BGP_DUMP_UPDATES,
@ -49,15 +48,11 @@ enum bgp_dump_type
static const struct bgp_dump_type_map {
enum bgp_dump_type type;
const char *str;
} bgp_dump_type_map[] =
{
{BGP_DUMP_ALL, "all"},
{BGP_DUMP_ALL_ET, "all-et"},
{BGP_DUMP_UPDATES, "updates"},
{BGP_DUMP_UPDATES_ET, "updates-et"},
{BGP_DUMP_ROUTES, "routes-mrt"},
{0, NULL},
};
} bgp_dump_type_map[] = {
{BGP_DUMP_ALL, "all"}, {BGP_DUMP_ALL_ET, "all-et"},
{BGP_DUMP_UPDATES, "updates"}, {BGP_DUMP_UPDATES_ET, "updates-et"},
{BGP_DUMP_ROUTES, "routes-mrt"}, {0, NULL},
};
enum MRT_MSG_TYPES {
MSG_NULL,
@ -76,8 +71,7 @@ enum MRT_MSG_TYPES {
MSG_TABLE_DUMP_V2 /* routing table dump, version 2 */
};
struct bgp_dump
{
struct bgp_dump {
enum bgp_dump_type type;
char *filename;
@ -91,8 +85,8 @@ struct bgp_dump
struct thread *t_interval;
};
static int bgp_dump_unset (struct bgp_dump *bgp_dump);
static int bgp_dump_interval_func (struct thread *);
static int bgp_dump_unset(struct bgp_dump *bgp_dump);
static int bgp_dump_interval_func(struct thread *);
/* BGP packet dump output buffer. */
struct stream *bgp_dump_obuf;
@ -106,8 +100,7 @@ struct bgp_dump bgp_dump_updates;
/* BGP dump structure for 'dump bgp routes' */
struct bgp_dump bgp_dump_routes;
static FILE *
bgp_dump_open_file (struct bgp_dump *bgp_dump)
static FILE *bgp_dump_open_file(struct bgp_dump *bgp_dump)
{
int ret;
time_t clock;
@ -116,33 +109,30 @@ bgp_dump_open_file (struct bgp_dump *bgp_dump)
char realpath[MAXPATHLEN];
mode_t oldumask;
time (&clock);
tm = localtime (&clock);
time(&clock);
tm = localtime(&clock);
if (bgp_dump->filename[0] != DIRECTORY_SEP)
{
sprintf (fullpath, "%s/%s", vty_get_cwd (), bgp_dump->filename);
ret = strftime (realpath, MAXPATHLEN, fullpath, tm);
}
else
ret = strftime (realpath, MAXPATHLEN, bgp_dump->filename, tm);
if (bgp_dump->filename[0] != DIRECTORY_SEP) {
sprintf(fullpath, "%s/%s", vty_get_cwd(), bgp_dump->filename);
ret = strftime(realpath, MAXPATHLEN, fullpath, tm);
} else
ret = strftime(realpath, MAXPATHLEN, bgp_dump->filename, tm);
if (ret == 0)
{
zlog_warn ("bgp_dump_open_file: strftime error");
if (ret == 0) {
zlog_warn("bgp_dump_open_file: strftime error");
return NULL;
}
if (bgp_dump->fp)
fclose (bgp_dump->fp);
fclose(bgp_dump->fp);
oldumask = umask(0777 & ~LOGFILE_MASK);
bgp_dump->fp = fopen (realpath, "w");
bgp_dump->fp = fopen(realpath, "w");
if (bgp_dump->fp == NULL)
{
zlog_warn ("bgp_dump_open_file: %s: %s", realpath, strerror (errno));
if (bgp_dump->fp == NULL) {
zlog_warn("bgp_dump_open_file: %s: %s", realpath,
strerror(errno));
umask(oldumask);
return NULL;
}
@ -151,44 +141,44 @@ bgp_dump_open_file (struct bgp_dump *bgp_dump)
return bgp_dump->fp;
}
static int
bgp_dump_interval_add (struct bgp_dump *bgp_dump, int interval)
static int bgp_dump_interval_add(struct bgp_dump *bgp_dump, int interval)
{
int secs_into_day;
time_t t;
struct tm *tm;
if (interval > 0)
{
if (interval > 0) {
/* Periodic dump every interval seconds */
if ((interval < 86400) && ((86400 % interval) == 0))
{
/* Dump at predictable times: if a day has a whole number of
* intervals, dump every interval seconds starting from midnight
if ((interval < 86400) && ((86400 % interval) == 0)) {
/* Dump at predictable times: if a day has a whole
* number of
* intervals, dump every interval seconds starting from
* midnight
*/
(void) time(&t);
(void)time(&t);
tm = localtime(&t);
secs_into_day = tm->tm_sec + 60*tm->tm_min + 60*60*tm->tm_hour;
interval = interval - secs_into_day % interval; /* always > 0 */
secs_into_day = tm->tm_sec + 60 * tm->tm_min
+ 60 * 60 * tm->tm_hour;
interval = interval
- secs_into_day % interval; /* always > 0 */
}
bgp_dump->t_interval = NULL;
thread_add_timer(bm->master, bgp_dump_interval_func, bgp_dump, interval,
&bgp_dump->t_interval);
}
else
{
/* One-off dump: execute immediately, don't affect any scheduled dumps */
thread_add_timer(bm->master, bgp_dump_interval_func, bgp_dump,
interval, &bgp_dump->t_interval);
} else {
/* One-off dump: execute immediately, don't affect any scheduled
* dumps */
bgp_dump->t_interval = NULL;
thread_add_event(bm->master, bgp_dump_interval_func, bgp_dump, 0,
&bgp_dump->t_interval);
thread_add_event(bm->master, bgp_dump_interval_func, bgp_dump,
0, &bgp_dump->t_interval);
}
return 0;
}
/* Dump common header. */
static void
bgp_dump_header (struct stream *obuf, int type, int subtype, int dump_type)
static void bgp_dump_header(struct stream *obuf, int type, int subtype,
int dump_type)
{
struct timeval clock;
long msecs;
@ -204,29 +194,27 @@ bgp_dump_header (struct stream *obuf, int type, int subtype, int dump_type)
msecs = clock.tv_usec;
/* Put dump packet header. */
stream_putl (obuf, secs);
stream_putw (obuf, type);
stream_putw (obuf, subtype);
stream_putl (obuf, 0); /* len */
stream_putl(obuf, secs);
stream_putw(obuf, type);
stream_putw(obuf, subtype);
stream_putl(obuf, 0); /* len */
/* Adding microseconds for the MRT Extended Header */
if (type == MSG_PROTOCOL_BGP4MP_ET)
stream_putl (obuf, msecs);
stream_putl(obuf, msecs);
}
static void
bgp_dump_set_size (struct stream *s, int type)
static void bgp_dump_set_size(struct stream *s, int type)
{
/*
* The BGP_DUMP_HEADER_SIZE stay at 12 event when ET:
* "The Microsecond Timestamp is included in the computation
* of the Length field value." (RFC6396 2011)
*/
stream_putl_at (s, 8, stream_get_endp (s) - BGP_DUMP_HEADER_SIZE);
stream_putl_at(s, 8, stream_get_endp(s) - BGP_DUMP_HEADER_SIZE);
}
static void
bgp_dump_routes_index_table(struct bgp *bgp)
static void bgp_dump_routes_index_table(struct bgp *bgp)
{
struct peer *peer;
struct listnode *node;
@ -234,70 +222,69 @@ bgp_dump_routes_index_table(struct bgp *bgp)
struct stream *obuf;
obuf = bgp_dump_obuf;
stream_reset (obuf);
stream_reset(obuf);
/* MRT header */
bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_PEER_INDEX_TABLE,
bgp_dump_header(obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_PEER_INDEX_TABLE,
BGP_DUMP_ROUTES);
/* Collector BGP ID */
stream_put_in_addr (obuf, &bgp->router_id);
stream_put_in_addr(obuf, &bgp->router_id);
/* View name */
if(bgp->name)
{
stream_putw (obuf, strlen(bgp->name));
if (bgp->name) {
stream_putw(obuf, strlen(bgp->name));
stream_put(obuf, bgp->name, strlen(bgp->name));
}
else
{
} else {
stream_putw(obuf, 0);
}
/* Peer count ( plus one extra internal peer ) */
stream_putw (obuf, listcount(bgp->peer) + 1);
stream_putw(obuf, listcount(bgp->peer) + 1);
/* Populate fake peer at index 0, for locally originated routes */
/* Peer type (IPv4) */
stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
stream_putc(obuf,
TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4
+ TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
/* Peer BGP ID (0.0.0.0) */
stream_putl (obuf, 0);
stream_putl(obuf, 0);
/* Peer IP address (0.0.0.0) */
stream_putl (obuf, 0);
stream_putl(obuf, 0);
/* Peer ASN (0) */
stream_putl (obuf, 0);
stream_putl(obuf, 0);
/* Walk down all peers */
for(ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
{
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
/* Peer's type */
if (sockunion_family(&peer->su) == AF_INET)
{
stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
}
else if (sockunion_family(&peer->su) == AF_INET6)
{
stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6);
if (sockunion_family(&peer->su) == AF_INET) {
stream_putc(
obuf,
TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4
+ TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
} else if (sockunion_family(&peer->su) == AF_INET6) {
stream_putc(
obuf,
TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4
+ TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6);
}
/* Peer's BGP ID */
stream_put_in_addr (obuf, &peer->remote_id);
stream_put_in_addr(obuf, &peer->remote_id);
/* Peer's IP address */
if (sockunion_family(&peer->su) == AF_INET)
{
stream_put_in_addr (obuf, &peer->su.sin.sin_addr);
}
else if (sockunion_family(&peer->su) == AF_INET6)
{
stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr,
if (sockunion_family(&peer->su) == AF_INET) {
stream_put_in_addr(obuf, &peer->su.sin.sin_addr);
} else if (sockunion_family(&peer->su) == AF_INET6) {
stream_write(obuf, (u_char *)&peer->su.sin6.sin6_addr,
IPV6_MAX_BYTELEN);
}
/* Peer's AS number. */
/* Note that, as this is an AS4 compliant quagga, the RIB is always AS4 */
stream_putl (obuf, peer->as);
/* Note that, as this is an AS4 compliant quagga, the RIB is
* always AS4 */
stream_putl(obuf, peer->as);
/* Store the peer number for this peer */
peer->table_dump_index = peerno;
@ -306,77 +293,78 @@ bgp_dump_routes_index_table(struct bgp *bgp)
bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);
fflush (bgp_dump_routes.fp);
fwrite(STREAM_DATA(obuf), stream_get_endp(obuf), 1, bgp_dump_routes.fp);
fflush(bgp_dump_routes.fp);
}
static struct bgp_info *
bgp_dump_route_node_record (int afi, struct bgp_node *rn,
struct bgp_info *info, unsigned int seq)
static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
struct bgp_info *info,
unsigned int seq)
{
struct stream *obuf;
size_t sizep;
size_t endp;
obuf = bgp_dump_obuf;
stream_reset (obuf);
stream_reset(obuf);
/* MRT header */
if (afi == AFI_IP)
bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV4_UNICAST,
bgp_dump_header(obuf, MSG_TABLE_DUMP_V2,
TABLE_DUMP_V2_RIB_IPV4_UNICAST,
BGP_DUMP_ROUTES);
else if (afi == AFI_IP6)
bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV6_UNICAST,
bgp_dump_header(obuf, MSG_TABLE_DUMP_V2,
TABLE_DUMP_V2_RIB_IPV6_UNICAST,
BGP_DUMP_ROUTES);
/* Sequence number */
stream_putl (obuf, seq);
stream_putl(obuf, seq);
/* Prefix length */
stream_putc (obuf, rn->p.prefixlen);
stream_putc(obuf, rn->p.prefixlen);
/* Prefix */
if (afi == AFI_IP)
{
/* We'll dump only the useful bits (those not 0), but have to align on 8 bits */
stream_write (obuf, (u_char *)&rn->p.u.prefix4, (rn->p.prefixlen+7)/8);
}
else if (afi == AFI_IP6)
{
/* We'll dump only the useful bits (those not 0), but have to align on 8 bits */
stream_write (obuf, (u_char *)&rn->p.u.prefix6, (rn->p.prefixlen+7)/8);
if (afi == AFI_IP) {
/* We'll dump only the useful bits (those not 0), but have to
* align on 8 bits */
stream_write(obuf, (u_char *)&rn->p.u.prefix4,
(rn->p.prefixlen + 7) / 8);
} else if (afi == AFI_IP6) {
/* We'll dump only the useful bits (those not 0), but have to
* align on 8 bits */
stream_write(obuf, (u_char *)&rn->p.u.prefix6,
(rn->p.prefixlen + 7) / 8);
}
/* Save where we are now, so we can overwride the entry count later */
sizep = stream_get_endp (obuf);
sizep = stream_get_endp(obuf);
/* Entry count */
uint16_t entry_count = 0;
/* Entry count, note that this is overwritten later */
stream_putw (obuf, 0);
stream_putw(obuf, 0);
endp = stream_get_endp (obuf);
for (; info; info = info->next)
{
endp = stream_get_endp(obuf);
for (; info; info = info->next) {
size_t cur_endp;
/* Peer index */
stream_putw (obuf, info->peer->table_dump_index);
stream_putw(obuf, info->peer->table_dump_index);
/* Originated */
stream_putl (obuf, time(NULL) - (bgp_clock() - info->uptime));
stream_putl(obuf, time(NULL) - (bgp_clock() - info->uptime));
/* Dump attribute. */
/* Skip prefix & AFI/SAFI for MP_NLRI */
bgp_dump_routes_attr (obuf, info->attr, &rn->p);
bgp_dump_routes_attr(obuf, info->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
+ BGP_DUMP_HEADER_SIZE)
{
stream_set_endp (obuf, endp);
+ BGP_DUMP_HEADER_SIZE) {
stream_set_endp(obuf, endp);
break;
}
@ -385,25 +373,25 @@ bgp_dump_route_node_record (int afi, struct bgp_node *rn,
}
/* Overwrite the entry count, now that we know the right number */
stream_putw_at (obuf, sizep, entry_count);
stream_putw_at(obuf, sizep, entry_count);
bgp_dump_set_size (obuf, MSG_TABLE_DUMP_V2);
fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);
bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
fwrite(STREAM_DATA(obuf), stream_get_endp(obuf), 1, bgp_dump_routes.fp);
return info;
}
/* Runs under child process. */
static unsigned int
bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
static unsigned int bgp_dump_routes_func(int afi, int first_run,
unsigned int seq)
{
struct bgp_info *info;
struct bgp_node *rn;
struct bgp *bgp;
struct bgp_table *table;
bgp = bgp_get_default ();
bgp = bgp_get_default();
if (!bgp)
return seq;
@ -411,7 +399,8 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
return seq;
/* Note that bgp_dump_routes_index_table will do ipv4 and ipv6 peers,
so this should only be done on the first call to bgp_dump_routes_func.
so this should only be done on the first call to
bgp_dump_routes_func.
( this function will be called once for ipv4 and once for ipv6 ) */
if (first_run)
bgp_dump_routes_index_table(bgp);
@ -419,98 +408,91 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
/* Walk down each BGP route. */
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;
while (info)
{
info = bgp_dump_route_node_record (afi, rn, info, seq);
while (info) {
info = bgp_dump_route_node_record(afi, rn, info, seq);
seq++;
}
}
fflush (bgp_dump_routes.fp);
fflush(bgp_dump_routes.fp);
return seq;
}
static int
bgp_dump_interval_func (struct thread *t)
static int bgp_dump_interval_func(struct thread *t)
{
struct bgp_dump *bgp_dump;
bgp_dump = THREAD_ARG (t);
bgp_dump = THREAD_ARG(t);
bgp_dump->t_interval = NULL;
/* Reschedule dump even if file couldn't be opened this time... */
if (bgp_dump_open_file (bgp_dump) != NULL)
{
/* In case of bgp_dump_routes, we need special route dump function. */
if (bgp_dump->type == BGP_DUMP_ROUTES)
{
unsigned int seq = bgp_dump_routes_func (AFI_IP, 1, 0);
bgp_dump_routes_func (AFI_IP6, 0, seq);
/* Close the file now. For a RIB dump there's no point in leaving
if (bgp_dump_open_file(bgp_dump) != NULL) {
/* In case of bgp_dump_routes, we need special route dump
* function. */
if (bgp_dump->type == BGP_DUMP_ROUTES) {
unsigned int seq = bgp_dump_routes_func(AFI_IP, 1, 0);
bgp_dump_routes_func(AFI_IP6, 0, seq);
/* Close the file now. For a RIB dump there's no point
* in leaving
* it open until the next scheduled dump starts. */
fclose(bgp_dump->fp); bgp_dump->fp = NULL;
fclose(bgp_dump->fp);
bgp_dump->fp = NULL;
}
}
/* if interval is set reschedule */
if (bgp_dump->interval > 0)
bgp_dump_interval_add (bgp_dump, bgp_dump->interval);
bgp_dump_interval_add(bgp_dump, bgp_dump->interval);
return 0;
}
/* Dump common information. */
static void
bgp_dump_common (struct stream *obuf, struct peer *peer, int forceas4)
static void bgp_dump_common(struct stream *obuf, struct peer *peer,
int forceas4)
{
char empty[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
char empty[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/* Source AS number and Destination AS number. */
if (forceas4 || CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) )
{
stream_putl (obuf, peer->as);
stream_putl (obuf, peer->local_as);
}
else
{
stream_putw (obuf, peer->as);
stream_putw (obuf, peer->local_as);
if (forceas4 || CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) {
stream_putl(obuf, peer->as);
stream_putl(obuf, peer->local_as);
} else {
stream_putw(obuf, peer->as);
stream_putw(obuf, peer->local_as);
}
if (peer->su.sa.sa_family == AF_INET)
{
stream_putw (obuf, peer->ifindex);
stream_putw (obuf, AFI_IP);
if (peer->su.sa.sa_family == AF_INET) {
stream_putw(obuf, peer->ifindex);
stream_putw(obuf, AFI_IP);
stream_put (obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN);
stream_put(obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN);
if (peer->su_local)
stream_put (obuf, &peer->su_local->sin.sin_addr, IPV4_MAX_BYTELEN);
stream_put(obuf, &peer->su_local->sin.sin_addr,
IPV4_MAX_BYTELEN);
else
stream_put (obuf, empty, IPV4_MAX_BYTELEN);
}
else if (peer->su.sa.sa_family == AF_INET6)
{
stream_put(obuf, empty, IPV4_MAX_BYTELEN);
} else if (peer->su.sa.sa_family == AF_INET6) {
/* Interface Index and Address family. */
stream_putw (obuf, peer->ifindex);
stream_putw (obuf, AFI_IP6);
stream_putw(obuf, peer->ifindex);
stream_putw(obuf, AFI_IP6);
/* Source IP Address and Destination IP Address. */
stream_put (obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN);
stream_put(obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN);
if (peer->su_local)
stream_put (obuf, &peer->su_local->sin6.sin6_addr, IPV6_MAX_BYTELEN);
stream_put(obuf, &peer->su_local->sin6.sin6_addr,
IPV6_MAX_BYTELEN);
else
stream_put (obuf, empty, IPV6_MAX_BYTELEN);
stream_put(obuf, empty, IPV6_MAX_BYTELEN);
}
}
/* Dump BGP status change. */
void
bgp_dump_state (struct peer *peer, int status_old, int status_new)
void bgp_dump_state(struct peer *peer, int status_old, int status_new)
{
struct stream *obuf;
@ -520,25 +502,24 @@ bgp_dump_state (struct peer *peer, int status_old, int status_new)
/* Make dump stream. */
obuf = bgp_dump_obuf;
stream_reset (obuf);
stream_reset(obuf);
bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_STATE_CHANGE_AS4,
bgp_dump_header(obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_STATE_CHANGE_AS4,
bgp_dump_all.type);
bgp_dump_common (obuf, peer, 1);/* force this in as4speak*/
bgp_dump_common(obuf, peer, 1); /* force this in as4speak*/
stream_putw (obuf, status_old);
stream_putw (obuf, status_new);
stream_putw(obuf, status_old);
stream_putw(obuf, status_new);
/* Set length. */
bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);
bgp_dump_set_size(obuf, MSG_PROTOCOL_BGP4MP);
/* Write to the stream. */
fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_all.fp);
fflush (bgp_dump_all.fp);
fwrite(STREAM_DATA(obuf), stream_get_endp(obuf), 1, bgp_dump_all.fp);
fflush(bgp_dump_all.fp);
}
static void
bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
static void bgp_dump_packet_func(struct bgp_dump *bgp_dump, struct peer *peer,
struct stream *packet)
{
struct stream *obuf;
@ -549,46 +530,41 @@ bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
/* Make dump stream. */
obuf = bgp_dump_obuf;
stream_reset (obuf);
stream_reset(obuf);
/* Dump header and common part. */
if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) )
{
bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE_AS4,
if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) {
bgp_dump_header(obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE_AS4,
bgp_dump->type);
} else {
bgp_dump_header(obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE,
bgp_dump->type);
}
else
{
bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE,
bgp_dump->type);
}
bgp_dump_common (obuf, peer, 0);
bgp_dump_common(obuf, peer, 0);
/* Packet contents. */
stream_put (obuf, STREAM_DATA (packet), stream_get_endp (packet));
stream_put(obuf, STREAM_DATA(packet), stream_get_endp(packet));
/* Set length. */
bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);
bgp_dump_set_size(obuf, MSG_PROTOCOL_BGP4MP);
/* Write to the stream. */
fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump->fp);
fflush (bgp_dump->fp);
fwrite(STREAM_DATA(obuf), stream_get_endp(obuf), 1, bgp_dump->fp);
fflush(bgp_dump->fp);
}
/* Called from bgp_packet.c when BGP packet is received. */
void
bgp_dump_packet (struct peer *peer, int type, struct stream *packet)
void bgp_dump_packet(struct peer *peer, int type, struct stream *packet)
{
/* bgp_dump_all. */
bgp_dump_packet_func (&bgp_dump_all, peer, packet);
bgp_dump_packet_func(&bgp_dump_all, peer, packet);
/* bgp_dump_updates. */
if (type == BGP_MSG_UPDATE)
bgp_dump_packet_func (&bgp_dump_updates, peer, packet);
bgp_dump_packet_func(&bgp_dump_updates, peer, packet);
}
static unsigned int
bgp_dump_parse_time (const char *str)
static unsigned int bgp_dump_parse_time(const char *str)
{
int i;
int len;
@ -601,41 +577,33 @@ bgp_dump_parse_time (const char *str)
total = 0;
seen_h = 0;
seen_m = 0;
len = strlen (str);
len = strlen(str);
for (i = 0; i < len; i++)
{
if (isdigit ((int) str[i]))
{
for (i = 0; i < len; i++) {
if (isdigit((int)str[i])) {
time *= 10;
time += str[i] - '0';
}
else if (str[i] == 'H' || str[i] == 'h')
{
} else if (str[i] == 'H' || str[i] == 'h') {
if (seen_h)
return 0;
if (seen_m)
return 0;
total += time * 60 *60;
total += time * 60 * 60;
time = 0;
seen_h = 1;
}
else if (str[i] == 'M' || str[i] == 'm')
{
} else if (str[i] == 'M' || str[i] == 'm') {
if (seen_m)
return 0;
total += time * 60;
time = 0;
seen_m = 1;
}
else
} else
return 0;
}
return total + time;
}
static int
bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
static int bgp_dump_set(struct vty *vty, struct bgp_dump *bgp_dump,
enum bgp_dump_type type, const char *path,
const char *interval_str)
{
@ -643,16 +611,13 @@ bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
/* Don't schedule duplicate dumps if the dump command is given twice */
if (bgp_dump->filename && strcmp(path, bgp_dump->filename) == 0
&& type == bgp_dump->type)
{
if (interval_str)
{
if (bgp_dump->interval_str &&
strcmp(bgp_dump->interval_str, interval_str) == 0)
&& type == bgp_dump->type) {
if (interval_str) {
if (bgp_dump->interval_str
&& strcmp(bgp_dump->interval_str, interval_str)
== 0)
return CMD_SUCCESS;
}
else
{
} else {
if (!bgp_dump->interval_str)
return CMD_SUCCESS;
}
@ -661,21 +626,18 @@ bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
/* Removing previous config */
bgp_dump_unset(bgp_dump);
if (interval_str)
{
if (interval_str) {
/* Check interval string. */
interval = bgp_dump_parse_time (interval_str);
if (interval == 0)
{
vty_out (vty, "Malformed interval string\n");
interval = bgp_dump_parse_time(interval_str);
if (interval == 0) {
vty_out(vty, "Malformed interval string\n");
return CMD_WARNING_CONFIG_FAILED;
}
/* Setting interval string */
bgp_dump->interval_str = XSTRDUP(MTYPE_BGP_DUMP_STR, interval_str);
}
else
{
bgp_dump->interval_str =
XSTRDUP(MTYPE_BGP_DUMP_STR, interval_str);
} else {
interval = 0;
}
@ -686,46 +648,41 @@ bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
bgp_dump->interval = interval;
/* Set file name. */
bgp_dump->filename = XSTRDUP (MTYPE_BGP_DUMP_STR, path);
bgp_dump->filename = XSTRDUP(MTYPE_BGP_DUMP_STR, path);
/* Create interval thread. */
bgp_dump_interval_add (bgp_dump, interval);
bgp_dump_interval_add(bgp_dump, interval);
/* This should be called when interval is expired. */
bgp_dump_open_file (bgp_dump);
bgp_dump_open_file(bgp_dump);
return CMD_SUCCESS;
}
static int
bgp_dump_unset (struct bgp_dump *bgp_dump)
static int bgp_dump_unset(struct bgp_dump *bgp_dump)
{
/* Removing file name. */
if (bgp_dump->filename)
{
if (bgp_dump->filename) {
XFREE(MTYPE_BGP_DUMP_STR, bgp_dump->filename);
bgp_dump->filename = NULL;
}
/* Closing file. */
if (bgp_dump->fp)
{
fclose (bgp_dump->fp);
if (bgp_dump->fp) {
fclose(bgp_dump->fp);
bgp_dump->fp = NULL;
}
/* Removing interval thread. */
if (bgp_dump->t_interval)
{
thread_cancel (bgp_dump->t_interval);
if (bgp_dump->t_interval) {
thread_cancel(bgp_dump->t_interval);
bgp_dump->t_interval = NULL;
}
bgp_dump->interval = 0;
/* Removing interval string. */
if (bgp_dump->interval_str)
{
if (bgp_dump->interval_str) {
XFREE(MTYPE_BGP_DUMP_STR, bgp_dump->interval_str);
bgp_dump->interval_str = NULL;
}
@ -756,8 +713,7 @@ DEFUN (dump_bgp_all,
if (strmatch(argv[idx_dump_routes]->text, map->str))
bgp_dump_type = map->type;
switch (bgp_dump_type)
{
switch (bgp_dump_type) {
case BGP_DUMP_ALL:
case BGP_DUMP_ALL_ET:
bgp_dump_struct = &bgp_dump_all;
@ -776,7 +732,7 @@ DEFUN (dump_bgp_all,
if (argc == idx_interval + 1)
interval = argv[idx_interval]->arg;
return bgp_dump_set (vty, bgp_dump_struct, bgp_dump_type,
return bgp_dump_set(vty, bgp_dump_struct, bgp_dump_type,
argv[idx_path]->arg, interval);
}
@ -803,8 +759,7 @@ DEFUN (no_dump_bgp_all,
if (strmatch(argv[idx_dump_routes]->text, map->str))
bgp_dump_type = map->type;
switch (bgp_dump_type)
{
switch (bgp_dump_type) {
case BGP_DUMP_ALL:
case BGP_DUMP_ALL_ET:
bgp_dump_struct = &bgp_dump_all;
@ -819,16 +774,11 @@ DEFUN (no_dump_bgp_all,
break;
}
return bgp_dump_unset (bgp_dump_struct);
return bgp_dump_unset(bgp_dump_struct);
}
/* BGP node structure. */
static struct cmd_node bgp_dump_node =
{
DUMP_NODE,
"",
1
};
static struct cmd_node bgp_dump_node = {DUMP_NODE, "", 1};
#if 0
char *
@ -856,72 +806,69 @@ config_time2str (unsigned int interval)
}
#endif
static int
config_write_bgp_dump (struct vty *vty)
static int config_write_bgp_dump(struct vty *vty)
{
if (bgp_dump_all.filename)
{
if (bgp_dump_all.filename) {
const char *type_str = "all";
if (bgp_dump_all.type == BGP_DUMP_ALL_ET)
type_str = "all-et";
if (bgp_dump_all.interval_str)
vty_out (vty, "dump bgp %s %s %s\n", type_str,
bgp_dump_all.filename,bgp_dump_all.interval_str);
vty_out(vty, "dump bgp %s %s %s\n", type_str,
bgp_dump_all.filename,
bgp_dump_all.interval_str);
else
vty_out (vty, "dump bgp %s %s\n", type_str,
vty_out(vty, "dump bgp %s %s\n", type_str,
bgp_dump_all.filename);
}
if (bgp_dump_updates.filename)
{
if (bgp_dump_updates.filename) {
const char *type_str = "updates";
if (bgp_dump_updates.type == BGP_DUMP_UPDATES_ET)
type_str = "updates-et";
if (bgp_dump_updates.interval_str)
vty_out (vty, "dump bgp %s %s %s\n", type_str,
bgp_dump_updates.filename,bgp_dump_updates.interval_str);
vty_out(vty, "dump bgp %s %s %s\n", type_str,
bgp_dump_updates.filename,
bgp_dump_updates.interval_str);
else
vty_out (vty, "dump bgp %s %s\n", type_str,
vty_out(vty, "dump bgp %s %s\n", type_str,
bgp_dump_updates.filename);
}
if (bgp_dump_routes.filename)
{
if (bgp_dump_routes.filename) {
if (bgp_dump_routes.interval_str)
vty_out (vty, "dump bgp routes-mrt %s %s\n",
bgp_dump_routes.filename,bgp_dump_routes.interval_str);
vty_out(vty, "dump bgp routes-mrt %s %s\n",
bgp_dump_routes.filename,
bgp_dump_routes.interval_str);
else
vty_out (vty, "dump bgp routes-mrt %s\n",
vty_out(vty, "dump bgp routes-mrt %s\n",
bgp_dump_routes.filename);
}
return 0;
}
/* Initialize BGP packet dump functionality. */
void
bgp_dump_init (void)
void bgp_dump_init(void)
{
memset (&bgp_dump_all, 0, sizeof (struct bgp_dump));
memset (&bgp_dump_updates, 0, sizeof (struct bgp_dump));
memset (&bgp_dump_routes, 0, sizeof (struct bgp_dump));
memset(&bgp_dump_all, 0, sizeof(struct bgp_dump));
memset(&bgp_dump_updates, 0, sizeof(struct bgp_dump));
memset(&bgp_dump_routes, 0, sizeof(struct bgp_dump));
bgp_dump_obuf = stream_new ((BGP_MAX_PACKET_SIZE << 1)
+ BGP_DUMP_MSG_HEADER + BGP_DUMP_HEADER_SIZE);
bgp_dump_obuf =
stream_new((BGP_MAX_PACKET_SIZE << 1) + BGP_DUMP_MSG_HEADER
+ BGP_DUMP_HEADER_SIZE);
install_node (&bgp_dump_node, config_write_bgp_dump);
install_node(&bgp_dump_node, config_write_bgp_dump);
install_element (CONFIG_NODE, &dump_bgp_all_cmd);
install_element (CONFIG_NODE, &no_dump_bgp_all_cmd);
install_element(CONFIG_NODE, &dump_bgp_all_cmd);
install_element(CONFIG_NODE, &no_dump_bgp_all_cmd);
}
void
bgp_dump_finish (void)
void bgp_dump_finish(void)
{
bgp_dump_unset (&bgp_dump_all);
bgp_dump_unset (&bgp_dump_updates);
bgp_dump_unset (&bgp_dump_routes);
bgp_dump_unset(&bgp_dump_all);
bgp_dump_unset(&bgp_dump_updates);
bgp_dump_unset(&bgp_dump_routes);
stream_free (bgp_dump_obuf);
stream_free(bgp_dump_obuf);
bgp_dump_obuf = NULL;
}

View File

@ -49,9 +49,9 @@
#define TABLE_DUMP_V2_PEER_INDEX_TABLE_AS2 0
#define TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4 2
extern void bgp_dump_init (void);
extern void bgp_dump_finish (void);
extern void bgp_dump_state (struct peer *, int, int);
extern void bgp_dump_packet (struct peer *, int, struct stream *);
extern void bgp_dump_init(void);
extern void bgp_dump_finish(void);
extern void bgp_dump_state(struct peer *, int, int);
extern void bgp_dump_packet(struct peer *, int, struct stream *);
#endif /* _QUAGGA_BGP_DUMP_H */

View File

@ -36,27 +36,24 @@
static struct hash *ecomhash;
/* Allocate a new ecommunities. */
struct ecommunity *
ecommunity_new (void)
struct ecommunity *ecommunity_new(void)
{
return (struct ecommunity *) XCALLOC (MTYPE_ECOMMUNITY,
sizeof (struct ecommunity));
return (struct ecommunity *)XCALLOC(MTYPE_ECOMMUNITY,
sizeof(struct ecommunity));
}
/* Allocate ecommunities. */
void
ecommunity_free (struct ecommunity **ecom)
void ecommunity_free(struct ecommunity **ecom)
{
if ((*ecom)->val)
XFREE (MTYPE_ECOMMUNITY_VAL, (*ecom)->val);
XFREE(MTYPE_ECOMMUNITY_VAL, (*ecom)->val);
if ((*ecom)->str)
XFREE (MTYPE_ECOMMUNITY_STR, (*ecom)->str);
XFREE (MTYPE_ECOMMUNITY, *ecom);
XFREE(MTYPE_ECOMMUNITY_STR, (*ecom)->str);
XFREE(MTYPE_ECOMMUNITY, *ecom);
ecom = NULL;
}
static void
ecommunity_hash_free (struct ecommunity *ecom)
static void ecommunity_hash_free(struct ecommunity *ecom)
{
ecommunity_free(&ecom);
}
@ -67,27 +64,24 @@ ecommunity_hash_free (struct ecommunity *ecom)
structure, we don't add the value. Newly added value is sorted by
numerical order. When the value is added to the structure return 1
else return 0. */
int
ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
int ecommunity_add_val(struct ecommunity *ecom, struct ecommunity_val *eval)
{
u_int8_t *p;
int ret;
int c;
/* When this is fist value, just add it. */
if (ecom->val == NULL)
{
if (ecom->val == NULL) {
ecom->size++;
ecom->val = XMALLOC (MTYPE_ECOMMUNITY_VAL, ecom_length (ecom));
memcpy (ecom->val, eval->val, ECOMMUNITY_SIZE);
ecom->val = XMALLOC(MTYPE_ECOMMUNITY_VAL, ecom_length(ecom));
memcpy(ecom->val, eval->val, ECOMMUNITY_SIZE);
return 1;
}
/* If the value already exists in the structure return 0. */
c = 0;
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
{
ret = memcmp (p, eval->val, ECOMMUNITY_SIZE);
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++) {
ret = memcmp(p, eval->val, ECOMMUNITY_SIZE);
if (ret == 0)
return 0;
if (ret > 0)
@ -96,12 +90,13 @@ ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
/* Add the value to the structure with numerical sorting. */
ecom->size++;
ecom->val = XREALLOC (MTYPE_ECOMMUNITY_VAL, ecom->val, ecom_length (ecom));
ecom->val =
XREALLOC(MTYPE_ECOMMUNITY_VAL, ecom->val, ecom_length(ecom));
memmove (ecom->val + (c + 1) * ECOMMUNITY_SIZE,
memmove(ecom->val + (c + 1) * ECOMMUNITY_SIZE,
ecom->val + c * ECOMMUNITY_SIZE,
(ecom->size - 1 - c) * ECOMMUNITY_SIZE);
memcpy (ecom->val + c * ECOMMUNITY_SIZE, eval->val, ECOMMUNITY_SIZE);
memcpy(ecom->val + c * ECOMMUNITY_SIZE, eval->val, ECOMMUNITY_SIZE);
return 1;
}
@ -109,29 +104,27 @@ ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
/* This function takes pointer to Extended Communites strucutre then
create a new Extended Communities structure by uniq and sort each
Extended Communities value. */
struct ecommunity *
ecommunity_uniq_sort (struct ecommunity *ecom)
struct ecommunity *ecommunity_uniq_sort(struct ecommunity *ecom)
{
int i;
struct ecommunity *new;
struct ecommunity_val *eval;
if (! ecom)
if (!ecom)
return NULL;
new = ecommunity_new ();
new = ecommunity_new();
for (i = 0; i < ecom->size; i++)
{
eval = (struct ecommunity_val *) (ecom->val + (i * ECOMMUNITY_SIZE));
ecommunity_add_val (new, eval);
for (i = 0; i < ecom->size; i++) {
eval = (struct ecommunity_val *)(ecom->val
+ (i * ECOMMUNITY_SIZE));
ecommunity_add_val(new, eval);
}
return new;
}
/* Parse Extended Communites Attribute in BGP packet. */
struct ecommunity *
ecommunity_parse (u_int8_t *pnt, u_short length)
struct ecommunity *ecommunity_parse(u_int8_t *pnt, u_short length)
{
struct ecommunity tmp;
struct ecommunity *new;
@ -147,80 +140,79 @@ ecommunity_parse (u_int8_t *pnt, u_short length)
/* Create a new Extended Communities Attribute by uniq and sort each
Extended Communities value */
new = ecommunity_uniq_sort (&tmp);
new = ecommunity_uniq_sort(&tmp);
return ecommunity_intern (new);
return ecommunity_intern(new);
}
/* Duplicate the Extended Communities Attribute structure. */
struct ecommunity *
ecommunity_dup (struct ecommunity *ecom)
struct ecommunity *ecommunity_dup(struct ecommunity *ecom)
{
struct ecommunity *new;
new = XCALLOC (MTYPE_ECOMMUNITY, sizeof (struct ecommunity));
new = XCALLOC(MTYPE_ECOMMUNITY, sizeof(struct ecommunity));
new->size = ecom->size;
if (new->size)
{
new->val = XMALLOC (MTYPE_ECOMMUNITY_VAL, ecom->size * ECOMMUNITY_SIZE);
memcpy (new->val, ecom->val, ecom->size * ECOMMUNITY_SIZE);
}
else
if (new->size) {
new->val = XMALLOC(MTYPE_ECOMMUNITY_VAL,
ecom->size * ECOMMUNITY_SIZE);
memcpy(new->val, ecom->val, ecom->size * ECOMMUNITY_SIZE);
} else
new->val = NULL;
return new;
}
/* Retrun string representation of communities attribute. */
char *
ecommunity_str (struct ecommunity *ecom)
char *ecommunity_str(struct ecommunity *ecom)
{
if (! ecom->str)
ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
if (!ecom->str)
ecom->str =
ecommunity_ecom2str(ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
return ecom->str;
}
/* Merge two Extended Communities Attribute structure. */
struct ecommunity *
ecommunity_merge (struct ecommunity *ecom1, struct ecommunity *ecom2)
struct ecommunity *ecommunity_merge(struct ecommunity *ecom1,
struct ecommunity *ecom2)
{
if (ecom1->val)
ecom1->val = XREALLOC (MTYPE_ECOMMUNITY_VAL, ecom1->val,
ecom1->val =
XREALLOC(MTYPE_ECOMMUNITY_VAL, ecom1->val,
(ecom1->size + ecom2->size) * ECOMMUNITY_SIZE);
else
ecom1->val = XMALLOC (MTYPE_ECOMMUNITY_VAL,
ecom1->val =
XMALLOC(MTYPE_ECOMMUNITY_VAL,
(ecom1->size + ecom2->size) * ECOMMUNITY_SIZE);
memcpy (ecom1->val + (ecom1->size * ECOMMUNITY_SIZE),
ecom2->val, ecom2->size * ECOMMUNITY_SIZE);
memcpy(ecom1->val + (ecom1->size * ECOMMUNITY_SIZE), ecom2->val,
ecom2->size * ECOMMUNITY_SIZE);
ecom1->size += ecom2->size;
return ecom1;
}
/* Intern Extended Communities Attribute. */
struct ecommunity *
ecommunity_intern (struct ecommunity *ecom)
struct ecommunity *ecommunity_intern(struct ecommunity *ecom)
{
struct ecommunity *find;
assert (ecom->refcnt == 0);
assert(ecom->refcnt == 0);
find = (struct ecommunity *) hash_get (ecomhash, ecom, hash_alloc_intern);
find = (struct ecommunity *)hash_get(ecomhash, ecom, hash_alloc_intern);
if (find != ecom)
ecommunity_free (&ecom);
ecommunity_free(&ecom);
find->refcnt++;
if (! find->str)
find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY, 0);
if (!find->str)
find->str =
ecommunity_ecom2str(find, ECOMMUNITY_FORMAT_DISPLAY, 0);
return find;
}
/* Unintern Extended Communities Attribute. */
void
ecommunity_unintern (struct ecommunity **ecom)
void ecommunity_unintern(struct ecommunity **ecom)
{
struct ecommunity *ret;
@ -228,19 +220,17 @@ ecommunity_unintern (struct ecommunity **ecom)
(*ecom)->refcnt--;
/* Pull off from hash. */
if ((*ecom)->refcnt == 0)
{
if ((*ecom)->refcnt == 0) {
/* Extended community must be in the hash. */
ret = (struct ecommunity *) hash_release (ecomhash, *ecom);
assert (ret != NULL);
ret = (struct ecommunity *)hash_release(ecomhash, *ecom);
assert(ret != NULL);
ecommunity_free (ecom);
ecommunity_free(ecom);
}
}
/* Utinity function to make hash key. */
unsigned int
ecommunity_hash_make (void *arg)
unsigned int ecommunity_hash_make(void *arg)
{
const struct ecommunity *ecom = arg;
int size = ecom->size * ECOMMUNITY_SIZE;
@ -248,8 +238,7 @@ ecommunity_hash_make (void *arg)
unsigned int key = 0;
int c;
for (c = 0; c < size; c += ECOMMUNITY_SIZE)
{
for (c = 0; c < size; c += ECOMMUNITY_SIZE) {
key += pnt[c];
key += pnt[c + 1];
key += pnt[c + 2];
@ -264,8 +253,7 @@ ecommunity_hash_make (void *arg)
}
/* Compare two Extended Communities Attribute structure. */
int
ecommunity_cmp (const void *arg1, const void *arg2)
int ecommunity_cmp(const void *arg1, const void *arg2)
{
const struct ecommunity *ecom1 = arg1;
const struct ecommunity *ecom2 = arg2;
@ -277,27 +265,25 @@ ecommunity_cmp (const void *arg1, const void *arg2)
return 0;
return (ecom1->size == ecom2->size
&& memcmp (ecom1->val, ecom2->val, ecom1->size * ECOMMUNITY_SIZE) == 0);
&& memcmp(ecom1->val, ecom2->val, ecom1->size * ECOMMUNITY_SIZE)
== 0);
}
/* Initialize Extended Comminities related hash. */
void
ecommunity_init (void)
void ecommunity_init(void)
{
ecomhash = hash_create (ecommunity_hash_make, ecommunity_cmp, NULL);
ecomhash = hash_create(ecommunity_hash_make, ecommunity_cmp, NULL);
}
void
ecommunity_finish (void)
void ecommunity_finish(void)
{
hash_clean (ecomhash, (void (*)(void *))ecommunity_hash_free);
hash_free (ecomhash);
hash_clean(ecomhash, (void (*)(void *))ecommunity_hash_free);
hash_free(ecomhash);
ecomhash = NULL;
}
/* Extended Communities token enum. */
enum ecommunity_token
{
enum ecommunity_token {
ecommunity_token_unknown = 0,
ecommunity_token_rt,
ecommunity_token_soo,
@ -308,20 +294,16 @@ enum ecommunity_token
* Encode BGP extended community from passed values. Supports types
* defined in RFC 4360 and well-known sub-types.
*/
static int
ecommunity_encode (u_char type, u_char sub_type, int trans,
as_t as, struct in_addr ip, u_int32_t val,
static int ecommunity_encode(u_char type, u_char sub_type, int trans, as_t as,
struct in_addr ip, u_int32_t val,
struct ecommunity_val *eval)
{
assert (eval);
if (type == ECOMMUNITY_ENCODE_AS)
{
assert(eval);
if (type == ECOMMUNITY_ENCODE_AS) {
if (as > BGP_AS_MAX)
return -1;
}
else if (type == ECOMMUNITY_ENCODE_IP
|| type == ECOMMUNITY_ENCODE_AS4)
{
} else if (type == ECOMMUNITY_ENCODE_IP
|| type == ECOMMUNITY_ENCODE_AS4) {
if (val > UINT16_MAX)
return -1;
}
@ -331,23 +313,18 @@ ecommunity_encode (u_char type, u_char sub_type, int trans,
if (!trans)
eval->val[0] |= ECOMMUNITY_FLAG_NON_TRANSITIVE;
eval->val[1] = sub_type;
if (type == ECOMMUNITY_ENCODE_AS)
{
if (type == ECOMMUNITY_ENCODE_AS) {
eval->val[2] = (as >> 8) & 0xff;
eval->val[3] = as & 0xff;
eval->val[4] = (val >> 24) & 0xff;
eval->val[5] = (val >> 16) & 0xff;
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
else if (type == ECOMMUNITY_ENCODE_IP)
{
memcpy (&eval->val[2], &ip, sizeof (struct in_addr));
} else if (type == ECOMMUNITY_ENCODE_IP) {
memcpy(&eval->val[2], &ip, sizeof(struct in_addr));
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
else
{
} else {
eval->val[2] = (as >> 24) & 0xff;
eval->val[3] = (as >> 16) & 0xff;
eval->val[4] = (as >> 8) & 0xff;
@ -360,8 +337,8 @@ ecommunity_encode (u_char type, u_char sub_type, int trans,
}
/* Get next Extended Communities token from the string. */
static const char *
ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
static const char *ecommunity_gettoken(const char *str,
struct ecommunity_val *eval,
enum ecommunity_token *token)
{
int ret;
@ -377,8 +354,7 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
char buf[INET_ADDRSTRLEN + 1];
/* Skip white space. */
while (isspace ((int) *p))
{
while (isspace((int)*p)) {
p++;
str++;
}
@ -388,47 +364,38 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
return NULL;
/* "rt" and "soo" keyword parse. */
if (! isdigit ((int) *p))
{
if (!isdigit((int)*p)) {
/* "rt" match check. */
if (tolower ((int) *p) == 'r')
{
if (tolower((int)*p) == 'r') {
p++;
if (tolower ((int) *p) == 't')
{
if (tolower((int)*p) == 't') {
p++;
*token = ecommunity_token_rt;
return p;
}
if (isspace ((int) *p) || *p == '\0')
{
if (isspace((int)*p) || *p == '\0') {
*token = ecommunity_token_rt;
return p;
}
goto error;
}
/* "soo" match check. */
else if (tolower ((int) *p) == 's')
{
else if (tolower((int)*p) == 's') {
p++;
if (tolower ((int) *p) == 'o')
{
if (tolower((int)*p) == 'o') {
p++;
if (tolower ((int) *p) == 'o')
{
if (tolower((int)*p) == 'o') {
p++;
*token = ecommunity_token_soo;
return p;
}
if (isspace ((int) *p) || *p == '\0')
{
if (isspace((int)*p) || *p == '\0') {
*token = ecommunity_token_soo;
return p;
}
goto error;
}
if (isspace ((int) *p) || *p == '\0')
{
if (isspace((int)*p) || *p == '\0') {
*token = ecommunity_token_soo;
return p;
}
@ -450,10 +417,8 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
* OPQR: Four byte value
*
*/
while (isdigit ((int) *p) || *p == ':' || *p == '.')
{
if (*p == ':')
{
while (isdigit((int)*p) || *p == ':' || *p == '.') {
if (*p == ':') {
if (separator)
goto error;
@ -462,41 +427,33 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
if ((p - str) > INET_ADDRSTRLEN)
goto error;
memset (buf, 0, INET_ADDRSTRLEN + 1);
memcpy (buf, str, p - str);
memset(buf, 0, INET_ADDRSTRLEN + 1);
memcpy(buf, str, p - str);
if (dot)
{
if (dot) {
/* Parsing A.B.C.D in:
* A.B.C.D:MN
*/
ret = inet_aton (buf, &ip);
ret = inet_aton(buf, &ip);
if (ret == 0)
goto error;
}
else
{
} else {
/* ASN */
as = strtoul (buf, &endptr, 10);
as = strtoul(buf, &endptr, 10);
if (*endptr != '\0' || as == BGP_AS4_MAX)
goto error;
}
}
else if (*p == '.')
{
} else if (*p == '.') {
if (separator)
goto error;
dot++;
if (dot > 4)
goto error;
}
else
{
} else {
digit = 1;
/* We're past the IP/ASN part */
if (separator)
{
if (separator) {
val *= 10;
val += (*p - '0');
}
@ -515,12 +472,12 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
ecomm_type = ECOMMUNITY_ENCODE_AS4;
else
ecomm_type = ECOMMUNITY_ENCODE_AS;
if (ecommunity_encode (ecomm_type, 0, 1, as, ip, val, eval))
if (ecommunity_encode(ecomm_type, 0, 1, as, ip, val, eval))
goto error;
*token = ecommunity_token_val;
return p;
error:
error:
*token = ecommunity_token_unknown;
return p;
}
@ -551,87 +508,76 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
type = 0
keyword_include = 1
*/
struct ecommunity *
ecommunity_str2com (const char *str, int type, int keyword_included)
struct ecommunity *ecommunity_str2com(const char *str, int type,
int keyword_included)
{
struct ecommunity *ecom = NULL;
enum ecommunity_token token = ecommunity_token_unknown;
struct ecommunity_val eval;
int keyword = 0;
while ((str = ecommunity_gettoken (str, &eval, &token)))
{
switch (token)
{
while ((str = ecommunity_gettoken(str, &eval, &token))) {
switch (token) {
case ecommunity_token_rt:
case ecommunity_token_soo:
if (! keyword_included || keyword)
{
if (!keyword_included || keyword) {
if (ecom)
ecommunity_free (&ecom);
ecommunity_free(&ecom);
return NULL;
}
keyword = 1;
if (token == ecommunity_token_rt)
{
if (token == ecommunity_token_rt) {
type = ECOMMUNITY_ROUTE_TARGET;
}
if (token == ecommunity_token_soo)
{
if (token == ecommunity_token_soo) {
type = ECOMMUNITY_SITE_ORIGIN;
}
break;
case ecommunity_token_val:
if (keyword_included)
{
if (! keyword)
{
if (keyword_included) {
if (!keyword) {
if (ecom)
ecommunity_free (&ecom);
ecommunity_free(&ecom);
return NULL;
}
keyword = 0;
}
if (ecom == NULL)
ecom = ecommunity_new ();
ecom = ecommunity_new();
eval.val[1] = type;
ecommunity_add_val (ecom, &eval);
ecommunity_add_val(ecom, &eval);
break;
case ecommunity_token_unknown:
default:
if (ecom)
ecommunity_free (&ecom);
ecommunity_free(&ecom);
return NULL;
}
}
return ecom;
}
static int
ecommunity_rt_soo_str (char *buf, u_int8_t *pnt, int type,
static int ecommunity_rt_soo_str(char *buf, u_int8_t *pnt, int type,
int sub_type, int format)
{
int len = 0;
const char *prefix;
/* For parse Extended Community attribute tupple. */
struct ecommunity_as
{
struct ecommunity_as {
as_t as;
u_int32_t val;
} eas;
struct ecommunity_ip
{
struct ecommunity_ip {
struct in_addr ip;
u_int16_t val;
} eip;
/* Determine prefix for string, if any. */
switch (format)
{
switch (format) {
case ECOMMUNITY_FORMAT_COMMUNITY_LIST:
prefix = (sub_type == ECOMMUNITY_ROUTE_TARGET ? "rt " : "soo ");
break;
@ -647,8 +593,7 @@ ecommunity_rt_soo_str (char *buf, u_int8_t *pnt, int type,
}
/* Put string into buffer. */
if (type == ECOMMUNITY_ENCODE_AS4)
{
if (type == ECOMMUNITY_ENCODE_AS4) {
eas.as = (*pnt++ << 24);
eas.as |= (*pnt++ << 16);
eas.as |= (*pnt++ << 8);
@ -656,10 +601,8 @@ ecommunity_rt_soo_str (char *buf, u_int8_t *pnt, int type,
eas.val = (*pnt++ << 8);
eas.val |= (*pnt++);
len = sprintf (buf, "%s%u:%u", prefix, eas.as, eas.val);
}
else if (type == ECOMMUNITY_ENCODE_AS)
{
len = sprintf(buf, "%s%u:%u", prefix, eas.as, eas.val);
} else if (type == ECOMMUNITY_ENCODE_AS) {
eas.as = (*pnt++ << 8);
eas.as |= (*pnt++);
@ -668,16 +611,15 @@ ecommunity_rt_soo_str (char *buf, u_int8_t *pnt, int type,
eas.val |= (*pnt++ << 8);
eas.val |= (*pnt++);
len = sprintf (buf, "%s%u:%u", prefix, eas.as, eas.val);
}
else if (type == ECOMMUNITY_ENCODE_IP)
{
memcpy (&eip.ip, pnt, 4);
len = sprintf(buf, "%s%u:%u", prefix, eas.as, eas.val);
} else if (type == ECOMMUNITY_ENCODE_IP) {
memcpy(&eip.ip, pnt, 4);
pnt += 4;
eip.val = (*pnt++ << 8);
eip.val |= (*pnt++);
len = sprintf (buf, "%s%s:%u", prefix, inet_ntoa (eip.ip), eip.val);
len = sprintf(buf, "%s%s:%u", prefix, inet_ntoa(eip.ip),
eip.val);
}
return len;
@ -707,8 +649,7 @@ ecommunity_rt_soo_str (char *buf, u_int8_t *pnt, int type,
Filter is added to display only ECOMMUNITY_ROUTE_TARGET in some cases.
0 value displays all
*/
char *
ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
{
int i;
u_int8_t *pnt;
@ -721,32 +662,30 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
int len = 0;
int first = 1;
if (ecom->size == 0)
{
str_buf = XMALLOC (MTYPE_ECOMMUNITY_STR, 1);
if (ecom->size == 0) {
str_buf = XMALLOC(MTYPE_ECOMMUNITY_STR, 1);
str_buf[0] = '\0';
return str_buf;
}
/* Prepare buffer. */
str_buf = XMALLOC (MTYPE_ECOMMUNITY_STR, ECOMMUNITY_STR_DEFAULT_LEN + 1);
str_buf = XMALLOC(MTYPE_ECOMMUNITY_STR, ECOMMUNITY_STR_DEFAULT_LEN + 1);
str_size = ECOMMUNITY_STR_DEFAULT_LEN + 1;
str_buf[0] = '\0';
str_pnt = 0;
for (i = 0; i < ecom->size; i++)
{
for (i = 0; i < ecom->size; i++) {
int unk_ecom = 0;
/* Make it sure size is enough. */
while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size)
{
while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size) {
str_size *= 2;
str_buf = XREALLOC (MTYPE_ECOMMUNITY_STR, str_buf, str_size);
str_buf = XREALLOC(MTYPE_ECOMMUNITY_STR, str_buf,
str_size);
}
/* Space between each value. */
if (! first)
if (!first)
str_buf[str_pnt++] = ' ';
pnt = ecom->val + (i * 8);
@ -754,66 +693,62 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
/* High-order octet of type. */
type = *pnt++;
if (type == ECOMMUNITY_ENCODE_AS ||
type == ECOMMUNITY_ENCODE_IP ||
type == ECOMMUNITY_ENCODE_AS4)
{
if (type == ECOMMUNITY_ENCODE_AS || type == ECOMMUNITY_ENCODE_IP
|| type == ECOMMUNITY_ENCODE_AS4) {
/* Low-order octet of type. */
sub_type = *pnt++;
if (sub_type != ECOMMUNITY_ROUTE_TARGET &&
sub_type != ECOMMUNITY_SITE_ORIGIN)
if (sub_type != ECOMMUNITY_ROUTE_TARGET
&& sub_type != ECOMMUNITY_SITE_ORIGIN)
unk_ecom = 1;
else
len = ecommunity_rt_soo_str (str_buf + str_pnt, pnt, type,
sub_type, format);
}
else if (type == ECOMMUNITY_ENCODE_OPAQUE)
{
len = ecommunity_rt_soo_str(str_buf + str_pnt,
pnt, type, sub_type,
format);
} else if (type == ECOMMUNITY_ENCODE_OPAQUE) {
if (filter == ECOMMUNITY_ROUTE_TARGET)
continue;
if (*pnt == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP)
{
if (*pnt == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP) {
uint16_t tunneltype;
memcpy (&tunneltype, pnt + 5, 2);
memcpy(&tunneltype, pnt + 5, 2);
tunneltype = ntohs(tunneltype);
len = sprintf (str_buf + str_pnt, "ET:%d", tunneltype);
}
else
len = sprintf(str_buf + str_pnt, "ET:%d",
tunneltype);
} else
unk_ecom = 1;
}
else if (type == ECOMMUNITY_ENCODE_EVPN)
{
} else if (type == ECOMMUNITY_ENCODE_EVPN) {
if (filter == ECOMMUNITY_ROUTE_TARGET)
continue;
if (*pnt == ECOMMUNITY_SITE_ORIGIN)
{
if (*pnt == ECOMMUNITY_SITE_ORIGIN) {
char macaddr[6];
pnt++;
memcpy(&macaddr, pnt, 6);
len = sprintf(str_buf + str_pnt, "EVPN:%02x:%02x:%02x:%02x:%02x:%02x",
len = sprintf(
str_buf + str_pnt,
"EVPN:%02x:%02x:%02x:%02x:%02x:%02x",
macaddr[0], macaddr[1], macaddr[2],
macaddr[3], macaddr[4], macaddr[5]);
}
else if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY)
{
} else if (*pnt
== ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
u_int32_t seqnum;
u_char flags = *++pnt;
memcpy (&seqnum, pnt + 2, 4);
memcpy(&seqnum, pnt + 2, 4);
seqnum = ntohl(seqnum);
if (flags & ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY)
len = sprintf (str_buf + str_pnt, "MM:%u, sticky MAC", seqnum);
else
len = sprintf (str_buf + str_pnt, "MM:%u", seqnum);
}
if (flags
& ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY)
len = sprintf(str_buf + str_pnt,
"MM:%u, sticky MAC",
seqnum);
else
len = sprintf(str_buf + str_pnt,
"MM:%u", seqnum);
} else
unk_ecom = 1;
}
else
} else
unk_ecom = 1;
if (unk_ecom)
len = sprintf (str_buf + str_pnt, "?");
len = sprintf(str_buf + str_pnt, "?");
str_pnt += len;
first = 0;
@ -822,8 +757,7 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
return str_buf;
}
int
ecommunity_match (const struct ecommunity *ecom1,
int ecommunity_match(const struct ecommunity *ecom1,
const struct ecommunity *ecom2)
{
int i = 0;
@ -839,11 +773,10 @@ ecommunity_match (const struct ecommunity *ecom1,
return 0;
/* Every community on com2 needs to be on com1 for this to match */
while (i < ecom1->size && j < ecom2->size)
{
if (memcmp (ecom1->val + i * ECOMMUNITY_SIZE,
ecom2->val + j * ECOMMUNITY_SIZE,
ECOMMUNITY_SIZE) == 0)
while (i < ecom1->size && j < ecom2->size) {
if (memcmp(ecom1->val + i * ECOMMUNITY_SIZE,
ecom2->val + j * ECOMMUNITY_SIZE, ECOMMUNITY_SIZE)
== 0)
j++;
i++;
}
@ -855,20 +788,19 @@ ecommunity_match (const struct ecommunity *ecom1,
}
/* return first occurence of type */
extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity *ecom, uint8_t type, uint8_t subtype)
extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *ecom,
uint8_t type, uint8_t subtype)
{
u_int8_t *p;
int c;
/* If the value already exists in the structure return 0. */
c = 0;
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
{
if(p == NULL)
{
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++) {
if (p == NULL) {
continue;
}
if(p[0] == type && p[1] == subtype)
if (p[0] == type && p[1] == subtype)
return (struct ecommunity_val *)p;
}
return NULL;
@ -877,22 +809,20 @@ extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity *ecom,
/* remove ext. community matching type and subtype
* return 1 on success ( removed ), 0 otherwise (not present)
*/
extern int ecommunity_strip (struct ecommunity *ecom, uint8_t type, uint8_t subtype)
extern int ecommunity_strip(struct ecommunity *ecom, uint8_t type,
uint8_t subtype)
{
u_int8_t *p;
int c, found = 0;
/* When this is fist value, just add it. */
if (ecom == NULL || ecom->val == NULL)
{
if (ecom == NULL || ecom->val == NULL) {
return 0;
}
/* If the value already exists in the structure return 0. */
c = 0;
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
{
if (p[0] == type && p[1] == subtype)
{
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++) {
if (p[0] == type && p[1] == subtype) {
found = 1;
break;
}
@ -902,15 +832,15 @@ extern int ecommunity_strip (struct ecommunity *ecom, uint8_t type, uint8_t subt
/* Strip The selected value */
ecom->size--;
/* size is reduced. no memmove to do */
p = XMALLOC (MTYPE_ECOMMUNITY_VAL, ecom->size * ECOMMUNITY_SIZE);
p = XMALLOC(MTYPE_ECOMMUNITY_VAL, ecom->size * ECOMMUNITY_SIZE);
if (c != 0)
memcpy(p, ecom->val, c * ECOMMUNITY_SIZE);
if( (ecom->size - c) != 0)
memcpy(p + (c) * ECOMMUNITY_SIZE,
ecom->val + (c +1)* ECOMMUNITY_SIZE,
if ((ecom->size - c) != 0)
memcpy(p + (c)*ECOMMUNITY_SIZE,
ecom->val + (c + 1) * ECOMMUNITY_SIZE,
(ecom->size - c) * ECOMMUNITY_SIZE);
/* shift last ecommunities */
XFREE (MTYPE_ECOMMUNITY, ecom->val);
XFREE(MTYPE_ECOMMUNITY, ecom->val);
ecom->val = p;
return 1;
}

View File

@ -56,8 +56,7 @@
#define ECOMMUNITY_FLAG_NON_TRANSITIVE 0x40
/* Extended Communities attribute. */
struct ecommunity
{
struct ecommunity {
/* Reference counter. */
unsigned long refcnt;
@ -72,8 +71,7 @@ struct ecommunity
};
/* Extended community value is eight octet. */
struct ecommunity_val
{
struct ecommunity_val {
char val[ECOMMUNITY_SIZE];
};
@ -82,8 +80,7 @@ struct ecommunity_val
/*
* Encode BGP Route Target AS:nn.
*/
static inline void
encode_route_target_as (as_t as, u_int32_t val,
static inline void encode_route_target_as(as_t as, u_int32_t val,
struct ecommunity_val *eval)
{
eval->val[0] = ECOMMUNITY_ENCODE_AS;
@ -99,13 +96,12 @@ encode_route_target_as (as_t as, u_int32_t val,
/*
* Encode BGP Route Target IP:nn.
*/
static inline void
encode_route_target_ip (struct in_addr ip, u_int16_t val,
static inline void encode_route_target_ip(struct in_addr ip, u_int16_t val,
struct ecommunity_val *eval)
{
eval->val[0] = ECOMMUNITY_ENCODE_IP;
eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
memcpy (&eval->val[2], &ip, sizeof (struct in_addr));
memcpy(&eval->val[2], &ip, sizeof(struct in_addr));
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
@ -113,8 +109,7 @@ encode_route_target_ip (struct in_addr ip, u_int16_t val,
/*
* Encode BGP Route Target AS4:nn.
*/
static inline void
encode_route_target_as4 (as_t as, u_int16_t val,
static inline void encode_route_target_as4(as_t as, u_int16_t val,
struct ecommunity_val *eval)
{
eval->val[0] = ECOMMUNITY_ENCODE_AS4;
@ -127,27 +122,32 @@ encode_route_target_as4 (as_t as, u_int16_t val,
eval->val[7] = val & 0xff;
}
extern void ecommunity_init (void);
extern void ecommunity_finish (void);
extern void ecommunity_free (struct ecommunity **);
extern struct ecommunity *ecommunity_parse (u_int8_t *, u_short);
extern struct ecommunity *ecommunity_dup (struct ecommunity *);
extern struct ecommunity *ecommunity_merge (struct ecommunity *, struct ecommunity *);
extern struct ecommunity *ecommunity_uniq_sort (struct ecommunity *);
extern struct ecommunity *ecommunity_intern (struct ecommunity *);
extern int ecommunity_cmp (const void *, const void *);
extern void ecommunity_unintern (struct ecommunity **);
extern unsigned int ecommunity_hash_make (void *);
extern struct ecommunity *ecommunity_str2com (const char *, int, int);
extern char *ecommunity_ecom2str (struct ecommunity *, int, int);
extern int ecommunity_match (const struct ecommunity *, const struct ecommunity *);
extern char *ecommunity_str (struct ecommunity *);
extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity *, uint8_t, uint8_t );
extern int ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval);
extern void ecommunity_init(void);
extern void ecommunity_finish(void);
extern void ecommunity_free(struct ecommunity **);
extern struct ecommunity *ecommunity_parse(u_int8_t *, u_short);
extern struct ecommunity *ecommunity_dup(struct ecommunity *);
extern struct ecommunity *ecommunity_merge(struct ecommunity *,
struct ecommunity *);
extern struct ecommunity *ecommunity_uniq_sort(struct ecommunity *);
extern struct ecommunity *ecommunity_intern(struct ecommunity *);
extern int ecommunity_cmp(const void *, const void *);
extern void ecommunity_unintern(struct ecommunity **);
extern unsigned int ecommunity_hash_make(void *);
extern struct ecommunity *ecommunity_str2com(const char *, int, int);
extern char *ecommunity_ecom2str(struct ecommunity *, int, int);
extern int ecommunity_match(const struct ecommunity *,
const struct ecommunity *);
extern char *ecommunity_str(struct ecommunity *);
extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *,
uint8_t, uint8_t);
extern int ecommunity_add_val(struct ecommunity *ecom,
struct ecommunity_val *eval);
/* for vpn */
extern struct ecommunity *ecommunity_new (void);
extern int ecommunity_add_val (struct ecommunity *, struct ecommunity_val *);
extern int ecommunity_strip (struct ecommunity *ecom, uint8_t type, uint8_t subtype);
extern struct ecommunity *ecommunity_new (void);
extern struct ecommunity *ecommunity_new(void);
extern int ecommunity_add_val(struct ecommunity *, struct ecommunity_val *);
extern int ecommunity_strip(struct ecommunity *ecom, uint8_t type,
uint8_t subtype);
extern struct ecommunity *ecommunity_new(void);
#endif /* _QUAGGA_BGP_ECOMMUNITY_H */

File diff suppressed because it is too large Load Diff

View File

@ -19,157 +19,115 @@
#ifndef _QUAGGA_BGP_ENCAP_TLV_H
#define _QUAGGA_BGP_ENCAP_TLV_H
/***********************************************************************
* TUNNEL TYPE-SPECIFIC TLV ENCODE
***********************************************************************/
extern void
bgp_encap_type_l2tpv3overip_to_tlv(
struct bgp_encap_type_l2tpv3_over_ip *bet,
bgp_encap_type_l2tpv3overip_to_tlv(struct bgp_encap_type_l2tpv3_over_ip *bet,
struct attr *attr);
extern void
bgp_encap_type_gre_to_tlv(
struct bgp_encap_type_gre *bet,
extern void bgp_encap_type_gre_to_tlv(struct bgp_encap_type_gre *bet,
struct attr *attr);
extern void
bgp_encap_type_ip_in_ip_to_tlv(
struct bgp_encap_type_ip_in_ip *bet,
extern void bgp_encap_type_ip_in_ip_to_tlv(struct bgp_encap_type_ip_in_ip *bet,
struct attr *attr);
extern void
bgp_encap_type_transmit_tunnel_endpoint(
struct bgp_encap_type_transmit_tunnel_endpoint *bet,
struct attr *attr);
extern void bgp_encap_type_transmit_tunnel_endpoint(
struct bgp_encap_type_transmit_tunnel_endpoint *bet, struct attr *attr);
extern void
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
struct bgp_encap_type_ipsec_in_tunnel_mode *bet,
struct attr *attr);
extern void bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
struct bgp_encap_type_ipsec_in_tunnel_mode *bet, struct attr *attr);
extern void
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
extern void bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet,
struct attr *attr);
extern void
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
extern void bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet,
struct attr *attr);
extern void
bgp_encap_type_pbb_to_tlv(
struct bgp_encap_type_pbb *bet,
extern void bgp_encap_type_pbb_to_tlv(struct bgp_encap_type_pbb *bet,
struct attr *attr);
extern void bgp_encap_type_vxlan_to_tlv(struct bgp_encap_type_vxlan *bet,
struct attr *attr);
extern void bgp_encap_type_nvgre_to_tlv(struct bgp_encap_type_nvgre *bet,
struct attr *attr);
extern void bgp_encap_type_mpls_to_tlv(struct bgp_encap_type_mpls *bet,
struct attr *attr);
extern void
bgp_encap_type_vxlan_to_tlv(
struct bgp_encap_type_vxlan *bet,
bgp_encap_type_mpls_in_gre_to_tlv(struct bgp_encap_type_mpls_in_gre *bet,
struct attr *attr);
extern void
bgp_encap_type_nvgre_to_tlv(
struct bgp_encap_type_nvgre *bet,
bgp_encap_type_vxlan_gpe_to_tlv(struct bgp_encap_type_vxlan_gpe *bet,
struct attr *attr);
extern void
bgp_encap_type_mpls_to_tlv(
struct bgp_encap_type_mpls *bet,
struct attr *attr);
extern void
bgp_encap_type_mpls_in_gre_to_tlv(
struct bgp_encap_type_mpls_in_gre *bet,
struct attr *attr);
extern void
bgp_encap_type_vxlan_gpe_to_tlv(
struct bgp_encap_type_vxlan_gpe *bet,
struct attr *attr);
extern void
bgp_encap_type_mpls_in_udp_to_tlv(
struct bgp_encap_type_mpls_in_udp *bet,
bgp_encap_type_mpls_in_udp_to_tlv(struct bgp_encap_type_mpls_in_udp *bet,
struct attr *attr);
/***********************************************************************
* TUNNEL TYPE-SPECIFIC TLV DECODE
***********************************************************************/
extern int
tlv_to_bgp_encap_type_l2tpv3overip(
extern int tlv_to_bgp_encap_type_l2tpv3overip(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_l2tpv3_over_ip *bet); /* caller-allocated */
extern int
tlv_to_bgp_encap_type_gre(
extern int tlv_to_bgp_encap_type_gre(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_gre *bet); /* caller-allocated */
extern int
tlv_to_bgp_encap_type_ip_in_ip(
extern int tlv_to_bgp_encap_type_ip_in_ip(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_ip_in_ip *bet); /* caller-allocated */
extern int
tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
extern int tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_transmit_tunnel_endpoint *bet);
extern int
tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
extern int tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_ipsec_in_tunnel_mode *bet); /* caller-allocated */
extern int
tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
extern int tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet);
extern int
tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
extern int tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet);
extern int
tlv_to_bgp_encap_type_vxlan(
struct bgp_attr_encap_subtlv *stlv,
extern int tlv_to_bgp_encap_type_vxlan(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_vxlan *bet);
extern int
tlv_to_bgp_encap_type_nvgre(
struct bgp_attr_encap_subtlv *stlv,
extern int tlv_to_bgp_encap_type_nvgre(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_nvgre *bet);
extern int
tlv_to_bgp_encap_type_mpls(
struct bgp_attr_encap_subtlv *stlv,
extern int tlv_to_bgp_encap_type_mpls(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls *bet);
extern int tlv_to_bgp_encap_type_mpls(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls *bet);
extern int
tlv_to_bgp_encap_type_mpls(
struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls *bet);
extern int
tlv_to_bgp_encap_type_mpls_in_gre(
struct bgp_attr_encap_subtlv *stlv,
tlv_to_bgp_encap_type_mpls_in_gre(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls_in_gre *bet);
extern int
tlv_to_bgp_encap_type_vxlan_gpe(
struct bgp_attr_encap_subtlv *stlv,
tlv_to_bgp_encap_type_vxlan_gpe(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_vxlan_gpe *bet);
extern int
tlv_to_bgp_encap_type_mpls_in_udp(
struct bgp_attr_encap_subtlv *stlv,
tlv_to_bgp_encap_type_mpls_in_udp(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls_in_udp *bet);
extern int
tlv_to_bgp_encap_type_pbb(
extern int tlv_to_bgp_encap_type_pbb(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_pbb *bet); /* caller-allocated */

View File

@ -21,31 +21,34 @@
#include "bgpd/bgp_ecommunity.h"
/* from http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#tunnel-types */
/* from
* http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#tunnel-types
*/
typedef enum {
BGP_ENCAP_TYPE_RESERVED=0,
BGP_ENCAP_TYPE_L2TPV3_OVER_IP=1,
BGP_ENCAP_TYPE_GRE=2,
BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT=3,
BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE=4,
BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE=5,
BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE=6,
BGP_ENCAP_TYPE_IP_IN_IP=7,
BGP_ENCAP_TYPE_VXLAN=8,
BGP_ENCAP_TYPE_NVGRE=9,
BGP_ENCAP_TYPE_MPLS=10, /* NOTE: Encap SAFI&Attribute not used */
BGP_ENCAP_TYPE_MPLS_IN_GRE=11,
BGP_ENCAP_TYPE_VXLAN_GPE=12,
BGP_ENCAP_TYPE_MPLS_IN_UDP=13,
BGP_ENCAP_TYPE_RESERVED = 0,
BGP_ENCAP_TYPE_L2TPV3_OVER_IP = 1,
BGP_ENCAP_TYPE_GRE = 2,
BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT = 3,
BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE = 4,
BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE = 5,
BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE = 6,
BGP_ENCAP_TYPE_IP_IN_IP = 7,
BGP_ENCAP_TYPE_VXLAN = 8,
BGP_ENCAP_TYPE_NVGRE = 9,
BGP_ENCAP_TYPE_MPLS = 10, /* NOTE: Encap SAFI&Attribute not used */
BGP_ENCAP_TYPE_MPLS_IN_GRE = 11,
BGP_ENCAP_TYPE_VXLAN_GPE = 12,
BGP_ENCAP_TYPE_MPLS_IN_UDP = 13,
BGP_ENCAP_TYPE_PBB
} bgp_encap_types;
typedef enum {
BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION=1,
BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE=2,
BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA=3,
BGP_ENCAP_SUBTLV_TYPE_COLOR=4,
BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT=6 /* speculative, IANA assignment TBD */
BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION = 1,
BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE = 2,
BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA = 3,
BGP_ENCAP_SUBTLV_TYPE_COLOR = 4,
BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT =
6 /* speculative, IANA assignment TBD */
} bgp_encap_subtlv_types;
/*
@ -62,10 +65,10 @@ struct bgp_tea_subtlv_encap_gre_key {
};
struct bgp_tea_subtlv_encap_pbb {
uint32_t flag_isid:1;
uint32_t flag_vid:1;
uint32_t isid:24;
uint16_t vid:12;
uint32_t flag_isid : 1;
uint32_t flag_vid : 1;
uint32_t isid : 24;
uint16_t vid : 12;
uint8_t macaddr[6];
};
@ -215,15 +218,14 @@ struct bgp_encap_type_pbb {
struct bgp_tea_subtlv_encap_pbb st_encap;
};
static inline void
encode_encap_extcomm (bgp_encap_types tnl_type,
static inline void encode_encap_extcomm(bgp_encap_types tnl_type,
struct ecommunity_val *eval)
{
memset (eval, 0, sizeof (*eval));
memset(eval, 0, sizeof(*eval));
eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE;
eval->val[1] = ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP;
eval->val[6] = ((tnl_type) >> 8) & 0xff;
eval->val[7] = (tnl_type) & 0xff;
eval->val[7] = (tnl_type)&0xff;
}
#endif /* _QUAGGA_BGP_ENCAP_TYPES_H */

File diff suppressed because it is too large Load Diff

View File

@ -25,41 +25,29 @@
#define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
extern void
bgp_evpn_handle_router_id_update (struct bgp *bgp, int withdraw);
extern char *
bgp_evpn_label2str (mpls_label_t *label, char *buf, int len);
extern char *
bgp_evpn_route2str (struct prefix_evpn *p, char *buf, int len);
extern void
bgp_evpn_encode_prefix (struct stream *s, struct prefix *p,
extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
extern char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len);
extern char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len);
extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
struct prefix_rd *prd, mpls_label_t *label,
struct attr *attr, int addpath_encode,
u_int32_t addpath_tx_id);
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
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);
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);
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);
extern int
bgp_evpn_local_macip_add (struct bgp *bgp, vni_t vni,
extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
struct ethaddr *mac, struct ipaddr *ip,
u_char sticky);
extern int
bgp_evpn_local_vni_del (struct bgp *bgp, vni_t vni);
extern int
bgp_evpn_local_vni_add (struct bgp *bgp, vni_t vni, struct in_addr originator_ip);
extern void
bgp_evpn_cleanup_on_disable (struct bgp *bgp);
extern void
bgp_evpn_cleanup (struct bgp *bgp);
extern void
bgp_evpn_init (struct bgp *bgp);
extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni);
extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
struct in_addr originator_ip);
extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);
extern void bgp_evpn_cleanup(struct bgp *bgp);
extern void bgp_evpn_init(struct bgp *bgp);
#endif /* _QUAGGA_BGP_EVPN_H */

View File

@ -33,8 +33,7 @@
#define EVPN_TYPE_3_ROUTE_PREFIXLEN 224
/* EVPN route types. */
typedef enum
{
typedef enum {
BGP_EVPN_AD_ROUTE = 1, /* Ethernet Auto-Discovery (A-D) route */
BGP_EVPN_MAC_IP_ROUTE, /* MAC/IP Advertisement route */
BGP_EVPN_IMET_ROUTE, /* Inclusive Multicast Ethernet Tag route */
@ -50,8 +49,7 @@ typedef enum
* on the system (through interaction with zebra) as well as pre-configured
* VNIs (which need to be defined in the system to become "live").
*/
struct bgpevpn
{
struct bgpevpn {
vni_t vni;
u_int32_t flags;
#define VNI_FLAG_CFGD 0x1 /* VNI is user configured */
@ -85,8 +83,7 @@ DECLARE_QOBJ_TYPE(bgpevpn)
* The Import RTs of all VNIs are maintained in a hash table with each
* RT linking to all VNIs that will import routes matching this RT.
*/
struct irt_node
{
struct irt_node {
/* RT */
struct ecommunity_val rt;
@ -98,77 +95,67 @@ struct irt_node
#define RT_TYPE_EXPORT 2
#define RT_TYPE_BOTH 3
static inline int
is_vni_configured (struct bgpevpn *vpn)
static inline int is_vni_configured(struct bgpevpn *vpn)
{
return (CHECK_FLAG (vpn->flags, VNI_FLAG_CFGD));
return (CHECK_FLAG(vpn->flags, VNI_FLAG_CFGD));
}
static inline int
is_vni_live (struct bgpevpn *vpn)
static inline int is_vni_live(struct bgpevpn *vpn)
{
return (CHECK_FLAG (vpn->flags, VNI_FLAG_LIVE));
return (CHECK_FLAG(vpn->flags, VNI_FLAG_LIVE));
}
static inline int
is_rd_configured (struct bgpevpn *vpn)
static inline int is_rd_configured(struct bgpevpn *vpn)
{
return (CHECK_FLAG (vpn->flags, VNI_FLAG_RD_CFGD));
return (CHECK_FLAG(vpn->flags, VNI_FLAG_RD_CFGD));
}
static inline int
bgp_evpn_rd_matches_existing (struct bgpevpn *vpn, struct prefix_rd *prd)
static inline int bgp_evpn_rd_matches_existing(struct bgpevpn *vpn,
struct prefix_rd *prd)
{
return(memcmp (&vpn->prd.val, prd->val, ECOMMUNITY_SIZE) == 0);
return (memcmp(&vpn->prd.val, prd->val, ECOMMUNITY_SIZE) == 0);
}
static inline int
is_import_rt_configured (struct bgpevpn *vpn)
static inline int is_import_rt_configured(struct bgpevpn *vpn)
{
return (CHECK_FLAG (vpn->flags, VNI_FLAG_IMPRT_CFGD));
return (CHECK_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD));
}
static inline int
is_export_rt_configured (struct bgpevpn *vpn)
static inline int is_export_rt_configured(struct bgpevpn *vpn)
{
return (CHECK_FLAG (vpn->flags, VNI_FLAG_EXPRT_CFGD));
return (CHECK_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD));
}
static inline int
is_vni_param_configured (struct bgpevpn *vpn)
static inline int is_vni_param_configured(struct bgpevpn *vpn)
{
return (is_rd_configured (vpn) ||
is_import_rt_configured (vpn) ||
is_export_rt_configured (vpn));
return (is_rd_configured(vpn) || is_import_rt_configured(vpn)
|| is_export_rt_configured(vpn));
}
static inline void
vni2label (vni_t vni, mpls_label_t *label)
static inline void vni2label(vni_t vni, mpls_label_t *label)
{
u_char *tag = (u_char *) label;
u_char *tag = (u_char *)label;
tag[0] = (vni >> 16) & 0xFF;
tag[1] = (vni >> 8) & 0xFF;
tag[2] = vni & 0xFF;
}
static inline vni_t
label2vni (mpls_label_t *label)
static inline vni_t label2vni(mpls_label_t *label)
{
u_char *tag = (u_char *) label;
u_char *tag = (u_char *)label;
vni_t vni;
vni = ((u_int32_t) *tag++ << 16);
vni |= (u_int32_t) *tag++ << 8;
vni |= (u_int32_t) (*tag & 0xFF);
vni = ((u_int32_t)*tag++ << 16);
vni |= (u_int32_t)*tag++ << 8;
vni |= (u_int32_t)(*tag & 0xFF);
return vni;
}
static inline void
encode_mac_mobility_extcomm (int static_mac, u_int32_t seq,
static inline void encode_mac_mobility_extcomm(int static_mac, u_int32_t seq,
struct ecommunity_val *eval)
{
memset (eval, 0, sizeof (*eval));
memset(eval, 0, sizeof(*eval));
eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY;
if (static_mac)
@ -179,24 +166,24 @@ encode_mac_mobility_extcomm (int static_mac, u_int32_t seq,
eval->val[7] = seq & 0xff;
}
static inline void
build_evpn_type2_prefix (struct prefix_evpn *p, struct ethaddr *mac,
static inline void build_evpn_type2_prefix(struct prefix_evpn *p,
struct ethaddr *mac,
struct ipaddr *ip)
{
memset (p, 0, sizeof (struct prefix_evpn));
memset(p, 0, sizeof(struct prefix_evpn));
p->family = AF_ETHERNET;
p->prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
memcpy(&p->prefix.mac.octet, mac->octet, ETHER_ADDR_LEN);
p->prefix.ip.ipa_type = IPADDR_NONE;
if (ip)
memcpy(&p->prefix.ip, ip, sizeof (*ip));
memcpy(&p->prefix.ip, ip, sizeof(*ip));
}
static inline void
build_evpn_type3_prefix (struct prefix_evpn *p, struct in_addr originator_ip)
static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
struct in_addr originator_ip)
{
memset (p, 0, sizeof (struct prefix_evpn));
memset(p, 0, sizeof(struct prefix_evpn));
p->family = AF_ETHERNET;
p->prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
p->prefix.route_type = BGP_EVPN_IMET_ROUTE;
@ -205,28 +192,22 @@ build_evpn_type3_prefix (struct prefix_evpn *p, struct in_addr originator_ip)
}
extern int
bgp_evpn_handle_export_rt_change (struct bgp *bgp, struct bgpevpn *vpn);
extern void
bgp_evpn_handle_rd_change (struct bgp *bgp, struct bgpevpn *vpn, int withdraw);
extern int
bgp_evpn_install_routes (struct bgp *bgp, struct bgpevpn *vpn);
extern int
bgp_evpn_uninstall_routes (struct bgp *bgp, struct bgpevpn *vpn);
extern void
bgp_evpn_map_vni_to_its_rts (struct bgp *bgp, struct bgpevpn *vpn);
extern void
bgp_evpn_unmap_vni_from_its_rts (struct bgp *bgp, struct bgpevpn *vpn);
extern void
bgp_evpn_derive_auto_rt_import (struct bgp *bgp, struct bgpevpn *vpn);
extern void
bgp_evpn_derive_auto_rt_export (struct bgp *bgp, struct bgpevpn *vpn);
extern void
bgp_evpn_derive_auto_rd (struct bgp *bgp, struct bgpevpn *vpn);
extern struct bgpevpn *
bgp_evpn_lookup_vni (struct bgp *bgp, vni_t vni);
extern struct bgpevpn *
bgp_evpn_new (struct bgp *bgp, vni_t vni, struct in_addr originator_ip);
extern void
bgp_evpn_free (struct bgp *bgp, struct bgpevpn *vpn);
extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp,
struct bgpevpn *vpn);
extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
int withdraw);
extern int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn);
extern int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn);
extern void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn);
extern void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp,
struct bgpevpn *vpn);
extern void bgp_evpn_derive_auto_rt_import(struct bgp *bgp,
struct bgpevpn *vpn);
extern void bgp_evpn_derive_auto_rt_export(struct bgp *bgp,
struct bgpevpn *vpn);
extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn);
extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni);
extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
struct in_addr originator_ip);
extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn);
#endif /* _BGP_EVPN_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@ -21,9 +21,8 @@
#ifndef _FRR_BGP_EVPN_VTY_H
#define _FRR_BGP_EVPN_VTY_H
extern void
bgp_config_write_evpn_info (struct vty *vty, struct bgp *bgp, afi_t afi,
safi_t safi, int *write);
extern void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp,
afi_t afi, safi_t safi, int *write);
extern void bgp_ethernetvpn_init(void);
#define L2VPN_HELP_STR "Layer 2 Virtual Private Network\n"

View File

@ -33,15 +33,13 @@
#include "bgpd/bgp_filter.h"
/* List of AS filter list. */
struct as_list_list
{
struct as_list_list {
struct as_list *head;
struct as_list *tail;
};
/* AS path filter master. */
struct as_list_master
{
struct as_list_master {
/* List of access_list which name is number. */
struct as_list_list num;
@ -49,15 +47,14 @@ struct as_list_master
struct as_list_list str;
/* Hook function which is executed when new access_list is added. */
void (*add_hook) (char *);
void (*add_hook)(char *);
/* Hook function which is executed when access_list is deleted. */
void (*delete_hook) (const char *);
void (*delete_hook)(const char *);
};
/* Element of AS path filter. */
struct as_filter
{
struct as_filter {
struct as_filter *next;
struct as_filter *prev;
@ -68,8 +65,7 @@ struct as_filter
};
/* AS path filter list. */
struct as_list
{
struct as_list {
char *name;
enum access_type type;
@ -83,60 +79,55 @@ struct as_list
/* ip 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
};
NULL};
/* Allocate new AS filter. */
static struct as_filter *
as_filter_new (void)
static struct as_filter *as_filter_new(void)
{
return XCALLOC (MTYPE_AS_FILTER, sizeof (struct as_filter));
return XCALLOC(MTYPE_AS_FILTER, sizeof(struct as_filter));
}
/* Free allocated AS filter. */
static void
as_filter_free (struct as_filter *asfilter)
static void as_filter_free(struct as_filter *asfilter)
{
if (asfilter->reg)
bgp_regex_free (asfilter->reg);
bgp_regex_free(asfilter->reg);
if (asfilter->reg_str)
XFREE (MTYPE_AS_FILTER_STR, asfilter->reg_str);
XFREE (MTYPE_AS_FILTER, asfilter);
XFREE(MTYPE_AS_FILTER_STR, asfilter->reg_str);
XFREE(MTYPE_AS_FILTER, asfilter);
}
/* Make new AS filter. */
static struct as_filter *
as_filter_make (regex_t *reg, const char *reg_str, enum as_filter_type type)
static struct as_filter *as_filter_make(regex_t *reg, const char *reg_str,
enum as_filter_type type)
{
struct as_filter *asfilter;
asfilter = as_filter_new ();
asfilter = as_filter_new();
asfilter->reg = reg;
asfilter->type = type;
asfilter->reg_str = XSTRDUP (MTYPE_AS_FILTER_STR, reg_str);
asfilter->reg_str = XSTRDUP(MTYPE_AS_FILTER_STR, reg_str);
return asfilter;
}
static struct as_filter *
as_filter_lookup (struct as_list *aslist, const char *reg_str,
static struct as_filter *as_filter_lookup(struct as_list *aslist,
const char *reg_str,
enum as_filter_type type)
{
struct as_filter *asfilter;
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
if (strcmp (reg_str, asfilter->reg_str) == 0)
if (strcmp(reg_str, asfilter->reg_str) == 0)
return asfilter;
return NULL;
}
static void
as_list_filter_add (struct as_list *aslist, struct as_filter *asfilter)
static void as_list_filter_add(struct as_list *aslist,
struct as_filter *asfilter)
{
asfilter->next = NULL;
asfilter->prev = aslist->tail;
@ -149,13 +140,11 @@ as_list_filter_add (struct as_list *aslist, struct as_filter *asfilter)
/* Run hook function. */
if (as_list_master.add_hook)
(*as_list_master.add_hook) (aslist->name);
(*as_list_master.add_hook)(aslist->name);
}
/* Lookup as_list from list of as_list by name. */
struct as_list *
as_list_lookup (const char *name)
struct as_list *as_list_lookup(const char *name)
{
struct as_list *aslist;
@ -163,37 +152,33 @@ as_list_lookup (const char *name)
return NULL;
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
if (strcmp (aslist->name, name) == 0)
if (strcmp(aslist->name, name) == 0)
return aslist;
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
if (strcmp (aslist->name, name) == 0)
if (strcmp(aslist->name, name) == 0)
return aslist;
return NULL;
}
static struct as_list *
as_list_new (void)
static struct as_list *as_list_new(void)
{
return XCALLOC (MTYPE_AS_LIST, sizeof (struct as_list));
return XCALLOC(MTYPE_AS_LIST, sizeof(struct as_list));
}
static void
as_list_free (struct as_list *aslist)
static void as_list_free(struct as_list *aslist)
{
if (aslist->name)
{
if (aslist->name) {
XFREE(MTYPE_AS_STR, aslist->name);
aslist->name = NULL;
}
XFREE (MTYPE_AS_LIST, aslist);
XFREE(MTYPE_AS_LIST, aslist);
}
/* Insert new AS list to list of as_list. Each as_list is sorted by
the name. */
static struct as_list *
as_list_insert (const char *name)
static struct as_list *as_list_insert(const char *name)
{
size_t i;
long number;
@ -202,34 +187,30 @@ as_list_insert (const char *name)
struct as_list_list *list;
/* Allocate new access_list and copy given name. */
aslist = as_list_new ();
aslist = as_list_new();
aslist->name = XSTRDUP(MTYPE_AS_STR, name);
assert (aslist->name);
assert(aslist->name);
/* If name is made by all digit character. We treat it as
number. */
for (number = 0, i = 0; i < strlen (name); i++)
{
if (isdigit ((int) name[i]))
for (number = 0, i = 0; i < strlen(name); i++) {
if (isdigit((int)name[i]))
number = (number * 10) + (name[i] - '0');
else
break;
}
/* In case of name is all digit character */
if (i == strlen (name))
{
if (i == strlen(name)) {
aslist->type = ACCESS_TYPE_NUMBER;
/* Set access_list to number list. */
list = &as_list_master.num;
for (point = list->head; point; point = point->next)
if (atol (point->name) >= number)
if (atol(point->name) >= number)
break;
}
else
{
} else {
aslist->type = ACCESS_TYPE_STRING;
/* Set access_list to string list. */
@ -237,20 +218,18 @@ as_list_insert (const char *name)
/* Set point to insertion point. */
for (point = list->head; point; point = point->next)
if (strcmp (point->name, name) >= 0)
if (strcmp(point->name, name) >= 0)
break;
}
/* In case of this is the first element of master. */
if (list->head == NULL)
{
if (list->head == NULL) {
list->head = list->tail = aslist;
return aslist;
}
/* In case of insertion is made at the tail of access_list. */
if (point == NULL)
{
if (point == NULL) {
aslist->prev = list->tail;
list->tail->next = aslist;
list->tail = aslist;
@ -258,8 +237,7 @@ as_list_insert (const char *name)
}
/* In case of insertion is made at the head of access_list. */
if (point == list->head)
{
if (point == list->head) {
aslist->next = list->head;
list->head->prev = aslist;
list->head = aslist;
@ -277,23 +255,20 @@ as_list_insert (const char *name)
return aslist;
}
static struct as_list *
as_list_get (const char *name)
static struct as_list *as_list_get(const char *name)
{
struct as_list *aslist;
aslist = as_list_lookup (name);
aslist = as_list_lookup(name);
if (aslist == NULL)
aslist = as_list_insert (name);
aslist = as_list_insert(name);
return aslist;
}
static const char *
filter_type_str (enum as_filter_type type)
static const char *filter_type_str(enum as_filter_type type)
{
switch (type)
{
switch (type) {
case AS_FILTER_PERMIT:
return "permit";
case AS_FILTER_DENY:
@ -303,16 +278,14 @@ filter_type_str (enum as_filter_type type)
}
}
static void
as_list_delete (struct as_list *aslist)
static void as_list_delete(struct as_list *aslist)
{
struct as_list_list *list;
struct as_filter *filter, *next;
for (filter = aslist->head; filter; filter = next)
{
for (filter = aslist->head; filter; filter = next) {
next = filter->next;
as_filter_free (filter);
as_filter_free(filter);
}
if (aslist->type == ACCESS_TYPE_NUMBER)
@ -330,11 +303,10 @@ as_list_delete (struct as_list *aslist)
else
list->head = aslist->next;
as_list_free (aslist);
as_list_free(aslist);
}
static int
as_list_empty (struct as_list *aslist)
static int as_list_empty(struct as_list *aslist)
{
if (aslist->head == NULL && aslist->tail == NULL)
return 1;
@ -342,8 +314,8 @@ as_list_empty (struct as_list *aslist)
return 0;
}
static void
as_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter)
static void as_list_filter_delete(struct as_list *aslist,
struct as_filter *asfilter)
{
char *name = XSTRDUP(MTYPE_AS_STR, aslist->name);
@ -357,70 +329,63 @@ as_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter)
else
aslist->head = asfilter->next;
as_filter_free (asfilter);
as_filter_free(asfilter);
/* If access_list becomes empty delete it from access_master. */
if (as_list_empty (aslist))
as_list_delete (aslist);
if (as_list_empty(aslist))
as_list_delete(aslist);
/* Run hook function. */
if (as_list_master.delete_hook)
(*as_list_master.delete_hook) (name);
(*as_list_master.delete_hook)(name);
if (name)
XFREE(MTYPE_AS_STR, name);
}
static int
as_filter_match (struct as_filter *asfilter, struct aspath *aspath)
static int as_filter_match(struct as_filter *asfilter, struct aspath *aspath)
{
if (bgp_regexec (asfilter->reg, aspath) != REG_NOMATCH)
if (bgp_regexec(asfilter->reg, aspath) != REG_NOMATCH)
return 1;
return 0;
}
/* Apply AS path filter to AS. */
enum as_filter_type
as_list_apply (struct as_list *aslist, void *object)
enum as_filter_type as_list_apply(struct as_list *aslist, void *object)
{
struct as_filter *asfilter;
struct aspath *aspath;
aspath = (struct aspath *) object;
aspath = (struct aspath *)object;
if (aslist == NULL)
return AS_FILTER_DENY;
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
if (as_filter_match (asfilter, aspath))
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
if (as_filter_match(asfilter, aspath))
return asfilter->type;
}
return AS_FILTER_DENY;
}
/* Add hook function. */
void
as_list_add_hook (void (*func) (char *))
void as_list_add_hook(void (*func)(char *))
{
as_list_master.add_hook = func;
}
/* Delete hook function. */
void
as_list_delete_hook (void (*func) (const char *))
void as_list_delete_hook(void (*func)(const char *))
{
as_list_master.delete_hook = func;
}
static int
as_list_dup_check (struct as_list *aslist, struct as_filter *new)
static int as_list_dup_check(struct as_list *aslist, struct as_filter *new)
{
struct as_filter *asfilter;
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
if (asfilter->type == new->type
&& strcmp (asfilter->reg_str, new->reg_str) == 0)
&& strcmp(asfilter->reg_str, new->reg_str) == 0)
return 1;
}
return 0;
@ -445,35 +410,36 @@ DEFUN (ip_as_path,
char *regstr;
/* Retrieve access list name */
char *alname = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
char *alname =
argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
/* Check the filter type. */
type = argv_find (argv, argc, "deny", &idx) ? AS_FILTER_DENY : AS_FILTER_PERMIT;
type = argv_find(argv, argc, "deny", &idx) ? AS_FILTER_DENY
: AS_FILTER_PERMIT;
/* Check AS path regex. */
argv_find (argv, argc, "LINE", &idx);
argv_find(argv, argc, "LINE", &idx);
regstr = argv_concat(argv, argc, idx);
regex = bgp_regcomp (regstr);
if (!regex)
{
vty_out (vty, "can't compile regexp %s\n", regstr);
XFREE (MTYPE_TMP, regstr);
regex = bgp_regcomp(regstr);
if (!regex) {
vty_out(vty, "can't compile regexp %s\n", regstr);
XFREE(MTYPE_TMP, regstr);
return CMD_WARNING_CONFIG_FAILED;
}
asfilter = as_filter_make (regex, regstr, type);
asfilter = as_filter_make(regex, regstr, type);
XFREE (MTYPE_TMP, regstr);
XFREE(MTYPE_TMP, regstr);
/* Install new filter to the access_list. */
aslist = as_list_get (alname);
aslist = as_list_get(alname);
/* Duplicate insertion check. */;
if (as_list_dup_check (aslist, asfilter))
as_filter_free (asfilter);
if (as_list_dup_check(aslist, asfilter))
as_filter_free(asfilter);
else
as_list_filter_add (aslist, asfilter);
as_list_filter_add(aslist, asfilter);
return CMD_SUCCESS;
}
@ -497,52 +463,50 @@ DEFUN (no_ip_as_path,
char *regstr;
regex_t *regex;
char *aslistname = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
char *aslistname =
argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
/* Lookup AS list from AS path list. */
aslist = as_list_lookup (aslistname);
if (aslist == NULL)
{
vty_out (vty, "ip as-path access-list %s doesn't exist\n",aslistname);
aslist = as_list_lookup(aslistname);
if (aslist == NULL) {
vty_out(vty, "ip as-path access-list %s doesn't exist\n",
aslistname);
return CMD_WARNING_CONFIG_FAILED;
}
/* Check the filter type. */
if (argv_find (argv, argc, "permit", &idx))
if (argv_find(argv, argc, "permit", &idx))
type = AS_FILTER_PERMIT;
else if (argv_find (argv, argc, "deny", &idx))
else if (argv_find(argv, argc, "deny", &idx))
type = AS_FILTER_DENY;
else
{
vty_out (vty, "filter type must be [permit|deny]\n");
else {
vty_out(vty, "filter type must be [permit|deny]\n");
return CMD_WARNING_CONFIG_FAILED;
}
/* Compile AS path. */
argv_find (argv, argc, "LINE", &idx);
argv_find(argv, argc, "LINE", &idx);
regstr = argv_concat(argv, argc, idx);
regex = bgp_regcomp (regstr);
if (!regex)
{
vty_out (vty, "can't compile regexp %s\n", regstr);
XFREE (MTYPE_TMP, regstr);
regex = bgp_regcomp(regstr);
if (!regex) {
vty_out(vty, "can't compile regexp %s\n", regstr);
XFREE(MTYPE_TMP, regstr);
return CMD_WARNING_CONFIG_FAILED;
}
/* Lookup asfilter. */
asfilter = as_filter_lookup (aslist, regstr, type);
asfilter = as_filter_lookup(aslist, regstr, type);
XFREE (MTYPE_TMP, regstr);
bgp_regex_free (regex);
XFREE(MTYPE_TMP, regstr);
bgp_regex_free(regex);
if (asfilter == NULL)
{
vty_out (vty, "\n");
if (asfilter == NULL) {
vty_out(vty, "\n");
return CMD_WARNING_CONFIG_FAILED;
}
as_list_filter_delete (aslist, asfilter);
as_list_filter_delete(aslist, asfilter);
return CMD_SUCCESS;
}
@ -559,61 +523,57 @@ DEFUN (no_ip_as_path_all,
int idx_word = 4;
struct as_list *aslist;
aslist = as_list_lookup (argv[idx_word]->arg);
if (aslist == NULL)
{
vty_out (vty, "ip as-path access-list %s doesn't exist\n",
aslist = as_list_lookup(argv[idx_word]->arg);
if (aslist == NULL) {
vty_out(vty, "ip as-path access-list %s doesn't exist\n",
argv[idx_word]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
as_list_delete (aslist);
as_list_delete(aslist);
/* Run hook function. */
if (as_list_master.delete_hook)
(*as_list_master.delete_hook) (argv[idx_word]->arg);
(*as_list_master.delete_hook)(argv[idx_word]->arg);
return CMD_SUCCESS;
}
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;
vty_out (vty, "AS path access list %s\n", aslist->name);
vty_out(vty, "AS path access list %s\n", aslist->name);
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_out (vty, " %s %s\n", filter_type_str (asfilter->type),
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
vty_out(vty, " %s %s\n", filter_type_str(asfilter->type),
asfilter->reg_str);
}
}
static void
as_list_show_all (struct vty *vty)
static void as_list_show_all(struct vty *vty)
{
struct as_list *aslist;
struct as_filter *asfilter;
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
{
vty_out (vty, "AS path access list %s\n", aslist->name);
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next) {
vty_out(vty, "AS path access list %s\n", aslist->name);
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_out (vty, " %s %s\n", filter_type_str (asfilter->type),
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, " %s %s\n",
filter_type_str(asfilter->type),
asfilter->reg_str);
}
}
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
{
vty_out (vty, "AS path access list %s\n", aslist->name);
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next) {
vty_out(vty, "AS path access list %s\n", aslist->name);
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_out (vty, " %s %s\n", filter_type_str (asfilter->type),
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, " %s %s\n",
filter_type_str(asfilter->type),
asfilter->reg_str);
}
}
@ -630,9 +590,9 @@ DEFUN (show_ip_as_path_access_list,
int idx_word = 3;
struct as_list *aslist;
aslist = as_list_lookup (argv[idx_word]->arg);
aslist = as_list_lookup(argv[idx_word]->arg);
if (aslist)
as_list_show (vty, aslist);
as_list_show(vty, aslist);
return CMD_SUCCESS;
}
@ -644,79 +604,69 @@ DEFUN (show_ip_as_path_access_list_all,
IP_STR
"List AS path access lists\n")
{
as_list_show_all (vty);
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)
{
struct as_list *aslist;
struct as_filter *asfilter;
int write = 0;
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_out (vty, "ip as-path access-list %s %s %s\n",
aslist->name, filter_type_str (asfilter->type),
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, "ip as-path access-list %s %s %s\n",
aslist->name, filter_type_str(asfilter->type),
asfilter->reg_str);
write++;
}
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_out (vty, "ip as-path access-list %s %s %s\n",
aslist->name, filter_type_str (asfilter->type),
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, "ip as-path access-list %s %s %s\n",
aslist->name, filter_type_str(asfilter->type),
asfilter->reg_str);
write++;
}
return write;
}
static struct cmd_node as_list_node =
{
AS_LIST_NODE,
"",
1
};
static struct cmd_node as_list_node = {AS_LIST_NODE, "", 1};
/* Register functions. */
void
bgp_filter_init (void)
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, &ip_as_path_cmd);
install_element (CONFIG_NODE, &no_ip_as_path_cmd);
install_element (CONFIG_NODE, &no_ip_as_path_all_cmd);
install_element(CONFIG_NODE, &ip_as_path_cmd);
install_element(CONFIG_NODE, &no_ip_as_path_cmd);
install_element(CONFIG_NODE, &no_ip_as_path_all_cmd);
install_element (VIEW_NODE, &show_ip_as_path_access_list_cmd);
install_element (VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
install_element(VIEW_NODE, &show_ip_as_path_access_list_cmd);
install_element(VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
}
void
bgp_filter_reset (void)
void bgp_filter_reset(void)
{
struct as_list *aslist;
struct as_list *next;
for (aslist = as_list_master.num.head; aslist; aslist = next)
{
for (aslist = as_list_master.num.head; aslist; aslist = next) {
next = aslist->next;
as_list_delete (aslist);
as_list_delete(aslist);
}
for (aslist = as_list_master.str.head; aslist; aslist = next)
{
for (aslist = as_list_master.str.head; aslist; aslist = next) {
next = aslist->next;
as_list_delete (aslist);
as_list_delete(aslist);
}
assert (as_list_master.num.head == NULL);
assert (as_list_master.num.tail == NULL);
assert(as_list_master.num.head == NULL);
assert(as_list_master.num.tail == NULL);
assert (as_list_master.str.head == NULL);
assert (as_list_master.str.tail == NULL);
assert(as_list_master.str.head == NULL);
assert(as_list_master.str.tail == NULL);
}

View File

@ -21,19 +21,15 @@
#ifndef _QUAGGA_BGP_FILTER_H
#define _QUAGGA_BGP_FILTER_H
enum as_filter_type
{
AS_FILTER_DENY,
AS_FILTER_PERMIT
};
enum as_filter_type { AS_FILTER_DENY, AS_FILTER_PERMIT };
extern void bgp_filter_init (void);
extern void bgp_filter_reset (void);
extern void bgp_filter_init(void);
extern void bgp_filter_reset(void);
extern enum as_filter_type as_list_apply (struct as_list *, void *);
extern enum as_filter_type as_list_apply(struct as_list *, void *);
extern struct as_list *as_list_lookup (const char *);
extern void as_list_add_hook (void (*func) (char *));
extern void as_list_delete_hook (void (*func) (const char *));
extern struct as_list *as_list_lookup(const char *);
extern void as_list_add_hook(void (*func)(char *));
extern void as_list_delete_hook(void (*func)(const char *));
#endif /* _QUAGGA_BGP_FILTER_H */

File diff suppressed because it is too large Load Diff

View File

@ -23,10 +23,10 @@
#define _QUAGGA_BGP_FSM_H
/* Macro for BGP read, write and timer thread. */
#define BGP_READ_ON(T,F,V) \
#define BGP_READ_ON(T, F, V) \
do { \
if ((peer->status != Deleted)) \
thread_add_read (bm->master,(F),peer,(V),&(T)); \
thread_add_read(bm->master, (F), peer, (V), &(T)); \
} while (0)
#define BGP_READ_OFF(T) \
@ -35,16 +35,16 @@
THREAD_READ_OFF(T); \
} while (0)
#define BGP_WRITE_ON(T,F,V) \
#define BGP_WRITE_ON(T, F, V) \
do { \
if ((peer)->status != Deleted) \
thread_add_write (bm->master,(F),(peer),(V),&(T)); \
thread_add_write(bm->master, (F), (peer), (V), &(T)); \
} while (0)
#define BGP_PEER_WRITE_ON(T,F,V, peer) \
#define BGP_PEER_WRITE_ON(T, F, V, peer) \
do { \
if ((peer)->status != Deleted) \
thread_add_write (bm->master,(F),(peer),(V),&(T)); \
thread_add_write(bm->master, (F), (peer), (V), &(T)); \
} while (0)
#define BGP_WRITE_OFF(T) \
@ -53,10 +53,10 @@
THREAD_WRITE_OFF(T); \
} while (0)
#define BGP_TIMER_ON(T,F,V) \
#define BGP_TIMER_ON(T, F, V) \
do { \
if ((peer->status != Deleted)) \
thread_add_timer (bm->master,(F),peer,(V),&(T)); \
thread_add_timer(bm->master, (F), peer, (V), &(T)); \
} while (0)
#define BGP_TIMER_OFF(T) \
@ -65,40 +65,41 @@
THREAD_TIMER_OFF(T); \
} while (0)
#define BGP_EVENT_ADD(P,E) \
#define BGP_EVENT_ADD(P, E) \
do { \
if ((P)->status != Deleted) \
thread_add_event (bm->master, bgp_event, (P), (E), NULL); \
thread_add_event(bm->master, bgp_event, (P), (E), \
NULL); \
} while (0)
#define BGP_EVENT_FLUSH(P) \
do { \
assert (peer); \
thread_cancel_event (bm->master, (P)); \
assert(peer); \
thread_cancel_event(bm->master, (P)); \
} while (0)
#define BGP_MSEC_JITTER 10
/* Prototypes. */
extern void bgp_fsm_nht_update(struct peer *, int valid);
extern int bgp_event (struct thread *);
extern int bgp_event_update (struct peer *, int event);
extern int bgp_stop (struct peer *peer);
extern void bgp_timer_set (struct peer *);
extern int bgp_routeadv_timer (struct thread *);
extern void bgp_fsm_change_status (struct peer *peer, int status);
extern int bgp_event(struct thread *);
extern int bgp_event_update(struct peer *, int event);
extern int bgp_stop(struct peer *peer);
extern void bgp_timer_set(struct peer *);
extern int bgp_routeadv_timer(struct thread *);
extern void bgp_fsm_change_status(struct peer *peer, int status);
extern const char *peer_down_str[];
extern void bgp_update_delay_end (struct bgp *);
extern void bgp_maxmed_update (struct bgp *);
extern int bgp_maxmed_onstartup_configured (struct bgp *);
extern int bgp_maxmed_onstartup_active (struct bgp *);
extern void bgp_update_delay_end(struct bgp *);
extern void bgp_maxmed_update(struct bgp *);
extern int bgp_maxmed_onstartup_configured(struct bgp *);
extern int bgp_maxmed_onstartup_active(struct bgp *);
/**
* Start the route advertisement timer (that honors MRAI) for all the
* peers. Typically called at the end of initial convergence, coming
* out of read-only mode.
*/
extern void bgp_start_routeadv (struct bgp *);
extern void bgp_start_routeadv(struct bgp *);
/**
* See if the route advertisement timer needs to be adjusted for a
@ -107,10 +108,10 @@ extern void bgp_start_routeadv (struct bgp *);
* timer to expire to send the new set of prefixes. It should fire
* instantly and updates should go out sooner.
*/
extern void bgp_adjust_routeadv (struct peer *);
extern void bgp_adjust_routeadv(struct peer *);
#include "hook.h"
DECLARE_HOOK(peer_backward_transition, (struct peer *peer), (peer))
DECLARE_HOOK(peer_established, (struct peer *peer), (peer))
DECLARE_HOOK(peer_backward_transition, (struct peer * peer), (peer))
DECLARE_HOOK(peer_established, (struct peer * peer), (peer))
#endif /* _QUAGGA_BGP_FSM_H */

View File

@ -41,8 +41,7 @@
extern struct zclient *zclient;
int
bgp_parse_fec_update (void)
int bgp_parse_fec_update(void)
{
struct stream *s;
struct bgp_node *rn;
@ -65,21 +64,18 @@ bgp_parse_fec_update (void)
afi = family2afi(p.family);
safi = SAFI_UNICAST;
bgp = bgp_get_default();
if (!bgp)
{
if (!bgp) {
zlog_debug("no default bgp instance");
return -1;
}
table = bgp->rib[afi][safi];
if (!table)
{
if (!table) {
zlog_debug("no %u unicast table", p.family);
return -1;
}
rn = bgp_node_lookup(table, &p);
if (!rn)
{
if (!rn) {
zlog_debug("no node for the prefix");
return -1;
}
@ -87,20 +83,18 @@ bgp_parse_fec_update (void)
/* treat it as implicit withdraw - the label is invalid */
if (label == MPLS_INVALID_LABEL)
bgp_unset_valid_label(&rn->local_label);
else
{
else {
label_ntop(label, 1, &rn->local_label);
bgp_set_valid_label(&rn->local_label);
}
SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
bgp_unlock_node (rn);
bgp_process (bgp, rn, afi, safi);
bgp_unlock_node(rn);
bgp_process(bgp, rn, afi, safi);
return 1;
}
mpls_label_t
bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to,
afi_t afi, safi_t safi)
mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
struct peer *to, afi_t afi, safi_t safi)
{
struct peer *from;
mpls_label_t remote_label;
@ -111,9 +105,11 @@ bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to,
remote_label = ri->extra ? ri->extra->label : MPLS_INVALID_LABEL;
from = ri->peer;
reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
reflect =
((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
if (reflect && !CHECK_FLAG(to->af_flags[afi][safi],
if (reflect
&& !CHECK_FLAG(to->af_flags[afi][safi],
PEER_FLAG_FORCE_NEXTHOP_SELF))
return remote_label;
@ -123,9 +119,7 @@ bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to,
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_info *ri, int reg)
{
struct stream *s;
struct prefix *p;
@ -139,46 +133,41 @@ bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
p = &(rn->p);
s = zclient->obuf;
stream_reset (s);
stream_reset(s);
command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
zclient_create_header (s, command, VRF_DEFAULT);
flags_pos = stream_get_endp (s); /* save position of 'flags' */
zclient_create_header(s, command, VRF_DEFAULT);
flags_pos = stream_get_endp(s); /* save position of 'flags' */
stream_putw(s, flags); /* initial flags */
stream_putw(s, PREFIX_FAMILY(p));
stream_put_prefix(s, p);
if (reg)
{
assert (ri);
if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
{
if (ri->attr->label_index != BGP_INVALID_LABEL_INDEX)
{
if (reg) {
assert(ri);
if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
if (ri->attr->label_index != BGP_INVALID_LABEL_INDEX) {
flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
stream_putl (s, ri->attr->label_index);
stream_putl(s, ri->attr->label_index);
}
}
SET_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
}
else
UNSET_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
} else
UNSET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
/* Set length and flags */
stream_putw_at (s, 0, stream_get_endp (s));
stream_putw_at (s, flags_pos, flags);
stream_putw_at(s, 0, stream_get_endp(s));
stream_putw_at(s, flags_pos, flags);
zclient_send_message(zclient);
}
static int
bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen, mpls_label_t *label)
static int bgp_nlri_get_labels(struct peer *peer, u_char *pnt, u_char plen,
mpls_label_t *label)
{
u_char *data = pnt;
u_char *lim = pnt + plen;
u_char llen = 0;
u_char label_depth = 0;
for (; data < lim; data += BGP_LABEL_BYTES)
{
for (; data < lim; data += BGP_LABEL_BYTES) {
memcpy(label, data, BGP_LABEL_BYTES);
llen += BGP_LABEL_BYTES;
@ -192,18 +181,18 @@ bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen, mpls_label_t *
/* If we RX multiple labels we will end up keeping only the last
* one. We do not yet support a label stack greater than 1. */
if (label_depth > 1)
zlog_warn("%s rcvd UPDATE with label stack %d deep",
peer->host, label_depth);
zlog_warn("%s rcvd UPDATE with label stack %d deep", peer->host,
label_depth);
if (!(bgp_is_withdraw_label(label) || label_bos(label)))
zlog_warn("%s rcvd UPDATE with invalid label stack - no bottom of stack",
zlog_warn(
"%s rcvd UPDATE with invalid label stack - no bottom of stack",
peer->host);
return llen;
}
int
bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
struct bgp_nlri *packet)
{
u_char *pnt;
@ -228,37 +217,36 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
safi = packet->safi;
addpath_id = 0;
addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
addpath_encoded =
(CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
&& CHECK_FLAG(peer->af_cap[afi][safi],
PEER_CAP_ADDPATH_AF_TX_RCV));
for (; pnt < lim; pnt += psize)
{
for (; pnt < lim; pnt += psize) {
/* Clear prefix structure. */
memset (&p, 0, sizeof (struct prefix));
memset(&p, 0, sizeof(struct prefix));
llen = 0;
if (addpath_encoded)
{
if (addpath_encoded) {
/* When packet overflow occurs return immediately. */
if (pnt + BGP_ADDPATH_ID_LEN > lim)
return -1;
addpath_id = ntohl(*((uint32_t*) pnt));
addpath_id = ntohl(*((uint32_t *)pnt));
pnt += BGP_ADDPATH_ID_LEN;
}
/* Fetch prefix length. */
prefixlen = *pnt++;
p.family = afi2family (packet->afi);
psize = PSIZE (prefixlen);
p.family = afi2family(packet->afi);
psize = PSIZE(prefixlen);
/* sanity check against packet data */
if ((pnt + psize) > lim)
{
zlog_err ("%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
peer->host,
prefixlen, (uint)(lim-pnt));
if ((pnt + psize) > lim) {
zlog_err(
"%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
peer->host, prefixlen, (uint)(lim - pnt));
return -1;
}
@ -267,12 +255,12 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
p.prefixlen = prefixlen - BSIZE(llen);
/* There needs to be at least one label */
if (prefixlen < 24)
{
zlog_err ("%s [Error] Update packet error"
if (prefixlen < 24) {
zlog_err(
"%s [Error] Update packet error"
" (wrong label length %d)",
peer->host, prefixlen);
bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_INVAL_NETWORK);
return -1;
}
@ -282,65 +270,69 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
return -1;
/* Fetch prefix from NLRI packet */
memcpy (&p.u.prefix, pnt + llen, psize - llen);
memcpy(&p.u.prefix, pnt + llen, psize - llen);
/* Check address. */
if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
{
if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
{
if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST) {
if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
/* From RFC4271 Section 6.3:
*
* If a prefix in the NLRI field is semantically incorrect
* (e.g., an unexpected multicast IP address), an error SHOULD
* be logged locally, and the prefix SHOULD be ignored.
* If a prefix in the NLRI field is semantically
* incorrect
* (e.g., an unexpected multicast IP address),
* an error SHOULD
* be logged locally, and the prefix SHOULD be
* ignored.
*/
zlog_err ("%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
peer->host, inet_ntoa (p.u.prefix4));
zlog_err(
"%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
peer->host, inet_ntoa(p.u.prefix4));
continue;
}
}
/* Check address. */
if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
{
if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
{
if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST) {
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
char buf[BUFSIZ];
zlog_err ("%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
zlog_err(
"%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
peer->host,
inet_ntop(AF_INET6, &p.u.prefix6, buf,
BUFSIZ));
continue;
}
if (IN6_IS_ADDR_MULTICAST (&p.u.prefix6))
{
if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
char buf[BUFSIZ];
zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
zlog_err(
"%s: IPv6 unicast NLRI is multicast address %s, ignoring",
peer->host,
inet_ntop(AF_INET6, &p.u.prefix6, buf,
BUFSIZ));
continue;
}
}
if (attr)
{
bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_UNICAST,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, &label, 0, NULL);
}
else
{
bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_UNICAST,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, &label, NULL);
if (attr) {
bgp_update(peer, &p, addpath_id, attr, packet->afi,
SAFI_UNICAST, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, NULL, &label, 0, NULL);
} else {
bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
SAFI_UNICAST, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, NULL, &label, NULL);
}
}
/* Packet length consistency check. */
if (pnt != lim)
{
zlog_err ("%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
if (pnt != lim) {
zlog_err(
"%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
peer->host, lim - pnt);
return -1;
}

View File

@ -29,90 +29,83 @@ struct bgp_node;
struct bgp_info;
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, struct bgp_info *ri,
int reg);
extern int bgp_parse_fec_update(void);
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
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,
struct bgp_nlri *packet);
static inline int
bgp_labeled_safi (safi_t safi)
static inline int bgp_labeled_safi(safi_t safi)
{
/* NOTE: This API really says a label (tag) MAY be present. Not all EVPN
* routes will have a label.
*/
if ((safi == SAFI_LABELED_UNICAST) || (safi == SAFI_MPLS_VPN) ||
(safi == SAFI_EVPN))
if ((safi == SAFI_LABELED_UNICAST) || (safi == SAFI_MPLS_VPN)
|| (safi == SAFI_EVPN))
return 1;
return 0;
}
static inline int
bgp_is_withdraw_label (mpls_label_t *label)
static inline int bgp_is_withdraw_label(mpls_label_t *label)
{
u_char *pkt = (u_char *) label;
u_char *pkt = (u_char *)label;
/* The check on pkt[2] for 0x00 or 0x02 is in case bgp_set_valid_label()
* was called on the withdraw label */
if ((pkt[0] == 0x80) && (pkt[1] == 0x00) && ((pkt[2] == 0x00) || (pkt[2] == 0x02)))
if ((pkt[0] == 0x80) && (pkt[1] == 0x00)
&& ((pkt[2] == 0x00) || (pkt[2] == 0x02)))
return 1;
return 0;
}
static inline int
bgp_is_valid_label (mpls_label_t *label)
static inline int bgp_is_valid_label(mpls_label_t *label)
{
u_char *t= (u_char *) label;
u_char *t = (u_char *)label;
if (!t)
return 0;
return (t[2] & 0x02);
}
static inline void
bgp_set_valid_label (mpls_label_t *label)
static inline void bgp_set_valid_label(mpls_label_t *label)
{
u_char *t= (u_char *) label;
u_char *t = (u_char *)label;
if (t)
t[2] |= 0x02;
}
static inline void
bgp_unset_valid_label (mpls_label_t *label)
static inline void bgp_unset_valid_label(mpls_label_t *label)
{
u_char *t= (u_char *) label;
u_char *t = (u_char *)label;
if (t)
t[2] &= ~0x02;
}
static inline void
bgp_register_for_label (struct bgp_node *rn, struct bgp_info *ri)
static inline void bgp_register_for_label(struct bgp_node *rn,
struct bgp_info *ri)
{
bgp_reg_dereg_for_label (rn, ri, 1);
bgp_reg_dereg_for_label(rn, ri, 1);
}
static inline void
bgp_unregister_for_label (struct bgp_node *rn)
static inline void bgp_unregister_for_label(struct bgp_node *rn)
{
bgp_reg_dereg_for_label (rn, NULL, 0);
bgp_reg_dereg_for_label(rn, NULL, 0);
}
/* Label stream to value */
static inline u_int32_t
label_pton (mpls_label_t *label)
static inline u_int32_t label_pton(mpls_label_t *label)
{
u_char *t= (u_char *) label;
return ((((unsigned int) t[0]) << 12) | (((unsigned int) t[1]) << 4) |
((unsigned int) ((t[2] & 0xF0) >> 4)));
u_char *t = (u_char *)label;
return ((((unsigned int)t[0]) << 12) | (((unsigned int)t[1]) << 4)
| ((unsigned int)((t[2] & 0xF0) >> 4)));
}
/* Encode label values */
static inline void
label_ntop (u_int32_t l, int bos, mpls_label_t *label)
static inline void label_ntop(u_int32_t l, int bos, mpls_label_t *label)
{
u_char *t= (u_char *) label;
u_char *t = (u_char *)label;
t[0] = ((l & 0x000FF000) >> 12);
t[1] = ((l & 0x00000FF0) >> 4);
t[2] = ((l & 0x0000000F) << 4);
@ -121,10 +114,9 @@ label_ntop (u_int32_t l, int bos, mpls_label_t *label)
}
/* Return BOS value of label stream */
static inline u_char
label_bos (mpls_label_t *label)
static inline u_char label_bos(mpls_label_t *label)
{
u_char *t= (u_char *) label;
u_char *t = (u_char *)label;
return (t[2] & 0x01);
};

View File

@ -34,29 +34,26 @@
static struct hash *lcomhash;
/* Allocate a new lcommunities. */
static struct lcommunity *
lcommunity_new (void)
static struct lcommunity *lcommunity_new(void)
{
return (struct lcommunity *) XCALLOC (MTYPE_LCOMMUNITY,
sizeof (struct lcommunity));
return (struct lcommunity *)XCALLOC(MTYPE_LCOMMUNITY,
sizeof(struct lcommunity));
}
/* Allocate lcommunities. */
void
lcommunity_free (struct lcommunity **lcom)
void lcommunity_free(struct lcommunity **lcom)
{
if ((*lcom)->val)
XFREE (MTYPE_LCOMMUNITY_VAL, (*lcom)->val);
XFREE(MTYPE_LCOMMUNITY_VAL, (*lcom)->val);
if ((*lcom)->str)
XFREE (MTYPE_LCOMMUNITY_STR, (*lcom)->str);
XFREE (MTYPE_LCOMMUNITY, *lcom);
XFREE(MTYPE_LCOMMUNITY_STR, (*lcom)->str);
XFREE(MTYPE_LCOMMUNITY, *lcom);
lcom = NULL;
}
static void
lcommunity_hash_free (struct lcommunity *lcom)
static void lcommunity_hash_free(struct lcommunity *lcom)
{
lcommunity_free (&lcom);
lcommunity_free(&lcom);
}
/* Add a new Large Communities value to Large Communities
@ -64,27 +61,25 @@ lcommunity_hash_free (struct lcommunity *lcom)
structure, we don't add the value. Newly added value is sorted by
numerical order. When the value is added to the structure return 1
else return 0. */
static int
lcommunity_add_val (struct lcommunity *lcom, struct lcommunity_val *lval)
static int lcommunity_add_val(struct lcommunity *lcom,
struct lcommunity_val *lval)
{
u_int8_t *p;
int ret;
int c;
/* When this is fist value, just add it. */
if (lcom->val == NULL)
{
if (lcom->val == NULL) {
lcom->size++;
lcom->val = XMALLOC (MTYPE_LCOMMUNITY_VAL, lcom_length (lcom));
memcpy (lcom->val, lval->val, LCOMMUNITY_SIZE);
lcom->val = XMALLOC(MTYPE_LCOMMUNITY_VAL, lcom_length(lcom));
memcpy(lcom->val, lval->val, LCOMMUNITY_SIZE);
return 1;
}
/* If the value already exists in the structure return 0. */
c = 0;
for (p = lcom->val; c < lcom->size; p += LCOMMUNITY_SIZE, c++)
{
ret = memcmp (p, lval->val, LCOMMUNITY_SIZE);
for (p = lcom->val; c < lcom->size; p += LCOMMUNITY_SIZE, c++) {
ret = memcmp(p, lval->val, LCOMMUNITY_SIZE);
if (ret == 0)
return 0;
if (ret > 0)
@ -93,12 +88,13 @@ lcommunity_add_val (struct lcommunity *lcom, struct lcommunity_val *lval)
/* Add the value to the structure with numerical sorting. */
lcom->size++;
lcom->val = XREALLOC (MTYPE_LCOMMUNITY_VAL, lcom->val, lcom_length (lcom));
lcom->val =
XREALLOC(MTYPE_LCOMMUNITY_VAL, lcom->val, lcom_length(lcom));
memmove (lcom->val + (c + 1) * LCOMMUNITY_SIZE,
memmove(lcom->val + (c + 1) * LCOMMUNITY_SIZE,
lcom->val + c * LCOMMUNITY_SIZE,
(lcom->size - 1 - c) * LCOMMUNITY_SIZE);
memcpy (lcom->val + c * LCOMMUNITY_SIZE, lval->val, LCOMMUNITY_SIZE);
memcpy(lcom->val + c * LCOMMUNITY_SIZE, lval->val, LCOMMUNITY_SIZE);
return 1;
}
@ -106,29 +102,27 @@ lcommunity_add_val (struct lcommunity *lcom, struct lcommunity_val *lval)
/* This function takes pointer to Large Communites strucutre then
create a new Large Communities structure by uniq and sort each
Large Communities value. */
struct lcommunity *
lcommunity_uniq_sort (struct lcommunity *lcom)
struct lcommunity *lcommunity_uniq_sort(struct lcommunity *lcom)
{
int i;
struct lcommunity *new;
struct lcommunity_val *lval;
if (! lcom)
if (!lcom)
return NULL;
new = lcommunity_new ();
new = lcommunity_new();
for (i = 0; i < lcom->size; i++)
{
lval = (struct lcommunity_val *) (lcom->val + (i * LCOMMUNITY_SIZE));
lcommunity_add_val (new, lval);
for (i = 0; i < lcom->size; i++) {
lval = (struct lcommunity_val *)(lcom->val
+ (i * LCOMMUNITY_SIZE));
lcommunity_add_val(new, lval);
}
return new;
}
/* Parse Large Communites Attribute in BGP packet. */
struct lcommunity *
lcommunity_parse (u_int8_t *pnt, u_short length)
struct lcommunity *lcommunity_parse(u_int8_t *pnt, u_short length)
{
struct lcommunity tmp;
struct lcommunity *new;
@ -144,80 +138,79 @@ lcommunity_parse (u_int8_t *pnt, u_short length)
/* Create a new Large Communities Attribute by uniq and sort each
Large Communities value */
new = lcommunity_uniq_sort (&tmp);
new = lcommunity_uniq_sort(&tmp);
return lcommunity_intern (new);
return lcommunity_intern(new);
}
/* Duplicate the Large Communities Attribute structure. */
struct lcommunity *
lcommunity_dup (struct lcommunity *lcom)
struct lcommunity *lcommunity_dup(struct lcommunity *lcom)
{
struct lcommunity *new;
new = XCALLOC (MTYPE_LCOMMUNITY, sizeof (struct lcommunity));
new = XCALLOC(MTYPE_LCOMMUNITY, sizeof(struct lcommunity));
new->size = lcom->size;
if (new->size)
{
new->val = XMALLOC (MTYPE_LCOMMUNITY_VAL, lcom->size * LCOMMUNITY_SIZE);
memcpy (new->val, lcom->val, lcom->size * LCOMMUNITY_SIZE);
}
else
if (new->size) {
new->val = XMALLOC(MTYPE_LCOMMUNITY_VAL,
lcom->size * LCOMMUNITY_SIZE);
memcpy(new->val, lcom->val, lcom->size * LCOMMUNITY_SIZE);
} else
new->val = NULL;
return new;
}
/* Retrun string representation of communities attribute. */
char *
lcommunity_str (struct lcommunity *lcom)
char *lcommunity_str(struct lcommunity *lcom)
{
if (! lcom->str)
lcom->str = lcommunity_lcom2str (lcom, LCOMMUNITY_FORMAT_DISPLAY);
if (!lcom->str)
lcom->str =
lcommunity_lcom2str(lcom, LCOMMUNITY_FORMAT_DISPLAY);
return lcom->str;
}
/* Merge two Large Communities Attribute structure. */
struct lcommunity *
lcommunity_merge (struct lcommunity *lcom1, struct lcommunity *lcom2)
struct lcommunity *lcommunity_merge(struct lcommunity *lcom1,
struct lcommunity *lcom2)
{
if (lcom1->val)
lcom1->val = XREALLOC (MTYPE_LCOMMUNITY_VAL, lcom1->val,
lcom1->val =
XREALLOC(MTYPE_LCOMMUNITY_VAL, lcom1->val,
(lcom1->size + lcom2->size) * LCOMMUNITY_SIZE);
else
lcom1->val = XMALLOC (MTYPE_LCOMMUNITY_VAL,
lcom1->val =
XMALLOC(MTYPE_LCOMMUNITY_VAL,
(lcom1->size + lcom2->size) * LCOMMUNITY_SIZE);
memcpy (lcom1->val + (lcom1->size * LCOMMUNITY_SIZE),
lcom2->val, lcom2->size * LCOMMUNITY_SIZE);
memcpy(lcom1->val + (lcom1->size * LCOMMUNITY_SIZE), lcom2->val,
lcom2->size * LCOMMUNITY_SIZE);
lcom1->size += lcom2->size;
return lcom1;
}
/* Intern Large Communities Attribute. */
struct lcommunity *
lcommunity_intern (struct lcommunity *lcom)
struct lcommunity *lcommunity_intern(struct lcommunity *lcom)
{
struct lcommunity *find;
assert (lcom->refcnt == 0);
assert(lcom->refcnt == 0);
find = (struct lcommunity *) hash_get (lcomhash, lcom, hash_alloc_intern);
find = (struct lcommunity *)hash_get(lcomhash, lcom, hash_alloc_intern);
if (find != lcom)
lcommunity_free (&lcom);
lcommunity_free(&lcom);
find->refcnt++;
if (! find->str)
find->str = lcommunity_lcom2str (find, LCOMMUNITY_FORMAT_DISPLAY);
if (!find->str)
find->str =
lcommunity_lcom2str(find, LCOMMUNITY_FORMAT_DISPLAY);
return find;
}
/* Unintern Large Communities Attribute. */
void
lcommunity_unintern (struct lcommunity **lcom)
void lcommunity_unintern(struct lcommunity **lcom)
{
struct lcommunity *ret;
@ -225,19 +218,17 @@ lcommunity_unintern (struct lcommunity **lcom)
(*lcom)->refcnt--;
/* Pull off from hash. */
if ((*lcom)->refcnt == 0)
{
if ((*lcom)->refcnt == 0) {
/* Large community must be in the hash. */
ret = (struct lcommunity *) hash_release (lcomhash, *lcom);
assert (ret != NULL);
ret = (struct lcommunity *)hash_release(lcomhash, *lcom);
assert(ret != NULL);
lcommunity_free (lcom);
lcommunity_free(lcom);
}
}
/* Utility function to make hash key. */
unsigned int
lcommunity_hash_make (void *arg)
unsigned int lcommunity_hash_make(void *arg)
{
const struct lcommunity *lcom = arg;
int size = lcom->size * LCOMMUNITY_SIZE;
@ -245,8 +236,7 @@ lcommunity_hash_make (void *arg)
unsigned int key = 0;
int c;
for (c = 0; c < size; c += LCOMMUNITY_SIZE)
{
for (c = 0; c < size; c += LCOMMUNITY_SIZE) {
key += pnt[c];
key += pnt[c + 1];
key += pnt[c + 2];
@ -265,55 +255,50 @@ lcommunity_hash_make (void *arg)
}
/* Compare two Large Communities Attribute structure. */
int
lcommunity_cmp (const void *arg1, const void *arg2)
int lcommunity_cmp(const void *arg1, const void *arg2)
{
const struct lcommunity *lcom1 = arg1;
const struct lcommunity *lcom2 = arg2;
return (lcom1->size == lcom2->size
&& memcmp (lcom1->val, lcom2->val, lcom1->size * LCOMMUNITY_SIZE) == 0);
&& memcmp(lcom1->val, lcom2->val, lcom1->size * LCOMMUNITY_SIZE)
== 0);
}
/* Return communities hash. */
struct hash *
lcommunity_hash (void)
struct hash *lcommunity_hash(void)
{
return lcomhash;
}
/* Initialize Large Comminities related hash. */
void
lcommunity_init (void)
void lcommunity_init(void)
{
lcomhash = hash_create (lcommunity_hash_make, lcommunity_cmp, NULL);
lcomhash = hash_create(lcommunity_hash_make, lcommunity_cmp, NULL);
}
void
lcommunity_finish (void)
void lcommunity_finish(void)
{
hash_clean (lcomhash, (void (*)(void *))lcommunity_hash_free);
hash_free (lcomhash);
hash_clean(lcomhash, (void (*)(void *))lcommunity_hash_free);
hash_free(lcomhash);
lcomhash = NULL;
}
/* Large Communities token enum. */
enum lcommunity_token
{
enum lcommunity_token {
lcommunity_token_unknown = 0,
lcommunity_token_val,
};
/* Get next Large Communities token from the string. */
static const char *
lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
static const char *lcommunity_gettoken(const char *str,
struct lcommunity_val *lval,
enum lcommunity_token *token)
{
const char *p = str;
/* Skip white space. */
while (isspace ((int) *p))
{
while (isspace((int)*p)) {
p++;
str++;
}
@ -323,25 +308,19 @@ lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
return NULL;
/* Community value. */
if (isdigit ((int) *p))
{
if (isdigit((int)*p)) {
int separator = 0;
int digit = 0;
u_int32_t globaladmin = 0;
u_int32_t localdata1 = 0;
u_int32_t localdata2 = 0;
while (isdigit ((int) *p) || *p == ':')
{
if (*p == ':')
{
if (separator == 2)
{
while (isdigit((int)*p) || *p == ':') {
if (*p == ':') {
if (separator == 2) {
*token = lcommunity_token_unknown;
return NULL;
}
else
{
} else {
separator++;
digit = 0;
if (separator == 1) {
@ -351,17 +330,14 @@ lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
}
localdata2 = 0;
}
}
else
{
} else {
digit = 1;
localdata2 *= 10;
localdata2 += (*p - '0');
}
p++;
}
if (! digit)
{
if (!digit) {
*token = lcommunity_token_unknown;
return NULL;
}
@ -396,34 +372,30 @@ lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
When string includes keyword for each large community value.
Please specify keyword_included as non-zero value.
*/
struct lcommunity *
lcommunity_str2com (const char *str)
struct lcommunity *lcommunity_str2com(const char *str)
{
struct lcommunity *lcom = NULL;
enum lcommunity_token token = lcommunity_token_unknown;
struct lcommunity_val lval;
while ((str = lcommunity_gettoken (str, &lval, &token)))
{
switch (token)
{
while ((str = lcommunity_gettoken(str, &lval, &token))) {
switch (token) {
case lcommunity_token_val:
if (lcom == NULL)
lcom = lcommunity_new ();
lcommunity_add_val (lcom, &lval);
lcom = lcommunity_new();
lcommunity_add_val(lcom, &lval);
break;
case lcommunity_token_unknown:
default:
if (lcom)
lcommunity_free (&lcom);
lcommunity_free(&lcom);
return NULL;
}
}
return lcom;
}
int
lcommunity_include (struct lcommunity *lcom, u_char *ptr)
int lcommunity_include(struct lcommunity *lcom, u_char *ptr)
{
int i;
u_char *lcom_ptr;
@ -431,7 +403,7 @@ lcommunity_include (struct lcommunity *lcom, u_char *ptr)
lcom_ptr = lcom->val;
for (i = 0; i < lcom->size; i++) {
lcom_ptr += (i * LCOMMUNITY_SIZE);
if (memcmp (ptr, lcom_ptr, LCOMMUNITY_SIZE) == 0)
if (memcmp(ptr, lcom_ptr, LCOMMUNITY_SIZE) == 0)
return 1;
}
return 0;
@ -440,8 +412,7 @@ lcommunity_include (struct lcommunity *lcom, u_char *ptr)
/* Convert large community attribute to string.
The large coms will be in 65535:65531:0 format.
*/
char *
lcommunity_lcom2str (struct lcommunity *lcom, int format)
char *lcommunity_lcom2str(struct lcommunity *lcom, int format)
{
int i;
u_int8_t *pnt;
@ -453,29 +424,27 @@ lcommunity_lcom2str (struct lcommunity *lcom, int format)
int first = 1;
u_int32_t globaladmin, localdata1, localdata2;
if (lcom->size == 0)
{
str_buf = XMALLOC (MTYPE_LCOMMUNITY_STR, 1);
if (lcom->size == 0) {
str_buf = XMALLOC(MTYPE_LCOMMUNITY_STR, 1);
str_buf[0] = '\0';
return str_buf;
}
/* Prepare buffer. */
str_buf = XMALLOC (MTYPE_LCOMMUNITY_STR, LCOMMUNITY_STR_DEFAULT_LEN + 1);
str_buf = XMALLOC(MTYPE_LCOMMUNITY_STR, LCOMMUNITY_STR_DEFAULT_LEN + 1);
str_size = LCOMMUNITY_STR_DEFAULT_LEN + 1;
str_pnt = 0;
for (i = 0; i < lcom->size; i++)
{
for (i = 0; i < lcom->size; i++) {
/* Make it sure size is enough. */
while (str_pnt + LCOMMUNITY_STR_DEFAULT_LEN >= str_size)
{
while (str_pnt + LCOMMUNITY_STR_DEFAULT_LEN >= str_size) {
str_size *= 2;
str_buf = XREALLOC (MTYPE_LCOMMUNITY_STR, str_buf, str_size);
str_buf = XREALLOC(MTYPE_LCOMMUNITY_STR, str_buf,
str_size);
}
/* Space between each value. */
if (! first)
if (!first)
str_buf[str_pnt++] = ' ';
pnt = lcom->val + (i * 12);
@ -495,7 +464,7 @@ lcommunity_lcom2str (struct lcommunity *lcom, int format)
localdata2 |= (*pnt++ << 8);
localdata2 |= (*pnt++);
len = sprintf( str_buf + str_pnt, "%u:%u:%u", globaladmin,
len = sprintf(str_buf + str_pnt, "%u:%u:%u", globaladmin,
localdata1, localdata2);
str_pnt += len;
first = 0;
@ -503,8 +472,7 @@ lcommunity_lcom2str (struct lcommunity *lcom, int format)
return str_buf;
}
int
lcommunity_match (const struct lcommunity *lcom1,
int lcommunity_match(const struct lcommunity *lcom1,
const struct lcommunity *lcom2)
{
int i = 0;
@ -520,9 +488,10 @@ lcommunity_match (const struct lcommunity *lcom1,
return 0;
/* Every community on com2 needs to be on com1 for this to match */
while (i < lcom1->size && j < lcom2->size)
{
if (memcmp (lcom1->val + (i*12), lcom2->val + (j*12), LCOMMUNITY_SIZE) == 0)
while (i < lcom1->size && j < lcom2->size) {
if (memcmp(lcom1->val + (i * 12), lcom2->val + (j * 12),
LCOMMUNITY_SIZE)
== 0)
j++;
i++;
}
@ -534,32 +503,33 @@ lcommunity_match (const struct lcommunity *lcom1,
}
/* Delete one lcommunity. */
void
lcommunity_del_val (struct lcommunity *lcom, u_char *ptr)
void lcommunity_del_val(struct lcommunity *lcom, u_char *ptr)
{
int i = 0;
int c = 0;
if (! lcom->val)
if (!lcom->val)
return;
while (i < lcom->size)
{
if (memcmp (lcom->val + i*LCOMMUNITY_SIZE, ptr, LCOMMUNITY_SIZE) == 0)
{
c = lcom->size -i -1;
while (i < lcom->size) {
if (memcmp(lcom->val + i * LCOMMUNITY_SIZE, ptr,
LCOMMUNITY_SIZE)
== 0) {
c = lcom->size - i - 1;
if (c > 0)
memmove (lcom->val + i*LCOMMUNITY_SIZE, lcom->val + (i + 1)*LCOMMUNITY_SIZE, c * LCOMMUNITY_SIZE);
memmove(lcom->val + i * LCOMMUNITY_SIZE,
lcom->val + (i + 1) * LCOMMUNITY_SIZE,
c * LCOMMUNITY_SIZE);
lcom->size--;
if (lcom->size > 0)
lcom->val = XREALLOC (MTYPE_COMMUNITY_VAL, lcom->val,
lcom_length (lcom));
else
{
XFREE (MTYPE_COMMUNITY_VAL, lcom->val);
lcom->val =
XREALLOC(MTYPE_COMMUNITY_VAL, lcom->val,
lcom_length(lcom));
else {
XFREE(MTYPE_COMMUNITY_VAL, lcom->val);
lcom->val = NULL;
}
return;

View File

@ -30,8 +30,7 @@
#define LCOMMUNITY_SIZE 12
/* Large Communities attribute. */
struct lcommunity
{
struct lcommunity {
/* Reference counter. */
unsigned long refcnt;
@ -46,29 +45,30 @@ struct lcommunity
};
/* Extended community value is eight octet. */
struct lcommunity_val
{
struct lcommunity_val {
char val[LCOMMUNITY_SIZE];
};
#define lcom_length(X) ((X)->size * LCOMMUNITY_SIZE)
extern void lcommunity_init (void);
extern void lcommunity_finish (void);
extern void lcommunity_free (struct lcommunity **);
extern struct lcommunity *lcommunity_parse (u_int8_t *, u_short);
extern struct lcommunity *lcommunity_dup (struct lcommunity *);
extern struct lcommunity *lcommunity_merge (struct lcommunity *, struct lcommunity *);
extern struct lcommunity *lcommunity_uniq_sort (struct lcommunity *);
extern struct lcommunity *lcommunity_intern (struct lcommunity *);
extern int lcommunity_cmp (const void *, const void *);
extern void lcommunity_unintern (struct lcommunity **);
extern unsigned int lcommunity_hash_make (void *);
extern struct hash *lcommunity_hash (void);
extern struct lcommunity *lcommunity_str2com (const char *);
extern char *lcommunity_lcom2str (struct lcommunity *, int);
extern int lcommunity_match (const struct lcommunity *, const struct lcommunity *);
extern char *lcommunity_str (struct lcommunity *);
extern int lcommunity_include (struct lcommunity *lcom, u_char *ptr);
extern void lcommunity_del_val (struct lcommunity *lcom, u_char *ptr);
extern void lcommunity_init(void);
extern void lcommunity_finish(void);
extern void lcommunity_free(struct lcommunity **);
extern struct lcommunity *lcommunity_parse(u_int8_t *, u_short);
extern struct lcommunity *lcommunity_dup(struct lcommunity *);
extern struct lcommunity *lcommunity_merge(struct lcommunity *,
struct lcommunity *);
extern struct lcommunity *lcommunity_uniq_sort(struct lcommunity *);
extern struct lcommunity *lcommunity_intern(struct lcommunity *);
extern int lcommunity_cmp(const void *, const void *);
extern void lcommunity_unintern(struct lcommunity **);
extern unsigned int lcommunity_hash_make(void *);
extern struct hash *lcommunity_hash(void);
extern struct lcommunity *lcommunity_str2com(const char *);
extern char *lcommunity_lcom2str(struct lcommunity *, int);
extern int lcommunity_match(const struct lcommunity *,
const struct lcommunity *);
extern char *lcommunity_str(struct lcommunity *);
extern int lcommunity_include(struct lcommunity *lcom, u_char *ptr);
extern void lcommunity_del_val(struct lcommunity *lcom, u_char *ptr);
#endif /* _QUAGGA_BGP_LCOMMUNITY_H */

View File

@ -60,27 +60,24 @@
#endif
/* bgpd options, we use GNU getopt library. */
static const struct option longopts[] =
{
{ "bgp_port", required_argument, NULL, 'p'},
{ "listenon", required_argument, NULL, 'l'},
{ "retain", no_argument, NULL, 'r'},
{ "no_kernel", no_argument, NULL, 'n'},
{ "skip_runas", no_argument, NULL, 'S'},
{ "ecmp", required_argument, NULL, 'e'},
{ 0 }
};
static const struct option longopts[] = {
{"bgp_port", required_argument, NULL, 'p'},
{"listenon", required_argument, NULL, 'l'},
{"retain", no_argument, NULL, 'r'},
{"no_kernel", no_argument, NULL, 'n'},
{"skip_runas", no_argument, NULL, 'S'},
{"ecmp", required_argument, NULL, 'e'},
{0}};
/* signal definitions */
void sighup (void);
void sigint (void);
void sigusr1 (void);
void sighup(void);
void sigint(void);
void sigusr1(void);
static void bgp_exit (int);
static void bgp_vrf_terminate (void);
static void bgp_exit(int);
static void bgp_vrf_terminate(void);
static struct quagga_signal_t bgp_signals[] =
{
static struct quagga_signal_t bgp_signals[] = {
{
.signal = SIGHUP,
.handler = &sighup,
@ -103,15 +100,11 @@ static struct quagga_signal_t bgp_signals[] =
static int retain_mode = 0;
/* privileges */
static zebra_capabilities_t _caps_p [] =
{
ZCAP_BIND,
ZCAP_NET_RAW,
ZCAP_NET_ADMIN,
static zebra_capabilities_t _caps_p[] = {
ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN,
};
struct zebra_privs_t bgpd_privs =
{
struct zebra_privs_t bgpd_privs = {
#if defined(FRR_USER) && defined(FRR_GROUP)
.user = FRR_USER,
.group = FRR_GROUP,
@ -127,43 +120,39 @@ struct zebra_privs_t bgpd_privs =
static struct frr_daemon_info bgpd_di;
/* SIGHUP handler. */
void
sighup (void)
void sighup(void)
{
zlog_info ("SIGHUP received");
zlog_info("SIGHUP received");
/* Terminate all thread. */
bgp_terminate ();
bgp_reset ();
zlog_info ("bgpd restarting!");
bgp_terminate();
bgp_reset();
zlog_info("bgpd restarting!");
/* Reload config file. */
vty_read_config (bgpd_di.config_file, config_default);
vty_read_config(bgpd_di.config_file, config_default);
/* Try to return to normal operation. */
}
/* SIGINT handler. */
__attribute__((__noreturn__)) void
sigint (void)
__attribute__((__noreturn__)) void sigint(void)
{
zlog_notice ("Terminating on signal");
zlog_notice("Terminating on signal");
if (! retain_mode)
{
bgp_terminate ();
if (!retain_mode) {
bgp_terminate();
if (bgpd_privs.user) /* NULL if skip_runas flag set */
zprivs_terminate (&bgpd_privs);
zprivs_terminate(&bgpd_privs);
}
bgp_exit (0);
bgp_exit(0);
exit (0);
exit(0);
}
/* SIGUSR1 handler. */
void
sigusr1 (void)
void sigusr1(void)
{
zlog_rotate();
}
@ -175,59 +164,58 @@ sigusr1 (void)
Zebra route removal and protocol teardown are not meant to be done here.
For example, "retain_mode" may be set.
*/
static __attribute__((__noreturn__)) void
bgp_exit (int status)
static __attribute__((__noreturn__)) void bgp_exit(int status)
{
struct bgp *bgp;
struct listnode *node, *nnode;
/* it only makes sense for this to be called on a clean exit */
assert (status == 0);
assert(status == 0);
bfd_gbl_exit();
bgp_close();
if (retain_mode)
if_add_hook (IF_DELETE_HOOK, NULL);
if_add_hook(IF_DELETE_HOOK, NULL);
/* reverse bgp_master_init */
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
bgp_delete (bgp);
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
bgp_delete(bgp);
/* reverse bgp_dump_init */
bgp_dump_finish ();
bgp_dump_finish();
/* reverse bgp_route_init */
bgp_route_finish ();
bgp_route_finish();
/* cleanup route maps */
bgp_route_map_terminate();
/* reverse bgp_attr_init */
bgp_attr_finish ();
bgp_attr_finish();
/* reverse access_list_init */
access_list_add_hook (NULL);
access_list_delete_hook (NULL);
access_list_reset ();
access_list_add_hook(NULL);
access_list_delete_hook(NULL);
access_list_reset();
/* reverse bgp_filter_init */
as_list_add_hook (NULL);
as_list_delete_hook (NULL);
bgp_filter_reset ();
as_list_add_hook(NULL);
as_list_delete_hook(NULL);
bgp_filter_reset();
/* reverse prefix_list_init */
prefix_list_add_hook (NULL);
prefix_list_delete_hook (NULL);
prefix_list_reset ();
prefix_list_add_hook(NULL);
prefix_list_delete_hook(NULL);
prefix_list_reset();
/* reverse community_list_init */
community_list_terminate (bgp_clist);
community_list_terminate(bgp_clist);
bgp_vrf_terminate ();
cmd_terminate ();
vty_terminate ();
bgp_vrf_terminate();
cmd_terminate();
vty_terminate();
#if ENABLE_BGP_VNC
vnc_zebra_destroy();
#endif
@ -235,63 +223,58 @@ bgp_exit (int status)
/* reverse bgp_master_init */
if (bm->master)
thread_master_free (bm->master);
thread_master_free(bm->master);
closezlog ();
closezlog();
list_delete (bm->bgp);
memset (bm, 0, sizeof (*bm));
list_delete(bm->bgp);
memset(bm, 0, sizeof(*bm));
if (bgp_debug_count())
log_memstats_stderr ("bgpd");
exit (status);
log_memstats_stderr("bgpd");
exit(status);
}
static int
bgp_vrf_new (struct vrf *vrf)
static int bgp_vrf_new(struct vrf *vrf)
{
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug ("VRF Created: %s(%d)", vrf->name, vrf->vrf_id);
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF Created: %s(%d)", vrf->name, vrf->vrf_id);
return 0;
}
static int
bgp_vrf_delete (struct vrf *vrf)
static int bgp_vrf_delete(struct vrf *vrf)
{
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug ("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id);
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id);
return 0;
}
static int
bgp_vrf_enable (struct vrf *vrf)
static int bgp_vrf_enable(struct vrf *vrf)
{
struct bgp *bgp;
vrf_id_t old_vrf_id;
if (BGP_DEBUG (zebra, ZEBRA))
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF enable add %s id %d", vrf->name, vrf->vrf_id);
bgp = bgp_lookup_by_name (vrf->name);
if (bgp)
{
bgp = bgp_lookup_by_name(vrf->name);
if (bgp) {
old_vrf_id = bgp->vrf_id;
/* We have instance configured, link to VRF and make it "up". */
bgp_vrf_link (bgp, vrf);
bgp_vrf_link(bgp, vrf);
/* Update any redistribute vrf bitmaps if the vrf_id changed */
if (old_vrf_id != bgp->vrf_id)
bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
bgp_instance_up (bgp);
bgp_instance_up(bgp);
}
return 0;
}
static int
bgp_vrf_disable (struct vrf *vrf)
static int bgp_vrf_disable(struct vrf *vrf)
{
struct bgp *bgp;
vrf_id_t old_vrf_id;
@ -299,55 +282,46 @@ bgp_vrf_disable (struct vrf *vrf)
if (vrf->vrf_id == VRF_DEFAULT)
return 0;
if (BGP_DEBUG (zebra, ZEBRA))
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
bgp = bgp_lookup_by_name (vrf->name);
if (bgp)
{
bgp = bgp_lookup_by_name(vrf->name);
if (bgp) {
old_vrf_id = bgp->vrf_id;
/* We have instance configured, unlink from VRF and make it "down". */
bgp_vrf_unlink (bgp, vrf);
/* We have instance configured, unlink from VRF and make it
* "down". */
bgp_vrf_unlink(bgp, vrf);
/* Update any redistribute vrf bitmaps if the vrf_id changed */
if (old_vrf_id != bgp->vrf_id)
bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
bgp_instance_down (bgp);
bgp_instance_down(bgp);
}
/* Note: This is a callback, the VRF will be deleted by the caller. */
return 0;
}
static void
bgp_vrf_init (void)
static void bgp_vrf_init(void)
{
vrf_init (bgp_vrf_new,
bgp_vrf_enable,
bgp_vrf_disable,
bgp_vrf_delete);
vrf_init(bgp_vrf_new, bgp_vrf_enable, bgp_vrf_disable, bgp_vrf_delete);
}
static void
bgp_vrf_terminate (void)
static void bgp_vrf_terminate(void)
{
vrf_terminate ();
vrf_terminate();
}
FRR_DAEMON_INFO(bgpd, BGP,
.vty_port = BGP_VTY_PORT,
FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
.proghelp = "Implementation of the BGP routing protocol.",
.signals = bgp_signals,
.n_signals = array_size(bgp_signals),
.signals = bgp_signals, .n_signals = array_size(bgp_signals),
.privs = &bgpd_privs,
)
.privs = &bgpd_privs, )
/* Main routine of bgpd. Treatment of argument and start bgp finite
state machine is handled at here. */
int
main (int argc, char **argv)
int main(int argc, char **argv)
{
int opt;
int tmp_port;
@ -358,7 +332,8 @@ main (int argc, char **argv)
int skip_runas = 0;
frr_preinit(&bgpd_di, argc, argv);
frr_opt_add("p:l:rne:", longopts,
frr_opt_add(
"p:l:rne:", longopts,
" -p, --bgp_port Set bgp protocol's port number\n"
" -l, --listenon Listen on specified address (implies -n)\n"
" -r, --retain When program terminates, retain added route by bgpd.\n"
@ -367,29 +342,29 @@ main (int argc, char **argv)
" -e, --ecmp Specify ECMP to use.\n");
/* Command line argument treatment. */
while (1)
{
opt = frr_getopt (argc, argv, 0);
while (1) {
opt = frr_getopt(argc, argv, 0);
if (opt == EOF)
break;
switch (opt)
{
switch (opt) {
case 0:
break;
case 'p':
tmp_port = atoi (optarg);
tmp_port = atoi(optarg);
if (tmp_port <= 0 || tmp_port > 0xffff)
bgp_port = BGP_PORT_DEFAULT;
else
bgp_port = tmp_port;
break;
case 'e':
multipath_num = atoi (optarg);
if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
{
zlog_err ("Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM);
multipath_num = atoi(optarg);
if (multipath_num > MULTIPATH_NUM
|| multipath_num <= 0) {
zlog_err(
"Multipath Number specified must be less than %d and greater than 0",
MULTIPATH_NUM);
return 1;
}
break;
@ -407,32 +382,31 @@ main (int argc, char **argv)
skip_runas = 1;
break;
default:
frr_help_exit (1);
frr_help_exit(1);
break;
}
}
if (skip_runas)
memset (&bgpd_privs, 0, sizeof (bgpd_privs));
memset(&bgpd_privs, 0, sizeof(bgpd_privs));
/* BGP master init. */
bgp_master_init (frr_init ());
bgp_master_init(frr_init());
bm->port = bgp_port;
bm->address = bgp_address;
if (no_fib_flag)
bgp_option_set (BGP_OPT_NO_FIB);
bgp_option_set(BGP_OPT_NO_FIB);
/* Initializations. */
bgp_vrf_init ();
bgp_vrf_init();
/* BGP related initialization. */
bgp_init ();
bgp_init();
snprintf (bgpd_di.startinfo, sizeof (bgpd_di.startinfo), ", bgp@%s:%d",
(bm->address ? bm->address : "<all>"),
bm->port);
snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), ", bgp@%s:%d",
(bm->address ? bm->address : "<all>"), bm->port);
frr_config_fork ();
frr_run (bm->master);
frr_config_fork();
frr_run(bm->master);
/* Not reached. */
return (0);

View File

@ -45,15 +45,13 @@
*
* Record maximum-paths configuration for BGP instance
*/
int
bgp_maximum_paths_set (struct bgp *bgp, afi_t afi, safi_t safi,
int peertype, u_int16_t maxpaths, u_int16_t options)
int bgp_maximum_paths_set(struct bgp *bgp, afi_t afi, safi_t safi, int peertype,
u_int16_t maxpaths, u_int16_t options)
{
if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX))
return -1;
switch (peertype)
{
switch (peertype) {
case BGP_PEER_IBGP:
bgp->maxpaths[afi][safi].maxpaths_ibgp = maxpaths;
bgp->maxpaths[afi][safi].ibgp_flags |= options;
@ -73,15 +71,13 @@ bgp_maximum_paths_set (struct bgp *bgp, afi_t afi, safi_t safi,
*
* Remove maximum-paths configuration from BGP instance
*/
int
bgp_maximum_paths_unset (struct bgp *bgp, afi_t afi, safi_t safi,
int bgp_maximum_paths_unset(struct bgp *bgp, afi_t afi, safi_t safi,
int peertype)
{
if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX))
return -1;
switch (peertype)
{
switch (peertype) {
case BGP_PEER_IBGP:
bgp->maxpaths[afi][safi].maxpaths_ibgp = multipath_num;
bgp->maxpaths[afi][safi].ibgp_flags = 0;
@ -103,49 +99,50 @@ bgp_maximum_paths_unset (struct bgp *bgp, afi_t afi, safi_t safi,
* or greater than zero if bi1 is respectively less than, equal to,
* or greater than bi2.
*/
int
bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2)
int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
{
int compare;
compare = IPV4_ADDR_CMP (&bi1->attr->nexthop, &bi2->attr->nexthop);
if (!compare)
{
if (bi1->attr->mp_nexthop_len == bi2->attr->mp_nexthop_len)
{
switch (bi1->attr->mp_nexthop_len)
{
compare = IPV4_ADDR_CMP(&bi1->attr->nexthop, &bi2->attr->nexthop);
if (!compare) {
if (bi1->attr->mp_nexthop_len == bi2->attr->mp_nexthop_len) {
switch (bi1->attr->mp_nexthop_len) {
case BGP_ATTR_NHLEN_IPV4:
case BGP_ATTR_NHLEN_VPNV4:
compare = IPV4_ADDR_CMP (&bi1->attr->mp_nexthop_global_in,
compare = IPV4_ADDR_CMP(
&bi1->attr->mp_nexthop_global_in,
&bi2->attr->mp_nexthop_global_in);
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
compare = IPV6_ADDR_CMP (&bi1->attr->mp_nexthop_global,
compare = IPV6_ADDR_CMP(
&bi1->attr->mp_nexthop_global,
&bi2->attr->mp_nexthop_global);
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
compare = IPV6_ADDR_CMP (&bi1->attr->mp_nexthop_global,
compare = IPV6_ADDR_CMP(
&bi1->attr->mp_nexthop_global,
&bi2->attr->mp_nexthop_global);
if (!compare)
compare = IPV6_ADDR_CMP (&bi1->attr->mp_nexthop_local,
compare = IPV6_ADDR_CMP(
&bi1->attr->mp_nexthop_local,
&bi2->attr->mp_nexthop_local);
break;
}
}
/* This can happen if one IPv6 peer sends you global and link-local
/* This can happen if one IPv6 peer sends you global and
* link-local
* nexthops but another IPv6 peer only sends you global
*/
else if (bi1->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL ||
bi1->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
{
compare = IPV6_ADDR_CMP (&bi1->attr->mp_nexthop_global,
else if (bi1->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
|| bi1->attr->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
compare = IPV6_ADDR_CMP(&bi1->attr->mp_nexthop_global,
&bi2->attr->mp_nexthop_global);
if (!compare)
{
if (bi1->attr->mp_nexthop_len < bi2->attr->mp_nexthop_len)
if (!compare) {
if (bi1->attr->mp_nexthop_len
< bi2->attr->mp_nexthop_len)
compare = -1;
else
compare = 1;
@ -168,8 +165,7 @@ bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2)
* The order of paths is determined first by received nexthop, and then
* by peer address if the nexthops are the same.
*/
static int
bgp_info_mpath_cmp (void *val1, void *val2)
static int bgp_info_mpath_cmp(void *val1, void *val2)
{
struct bgp_info *bi1, *bi2;
int compare;
@ -177,10 +173,9 @@ bgp_info_mpath_cmp (void *val1, void *val2)
bi1 = val1;
bi2 = val2;
compare = bgp_info_nexthop_cmp (bi1, bi2);
compare = bgp_info_nexthop_cmp(bi1, bi2);
if (!compare)
{
if (!compare) {
if (!bi1->peer->su_remote && !bi2->peer->su_remote)
compare = 0;
else if (!bi1->peer->su_remote)
@ -188,7 +183,8 @@ bgp_info_mpath_cmp (void *val1, void *val2)
else if (!bi2->peer->su_remote)
compare = -1;
else
compare = sockunion_cmp (bi1->peer->su_remote, bi2->peer->su_remote);
compare = sockunion_cmp(bi1->peer->su_remote,
bi2->peer->su_remote);
}
return compare;
@ -200,11 +196,10 @@ bgp_info_mpath_cmp (void *val1, void *val2)
* Initialize the mp_list, which holds the list of multipaths
* selected by bgp_best_selection
*/
void
bgp_mp_list_init (struct list *mp_list)
void bgp_mp_list_init(struct list *mp_list)
{
assert (mp_list);
memset (mp_list, 0, sizeof (struct list));
assert(mp_list);
memset(mp_list, 0, sizeof(struct list));
mp_list->cmp = bgp_info_mpath_cmp;
}
@ -213,11 +208,10 @@ bgp_mp_list_init (struct list *mp_list)
*
* Clears all entries out of the mp_list
*/
void
bgp_mp_list_clear (struct list *mp_list)
void bgp_mp_list_clear(struct list *mp_list)
{
assert (mp_list);
list_delete_all_node (mp_list);
assert(mp_list);
list_delete_all_node(mp_list);
}
/*
@ -225,11 +219,10 @@ bgp_mp_list_clear (struct list *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_info *mpinfo)
{
assert (mp_list && mpinfo);
listnode_add_sort (mp_list, mpinfo);
assert(mp_list && mpinfo);
listnode_add_sort(mp_list, mpinfo);
}
/*
@ -237,11 +230,11 @@ bgp_mp_list_add (struct list *mp_list, struct bgp_info *mpinfo)
*
* Allocate and zero memory for a new bgp_info_mpath element
*/
static struct bgp_info_mpath *
bgp_info_mpath_new (void)
static struct bgp_info_mpath *bgp_info_mpath_new(void)
{
struct bgp_info_mpath *new_mpath;
new_mpath = XCALLOC (MTYPE_BGP_MPATH_INFO, sizeof (struct bgp_info_mpath));
new_mpath =
XCALLOC(MTYPE_BGP_MPATH_INFO, sizeof(struct bgp_info_mpath));
return new_mpath;
}
@ -250,14 +243,12 @@ bgp_info_mpath_new (void)
*
* Release resources for a bgp_info_mpath element and zero out pointer
*/
void
bgp_info_mpath_free (struct bgp_info_mpath **mpath)
void bgp_info_mpath_free(struct bgp_info_mpath **mpath)
{
if (mpath && *mpath)
{
if (mpath && *mpath) {
if ((*mpath)->mp_attr)
bgp_attr_unintern (&(*mpath)->mp_attr);
XFREE (MTYPE_BGP_MPATH_INFO, *mpath);
bgp_attr_unintern(&(*mpath)->mp_attr);
XFREE(MTYPE_BGP_MPATH_INFO, *mpath);
*mpath = NULL;
}
}
@ -268,12 +259,10 @@ bgp_info_mpath_free (struct bgp_info_mpath **mpath)
* Fetch the mpath element for the given bgp_info. Used for
* doing lazy allocation.
*/
static struct bgp_info_mpath *
bgp_info_mpath_get (struct bgp_info *binfo)
static struct bgp_info_mpath *bgp_info_mpath_get(struct bgp_info *binfo)
{
struct bgp_info_mpath *mpath;
if (!binfo->mpath)
{
if (!binfo->mpath) {
mpath = bgp_info_mpath_new();
if (!mpath)
return NULL;
@ -289,13 +278,13 @@ bgp_info_mpath_get (struct bgp_info *binfo)
* Enqueue a path onto the multipath list given the previous multipath
* list entry
*/
static void
bgp_info_mpath_enqueue (struct bgp_info *prev_info, struct bgp_info *binfo)
static void bgp_info_mpath_enqueue(struct bgp_info *prev_info,
struct bgp_info *binfo)
{
struct bgp_info_mpath *prev, *mpath;
prev = bgp_info_mpath_get (prev_info);
mpath = bgp_info_mpath_get (binfo);
prev = bgp_info_mpath_get(prev_info);
mpath = bgp_info_mpath_get(binfo);
if (!prev || !mpath)
return;
@ -305,7 +294,7 @@ bgp_info_mpath_enqueue (struct bgp_info *prev_info, struct bgp_info *binfo)
prev->mp_next->mp_prev = mpath;
prev->mp_next = mpath;
SET_FLAG (binfo->flags, BGP_INFO_MULTIPATH);
SET_FLAG(binfo->flags, BGP_INFO_MULTIPATH);
}
/*
@ -313,8 +302,7 @@ bgp_info_mpath_enqueue (struct bgp_info *prev_info, struct bgp_info *binfo)
*
* Remove a path from the multipath list
*/
void
bgp_info_mpath_dequeue (struct bgp_info *binfo)
void bgp_info_mpath_dequeue(struct bgp_info *binfo)
{
struct bgp_info_mpath *mpath = binfo->mpath;
if (!mpath)
@ -324,7 +312,7 @@ bgp_info_mpath_dequeue (struct bgp_info *binfo)
if (mpath->mp_next)
mpath->mp_next->mp_prev = mpath->mp_prev;
mpath->mp_next = mpath->mp_prev = NULL;
UNSET_FLAG (binfo->flags, BGP_INFO_MULTIPATH);
UNSET_FLAG(binfo->flags, BGP_INFO_MULTIPATH);
}
/*
@ -332,8 +320,7 @@ bgp_info_mpath_dequeue (struct bgp_info *binfo)
*
* Given a bgp_info, return the next multipath entry
*/
struct bgp_info *
bgp_info_mpath_next (struct bgp_info *binfo)
struct bgp_info *bgp_info_mpath_next(struct bgp_info *binfo)
{
if (!binfo->mpath || !binfo->mpath->mp_next)
return NULL;
@ -345,10 +332,9 @@ bgp_info_mpath_next (struct bgp_info *binfo)
*
* Given bestpath bgp_info, return the first multipath entry.
*/
struct bgp_info *
bgp_info_mpath_first (struct bgp_info *binfo)
struct bgp_info *bgp_info_mpath_first(struct bgp_info *binfo)
{
return bgp_info_mpath_next (binfo);
return bgp_info_mpath_next(binfo);
}
/*
@ -356,8 +342,7 @@ bgp_info_mpath_first (struct bgp_info *binfo)
*
* Given the bestpath bgp_info, return the number of multipath entries
*/
u_int32_t
bgp_info_mpath_count (struct bgp_info *binfo)
u_int32_t bgp_info_mpath_count(struct bgp_info *binfo)
{
if (!binfo->mpath)
return 0;
@ -369,13 +354,12 @@ bgp_info_mpath_count (struct bgp_info *binfo)
*
* Sets the count of multipaths into bestpath's mpath element
*/
static void
bgp_info_mpath_count_set (struct bgp_info *binfo, u_int32_t count)
static void bgp_info_mpath_count_set(struct bgp_info *binfo, u_int32_t count)
{
struct bgp_info_mpath *mpath;
if (!count && !binfo->mpath)
return;
mpath = bgp_info_mpath_get (binfo);
mpath = bgp_info_mpath_get(binfo);
if (!mpath)
return;
mpath->mp_count = count;
@ -387,8 +371,7 @@ bgp_info_mpath_count_set (struct bgp_info *binfo, u_int32_t count)
* Given bestpath bgp_info, return aggregated attribute set used
* for advertising the multipath route
*/
struct attr *
bgp_info_mpath_attr (struct bgp_info *binfo)
struct attr *bgp_info_mpath_attr(struct bgp_info *binfo)
{
if (!binfo->mpath)
return NULL;
@ -400,13 +383,12 @@ bgp_info_mpath_attr (struct bgp_info *binfo)
*
* 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_info_mpath_attr_set(struct bgp_info *binfo, struct attr *attr)
{
struct bgp_info_mpath *mpath;
if (!attr && !binfo->mpath)
return;
mpath = bgp_info_mpath_get (binfo);
mpath = bgp_info_mpath_get(binfo);
if (!mpath)
return;
mpath->mp_attr = attr;
@ -418,8 +400,7 @@ bgp_info_mpath_attr_set (struct bgp_info *binfo, struct attr *attr)
* Compare and sync up the multipath list with the mp_list generated by
* bgp_best_selection
*/
void
bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
struct bgp_info *old_best, struct list *mp_list,
struct bgp_maxpaths_cfg *mpath_cfg)
{
@ -436,33 +417,33 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
cur_mpath = NULL;
old_mpath_count = 0;
prev_mpath = new_best;
mp_node = listhead (mp_list);
mp_node = listhead(mp_list);
debug = bgp_debug_bestpath(&rn->p);
if (debug)
prefix2str (&rn->p, pfx_buf, sizeof (pfx_buf));
prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
if (new_best)
{
if (new_best) {
mpath_count++;
if (new_best != old_best)
bgp_info_mpath_dequeue (new_best);
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP) ?
mpath_cfg->maxpaths_ibgp : mpath_cfg->maxpaths_ebgp;
bgp_info_mpath_dequeue(new_best);
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP)
? mpath_cfg->maxpaths_ibgp
: mpath_cfg->maxpaths_ebgp;
}
if (old_best)
{
cur_mpath = bgp_info_mpath_first (old_best);
old_mpath_count = bgp_info_mpath_count (old_best);
bgp_info_mpath_count_set (old_best, 0);
bgp_info_mpath_dequeue (old_best);
if (old_best) {
cur_mpath = bgp_info_mpath_first(old_best);
old_mpath_count = bgp_info_mpath_count(old_best);
bgp_info_mpath_count_set(old_best, 0);
bgp_info_mpath_dequeue(old_best);
}
if (debug)
zlog_debug("%s: starting mpath update, newbest %s num candidates %d old-mpath-count %d",
zlog_debug(
"%s: starting mpath update, newbest %s num candidates %d old-mpath-count %d",
pfx_buf, new_best ? new_best->peer->host : "NONE",
listcount (mp_list), old_mpath_count);
listcount(mp_list), old_mpath_count);
/*
* We perform an ordered walk through both lists in parallel.
@ -475,8 +456,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
* Note that new_best might be somewhere in the mp_list, so we need
* to skip over it
*/
while (mp_node || cur_mpath)
{
while (mp_node || cur_mpath) {
struct bgp_info *tmp_info;
/*
@ -487,46 +467,49 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
if (!cur_mpath && (mpath_count >= maxpaths))
break;
mp_next_node = mp_node ? listnextnode (mp_node) : NULL;
next_mpath = cur_mpath ? bgp_info_mpath_next (cur_mpath) : NULL;
tmp_info = mp_node ? listgetdata (mp_node) : NULL;
mp_next_node = mp_node ? listnextnode(mp_node) : NULL;
next_mpath = cur_mpath ? bgp_info_mpath_next(cur_mpath) : NULL;
tmp_info = mp_node ? listgetdata(mp_node) : NULL;
if (debug)
zlog_debug("%s: comparing candidate %s with existing mpath %s",
pfx_buf, tmp_info ? tmp_info->peer->host : "NONE",
zlog_debug(
"%s: comparing candidate %s with existing mpath %s",
pfx_buf,
tmp_info ? tmp_info->peer->host : "NONE",
cur_mpath ? cur_mpath->peer->host : "NONE");
/*
* If equal, the path was a multipath and is still a multipath.
* Insert onto new multipath list if maxpaths allows.
*/
if (mp_node && (listgetdata (mp_node) == cur_mpath))
{
list_delete_node (mp_list, mp_node);
bgp_info_mpath_dequeue (cur_mpath);
if ((mpath_count < maxpaths) &&
bgp_info_nexthop_cmp (prev_mpath, cur_mpath))
{
bgp_info_mpath_enqueue (prev_mpath, cur_mpath);
if (mp_node && (listgetdata(mp_node) == cur_mpath)) {
list_delete_node(mp_list, mp_node);
bgp_info_mpath_dequeue(cur_mpath);
if ((mpath_count < maxpaths)
&& bgp_info_nexthop_cmp(prev_mpath, cur_mpath)) {
bgp_info_mpath_enqueue(prev_mpath, cur_mpath);
prev_mpath = cur_mpath;
mpath_count++;
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug("%s: %s is still multipath, cur count %d",
if (debug) {
bgp_info_path_with_addpath_rx_str(
cur_mpath, path_buf);
zlog_debug(
"%s: %s is still multipath, cur count %d",
pfx_buf, path_buf, mpath_count);
}
}
else
{
} else {
mpath_changed = 1;
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug ("%s: remove mpath %s nexthop %s, cur count %d",
if (debug) {
bgp_info_path_with_addpath_rx_str(
cur_mpath, path_buf);
zlog_debug(
"%s: remove mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &cur_mpath->attr->nexthop,
nh_buf[0], sizeof (nh_buf[0])),
inet_ntop(AF_INET,
&cur_mpath->attr
->nexthop,
nh_buf[0],
sizeof(nh_buf[0])),
mpath_count);
}
}
@ -535,62 +518,73 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
continue;
}
if (cur_mpath && (!mp_node ||
(bgp_info_mpath_cmp (cur_mpath,
listgetdata (mp_node)) < 0)))
{
if (cur_mpath
&& (!mp_node
|| (bgp_info_mpath_cmp(cur_mpath, listgetdata(mp_node))
< 0))) {
/*
* If here, we have an old multipath and either the mp_list
* If here, we have an old multipath and either the
* mp_list
* is finished or the next mp_node points to a later
* multipath, so we need to purge this path from the
* multipath list
*/
bgp_info_mpath_dequeue (cur_mpath);
bgp_info_mpath_dequeue(cur_mpath);
mpath_changed = 1;
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug ("%s: remove mpath %s nexthop %s, cur count %d",
if (debug) {
bgp_info_path_with_addpath_rx_str(cur_mpath,
path_buf);
zlog_debug(
"%s: remove mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &cur_mpath->attr->nexthop,
nh_buf[0], sizeof (nh_buf[0])),
inet_ntop(AF_INET,
&cur_mpath->attr->nexthop,
nh_buf[0], sizeof(nh_buf[0])),
mpath_count);
}
cur_mpath = next_mpath;
}
else
{
} else {
/*
* If here, we have a path on the mp_list that was not previously
* a multipath (due to non-equivalance or maxpaths exceeded),
* or the matching multipath is sorted later in the multipath
* list. Before we enqueue the path on the new multipath list,
* make sure its not on the old_best multipath list or referenced
* If here, we have a path on the mp_list that was not
* previously
* a multipath (due to non-equivalance or maxpaths
* exceeded),
* or the matching multipath is sorted later in the
* multipath
* list. Before we enqueue the path on the new multipath
* list,
* make sure its not on the old_best multipath list or
* referenced
* via next_mpath:
* - If next_mpath points to this new path, update next_mpath to
* - If next_mpath points to this new path, update
* next_mpath to
* point to the multipath after this one
* - Dequeue the path from the multipath list just to make sure
* - Dequeue the path from the multipath list just to
* make sure
*/
new_mpath = listgetdata (mp_node);
list_delete_node (mp_list, mp_node);
if ((mpath_count < maxpaths) && (new_mpath != new_best) &&
bgp_info_nexthop_cmp (prev_mpath, new_mpath))
{
new_mpath = listgetdata(mp_node);
list_delete_node(mp_list, mp_node);
if ((mpath_count < maxpaths) && (new_mpath != new_best)
&& bgp_info_nexthop_cmp(prev_mpath, new_mpath)) {
if (new_mpath == next_mpath)
bgp_info_mpath_next (new_mpath);
bgp_info_mpath_dequeue (new_mpath);
bgp_info_mpath_next(new_mpath);
bgp_info_mpath_dequeue(new_mpath);
bgp_info_mpath_enqueue (prev_mpath, new_mpath);
bgp_info_mpath_enqueue(prev_mpath, new_mpath);
prev_mpath = new_mpath;
mpath_changed = 1;
mpath_count++;
if (debug)
{
bgp_info_path_with_addpath_rx_str(new_mpath, path_buf);
zlog_debug ("%s: add mpath %s nexthop %s, cur count %d",
if (debug) {
bgp_info_path_with_addpath_rx_str(
new_mpath, path_buf);
zlog_debug(
"%s: add mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &new_mpath->attr->nexthop,
nh_buf[0], sizeof (nh_buf[0])),
inet_ntop(AF_INET,
&new_mpath->attr
->nexthop,
nh_buf[0],
sizeof(nh_buf[0])),
mpath_count);
}
}
@ -598,15 +592,17 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
}
}
if (new_best)
{
if (new_best) {
if (debug)
zlog_debug("%s: New mpath count (incl newbest) %d mpath-change %s",
pfx_buf, mpath_count, mpath_changed ? "YES" : "NO");
zlog_debug(
"%s: New mpath count (incl newbest) %d mpath-change %s",
pfx_buf, mpath_count,
mpath_changed ? "YES" : "NO");
bgp_info_mpath_count_set (new_best, mpath_count-1);
if (mpath_changed || (bgp_info_mpath_count (new_best) != old_mpath_count))
SET_FLAG (new_best->flags, BGP_INFO_MULTIPATH_CHG);
bgp_info_mpath_count_set(new_best, mpath_count - 1);
if (mpath_changed
|| (bgp_info_mpath_count(new_best) != old_mpath_count))
SET_FLAG(new_best->flags, BGP_INFO_MULTIPATH_CHG);
}
}
@ -616,23 +612,22 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
* Clean up multipath information for BGP_INFO_DMED_SELECTED path that
* is not selected as best path
*/
void
bgp_mp_dmed_deselect (struct bgp_info *dmed_best)
void bgp_mp_dmed_deselect(struct bgp_info *dmed_best)
{
struct bgp_info *mpinfo, *mpnext;
if (!dmed_best)
return;
for (mpinfo = bgp_info_mpath_first (dmed_best); mpinfo; mpinfo = mpnext)
{
mpnext = bgp_info_mpath_next (mpinfo);
bgp_info_mpath_dequeue (mpinfo);
for (mpinfo = bgp_info_mpath_first(dmed_best); mpinfo;
mpinfo = mpnext) {
mpnext = bgp_info_mpath_next(mpinfo);
bgp_info_mpath_dequeue(mpinfo);
}
bgp_info_mpath_count_set (dmed_best, 0);
UNSET_FLAG (dmed_best->flags, BGP_INFO_MULTIPATH_CHG);
assert (bgp_info_mpath_first (dmed_best) == 0);
bgp_info_mpath_count_set(dmed_best, 0);
UNSET_FLAG(dmed_best->flags, BGP_INFO_MULTIPATH_CHG);
assert(bgp_info_mpath_first(dmed_best) == 0);
}
/*
@ -647,8 +642,7 @@ bgp_mp_dmed_deselect (struct bgp_info *dmed_best)
* is no change in multipath selection and no attribute change in
* any multipath.
*/
void
bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
struct bgp_info *old_best)
{
struct bgp_info *mpinfo;
@ -659,117 +653,113 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
struct community *community, *commerge;
struct ecommunity *ecomm, *ecommerge;
struct lcommunity *lcomm, *lcommerge;
struct attr attr = { 0 };
struct attr attr = {0};
if (old_best && (old_best != new_best) &&
(old_attr = bgp_info_mpath_attr (old_best)))
{
bgp_attr_unintern (&old_attr);
bgp_info_mpath_attr_set (old_best, NULL);
if (old_best && (old_best != new_best)
&& (old_attr = bgp_info_mpath_attr(old_best))) {
bgp_attr_unintern(&old_attr);
bgp_info_mpath_attr_set(old_best, NULL);
}
if (!new_best)
return;
if (!bgp_info_mpath_count (new_best))
{
if ((new_attr = bgp_info_mpath_attr (new_best)))
{
bgp_attr_unintern (&new_attr);
bgp_info_mpath_attr_set (new_best, NULL);
SET_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED);
if (!bgp_info_mpath_count(new_best)) {
if ((new_attr = bgp_info_mpath_attr(new_best))) {
bgp_attr_unintern(&new_attr);
bgp_info_mpath_attr_set(new_best, NULL);
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
}
return;
}
bgp_attr_dup (&attr, new_best->attr);
bgp_attr_dup(&attr, new_best->attr);
if (new_best->peer &&
bgp_flag_check (new_best->peer->bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET))
{
if (new_best->peer && bgp_flag_check(new_best->peer->bgp,
BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
/* aggregate attribute from multipath constituents */
aspath = aspath_dup (attr.aspath);
aspath = aspath_dup(attr.aspath);
origin = attr.origin;
community = attr.community ? community_dup (attr.community) : NULL;
ecomm = (attr.ecommunity) ? ecommunity_dup (attr.ecommunity) : NULL;
lcomm = (attr.lcommunity) ? lcommunity_dup (attr.lcommunity) : NULL;
community =
attr.community ? community_dup(attr.community) : NULL;
ecomm = (attr.ecommunity) ? ecommunity_dup(attr.ecommunity)
: NULL;
lcomm = (attr.lcommunity) ? lcommunity_dup(attr.lcommunity)
: NULL;
for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
mpinfo = bgp_info_mpath_next (mpinfo))
{
asmerge = aspath_aggregate (aspath, mpinfo->attr->aspath);
aspath_free (aspath);
for (mpinfo = bgp_info_mpath_first(new_best); mpinfo;
mpinfo = bgp_info_mpath_next(mpinfo)) {
asmerge =
aspath_aggregate(aspath, mpinfo->attr->aspath);
aspath_free(aspath);
aspath = asmerge;
if (origin < mpinfo->attr->origin)
origin = mpinfo->attr->origin;
if (mpinfo->attr->community)
{
if (community)
{
commerge = community_merge (community, mpinfo->attr->community);
community = community_uniq_sort (commerge);
community_free (commerge);
}
else
community = community_dup (mpinfo->attr->community);
if (mpinfo->attr->community) {
if (community) {
commerge = community_merge(
community,
mpinfo->attr->community);
community =
community_uniq_sort(commerge);
community_free(commerge);
} else
community = community_dup(
mpinfo->attr->community);
}
if (mpinfo->attr->ecommunity)
{
if (ecomm)
{
ecommerge = ecommunity_merge (ecomm, mpinfo->attr->ecommunity);
ecomm = ecommunity_uniq_sort (ecommerge);
ecommunity_free (&ecommerge);
if (mpinfo->attr->ecommunity) {
if (ecomm) {
ecommerge = ecommunity_merge(
ecomm,
mpinfo->attr->ecommunity);
ecomm = ecommunity_uniq_sort(ecommerge);
ecommunity_free(&ecommerge);
} else
ecomm = ecommunity_dup(
mpinfo->attr->ecommunity);
}
else
ecomm = ecommunity_dup (mpinfo->attr->ecommunity);
}
if (mpinfo->attr->lcommunity)
{
if (lcomm)
{
lcommerge = lcommunity_merge (lcomm, mpinfo->attr->lcommunity);
lcomm = lcommunity_uniq_sort (lcommerge);
lcommunity_free (&lcommerge);
}
else
lcomm = lcommunity_dup (mpinfo->attr->lcommunity);
if (mpinfo->attr->lcommunity) {
if (lcomm) {
lcommerge = lcommunity_merge(
lcomm,
mpinfo->attr->lcommunity);
lcomm = lcommunity_uniq_sort(lcommerge);
lcommunity_free(&lcommerge);
} else
lcomm = lcommunity_dup(
mpinfo->attr->lcommunity);
}
}
attr.aspath = aspath;
attr.origin = origin;
if (community)
{
if (community) {
attr.community = community;
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
}
if (ecomm)
{
if (ecomm) {
attr.ecommunity = ecomm;
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
/* Zap multipath attr nexthop so we set nexthop to self */
attr.nexthop.s_addr = 0;
memset (&attr.mp_nexthop_global, 0, sizeof (struct in6_addr));
memset(&attr.mp_nexthop_global, 0, sizeof(struct in6_addr));
/* TODO: should we set ATOMIC_AGGREGATE and AGGREGATOR? */
}
new_attr = bgp_attr_intern (&attr);
new_attr = bgp_attr_intern(&attr);
if (new_attr != bgp_info_mpath_attr (new_best))
{
if ((old_attr = bgp_info_mpath_attr (new_best)))
bgp_attr_unintern (&old_attr);
bgp_info_mpath_attr_set (new_best, new_attr);
SET_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED);
}
else
bgp_attr_unintern (&new_attr);
if (new_attr != bgp_info_mpath_attr(new_best)) {
if ((old_attr = bgp_info_mpath_attr(new_best)))
bgp_attr_unintern(&old_attr);
bgp_info_mpath_attr_set(new_best, new_attr);
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
} else
bgp_attr_unintern(&new_attr);
}

View File

@ -25,8 +25,7 @@
/* Supplemental information linked to bgp_info for keeping track of
* multipath selections, lazily allocated to save memory
*/
struct bgp_info_mpath
{
struct bgp_info_mpath {
/* Points to the first multipath (on bestpath) or the next multipath */
struct bgp_info_mpath *mp_next;
@ -44,34 +43,34 @@ struct bgp_info_mpath
};
/* Functions to support maximum-paths configuration */
extern int bgp_maximum_paths_set (struct bgp *, afi_t, safi_t, int, u_int16_t,
extern int bgp_maximum_paths_set(struct bgp *, afi_t, safi_t, int, u_int16_t,
u_int16_t);
extern int bgp_maximum_paths_unset (struct bgp *, afi_t, safi_t, int);
extern int bgp_maximum_paths_unset(struct bgp *, afi_t, safi_t, int);
/* Functions used by bgp_best_selection to record current
* multipath selections
*/
extern int bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2);
extern void bgp_mp_list_init (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_dmed_deselect (struct bgp_info *);
extern void bgp_info_mpath_update (struct bgp_node *, struct bgp_info *,
extern int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2);
extern void bgp_mp_list_init(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_dmed_deselect(struct bgp_info *);
extern void bgp_info_mpath_update(struct bgp_node *, struct bgp_info *,
struct bgp_info *, struct list *,
struct bgp_maxpaths_cfg *);
extern void bgp_info_mpath_aggregate_update (struct bgp_info *,
extern void bgp_info_mpath_aggregate_update(struct bgp_info *,
struct bgp_info *);
/* Unlink and free multipath information associated with a bgp_info */
extern void bgp_info_mpath_dequeue (struct bgp_info *);
extern void bgp_info_mpath_free (struct bgp_info_mpath **);
extern void bgp_info_mpath_dequeue(struct bgp_info *);
extern void bgp_info_mpath_free(struct bgp_info_mpath **);
/* Walk list of multipaths associated with a best path */
extern struct bgp_info *bgp_info_mpath_first (struct bgp_info *);
extern struct bgp_info *bgp_info_mpath_next (struct bgp_info *);
extern struct bgp_info *bgp_info_mpath_first(struct bgp_info *);
extern struct bgp_info *bgp_info_mpath_next(struct bgp_info *);
/* Accessors for multipath information */
extern u_int32_t bgp_info_mpath_count (struct bgp_info *);
extern struct attr *bgp_info_mpath_attr (struct bgp_info *);
extern u_int32_t bgp_info_mpath_count(struct bgp_info *);
extern struct attr *bgp_info_mpath_attr(struct bgp_info *);
#endif /* _QUAGGA_BGP_MPATH_H */

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
#include "bgpd/bgp_rd.h"
#ifdef MPLS_LABEL_MAX
# undef MPLS_LABEL_MAX
#undef MPLS_LABEL_MAX
#endif
typedef enum {
@ -48,12 +48,11 @@ typedef enum {
MPLS_LABEL_ILLEGAL = 0xFFFFFFFF /* for internal use only */
} mpls_special_label_t;
#define MPLS_LABEL_IS_SPECIAL(label) \
((label) <= MPLS_LABEL_EXTENSION)
#define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
#define MPLS_LABEL_IS_NULL(label) \
((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL || \
(label) == MPLS_LABEL_IPV6_EXPLICIT_NULL || \
(label) == MPLS_LABEL_IMPLICIT_NULL)
((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \
|| (label) == MPLS_LABEL_IPV6_EXPLICIT_NULL \
|| (label) == MPLS_LABEL_IMPLICIT_NULL)
#define BGP_VPNVX_HELP_STR \
"Address Family\n" \
@ -61,19 +60,19 @@ typedef enum {
#define V4_HEADER \
" Network Next Hop Metric LocPrf Weight Path\n"
#define V4_HEADER_TAG \
" Network Next Hop In tag/Out tag\n"
#define V4_HEADER_TAG " Network Next Hop In tag/Out tag\n"
#define V4_HEADER_OVERLAY \
" Network Next Hop EthTag Overlay Index RouterMac\n"
extern void bgp_mplsvpn_init (void);
extern int bgp_nlri_parse_vpn (struct peer *, struct attr *, struct bgp_nlri *);
extern u_int32_t decode_label (mpls_label_t *);
extern void bgp_mplsvpn_init(void);
extern int bgp_nlri_parse_vpn(struct peer *, struct attr *, struct bgp_nlri *);
extern u_int32_t decode_label(mpls_label_t *);
extern void encode_label(mpls_label_t, mpls_label_t *);
extern int
argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi);
extern int bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
enum bgp_show_type type, void *output_arg, int tags, u_char use_json);
extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
int *index, afi_t *afi);
extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
enum bgp_show_type type, void *output_arg,
int tags, u_char use_json);
#endif /* _QUAGGA_BGP_MPLSVPN_H */

View File

@ -47,8 +47,7 @@ extern struct zebra_privs_t bgpd_privs;
static int bgp_bind(struct peer *);
/* BGP listening socket. */
struct bgp_listener
{
struct bgp_listener {
int fd;
union sockunion su;
struct thread *thread;
@ -58,8 +57,8 @@ struct bgp_listener
* Set MD5 key for the socket, for the given IPv4 peer address.
* If the password is NULL or zero-length, the option will be disabled.
*/
static int
bgp_md5_set_socket (int socket, union sockunion *su, const char *password)
static int bgp_md5_set_socket(int socket, union sockunion *su,
const char *password)
{
int ret = -1;
int en = ENOSYS;
@ -67,130 +66,124 @@ bgp_md5_set_socket (int socket, union sockunion *su, const char *password)
union sockunion su2;
#endif /* HAVE_TCP_MD5SIG */
assert (socket >= 0);
assert(socket >= 0);
#if HAVE_DECL_TCP_MD5SIG
/* Ensure there is no extraneous port information. */
memcpy (&su2, su, sizeof (union sockunion));
memcpy(&su2, su, sizeof(union sockunion));
if (su2.sa.sa_family == AF_INET)
su2.sin.sin_port = 0;
else
su2.sin6.sin6_port = 0;
ret = sockopt_tcp_signature (socket, &su2, password);
ret = sockopt_tcp_signature(socket, &su2, password);
en = errno;
#endif /* HAVE_TCP_MD5SIG */
if (ret < 0)
zlog_warn ("can't set TCP_MD5SIG option on socket %d: %s", socket, safe_strerror (en));
zlog_warn("can't set TCP_MD5SIG option on socket %d: %s",
socket, safe_strerror(en));
return ret;
}
/* Helper for bgp_connect */
static int
bgp_md5_set_connect (int socket, union sockunion *su, const char *password)
static int bgp_md5_set_connect(int socket, union sockunion *su,
const char *password)
{
int ret = -1;
#if HAVE_DECL_TCP_MD5SIG
if ( bgpd_privs.change (ZPRIVS_RAISE) )
{
zlog_err ("%s: could not raise privs", __func__);
if (bgpd_privs.change(ZPRIVS_RAISE)) {
zlog_err("%s: could not raise privs", __func__);
return ret;
}
ret = bgp_md5_set_socket (socket, su, password);
ret = bgp_md5_set_socket(socket, su, password);
if (bgpd_privs.change (ZPRIVS_LOWER) )
zlog_err ("%s: could not lower privs", __func__);
if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("%s: could not lower privs", __func__);
#endif /* HAVE_TCP_MD5SIG */
return ret;
}
static int
bgp_md5_set_password (struct peer *peer, const char *password)
static int bgp_md5_set_password(struct peer *peer, const char *password)
{
struct listnode *node;
int ret = 0;
struct bgp_listener *listener;
if ( bgpd_privs.change (ZPRIVS_RAISE) )
{
zlog_err ("%s: could not raise privs", __func__);
if (bgpd_privs.change(ZPRIVS_RAISE)) {
zlog_err("%s: could not raise privs", __func__);
return -1;
}
/* Set or unset the password on the listen socket(s). Outbound connections
/* Set or unset the password on the listen socket(s). Outbound
* connections
* are taken care of in bgp_connect() below.
*/
for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
if (listener->su.sa.sa_family == peer->su.sa.sa_family)
{
ret = bgp_md5_set_socket (listener->fd, &peer->su, password);
if (listener->su.sa.sa_family == peer->su.sa.sa_family) {
ret = bgp_md5_set_socket(listener->fd, &peer->su,
password);
break;
}
if (bgpd_privs.change (ZPRIVS_LOWER) )
zlog_err ("%s: could not lower privs", __func__);
if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("%s: could not lower privs", __func__);
return ret;
}
int
bgp_md5_set (struct peer *peer)
int bgp_md5_set(struct peer *peer)
{
/* Set the password from listen socket. */
return bgp_md5_set_password (peer, peer->password);
return bgp_md5_set_password(peer, peer->password);
}
int
bgp_md5_unset (struct peer *peer)
int bgp_md5_unset(struct peer *peer)
{
/* Unset the password from listen socket. */
return bgp_md5_set_password (peer, NULL);
return bgp_md5_set_password(peer, NULL);
}
int
bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
int bgp_set_socket_ttl(struct peer *peer, int bgp_sock)
{
char buf[INET_ADDRSTRLEN];
int ret = 0;
/* In case of peer is EBGP, we should set TTL for this connection. */
if (!peer->gtsm_hops && (peer_sort (peer) == BGP_PEER_EBGP))
{
ret = sockopt_ttl (peer->su.sa.sa_family, bgp_sock, peer->ttl);
if (ret)
{
zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
if (!peer->gtsm_hops && (peer_sort(peer) == BGP_PEER_EBGP)) {
ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl);
if (ret) {
zlog_err(
"%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__, inet_ntop(AF_INET, &peer->remote_id,
buf, sizeof(buf)),
errno);
return ret;
}
}
else if (peer->gtsm_hops)
{
/* On Linux, setting minttl without setting ttl seems to mess with the
} else if (peer->gtsm_hops) {
/* On Linux, setting minttl without setting ttl seems to mess
with the
outgoing ttl. Therefore setting both.
*/
ret = sockopt_ttl (peer->su.sa.sa_family, bgp_sock, MAXTTL);
if (ret)
{
zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL);
if (ret) {
zlog_err(
"%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__, inet_ntop(AF_INET, &peer->remote_id,
buf, sizeof(buf)),
errno);
return ret;
}
ret = sockopt_minttl (peer->su.sa.sa_family, bgp_sock,
ret = sockopt_minttl(peer->su.sa.sa_family, bgp_sock,
MAXTTL + 1 - peer->gtsm_hops);
if (ret)
{
zlog_err ("%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
if (ret) {
zlog_err(
"%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
__func__, inet_ntop(AF_INET, &peer->remote_id,
buf, sizeof(buf)),
errno);
return ret;
}
@ -206,17 +199,17 @@ bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
* which the incoming connection is bound to. This could either be a VRF
* or it could be an interface, which in turn determines the VRF.
*/
static int
bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst)
{
#ifndef SO_BINDTODEVICE
/* only Linux has SO_BINDTODEVICE, but we're in Linux-specific code here
* anyway since the assumption is that the interface name returned by
* getsockopt() is useful in identifying the VRF, particularly with Linux's
* getsockopt() is useful in identifying the VRF, particularly with
* Linux's
* VRF l3master device. The whole mechanism is specific to Linux, so...
* when other platforms add VRF support, this will need handling here as
* well. (or, some restructuring) */
*bgp_inst = bgp_get_default ();
*bgp_inst = bgp_get_default();
return !*bgp_inst;
#else
@ -229,25 +222,22 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
*bgp_inst = NULL;
name[0] = '\0';
rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
if (rc != 0)
{
#if defined (HAVE_CUMULUS)
zlog_err ("[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
safe_strerror (errno), sock);
if (rc != 0) {
#if defined(HAVE_CUMULUS)
zlog_err("[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
safe_strerror(errno), sock);
return -1;
#endif
}
if (!strlen(name))
{
*bgp_inst = bgp_get_default ();
if (!strlen(name)) {
*bgp_inst = bgp_get_default();
return 0; /* default instance. */
}
/* First try match to instance; if that fails, check for interfaces. */
bgp = bgp_lookup_by_name (name);
if (bgp)
{
bgp = bgp_lookup_by_name(name);
if (bgp) {
if (!bgp->vrf_id) // unexpected
return -1;
*bgp_inst = bgp;
@ -255,16 +245,14 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
}
/* TODO - This will be optimized once interfaces move into the NS */
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
struct interface *ifp;
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
continue;
ifp = if_lookup_by_name (name, bgp->vrf_id);
if (ifp)
{
ifp = if_lookup_by_name(name, bgp->vrf_id);
if (ifp) {
*bgp_inst = bgp;
return 0;
}
@ -276,8 +264,7 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
}
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
static int bgp_accept(struct thread *thread)
{
int bgp_sock;
int accept_sock;
@ -288,13 +275,12 @@ bgp_accept (struct thread *thread)
char buf[SU_ADDRSTRLEN];
struct bgp *bgp = NULL;
sockunion_init (&su);
sockunion_init(&su);
/* Register accept thread. */
accept_sock = THREAD_FD (thread);
if (accept_sock < 0)
{
zlog_err ("accept_sock is nevative value %d", accept_sock);
accept_sock = THREAD_FD(thread);
if (accept_sock < 0) {
zlog_err("accept_sock is nevative value %d", accept_sock);
return -1;
}
listener->thread = NULL;
@ -302,65 +288,63 @@ bgp_accept (struct thread *thread)
&listener->thread);
/* Accept client connection. */
bgp_sock = sockunion_accept (accept_sock, &su);
if (bgp_sock < 0)
{
zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
bgp_sock = sockunion_accept(accept_sock, &su);
if (bgp_sock < 0) {
zlog_err("[Error] BGP socket accept failed (%s)",
safe_strerror(errno));
return -1;
}
set_nonblocking (bgp_sock);
set_nonblocking(bgp_sock);
/* Obtain BGP instance this connection is meant for. */
if (bgp_get_instance_for_inc_conn (bgp_sock, &bgp))
{
if (bgp_get_instance_for_inc_conn(bgp_sock, &bgp)) {
if (bgp_debug_neighbor_events(NULL))
zlog_debug ("[Event] Could not get instance for incoming conn from %s",
inet_sutop (&su, buf));
close (bgp_sock);
zlog_debug(
"[Event] Could not get instance for incoming conn from %s",
inet_sutop(&su, buf));
close(bgp_sock);
return -1;
}
/* Set socket send buffer size */
setsockopt_so_sendbuf (bgp_sock, BGP_SOCKET_SNDBUF_SIZE);
setsockopt_so_sendbuf(bgp_sock, BGP_SOCKET_SNDBUF_SIZE);
/* Check remote IP address */
peer1 = peer_lookup (bgp, &su);
peer1 = peer_lookup(bgp, &su);
if (! peer1)
{
peer1 = peer_lookup_dynamic_neighbor (bgp, &su);
if (peer1)
{
if (!peer1) {
peer1 = peer_lookup_dynamic_neighbor(bgp, &su);
if (peer1) {
/* Dynamic neighbor has been created, let it proceed */
peer1->fd = bgp_sock;
bgp_fsm_change_status(peer1, Active);
BGP_TIMER_OFF(peer1->t_start); /* created in peer_create() */
BGP_TIMER_OFF(
peer1->t_start); /* created in peer_create() */
if (peer_active (peer1))
BGP_EVENT_ADD (peer1, TCP_connection_open);
if (peer_active(peer1))
BGP_EVENT_ADD(peer1, TCP_connection_open);
return 0;
}
}
if (! peer1)
{
if (bgp_debug_neighbor_events(NULL))
{
zlog_debug ("[Event] %s connection rejected - not configured"
if (!peer1) {
if (bgp_debug_neighbor_events(NULL)) {
zlog_debug(
"[Event] %s connection rejected - not configured"
" and not valid for dynamic",
inet_sutop (&su, buf));
inet_sutop(&su, buf));
}
close (bgp_sock);
close(bgp_sock);
return -1;
}
if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN))
{
if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN)) {
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("[Event] connection from %s rejected due to admin shutdown",
inet_sutop (&su, buf));
close (bgp_sock);
zlog_debug(
"[Event] connection from %s rejected due to admin shutdown",
inet_sutop(&su, buf));
close(bgp_sock);
return -1;
}
@ -370,53 +354,55 @@ bgp_accept (struct thread *thread)
* Established and then the Clearing_Completed event is generated. Also,
* block incoming connection in Deleted state.
*/
if (peer1->status == Clearing || peer1->status == Deleted)
{
if (peer1->status == Clearing || peer1->status == Deleted) {
if (bgp_debug_neighbor_events(peer1))
zlog_debug("[Event] Closing incoming conn for %s (%p) state %d",
zlog_debug(
"[Event] Closing incoming conn for %s (%p) state %d",
peer1->host, peer1, peer1->status);
close (bgp_sock);
close(bgp_sock);
return -1;
}
/* Check that at least one AF is activated for the peer. */
if (!peer_active (peer1))
{
if (!peer_active(peer1)) {
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("%s - incoming conn rejected - no AF activated for peer",
zlog_debug(
"%s - incoming conn rejected - no AF activated for peer",
peer1->host);
close (bgp_sock);
close(bgp_sock);
return -1;
}
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("[Event] BGP connection from host %s fd %d",
inet_sutop (&su, buf), bgp_sock);
zlog_debug("[Event] BGP connection from host %s fd %d",
inet_sutop(&su, buf), bgp_sock);
if (peer1->doppelganger)
{
if (peer1->doppelganger) {
/* We have an existing connection. Kill the existing one and run
with this one.
*/
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("[Event] New active connection from peer %s, Killing"
" previous active connection", peer1->host);
zlog_debug(
"[Event] New active connection from peer %s, Killing"
" previous active connection",
peer1->host);
peer_delete(peer1->doppelganger);
}
if (bgp_set_socket_ttl (peer1, bgp_sock) < 0)
if (bgp_set_socket_ttl(peer1, bgp_sock) < 0)
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("[Event] Unable to set min/max TTL on peer %s, Continuing",
zlog_debug(
"[Event] Unable to set min/max TTL on peer %s, Continuing",
peer1->host);
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);
peer->su = su;
hash_release(peer->bgp->peerhash, peer);
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
peer_xfer_config(peer, peer1);
UNSET_FLAG (peer->flags, PEER_FLAG_CONFIG_NODE);
UNSET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
peer->doppelganger = peer1;
peer1->doppelganger = peer;
@ -425,32 +411,31 @@ bgp_accept (struct thread *thread)
bgp_fsm_change_status(peer, Active);
BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */
SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
/* Make dummy peer until read Open packet. */
if (peer1->status == Established &&
CHECK_FLAG (peer1->sflags, PEER_STATUS_NSF_MODE))
{
/* If we have an existing established connection with graceful restart
* capability announced with one or more address families, then drop
if (peer1->status == Established
&& CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
/* If we have an existing established connection with graceful
* restart
* capability announced with one or more address families, then
* drop
* existing established connection and move state to connect.
*/
peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
SET_FLAG (peer1->sflags, PEER_STATUS_NSF_WAIT);
SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT);
bgp_event_update(peer1, TCP_connection_closed);
}
if (peer_active (peer))
{
BGP_EVENT_ADD (peer, TCP_connection_open);
if (peer_active(peer)) {
BGP_EVENT_ADD(peer, TCP_connection_open);
}
return 0;
}
/* BGP socket bind. */
static int
bgp_bind (struct peer *peer)
static int bgp_bind(struct peer *peer)
{
#ifdef SO_BINDTODEVICE
int ret;
@ -458,11 +443,11 @@ bgp_bind (struct peer *peer)
char *name = NULL;
/* If not bound to an interface or part of a VRF, we don't care. */
if (!peer->bgp->vrf_id && ! peer->ifname && !peer->conf_if)
if (!peer->bgp->vrf_id && !peer->ifname && !peer->conf_if)
return 0;
if (peer->su.sa.sa_family != AF_INET &&
peer->su.sa.sa_family != AF_INET6)
if (peer->su.sa.sa_family != AF_INET
&& peer->su.sa.sa_family != AF_INET6)
return 0; // unexpected
/* For IPv6 peering, interface (unnumbered or link-local with interface)
@ -470,8 +455,9 @@ bgp_bind (struct peer *peer)
* VRF are the situations to bind.
*/
if (peer->su.sa.sa_family == AF_INET6)
name = (peer->conf_if ? peer->conf_if : \
(peer->ifname ? peer->ifname : peer->bgp->name));
name = (peer->conf_if ? peer->conf_if
: (peer->ifname ? peer->ifname
: peer->bgp->name));
else
name = peer->ifname ? peer->ifname : peer->bgp->name;
@ -479,30 +465,29 @@ bgp_bind (struct peer *peer)
return 0;
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Binding to interface %s", peer->host, name);
zlog_debug("%s Binding to interface %s", peer->host, name);
if ( bgpd_privs.change (ZPRIVS_RAISE) )
zlog_err ("bgp_bind: could not raise privs");
if (bgpd_privs.change(ZPRIVS_RAISE))
zlog_err("bgp_bind: could not raise privs");
ret = setsockopt (peer->fd, SOL_SOCKET, SO_BINDTODEVICE,
name, strlen(name));
ret = setsockopt(peer->fd, SOL_SOCKET, SO_BINDTODEVICE, name,
strlen(name));
myerrno = errno;
if (bgpd_privs.change (ZPRIVS_LOWER) )
zlog_err ("bgp_bind: could not lower privs");
if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("bgp_bind: could not lower privs");
if (ret < 0)
{
if (bgp_debug_neighbor_events (peer))
zlog_debug ("bind to interface %s failed, errno=%d", name, myerrno);
if (ret < 0) {
if (bgp_debug_neighbor_events(peer))
zlog_debug("bind to interface %s failed, errno=%d",
name, myerrno);
return ret;
}
#endif /* SO_BINDTODEVICE */
return 0;
}
static int
bgp_update_address (struct interface *ifp, const union sockunion *dst,
static int bgp_update_address(struct interface *ifp, const union sockunion *dst,
union sockunion *addr)
{
struct prefix *p, *sel, d;
@ -510,55 +495,52 @@ bgp_update_address (struct interface *ifp, const union sockunion *dst,
struct listnode *node;
int common;
sockunion2hostprefix (dst, &d);
sockunion2hostprefix(dst, &d);
sel = NULL;
common = -1;
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
{
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
p = connected->address;
if (p->family != d.family)
continue;
if (prefix_common_bits (p, &d) > common)
{
if (prefix_common_bits(p, &d) > common) {
sel = p;
common = prefix_common_bits (sel, &d);
common = prefix_common_bits(sel, &d);
}
}
if (!sel)
return 1;
prefix2sockunion (sel, addr);
prefix2sockunion(sel, addr);
return 0;
}
/* Update source selection. */
static int
bgp_update_source (struct peer *peer)
static int bgp_update_source(struct peer *peer)
{
struct interface *ifp;
union sockunion addr;
int ret = 0;
sockunion_init (&addr);
sockunion_init(&addr);
/* Source is specified with interface name. */
if (peer->update_if)
{
ifp = if_lookup_by_name (peer->update_if, peer->bgp->vrf_id);
if (! ifp)
if (peer->update_if) {
ifp = if_lookup_by_name(peer->update_if, peer->bgp->vrf_id);
if (!ifp)
return -1;
if (bgp_update_address (ifp, &peer->su, &addr))
if (bgp_update_address(ifp, &peer->su, &addr))
return -1;
ret = sockunion_bind (peer->fd, &addr, 0, &addr);
ret = sockunion_bind(peer->fd, &addr, 0, &addr);
}
/* Source is specified with IP address. */
if (peer->update_source)
ret = sockunion_bind (peer->fd, peer->update_source, 0, peer->update_source);
ret = sockunion_bind(peer->fd, peer->update_source, 0,
peer->update_source);
return ret;
}
@ -566,95 +548,94 @@ bgp_update_source (struct peer *peer)
#define DATAPLANE_MARK 254 /* main table ID */
/* BGP try to connect to the peer. */
int
bgp_connect (struct peer *peer)
int bgp_connect(struct peer *peer)
{
ifindex_t ifindex = 0;
if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer))
{
if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer)) {
zlog_debug("Peer address not learnt: Returning from connect");
return 0;
}
/* Make socket for the peer. */
peer->fd = sockunion_socket (&peer->su);
peer->fd = sockunion_socket(&peer->su);
if (peer->fd < 0)
return -1;
set_nonblocking (peer->fd);
set_nonblocking(peer->fd);
/* Set socket send buffer size */
setsockopt_so_sendbuf (peer->fd, BGP_SOCKET_SNDBUF_SIZE);
setsockopt_so_sendbuf(peer->fd, BGP_SOCKET_SNDBUF_SIZE);
if (bgp_set_socket_ttl (peer, peer->fd) < 0)
if (bgp_set_socket_ttl(peer, peer->fd) < 0)
return -1;
sockopt_reuseaddr (peer->fd);
sockopt_reuseport (peer->fd);
sockopt_reuseaddr(peer->fd);
sockopt_reuseport(peer->fd);
if (sockopt_mark_default(peer->fd, DATAPLANE_MARK, &bgpd_privs) < 0)
zlog_warn("Unable to set mark on FD for peer %s, err=%s", peer->host,
safe_strerror(errno));
zlog_warn("Unable to set mark on FD for peer %s, err=%s",
peer->host, safe_strerror(errno));
#ifdef IPTOS_PREC_INTERNETCONTROL
if (bgpd_privs.change (ZPRIVS_RAISE))
zlog_err ("%s: could not raise privs", __func__);
if (sockunion_family (&peer->su) == AF_INET)
setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
else if (sockunion_family (&peer->su) == AF_INET6)
setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL);
if (bgpd_privs.change (ZPRIVS_LOWER))
zlog_err ("%s: could not lower privs", __func__);
if (bgpd_privs.change(ZPRIVS_RAISE))
zlog_err("%s: could not raise privs", __func__);
if (sockunion_family(&peer->su) == AF_INET)
setsockopt_ipv4_tos(peer->fd, IPTOS_PREC_INTERNETCONTROL);
else if (sockunion_family(&peer->su) == AF_INET6)
setsockopt_ipv6_tclass(peer->fd, IPTOS_PREC_INTERNETCONTROL);
if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("%s: could not lower privs", __func__);
#endif
if (peer->password)
bgp_md5_set_connect (peer->fd, &peer->su, peer->password);
bgp_md5_set_connect(peer->fd, &peer->su, peer->password);
/* Bind socket. */
bgp_bind (peer);
bgp_bind(peer);
/* Update source bind. */
if (bgp_update_source (peer) < 0)
{
if (bgp_update_source(peer) < 0) {
return connect_error;
}
if (peer->conf_if || peer->ifname)
ifindex = ifname2ifindex (peer->conf_if ? peer->conf_if : peer->ifname, peer->bgp->vrf_id);
ifindex = ifname2ifindex(peer->conf_if ? peer->conf_if
: peer->ifname,
peer->bgp->vrf_id);
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s [Event] Connect start to %s fd %d",
peer->host, peer->host, peer->fd);
zlog_debug("%s [Event] Connect start to %s fd %d", peer->host,
peer->host, peer->fd);
/* Connect to the remote peer. */
return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
return sockunion_connect(peer->fd, &peer->su, htons(peer->port),
ifindex);
}
/* After TCP connection is established. Get local address and port. */
int
bgp_getsockname (struct peer *peer)
int bgp_getsockname(struct peer *peer)
{
if (peer->su_local)
{
sockunion_free (peer->su_local);
if (peer->su_local) {
sockunion_free(peer->su_local);
peer->su_local = NULL;
}
if (peer->su_remote)
{
sockunion_free (peer->su_remote);
if (peer->su_remote) {
sockunion_free(peer->su_remote);
peer->su_remote = NULL;
}
peer->su_local = sockunion_getsockname (peer->fd);
if (!peer->su_local) return -1;
peer->su_remote = sockunion_getpeername (peer->fd);
if (!peer->su_remote) return -1;
peer->su_local = sockunion_getsockname(peer->fd);
if (!peer->su_local)
return -1;
peer->su_remote = sockunion_getpeername(peer->fd);
if (!peer->su_remote)
return -1;
if (bgp_nexthop_set (peer->su_local, peer->su_remote,
&peer->nexthop, peer))
{
#if defined (HAVE_CUMULUS)
zlog_err ("%s: nexthop_set failed, resetting connection - intf %p",
if (bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop,
peer)) {
#if defined(HAVE_CUMULUS)
zlog_err(
"%s: nexthop_set failed, resetting connection - intf %p",
peer->host, peer->nexthop.ifp);
return -1;
#endif
@ -664,58 +645,55 @@ bgp_getsockname (struct peer *peer)
}
static int
bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen)
{
struct bgp_listener *listener;
int ret, en;
sockopt_reuseaddr (sock);
sockopt_reuseport (sock);
sockopt_reuseaddr(sock);
sockopt_reuseport(sock);
if (bgpd_privs.change (ZPRIVS_RAISE))
zlog_err ("%s: could not raise privs", __func__);
if (bgpd_privs.change(ZPRIVS_RAISE))
zlog_err("%s: could not raise privs", __func__);
#ifdef IPTOS_PREC_INTERNETCONTROL
if (sa->sa_family == AF_INET)
setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL);
setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL);
else if (sa->sa_family == AF_INET6)
setsockopt_ipv6_tclass (sock, IPTOS_PREC_INTERNETCONTROL);
setsockopt_ipv6_tclass(sock, IPTOS_PREC_INTERNETCONTROL);
#endif
sockopt_v6only (sa->sa_family, sock);
sockopt_v6only(sa->sa_family, sock);
ret = bind (sock, sa, salen);
ret = bind(sock, sa, salen);
en = errno;
if (bgpd_privs.change (ZPRIVS_LOWER))
zlog_err ("%s: could not lower privs", __func__);
if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("%s: could not lower privs", __func__);
if (ret < 0)
{
zlog_err ("bind: %s", safe_strerror (en));
if (ret < 0) {
zlog_err("bind: %s", safe_strerror(en));
return ret;
}
ret = listen (sock, 3);
if (ret < 0)
{
zlog_err ("listen: %s", safe_strerror (errno));
ret = listen(sock, 3);
if (ret < 0) {
zlog_err("listen: %s", safe_strerror(errno));
return ret;
}
listener = XMALLOC (MTYPE_BGP_LISTENER, sizeof(*listener));
listener = XMALLOC(MTYPE_BGP_LISTENER, sizeof(*listener));
listener->fd = sock;
memcpy(&listener->su, sa, salen);
listener->thread = NULL;
thread_add_read(bm->master, bgp_accept, listener, sock, &listener->thread);
listnode_add (bm->listen_sockets, listener);
thread_add_read(bm->master, bgp_accept, listener, sock,
&listener->thread);
listnode_add(bm->listen_sockets, listener);
return 0;
}
/* IPv6 supported version of BGP server socket setup. */
int
bgp_socket (unsigned short port, const char *address)
int bgp_socket(unsigned short port, const char *address)
{
struct addrinfo *ainfo;
struct addrinfo *ainfo_save;
@ -727,52 +705,49 @@ bgp_socket (unsigned short port, const char *address)
int ret, count;
char port_str[BUFSIZ];
snprintf (port_str, sizeof(port_str), "%d", port);
port_str[sizeof (port_str) - 1] = '\0';
snprintf(port_str, sizeof(port_str), "%d", port);
port_str[sizeof(port_str) - 1] = '\0';
ret = getaddrinfo (address, port_str, &req, &ainfo_save);
if (ret != 0)
{
zlog_err ("getaddrinfo: %s", gai_strerror (ret));
ret = getaddrinfo(address, port_str, &req, &ainfo_save);
if (ret != 0) {
zlog_err("getaddrinfo: %s", gai_strerror(ret));
return -1;
}
count = 0;
for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next)
{
for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next) {
int sock;
if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
continue;
sock = socket (ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
if (sock < 0)
{
zlog_err ("socket: %s", safe_strerror (errno));
sock = socket(ainfo->ai_family, ainfo->ai_socktype,
ainfo->ai_protocol);
if (sock < 0) {
zlog_err("socket: %s", safe_strerror(errno));
continue;
}
/* if we intend to implement ttl-security, this socket needs ttl=255 */
sockopt_ttl (ainfo->ai_family, sock, MAXTTL);
/* if we intend to implement ttl-security, this socket needs
* ttl=255 */
sockopt_ttl(ainfo->ai_family, sock, MAXTTL);
ret = bgp_listener (sock, ainfo->ai_addr, ainfo->ai_addrlen);
ret = bgp_listener(sock, ainfo->ai_addr, ainfo->ai_addrlen);
if (ret == 0)
++count;
else
close(sock);
}
freeaddrinfo (ainfo_save);
if (count == 0)
{
zlog_err ("%s: no usable addresses", __func__);
freeaddrinfo(ainfo_save);
if (count == 0) {
zlog_err("%s: no usable addresses", __func__);
return -1;
}
return 0;
}
void
bgp_close (void)
void bgp_close(void)
{
struct listnode *node, *next;
struct bgp_listener *listener;
@ -780,11 +755,10 @@ bgp_close (void)
if (bm->listen_sockets == NULL)
return;
for (ALL_LIST_ELEMENTS (bm->listen_sockets, node, next, listener))
{
thread_cancel (listener->thread);
close (listener->fd);
listnode_delete (bm->listen_sockets, listener);
XFREE (MTYPE_BGP_LISTENER, listener);
for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
thread_cancel(listener->thread);
close(listener->fd);
listnode_delete(bm->listen_sockets, listener);
XFREE(MTYPE_BGP_LISTENER, listener);
}
}

View File

@ -23,13 +23,13 @@
#define BGP_SOCKET_SNDBUF_SIZE 65536
extern int bgp_socket (unsigned short, const char *);
extern void bgp_close (void);
extern int bgp_connect (struct peer *);
extern int bgp_getsockname (struct peer *);
extern int bgp_socket(unsigned short, const char *);
extern void bgp_close(void);
extern int bgp_connect(struct peer *);
extern int bgp_getsockname(struct peer *);
extern int bgp_md5_set (struct peer *);
extern int bgp_md5_unset (struct peer *);
extern int bgp_md5_set(struct peer *);
extern int bgp_md5_unset(struct peer *);
extern int bgp_set_socket_ttl(struct peer *, int fd);
#endif /* _QUAGGA_BGP_NETWORK_H */

View File

@ -47,88 +47,78 @@
#include "zebra/rib.h"
#include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
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);
return buf;
}
void
bnc_nexthop_free (struct bgp_nexthop_cache *bnc)
void bnc_nexthop_free(struct bgp_nexthop_cache *bnc)
{
nexthops_free(bnc->nexthop);
}
struct bgp_nexthop_cache *
bnc_new (void)
struct bgp_nexthop_cache *bnc_new(void)
{
struct bgp_nexthop_cache *bnc;
bnc = XCALLOC (MTYPE_BGP_NEXTHOP_CACHE, sizeof (struct bgp_nexthop_cache));
bnc = XCALLOC(MTYPE_BGP_NEXTHOP_CACHE,
sizeof(struct bgp_nexthop_cache));
LIST_INIT(&(bnc->paths));
return bnc;
}
void
bnc_free (struct bgp_nexthop_cache *bnc)
void bnc_free(struct bgp_nexthop_cache *bnc)
{
bnc_nexthop_free (bnc);
XFREE (MTYPE_BGP_NEXTHOP_CACHE, bnc);
bnc_nexthop_free(bnc);
XFREE(MTYPE_BGP_NEXTHOP_CACHE, bnc);
}
/* Reset and free all BGP nexthop cache. */
static void
bgp_nexthop_cache_reset (struct bgp_table *table)
static void bgp_nexthop_cache_reset(struct bgp_table *table)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
if ((bnc = rn->info) != NULL)
{
bnc_free (bnc);
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
if ((bnc = rn->info) != NULL) {
bnc_free(bnc);
rn->info = NULL;
bgp_unlock_node (rn);
bgp_unlock_node(rn);
}
}
/* BGP own address structure */
struct bgp_addr
{
struct bgp_addr {
struct in_addr addr;
int refcnt;
};
static void *
bgp_address_hash_alloc (void *p)
static void *bgp_address_hash_alloc(void *p)
{
const struct in_addr *val = (const struct in_addr *)p;
struct bgp_addr *addr;
addr = XMALLOC (MTYPE_BGP_ADDR, sizeof (struct bgp_addr));
addr = XMALLOC(MTYPE_BGP_ADDR, sizeof(struct bgp_addr));
addr->refcnt = 0;
addr->addr.s_addr = val->s_addr;
return addr;
}
static void
bgp_address_hash_free (void *addr)
static void bgp_address_hash_free(void *addr)
{
XFREE (MTYPE_BGP_ADDR, addr);
XFREE(MTYPE_BGP_ADDR, addr);
}
static unsigned int
bgp_address_hash_key_make (void *p)
static unsigned int bgp_address_hash_key_make(void *p)
{
const struct bgp_addr *addr = p;
return jhash_1word(addr->addr.s_addr, 0);
}
static int
bgp_address_hash_cmp (const void *p1, const void *p2)
static int bgp_address_hash_cmp(const void *p1, const void *p2)
{
const struct bgp_addr *addr1 = p1;
const struct bgp_addr *addr2 = p2;
@ -136,15 +126,13 @@ bgp_address_hash_cmp (const void *p1, const void *p2)
return addr1->addr.s_addr == addr2->addr.s_addr;
}
void
bgp_address_init (struct bgp *bgp)
void bgp_address_init(struct bgp *bgp)
{
bgp->address_hash = hash_create (bgp_address_hash_key_make,
bgp->address_hash = hash_create(bgp_address_hash_key_make,
bgp_address_hash_cmp, NULL);
}
void
bgp_address_destroy (struct bgp *bgp)
void bgp_address_destroy(struct bgp *bgp)
{
if (bgp->address_hash == NULL)
return;
@ -153,51 +141,46 @@ bgp_address_destroy (struct bgp *bgp)
bgp->address_hash = NULL;
}
static void
bgp_address_add (struct bgp *bgp, struct prefix *p)
static void bgp_address_add(struct bgp *bgp, struct prefix *p)
{
struct bgp_addr tmp;
struct bgp_addr *addr;
tmp.addr = p->u.prefix4;
addr = hash_get (bgp->address_hash, &tmp, bgp_address_hash_alloc);
addr = hash_get(bgp->address_hash, &tmp, bgp_address_hash_alloc);
if (!addr)
return;
addr->refcnt++;
}
static void
bgp_address_del (struct bgp *bgp, struct prefix *p)
static void bgp_address_del(struct bgp *bgp, struct prefix *p)
{
struct bgp_addr tmp;
struct bgp_addr *addr;
tmp.addr = p->u.prefix4;
addr = hash_lookup (bgp->address_hash, &tmp);
addr = hash_lookup(bgp->address_hash, &tmp);
/* may have been deleted earlier by bgp_interface_down() */
if (addr == NULL)
return;
addr->refcnt--;
if (addr->refcnt == 0)
{
hash_release (bgp->address_hash, addr);
XFREE (MTYPE_BGP_ADDR, addr);
if (addr->refcnt == 0) {
hash_release(bgp->address_hash, addr);
XFREE(MTYPE_BGP_ADDR, addr);
}
}
struct bgp_connected_ref
{
struct bgp_connected_ref {
unsigned int refcnt;
};
void
bgp_connected_add (struct bgp *bgp, struct connected *ifc)
void bgp_connected_add(struct bgp *bgp, struct connected *ifc)
{
struct prefix p;
struct prefix *addr;
@ -209,67 +192,61 @@ bgp_connected_add (struct bgp *bgp, struct connected *ifc)
addr = ifc->address;
p = *(CONNECTED_PREFIX(ifc));
if (addr->family == AF_INET)
{
apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
if (addr->family == AF_INET) {
apply_mask_ipv4((struct prefix_ipv4 *)&p);
if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
return;
bgp_address_add (bgp, addr);
bgp_address_add(bgp, addr);
rn = bgp_node_get (bgp->connected_table[AFI_IP], (struct prefix *) &p);
if (rn->info)
{
rn = bgp_node_get(bgp->connected_table[AFI_IP],
(struct prefix *)&p);
if (rn->info) {
bc = rn->info;
bc->refcnt++;
}
else
{
bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
} else {
bc = XCALLOC(MTYPE_BGP_CONN,
sizeof(struct bgp_connected_ref));
bc->refcnt = 1;
rn->info = bc;
}
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0) &&
peer->status != Established &&
!CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
{
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (peer->conf_if
&& (strcmp(peer->conf_if, ifc->ifp->name) == 0)
&& peer->status != Established
&& !CHECK_FLAG(peer->flags,
PEER_FLAG_IFPEER_V6ONLY)) {
if (peer_active(peer))
BGP_EVENT_ADD (peer, BGP_Stop);
BGP_EVENT_ADD (peer, BGP_Start);
BGP_EVENT_ADD(peer, BGP_Stop);
BGP_EVENT_ADD(peer, BGP_Start);
}
}
}
else if (addr->family == AF_INET6)
{
apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
} else if (addr->family == AF_INET6) {
apply_mask_ipv6((struct prefix_ipv6 *)&p);
if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
return;
if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
return;
rn = bgp_node_get (bgp->connected_table[AFI_IP6], (struct prefix *) &p);
if (rn->info)
{
rn = bgp_node_get(bgp->connected_table[AFI_IP6],
(struct prefix *)&p);
if (rn->info) {
bc = rn->info;
bc->refcnt++;
}
else
{
bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
} else {
bc = XCALLOC(MTYPE_BGP_CONN,
sizeof(struct bgp_connected_ref));
bc->refcnt = 1;
rn->info = bc;
}
}
}
void
bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
void bgp_connected_delete(struct bgp *bgp, struct connected *ifc)
{
struct prefix p;
struct prefix *addr;
@ -279,71 +256,65 @@ bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
addr = ifc->address;
p = *(CONNECTED_PREFIX(ifc));
if (addr->family == AF_INET)
{
apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
if (addr->family == AF_INET) {
apply_mask_ipv4((struct prefix_ipv4 *)&p);
if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
return;
bgp_address_del (bgp, addr);
bgp_address_del(bgp, addr);
rn = bgp_node_lookup (bgp->connected_table[AFI_IP], &p);
if (! rn)
rn = bgp_node_lookup(bgp->connected_table[AFI_IP], &p);
if (!rn)
return;
bc = rn->info;
bc->refcnt--;
if (bc->refcnt == 0)
{
XFREE (MTYPE_BGP_CONN, bc);
if (bc->refcnt == 0) {
XFREE(MTYPE_BGP_CONN, bc);
rn->info = NULL;
}
bgp_unlock_node (rn);
bgp_unlock_node (rn);
}
else if (addr->family == AF_INET6)
{
apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
bgp_unlock_node(rn);
bgp_unlock_node(rn);
} else if (addr->family == AF_INET6) {
apply_mask_ipv6((struct prefix_ipv6 *)&p);
if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
return;
if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
return;
rn = bgp_node_lookup (bgp->connected_table[AFI_IP6], (struct prefix *) &p);
if (! rn)
rn = bgp_node_lookup(bgp->connected_table[AFI_IP6],
(struct prefix *)&p);
if (!rn)
return;
bc = rn->info;
bc->refcnt--;
if (bc->refcnt == 0)
{
XFREE (MTYPE_BGP_CONN, bc);
if (bc->refcnt == 0) {
XFREE(MTYPE_BGP_CONN, bc);
rn->info = NULL;
}
bgp_unlock_node (rn);
bgp_unlock_node (rn);
bgp_unlock_node(rn);
bgp_unlock_node(rn);
}
}
int
bgp_nexthop_self (struct bgp *bgp, struct in_addr nh_addr)
int bgp_nexthop_self(struct bgp *bgp, struct in_addr nh_addr)
{
struct bgp_addr tmp, *addr;
tmp.addr = nh_addr;
addr = hash_lookup (bgp->address_hash, &tmp);
addr = hash_lookup(bgp->address_hash, &tmp);
if (addr)
return 1;
return 0;
}
int
bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer)
{
struct bgp_node *rn1;
struct bgp_node *rn2;
@ -354,7 +325,7 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = nexthop;
rn1 = bgp_node_match (peer->bgp->connected_table[AFI_IP], &p);
rn1 = bgp_node_match(peer->bgp->connected_table[AFI_IP], &p);
if (!rn1)
return 0;
@ -362,9 +333,8 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = peer->su.sin.sin_addr;
rn2 = bgp_node_match (peer->bgp->connected_table[AFI_IP], &p);
if (!rn2)
{
rn2 = bgp_node_match(peer->bgp->connected_table[AFI_IP], &p);
if (!rn2) {
bgp_unlock_node(rn1);
return 0;
}
@ -377,8 +347,7 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
return (ret);
}
static void
bgp_show_nexthops (struct vty *vty, struct bgp *bgp, int detail)
static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
@ -387,100 +356,133 @@ bgp_show_nexthops (struct vty *vty, struct bgp *bgp, int detail)
time_t tbuf;
afi_t afi;
vty_out (vty, "Current BGP nexthop cache:\n");
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
{
vty_out(vty, "Current BGP nexthop cache:\n");
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
if (!bgp->nexthop_cache_table[afi])
continue;
for (rn = bgp_table_top (bgp->nexthop_cache_table[afi]); rn; rn = bgp_route_next (rn))
{
if ((bnc = rn->info) != NULL)
{
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID))
{
vty_out (vty, " %s valid [IGP metric %d], #paths %d\n",
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf)),
for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn;
rn = bgp_route_next(rn)) {
if ((bnc = rn->info) != NULL) {
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) {
vty_out(vty,
" %s valid [IGP metric %d], #paths %d\n",
inet_ntop(rn->p.family,
&rn->p.u.prefix, buf,
sizeof(buf)),
bnc->metric, bnc->path_count);
if (detail)
for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next)
switch (nexthop->type)
{
for (nexthop = bnc->nexthop;
nexthop;
nexthop = nexthop->next)
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV6:
vty_out (vty, " gate %s\n",
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, sizeof(buf)));
vty_out(vty,
" gate %s\n",
inet_ntop(
AF_INET6,
&nexthop->gate
.ipv6,
buf,
sizeof(buf)));
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
vty_out (vty, " gate %s, if %s\n",
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
sizeof (buf)),
ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
vty_out(vty,
" gate %s, if %s\n",
inet_ntop(
AF_INET6,
&nexthop->gate
.ipv6,
buf,
sizeof(buf)),
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_IPV4:
vty_out (vty, " gate %s\n",
inet_ntop(AF_INET, &nexthop->gate.ipv4, buf, sizeof(buf)));
vty_out(vty,
" gate %s\n",
inet_ntop(
AF_INET,
&nexthop->gate
.ipv4,
buf,
sizeof(buf)));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out (vty, " if %s\n",
ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
vty_out(vty,
" if %s\n",
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out (vty, " gate %s, if %s\n",
inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
sizeof (buf)),
ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
vty_out(vty,
" gate %s, if %s\n",
inet_ntop(
AF_INET,
&nexthop->gate
.ipv4,
buf,
sizeof(buf)),
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
default:
vty_out (vty, " invalid nexthop type %u\n",
vty_out(vty,
" invalid nexthop type %u\n",
nexthop->type);
}
} else {
vty_out(vty, " %s invalid\n",
inet_ntop(rn->p.family,
&rn->p.u.prefix, buf,
sizeof(buf)));
if (CHECK_FLAG(bnc->flags,
BGP_NEXTHOP_CONNECTED))
vty_out(vty,
" Must be Connected\n");
}
else
{
vty_out (vty, " %s invalid\n",
inet_ntop(rn->p.family, &rn->p.u.prefix, buf, sizeof(buf)));
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
vty_out (vty, " Must be Connected\n");
}
tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
vty_out (vty, " Last update: %s", ctime(&tbuf));
vty_out (vty, "\n");
tbuf = time(NULL)
- (bgp_clock() - bnc->last_update);
vty_out(vty, " Last update: %s", ctime(&tbuf));
vty_out(vty, "\n");
}
}
}
}
static int
show_ip_bgp_nexthop_table (struct vty *vty, const char *name, int detail)
static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
int detail)
{
struct bgp *bgp;
if (name)
bgp = bgp_lookup_by_name (name);
bgp = bgp_lookup_by_name(name);
else
bgp = bgp_get_default ();
if (!bgp)
{
vty_out (vty, "%% No such BGP instance exist\n");
bgp = bgp_get_default();
if (!bgp) {
vty_out(vty, "%% No such BGP instance exist\n");
return CMD_WARNING;
}
bgp_show_nexthops (vty, bgp, detail);
bgp_show_nexthops(vty, bgp, detail);
return CMD_SUCCESS;
}
static void
bgp_show_all_instances_nexthops_vty (struct vty *vty)
static void bgp_show_all_instances_nexthops_vty(struct vty *vty)
{
struct listnode *node, *nnode;
struct bgp *bgp;
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
vty_out (vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? "Default" : bgp->name);
bgp_show_nexthops (vty, bgp, 0);
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
? "Default"
: bgp->name);
bgp_show_nexthops(vty, bgp, 0);
}
}
@ -495,9 +497,9 @@ DEFUN (show_ip_bgp_nexthop,
"Show detailed information\n")
{
int idx = 0;
char *vrf = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
int detail = argv_find (argv, argc, "detail", &idx) ? 1 : 0;
return show_ip_bgp_nexthop_table (vty, vrf, detail);
char *vrf = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
int detail = argv_find(argv, argc, "detail", &idx) ? 1 : 0;
return show_ip_bgp_nexthop_table(vty, vrf, detail);
}
DEFUN (show_ip_bgp_instance_all_nexthop,
@ -509,46 +511,43 @@ DEFUN (show_ip_bgp_instance_all_nexthop,
BGP_INSTANCE_ALL_HELP_STR
"BGP nexthop table\n")
{
bgp_show_all_instances_nexthops_vty (vty);
bgp_show_all_instances_nexthops_vty(vty);
return CMD_SUCCESS;
}
void
bgp_scan_init (struct bgp *bgp)
void bgp_scan_init(struct bgp *bgp)
{
afi_t afi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
{
bgp->nexthop_cache_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
bgp->connected_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
bgp->import_check_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
bgp->nexthop_cache_table[afi] =
bgp_table_init(afi, SAFI_UNICAST);
bgp->connected_table[afi] = bgp_table_init(afi, SAFI_UNICAST);
bgp->import_check_table[afi] =
bgp_table_init(afi, SAFI_UNICAST);
}
}
void
bgp_scan_vty_init (void)
void bgp_scan_vty_init(void)
{
install_element (VIEW_NODE, &show_ip_bgp_nexthop_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_all_nexthop_cmd);
install_element(VIEW_NODE, &show_ip_bgp_nexthop_cmd);
install_element(VIEW_NODE, &show_ip_bgp_instance_all_nexthop_cmd);
}
void
bgp_scan_finish (struct bgp *bgp)
void bgp_scan_finish(struct bgp *bgp)
{
afi_t afi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
{
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
/* Only the current one needs to be reset. */
bgp_nexthop_cache_reset (bgp->nexthop_cache_table[afi]);
bgp_table_unlock (bgp->nexthop_cache_table[afi]);
bgp_nexthop_cache_reset(bgp->nexthop_cache_table[afi]);
bgp_table_unlock(bgp->nexthop_cache_table[afi]);
bgp->nexthop_cache_table[afi] = NULL;
bgp_table_unlock (bgp->connected_table[afi]);
bgp_table_unlock(bgp->connected_table[afi]);
bgp->connected_table[afi] = NULL;
bgp_table_unlock (bgp->import_check_table[afi]);
bgp_table_unlock(bgp->import_check_table[afi]);
bgp->import_check_table[afi] = NULL;
}
}

View File

@ -25,20 +25,18 @@
#include "queue.h"
#include "prefix.h"
#define NEXTHOP_FAMILY(nexthop_len) ( \
((nexthop_len) == 4 || \
(nexthop_len) == 12 ? AF_INET : \
((nexthop_len) == 16 || \
(nexthop_len) == 24 || \
(nexthop_len) == 48 ? AF_INET6 : \
AF_UNSPEC)) \
)
#define NEXTHOP_FAMILY(nexthop_len) \
(((nexthop_len) == 4 || (nexthop_len) == 12 \
? AF_INET \
: ((nexthop_len) == 16 || (nexthop_len) == 24 \
|| (nexthop_len) == 48 \
? AF_INET6 \
: AF_UNSPEC)))
#define BGP_MP_NEXTHOP_FAMILY NEXTHOP_FAMILY
/* BGP nexthop cache value structure. */
struct bgp_nexthop_cache
{
struct bgp_nexthop_cache {
/* IGP route's metric. */
u_int32_t metric;
@ -68,13 +66,13 @@ struct bgp_nexthop_cache
struct bgp *bgp;
};
extern int bgp_nexthop_lookup (afi_t, struct peer *peer, struct bgp_info *,
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_delete (struct bgp *bgp, struct connected *c);
extern int bgp_multiaccess_check_v4 (struct in_addr, struct peer *);
extern int bgp_config_write_scan_time (struct vty *);
extern int bgp_nexthop_self (struct bgp *, struct in_addr);
extern void bgp_connected_add(struct bgp *bgp, struct connected *c);
extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
extern int bgp_multiaccess_check_v4(struct in_addr, struct peer *);
extern int bgp_config_write_scan_time(struct vty *);
extern int bgp_nexthop_self(struct bgp *, struct in_addr);
extern struct bgp_nexthop_cache *bnc_new(void);
extern void bnc_free(struct bgp_nexthop_cache *bnc);
extern void bnc_nexthop_free(struct bgp_nexthop_cache *bnc);
@ -82,7 +80,7 @@ extern char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size);
extern void bgp_scan_init(struct bgp *bgp);
extern void bgp_scan_finish(struct bgp *bgp);
extern void bgp_scan_vty_init(void);
extern void bgp_address_init (struct bgp *bgp);
extern void bgp_address_destroy (struct bgp *bgp);
extern void bgp_address_init(struct bgp *bgp);
extern void bgp_address_destroy(struct bgp *bgp);
#endif /* _QUAGGA_BGP_NEXTHOP_H */

View File

@ -53,15 +53,13 @@ static int make_prefix(int afi, struct bgp_info *ri, 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)
{
return (bgp_zebra_num_connects() == 0 ||
(bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)));
return (bgp_zebra_num_connects() == 0
|| (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)));
}
int
bgp_find_nexthop (struct bgp_info *path, int connected)
int bgp_find_nexthop(struct bgp_info *path, int connected)
{
struct bgp_nexthop_cache *bnc = path->nexthop;
@ -82,18 +80,16 @@ bgp_find_nexthop (struct bgp_info *path, int connected)
return (bgp_isvalid_nexthop(bnc));
}
static void
bgp_unlink_nexthop_check (struct bgp_nexthop_cache *bnc)
static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
{
if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info)
{
if (BGP_DEBUG(nht, NHT))
{
if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info) {
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
zlog_debug("bgp_unlink_nexthop: freeing bnc %s",
bnc_str(bnc, buf, PREFIX2STR_BUFFER));
}
unregister_zebra_rnh(bnc, CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
unregister_zebra_rnh(bnc,
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
bnc->node->info = NULL;
bgp_unlock_node(bnc->node);
bnc->node = NULL;
@ -101,8 +97,7 @@ bgp_unlink_nexthop_check (struct bgp_nexthop_cache *bnc)
}
}
void
bgp_unlink_nexthop (struct bgp_info *path)
void bgp_unlink_nexthop(struct bgp_info *path)
{
struct bgp_nexthop_cache *bnc = path->nexthop;
@ -111,21 +106,20 @@ bgp_unlink_nexthop (struct bgp_info *path)
path_nh_map(path, NULL, 0);
bgp_unlink_nexthop_check (bnc);
bgp_unlink_nexthop_check(bnc);
}
void
bgp_unlink_nexthop_by_peer (struct peer *peer)
void bgp_unlink_nexthop_by_peer(struct peer *peer)
{
struct prefix p;
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
afi_t afi = family2afi(peer->su.sa.sa_family);
if (! sockunion2hostprefix (&peer->su, &p))
if (!sockunion2hostprefix(&peer->su, &p))
return;
rn = bgp_node_get (peer->bgp->nexthop_cache_table[afi], &p);
rn = bgp_node_get(peer->bgp->nexthop_cache_table[afi], &p);
if (!rn->info)
return;
@ -135,11 +129,10 @@ bgp_unlink_nexthop_by_peer (struct peer *peer)
/* cleanup the peer reference */
bnc->nht_info = NULL;
bgp_unlink_nexthop_check (bnc);
bgp_unlink_nexthop_check(bnc);
}
int
bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
int bgp_find_or_add_nexthop(struct bgp *bgp, afi_t afi, struct bgp_info *ri,
struct peer *peer, int connected)
{
struct bgp_node *rn;
@ -147,53 +140,52 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
struct prefix p;
int is_bgp_static_route = 0;
if (ri)
{
is_bgp_static_route = ((ri->type == ZEBRA_ROUTE_BGP) &&
(ri->sub_type == BGP_ROUTE_STATIC)) ? 1 : 0;
if (ri) {
is_bgp_static_route = ((ri->type == ZEBRA_ROUTE_BGP)
&& (ri->sub_type == BGP_ROUTE_STATIC))
? 1
: 0;
/* Since Extended Next-hop Encoding (RFC5549) support, we want to derive
/* Since Extended Next-hop Encoding (RFC5549) support, we want
to derive
address-family from the next-hop. */
if (!is_bgp_static_route)
afi = BGP_ATTR_NEXTHOP_AFI_IP6(ri->attr) ? AFI_IP6 : AFI_IP;
afi = BGP_ATTR_NEXTHOP_AFI_IP6(ri->attr) ? AFI_IP6
: AFI_IP;
/* This will return TRUE if the global IPv6 NH is a link local addr */
/* This will return TRUE if the global IPv6 NH is a link local
* addr */
if (make_prefix(afi, ri, &p) < 0)
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))
if (afi == AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr))
return 1;
if (! sockunion2hostprefix (&peer->su, &p))
{
if (BGP_DEBUG(nht, NHT))
{
zlog_debug("%s: Attempting to register with unknown AFI %d (not %d or %d)",
if (!sockunion2hostprefix(&peer->su, &p)) {
if (BGP_DEBUG(nht, NHT)) {
zlog_debug(
"%s: Attempting to register with unknown AFI %d (not %d or %d)",
__FUNCTION__, afi, AFI_IP, AFI_IP6);
}
return 0;
}
}
else
} else
return 0;
if (is_bgp_static_route)
rn = bgp_node_get (bgp->import_check_table[afi], &p);
rn = bgp_node_get(bgp->import_check_table[afi], &p);
else
rn = bgp_node_get (bgp->nexthop_cache_table[afi], &p);
rn = bgp_node_get(bgp->nexthop_cache_table[afi], &p);
if (!rn->info)
{
if (!rn->info) {
bnc = bnc_new();
rn->info = bnc;
bnc->node = rn;
bnc->bgp = bgp;
bgp_lock_node(rn);
if (BGP_DEBUG(nht, NHT))
{
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
zlog_debug("Allocated bnc %s peer %p",
@ -202,62 +194,58 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
}
bnc = rn->info;
bgp_unlock_node (rn);
if (is_bgp_static_route)
{
bgp_unlock_node(rn);
if (is_bgp_static_route) {
SET_FLAG(bnc->flags, BGP_STATIC_ROUTE);
/* If we're toggling the type, re-register */
if ((bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) &&
!CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
{
if ((bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK))
&& !CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)) {
SET_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
}
else if ((!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) &&
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
{
} else if ((!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK))
&& CHECK_FLAG(bnc->flags,
BGP_STATIC_ROUTE_EXACT_MATCH)) {
UNSET_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
}
}
/* When nexthop is already known, but now requires 'connected' resolution,
* re-register it. The reverse scenario where the nexthop currently requires
/* When nexthop is already known, but now requires 'connected'
* resolution,
* re-register it. The reverse scenario where the nexthop currently
* requires
* 'connected' resolution does not need a re-register (i.e., we treat
* 'connected-required' as an override) except in the scenario where this
* 'connected-required' as an override) except in the scenario where
* this
* is actually a case of tracking a peer for connectivity (e.g., after
* disable connected-check).
* NOTE: We don't track the number of paths separately for 'connected-
* required' vs 'connected-not-required' as this change is not a common
* scenario.
*/
else if (connected && ! CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
{
else if (connected && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) {
SET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
}
else if (peer && !connected && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
{
} else if (peer && !connected
&& CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) {
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
}
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
{
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) {
bnc->flags |= BGP_NEXTHOP_REGISTERED;
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);
if (ri && ri->nexthop != bnc)
{
/* Unlink from existing nexthop cache, if any. This will also free
if (ri && ri->nexthop != bnc) {
/* Unlink from existing nexthop cache, if any. This will also
* free
* the nexthop cache entry, if appropriate.
*/
bgp_unlink_nexthop (ri);
bgp_unlink_nexthop(ri);
path_nh_map(ri, bnc, 1); /* updates NHT ri list reference */
@ -265,8 +253,7 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
(bgp_info_extra_get(ri))->igpmetric = bnc->metric;
else if (ri->extra)
ri->extra->igpmetric = 0;
}
else if (peer)
} else if (peer)
bnc->nht_info = (void *)peer; /* NHT peer reference */
/*
@ -280,8 +267,7 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
return (bgp_isvalid_nexthop(bnc));
}
void
bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
@ -291,37 +277,37 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
return;
/* We don't register link local address for NHT */
if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr))
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;
rn = bgp_node_lookup(peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
if (!rn || !rn->info)
{
rn = bgp_node_lookup(
peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
if (!rn || !rn->info) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("Cannot find connected NHT node for peer %s", peer->host);
zlog_debug("Cannot find connected NHT node for peer %s",
peer->host);
if (rn)
bgp_unlock_node (rn);
bgp_unlock_node(rn);
return;
}
bnc = rn->info;
bgp_unlock_node(rn);
if (bnc->nht_info != peer)
{
if (bnc->nht_info != peer) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("Connected NHT %p node for peer %s points to %p",
zlog_debug(
"Connected NHT %p node for peer %s points to %p",
bnc, peer->host, bnc->nht_info);
return;
}
bnc->nht_info = NULL;
if (LIST_EMPTY(&(bnc->paths)))
{
if (LIST_EMPTY(&(bnc->paths))) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("Freeing connected NHT node %p for peer %s",
bnc, peer->host);
@ -332,8 +318,7 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
}
}
void
bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
{
struct stream *s;
struct bgp_node *rn = NULL;
@ -348,10 +333,11 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
int i;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
{
zlog_err("parse nexthop update: instance not found for vrf_id %d", vrf_id);
bgp = bgp_lookup_by_vrf_id(vrf_id);
if (!bgp) {
zlog_err(
"parse nexthop update: instance not found for vrf_id %d",
vrf_id);
return;
}
@ -360,10 +346,9 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
memset(&p, 0, sizeof(struct prefix));
p.family = stream_getw(s);
p.prefixlen = stream_getc(s);
switch (p.family)
{
switch (p.family) {
case AF_INET:
p.u.prefix4.s_addr = stream_get_ipv4 (s);
p.u.prefix4.s_addr = stream_get_ipv4(s);
break;
case AF_INET6:
stream_get(&p.u.prefix6, s, 16);
@ -373,49 +358,49 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
}
if (command == ZEBRA_NEXTHOP_UPDATE)
rn = bgp_node_lookup(bgp->nexthop_cache_table[family2afi(p.family)], &p);
rn = bgp_node_lookup(
bgp->nexthop_cache_table[family2afi(p.family)], &p);
else if (command == ZEBRA_IMPORT_CHECK_UPDATE)
rn = bgp_node_lookup(bgp->import_check_table[family2afi(p.family)], &p);
rn = bgp_node_lookup(
bgp->import_check_table[family2afi(p.family)], &p);
if (!rn || !rn->info)
{
if (BGP_DEBUG(nht, NHT))
{
if (!rn || !rn->info) {
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&p, buf, sizeof(buf));
zlog_debug("parse nexthop update(%s): rn not found", buf);
zlog_debug("parse nexthop update(%s): rn not found",
buf);
}
if (rn)
bgp_unlock_node (rn);
bgp_unlock_node(rn);
return;
}
bnc = rn->info;
bgp_unlock_node (rn);
bgp_unlock_node(rn);
bnc->last_update = bgp_clock();
bnc->change_flags = 0;
stream_getc (s); // Distance but not currently used
metric = stream_getl (s);
nexthop_num = stream_getc (s);
stream_getc(s); // Distance but not currently used
metric = stream_getl(s);
nexthop_num = stream_getc(s);
/* debug print the input */
if (BGP_DEBUG(nht, NHT))
{
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&p, buf, sizeof (buf));
zlog_debug("%d: Rcvd NH update %s - metric %d/%d #nhops %d/%d flags 0x%x",
vrf_id, buf, metric, bnc->metric, nexthop_num, bnc->nexthop_num,
bnc->flags);
prefix2str(&p, buf, sizeof(buf));
zlog_debug(
"%d: Rcvd NH update %s - metric %d/%d #nhops %d/%d flags 0x%x",
vrf_id, buf, metric, bnc->metric, nexthop_num,
bnc->nexthop_num, bnc->flags);
}
if (metric != bnc->metric)
bnc->change_flags |= BGP_NEXTHOP_METRIC_CHANGED;
if(nexthop_num != bnc->nexthop_num)
if (nexthop_num != bnc->nexthop_num)
bnc->change_flags |= BGP_NEXTHOP_CHANGED;
if (nexthop_num)
{
if (nexthop_num) {
/* notify bgp fsm if nbr ip goes from invalid->valid */
if (!bnc->nexthop_num)
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
@ -424,55 +409,51 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
bnc->metric = metric;
bnc->nexthop_num = nexthop_num;
for (i = 0; i < nexthop_num; i++)
{
for (i = 0; i < nexthop_num; i++) {
nexthop = nexthop_new();
nexthop->type = stream_getc (s);
switch (nexthop->type)
{
nexthop->type = stream_getc(s);
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
nexthop->ifindex = stream_getl (s);
nexthop->gate.ipv4.s_addr = stream_get_ipv4(s);
nexthop->ifindex = stream_getl(s);
break;
case NEXTHOP_TYPE_IFINDEX:
nexthop->ifindex = stream_getl (s);
nexthop->ifindex = stream_getl(s);
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
nexthop->ifindex = stream_getl (s);
nexthop->gate.ipv4.s_addr = stream_get_ipv4(s);
nexthop->ifindex = stream_getl(s);
break;
case NEXTHOP_TYPE_IPV6:
stream_get (&nexthop->gate.ipv6, s, 16);
nexthop->ifindex = stream_getl (s);
stream_get(&nexthop->gate.ipv6, s, 16);
nexthop->ifindex = stream_getl(s);
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
stream_get (&nexthop->gate.ipv6, s, 16);
nexthop->ifindex = stream_getl (s);
stream_get(&nexthop->gate.ipv6, s, 16);
nexthop->ifindex = stream_getl(s);
break;
default:
/* do nothing */
break;
}
if (BGP_DEBUG(nht, NHT))
{
if (BGP_DEBUG(nht, NHT)) {
char buf[NEXTHOP_STRLEN];
zlog_debug(" nhop via %s",
nexthop2str (nexthop, buf, sizeof (buf)));
zlog_debug(
" nhop via %s",
nexthop2str(nexthop, buf, sizeof(buf)));
}
if (nhlist_tail)
{
if (nhlist_tail) {
nhlist_tail->next = nexthop;
nhlist_tail = nexthop;
}
else
{
} else {
nhlist_tail = nexthop;
nhlist_head = nexthop;
}
/* No need to evaluate the nexthop if we have already determined
/* No need to evaluate the nexthop if we have already
* determined
* that there has been a change.
*/
if (bnc->change_flags & BGP_NEXTHOP_CHANGED)
@ -487,9 +468,7 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
}
bnc_nexthop_free(bnc);
bnc->nexthop = nhlist_head;
}
else
{
} else {
bnc->flags &= ~BGP_NEXTHOP_VALID;
bnc->nexthop_num = nexthop_num;
@ -507,25 +486,22 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
* make_prefix - make a prefix structure from the path (essentially
* path's node.
*/
static int
make_prefix (int afi, struct bgp_info *ri, struct prefix *p)
static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
{
int is_bgp_static = ((ri->type == ZEBRA_ROUTE_BGP) &&
(ri->sub_type == BGP_ROUTE_STATIC)) ? 1 : 0;
int is_bgp_static = ((ri->type == ZEBRA_ROUTE_BGP)
&& (ri->sub_type == BGP_ROUTE_STATIC))
? 1
: 0;
memset (p, 0, sizeof (struct prefix));
switch (afi)
{
memset(p, 0, sizeof(struct prefix));
switch (afi) {
case AFI_IP:
p->family = AF_INET;
if (is_bgp_static)
{
if (is_bgp_static) {
p->u.prefix4 = ri->net->p.u.prefix4;
p->prefixlen = ri->net->p.prefixlen;
}
else
{
} else {
p->u.prefix4 = ri->attr->nexthop;
p->prefixlen = IPV4_MAX_BITLEN;
}
@ -533,26 +509,23 @@ make_prefix (int afi, struct bgp_info *ri, struct prefix *p)
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))
|| IN6_IS_ADDR_LINKLOCAL(&ri->attr->mp_nexthop_global))
return -1;
p->family = AF_INET6;
if (is_bgp_static)
{
if (is_bgp_static) {
p->u.prefix6 = ri->net->p.u.prefix6;
p->prefixlen = ri->net->p.prefixlen;
}
else
{
} else {
p->u.prefix6 = ri->attr->mp_nexthop_global;
p->prefixlen = IPV6_MAX_BITLEN;
}
break;
default:
if (BGP_DEBUG(nht, NHT))
{
zlog_debug("%s: Attempting to make prefix with unknown AFI %d (not %d or %d)",
if (BGP_DEBUG(nht, NHT)) {
zlog_debug(
"%s: Attempting to make prefix with unknown AFI %d (not %d or %d)",
__FUNCTION__, afi, AFI_IP, AFI_IP6);
}
break;
@ -569,8 +542,7 @@ make_prefix (int afi, struct bgp_info *ri, struct prefix *p)
* RETURNS:
* void.
*/
static void
sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
{
struct stream *s;
struct prefix *p;
@ -586,20 +558,19 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
p = &(bnc->node->p);
s = zclient->obuf;
stream_reset (s);
zclient_create_header (s, command, bnc->bgp->vrf_id);
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED) ||
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
stream_reset(s);
zclient_create_header(s, command, bnc->bgp->vrf_id);
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)
|| CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
stream_putc(s, 1);
else
stream_putc(s, 0);
stream_putw(s, PREFIX_FAMILY(p));
stream_putc(s, p->prefixlen);
switch (PREFIX_FAMILY(p))
{
switch (PREFIX_FAMILY(p)) {
case AF_INET:
stream_put_in_addr (s, &p->u.prefix4);
stream_put_in_addr(s, &p->u.prefix4);
break;
case AF_INET6:
stream_put(s, &(p->u.prefix6), 16);
@ -607,18 +578,18 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
default:
break;
}
stream_putw_at (s, 0, stream_get_endp (s));
stream_putw_at(s, 0, stream_get_endp(s));
ret = zclient_send_message(zclient);
/* TBD: handle the failure */
if (ret < 0)
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
if ((command == ZEBRA_NEXTHOP_REGISTER) ||
(command == ZEBRA_IMPORT_ROUTE_REGISTER))
if ((command == ZEBRA_NEXTHOP_REGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_REGISTER))
SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
else if ((command == ZEBRA_NEXTHOP_UNREGISTER) ||
(command == ZEBRA_IMPORT_ROUTE_UNREGISTER))
else if ((command == ZEBRA_NEXTHOP_UNREGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_UNREGISTER))
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
return;
}
@ -631,8 +602,8 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
* RETURNS:
* void.
*/
static void
register_zebra_rnh (struct bgp_nexthop_cache *bnc, int is_bgp_import_route)
static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
int is_bgp_import_route)
{
/* Check if we have already registered */
if (bnc->flags & BGP_NEXTHOP_REGISTERED)
@ -650,8 +621,8 @@ register_zebra_rnh (struct bgp_nexthop_cache *bnc, int is_bgp_import_route)
* RETURNS:
* void.
*/
static void
unregister_zebra_rnh (struct bgp_nexthop_cache *bnc, int is_bgp_import_route)
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
int is_bgp_import_route)
{
/* Check if we have already registered */
if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
@ -670,8 +641,7 @@ unregister_zebra_rnh (struct bgp_nexthop_cache *bnc, int is_bgp_import_route)
* RETURNS:
* void.
*/
static void
evaluate_paths (struct bgp_nexthop_cache *bnc)
static void evaluate_paths(struct bgp_nexthop_cache *bnc)
{
struct bgp_node *rn;
struct bgp_info *path;
@ -681,62 +651,61 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
struct bgp_table *table;
safi_t safi;
if (BGP_DEBUG(nht, NHT))
{
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
bnc_str(bnc, buf, PREFIX2STR_BUFFER);
zlog_debug("NH update for %s - flags 0x%x chgflags 0x%x - evaluate paths",
zlog_debug(
"NH update for %s - flags 0x%x chgflags 0x%x - evaluate paths",
buf, bnc->flags, bnc->change_flags);
}
LIST_FOREACH(path, &(bnc->paths), nh_thread)
{
if (!(path->type == ZEBRA_ROUTE_BGP &&
((path->sub_type == BGP_ROUTE_NORMAL) ||
(path->sub_type == BGP_ROUTE_STATIC))))
if (!(path->type == ZEBRA_ROUTE_BGP
&& ((path->sub_type == BGP_ROUTE_NORMAL)
|| (path->sub_type == BGP_ROUTE_STATIC))))
continue;
rn = path->net;
assert (rn && bgp_node_table (rn));
assert(rn && bgp_node_table(rn));
afi = family2afi(rn->p.family);
table = bgp_node_table (rn);
table = bgp_node_table(rn);
safi = table->safi;
/* Path becomes valid/invalid depending on whether the nexthop
* reachable/unreachable.
*/
if ((CHECK_FLAG(path->flags, BGP_INFO_VALID) ? 1 : 0) !=
(bgp_isvalid_nexthop(bnc) ? 1 : 0))
{
if (CHECK_FLAG (path->flags, BGP_INFO_VALID))
{
bgp_aggregate_decrement (bgp, &rn->p, path, afi, safi);
bgp_info_unset_flag (rn, path, BGP_INFO_VALID);
}
else
{
bgp_info_set_flag (rn, path, BGP_INFO_VALID);
bgp_aggregate_increment (bgp, &rn->p, path, afi, safi);
if ((CHECK_FLAG(path->flags, BGP_INFO_VALID) ? 1 : 0)
!= (bgp_isvalid_nexthop(bnc) ? 1 : 0)) {
if (CHECK_FLAG(path->flags, BGP_INFO_VALID)) {
bgp_aggregate_decrement(bgp, &rn->p, path, afi,
safi);
bgp_info_unset_flag(rn, path, BGP_INFO_VALID);
} else {
bgp_info_set_flag(rn, path, BGP_INFO_VALID);
bgp_aggregate_increment(bgp, &rn->p, path, afi,
safi);
}
}
/* Copy the metric to the path. Will be used for bestpath computation */
/* Copy the metric to the path. Will be used for bestpath
* computation */
if (bgp_isvalid_nexthop(bnc) && bnc->metric)
(bgp_info_extra_get(path))->igpmetric = bnc->metric;
else if (path->extra)
path->extra->igpmetric = 0;
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED) ||
CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED)
|| CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
SET_FLAG(path->flags, BGP_INFO_IGP_CHANGED);
bgp_process(bgp, rn, afi, safi);
}
if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED))
{
if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED)) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("%s: Updating peer (%s) status with NHT", __FUNCTION__, peer->host);
zlog_debug("%s: Updating peer (%s) status with NHT",
__FUNCTION__, peer->host);
bgp_fsm_nht_update(peer, bgp_isvalid_nexthop(bnc));
SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
}
@ -752,17 +721,15 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
* make - if set, make the association. if unset, just break the existing
* association.
*/
static void
path_nh_map (struct bgp_info *path, struct bgp_nexthop_cache *bnc, int make)
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
int make)
{
if (path->nexthop)
{
if (path->nexthop) {
LIST_REMOVE(path, nh_thread);
path->nexthop->path_count--;
path->nexthop = NULL;
}
if (make)
{
if (make) {
LIST_INSERT_HEAD(&(bnc->paths), path, nh_thread);
path->nexthop = bnc;
path->nexthop->path_count++;

View File

@ -45,8 +45,8 @@ extern int bgp_find_nexthop(struct bgp_info *p, int connected);
* peer - The BGP peer associated with this NHT
* connected - True if NH MUST be a connected route
*/
extern int bgp_find_or_add_nexthop(struct bgp *bgp, afi_t a,
struct bgp_info *p, struct peer *peer, int connected);
extern int bgp_find_or_add_nexthop(struct bgp *bgp, afi_t a, struct bgp_info *p,
struct peer *peer, int connected);
/**
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
@ -54,7 +54,7 @@ extern int bgp_find_or_add_nexthop(struct bgp *bgp, afi_t a,
* p - path structure.
*/
extern void bgp_unlink_nexthop(struct bgp_info *p);
void bgp_unlink_nexthop_by_peer (struct peer *);
void bgp_unlink_nexthop_by_peer(struct peer *);
/**
* bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
@ -64,6 +64,6 @@ void bgp_unlink_nexthop_by_peer (struct peer *);
* afi - afi: AFI_IP or AF_IP6
* peer - Ptr to peer
*/
extern void bgp_delete_connected_nexthop (afi_t afi, struct peer *peer);
extern void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer);
#endif /* _BGP_NHT_H */

File diff suppressed because it is too large Load Diff

View File

@ -22,34 +22,29 @@
#define _QUAGGA_BGP_OPEN_H
/* Standard header for capability TLV */
struct capability_header
{
struct capability_header {
u_char code;
u_char length;
};
/* Generic MP capability data */
struct capability_mp_data
{
struct capability_mp_data {
iana_afi_t afi;
u_char reserved;
safi_t safi;
};
struct capability_as4
{
struct capability_as4 {
uint32_t as4;
};
struct graceful_restart_af
{
struct graceful_restart_af {
afi_t afi;
safi_t safi;
u_char flag;
};
struct capability_gr
{
struct capability_gr {
u_int16_t restart_flag_time;
struct graceful_restart_af gr[];
};
@ -68,7 +63,6 @@ struct capability_gr
#define CAPABILITY_CODE_REFRESH_OLD 128 /* Route Refresh Capability(cisco) */
#define CAPABILITY_CODE_ORF_OLD 130 /* Cooperative Route Filtering Capability(cisco) */
/* Capability Length */
#define CAPABILITY_CODE_MP_LEN 4
#define CAPABILITY_CODE_REFRESH_LEN 0
@ -99,9 +93,10 @@ struct capability_gr
#define RESTART_R_BIT 0x8000
#define RESTART_F_BIT 0x80
extern int bgp_open_option_parse (struct peer *, u_char, int *);
extern void bgp_open_capability (struct stream *, struct peer *);
extern void bgp_capability_vty_out (struct vty *, struct peer *, u_char, json_object *);
extern as_t peek_for_as4_capability (struct peer *, u_char);
extern int bgp_open_option_parse(struct peer *, u_char, int *);
extern void bgp_open_capability(struct stream *, struct peer *);
extern void bgp_capability_vty_out(struct vty *, struct peer *, u_char,
json_object *);
extern as_t peek_for_as4_capability(struct peer *, u_char);
#endif /* _QUAGGA_BGP_OPEN_H */

File diff suppressed because it is too large Load Diff

View File

@ -38,31 +38,33 @@
#define ORF_COMMON_PART_DENY 0x20
/* Packet send and receive function prototypes. */
extern int bgp_read (struct thread *);
extern int bgp_write (struct thread *);
extern int bgp_connect_check (struct peer *, int change_state);
extern int bgp_read(struct thread *);
extern int bgp_write(struct thread *);
extern int bgp_connect_check(struct peer *, int change_state);
extern void bgp_keepalive_send (struct peer *);
extern void bgp_open_send (struct peer *);
extern void bgp_notify_send (struct peer *, u_int8_t, u_int8_t);
extern void bgp_notify_send_with_data (struct peer *, u_int8_t, u_int8_t,
extern void bgp_keepalive_send(struct peer *);
extern void bgp_open_send(struct peer *);
extern void bgp_notify_send(struct peer *, u_int8_t, u_int8_t);
extern void bgp_notify_send_with_data(struct peer *, u_int8_t, u_int8_t,
u_int8_t *, size_t);
extern void bgp_route_refresh_send (struct peer *, afi_t, safi_t, u_char, u_char, int);
extern void bgp_capability_send (struct peer *, afi_t, safi_t, int, int);
extern void bgp_default_update_send (struct peer *, struct attr *,
afi_t, safi_t, struct peer *);
extern void bgp_default_withdraw_send (struct peer *, afi_t, safi_t);
extern void bgp_route_refresh_send(struct peer *, afi_t, safi_t, u_char, u_char,
int);
extern void bgp_capability_send(struct peer *, afi_t, safi_t, int, int);
extern void bgp_default_update_send(struct peer *, struct attr *, afi_t, safi_t,
struct peer *);
extern void bgp_default_withdraw_send(struct peer *, afi_t, safi_t);
extern int bgp_capability_receive (struct peer *, bgp_size_t);
extern int bgp_capability_receive(struct peer *, bgp_size_t);
extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *, int mp_withdraw);
extern int bgp_nlri_parse(struct peer *, struct attr *, struct bgp_nlri *,
int mp_withdraw);
extern void bgp_update_restarted_peers (struct peer *);
extern void bgp_update_implicit_eors (struct peer *);
extern void bgp_check_update_delay (struct bgp *);
extern void bgp_update_restarted_peers(struct peer *);
extern void bgp_update_implicit_eors(struct peer *);
extern void bgp_check_update_delay(struct bgp *);
extern int bgp_packet_set_marker (struct stream *s, u_char type);
extern int bgp_packet_set_size (struct stream *s);
extern void bgp_packet_add (struct peer *peer, struct stream *s);
extern int bgp_packet_set_marker(struct stream *s, u_char type);
extern int bgp_packet_set_size(struct stream *s);
extern void bgp_packet_add(struct peer *peer, struct stream *s);
#endif /* _QUAGGA_BGP_PACKET_H */

View File

@ -36,80 +36,73 @@
#include "bgpd/rfapi/rfapi_backend.h"
#endif
u_int16_t
decode_rd_type (u_char *pnt)
u_int16_t decode_rd_type(u_char *pnt)
{
u_int16_t v;
v = ((u_int16_t) *pnt++ << 8);
v = ((u_int16_t)*pnt++ << 8);
#if ENABLE_BGP_VNC
/*
* VNC L2 stores LHI in lower byte, so omit it
*/
if (v != RD_TYPE_VNC_ETH)
v |= (u_int16_t) *pnt;
v |= (u_int16_t)*pnt;
#else /* duplicate code for clarity */
v |= (u_int16_t) *pnt;
v |= (u_int16_t)*pnt;
#endif
return v;
}
void
encode_rd_type (u_int16_t v, u_char *pnt)
void encode_rd_type(u_int16_t v, u_char *pnt)
{
*((u_int16_t *)pnt) = htons(v);
}
/* type == RD_TYPE_AS */
void
decode_rd_as (u_char *pnt, struct rd_as *rd_as)
void decode_rd_as(u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int16_t) *pnt++ << 8;
rd_as->as |= (u_int16_t) *pnt++;
rd_as->as = (u_int16_t)*pnt++ << 8;
rd_as->as |= (u_int16_t)*pnt++;
rd_as->val = ((u_int32_t) *pnt++ << 24);
rd_as->val |= ((u_int32_t) *pnt++ << 16);
rd_as->val |= ((u_int32_t) *pnt++ << 8);
rd_as->val |= (u_int32_t) *pnt;
rd_as->val = ((u_int32_t)*pnt++ << 24);
rd_as->val |= ((u_int32_t)*pnt++ << 16);
rd_as->val |= ((u_int32_t)*pnt++ << 8);
rd_as->val |= (u_int32_t)*pnt;
}
/* type == RD_TYPE_AS4 */
void
decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
void decode_rd_as4(u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int32_t) *pnt++ << 24;
rd_as->as |= (u_int32_t) *pnt++ << 16;
rd_as->as |= (u_int32_t) *pnt++ << 8;
rd_as->as |= (u_int32_t) *pnt++;
rd_as->as = (u_int32_t)*pnt++ << 24;
rd_as->as |= (u_int32_t)*pnt++ << 16;
rd_as->as |= (u_int32_t)*pnt++ << 8;
rd_as->as |= (u_int32_t)*pnt++;
rd_as->val = ((u_int16_t) *pnt++ << 8);
rd_as->val |= (u_int16_t) *pnt;
rd_as->val = ((u_int16_t)*pnt++ << 8);
rd_as->val |= (u_int16_t)*pnt;
}
/* type == RD_TYPE_IP */
void
decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
void decode_rd_ip(u_char *pnt, struct rd_ip *rd_ip)
{
memcpy (&rd_ip->ip, pnt, 4);
memcpy(&rd_ip->ip, pnt, 4);
pnt += 4;
rd_ip->val = ((u_int16_t) *pnt++ << 8);
rd_ip->val |= (u_int16_t) *pnt;
rd_ip->val = ((u_int16_t)*pnt++ << 8);
rd_ip->val |= (u_int16_t)*pnt;
}
#if ENABLE_BGP_VNC
/* type == RD_TYPE_VNC_ETH */
void
decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
void decode_rd_vnc_eth(u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
{
rd_vnc_eth->type = RD_TYPE_VNC_ETH;
rd_vnc_eth->local_nve_id = pnt[1];
memcpy (rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
memcpy(rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
}
#endif
int
str2prefix_rd (const char *str, struct prefix_rd *prd)
int str2prefix_rd(const char *str, struct prefix_rd *prd)
{
int ret; /* ret of called functions */
int lret; /* local ret, of this func */
@ -119,69 +112,62 @@ str2prefix_rd (const char *str, struct prefix_rd *prd)
char *half = NULL;
struct in_addr addr;
s = stream_new (8);
s = stream_new(8);
prd->family = AF_UNSPEC;
prd->prefixlen = 64;
lret = 0;
p = strchr (str, ':');
if (! p)
p = strchr(str, ':');
if (!p)
goto out;
if (! all_digit (p + 1))
if (!all_digit(p + 1))
goto out;
half = XMALLOC (MTYPE_TMP, (p - str) + 1);
memcpy (half, str, (p - str));
half = XMALLOC(MTYPE_TMP, (p - str) + 1);
memcpy(half, str, (p - str));
half[p - str] = '\0';
p2 = strchr (str, '.');
p2 = strchr(str, '.');
if (! p2)
{
if (!p2) {
unsigned long as_val;
if (! all_digit (half))
if (!all_digit(half))
goto out;
as_val = atol(half);
if (as_val > 0xffff)
{
stream_putw (s, RD_TYPE_AS4);
stream_putl (s, as_val);
stream_putw (s, atol (p + 1));
if (as_val > 0xffff) {
stream_putw(s, RD_TYPE_AS4);
stream_putl(s, as_val);
stream_putw(s, atol(p + 1));
} else {
stream_putw(s, RD_TYPE_AS);
stream_putw(s, as_val);
stream_putl(s, atol(p + 1));
}
else
{
stream_putw (s, RD_TYPE_AS);
stream_putw (s, as_val);
stream_putl (s, atol (p + 1));
}
}
else
{
ret = inet_aton (half, &addr);
if (! ret)
} else {
ret = inet_aton(half, &addr);
if (!ret)
goto out;
stream_putw (s, RD_TYPE_IP);
stream_put_in_addr (s, &addr);
stream_putw (s, atol (p + 1));
stream_putw(s, RD_TYPE_IP);
stream_put_in_addr(s, &addr);
stream_putw(s, atol(p + 1));
}
memcpy (prd->val, s->data, 8);
memcpy(prd->val, s->data, 8);
lret = 1;
out:
if (s)
stream_free (s);
stream_free(s);
if (half)
XFREE(MTYPE_TMP, half);
return lret;
}
char *
prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
char *prefix_rd2str(struct prefix_rd *prd, char *buf, size_t size)
{
u_char *pnt;
u_int16_t type;
@ -193,37 +179,28 @@ prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
pnt = prd->val;
type = decode_rd_type (pnt);
type = decode_rd_type(pnt);
if (type == RD_TYPE_AS)
{
decode_rd_as (pnt + 2, &rd_as);
snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
if (type == RD_TYPE_AS) {
decode_rd_as(pnt + 2, &rd_as);
snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
return buf;
}
else if (type == RD_TYPE_AS4)
{
decode_rd_as4 (pnt + 2, &rd_as);
snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
} else if (type == RD_TYPE_AS4) {
decode_rd_as4(pnt + 2, &rd_as);
snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
return buf;
}
else if (type == RD_TYPE_IP)
{
decode_rd_ip (pnt + 2, &rd_ip);
snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
} else if (type == RD_TYPE_IP) {
decode_rd_ip(pnt + 2, &rd_ip);
snprintf(buf, size, "%s:%d", inet_ntoa(rd_ip.ip), rd_ip.val);
return buf;
}
#if ENABLE_BGP_VNC
else if (type == RD_TYPE_VNC_ETH)
{
else if (type == RD_TYPE_VNC_ETH) {
snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
*(pnt+1), /* LHI */
*(pnt+2), /* MAC[0] */
*(pnt+3),
*(pnt+4),
*(pnt+5),
*(pnt+6),
*(pnt+7));
*(pnt + 1), /* LHI */
*(pnt + 2), /* MAC[0] */
*(pnt + 3), *(pnt + 4), *(pnt + 5), *(pnt + 6),
*(pnt + 7));
return buf;
}

View File

@ -34,41 +34,37 @@
#define RD_ADDRSTRLEN 28
struct rd_as
{
struct rd_as {
u_int16_t type;
as_t as;
u_int32_t val;
};
struct rd_ip
{
struct rd_ip {
u_int16_t type;
struct in_addr ip;
u_int16_t val;
};
#if ENABLE_BGP_VNC
struct rd_vnc_eth
{
struct rd_vnc_eth {
u_int16_t type;
uint8_t local_nve_id;
struct ethaddr macaddr;
};
#endif
extern u_int16_t decode_rd_type (u_char *pnt);
extern void encode_rd_type (u_int16_t, u_char *);
extern u_int16_t decode_rd_type(u_char *pnt);
extern void encode_rd_type(u_int16_t, u_char *);
extern void decode_rd_as (u_char *pnt, struct rd_as *rd_as);
extern void decode_rd_as4 (u_char *pnt, struct rd_as *rd_as);
extern void decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip);
extern void decode_rd_as(u_char *pnt, struct rd_as *rd_as);
extern void decode_rd_as4(u_char *pnt, struct rd_as *rd_as);
extern void decode_rd_ip(u_char *pnt, struct rd_ip *rd_ip);
#if ENABLE_BGP_VNC
extern void
decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth);
extern void decode_rd_vnc_eth(u_char *pnt, struct rd_vnc_eth *rd_vnc_eth);
#endif
extern int str2prefix_rd (const char *, struct prefix_rd *);
extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
extern int str2prefix_rd(const char *, struct prefix_rd *);
extern char *prefix_rd2str(struct prefix_rd *, char *, size_t);
#endif /* _QUAGGA_BGP_RD_H */

View File

@ -35,8 +35,7 @@
(^|[,{}() ]|$) */
regex_t *
bgp_regcomp (const char *regstr)
regex_t *bgp_regcomp(const char *regstr)
{
/* Convert _ character to generic regular expression. */
int i, j;
@ -47,49 +46,44 @@ bgp_regcomp (const char *regstr)
int ret;
regex_t *regex;
len = strlen (regstr);
len = strlen(regstr);
for (i = 0; i < len; i++)
if (regstr[i] == '_')
magic++;
magic_str = XMALLOC (MTYPE_TMP, len + (14 * magic) + 1);
magic_str = XMALLOC(MTYPE_TMP, len + (14 * magic) + 1);
for (i = 0, j = 0; i < len; i++)
{
if (regstr[i] == '_')
{
memcpy (magic_str + j, magic_regexp, strlen (magic_regexp));
j += strlen (magic_regexp);
}
else
for (i = 0, j = 0; i < len; i++) {
if (regstr[i] == '_') {
memcpy(magic_str + j, magic_regexp,
strlen(magic_regexp));
j += strlen(magic_regexp);
} else
magic_str[j++] = regstr[i];
}
magic_str[j] = '\0';
regex = XMALLOC (MTYPE_BGP_REGEXP, sizeof (regex_t));
regex = XMALLOC(MTYPE_BGP_REGEXP, sizeof(regex_t));
ret = regcomp (regex, magic_str, REG_EXTENDED|REG_NOSUB);
ret = regcomp(regex, magic_str, REG_EXTENDED | REG_NOSUB);
XFREE (MTYPE_TMP, magic_str);
XFREE(MTYPE_TMP, magic_str);
if (ret != 0)
{
XFREE (MTYPE_BGP_REGEXP, regex);
if (ret != 0) {
XFREE(MTYPE_BGP_REGEXP, regex);
return NULL;
}
return regex;
}
int
bgp_regexec (regex_t *regex, struct aspath *aspath)
int bgp_regexec(regex_t *regex, struct aspath *aspath)
{
return regexec (regex, aspath->str, 0, NULL, 0);
return regexec(regex, aspath->str, 0, NULL, 0);
}
void
bgp_regex_free (regex_t *regex)
void bgp_regex_free(regex_t *regex)
{
regfree (regex);
XFREE (MTYPE_BGP_REGEXP, regex);
regfree(regex);
XFREE(MTYPE_BGP_REGEXP, regex);
}

View File

@ -24,13 +24,13 @@
#include <zebra.h>
#ifdef HAVE_LIBPCREPOSIX
# include <pcreposix.h>
#include <pcreposix.h>
#else
# include <regex.h>
#include <regex.h>
#endif /* HAVE_LIBPCREPOSIX */
extern void bgp_regex_free (regex_t *regex);
extern regex_t *bgp_regcomp (const char *str);
extern int bgp_regexec (regex_t *regex, struct aspath *aspath);
extern void bgp_regex_free(regex_t *regex);
extern regex_t *bgp_regcomp(const char *str);
extern int bgp_regexec(regex_t *regex, struct aspath *aspath);
#endif /* _QUAGGA_BGP_REGEX_H */

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,7 @@
struct bgp_nexthop_cache;
struct bgp_route_evpn;
enum bgp_show_type
{
enum bgp_show_type {
bgp_show_type_normal,
bgp_show_type_regexp,
bgp_show_type_prefix_list,
@ -52,8 +51,9 @@ enum bgp_show_type
};
#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, "\
"h history, * valid, > best, = multipath,\n"\
#define BGP_SHOW_SCODE_HEADER \
"Status codes: s suppressed, d damped, " \
"h history, * valid, > best, = multipath,\n" \
" i internal, r RIB-failure, S Stale, R Removed\n"
#define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"
#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n"
@ -62,8 +62,7 @@ enum bgp_show_type
* used for uncommonly used data (aggregation, MPLS, etc.)
* and lazily allocated to save memory.
*/
struct bgp_info_extra
{
struct bgp_info_extra {
/* Pointer to dampening structure. */
struct bgp_damp_info *damp_info;
@ -80,32 +79,39 @@ struct bgp_info_extra
union {
struct {
void *rfapi_handle; /* export: NVE advertising this route */
struct list *local_nexthops; /* optional, for static routes */
void *rfapi_handle; /* export: NVE advertising this
route */
struct list *local_nexthops; /* optional, for static
routes */
} export;
struct {
struct thread *timer;
void *hme; /* encap monitor, if this is a VPN route */
struct prefix_rd rd; /* import: route's route-distinguisher */
u_char un_family; /* family of cached un address, 0 if unset */
struct prefix_rd
rd; /* import: route's route-distinguisher */
u_char un_family; /* family of cached un address, 0 if
unset */
union {
struct in_addr addr4;
struct in6_addr addr6;
} un; /* cached un address */
time_t create_time;
struct prefix aux_prefix; /* AFI_L2VPN: the IP addr, if family set */
struct
prefix
aux_prefix; /* AFI_L2VPN: the IP addr,
if family set */
} import;
} vnc;
#endif
/* For imported routes into a VNI (or VRF), this points to the parent. */
/* For imported routes into a VNI (or VRF), this points to the parent.
*/
void *parent;
};
struct bgp_info
{
struct bgp_info {
/* For linked list. */
struct bgp_info *next;
struct bgp_info *prev;
@ -174,19 +180,16 @@ struct bgp_info
/* Addpath identifiers */
u_int32_t addpath_rx_id;
u_int32_t addpath_tx_id;
};
/* Structure used in BGP path selection */
struct bgp_info_pair
{
struct bgp_info_pair {
struct bgp_info *old;
struct bgp_info *new;
};
/* BGP static route configuration. */
struct bgp_static
{
struct bgp_static {
/* Backdoor configuration. */
int backdoor;
@ -207,8 +210,7 @@ struct bgp_static
u_int32_t atomic;
/* BGP redistribute route-map. */
struct
{
struct {
char *name;
struct route_map *map;
} rmap;
@ -227,27 +229,27 @@ struct bgp_static
};
#define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen) \
((nhlen) < IPV4_MAX_BYTELEN ? 0 : \
((nhlen) < IPV6_MAX_BYTELEN ? AFI_IP : AFI_IP6))
((nhlen) < IPV4_MAX_BYTELEN \
? 0 \
: ((nhlen) < IPV6_MAX_BYTELEN ? AFI_IP : AFI_IP6))
#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
(! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP)) && \
((attr)->mp_nexthop_len == 16 || \
(attr)->mp_nexthop_len == 32))
(!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) \
&& ((attr)->mp_nexthop_len == 16 || (attr)->mp_nexthop_len == 32))
#define BGP_INFO_COUNTABLE(BI) \
(! CHECK_FLAG ((BI)->flags, BGP_INFO_HISTORY) \
&& ! CHECK_FLAG ((BI)->flags, BGP_INFO_REMOVED))
(!CHECK_FLAG((BI)->flags, BGP_INFO_HISTORY) \
&& !CHECK_FLAG((BI)->flags, BGP_INFO_REMOVED))
/* Flags which indicate a route is unuseable in some form */
#define BGP_INFO_UNUSEABLE \
(BGP_INFO_HISTORY|BGP_INFO_DAMPED|BGP_INFO_REMOVED)
(BGP_INFO_HISTORY | BGP_INFO_DAMPED | BGP_INFO_REMOVED)
/* Macro to check BGP information is alive or not. Sadly,
* not equivalent to just checking previous, because of the
* sense of the additional VALID flag.
*/
#define BGP_INFO_HOLDDOWN(BI) \
(! CHECK_FLAG ((BI)->flags, BGP_INFO_VALID) \
|| CHECK_FLAG ((BI)->flags, BGP_INFO_UNUSEABLE))
(!CHECK_FLAG((BI)->flags, BGP_INFO_VALID) \
|| CHECK_FLAG((BI)->flags, BGP_INFO_UNUSEABLE))
#define DISTRIBUTE_IN_NAME(F) ((F)->dlist[FILTER_IN].name)
#define DISTRIBUTE_IN(F) ((F)->dlist[FILTER_IN].alist)
@ -275,127 +277,129 @@ struct bgp_static
/* path PREFIX (addpath rxid NUMBER) */
#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_ALL, BGP_PATH_BESTPATH, BGP_PATH_MULTIPATH };
static inline void
bgp_bump_version (struct bgp_node *node)
static inline void bgp_bump_version(struct bgp_node *node)
{
node->version = bgp_table_next_version(bgp_node_table(node));
}
static inline int
bgp_fibupd_safi (safi_t safi)
static inline int bgp_fibupd_safi(safi_t safi)
{
if (safi == SAFI_UNICAST ||
safi == SAFI_MULTICAST ||
safi == SAFI_LABELED_UNICAST)
if (safi == SAFI_UNICAST || safi == SAFI_MULTICAST
|| safi == SAFI_LABELED_UNICAST)
return 1;
return 0;
}
/* Prototypes. */
extern void bgp_process_queue_init (void);
extern void bgp_route_init (void);
extern void bgp_route_finish (void);
extern void bgp_cleanup_routes (struct bgp *);
extern void bgp_announce_route (struct peer *, afi_t, safi_t);
extern void bgp_process_queue_init(void);
extern void bgp_route_init(void);
extern void bgp_route_finish(void);
extern void bgp_cleanup_routes(struct bgp *);
extern void bgp_announce_route(struct peer *, afi_t, safi_t);
extern void bgp_stop_announce_route_timer(struct peer_af *paf);
extern void bgp_announce_route_all (struct peer *);
extern void bgp_default_originate (struct peer *, afi_t, safi_t, int);
extern void bgp_soft_reconfig_in (struct peer *, afi_t, safi_t);
extern void bgp_clear_route (struct peer *, afi_t, safi_t);
extern void bgp_clear_route_all (struct peer *);
extern void bgp_clear_adj_in (struct peer *, afi_t, safi_t);
extern void bgp_clear_stale_route (struct peer *, afi_t, safi_t);
extern void bgp_announce_route_all(struct peer *);
extern void bgp_default_originate(struct peer *, afi_t, safi_t, int);
extern void bgp_soft_reconfig_in(struct peer *, afi_t, safi_t);
extern void bgp_clear_route(struct peer *, afi_t, safi_t);
extern void bgp_clear_route_all(struct peer *);
extern void bgp_clear_adj_in(struct peer *, afi_t, safi_t);
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,
struct prefix_rd *prd);
extern struct bgp_info *bgp_info_lock (struct bgp_info *);
extern struct bgp_info *bgp_info_unlock (struct bgp_info *);
extern void bgp_info_add (struct bgp_node *rn, struct bgp_info *ri);
extern void bgp_info_reap (struct bgp_node *rn, struct bgp_info *ri);
extern void bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri);
extern struct bgp_info_extra *bgp_info_extra_get (struct bgp_info *);
extern void bgp_info_set_flag (struct bgp_node *, struct bgp_info *, u_int32_t);
extern void bgp_info_unset_flag (struct bgp_node *, struct bgp_info *, u_int32_t);
extern void bgp_info_path_with_addpath_rx_str (struct bgp_info *ri, char *buf);
extern struct bgp_info *bgp_info_lock(struct bgp_info *);
extern struct bgp_info *bgp_info_unlock(struct bgp_info *);
extern void bgp_info_add(struct bgp_node *rn, struct bgp_info *ri);
extern void bgp_info_reap(struct bgp_node *rn, struct bgp_info *ri);
extern void bgp_info_delete(struct bgp_node *rn, struct bgp_info *ri);
extern struct bgp_info_extra *bgp_info_extra_get(struct bgp_info *);
extern void bgp_info_set_flag(struct bgp_node *, struct bgp_info *, u_int32_t);
extern void bgp_info_unset_flag(struct bgp_node *, struct bgp_info *,
u_int32_t);
extern void bgp_info_path_with_addpath_rx_str(struct bgp_info *ri, 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 *);
extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
extern int bgp_maximum_prefix_overflow(struct peer *, afi_t, safi_t, int);
extern void bgp_redistribute_add (struct bgp *, struct prefix *, const struct in_addr *,
extern void bgp_redistribute_add(struct bgp *, struct prefix *,
const struct in_addr *,
const struct in6_addr *, unsigned int ifindex,
u_int32_t, u_char, u_short, route_tag_t);
extern void bgp_redistribute_delete (struct bgp *, struct prefix *, u_char, u_short);
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int, u_short);
extern void bgp_redistribute_delete(struct bgp *, struct prefix *, u_char,
u_short);
extern void bgp_redistribute_withdraw(struct bgp *, afi_t, int, u_short);
extern void bgp_static_add (struct bgp *);
extern void bgp_static_delete (struct bgp *);
extern void bgp_static_redo_import_check (struct bgp *);
extern void bgp_purge_static_redist_routes (struct bgp *bgp);
extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,
afi_t, safi_t);
extern void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t);
extern void bgp_static_add(struct bgp *);
extern void bgp_static_delete(struct bgp *);
extern void bgp_static_redo_import_check(struct bgp *);
extern void bgp_purge_static_redist_routes(struct bgp *bgp);
extern void bgp_static_update(struct bgp *, struct prefix *,
struct bgp_static *, afi_t, safi_t);
extern void bgp_static_withdraw(struct bgp *, struct prefix *, afi_t, safi_t);
extern int bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *,
extern int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
const char *, const char *, const char *,
int, const char *, const char *, const char *, const char *);
const char *, int, const char *, const char *,
const char *, const char *);
extern int bgp_static_unset_safi (afi_t afi, safi_t safi, struct vty *, const char *,
const char *, const char *,
int, const char *, const char *, const char *);
extern int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *,
const char *, const char *, const char *, int,
const char *, const char *, const char *);
/* this is primarily for MPLS-VPN */
extern int bgp_update (struct peer *, struct prefix *, u_int32_t, struct attr *,
extern int bgp_update(struct peer *, struct prefix *, u_int32_t, struct attr *,
afi_t, safi_t, int, int, struct prefix_rd *,
mpls_label_t *, int, struct bgp_route_evpn *);
extern int bgp_withdraw (struct peer *, struct prefix *, u_int32_t, struct attr *,
afi_t, safi_t, int, int, struct prefix_rd *, mpls_label_t *,
extern int bgp_withdraw(struct peer *, struct prefix *, u_int32_t,
struct attr *, afi_t, safi_t, int, int,
struct prefix_rd *, mpls_label_t *,
struct bgp_route_evpn *);
/* for bgp_nexthop and bgp_damp */
extern void bgp_process (struct bgp *, struct bgp_node *, afi_t, safi_t);
extern void bgp_process(struct bgp *, struct bgp_node *, afi_t, safi_t);
/*
* Add an end-of-initial-update marker to the process queue. This is just a
* queue element with NULL bgp node.
*/
extern void bgp_add_eoiu_mark (struct bgp *);
extern int bgp_config_write_table_map (struct vty *, struct bgp *, afi_t, safi_t,
extern void bgp_add_eoiu_mark(struct bgp *);
extern int bgp_config_write_table_map(struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern int bgp_config_write_network(struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern int bgp_config_write_distance(struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern int bgp_config_write_network (struct vty *, struct bgp *, afi_t, safi_t, int *);
extern int bgp_config_write_distance (struct vty *, struct bgp *, afi_t, safi_t, int *);
extern void bgp_aggregate_increment (struct bgp *, struct prefix *, struct bgp_info *,
afi_t, safi_t);
extern void bgp_aggregate_decrement (struct bgp *, struct prefix *, struct bgp_info *,
afi_t, safi_t);
extern void bgp_aggregate_increment(struct bgp *, struct prefix *,
struct bgp_info *, afi_t, safi_t);
extern void bgp_aggregate_decrement(struct bgp *, struct prefix *,
struct bgp_info *, afi_t, safi_t);
extern u_char bgp_distance_apply (struct prefix *, struct bgp_info *, afi_t, safi_t, struct bgp *);
extern u_char bgp_distance_apply(struct prefix *, struct bgp_info *, afi_t,
safi_t, struct bgp *);
extern afi_t bgp_node_afi (struct vty *);
extern safi_t bgp_node_safi (struct vty *);
extern afi_t bgp_node_afi(struct vty *);
extern safi_t bgp_node_safi(struct vty *);
extern struct bgp_info *
info_make (int type, int sub_type, u_short instance, struct peer *peer,
struct attr *attr, struct bgp_node *rn);
extern struct bgp_info *info_make(int type, int sub_type, u_short instance,
struct peer *peer, struct attr *attr,
struct bgp_node *rn);
extern void route_vty_out (struct vty *, struct prefix *, struct bgp_info *, int, safi_t, json_object *);
extern void route_vty_out_tag (struct vty *, struct prefix *, struct bgp_info *, int, safi_t, json_object *);
extern void route_vty_out_tmp (struct vty *, struct prefix *, struct attr *, safi_t, u_char, json_object *);
extern void
route_vty_out_overlay (struct vty *vty, struct prefix *p,
struct bgp_info *binfo, int display, json_object *json);
extern void route_vty_out(struct vty *, struct prefix *, struct bgp_info *, int,
safi_t, json_object *);
extern void route_vty_out_tag(struct vty *, struct prefix *, struct bgp_info *,
int, safi_t, json_object *);
extern void route_vty_out_tmp(struct vty *, struct prefix *, struct attr *,
safi_t, u_char, json_object *);
extern void route_vty_out_overlay(struct vty *vty, struct prefix *p,
struct bgp_info *binfo, int display,
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_node *rn,
u_int32_t addpath_tx_id);
@ -404,39 +408,36 @@ extern int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
struct update_subgroup *subgrp,
struct prefix *p, struct attr *attr);
extern void bgp_peer_clear_node_queue_drain_immediate (struct peer *peer);
extern void bgp_process_queues_drain_immediate (void);
extern void bgp_peer_clear_node_queue_drain_immediate(struct peer *peer);
extern void bgp_process_queues_drain_immediate(void);
/* for encap/vpn */
extern struct bgp_node *
bgp_afi_node_get (struct bgp_table *, afi_t , safi_t , struct prefix *,
struct prefix_rd *);
extern struct bgp_node *
bgp_afi_node_lookup (struct bgp_table *table, afi_t afi, safi_t safi,
struct prefix *p, struct prefix_rd *prd);
extern struct bgp_info *bgp_info_new (void);
extern void bgp_info_restore (struct bgp_node *, struct bgp_info *);
extern struct bgp_node *bgp_afi_node_get(struct bgp_table *, afi_t, safi_t,
struct prefix *, struct prefix_rd *);
extern struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
safi_t safi, struct prefix *p,
struct prefix_rd *prd);
extern struct bgp_info *bgp_info_new(void);
extern void bgp_info_restore(struct bgp_node *, struct bgp_info *);
extern int
bgp_info_cmp_compatible (struct bgp *, struct bgp_info *, struct bgp_info *,
char *pfx_buf, afi_t afi, safi_t safi);
extern int bgp_info_cmp_compatible(struct bgp *, struct bgp_info *,
struct bgp_info *, char *pfx_buf, afi_t afi,
safi_t safi);
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_info_pair *result,
afi_t afi, safi_t safi);
extern void bgp_zebra_clear_route_change_flags (struct bgp_node *rn);
extern int
bgp_zebra_has_route_changed (struct bgp_node *rn, struct bgp_info *selected);
struct bgp_info_pair *result, afi_t afi,
safi_t safi);
extern void bgp_zebra_clear_route_change_flags(struct bgp_node *rn);
extern int bgp_zebra_has_route_changed(struct bgp_node *rn,
struct bgp_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 prefix_rd *prd, afi_t afi, safi_t safi,
json_object *json);
extern void
route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
struct bgp_info *binfo, afi_t afi, safi_t safi,
struct prefix_rd *prd, afi_t afi,
safi_t safi, json_object *json);
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct prefix *p, struct bgp_info *binfo,
afi_t afi, safi_t safi,
json_object *json_paths);
#endif /* _QUAGGA_BGP_ROUTE_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -30,34 +30,29 @@
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
void
bgp_table_lock (struct bgp_table *rt)
void bgp_table_lock(struct bgp_table *rt)
{
rt->lock++;
}
void
bgp_table_unlock (struct bgp_table *rt)
void bgp_table_unlock(struct bgp_table *rt)
{
assert (rt->lock > 0);
assert(rt->lock > 0);
rt->lock--;
if (rt->lock != 0)
{
if (rt->lock != 0) {
return;
}
route_table_finish (rt->route_table);
route_table_finish(rt->route_table);
rt->route_table = NULL;
XFREE (MTYPE_BGP_TABLE, rt);
XFREE(MTYPE_BGP_TABLE, rt);
}
void
bgp_table_finish (struct bgp_table **rt)
void bgp_table_finish(struct bgp_table **rt)
{
if (*rt != NULL)
{
if (*rt != NULL) {
bgp_table_unlock(*rt);
*rt = NULL;
}
@ -66,53 +61,49 @@ bgp_table_finish (struct bgp_table **rt)
/*
* bgp_node_create
*/
static struct route_node *
bgp_node_create (route_table_delegate_t *delegate, struct route_table *table)
static struct route_node *bgp_node_create(route_table_delegate_t *delegate,
struct route_table *table)
{
struct bgp_node *node;
node = XCALLOC (MTYPE_BGP_NODE, sizeof (struct bgp_node));
return bgp_node_to_rnode (node);
node = XCALLOC(MTYPE_BGP_NODE, sizeof(struct bgp_node));
return bgp_node_to_rnode(node);
}
/*
* bgp_node_destroy
*/
static void
bgp_node_destroy (route_table_delegate_t *delegate,
static void bgp_node_destroy(route_table_delegate_t *delegate,
struct route_table *table, struct route_node *node)
{
struct bgp_node *bgp_node;
bgp_node = bgp_node_from_rnode (node);
XFREE (MTYPE_BGP_NODE, bgp_node);
bgp_node = bgp_node_from_rnode(node);
XFREE(MTYPE_BGP_NODE, bgp_node);
}
/*
* Function vector to customize the behavior of the route table
* library for BGP route tables.
*/
route_table_delegate_t bgp_table_delegate = {
.create_node = bgp_node_create,
.destroy_node = bgp_node_destroy
};
route_table_delegate_t bgp_table_delegate = {.create_node = bgp_node_create,
.destroy_node = bgp_node_destroy};
/*
* bgp_table_init
*/
struct bgp_table *
bgp_table_init (afi_t afi, safi_t safi)
struct bgp_table *bgp_table_init(afi_t afi, safi_t safi)
{
struct bgp_table *rt;
rt = XCALLOC (MTYPE_BGP_TABLE, sizeof (struct bgp_table));
rt = XCALLOC(MTYPE_BGP_TABLE, sizeof(struct bgp_table));
rt->route_table = route_table_init_with_delegate (&bgp_table_delegate);
rt->route_table = route_table_init_with_delegate(&bgp_table_delegate);
/*
* Set up back pointer to bgp_table.
*/
rt->route_table->info = rt;
bgp_table_lock (rt);
bgp_table_lock(rt);
rt->afi = afi;
rt->safi = safi;

View File

@ -24,8 +24,7 @@
#include "mpls.h"
#include "table.h"
struct bgp_table
{
struct bgp_table {
/* afi/safi of this table */
afi_t afi;
safi_t safi;
@ -36,8 +35,7 @@ struct bgp_table
uint64_t version;
};
struct bgp_node
{
struct bgp_node {
/*
* CAUTION
*
@ -69,16 +67,15 @@ struct bgp_node
*
* Structure that holds state for iterating over a bgp table.
*/
typedef struct bgp_table_iter_t_
{
typedef struct bgp_table_iter_t_ {
struct bgp_table *table;
route_table_iter_t rt_iter;
} bgp_table_iter_t;
extern struct bgp_table *bgp_table_init (afi_t, safi_t);
extern void bgp_table_lock (struct bgp_table *);
extern void bgp_table_unlock (struct bgp_table *);
extern void bgp_table_finish (struct bgp_table **);
extern struct bgp_table *bgp_table_init(afi_t, safi_t);
extern void bgp_table_lock(struct bgp_table *);
extern void bgp_table_unlock(struct bgp_table *);
extern void bgp_table_finish(struct bgp_table **);
/*
@ -86,10 +83,9 @@ extern void bgp_table_finish (struct bgp_table **);
*
* Returns the bgp_node structure corresponding to a route_node.
*/
static inline struct bgp_node *
bgp_node_from_rnode (struct route_node *rnode)
static inline struct bgp_node *bgp_node_from_rnode(struct route_node *rnode)
{
return (struct bgp_node *) rnode;
return (struct bgp_node *)rnode;
}
/*
@ -97,10 +93,9 @@ bgp_node_from_rnode (struct route_node *rnode)
*
* Returns the route_node structure corresponding to a bgp_node.
*/
static inline struct route_node *
bgp_node_to_rnode (struct bgp_node *node)
static inline struct route_node *bgp_node_to_rnode(struct bgp_node *node)
{
return (struct route_node *) node;
return (struct route_node *)node;
}
/*
@ -108,10 +103,9 @@ bgp_node_to_rnode (struct bgp_node *node)
*
* Returns the bgp_table that the given node is in.
*/
static inline struct bgp_table *
bgp_node_table (struct bgp_node *node)
static inline struct bgp_table *bgp_node_table(struct bgp_node *node)
{
return bgp_node_to_rnode (node)->table->info;
return bgp_node_to_rnode(node)->table->info;
}
/*
@ -119,19 +113,17 @@ bgp_node_table (struct bgp_node *node)
*
* Gets the parent node of the given node without locking it.
*/
static inline struct bgp_node *
bgp_node_parent_nolock (struct bgp_node *node)
static inline struct bgp_node *bgp_node_parent_nolock(struct bgp_node *node)
{
return bgp_node_from_rnode (node->parent);
return bgp_node_from_rnode(node->parent);
}
/*
* bgp_unlock_node
*/
static inline void
bgp_unlock_node (struct bgp_node *node)
static inline void bgp_unlock_node(struct bgp_node *node)
{
route_unlock_node (bgp_node_to_rnode (node));
route_unlock_node(bgp_node_to_rnode(node));
}
/*
@ -142,181 +134,171 @@ bgp_unlock_node (struct bgp_node *node)
* @see bgp_table_top
*/
static inline struct bgp_node *
bgp_table_top_nolock (const struct bgp_table *const table)
bgp_table_top_nolock(const struct bgp_table *const table)
{
return bgp_node_from_rnode (table->route_table->top);
return bgp_node_from_rnode(table->route_table->top);
}
/*
* bgp_table_top
*/
static inline struct bgp_node *
bgp_table_top (const struct bgp_table *const table)
bgp_table_top(const struct bgp_table *const table)
{
return bgp_node_from_rnode (route_top (table->route_table));
return bgp_node_from_rnode(route_top(table->route_table));
}
/*
* bgp_route_next
*/
static inline struct bgp_node *
bgp_route_next (struct bgp_node *node)
static inline struct bgp_node *bgp_route_next(struct bgp_node *node)
{
return bgp_node_from_rnode (route_next (bgp_node_to_rnode (node)));
return bgp_node_from_rnode(route_next(bgp_node_to_rnode(node)));
}
/*
* bgp_route_next_until
*/
static inline struct bgp_node *
bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit)
static inline struct bgp_node *bgp_route_next_until(struct bgp_node *node,
struct bgp_node *limit)
{
struct route_node *rnode;
rnode = route_next_until (bgp_node_to_rnode (node),
bgp_node_to_rnode (limit));
return bgp_node_from_rnode (rnode);
rnode = route_next_until(bgp_node_to_rnode(node),
bgp_node_to_rnode(limit));
return bgp_node_from_rnode(rnode);
}
/*
* bgp_node_get
*/
static inline struct bgp_node *
bgp_node_get (struct bgp_table *const table, struct prefix *p)
static inline struct bgp_node *bgp_node_get(struct bgp_table *const table,
struct prefix *p)
{
return bgp_node_from_rnode (route_node_get (table->route_table, p));
return bgp_node_from_rnode(route_node_get(table->route_table, p));
}
/*
* bgp_node_lookup
*/
static inline struct bgp_node *
bgp_node_lookup (const struct bgp_table *const table, struct prefix *p)
bgp_node_lookup(const struct bgp_table *const table, struct prefix *p)
{
return bgp_node_from_rnode (route_node_lookup (table->route_table, p));
return bgp_node_from_rnode(route_node_lookup(table->route_table, p));
}
/*
* bgp_lock_node
*/
static inline struct bgp_node *
bgp_lock_node (struct bgp_node *node)
static inline struct bgp_node *bgp_lock_node(struct bgp_node *node)
{
return bgp_node_from_rnode (route_lock_node (bgp_node_to_rnode (node)));
return bgp_node_from_rnode(route_lock_node(bgp_node_to_rnode(node)));
}
/*
* bgp_node_match
*/
static inline struct bgp_node *
bgp_node_match (const struct bgp_table *table, struct prefix *p)
static inline struct bgp_node *bgp_node_match(const struct bgp_table *table,
struct prefix *p)
{
return bgp_node_from_rnode (route_node_match (table->route_table, p));
return bgp_node_from_rnode(route_node_match(table->route_table, p));
}
/*
* bgp_node_match_ipv4
*/
static inline struct bgp_node *
bgp_node_match_ipv4 (const struct bgp_table *table, struct in_addr *addr)
bgp_node_match_ipv4(const struct bgp_table *table, struct in_addr *addr)
{
return bgp_node_from_rnode (route_node_match_ipv4 (table->route_table,
addr));
return bgp_node_from_rnode(
route_node_match_ipv4(table->route_table, addr));
}
/*
* bgp_node_match_ipv6
*/
static inline struct bgp_node *
bgp_node_match_ipv6 (const struct bgp_table *table, struct in6_addr *addr)
bgp_node_match_ipv6(const struct bgp_table *table, struct in6_addr *addr)
{
return bgp_node_from_rnode (route_node_match_ipv6 (table->route_table,
addr));
return bgp_node_from_rnode(
route_node_match_ipv6(table->route_table, addr));
}
static inline unsigned long
bgp_table_count (const struct bgp_table *const table)
static inline unsigned long bgp_table_count(const struct bgp_table *const table)
{
return route_table_count (table->route_table);
return route_table_count(table->route_table);
}
/*
* bgp_table_get_next
*/
static inline struct bgp_node *
bgp_table_get_next (const struct bgp_table *table, struct prefix *p)
static inline struct bgp_node *bgp_table_get_next(const struct bgp_table *table,
struct prefix *p)
{
return bgp_node_from_rnode (route_table_get_next (table->route_table, p));
return bgp_node_from_rnode(route_table_get_next(table->route_table, p));
}
/*
* bgp_table_iter_init
*/
static inline void
bgp_table_iter_init (bgp_table_iter_t * iter, struct bgp_table *table)
static inline void bgp_table_iter_init(bgp_table_iter_t *iter,
struct bgp_table *table)
{
bgp_table_lock (table);
bgp_table_lock(table);
iter->table = table;
route_table_iter_init (&iter->rt_iter, table->route_table);
route_table_iter_init(&iter->rt_iter, table->route_table);
}
/*
* bgp_table_iter_next
*/
static inline struct bgp_node *
bgp_table_iter_next (bgp_table_iter_t * iter)
static inline struct bgp_node *bgp_table_iter_next(bgp_table_iter_t *iter)
{
return bgp_node_from_rnode (route_table_iter_next (&iter->rt_iter));
return bgp_node_from_rnode(route_table_iter_next(&iter->rt_iter));
}
/*
* bgp_table_iter_cleanup
*/
static inline void
bgp_table_iter_cleanup (bgp_table_iter_t * iter)
static inline void bgp_table_iter_cleanup(bgp_table_iter_t *iter)
{
route_table_iter_cleanup (&iter->rt_iter);
bgp_table_unlock (iter->table);
route_table_iter_cleanup(&iter->rt_iter);
bgp_table_unlock(iter->table);
iter->table = NULL;
}
/*
* bgp_table_iter_pause
*/
static inline void
bgp_table_iter_pause (bgp_table_iter_t * iter)
static inline void bgp_table_iter_pause(bgp_table_iter_t *iter)
{
route_table_iter_pause (&iter->rt_iter);
route_table_iter_pause(&iter->rt_iter);
}
/*
* bgp_table_iter_is_done
*/
static inline int
bgp_table_iter_is_done (bgp_table_iter_t * iter)
static inline int bgp_table_iter_is_done(bgp_table_iter_t *iter)
{
return route_table_iter_is_done (&iter->rt_iter);
return route_table_iter_is_done(&iter->rt_iter);
}
/*
* bgp_table_iter_started
*/
static inline int
bgp_table_iter_started (bgp_table_iter_t * iter)
static inline int bgp_table_iter_started(bgp_table_iter_t *iter)
{
return route_table_iter_started (&iter->rt_iter);
return route_table_iter_started(&iter->rt_iter);
}
/* This would benefit from a real atomic operation...
* until then. */
static inline uint64_t
bgp_table_next_version (struct bgp_table *table)
static inline uint64_t bgp_table_next_version(struct bgp_table *table)
{
return ++table->version;
}
static inline uint64_t
bgp_table_version (struct bgp_table *table)
static inline uint64_t bgp_table_version(struct bgp_table *table)
{
return table->version;
}

File diff suppressed because it is too large Load Diff

View File

@ -31,44 +31,32 @@
#define BGP_DEFAULT_SUBGROUP_COALESCE_TIME 200
#define PEER_UPDGRP_FLAGS (PEER_FLAG_LOCAL_AS_NO_PREPEND | \
PEER_FLAG_LOCAL_AS_REPLACE_AS)
#define PEER_UPDGRP_FLAGS \
(PEER_FLAG_LOCAL_AS_NO_PREPEND | PEER_FLAG_LOCAL_AS_REPLACE_AS)
#define PEER_UPDGRP_AF_FLAGS (PEER_FLAG_SEND_COMMUNITY | \
PEER_FLAG_SEND_EXT_COMMUNITY | \
PEER_FLAG_DEFAULT_ORIGINATE | \
PEER_FLAG_REFLECTOR_CLIENT | \
PEER_FLAG_RSERVER_CLIENT | \
PEER_FLAG_NEXTHOP_SELF | \
PEER_FLAG_NEXTHOP_UNCHANGED | \
PEER_FLAG_FORCE_NEXTHOP_SELF | \
PEER_FLAG_AS_PATH_UNCHANGED | \
PEER_FLAG_MED_UNCHANGED | \
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED | \
PEER_FLAG_REMOVE_PRIVATE_AS | \
PEER_FLAG_REMOVE_PRIVATE_AS_ALL | \
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE | \
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE | \
PEER_FLAG_ADDPATH_TX_ALL_PATHS | \
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS | \
PEER_FLAG_AS_OVERRIDE)
#define PEER_UPDGRP_AF_FLAGS \
(PEER_FLAG_SEND_COMMUNITY | PEER_FLAG_SEND_EXT_COMMUNITY \
| PEER_FLAG_DEFAULT_ORIGINATE | PEER_FLAG_REFLECTOR_CLIENT \
| PEER_FLAG_RSERVER_CLIENT | PEER_FLAG_NEXTHOP_SELF \
| PEER_FLAG_NEXTHOP_UNCHANGED | PEER_FLAG_FORCE_NEXTHOP_SELF \
| PEER_FLAG_AS_PATH_UNCHANGED | PEER_FLAG_MED_UNCHANGED \
| PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED | PEER_FLAG_REMOVE_PRIVATE_AS \
| PEER_FLAG_REMOVE_PRIVATE_AS_ALL \
| PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE \
| PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE \
| PEER_FLAG_ADDPATH_TX_ALL_PATHS \
| PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS | PEER_FLAG_AS_OVERRIDE)
#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)
#define PEER_UPDGRP_AF_CAP_FLAGS (PEER_CAP_ORF_PREFIX_SM_RCV | \
PEER_CAP_ORF_PREFIX_SM_OLD_RCV |\
PEER_CAP_ADDPATH_AF_TX_ADV |\
PEER_CAP_ADDPATH_AF_RX_RCV |\
PEER_CAP_ENHE_AF_NEGO)
#define PEER_UPDGRP_AF_CAP_FLAGS \
(PEER_CAP_ORF_PREFIX_SM_RCV | PEER_CAP_ORF_PREFIX_SM_OLD_RCV \
| PEER_CAP_ADDPATH_AF_TX_ADV | PEER_CAP_ADDPATH_AF_RX_RCV \
| PEER_CAP_ENHE_AF_NEGO)
typedef enum
{
BGP_ATTR_VEC_NH = 0,
BGP_ATTR_VEC_MAX
} bpacket_attr_vec_type;
typedef enum { BGP_ATTR_VEC_NH = 0, BGP_ATTR_VEC_MAX } bpacket_attr_vec_type;
typedef struct
{
typedef struct {
u_int32_t flags;
unsigned long offset;
} bpacket_attr_vec;
@ -81,18 +69,16 @@ typedef struct
#define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED (1 << 5)
#define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_LNH_CHANGED (1 << 6)
typedef struct bpacket_attr_vec_arr
{
typedef struct bpacket_attr_vec_arr {
bpacket_attr_vec entries[BGP_ATTR_VEC_MAX];
} bpacket_attr_vec_arr;
struct bpacket
{
struct bpacket {
/* for being part of an update subgroup's message list */
TAILQ_ENTRY (bpacket) pkt_train;
TAILQ_ENTRY(bpacket) pkt_train;
/* list of peers (well, peer_afs) that the packet needs to be sent to */
LIST_HEAD (pkt_peer_list, peer_af) peers;
LIST_HEAD(pkt_peer_list, peer_af) peers;
struct stream *buffer;
bpacket_attr_vec_arr arr;
@ -100,9 +86,8 @@ struct bpacket
unsigned int ver;
};
struct bpacket_queue
{
TAILQ_HEAD (pkt_queue, bpacket) pkts;
struct bpacket_queue {
TAILQ_HEAD(pkt_queue, bpacket) pkts;
#if 0
/* A dummy packet that is used to thread all peers that have
@ -116,13 +101,12 @@ struct bpacket_queue
unsigned int max_count_reached_count;
};
struct update_group
{
struct update_group {
/* back pointer to the BGP instance */
struct bgp *bgp;
/* list of subgroups that belong to the update group */
LIST_HEAD (subgrp_list, update_subgroup) subgrps;
LIST_HEAD(subgrp_list, update_subgroup) subgrps;
/* lazy way to store configuration common to all peers
hash function will compute from this data */
@ -169,20 +153,18 @@ struct update_group
/*
* Increment a counter on a update group and its parent structures.
*/
#define UPDGRP_INCR_STAT(subgrp, stat) \
UPDGRP_INCR_STAT_BY(subgrp, stat, 1)
#define UPDGRP_INCR_STAT(subgrp, stat) UPDGRP_INCR_STAT_BY(subgrp, stat, 1)
struct update_subgroup
{
struct update_subgroup {
/* back pointer to the parent update group */
struct update_group *update_group;
/* list of peers that belong to the subgroup */
LIST_HEAD (peer_list, peer_af) peers;
LIST_HEAD(peer_list, peer_af) peers;
int peer_count;
/* for being part of an update group's subgroup list */
LIST_ENTRY (update_subgroup) updgrp_train;
LIST_ENTRY(update_subgroup) updgrp_train;
struct bpacket_queue pkt_queue;
@ -191,7 +173,7 @@ struct update_subgroup
* It essentially represents the snapshot of every prefix that
* has been advertised to the members of the subgroup
*/
TAILQ_HEAD (adjout_queue, bgp_adj_out) adjq;
TAILQ_HEAD(adjout_queue, bgp_adj_out) adjq;
/* packet buffer for update generation */
struct stream *work;
@ -225,11 +207,11 @@ struct update_subgroup
time_t uptime;
/*
* Identifying information about the subgroup that this subgroup was split
* Identifying information about the subgroup that this subgroup was
* split
* from, if any.
*/
struct
{
struct {
uint64_t update_group_id;
uint64_t subgroup_id;
} split_from;
@ -271,27 +253,25 @@ struct update_subgroup
do { \
(subgrp)->stat += (value); \
if ((subgrp)->update_group) \
UPDGRP_INCR_STAT_BY((subgrp)->update_group, stat, value); \
UPDGRP_INCR_STAT_BY((subgrp)->update_group, stat, \
value); \
} while (0)
/*
* Increment a counter on a subgroup and its parent structures.
*/
#define SUBGRP_INCR_STAT(subgrp, stat) \
SUBGRP_INCR_STAT_BY(subgrp, stat, 1)
#define SUBGRP_INCR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, 1)
/*
* Decrement a counter on a subgroup and its parent structures.
*/
#define SUBGRP_DECR_STAT(subgrp, stat) \
SUBGRP_INCR_STAT_BY(subgrp, stat, -1)
#define SUBGRP_DECR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, -1)
typedef int (*updgrp_walkcb) (struct update_group * updgrp, void *ctx);
typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
/* really a private structure */
struct updwalk_context
{
struct updwalk_context {
struct vty *vty;
struct bgp_node *rn;
struct bgp_info *ri;
@ -321,8 +301,7 @@ struct updwalk_context
#define UPDGRP_AFI(u) ((u)->afi)
#define UPDGRP_SAFI(u) ((u)->safi)
#define UPDGRP_INST(u) ((u)->bgp)
#define UPDGRP_AFFLAGS(u) \
((u)->conf->af_flags[UPDGRP_AFI(u)][UPDGRP_SAFI(u)])
#define UPDGRP_AFFLAGS(u) ((u)->conf->af_flags[UPDGRP_AFI(u)][UPDGRP_SAFI(u)])
#define UPDGRP_DBG_ON(u) ((u)->num_dbg_en_peers)
#define UPDGRP_PEER_DBG_EN(u) (((u)->num_dbg_en_peers)++)
#define UPDGRP_PEER_DBG_DIS(u) (((u)->num_dbg_en_peers)--)
@ -345,7 +324,8 @@ struct updwalk_context
LIST_FOREACH(subgrp, &((updgrp)->subgrps), updgrp_train)
#define UPDGRP_FOREACH_SUBGRP_SAFE(updgrp, subgrp, tmp_subgrp) \
LIST_FOREACH_SAFE(subgrp, &((updgrp)->subgrps), updgrp_train, tmp_subgrp)
LIST_FOREACH_SAFE(subgrp, &((updgrp)->subgrps), updgrp_train, \
tmp_subgrp)
#define SUBGRP_FOREACH_PEER(subgrp, paf) \
LIST_FOREACH(paf, &(subgrp->peers), subgrp_train)
@ -361,128 +341,115 @@ struct updwalk_context
/* Prototypes. */
/* bgp_updgrp.c */
extern void update_bgp_group_init (struct bgp *);
extern void udpate_bgp_group_free (struct bgp *);
extern void update_bgp_group_init(struct bgp *);
extern void udpate_bgp_group_free(struct bgp *);
extern void
update_group_show (struct bgp *bgp, afi_t afi, safi_t safi, struct vty *vty, uint64_t subgrp_id);
extern void update_group_show_stats (struct bgp *bgp, struct vty *vty);
extern void update_group_adjust_peer (struct peer_af *paf);
extern int update_group_adjust_soloness (struct peer *peer, int set);
extern void update_group_show(struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, uint64_t subgrp_id);
extern void update_group_show_stats(struct bgp *bgp, struct vty *vty);
extern void update_group_adjust_peer(struct peer_af *paf);
extern int update_group_adjust_soloness(struct peer *peer, int set);
extern void
update_subgroup_remove_peer (struct update_subgroup *, struct peer_af *);
extern struct bgp_table *update_subgroup_rib (struct update_subgroup *);
extern void
update_subgroup_split_peer (struct peer_af *, struct update_group *);
extern int
update_subgroup_check_merge (struct update_subgroup *, const char *);
extern int
update_subgroup_trigger_merge_check (struct update_subgroup *,
extern void update_subgroup_remove_peer(struct update_subgroup *,
struct peer_af *);
extern struct bgp_table *update_subgroup_rib(struct update_subgroup *);
extern void update_subgroup_split_peer(struct peer_af *, struct update_group *);
extern int update_subgroup_check_merge(struct update_subgroup *, const char *);
extern int update_subgroup_trigger_merge_check(struct update_subgroup *,
int force);
extern void update_group_policy_update (struct bgp *bgp,
bgp_policy_type_e ptype, const char *pname,
int route_update, int start_event);
extern void update_group_af_walk (struct bgp *bgp, afi_t afi, safi_t safi,
extern void update_group_policy_update(struct bgp *bgp, bgp_policy_type_e ptype,
const char *pname, int route_update,
int start_event);
extern void update_group_af_walk(struct bgp *bgp, afi_t afi, safi_t safi,
updgrp_walkcb cb, void *ctx);
extern void update_group_walk (struct bgp *bgp, updgrp_walkcb cb, void *ctx);
extern void update_group_periodic_merge (struct bgp *bgp);
extern int update_group_refresh_default_originate_route_map (struct thread *thread);
extern void update_group_start_advtimer (struct bgp *bgp);
extern void update_group_walk(struct bgp *bgp, updgrp_walkcb cb, void *ctx);
extern void update_group_periodic_merge(struct bgp *bgp);
extern int
update_group_refresh_default_originate_route_map(struct thread *thread);
extern void update_group_start_advtimer(struct bgp *bgp);
extern void update_subgroup_inherit_info (struct update_subgroup *to,
extern void update_subgroup_inherit_info(struct update_subgroup *to,
struct update_subgroup *from);
/* bgp_updgrp_packet.c */
extern struct bpacket *bpacket_alloc (void);
extern void bpacket_free (struct bpacket *pkt);
extern void bpacket_queue_init (struct bpacket_queue *q);
extern void bpacket_queue_cleanup (struct bpacket_queue *q);
extern void bpacket_queue_sanity_check (struct bpacket_queue *q);
extern struct bpacket *bpacket_queue_add (struct bpacket_queue *q,
extern struct bpacket *bpacket_alloc(void);
extern void bpacket_free(struct bpacket *pkt);
extern void bpacket_queue_init(struct bpacket_queue *q);
extern void bpacket_queue_cleanup(struct bpacket_queue *q);
extern void bpacket_queue_sanity_check(struct bpacket_queue *q);
extern struct bpacket *bpacket_queue_add(struct bpacket_queue *q,
struct stream *s,
struct bpacket_attr_vec_arr
*vecarr);
struct bpacket *bpacket_queue_remove (struct bpacket_queue *q);
extern struct bpacket *bpacket_queue_first (struct bpacket_queue *q);
struct bpacket *bpacket_queue_last (struct bpacket_queue *q);
unsigned int bpacket_queue_length (struct bpacket_queue *q);
unsigned int bpacket_queue_hwm_length (struct bpacket_queue *q);
int bpacket_queue_is_full (struct bgp *bgp, struct bpacket_queue *q);
extern void bpacket_queue_advance_peer (struct peer_af *paf);
extern void bpacket_queue_remove_peer (struct peer_af *paf);
extern void bpacket_add_peer (struct bpacket *pkt, struct peer_af *paf);
unsigned int bpacket_queue_virtual_length (struct peer_af *paf);
extern void bpacket_queue_show_vty (struct bpacket_queue *q, struct vty *vty);
int subgroup_packets_to_build (struct update_subgroup *subgrp);
extern struct bpacket *subgroup_update_packet (struct update_subgroup *s);
extern struct bpacket *subgroup_withdraw_packet (struct update_subgroup *s);
extern struct stream *bpacket_reformat_for_peer (struct bpacket *pkt,
struct bpacket_attr_vec_arr *vecarr);
struct bpacket *bpacket_queue_remove(struct bpacket_queue *q);
extern struct bpacket *bpacket_queue_first(struct bpacket_queue *q);
struct bpacket *bpacket_queue_last(struct bpacket_queue *q);
unsigned int bpacket_queue_length(struct bpacket_queue *q);
unsigned int bpacket_queue_hwm_length(struct bpacket_queue *q);
int bpacket_queue_is_full(struct bgp *bgp, struct bpacket_queue *q);
extern void bpacket_queue_advance_peer(struct peer_af *paf);
extern void bpacket_queue_remove_peer(struct peer_af *paf);
extern void bpacket_add_peer(struct bpacket *pkt, struct peer_af *paf);
unsigned int bpacket_queue_virtual_length(struct peer_af *paf);
extern void bpacket_queue_show_vty(struct bpacket_queue *q, struct vty *vty);
int subgroup_packets_to_build(struct update_subgroup *subgrp);
extern struct bpacket *subgroup_update_packet(struct update_subgroup *s);
extern struct bpacket *subgroup_withdraw_packet(struct update_subgroup *s);
extern struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
struct peer_af *paf);
extern void bpacket_attr_vec_arr_reset (struct bpacket_attr_vec_arr *vecarr);
extern void bpacket_attr_vec_arr_set_vec (struct bpacket_attr_vec_arr *vecarr,
extern void bpacket_attr_vec_arr_reset(struct bpacket_attr_vec_arr *vecarr);
extern void bpacket_attr_vec_arr_set_vec(struct bpacket_attr_vec_arr *vecarr,
bpacket_attr_vec_type type,
struct stream *s,
struct attr *attr);
extern void
subgroup_default_update_packet (struct update_subgroup *subgrp,
struct attr *attr, struct peer *from);
extern void subgroup_default_withdraw_packet (struct update_subgroup *subgrp);
struct stream *s, struct attr *attr);
extern void subgroup_default_update_packet(struct update_subgroup *subgrp,
struct attr *attr,
struct peer *from);
extern void subgroup_default_withdraw_packet(struct update_subgroup *subgrp);
/* bgp_updgrp_adv.c */
extern struct bgp_advertise *bgp_advertise_clean_subgroup (struct
update_subgroup
*subgrp,
struct bgp_adj_out
*adj);
extern void update_group_show_adj_queue (struct bgp *bgp, afi_t afi,
extern struct bgp_advertise *
bgp_advertise_clean_subgroup(struct update_subgroup *subgrp,
struct bgp_adj_out *adj);
extern void update_group_show_adj_queue(struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, uint64_t id);
extern void update_group_show_advertised(struct bgp *bgp, afi_t afi,
safi_t safi, struct vty *vty,
uint64_t id);
extern void update_group_show_advertised (struct bgp *bgp, afi_t afi,
extern void update_group_show_packet_queue(struct bgp *bgp, afi_t afi,
safi_t safi, struct vty *vty,
uint64_t id);
extern void update_group_show_packet_queue (struct bgp *bgp, afi_t afi,
safi_t safi, struct vty *vty,
uint64_t id);
extern void subgroup_announce_route (struct update_subgroup *subgrp);
extern void subgroup_announce_all (struct update_subgroup *subgrp);
extern void subgroup_announce_route(struct update_subgroup *subgrp);
extern void subgroup_announce_all(struct update_subgroup *subgrp);
extern void
subgroup_default_originate (struct update_subgroup *subgrp, int withdraw);
extern void
group_announce_route (struct bgp *bgp, afi_t afi, safi_t safi,
extern void subgroup_default_originate(struct update_subgroup *subgrp,
int withdraw);
extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
struct bgp_node *rn, struct bgp_info *ri);
extern void subgroup_clear_table (struct update_subgroup *subgrp);
extern void update_group_announce (struct bgp *bgp);
extern void update_group_announce_rrclients (struct bgp *bgp);
extern void peer_af_announce_route (struct peer_af *paf, int combine);
extern struct bgp_adj_out *bgp_adj_out_alloc (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_rrclients(struct bgp *bgp);
extern void peer_af_announce_route(struct peer_af *paf, int combine);
extern struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp,
struct bgp_node *rn,
u_int32_t addpath_tx_id);
extern void bgp_adj_out_remove_subgroup (struct bgp_node *rn,
extern void bgp_adj_out_remove_subgroup(struct bgp_node *rn,
struct bgp_adj_out *adj,
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 attr *attr, struct bgp_info *binfo);
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,
char withdraw,
u_int32_t addpath_tx_id);
void
subgroup_announce_table (struct update_subgroup *subgrp,
char withdraw, u_int32_t addpath_tx_id);
void subgroup_announce_table(struct update_subgroup *subgrp,
struct bgp_table *table);
extern void
subgroup_trigger_write (struct update_subgroup *subgrp);
extern void subgroup_trigger_write(struct update_subgroup *subgrp);
extern int
update_group_clear_update_dbg (struct update_group *updgrp, void *arg);
extern int update_group_clear_update_dbg(struct update_group *updgrp,
void *arg);
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_tx_path (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,
struct bgp_info *ri);
/*
@ -492,8 +459,7 @@ extern int bgp_addpath_tx_path (struct peer *peer, afi_t afi, safi_t safi,
/*
* bpacket_queue_is_empty
*/
static inline int
bpacket_queue_is_empty (struct bpacket_queue *queue)
static inline int bpacket_queue_is_empty(struct bpacket_queue *queue)
{
/*
@ -502,7 +468,7 @@ bpacket_queue_is_empty (struct bpacket_queue *queue)
if (queue->curr_count != 1)
return 0;
assert (bpacket_queue_first (queue)->buffer == NULL);
assert(bpacket_queue_first(queue)->buffer == NULL);
return 1;
}
@ -511,10 +477,9 @@ bpacket_queue_is_empty (struct bpacket_queue *queue)
*
* Returns the packet after the given packet in a bpacket queue.
*/
static inline struct bpacket *
bpacket_next (struct bpacket *pkt)
static inline struct bpacket *bpacket_next(struct bpacket *pkt)
{
return TAILQ_NEXT (pkt, pkt_train);
return TAILQ_NEXT(pkt, pkt_train);
}
/*
@ -522,17 +487,15 @@ bpacket_next (struct bpacket *pkt)
*
* Adjust all peer_af structures for the given peer.
*/
static inline void
update_group_adjust_peer_afs (struct peer *peer)
static inline void update_group_adjust_peer_afs(struct peer *peer)
{
struct peer_af *paf;
int afidx;
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++)
{
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer->peer_af_array[afidx];
if (paf != NULL)
update_group_adjust_peer (paf);
update_group_adjust_peer(paf);
}
}
@ -541,17 +504,15 @@ update_group_adjust_peer_afs (struct peer *peer)
*
* Remove all peer_af structures for the given peer from their subgroups.
*/
static inline void
update_group_remove_peer_afs (struct peer *peer)
static inline void update_group_remove_peer_afs(struct peer *peer)
{
struct peer_af *paf;
int afidx;
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++)
{
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer->peer_af_array[afidx];
if (paf != NULL)
update_subgroup_remove_peer (PAF_SUBGRP (paf), paf);
update_subgroup_remove_peer(PAF_SUBGRP(paf), paf);
}
}
@ -559,9 +520,9 @@ update_group_remove_peer_afs (struct peer *peer)
* update_subgroup_needs_refresh
*/
static inline int
update_subgroup_needs_refresh (const struct update_subgroup *subgrp)
update_subgroup_needs_refresh(const struct update_subgroup *subgrp)
{
if (CHECK_FLAG (subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH))
if (CHECK_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH))
return 1;
else
return 0;
@ -571,22 +532,22 @@ update_subgroup_needs_refresh (const struct update_subgroup *subgrp)
* update_subgroup_set_needs_refresh
*/
static inline void
update_subgroup_set_needs_refresh (struct update_subgroup *subgrp, int value)
update_subgroup_set_needs_refresh(struct update_subgroup *subgrp, int value)
{
if (value)
SET_FLAG (subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
SET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
else
UNSET_FLAG (subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
UNSET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
}
static inline struct update_subgroup *
peer_subgroup (struct peer *peer, afi_t afi, safi_t safi)
static inline struct update_subgroup *peer_subgroup(struct peer *peer,
afi_t afi, safi_t safi)
{
struct peer_af *paf;
paf = peer_af_find (peer, afi, safi);
paf = peer_af_find(peer, afi, safi);
if (paf)
return PAF_SUBGRP (paf);
return PAF_SUBGRP(paf);
return NULL;
}
@ -595,30 +556,26 @@ peer_subgroup (struct peer *peer, afi_t afi, safi_t safi)
*
* Adjust all peer_af structures for the given peer.
*/
static inline void
bgp_announce_peer (struct peer *peer)
static inline void bgp_announce_peer(struct peer *peer)
{
struct peer_af *paf;
int afidx;
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++)
{
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer->peer_af_array[afidx];
if (paf != NULL)
subgroup_announce_all (PAF_SUBGRP (paf));
subgroup_announce_all(PAF_SUBGRP(paf));
}
}
/**
* advertise_list_is_empty
*/
static inline int
advertise_list_is_empty (struct update_subgroup *subgrp)
static inline int advertise_list_is_empty(struct update_subgroup *subgrp)
{
if (!BGP_ADV_FIFO_EMPTY (&subgrp->sync->update) ||
!BGP_ADV_FIFO_EMPTY (&subgrp->sync->withdraw) ||
!BGP_ADV_FIFO_EMPTY (&subgrp->sync->withdraw_low))
{
if (!BGP_ADV_FIFO_EMPTY(&subgrp->sync->update)
|| !BGP_ADV_FIFO_EMPTY(&subgrp->sync->withdraw)
|| !BGP_ADV_FIFO_EMPTY(&subgrp->sync->withdraw_low)) {
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,8 @@
#if ENABLE_BGP_VNC
typedef enum {
BGP_VNC_SUBTLV_TYPE_LIFETIME=1,
BGP_VNC_SUBTLV_TYPE_RFPOPTION=2, /* deprecated */
BGP_VNC_SUBTLV_TYPE_LIFETIME = 1,
BGP_VNC_SUBTLV_TYPE_RFPOPTION = 2, /* deprecated */
} bgp_vnc_subtlv_types;
/*

View File

@ -30,9 +30,9 @@
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_vpn.h"
int
show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
afi_t afi, safi_t safi, u_char use_json)
int show_adj_route_vpn(struct vty *vty, struct peer *peer,
struct prefix_rd *prd, afi_t afi, safi_t safi,
u_char use_json)
{
struct bgp *bgp;
struct bgp_table *table;
@ -47,16 +47,14 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
json_object *json_routes = NULL;
json_object *json_array = NULL;
bgp = bgp_get_default ();
if (bgp == NULL)
{
bgp = bgp_get_default();
if (bgp == NULL) {
if (!use_json)
vty_out (vty, "No BGP process is configured\n");
vty_out(vty, "No BGP process is configured\n");
return CMD_WARNING;
}
if (use_json)
{
if (use_json) {
json_scode = json_object_new_object();
json_ocode = json_object_new_object();
json_routes = json_object_new_object();
@ -74,14 +72,12 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
json_object_string_add(json_ocode, "incomplete", "?");
}
for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn;
rn = bgp_route_next (rn))
{
if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
rn = bgp_route_next(rn)) {
if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
continue;
if ((table = rn->info) != NULL)
{
if ((table = rn->info) != NULL) {
if (use_json)
json_array = json_object_new_array();
else
@ -89,111 +85,166 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
rd_header = 1;
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
{
if ((attr = rm->info) != NULL)
{
if (header)
{
if (use_json)
{
json_object_int_add(json, "bgpTableVersion", 0);
json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
json_object_object_add(json, "bgpStatusCodes", json_scode);
json_object_object_add(json, "bgpOriginCodes", json_ocode);
}
else
{
vty_out (vty, "BGP table version is 0, local router ID is %s\n",
inet_ntoa(bgp->router_id));
vty_out (vty,
for (rm = bgp_table_top(table); rm;
rm = bgp_route_next(rm)) {
if ((attr = rm->info) != NULL) {
if (header) {
if (use_json) {
json_object_int_add(
json,
"bgpTableVersion",
0);
json_object_string_add(
json,
"bgpLocalRouterId",
inet_ntoa(
bgp->router_id));
json_object_object_add(
json,
"bgpStatusCodes",
json_scode);
json_object_object_add(
json,
"bgpOriginCodes",
json_ocode);
} else {
vty_out(vty,
"BGP table version is 0, local router ID is %s\n",
inet_ntoa(
bgp->router_id));
vty_out(vty,
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
vty_out (vty, V4_HEADER);
vty_out(vty,
"Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
vty_out(vty, V4_HEADER);
}
header = 0;
}
if (rd_header)
{
if (rd_header) {
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip = {0};
#if ENABLE_BGP_VNC
struct rd_vnc_eth rd_vnc_eth = {0};
struct rd_vnc_eth rd_vnc_eth = {
0};
#endif
u_char *pnt;
pnt = rn->p.u.val;
/* Decode RD type. */
type = decode_rd_type (pnt);
type = decode_rd_type(pnt);
/* Decode RD value. */
if (type == RD_TYPE_AS)
decode_rd_as (pnt + 2, &rd_as);
decode_rd_as(pnt + 2,
&rd_as);
else if (type == RD_TYPE_AS4)
decode_rd_as4 (pnt + 2, &rd_as);
decode_rd_as4(pnt + 2,
&rd_as);
else if (type == RD_TYPE_IP)
decode_rd_ip (pnt + 2, &rd_ip);
decode_rd_ip(pnt + 2,
&rd_ip);
#if ENABLE_BGP_VNC
else if (type == RD_TYPE_VNC_ETH)
decode_rd_vnc_eth (pnt, &rd_vnc_eth);
else if (type
== RD_TYPE_VNC_ETH)
decode_rd_vnc_eth(
pnt,
&rd_vnc_eth);
#endif
if (use_json)
{
if (use_json) {
char buffer[BUFSIZ];
if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
json_object_string_add(json_routes, "routeDistinguisher", buffer);
}
else
{
vty_out (vty, "Route Distinguisher: ");
if (type == RD_TYPE_AS
|| type == RD_TYPE_AS4)
sprintf(buffer,
"%u:%d",
rd_as.as,
rd_as.val);
else if (type
== RD_TYPE_IP)
sprintf(buffer,
"%s:%d",
inet_ntoa(
rd_ip.ip),
rd_ip.val);
json_object_string_add(
json_routes,
"routeDistinguisher",
buffer);
} else {
vty_out(vty,
"Route Distinguisher: ");
if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
if (type == RD_TYPE_AS
|| type == RD_TYPE_AS4)
vty_out(vty,
"%u:%d",
rd_as.as,
rd_as.val);
else if (type
== RD_TYPE_IP)
vty_out(vty,
"%s:%d",
inet_ntoa(
rd_ip.ip),
rd_ip.val);
#if ENABLE_BGP_VNC
else if (type == RD_TYPE_VNC_ETH)
vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
rd_vnc_eth.local_nve_id,
rd_vnc_eth.macaddr.octet[0],
rd_vnc_eth.macaddr.octet[1],
rd_vnc_eth.macaddr.octet[2],
rd_vnc_eth.macaddr.octet[3],
rd_vnc_eth.macaddr.octet[4],
rd_vnc_eth.macaddr.octet[5]);
else if (
type
== RD_TYPE_VNC_ETH)
vty_out(vty,
"%u:%02x:%02x:%02x:%02x:%02x:%02x",
rd_vnc_eth
.local_nve_id,
rd_vnc_eth
.macaddr
.octet[0],
rd_vnc_eth
.macaddr
.octet[1],
rd_vnc_eth
.macaddr
.octet[2],
rd_vnc_eth
.macaddr
.octet[3],
rd_vnc_eth
.macaddr
.octet[4],
rd_vnc_eth
.macaddr
.octet[5]);
#endif
vty_out (vty, "\n");
vty_out(vty, "\n");
}
rd_header = 0;
}
route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN, use_json, json_array);
route_vty_out_tmp(vty, &rm->p, attr,
SAFI_MPLS_VPN,
use_json, json_array);
}
}
if (use_json)
{
if (use_json) {
struct prefix *p;
char buf_a[BUFSIZ];
char buf_b[BUFSIZ];
p = &rm->p;
sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
json_object_object_add(json_routes, buf_a, json_array);
sprintf(buf_a, "%s/%d",
inet_ntop(p->family, &p->u.prefix,
buf_b, BUFSIZ),
p->prefixlen);
json_object_object_add(json_routes, buf_a,
json_array);
}
}
}
if (use_json)
{
if (use_json) {
json_object_object_add(json, "routes", json_routes);
vty_out (vty, "%s\n",
json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
}
return CMD_SUCCESS;
}

View File

@ -23,8 +23,8 @@
#include <zebra.h>
extern int
show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
afi_t afi, safi_t safi, u_char use_json);
extern int show_adj_route_vpn(struct vty *vty, struct peer *peer,
struct prefix_rd *prd, afi_t afi, safi_t safi,
u_char use_json);
#endif /* _QUAGGA_BGP_VPN_H */

File diff suppressed because it is too large Load Diff

View File

@ -43,33 +43,31 @@ struct bgp;
"Address Family modifier\n" \
"Address Family modifier\n"
extern void bgp_vty_init (void);
extern const char *afi_safi_print (afi_t, safi_t);
extern const char *afi_safi_json (afi_t, safi_t);
extern int bgp_config_write_update_delay (struct vty *, struct bgp *);
extern void bgp_vty_init(void);
extern const char *afi_safi_print(afi_t, safi_t);
extern const char *afi_safi_json(afi_t, safi_t);
extern int bgp_config_write_update_delay(struct vty *, struct bgp *);
extern int bgp_config_write_wpkt_quanta(struct vty *vty, struct bgp *bgp);
extern int bgp_config_write_listen(struct vty *vty, struct bgp *bgp);
extern int bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp);
extern int bgp_vty_return (struct vty *vty, int ret);
extern struct peer *
peer_and_group_lookup_vty (struct vty *vty, const char *peer_str);
extern int bgp_vty_return(struct vty *vty, int ret);
extern struct peer *peer_and_group_lookup_vty(struct vty *vty,
const char *peer_str);
extern afi_t
bgp_vty_afi_from_str(const char *afi_str);
extern afi_t bgp_vty_afi_from_str(const char *afi_str);
extern safi_t
bgp_vty_safi_from_str(const char *safi_str);
extern safi_t bgp_vty_safi_from_str(const char *safi_str);
extern int
argv_find_and_parse_afi(struct cmd_token **argv, int argc, int *index, afi_t *afi);
extern int argv_find_and_parse_afi(struct cmd_token **argv, int argc,
int *index, afi_t *afi);
extern int
argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index, safi_t *safi);
extern int argv_find_and_parse_safi(struct cmd_token **argv, int argc,
int *index, safi_t *safi);
extern int
bgp_vty_find_and_parse_afi_safi_bgp (struct vty *vty, struct cmd_token **argv, int argc, int *idx,
afi_t *afi, safi_t *safi, struct bgp **bgp);
extern int
bgp_show_summary_vty (struct vty *vty, const char *name,
afi_t afi, safi_t safi, u_char use_json);
extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
struct cmd_token **argv,
int argc, int *idx, afi_t *afi,
safi_t *safi, struct bgp **bgp);
extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
safi_t safi, u_char use_json);
#endif /* _QUAGGA_BGP_VTY_H */

File diff suppressed because it is too large Load Diff

View File

@ -21,40 +21,43 @@
#ifndef _QUAGGA_BGP_ZEBRA_H
#define _QUAGGA_BGP_ZEBRA_H
extern void bgp_zebra_init (struct thread_master *master);
extern void bgp_zebra_destroy (void);
extern int bgp_if_update_all (void);
extern int bgp_config_write_maxpaths (struct vty *, struct bgp *, afi_t,
safi_t, int *);
extern int bgp_config_write_redistribute (struct vty *, struct bgp *, afi_t, safi_t,
extern void bgp_zebra_init(struct thread_master *master);
extern void bgp_zebra_destroy(void);
extern int bgp_if_update_all(void);
extern int bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern void bgp_zebra_announce (struct bgp_node *, struct prefix *,
extern int bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
safi_t, int *);
extern void bgp_zebra_announce(struct bgp_node *, struct prefix *,
struct bgp_info *, 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 *, safi_t);
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
extern void bgp_zebra_withdraw(struct prefix *, struct bgp_info *, safi_t);
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_initiate_radv(struct bgp *bgp, struct peer *peer);
extern void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer);
extern void bgp_zebra_instance_register (struct bgp *);
extern void bgp_zebra_instance_deregister (struct bgp *);
extern void bgp_zebra_instance_register(struct bgp *);
extern void bgp_zebra_instance_deregister(struct bgp *);
extern struct bgp_redist *bgp_redist_lookup (struct bgp *, afi_t, u_char, u_short);
extern struct bgp_redist *bgp_redist_add (struct bgp *, afi_t, u_char, u_short);
extern int bgp_redistribute_set (struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_resend (struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_rmap_set (struct bgp_redist *, const char *);
extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *,
afi_t, int, u_int32_t);
extern int bgp_redistribute_unset (struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_unreg (struct bgp *, afi_t, int, u_short);
extern struct bgp_redist *bgp_redist_lookup(struct bgp *, afi_t, u_char,
u_short);
extern struct bgp_redist *bgp_redist_add(struct bgp *, afi_t, u_char, u_short);
extern int bgp_redistribute_set(struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_resend(struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_rmap_set(struct bgp_redist *, const char *);
extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *, afi_t,
int, u_int32_t);
extern int bgp_redistribute_unset(struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_unreg(struct bgp *, afi_t, int, u_short);
extern struct interface *if_lookup_by_ipv4 (struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv6 (struct in6_addr *, ifindex_t, vrf_id_t);
extern struct interface *if_lookup_by_ipv6_exact (struct in6_addr *, ifindex_t, vrf_id_t);
extern struct interface *if_lookup_by_ipv4(struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv4_exact(struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv6(struct in6_addr *, ifindex_t,
vrf_id_t);
extern struct interface *if_lookup_by_ipv6_exact(struct in6_addr *, ifindex_t,
vrf_id_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_num_connects(void);

File diff suppressed because it is too large Load Diff

View File

@ -45,11 +45,11 @@ struct bpacket;
/*
* Allow the neighbor XXXX remote-as to take internal or external
* AS_SPECIFIED is zero to auto-inherit original non-feature/enhancement behavior
* AS_SPECIFIED is zero to auto-inherit original non-feature/enhancement
* behavior
* in the system.
*/
enum {
AS_UNSPECIFIED = 0,
enum { AS_UNSPECIFIED = 0,
AS_SPECIFIED,
AS_INTERNAL,
AS_EXTERNAL,
@ -60,13 +60,14 @@ typedef u_int32_t as_t;
typedef u_int16_t as16_t; /* we may still encounter 16 Bit asnums */
typedef u_int16_t bgp_size_t;
#define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
#define max(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
enum bgp_af_index
{
enum bgp_af_index {
BGP_AF_START,
BGP_AF_IPV4_UNICAST = BGP_AF_START,
BGP_AF_IPV4_MULTICAST,
@ -82,16 +83,14 @@ enum bgp_af_index
BGP_AF_MAX
};
#define AF_FOREACH(af) \
for ((af) = BGP_AF_START; (af) < BGP_AF_MAX; (af)++)
#define AF_FOREACH(af) for ((af) = BGP_AF_START; (af) < BGP_AF_MAX; (af)++)
#define FOREACH_AFI_SAFI(afi, safi) \
for (afi = AFI_IP; afi < AFI_MAX; afi++) \
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
/* BGP master for system wide configurations and variables. */
struct bgp_master
{
struct bgp_master {
/* BGP instance list. */
struct list *bgp;
@ -126,6 +125,8 @@ struct bgp_master
/* timer to dampen route map changes */
struct thread *t_rmap_update; /* Handle route map updates */
u_int32_t rmap_update_timer; /* Route map update timer */
/* $FRR indent$ */
/* clang-format off */
#define RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */
QOBJ_FIELDS
@ -133,14 +134,12 @@ struct bgp_master
DECLARE_QOBJ_TYPE(bgp_master)
/* BGP route-map structure. */
struct bgp_rmap
{
struct bgp_rmap {
char *name;
struct route_map *map;
};
struct bgp_redist
{
struct bgp_redist {
u_short instance;
/* BGP redistribute metric configuration. */
@ -159,16 +158,14 @@ struct bgp_redist
* The "default" instance is treated separately to simplify the code. Note
* that if deployed in a Multi-VRF environment, it may not exist.
*/
enum bgp_instance_type
{
enum bgp_instance_type {
BGP_INSTANCE_TYPE_DEFAULT,
BGP_INSTANCE_TYPE_VRF,
BGP_INSTANCE_TYPE_VIEW
};
/* BGP instance structure. */
struct bgp
{
struct bgp {
/* AS number of this BGP instance. */
as_t as;
@ -237,17 +234,26 @@ struct bgp
as_t *confed_peers;
int confed_peers_cnt;
struct thread *t_startup; /* start-up timer on only once at the beginning */
struct thread
*t_startup; /* start-up timer on only once at the beginning */
u_int32_t v_maxmed_onstartup; /* Duration of max-med on start-up */
/* $FRR indent$ */
/* clang-format off */
#define BGP_MAXMED_ONSTARTUP_UNCONFIGURED 0 /* 0 means off, its the default */
u_int32_t maxmed_onstartup_value; /* Max-med value when active on start-up */
struct thread *t_maxmed_onstartup; /* non-null when max-med onstartup is on */
u_int32_t maxmed_onstartup_value; /* Max-med value when active on
start-up */
struct thread
*t_maxmed_onstartup; /* non-null when max-med onstartup is on */
u_char maxmed_onstartup_over; /* Flag to make it effective only once */
u_char v_maxmed_admin; /* 1/0 if max-med administrative is on/off */
/* $FRR indent$ */
/* clang-format off */
#define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */
u_int32_t maxmed_admin_value; /* Max-med value when administrative in on */
u_int32_t
maxmed_admin_value; /* Max-med value when administrative in on
*/
#define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */
u_char maxmed_active; /* 1/0 if max-med is active or not */
@ -389,12 +395,12 @@ DECLARE_QOBJ_TYPE(bgp)
#define BGP_ROUTE_ADV_HOLD(bgp) (bgp->main_peers_update_hold)
#define IS_BGP_INST_KNOWN_TO_ZEBRA(bgp) \
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT || \
(bgp->inst_type == BGP_INSTANCE_TYPE_VRF && bgp->vrf_id != VRF_UNKNOWN))
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT \
|| (bgp->inst_type == BGP_INSTANCE_TYPE_VRF \
&& bgp->vrf_id != VRF_UNKNOWN))
/* BGP peer-group support. */
struct peer_group
{
struct peer_group {
/* Name of the peer-group. */
char *name;
@ -412,8 +418,7 @@ struct peer_group
};
/* BGP Notify message format. */
struct bgp_notify
{
struct bgp_notify {
u_char code;
u_char subcode;
char *data;
@ -422,8 +427,7 @@ struct bgp_notify
};
/* Next hop self address. */
struct bgp_nexthop
{
struct bgp_nexthop {
struct interface *ifp;
struct in_addr v4;
struct in6_addr v6_global;
@ -440,8 +444,7 @@ struct bgp_nexthop
/* BGP router distinguisher value. */
#define BGP_RD_SIZE 8
struct bgp_rd
{
struct bgp_rd {
u_char val[BGP_RD_SIZE];
};
@ -452,39 +455,33 @@ struct bgp_rd
#include "filter.h"
/* BGP filter structure. */
struct bgp_filter
{
struct bgp_filter {
/* Distribute-list. */
struct
{
struct {
char *name;
struct access_list *alist;
} dlist[FILTER_MAX];
/* Prefix-list. */
struct
{
struct {
char *name;
struct prefix_list *plist;
} plist[FILTER_MAX];
/* Filter-list. */
struct
{
struct {
char *name;
struct as_list *aslist;
} aslist[FILTER_MAX];
/* Route-map. */
struct
{
struct {
char *name;
struct route_map *map;
} map[RMAP_MAX];
/* Unsuppress-map. */
struct
{
struct {
char *name;
struct route_map *map;
} usmap;
@ -492,8 +489,7 @@ struct bgp_filter
/* IBGP/EBGP identifier. We also have a CONFED peer, which is to say,
a peer who's AS is part of our Confederation. */
typedef enum
{
typedef enum {
BGP_PEER_IBGP = 1,
BGP_PEER_EBGP,
BGP_PEER_INTERNAL,
@ -512,8 +508,7 @@ typedef enum
#define BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS 100
#define BGP_ANNOUNCE_ROUTE_DELAY_MS 500
struct peer_af
{
struct peer_af {
/* back pointer to the peer */
struct peer *peer;
@ -539,8 +534,7 @@ struct peer_af
};
/* BGP neighbor structure. */
struct peer
{
struct peer {
/* BGP structure. */
struct bgp *bgp;
@ -613,6 +607,8 @@ struct peer
unsigned short port; /* Destination port for peer */
char *host; /* Printable address of the peer. */
union sockunion su; /* Sockunion address of the peer. */
/* $FRR indent$ */
/* clang-format off */
#define BGP_PEER_SU_UNSPEC(peer) (peer->su.sa.sa_family == AF_UNSPEC)
time_t uptime; /* Last Up/Down time */
time_t readtime; /* Last read time */
@ -734,8 +730,7 @@ struct peer
char *password;
/* default-originate route-map. */
struct
{
struct {
char *name;
struct route_map *map;
} default_rmap[AFI_MAX][SAFI_MAX];
@ -814,7 +809,8 @@ struct peer
u_int32_t dropped; /* Dropped */
/* Update delay related fields */
u_char update_delay_over; /* When this is set, BGP is no more waiting for EOR */
u_char update_delay_over; /* When this is set, BGP is no more waiting
for EOR */
/* Syncronization list and time. */
struct bgp_synchronize *sync[AFI_MAX][SAFI_MAX];
@ -889,8 +885,8 @@ struct peer
#define PEER_DOWN_BFD_DOWN 24 /* BFD down */
#define PEER_DOWN_IF_DOWN 25 /* Interface down */
#define PEER_DOWN_NBR_ADDR_DEL 26 /* Peer address lost */
unsigned long last_reset_cause_size;
u_char last_reset_cause[BGP_MAX_PACKET_SIZE];
unsigned long last_reset_cause_size;
u_char last_reset_cause[BGP_MAX_PACKET_SIZE];
/* The kind of route-map Flags.*/
u_char rmap_type;
@ -916,16 +912,15 @@ DECLARE_QOBJ_TYPE(peer)
/* Check if suppress start/restart of sessions to peer. */
#define BGP_PEER_START_SUPPRESSED(P) \
(CHECK_FLAG ((P)->flags, PEER_FLAG_SHUTDOWN) \
|| CHECK_FLAG ((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW))
(CHECK_FLAG((P)->flags, PEER_FLAG_SHUTDOWN) \
|| CHECK_FLAG((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW))
#define PEER_PASSWORD_MINLEN (1)
#define PEER_PASSWORD_MAXLEN (80)
/* This structure's member directly points incoming packet data
stream. */
struct bgp_nlri
{
struct bgp_nlri {
/* AFI. */
afi_t afi;
@ -1115,8 +1110,7 @@ struct bgp_nlri
#define BGP_DYNAMIC_NEIGHBORS_LIMIT_MAX 5000
/* Flag for peer_clear_soft(). */
enum bgp_clear_type
{
enum bgp_clear_type {
BGP_CLEAR_SOFT_NONE,
BGP_CLEAR_SOFT_OUT,
BGP_CLEAR_SOFT_IN,
@ -1127,7 +1121,7 @@ enum bgp_clear_type
/* Macros. */
#define BGP_INPUT(P) ((P)->ibuf)
#define BGP_INPUT_PNT(P) (STREAM_PNT(BGP_INPUT(P)))
#define BGP_IS_VALID_STATE_FOR_NOTIF(S)\
#define BGP_IS_VALID_STATE_FOR_NOTIF(S) \
(((S) == OpenSent) || ((S) == OpenConfirm) || ((S) == Established))
/* BGP error codes. */
@ -1171,8 +1165,7 @@ enum bgp_clear_type
/*
* Enumeration of different policy kinds a peer can be configured with.
*/
typedef enum
{
typedef enum {
BGP_POLICY_ROUTE_MAP,
BGP_POLICY_FILTER_LIST,
BGP_POLICY_PREFIX_LIST,
@ -1183,32 +1176,34 @@ extern struct bgp_master *bm;
extern unsigned int multipath_num;
/* Prototypes. */
extern void bgp_terminate (void);
extern void bgp_reset (void);
extern time_t bgp_clock (void);
extern void bgp_zclient_reset (void);
extern int bgp_nexthop_set (union sockunion *, union sockunion *,
extern void bgp_terminate(void);
extern void bgp_reset(void);
extern time_t bgp_clock(void);
extern void bgp_zclient_reset(void);
extern int bgp_nexthop_set(union sockunion *, union sockunion *,
struct bgp_nexthop *, struct peer *);
extern struct bgp *bgp_get_default (void);
extern struct bgp *bgp_lookup (as_t, const char *);
extern struct bgp *bgp_lookup_by_name (const char *);
extern struct bgp *bgp_lookup_by_vrf_id (vrf_id_t);
extern struct peer *peer_lookup (struct bgp *, union sockunion *);
extern struct peer *peer_lookup_by_conf_if (struct bgp *, const char *);
extern struct bgp *bgp_get_default(void);
extern struct bgp *bgp_lookup(as_t, const char *);
extern struct bgp *bgp_lookup_by_name(const char *);
extern struct bgp *bgp_lookup_by_vrf_id(vrf_id_t);
extern struct peer *peer_lookup(struct bgp *, union sockunion *);
extern struct peer *peer_lookup_by_conf_if(struct bgp *, const char *);
extern struct peer *peer_lookup_by_hostname(struct bgp *, const char *);
extern void bgp_peer_conf_if_to_su_update (struct peer *);
extern void bgp_peer_conf_if_to_su_update(struct peer *);
extern int peer_group_listen_range_del(struct peer_group *, struct prefix *);
extern struct peer_group *peer_group_lookup (struct bgp *, const char *);
extern struct peer_group *peer_group_get (struct bgp *, const char *);
extern struct peer *peer_create_bind_dynamic_neighbor (struct bgp *,
union sockunion *, struct peer_group *);
extern struct prefix *peer_group_lookup_dynamic_neighbor_range (
struct peer_group *, struct prefix *);
extern struct peer_group *peer_group_lookup_dynamic_neighbor (struct bgp *,
struct prefix *, struct prefix **);
extern struct peer *peer_lookup_dynamic_neighbor (struct bgp *,
extern struct peer_group *peer_group_lookup(struct bgp *, const char *);
extern struct peer_group *peer_group_get(struct bgp *, const char *);
extern struct peer *peer_create_bind_dynamic_neighbor(struct bgp *,
union sockunion *,
struct peer_group *);
extern struct prefix *
peer_group_lookup_dynamic_neighbor_range(struct peer_group *, struct prefix *);
extern struct peer_group *peer_group_lookup_dynamic_neighbor(struct bgp *,
struct prefix *,
struct prefix **);
extern struct peer *peer_lookup_dynamic_neighbor(struct bgp *,
union sockunion *);
extern void peer_drop_dynamic_neighbor (struct peer *);
extern void peer_drop_dynamic_neighbor(struct peer *);
/*
* Peers are incredibly easy to memory leak
@ -1220,187 +1215,188 @@ extern struct peer *peer_unlock_with_caller(const char *, struct peer *);
#define peer_unlock(A) peer_unlock_with_caller(__FUNCTION__, (A))
#define peer_lock(B) peer_lock_with_caller(__FUNCTION__, (B))
extern bgp_peer_sort_t peer_sort (struct peer *peer);
extern int peer_active (struct peer *);
extern int peer_active_nego (struct peer *);
extern void bgp_recalculate_all_bestpaths (struct bgp *bgp);
extern bgp_peer_sort_t peer_sort(struct peer *peer);
extern int peer_active(struct peer *);
extern int peer_active_nego(struct peer *);
extern void bgp_recalculate_all_bestpaths(struct bgp *bgp);
extern struct peer *peer_create(union sockunion *, const char *, struct bgp *,
as_t, as_t, int, afi_t, safi_t, struct peer_group *);
extern struct peer *peer_create_accept (struct bgp *);
extern void peer_xfer_config (struct peer *dst, struct peer *src);
extern char *peer_uptime (time_t, char *, size_t, u_char, json_object *);
as_t, as_t, int, afi_t, safi_t,
struct peer_group *);
extern struct peer *peer_create_accept(struct bgp *);
extern void peer_xfer_config(struct peer *dst, struct peer *src);
extern char *peer_uptime(time_t, char *, size_t, u_char, json_object *);
extern int bgp_config_write (struct vty *);
extern void bgp_config_write_family_header (struct vty *, afi_t, safi_t, int *);
extern int bgp_config_write(struct vty *);
extern void bgp_config_write_family_header(struct vty *, afi_t, safi_t, int *);
extern void bgp_master_init (struct thread_master *master);
extern void bgp_master_init(struct thread_master *master);
extern void bgp_init (void);
extern void bgp_route_map_init (void);
extern void bgp_session_reset (struct peer *);
extern void bgp_init(void);
extern void bgp_route_map_init(void);
extern void bgp_session_reset(struct peer *);
extern int bgp_option_set (int);
extern int bgp_option_unset (int);
extern int bgp_option_check (int);
extern int bgp_option_set(int);
extern int bgp_option_unset(int);
extern int bgp_option_check(int);
extern int bgp_get (struct bgp **, as_t *, const char *, enum bgp_instance_type);
extern void bgp_instance_up (struct bgp *);
extern void bgp_instance_down (struct bgp *);
extern int bgp_delete (struct bgp *);
extern int bgp_get(struct bgp **, as_t *, const char *, enum bgp_instance_type);
extern void bgp_instance_up(struct bgp *);
extern void bgp_instance_down(struct bgp *);
extern int bgp_delete(struct bgp *);
extern int bgp_flag_set (struct bgp *, int);
extern int bgp_flag_unset (struct bgp *, int);
extern int bgp_flag_check (struct bgp *, int);
extern int bgp_flag_set(struct bgp *, int);
extern int bgp_flag_unset(struct bgp *, int);
extern int bgp_flag_check(struct bgp *, int);
extern void bgp_lock (struct bgp *);
extern void bgp_unlock (struct bgp *);
extern void bgp_lock(struct bgp *);
extern void bgp_unlock(struct bgp *);
extern void bgp_router_id_zebra_bump (vrf_id_t, const struct prefix*);
extern int bgp_router_id_static_set (struct bgp *, struct in_addr);
extern void bgp_router_id_zebra_bump(vrf_id_t, const struct prefix *);
extern int bgp_router_id_static_set(struct bgp *, struct in_addr);
extern int bgp_cluster_id_set (struct bgp *, struct in_addr *);
extern int bgp_cluster_id_unset (struct bgp *);
extern int bgp_cluster_id_set(struct bgp *, struct in_addr *);
extern int bgp_cluster_id_unset(struct bgp *);
extern int bgp_confederation_id_set (struct bgp *, as_t);
extern int bgp_confederation_id_unset (struct bgp *);
extern int bgp_confederation_peers_check (struct bgp *, as_t);
extern int bgp_confederation_id_set(struct bgp *, as_t);
extern int bgp_confederation_id_unset(struct bgp *);
extern int bgp_confederation_peers_check(struct bgp *, as_t);
extern int bgp_confederation_peers_add (struct bgp *, as_t);
extern int bgp_confederation_peers_remove (struct bgp *, as_t);
extern int bgp_confederation_peers_add(struct bgp *, as_t);
extern int bgp_confederation_peers_remove(struct bgp *, as_t);
extern int bgp_timers_set (struct bgp *, u_int32_t keepalive, u_int32_t holdtime);
extern int bgp_timers_unset (struct bgp *);
extern int bgp_timers_set(struct bgp *, u_int32_t keepalive,
u_int32_t holdtime);
extern int bgp_timers_unset(struct bgp *);
extern int bgp_default_local_preference_set (struct bgp *, u_int32_t);
extern int bgp_default_local_preference_unset (struct bgp *);
extern int bgp_default_local_preference_set(struct bgp *, u_int32_t);
extern int bgp_default_local_preference_unset(struct bgp *);
extern int bgp_default_subgroup_pkt_queue_max_set (struct bgp *bgp, u_int32_t);
extern int bgp_default_subgroup_pkt_queue_max_unset (struct bgp *bgp);
extern int bgp_default_subgroup_pkt_queue_max_set(struct bgp *bgp, u_int32_t);
extern int bgp_default_subgroup_pkt_queue_max_unset(struct bgp *bgp);
extern int bgp_listen_limit_set (struct bgp *, int);
extern int bgp_listen_limit_unset (struct bgp *);
extern int bgp_listen_limit_set(struct bgp *, int);
extern int bgp_listen_limit_unset(struct bgp *);
extern int bgp_update_delay_active (struct bgp *);
extern int bgp_update_delay_configured (struct bgp *);
extern void peer_as_change (struct peer *, as_t, int);
extern int peer_remote_as (struct bgp *, union sockunion *,const char *, as_t *,
extern int bgp_update_delay_active(struct bgp *);
extern int bgp_update_delay_configured(struct bgp *);
extern void peer_as_change(struct peer *, as_t, int);
extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *,
int, afi_t, safi_t);
extern int peer_group_remote_as (struct bgp *, const char *, as_t *, int);
extern int peer_delete (struct peer *peer);
extern int peer_group_delete (struct peer_group *);
extern int peer_group_remote_as_delete (struct peer_group *);
extern int peer_group_remote_as(struct bgp *, const char *, as_t *, int);
extern int peer_delete(struct peer *peer);
extern int peer_group_delete(struct peer_group *);
extern int peer_group_remote_as_delete(struct peer_group *);
extern int peer_group_listen_range_add(struct peer_group *, struct prefix *);
extern int peer_activate (struct peer *, afi_t, safi_t);
extern int peer_deactivate (struct peer *, afi_t, safi_t);
extern int peer_afc_set (struct peer *, afi_t, safi_t, int);
extern int peer_activate(struct peer *, afi_t, safi_t);
extern int peer_deactivate(struct peer *, afi_t, safi_t);
extern int peer_afc_set(struct peer *, afi_t, safi_t, int);
extern int peer_group_bind (struct bgp *, union sockunion *, struct peer *,
extern int peer_group_bind(struct bgp *, union sockunion *, struct peer *,
struct peer_group *, as_t *);
extern int peer_group_unbind (struct bgp *, struct peer *, struct peer_group *);
extern int peer_group_unbind(struct bgp *, struct peer *, struct peer_group *);
extern int peer_flag_set (struct peer *, u_int32_t);
extern int peer_flag_unset (struct peer *, u_int32_t);
extern int peer_flag_set(struct peer *, u_int32_t);
extern int peer_flag_unset(struct peer *, u_int32_t);
extern int peer_af_flag_set (struct peer *, afi_t, safi_t, u_int32_t);
extern int peer_af_flag_unset (struct peer *, afi_t, safi_t, u_int32_t);
extern int peer_af_flag_check (struct peer *, afi_t, safi_t, u_int32_t);
extern int peer_af_flag_set(struct peer *, afi_t, safi_t, u_int32_t);
extern int peer_af_flag_unset(struct peer *, afi_t, safi_t, u_int32_t);
extern int peer_af_flag_check(struct peer *, afi_t, safi_t, u_int32_t);
extern int peer_ebgp_multihop_set (struct peer *, int);
extern int peer_ebgp_multihop_unset (struct peer *);
extern int is_ebgp_multihop_configured (struct peer *peer);
extern int peer_ebgp_multihop_set(struct peer *, int);
extern int peer_ebgp_multihop_unset(struct peer *);
extern int is_ebgp_multihop_configured(struct peer *peer);
extern int peer_description_set (struct peer *, const char *);
extern int peer_description_unset (struct peer *);
extern int peer_description_set(struct peer *, const char *);
extern int peer_description_unset(struct peer *);
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_unset (struct peer *);
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_unset(struct peer *);
extern int peer_default_originate_set (struct peer *, afi_t, safi_t, const char *);
extern int peer_default_originate_unset (struct peer *, afi_t, safi_t);
extern int peer_default_originate_set(struct peer *, afi_t, safi_t,
const char *);
extern int peer_default_originate_unset(struct peer *, afi_t, safi_t);
extern int peer_port_set (struct peer *, u_int16_t);
extern int peer_port_unset (struct peer *);
extern int peer_port_set(struct peer *, u_int16_t);
extern int peer_port_unset(struct peer *);
extern int peer_weight_set (struct peer *, afi_t, safi_t, u_int16_t);
extern int peer_weight_unset (struct peer *, afi_t, safi_t);
extern int peer_weight_set(struct peer *, afi_t, safi_t, u_int16_t);
extern int peer_weight_unset(struct peer *, afi_t, safi_t);
extern int peer_timers_set (struct peer *, u_int32_t keepalive, u_int32_t holdtime);
extern int peer_timers_unset (struct peer *);
extern int peer_timers_set(struct peer *, u_int32_t keepalive,
u_int32_t holdtime);
extern int peer_timers_unset(struct peer *);
extern int peer_timers_connect_set (struct peer *, u_int32_t);
extern int peer_timers_connect_unset (struct peer *);
extern int peer_timers_connect_set(struct peer *, u_int32_t);
extern int peer_timers_connect_unset(struct peer *);
extern int peer_advertise_interval_set (struct peer *, u_int32_t);
extern int peer_advertise_interval_unset (struct peer *);
extern int peer_advertise_interval_set(struct peer *, u_int32_t);
extern int peer_advertise_interval_unset(struct peer *);
extern void peer_interface_set (struct peer *, const char *);
extern void peer_interface_unset (struct peer *);
extern void peer_interface_set(struct peer *, const char *);
extern void peer_interface_unset(struct peer *);
extern int peer_distribute_set (struct peer *, afi_t, safi_t, int, const char *);
extern int peer_distribute_unset (struct peer *, afi_t, safi_t, int);
extern int peer_distribute_set(struct peer *, afi_t, safi_t, int, const char *);
extern int peer_distribute_unset(struct peer *, afi_t, safi_t, int);
extern int peer_allowas_in_set (struct peer *, afi_t, safi_t, int, int);
extern int peer_allowas_in_unset (struct peer *, afi_t, safi_t);
extern int peer_allowas_in_set(struct peer *, afi_t, safi_t, int, int);
extern int peer_allowas_in_unset(struct peer *, afi_t, safi_t);
extern int peer_local_as_set (struct peer *, as_t, int, int);
extern int peer_local_as_unset (struct peer *);
extern int peer_local_as_set(struct peer *, as_t, int, int);
extern int peer_local_as_unset(struct peer *);
extern int peer_prefix_list_set (struct peer *, afi_t, safi_t, int, const char *);
extern int peer_prefix_list_unset (struct peer *, afi_t, safi_t, int);
extern int peer_prefix_list_set(struct peer *, afi_t, safi_t, int,
const char *);
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_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_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_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_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 *, afi_t, safi_t, const char *);
extern int peer_password_set (struct peer *, const char *);
extern int peer_password_unset (struct peer *);
extern int peer_password_set(struct peer *, const char *);
extern int peer_password_unset(struct peer *);
extern int peer_unsuppress_map_unset (struct peer *, afi_t, safi_t);
extern int peer_unsuppress_map_unset(struct peer *, afi_t, safi_t);
extern int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, u_char, int, u_int16_t);
extern int peer_maximum_prefix_unset (struct peer *, afi_t, safi_t);
extern int peer_maximum_prefix_set(struct peer *, afi_t, safi_t, u_int32_t,
u_char, int, u_int16_t);
extern int peer_maximum_prefix_unset(struct peer *, afi_t, safi_t);
extern int peer_clear (struct peer *, struct listnode **);
extern int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type);
extern int peer_clear(struct peer *, struct listnode **);
extern int peer_clear_soft(struct peer *, afi_t, safi_t, enum bgp_clear_type);
extern int peer_ttl_security_hops_set (struct peer *, int);
extern int peer_ttl_security_hops_unset (struct peer *);
extern int peer_ttl_security_hops_set(struct peer *, int);
extern int peer_ttl_security_hops_unset(struct peer *);
extern int peer_tx_shutdown_message_set (struct peer *, const char *msg);
extern int peer_tx_shutdown_message_unset (struct peer *);
extern int peer_tx_shutdown_message_set(struct peer *, const char *msg);
extern int peer_tx_shutdown_message_unset(struct peer *);
extern int bgp_route_map_update_timer (struct thread *thread);
extern int bgp_route_map_update_timer(struct thread *thread);
extern void bgp_route_map_terminate(void);
extern int peer_cmp (struct peer *p1, struct peer *p2);
extern int peer_cmp(struct peer *p1, struct peer *p2);
extern int
bgp_map_afi_safi_iana2int (iana_afi_t pkt_afi, safi_t pkt_safi,
extern int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, safi_t pkt_safi,
afi_t *afi, safi_t *safi);
extern int
bgp_map_afi_safi_int2iana (afi_t afi, safi_t safi,
extern int bgp_map_afi_safi_int2iana(afi_t afi, safi_t safi,
iana_afi_t *pkt_afi, safi_t *pkt_safi);
extern struct peer_af * peer_af_create (struct peer *, afi_t, safi_t);
extern struct peer_af * peer_af_find (struct peer *, afi_t, safi_t);
extern int peer_af_delete (struct peer *, afi_t, safi_t);
extern struct peer_af *peer_af_create(struct peer *, afi_t, safi_t);
extern struct peer_af *peer_af_find(struct peer *, afi_t, safi_t);
extern int peer_af_delete(struct peer *, afi_t, safi_t);
extern void bgp_close(void);
static inline int
afindex (afi_t afi, safi_t safi)
static inline int afindex(afi_t afi, safi_t safi)
{
switch (afi)
{
switch (afi) {
case AFI_IP:
switch (safi)
{
switch (safi) {
case SAFI_UNICAST:
return BGP_AF_IPV4_UNICAST;
break;
@ -1422,8 +1418,7 @@ afindex (afi_t afi, safi_t safi)
}
break;
case AFI_IP6:
switch (safi)
{
switch (safi) {
case SAFI_UNICAST:
return BGP_AF_IPV6_UNICAST;
break;
@ -1445,8 +1440,7 @@ afindex (afi_t afi, safi_t safi)
}
break;
case AFI_L2VPN:
switch (safi)
{
switch (safi) {
case SAFI_EVPN:
return BGP_AF_L2VPN_EVPN;
break;
@ -1461,17 +1455,15 @@ afindex (afi_t afi, safi_t safi)
}
/* If the peer is not a peer-group but is bound to a peer-group return 1 */
static inline int
peer_group_active (struct peer *peer)
static inline int peer_group_active(struct peer *peer)
{
if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) && peer->group)
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) && peer->group)
return 1;
return 0;
}
/* If peer is negotiated at least one address family return 1. */
static inline int
peer_afi_active_nego (const struct peer *peer, afi_t afi)
static inline int peer_afi_active_nego(const struct peer *peer, afi_t afi)
{
if (peer->afc_nego[afi][SAFI_UNICAST]
|| peer->afc_nego[afi][SAFI_MULTICAST]
@ -1484,64 +1476,55 @@ peer_afi_active_nego (const struct peer *peer, afi_t afi)
}
/* If at least one address family activated for group, return 1. */
static inline int
peer_group_af_configured (struct peer_group *group)
static inline int peer_group_af_configured(struct peer_group *group)
{
struct peer *peer = group->conf;
if (peer->afc[AFI_IP][SAFI_UNICAST]
|| peer->afc[AFI_IP][SAFI_MULTICAST]
if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
|| peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP][SAFI_ENCAP]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
|| peer->afc[AFI_IP6][SAFI_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MULTICAST]
|| peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP6][SAFI_ENCAP]
|| peer->afc[AFI_IP6][SAFI_EVPN])
|| peer->afc[AFI_IP6][SAFI_ENCAP] || peer->afc[AFI_IP6][SAFI_EVPN])
return 1;
return 0;
}
static inline char *
timestamp_string (time_t ts)
static inline char *timestamp_string(time_t ts)
{
time_t tbuf;
tbuf = time(NULL) - (bgp_clock() - ts);
return ctime(&tbuf);
}
static inline int
peer_established (struct peer *peer)
static inline int peer_established(struct peer *peer)
{
if (peer->status == Established)
return 1;
return 0;
}
static inline int
peer_dynamic_neighbor (struct peer *peer)
static inline int peer_dynamic_neighbor(struct peer *peer)
{
return (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR)) ? 1 : 0;
}
static inline int
peer_cap_enhe (struct peer *peer, afi_t afi, safi_t safi)
static inline int peer_cap_enhe(struct peer *peer, afi_t afi, safi_t safi)
{
return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_NEGO));
}
/* Lookup VRF for BGP instance based on its type. */
static inline struct vrf *
bgp_vrf_lookup_by_instance_type (struct bgp *bgp)
static inline struct vrf *bgp_vrf_lookup_by_instance_type(struct bgp *bgp)
{
struct vrf *vrf;
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
vrf = vrf_lookup_by_id (VRF_DEFAULT);
vrf = vrf_lookup_by_id(VRF_DEFAULT);
else if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
vrf = vrf_lookup_by_name (bgp->name);
vrf = vrf_lookup_by_name(bgp->name);
else
vrf = NULL;
@ -1549,32 +1532,28 @@ bgp_vrf_lookup_by_instance_type (struct bgp *bgp)
}
/* Link BGP instance to VRF. */
static inline void
bgp_vrf_link (struct bgp *bgp, struct vrf *vrf)
static inline void bgp_vrf_link(struct bgp *bgp, struct vrf *vrf)
{
bgp->vrf_id = vrf->vrf_id;
if (vrf->info != (void *)bgp)
{
bgp_lock (bgp);
if (vrf->info != (void *)bgp) {
bgp_lock(bgp);
vrf->info = (void *)bgp;
}
}
/* Unlink BGP instance from VRF. */
static inline void
bgp_vrf_unlink (struct bgp *bgp, struct vrf *vrf)
static inline void bgp_vrf_unlink(struct bgp *bgp, struct vrf *vrf)
{
if (vrf->info == (void *)bgp)
{
if (vrf->info == (void *)bgp) {
vrf->info = NULL;
bgp_unlock (bgp);
bgp_unlock(bgp);
}
bgp->vrf_id = VRF_UNKNOWN;
}
extern void bgp_update_redist_vrf_bitmaps (struct bgp*, vrf_id_t);
extern void bgp_update_redist_vrf_bitmaps(struct bgp *, vrf_id_t);
/* For benefit of rfapi */
extern struct peer * peer_new (struct bgp *bgp);
extern struct peer *peer_new(struct bgp *bgp);
#endif /* _QUAGGA_BGPD_H */

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,7 @@
#if ENABLE_BGP_VNC
#include "rfapi.h"
struct rfapi_l2_group_cfg
{
struct rfapi_l2_group_cfg {
char *name;
uint32_t logical_net_id;
struct list *labels; /* list of uint32_t */
@ -40,16 +39,14 @@ struct rfapi_l2_group_cfg
};
DECLARE_QOBJ_TYPE(rfapi_l2_group_cfg)
typedef enum
{
typedef enum {
RFAPI_GROUP_CFG_NVE = 1,
RFAPI_GROUP_CFG_VRF,
RFAPI_GROUP_CFG_L2,
RFAPI_GROUP_CFG_MAX
} rfapi_group_cfg_type_t;
struct rfapi_nve_group_cfg
{
struct rfapi_nve_group_cfg {
struct route_node *vn_node; /* backref */
struct route_node *un_node; /* backref */
@ -115,21 +112,18 @@ struct rfapi_nve_group_cfg
};
DECLARE_QOBJ_TYPE(rfapi_nve_group_cfg)
struct rfapi_rfg_name
{
struct rfapi_rfg_name {
struct rfapi_nve_group_cfg *rfg;
char *name;
};
typedef enum
{
typedef enum {
VNC_REDIST_MODE_PLAIN = 0, /* 0 = default */
VNC_REDIST_MODE_RFG,
VNC_REDIST_MODE_RESOLVE_NVE
} vnc_redist_mode_t;
struct rfapi_cfg
{
struct rfapi_cfg {
struct prefix_rd default_rd;
uint8_t default_l2rd;
struct ecommunity *default_rt_import_list;
@ -169,7 +163,8 @@ struct rfapi_cfg
/*
* List of NVE groups on whose behalf we will export VNC
* routes to zebra. ((NB: it's actually a list of <struct rfapi_rfg_name>)
* routes to zebra. ((NB: it's actually a list of <struct
* rfapi_rfg_name>)
* This list is used when BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS is
* BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP
*/
@ -245,96 +240,74 @@ struct rfapi_cfg
/* Default to updated-responses off */
/* Default to removal-responses off */
#define BGP_VNC_CONFIG_FLAGS_DEFAULT \
(BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP |\
BGP_VNC_CONFIG_CALLBACK_DISABLE |\
BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)
(BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP | BGP_VNC_CONFIG_CALLBACK_DISABLE \
| BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)
struct rfapi_rfp_cfg rfp_cfg; /* rfp related configuration */
};
#define VNC_EXPORT_ZEBRA_GRP_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP)
#define VNC_EXPORT_ZEBRA_RH_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH)
#define VNC_EXPORT_BGP_GRP_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP)
#define VNC_EXPORT_BGP_RH_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH)
#define VNC_EXPORT_BGP_CE_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE)
void
bgp_rfapi_cfg_init (void);
void bgp_rfapi_cfg_init(void);
struct rfapi_cfg *
bgp_rfapi_cfg_new (struct rfapi_rfp_cfg *cfg);
struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg);
void
bgp_rfapi_cfg_destroy (struct bgp *bgp, struct rfapi_cfg *h);
void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h);
int
bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp);
int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp);
extern int
bgp_rfapi_is_vnc_configured (struct bgp *bgp);
extern int bgp_rfapi_is_vnc_configured(struct bgp *bgp);
extern void
nve_group_to_nve_list (
struct rfapi_nve_group_cfg *rfg,
extern void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg,
struct list **nves,
uint8_t family); /* AF_INET, AF_INET6 */
struct rfapi_nve_group_cfg *
bgp_rfapi_cfg_match_group (
struct rfapi_cfg *hc,
struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
struct prefix *vn,
struct prefix *un);
struct rfapi_nve_group_cfg *
bgp_rfapi_cfg_match_byname (
struct bgp *bgp,
const char *name,
bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name,
rfapi_group_cfg_type_t type); /* _MAX = any */
extern void
vnc_prefix_list_update (struct bgp *bgp);
extern void vnc_prefix_list_update(struct bgp *bgp);
extern void
vnc_routemap_update (struct bgp *bgp, const char *unused);
extern void vnc_routemap_update(struct bgp *bgp, const char *unused);
extern void
bgp_rfapi_show_summary (struct bgp *bgp, struct vty *vty);
extern void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty);
extern struct rfapi_cfg *
bgp_rfapi_get_config (struct bgp *bgp);
extern struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp);
extern struct rfapi_l2_group_cfg *
bgp_rfapi_get_group_by_lni_label (
struct bgp *bgp,
uint32_t logical_net_id,
bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id,
uint32_t label);
extern struct ecommunity *
bgp_rfapi_get_ecommunity_by_lni_label (
struct bgp *bgp,
uint32_t is_import,
bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import,
uint32_t logical_net_id,
uint32_t label); /* note, 20bit label! */
extern struct list *
bgp_rfapi_get_labellist_by_lni_label (
struct bgp *bgp,
uint32_t logical_net_id,
bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp, uint32_t logical_net_id,
uint32_t label); /* note, 20bit label! */
#endif /* ENABLE_BGP_VNC */

File diff suppressed because it is too large Load Diff

View File

@ -32,43 +32,38 @@
#include "bgpd/bgp_encap_types.h"
/* probably ought to have a field-specific define in config.h */
# ifndef s6_addr32 /* for solaris/bsd */
# ifdef SOLARIS_IPV6
#ifndef s6_addr32 /* for solaris/bsd */
#ifdef SOLARIS_IPV6
# define s6_addr32 _S6_un._S6_u32
# else
#else
# define s6_addr32 __u6_addr.__u6_addr32
# endif
# endif
#endif
#endif
#define RFAPI_V4_ADDR 0x04
#define RFAPI_V6_ADDR 0x06
#define RFAPI_SHOW_STR "VNC information\n"
struct rfapi_ip_addr
{
struct rfapi_ip_addr {
uint8_t addr_family; /* AF_INET | AF_INET6 */
union
{
union {
struct in_addr v4; /* in network order */
struct in6_addr v6; /* in network order */
} addr;
};
struct rfapi_ip_prefix
{
struct rfapi_ip_prefix {
uint8_t length;
uint8_t cost; /* bgp local pref = 255 - cost */
struct rfapi_ip_addr prefix;
};
struct rfapi_nexthop
{
struct rfapi_nexthop {
struct prefix addr;
uint8_t cost;
};
struct rfapi_next_hop_entry
{
struct rfapi_next_hop_entry {
struct rfapi_next_hop_entry *next;
struct rfapi_ip_prefix prefix;
uint32_t lifetime;
@ -81,8 +76,7 @@ struct rfapi_next_hop_entry
#define RFAPI_REMOVE_RESPONSE_LIFETIME 0
#define RFAPI_INFINITE_LIFETIME 0xFFFFFFFF
struct rfapi_l2address_option
{
struct rfapi_l2address_option {
struct ethaddr macaddr; /* use 0 to assign label to IP prefix */
uint32_t label; /* 20bit label in low bits, no TC, S, or TTL */
uint32_t logical_net_id; /* ~= EVPN Ethernet Segment Id,
@ -91,24 +85,24 @@ struct rfapi_l2address_option
uint16_t tag_id; /* EVPN Ethernet Tag ID, 0 = none */
};
typedef enum
{
typedef enum {
RFAPI_UN_OPTION_TYPE_PROVISIONAL, /* internal use only */
RFAPI_UN_OPTION_TYPE_TUNNELTYPE,
} rfapi_un_option_type;
struct rfapi_tunneltype_option
{
struct rfapi_tunneltype_option {
bgp_encap_types type;
union
{
union {
struct bgp_encap_type_reserved reserved;
struct bgp_encap_type_l2tpv3_over_ip l2tpv3_ip;
struct bgp_encap_type_gre gre;
struct bgp_encap_type_transmit_tunnel_endpoint transmit_tunnel_endpoint;
struct bgp_encap_type_transmit_tunnel_endpoint
transmit_tunnel_endpoint;
struct bgp_encap_type_ipsec_in_tunnel_mode ipsec_tunnel;
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode ip_ipsec;
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode mpls_ipsec;
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode
ip_ipsec;
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode
mpls_ipsec;
struct bgp_encap_type_ip_in_ip ip_ip;
struct bgp_encap_type_vxlan vxlan;
struct bgp_encap_type_nvgre nvgre;
@ -120,31 +114,27 @@ struct rfapi_tunneltype_option
} bgpinfo;
};
struct rfapi_un_option
{
struct rfapi_un_option {
struct rfapi_un_option *next;
rfapi_un_option_type type;
union
{
union {
struct rfapi_tunneltype_option tunnel;
} v;
};
typedef enum
{
RFAPI_VN_OPTION_TYPE_L2ADDR = 3, /* Layer 2 address, 3 for legacy compatibility */
typedef enum {
RFAPI_VN_OPTION_TYPE_L2ADDR =
3, /* Layer 2 address, 3 for legacy compatibility */
RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP, /* for static routes */
RFAPI_VN_OPTION_TYPE_INTERNAL_RD, /* internal use only */
} rfapi_vn_option_type;
struct rfapi_vn_option
{
struct rfapi_vn_option {
struct rfapi_vn_option *next;
rfapi_vn_option_type type;
union
{
union {
struct rfapi_l2address_option l2addr;
/*
@ -160,8 +150,7 @@ struct rfapi_vn_option
} v;
};
struct rfapi_l2address_option_match
{
struct rfapi_l2address_option_match {
struct rfapi_l2address_option o;
uint32_t flags;
@ -211,7 +200,7 @@ typedef void *rfapi_handle;
* rfapi_open()
*
*------------------------------------------*/
typedef void (rfapi_response_cb_t) (struct rfapi_next_hop_entry * next_hops,
typedef void(rfapi_response_cb_t)(struct rfapi_next_hop_entry *next_hops,
void *userdata);
/*------------------------------------------
@ -228,7 +217,7 @@ typedef void (rfapi_response_cb_t) (struct rfapi_next_hop_entry * next_hops,
* ESTALE handle invalidated by configuration change
*
*------------------------------------------*/
typedef void (rfapi_nve_close_cb_t) (rfapi_handle pHandle, int reason);
typedef void(rfapi_nve_close_cb_t)(rfapi_handle pHandle, int reason);
/*------------------------------------------
* rfp_cfg_write_cb_t (callback typedef)
@ -247,7 +236,7 @@ typedef void (rfapi_nve_close_cb_t) (rfapi_handle pHandle, int reason);
* return value:
* lines written
--------------------------------------------*/
typedef int (rfp_cfg_write_cb_t) (struct vty * vty, void *rfp_start_val);
typedef int(rfp_cfg_write_cb_t)(struct vty *vty, void *rfp_start_val);
/*------------------------------------------
* rfp_cfg_group_write_cb_t (callback typedef)
@ -269,31 +258,26 @@ typedef int (rfp_cfg_write_cb_t) (struct vty * vty, void *rfp_start_val);
* return value:
* lines written
--------------------------------------------*/
typedef enum
{
typedef enum {
RFAPI_RFP_CFG_GROUP_DEFAULT,
RFAPI_RFP_CFG_GROUP_NVE,
RFAPI_RFP_CFG_GROUP_L2
} rfapi_rfp_cfg_group_type;
typedef int (rfp_cfg_group_write_cb_t) (struct vty * vty,
void *rfp_start_val,
typedef int(rfp_cfg_group_write_cb_t)(struct vty *vty, void *rfp_start_val,
rfapi_rfp_cfg_group_type type,
const char *name,
void *rfp_cfg_group);
const char *name, void *rfp_cfg_group);
/***********************************************************************
* Configuration related defines and structures
***********************************************************************/
struct rfapi_rfp_cb_methods
{
struct rfapi_rfp_cb_methods {
rfp_cfg_write_cb_t *cfg_cb; /* show top level config */
rfp_cfg_group_write_cb_t *cfg_group_cb; /* show group level config */
rfapi_response_cb_t *response_cb; /* unsolicited responses */
rfapi_response_cb_t *local_cb; /* local route add/delete */
rfapi_nve_close_cb_t *close_cb; /* handle closed */
};
/*
@ -319,16 +303,14 @@ struct rfapi_rfp_cb_methods
* rfapi_query. When partial table download is used, only
* information matching a query is passed.
*/
typedef enum
{
typedef enum {
RFAPI_RFP_DOWNLOAD_PARTIAL = 0,
RFAPI_RFP_DOWNLOAD_FULL
} rfapi_rfp_download_type;
#define RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL 1
struct rfapi_rfp_cfg
{
struct rfapi_rfp_cfg {
/* partial or full table download */
rfapi_rfp_download_type download_type; /* default=partial */
/*
@ -370,9 +352,7 @@ struct rfapi_rfp_cfg
* return value:
* rfp_start_val rfp returned value passed on rfp_stop and other rfapi calls
--------------------------------------------*/
extern void *
rfp_start (
struct thread_master *master,
extern void *rfp_start(struct thread_master *master,
struct rfapi_rfp_cfg **cfgp,
struct rfapi_rfp_cb_methods **cbmp);
@ -389,8 +369,7 @@ rfp_start (
*
* return value:
--------------------------------------------*/
extern void
rfp_stop (void *rfp_start_val);
extern void rfp_stop(void *rfp_start_val);
/***********************************************************************
* RFP processing behavior configuration
@ -413,9 +392,7 @@ rfp_stop (void *rfp_start_val);
* 0 Success
* ENXIO Unabled to locate configured BGP/VNC
--------------------------------------------*/
extern int
rfapi_rfp_set_configuration (
void *rfp_start_val,
extern int rfapi_rfp_set_configuration(void *rfp_start_val,
struct rfapi_rfp_cfg *rfp_cfg);
/*------------------------------------------
@ -433,9 +410,7 @@ rfapi_rfp_set_configuration (
* 0 Success
* ENXIO BGP or VNC not configured
*------------------------------------------*/
extern int
rfapi_rfp_set_cb_methods (
void *rfp_start_val,
extern int rfapi_rfp_set_cb_methods(void *rfp_start_val,
struct rfapi_rfp_cb_methods *methods);
/***********************************************************************
@ -463,9 +438,7 @@ rfapi_rfp_set_cb_methods (
* return value:
* rfp_cfg_group NULL or Pointer to configuration structure
--------------------------------------------*/
extern void *
rfapi_rfp_init_group_config_ptr_vty (
void *rfp_start_val,
extern void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val,
rfapi_rfp_cfg_group_type type,
struct vty *vty,
uint32_t size);
@ -489,9 +462,7 @@ rfapi_rfp_init_group_config_ptr_vty (
* return value:
* rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
extern void *
rfapi_rfp_get_group_config_ptr_vty (
void *rfp_start_val,
extern void *rfapi_rfp_get_group_config_ptr_vty(void *rfp_start_val,
rfapi_rfp_cfg_group_type type,
struct vty *vty);
@ -512,8 +483,7 @@ rfapi_rfp_get_group_config_ptr_vty (
* 0 Match/Success
* ENOENT No matching
--------------------------------------------*/
typedef int (rfp_group_config_search_cb_t) (void *criteria,
void *rfp_cfg_group);
typedef int(rfp_group_config_search_cb_t)(void *criteria, void *rfp_cfg_group);
/*------------------------------------------
* rfapi_rfp_get_group_config_ptr_name
@ -536,13 +506,9 @@ typedef int (rfp_group_config_search_cb_t) (void *criteria,
* return value:
* rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
extern void *
rfapi_rfp_get_group_config_ptr_name (
void *rfp_start_val,
rfapi_rfp_cfg_group_type type,
const char *name,
void *criteria,
rfp_group_config_search_cb_t *search_cb);
extern void *rfapi_rfp_get_group_config_ptr_name(
void *rfp_start_val, rfapi_rfp_cfg_group_type type, const char *name,
void *criteria, rfp_group_config_search_cb_t *search_cb);
/*------------------------------------------
* rfapi_rfp_get_l2_group_config_ptr_lni
@ -565,10 +531,8 @@ rfapi_rfp_get_group_config_ptr_name (
* rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
extern void *
rfapi_rfp_get_l2_group_config_ptr_lni (
void *rfp_start_val,
uint32_t logical_net_id,
void *criteria,
rfapi_rfp_get_l2_group_config_ptr_lni(void *rfp_start_val,
uint32_t logical_net_id, void *criteria,
rfp_group_config_search_cb_t *search_cb);
/***********************************************************************
@ -615,14 +579,10 @@ rfapi_rfp_get_l2_group_config_ptr_lni (
* but underlay network address is not IPv4
* EDEADLK Called from within a callback procedure
*------------------------------------------*/
extern int
rfapi_open (
void *rfp_start_val,
struct rfapi_ip_addr *vn,
extern int rfapi_open(void *rfp_start_val, struct rfapi_ip_addr *vn,
struct rfapi_ip_addr *un,
struct rfapi_un_option *default_options,
uint32_t *response_lifetime,
void *userdata,
uint32_t *response_lifetime, void *userdata,
rfapi_handle *pHandle);
@ -643,8 +603,7 @@ rfapi_open (
* EBADF invalid handle
* ENXIO BGP or VNC not configured
*------------------------------------------*/
extern int
rfapi_close (rfapi_handle rfd);
extern int rfapi_close(rfapi_handle rfd);
/*------------------------------------------
* rfapi_check
@ -664,8 +623,7 @@ rfapi_close (rfapi_handle rfd);
* ENXIO BGP or VNC not configured
* EAFNOSUPPORT Internal addressing error
*------------------------------------------*/
extern int
rfapi_check (rfapi_handle rfd);
extern int rfapi_check(rfapi_handle rfd);
/***********************************************************************
* NVE Routes
@ -701,10 +659,7 @@ rfapi_check (rfapi_handle rfd);
* ESTALE descriptor is no longer usable; should be closed
* EDEADLK Called from within a callback procedure
--------------------------------------------*/
extern int
rfapi_query (
rfapi_handle rfd,
struct rfapi_ip_addr *target,
extern int rfapi_query(rfapi_handle rfd, struct rfapi_ip_addr *target,
struct rfapi_l2address_option *l2o,
struct rfapi_next_hop_entry **ppNextHopEntry);
@ -728,8 +683,7 @@ rfapi_query (
* ESTALE descriptor is no longer usable; should be closed
* EDEADLK Called from within a callback procedure
--------------------------------------------*/
extern int
rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target);
extern int rfapi_query_done(rfapi_handle rfd, struct rfapi_ip_addr *target);
/*------------------------------------------
* rfapi_query_done_all
@ -750,8 +704,7 @@ rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target);
* ESTALE descriptor is no longer usable; should be closed
* EDEADLK Called from within a callback procedure
--------------------------------------------*/
extern int
rfapi_query_done_all (rfapi_handle rfd, int *count);
extern int rfapi_query_done_all(rfapi_handle rfd, int *count);
/*------------------------------------------
* rfapi_register
@ -785,19 +738,14 @@ rfapi_query_done_all (rfapi_handle rfd, int *count);
* EDEADLK Called from within a callback procedure
--------------------------------------------*/
typedef enum
{
typedef enum {
RFAPI_REGISTER_ADD,
RFAPI_REGISTER_WITHDRAW,
RFAPI_REGISTER_KILL
} rfapi_register_action;
extern int
rfapi_register (
rfapi_handle rfd,
struct rfapi_ip_prefix *prefix,
uint32_t lifetime,
struct rfapi_un_option *options_un,
extern int rfapi_register(rfapi_handle rfd, struct rfapi_ip_prefix *prefix,
uint32_t lifetime, struct rfapi_un_option *options_un,
struct rfapi_vn_option *options_vn,
rfapi_register_action action);
@ -818,8 +766,7 @@ rfapi_register (
* return value:
* vn NVE virtual network address
*------------------------------------------*/
extern struct rfapi_ip_addr *
rfapi_get_vn_addr (void *);
extern struct rfapi_ip_addr *rfapi_get_vn_addr(void *);
/*------------------------------------------
* rfapi_get_un_addr
@ -834,8 +781,7 @@ rfapi_get_vn_addr (void *);
* return value:
* un NVE underlay network address
*------------------------------------------*/
extern struct rfapi_ip_addr *
rfapi_get_un_addr (void *);
extern struct rfapi_ip_addr *rfapi_get_un_addr(void *);
/*------------------------------------------
* rfapi_error_str
@ -850,8 +796,7 @@ rfapi_get_un_addr (void *);
*
* const char * String
*------------------------------------------*/
extern const char *
rfapi_error_str (int code);
extern const char *rfapi_error_str(int code);
/*------------------------------------------
* rfapi_get_rfp_start_val
@ -864,8 +809,7 @@ rfapi_error_str (int code);
* returns:
* void *
*------------------------------------------*/
extern void *
rfapi_get_rfp_start_val (void *bgpv);
extern void *rfapi_get_rfp_start_val(void *bgpv);
/*------------------------------------------
* rfapi_compare_rfds
@ -882,8 +826,7 @@ rfapi_get_rfp_start_val (void *bgpv);
* 0 Mismatch
* 1 Match
*------------------------------------------*/
extern int
rfapi_compare_rfds (void *rfd1, void *rfd2);
extern int rfapi_compare_rfds(void *rfd1, void *rfd2);
/*------------------------------------------
* rfapi_free_next_hop_list
@ -898,8 +841,7 @@ rfapi_compare_rfds (void *rfd1, void *rfd2);
*
* return value: None
--------------------------------------------*/
extern void
rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list);
extern void rfapi_free_next_hop_list(struct rfapi_next_hop_entry *list);
/*------------------------------------------
* rfapi_get_response_lifetime_default
@ -915,8 +857,7 @@ rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list);
*
* return value: The bgp instance default lifetime for a response.
--------------------------------------------*/
extern int
rfapi_get_response_lifetime_default (void *rfp_start_val);
extern int rfapi_get_response_lifetime_default(void *rfp_start_val);
/*------------------------------------------
* rfapi_is_vnc_configured
@ -933,8 +874,7 @@ rfapi_get_response_lifetime_default (void *rfp_start_val);
* 0 Success
* ENXIO VNC not configured
--------------------------------------------*/
extern int
rfapi_is_vnc_configured (void *rfp_start_val);
extern int rfapi_is_vnc_configured(void *rfp_start_val);
/*------------------------------------------
* rfapi_bgp_lookup_by_rfp
@ -953,8 +893,7 @@ rfapi_is_vnc_configured (void *rfp_start_val);
* NULL = not found
*
--------------------------------------------*/
extern struct bgp *
rfapi_bgp_lookup_by_rfp (void *rfp_start_val);
extern struct bgp *rfapi_bgp_lookup_by_rfp(void *rfp_start_val);
/*------------------------------------------
* rfapi_get_rfp_start_val_by_bgp
@ -972,8 +911,7 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val);
* NULL = not found
*
--------------------------------------------*/
extern void *
rfapi_get_rfp_start_val_by_bgp (struct bgp *bgp);
extern void *rfapi_get_rfp_start_val_by_bgp(struct bgp *bgp);
#endif /* ENABLE_BGP_VNC */

View File

@ -83,8 +83,7 @@
* is used to spread out the sort for adbs with the same lifetime
* and thereby make the skip list operations more efficient.
*/
static int
sl_adb_lifetime_cmp (void *adb1, void *adb2)
static int sl_adb_lifetime_cmp(void *adb1, void *adb2)
{
struct rfapi_adb *a1 = adb1;
struct rfapi_adb *a2 = adb2;
@ -102,50 +101,47 @@ sl_adb_lifetime_cmp (void *adb1, void *adb2)
return 0;
}
void
rfapiApInit (struct rfapi_advertised_prefixes *ap)
void rfapiApInit(struct rfapi_advertised_prefixes *ap)
{
ap->ipN_by_prefix = skiplist_new (0, rfapi_rib_key_cmp, NULL);
ap->ip0_by_ether = skiplist_new (0, rfapi_rib_key_cmp, NULL);
ap->by_lifetime = skiplist_new (0, sl_adb_lifetime_cmp, NULL);
ap->ipN_by_prefix = skiplist_new(0, rfapi_rib_key_cmp, NULL);
ap->ip0_by_ether = skiplist_new(0, rfapi_rib_key_cmp, NULL);
ap->by_lifetime = skiplist_new(0, sl_adb_lifetime_cmp, NULL);
}
void
rfapiApRelease (struct rfapi_advertised_prefixes *ap)
void rfapiApRelease(struct rfapi_advertised_prefixes *ap)
{
struct rfapi_adb *adb;
/* Free ADBs and lifetime items */
while (0 == skiplist_first (ap->by_lifetime, NULL, (void **) &adb))
{
rfapiAdbFree (adb);
skiplist_delete_first (ap->by_lifetime);
while (0 == skiplist_first(ap->by_lifetime, NULL, (void **)&adb)) {
rfapiAdbFree(adb);
skiplist_delete_first(ap->by_lifetime);
}
while (0 == skiplist_delete_first (ap->ipN_by_prefix));
while (0 == skiplist_delete_first (ap->ip0_by_ether));
while (0 == skiplist_delete_first(ap->ipN_by_prefix))
;
while (0 == skiplist_delete_first(ap->ip0_by_ether))
;
/* Free lists */
skiplist_free (ap->ipN_by_prefix);
skiplist_free (ap->ip0_by_ether);
skiplist_free (ap->by_lifetime);
skiplist_free(ap->ipN_by_prefix);
skiplist_free(ap->ip0_by_ether);
skiplist_free(ap->by_lifetime);
ap->ipN_by_prefix = NULL;
ap->ip0_by_ether = NULL;
ap->by_lifetime = NULL;
}
int
rfapiApCount (struct rfapi_descriptor *rfd)
int rfapiApCount(struct rfapi_descriptor *rfd)
{
if (!rfd->advertised.by_lifetime)
return 0;
return skiplist_count (rfd->advertised.by_lifetime);
return skiplist_count(rfd->advertised.by_lifetime);
}
int
rfapiApCountAll (struct bgp *bgp)
int rfapiApCountAll(struct bgp *bgp)
{
struct rfapi *h;
struct listnode *node;
@ -153,34 +149,28 @@ rfapiApCountAll (struct bgp *bgp)
int total = 0;
h = bgp->rfapi;
if (h)
{
for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
{
total += rfapiApCount (rfd);
if (h) {
for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) {
total += rfapiApCount(rfd);
}
}
return total;
}
void
rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
void rfapiApReadvertiseAll(struct bgp *bgp, struct rfapi_descriptor *rfd)
{
struct rfapi_adb *adb;
void *cursor = NULL;
int rc;
for (rc =
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
&cursor); rc == 0;
rc =
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
&cursor))
{
for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL,
(void **)&adb, &cursor);
rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL,
(void **)&adb, &cursor)) {
struct prefix_rd prd;
uint32_t local_pref = rfp_cost_to_localpref (adb->cost);
uint32_t local_pref = rfp_cost_to_localpref(adb->cost);
prd = rfd->rd;
prd.family = AF_UNSPEC;
@ -190,17 +180,18 @@ rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
* TBD this is not quite right. When pfx_ip is 0/32 or 0/128,
* we need to substitute the VN address as the prefix
*/
add_vnc_route (rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, &prd, /* RD to use (0 for ENCAP) */
add_vnc_route(rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip,
&prd, /* RD to use (0 for ENCAP) */
&rfd->vn_addr, /* nexthop */
&local_pref, &adb->lifetime, NULL, NULL, /* struct rfapi_un_option */
&local_pref, &adb->lifetime, NULL,
NULL, /* struct rfapi_un_option */
NULL, /* struct rfapi_vn_option */
rfd->rt_export_list, NULL, /* med */
NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0);
}
}
void
rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd)
{
struct rfapi_adb *adb;
void *cursor;
@ -208,44 +199,40 @@ rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
cursor = NULL;
for (rc =
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
&cursor); rc == 0;
rc =
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
&cursor))
{
for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL,
(void **)&adb, &cursor);
rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL,
(void **)&adb, &cursor)) {
struct prefix pfx_vn_buf;
struct prefix *pfx_ip;
if (!(RFAPI_0_PREFIX (&adb->u.s.prefix_ip) &&
RFAPI_HOST_PREFIX (&adb->u.s.prefix_ip)))
{
if (!(RFAPI_0_PREFIX(&adb->u.s.prefix_ip)
&& RFAPI_HOST_PREFIX(&adb->u.s.prefix_ip))) {
pfx_ip = &adb->u.s.prefix_ip;
}
else
{
} else {
pfx_ip = NULL;
/*
* 0/32 or 0/128 => mac advertisement
*/
if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf))
{
if (rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn_buf)) {
/*
* Bad: it means we can't delete the route
*/
vnc_zlog_debug_verbose ("%s: BAD: handle has bad vn_addr: skipping",
vnc_zlog_debug_verbose(
"%s: BAD: handle has bad vn_addr: skipping",
__func__);
continue;
}
}
del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->u.s.prd, /* RD to use (0 for ENCAP) */
del_vnc_route(rfd, rfd->peer, bgp, SAFI_MPLS_VPN,
pfx_ip ? pfx_ip : &pfx_vn_buf,
&adb->u.s.prd, /* RD to use (0 for ENCAP) */
ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0);
}
}
@ -253,8 +240,7 @@ rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
/*
* returns nonzero if tunnel readvertisement is needed, 0 otherwise
*/
static int
rfapiApAdjustLifetimeStats (
static int rfapiApAdjustLifetimeStats(
struct rfapi_descriptor *rfd,
uint32_t *old_lifetime, /* set if removing/replacing */
uint32_t *new_lifetime) /* set if replacing/adding */
@ -263,20 +249,20 @@ rfapiApAdjustLifetimeStats (
int find_max = 0;
int find_min = 0;
vnc_zlog_debug_verbose ("%s: rfd=%p, pOldLife=%p, pNewLife=%p",
__func__, rfd, old_lifetime, new_lifetime);
vnc_zlog_debug_verbose("%s: rfd=%p, pOldLife=%p, pNewLife=%p", __func__,
rfd, old_lifetime, new_lifetime);
if (old_lifetime)
vnc_zlog_debug_verbose ("%s: OldLife=%d", __func__, *old_lifetime);
vnc_zlog_debug_verbose("%s: OldLife=%d", __func__,
*old_lifetime);
if (new_lifetime)
vnc_zlog_debug_verbose ("%s: NewLife=%d", __func__, *new_lifetime);
vnc_zlog_debug_verbose("%s: NewLife=%d", __func__,
*new_lifetime);
if (new_lifetime)
{
if (new_lifetime) {
/*
* Adding new lifetime
*/
if (old_lifetime)
{
if (old_lifetime) {
/*
* replacing existing lifetime
*/
@ -286,48 +272,38 @@ rfapiApAdjustLifetimeStats (
if (*old_lifetime == *new_lifetime)
return 0;
if (*old_lifetime == rfd->min_prefix_lifetime)
{
if (*old_lifetime == rfd->min_prefix_lifetime) {
find_min = 1;
}
if (*old_lifetime == rfd->max_prefix_lifetime)
{
if (*old_lifetime == rfd->max_prefix_lifetime) {
find_max = 1;
}
/* no need to search if new value is at or equals min|max */
if (*new_lifetime <= rfd->min_prefix_lifetime)
{
/* no need to search if new value is at or equals
* min|max */
if (*new_lifetime <= rfd->min_prefix_lifetime) {
rfd->min_prefix_lifetime = *new_lifetime;
find_min = 0;
}
if (*new_lifetime >= rfd->max_prefix_lifetime)
{
if (*new_lifetime >= rfd->max_prefix_lifetime) {
rfd->max_prefix_lifetime = *new_lifetime;
advertise = 1;
find_max = 0;
}
}
else
{
} else {
/*
* Just adding new lifetime
*/
if (*new_lifetime < rfd->min_prefix_lifetime)
{
if (*new_lifetime < rfd->min_prefix_lifetime) {
rfd->min_prefix_lifetime = *new_lifetime;
}
if (*new_lifetime > rfd->max_prefix_lifetime)
{
if (*new_lifetime > rfd->max_prefix_lifetime) {
advertise = 1;
rfd->max_prefix_lifetime = *new_lifetime;
}
}
}
else
{
} else {
/*
* Deleting
*/
@ -344,8 +320,7 @@ rfapiApAdjustLifetimeStats (
* address family that matches the VN address.
*
*/
if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime)
{
if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime) {
/*
* Common case: all lifetimes are the same. Only
@ -353,43 +328,35 @@ rfapiApAdjustLifetimeStats (
* no exported routes left. In that case, reinitialize
* the max and min values.
*/
if (!rfapiApCount (rfd))
{
if (!rfapiApCount(rfd)) {
rfd->max_prefix_lifetime = 0;
rfd->min_prefix_lifetime = UINT32_MAX;
}
}
else
{
if (old_lifetime)
{
if (*old_lifetime == rfd->min_prefix_lifetime)
{
} else {
if (old_lifetime) {
if (*old_lifetime == rfd->min_prefix_lifetime) {
find_min = 1;
}
if (*old_lifetime == rfd->max_prefix_lifetime)
{
if (*old_lifetime == rfd->max_prefix_lifetime) {
find_max = 1;
}
}
}
}
if (find_min || find_max)
{
if (find_min || find_max) {
uint32_t min = UINT32_MAX;
uint32_t max = 0;
struct rfapi_adb *adb_min;
struct rfapi_adb *adb_max;
if (!skiplist_first
(rfd->advertised.by_lifetime, (void **) &adb_min, NULL)
&& !skiplist_last (rfd->advertised.by_lifetime, (void **) &adb_max,
NULL))
{
if (!skiplist_first(rfd->advertised.by_lifetime,
(void **)&adb_min, NULL)
&& !skiplist_last(rfd->advertised.by_lifetime,
(void **)&adb_max, NULL)) {
/*
* This should always work
@ -397,25 +364,24 @@ rfapiApAdjustLifetimeStats (
min = adb_min->lifetime;
max = adb_max->lifetime;
}
else
{
} else {
void *cursor;
struct rfapi_rib_key rk;
struct rfapi_adb *adb;
int rc;
vnc_zlog_debug_verbose ("%s: walking to find new min/max", __func__);
vnc_zlog_debug_verbose(
"%s: walking to find new min/max", __func__);
cursor = NULL;
for (rc = skiplist_next (rfd->advertised.ipN_by_prefix,
(void **) &rk, (void **) &adb,
&cursor); !rc;
rc =
skiplist_next (rfd->advertised.ipN_by_prefix,
(void **) &rk, (void **) &adb, &cursor))
{
for (rc = skiplist_next(rfd->advertised.ipN_by_prefix,
(void **)&rk, (void **)&adb,
&cursor);
!rc;
rc = skiplist_next(rfd->advertised.ipN_by_prefix,
(void **)&rk, (void **)&adb,
&cursor)) {
uint32_t lt = adb->lifetime;
@ -425,13 +391,13 @@ rfapiApAdjustLifetimeStats (
min = lt;
}
cursor = NULL;
for (rc = skiplist_next (rfd->advertised.ip0_by_ether,
(void **) &rk, (void **) &adb,
&cursor); !rc;
rc =
skiplist_next (rfd->advertised.ip0_by_ether, (void **) &rk,
(void **) &adb, &cursor))
{
for (rc = skiplist_next(rfd->advertised.ip0_by_ether,
(void **)&rk, (void **)&adb,
&cursor);
!rc;
rc = skiplist_next(rfd->advertised.ip0_by_ether,
(void **)&rk, (void **)&adb,
&cursor)) {
uint32_t lt = adb->lifetime;
@ -453,7 +419,7 @@ rfapiApAdjustLifetimeStats (
rfd->min_prefix_lifetime = min;
}
vnc_zlog_debug_verbose ("%s: returning advertise=%d, min=%d, max=%d",
vnc_zlog_debug_verbose("%s: returning advertise=%d, min=%d, max=%d",
__func__, advertise, rfd->min_prefix_lifetime,
rfd->max_prefix_lifetime);
@ -466,15 +432,9 @@ rfapiApAdjustLifetimeStats (
* 0 No need to advertise tunnel route
* non-0 advertise tunnel route
*/
int
rfapiApAdd (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *pfx_ip,
struct prefix *pfx_eth,
struct prefix_rd *prd,
uint32_t lifetime,
uint8_t cost,
int rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct prefix *pfx_ip, struct prefix *pfx_eth,
struct prefix_rd *prd, uint32_t lifetime, uint8_t cost,
struct rfapi_l2address_option *l2o) /* other options TBD */
{
int rc;
@ -484,65 +444,55 @@ rfapiApAdd (
struct rfapi_rib_key rk;
rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk);
if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip))
{
if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) {
use_ip0 = 1;
assert (pfx_eth);
rc =
skiplist_search (rfd->advertised.ip0_by_ether, &rk,
(void **) &adb);
assert(pfx_eth);
rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk,
(void **)&adb);
}
else
{
} else {
/* find prefix in advertised prefixes list */
rc =
skiplist_search (rfd->advertised.ipN_by_prefix, &rk,
(void **) &adb);
rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk,
(void **)&adb);
}
if (rc)
{
if (rc) {
/* Not found */
adb = XCALLOC (MTYPE_RFAPI_ADB, sizeof (struct rfapi_adb));
assert (adb);
adb = XCALLOC(MTYPE_RFAPI_ADB, sizeof(struct rfapi_adb));
assert(adb);
adb->lifetime = lifetime;
adb->u.key = rk;
if (use_ip0)
{
assert (pfx_eth);
skiplist_insert (rfd->advertised.ip0_by_ether, &adb->u.key,
adb);
}
else
{
skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->u.key,
adb);
if (use_ip0) {
assert(pfx_eth);
skiplist_insert(rfd->advertised.ip0_by_ether,
&adb->u.key, adb);
} else {
skiplist_insert(rfd->advertised.ipN_by_prefix,
&adb->u.key, adb);
}
skiplist_insert (rfd->advertised.by_lifetime, adb, adb);
}
else
{
skiplist_insert(rfd->advertised.by_lifetime, adb, adb);
} else {
old_lifetime = adb->lifetime;
if (old_lifetime != lifetime)
{
assert (!skiplist_delete (rfd->advertised.by_lifetime, adb, NULL));
if (old_lifetime != lifetime) {
assert(!skiplist_delete(rfd->advertised.by_lifetime,
adb, NULL));
adb->lifetime = lifetime;
assert (!skiplist_insert (rfd->advertised.by_lifetime, adb, adb));
assert(!skiplist_insert(rfd->advertised.by_lifetime,
adb, adb));
}
}
adb->cost = cost;
if (l2o)
adb->l2o = *l2o;
else
memset (&adb->l2o, 0, sizeof (struct rfapi_l2address_option));
memset(&adb->l2o, 0, sizeof(struct rfapi_l2address_option));
if (rfapiApAdjustLifetimeStats
(rfd, (rc ? NULL : &old_lifetime), &lifetime))
if (rfapiApAdjustLifetimeStats(rfd, (rc ? NULL : &old_lifetime),
&lifetime))
return 1;
return 0;
@ -552,14 +502,9 @@ rfapiApAdd (
* After this function returns successfully, caller should call
* rfapiAdjustLifetimeStats() and possibly rfapiTunnelRouteAnnounce()
*/
int
rfapiApDelete (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *pfx_ip,
struct prefix *pfx_eth,
struct prefix_rd *prd,
int *advertise_tunnel) /* out */
int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct prefix *pfx_ip, struct prefix *pfx_eth,
struct prefix_rd *prd, int *advertise_tunnel) /* out */
{
int rc;
struct rfapi_adb *adb;
@ -572,49 +517,39 @@ rfapiApDelete (
rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk);
/* find prefix in advertised prefixes list */
if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip))
{
if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) {
use_ip0 = 1;
assert (pfx_eth);
assert(pfx_eth);
rc =
skiplist_search (rfd->advertised.ip0_by_ether, &rk,
(void **) &adb);
rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk,
(void **)&adb);
}
else
{
} else {
/* find prefix in advertised prefixes list */
rc =
skiplist_search (rfd->advertised.ipN_by_prefix, &rk,
(void **) &adb);
rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk,
(void **)&adb);
}
if (rc)
{
if (rc) {
return ENOENT;
}
old_lifetime = adb->lifetime;
if (use_ip0)
{
rc = skiplist_delete (rfd->advertised.ip0_by_ether, &rk, NULL);
if (use_ip0) {
rc = skiplist_delete(rfd->advertised.ip0_by_ether, &rk, NULL);
} else {
rc = skiplist_delete(rfd->advertised.ipN_by_prefix, &rk, NULL);
}
else
{
rc = skiplist_delete (rfd->advertised.ipN_by_prefix, &rk, NULL);
}
assert (!rc);
assert(!rc);
rc = skiplist_delete (rfd->advertised.by_lifetime, adb, NULL);
assert (!rc);
rc = skiplist_delete(rfd->advertised.by_lifetime, adb, NULL);
assert(!rc);
rfapiAdbFree (adb);
rfapiAdbFree(adb);
if (rfapiApAdjustLifetimeStats (rfd, &old_lifetime, NULL))
{
if (rfapiApAdjustLifetimeStats(rfd, &old_lifetime, NULL)) {
if (advertise_tunnel)
*advertise_tunnel = 1;
}

View File

@ -56,42 +56,28 @@
#include "rfapi_rib.h"
extern void
rfapiApInit (struct rfapi_advertised_prefixes *ap);
extern void rfapiApInit(struct rfapi_advertised_prefixes *ap);
extern void
rfapiApRelease (struct rfapi_advertised_prefixes *ap);
extern void rfapiApRelease(struct rfapi_advertised_prefixes *ap);
extern int rfapiApCount(struct rfapi_descriptor *rfd);
extern int rfapiApCountAll(struct bgp *bgp);
extern void rfapiApReadvertiseAll(struct bgp *bgp,
struct rfapi_descriptor *rfd);
extern void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd);
extern int
rfapiApCount (struct rfapi_descriptor *rfd);
extern int
rfapiApCountAll (struct bgp *bgp);
extern void
rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd);
extern void
rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd);
extern int
rfapiApAdd (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *pfx_ip,
struct prefix *pfx_eth,
struct prefix_rd *prd,
uint32_t lifetime,
rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *pfx_ip,
struct prefix *pfx_eth, struct prefix_rd *prd, uint32_t lifetime,
uint8_t cost,
struct rfapi_l2address_option *l2o); /* other options TBD */
extern int
rfapiApDelete (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *pfx_ip,
struct prefix *pfx_eth,
extern int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct prefix *pfx_ip, struct prefix *pfx_eth,
struct prefix_rd *prd,
int *advertise_tunnel); /* out */

View File

@ -26,56 +26,44 @@
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_nexthop.h"
extern void rfapi_init (void);
extern void vnc_zebra_init (struct thread_master *master);
extern void vnc_zebra_destroy (void);
extern void rfapi_init(void);
extern void vnc_zebra_init(struct thread_master *master);
extern void vnc_zebra_destroy(void);
extern void rfapi_delete (struct bgp *);
extern void rfapi_delete(struct bgp *);
struct rfapi *bgp_rfapi_new (struct bgp *bgp);
void bgp_rfapi_destroy (struct bgp *bgp, struct rfapi *h);
struct rfapi *bgp_rfapi_new(struct bgp *bgp);
void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h);
extern void
rfapiProcessUpdate (struct peer *peer,
void *rfd,
struct prefix *p,
struct prefix_rd *prd,
struct attr *attr,
afi_t afi,
safi_t safi,
u_char type, u_char sub_type, uint32_t * label);
extern void rfapiProcessUpdate(struct peer *peer, void *rfd, struct prefix *p,
struct prefix_rd *prd, struct attr *attr,
afi_t afi, safi_t safi, u_char type,
u_char sub_type, uint32_t *label);
extern void
rfapiProcessWithdraw (struct peer *peer,
void *rfd,
struct prefix *p,
struct prefix_rd *prd,
struct attr *attr,
extern void rfapiProcessWithdraw(struct peer *peer, void *rfd, struct prefix *p,
struct prefix_rd *prd, struct attr *attr,
afi_t afi, safi_t safi, u_char type, int kill);
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, struct bgp *bgp);
extern void vnc_zebra_announce(struct prefix *p, struct bgp_info *new_select,
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_info *old_select);
extern void
rfapi_vty_out_vncinfo (struct vty *vty,
struct prefix *p, struct bgp_info *bi, safi_t safi);
extern void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
struct bgp_info *bi, 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);
extern void vnc_direct_bgp_vpn_disable (struct bgp *bgp, afi_t afi);
extern void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi);
extern void vnc_direct_bgp_rh_vpn_enable (struct bgp *bgp, afi_t afi);
extern void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi);
extern void vnc_direct_bgp_rh_vpn_disable (struct bgp *bgp, afi_t afi);
extern void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi);
#endif /* ENABLE_BGP_VNC */

View File

@ -36,15 +36,14 @@
#include "bgpd/rfapi/vnc_debug.h"
void *
rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)
void *rfapi_create_generic(struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)
{
struct rfapi_descriptor *rfd;
rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor));
vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd);
rfd = XCALLOC(MTYPE_RFAPI_DESC, sizeof(struct rfapi_descriptor));
vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd);
rfd->vn_addr = *vn;
rfd->un_addr = *un;
return (void *) rfd;
return (void *)rfd;
}
/*------------------------------------------
@ -60,12 +59,11 @@ rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)
* return value:
*
*------------------------------------------*/
void
rfapi_free_generic (void *grfd)
void rfapi_free_generic(void *grfd)
{
struct rfapi_descriptor *rfd;
rfd = (struct rfapi_descriptor *) grfd;
XFREE (MTYPE_RFAPI_DESC, rfd);
rfd = (struct rfapi_descriptor *)grfd;
XFREE(MTYPE_RFAPI_DESC, rfd);
}
@ -84,22 +82,20 @@ rfapi_free_generic (void *grfd)
* 0 Mismatch
* 1 Match
*------------------------------------------*/
int
rfapi_compare_rfds (void *rfd1, void *rfd2)
int rfapi_compare_rfds(void *rfd1, void *rfd2)
{
struct rfapi_descriptor *rrfd1, *rrfd2;
int match = 0;
rrfd1 = (struct rfapi_descriptor *) rfd1;
rrfd2 = (struct rfapi_descriptor *) rfd2;
rrfd1 = (struct rfapi_descriptor *)rfd1;
rrfd2 = (struct rfapi_descriptor *)rfd2;
if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family)
{
if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family) {
if (rrfd1->vn_addr.addr_family == AF_INET)
match = IPV4_ADDR_SAME (&(rrfd1->vn_addr.addr.v4),
match = IPV4_ADDR_SAME(&(rrfd1->vn_addr.addr.v4),
&(rrfd2->vn_addr.addr.v4));
else
match = IPV6_ADDR_SAME (&(rrfd1->vn_addr.addr.v6),
match = IPV6_ADDR_SAME(&(rrfd1->vn_addr.addr.v6),
&(rrfd2->vn_addr.addr.v6));
}
@ -114,17 +110,16 @@ rfapi_compare_rfds (void *rfd1, void *rfd2)
* do the process again for the UN addresses.
*/
match = 0;
if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family)
{
if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family) {
/* VN addresses match
* UN address families match
* now check the actual UN addresses
*/
if (rrfd1->un_addr.addr_family == AF_INET)
match = IPV4_ADDR_SAME (&(rrfd1->un_addr.addr.v4),
match = IPV4_ADDR_SAME(&(rrfd1->un_addr.addr.v4),
&(rrfd2->un_addr.addr.v4));
else
match = IPV6_ADDR_SAME (&(rrfd1->un_addr.addr.v6),
match = IPV6_ADDR_SAME(&(rrfd1->un_addr.addr.v6),
&(rrfd2->un_addr.addr.v6));
}
return match;

View File

@ -19,7 +19,7 @@
*/
extern void *rfapi_create_generic (struct rfapi_ip_addr *vn,
extern void *rfapi_create_generic(struct rfapi_ip_addr *vn,
struct rfapi_ip_addr *un);
/*------------------------------------------
@ -35,4 +35,4 @@ extern void *rfapi_create_generic (struct rfapi_ip_addr *vn,
* return value:
*
*------------------------------------------*/
extern void rfapi_free_generic (void *grfd);
extern void rfapi_free_generic(void *grfd);

View File

@ -37,10 +37,8 @@
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
#include "bgpd/rfapi/vnc_debug.h"
static void
rfapi_add_endpoint_address_to_subtlv (
struct bgp *bgp,
struct rfapi_ip_addr *ea,
static void rfapi_add_endpoint_address_to_subtlv(
struct bgp *bgp, struct rfapi_ip_addr *ea,
struct bgp_tea_subtlv_remote_endpoint *subtlv)
{
subtlv->family = ea->addr_family;
@ -48,85 +46,84 @@ rfapi_add_endpoint_address_to_subtlv (
subtlv->ip_address.v4 = ea->addr.v4;
else
subtlv->ip_address.v6 = ea->addr.v6;
subtlv->as4 = htonl (bgp->as);
subtlv->as4 = htonl(bgp->as);
}
bgp_encap_types
rfapi_tunneltype_option_to_tlv (
struct bgp *bgp,
struct rfapi_ip_addr *ea,
rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea,
struct rfapi_tunneltype_option *tto,
struct attr *attr,
int always_add)
struct attr *attr, int always_add)
{
#define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype) \
if ((always_add || (bgp->rfapi_cfg && \
!CHECK_FLAG(bgp->rfapi_cfg->flags, \
BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) && \
ea && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype, \
if ((always_add \
|| (bgp->rfapi_cfg \
&& !CHECK_FLAG(bgp->rfapi_cfg->flags, \
BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) \
&& ea \
&& !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype, \
BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) { \
rfapi_add_endpoint_address_to_subtlv(bgp, ea, \
&tto->bgpinfo.ttype.st_endpoint); \
SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \
rfapi_add_endpoint_address_to_subtlv( \
bgp, ea, &tto->bgpinfo.ttype.st_endpoint); \
SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, \
BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \
}
struct rfapi_tunneltype_option dto;
if (tto == NULL)
{ /* create default type */
if (tto == NULL) { /* create default type */
tto = &dto;
memset (tto, 0, sizeof (dto));
memset(tto, 0, sizeof(dto));
tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT;
}
switch (tto->type)
{
switch (tto->type) {
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (l2tpv3_ip);
bgp_encap_type_l2tpv3overip_to_tlv (&tto->bgpinfo.l2tpv3_ip, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(l2tpv3_ip);
bgp_encap_type_l2tpv3overip_to_tlv(&tto->bgpinfo.l2tpv3_ip,
attr);
break;
case BGP_ENCAP_TYPE_GRE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (gre);
bgp_encap_type_gre_to_tlv (&tto->bgpinfo.gre, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(gre);
bgp_encap_type_gre_to_tlv(&tto->bgpinfo.gre, attr);
break;
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (transmit_tunnel_endpoint);
bgp_encap_type_transmit_tunnel_endpoint (&tto->bgpinfo.transmit_tunnel_endpoint,
attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(transmit_tunnel_endpoint);
bgp_encap_type_transmit_tunnel_endpoint(
&tto->bgpinfo.transmit_tunnel_endpoint, attr);
break;
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ipsec_tunnel);
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv (&tto->bgpinfo.ipsec_tunnel,
attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ipsec_tunnel);
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
&tto->bgpinfo.ipsec_tunnel, attr);
break;
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ip_ipsec);
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv
(&tto->bgpinfo.ip_ipsec, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ipsec);
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
&tto->bgpinfo.ip_ipsec, attr);
break;
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_ipsec);
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv
(&tto->bgpinfo.mpls_ipsec, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_ipsec);
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
&tto->bgpinfo.mpls_ipsec, attr);
break;
case BGP_ENCAP_TYPE_IP_IN_IP:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ip_ip);
bgp_encap_type_ip_in_ip_to_tlv (&tto->bgpinfo.ip_ip, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ip);
bgp_encap_type_ip_in_ip_to_tlv(&tto->bgpinfo.ip_ip, attr);
break;
case BGP_ENCAP_TYPE_VXLAN:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (vxlan);
bgp_encap_type_vxlan_to_tlv (&tto->bgpinfo.vxlan, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan);
bgp_encap_type_vxlan_to_tlv(&tto->bgpinfo.vxlan, attr);
break;
case BGP_ENCAP_TYPE_NVGRE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (nvgre);
bgp_encap_type_nvgre_to_tlv (&tto->bgpinfo.nvgre, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(nvgre);
bgp_encap_type_nvgre_to_tlv(&tto->bgpinfo.nvgre, attr);
break;
case BGP_ENCAP_TYPE_MPLS:
@ -134,33 +131,32 @@ rfapi_tunneltype_option_to_tlv (
break;
case BGP_ENCAP_TYPE_MPLS_IN_GRE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_gre);
bgp_encap_type_mpls_in_gre_to_tlv (&tto->bgpinfo.mpls_gre, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_gre);
bgp_encap_type_mpls_in_gre_to_tlv(&tto->bgpinfo.mpls_gre, attr);
break;
case BGP_ENCAP_TYPE_VXLAN_GPE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (vxlan_gpe);
bgp_encap_type_vxlan_gpe_to_tlv (&tto->bgpinfo.vxlan_gpe, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan_gpe);
bgp_encap_type_vxlan_gpe_to_tlv(&tto->bgpinfo.vxlan_gpe, attr);
break;
case BGP_ENCAP_TYPE_MPLS_IN_UDP:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_udp);
bgp_encap_type_mpls_in_udp_to_tlv (&tto->bgpinfo.mpls_udp, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_udp);
bgp_encap_type_mpls_in_udp_to_tlv(&tto->bgpinfo.mpls_udp, attr);
break;
case BGP_ENCAP_TYPE_PBB:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (pbb);
bgp_encap_type_pbb_to_tlv (&tto->bgpinfo.pbb, attr);
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(pbb);
bgp_encap_type_pbb_to_tlv(&tto->bgpinfo.pbb, attr);
break;
default:
assert (0);
assert(0);
}
return tto->type;
}
struct rfapi_un_option *
rfapi_encap_tlv_to_un_option (struct attr *attr)
struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr)
{
struct rfapi_un_option *uo = NULL;
struct rfapi_tunneltype_option *tto;
@ -173,85 +169,85 @@ rfapi_encap_tlv_to_un_option (struct attr *attr)
stlv = attr->encap_subtlvs;
uo = XCALLOC (MTYPE_RFAPI_UN_OPTION, sizeof (struct rfapi_un_option));
assert (uo);
uo = XCALLOC(MTYPE_RFAPI_UN_OPTION, sizeof(struct rfapi_un_option));
assert(uo);
uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE;
uo->v.tunnel.type = attr->encap_tunneltype;
tto = &uo->v.tunnel;
switch (attr->encap_tunneltype)
{
switch (attr->encap_tunneltype) {
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
rc = tlv_to_bgp_encap_type_l2tpv3overip (stlv, &tto->bgpinfo.l2tpv3_ip);
rc = tlv_to_bgp_encap_type_l2tpv3overip(
stlv, &tto->bgpinfo.l2tpv3_ip);
break;
case BGP_ENCAP_TYPE_GRE:
rc = tlv_to_bgp_encap_type_gre (stlv, &tto->bgpinfo.gre);
rc = tlv_to_bgp_encap_type_gre(stlv, &tto->bgpinfo.gre);
break;
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint (stlv,
&tto->bgpinfo.transmit_tunnel_endpoint);
rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
stlv, &tto->bgpinfo.transmit_tunnel_endpoint);
break;
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode (stlv,
&tto->bgpinfo.ipsec_tunnel);
rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
stlv, &tto->bgpinfo.ipsec_tunnel);
break;
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
rc =
tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stlv,
&tto->bgpinfo.ip_ipsec);
rc = tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
stlv, &tto->bgpinfo.ip_ipsec);
break;
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
rc =
tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode
(stlv, &tto->bgpinfo.mpls_ipsec);
rc = tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
stlv, &tto->bgpinfo.mpls_ipsec);
break;
case BGP_ENCAP_TYPE_IP_IN_IP:
rc = tlv_to_bgp_encap_type_ip_in_ip (stlv, &tto->bgpinfo.ip_ip);
rc = tlv_to_bgp_encap_type_ip_in_ip(stlv, &tto->bgpinfo.ip_ip);
break;
case BGP_ENCAP_TYPE_VXLAN:
rc = tlv_to_bgp_encap_type_vxlan (stlv, &tto->bgpinfo.vxlan);
rc = tlv_to_bgp_encap_type_vxlan(stlv, &tto->bgpinfo.vxlan);
break;
case BGP_ENCAP_TYPE_NVGRE:
rc = tlv_to_bgp_encap_type_nvgre (stlv, &tto->bgpinfo.nvgre);
rc = tlv_to_bgp_encap_type_nvgre(stlv, &tto->bgpinfo.nvgre);
break;
case BGP_ENCAP_TYPE_MPLS:
rc = tlv_to_bgp_encap_type_mpls (stlv, &tto->bgpinfo.mpls);
rc = tlv_to_bgp_encap_type_mpls(stlv, &tto->bgpinfo.mpls);
break;
case BGP_ENCAP_TYPE_MPLS_IN_GRE:
rc = tlv_to_bgp_encap_type_mpls_in_gre (stlv, &tto->bgpinfo.mpls_gre);
rc = tlv_to_bgp_encap_type_mpls_in_gre(stlv,
&tto->bgpinfo.mpls_gre);
break;
case BGP_ENCAP_TYPE_VXLAN_GPE:
rc = tlv_to_bgp_encap_type_vxlan_gpe (stlv, &tto->bgpinfo.vxlan_gpe);
rc = tlv_to_bgp_encap_type_vxlan_gpe(stlv,
&tto->bgpinfo.vxlan_gpe);
break;
case BGP_ENCAP_TYPE_MPLS_IN_UDP:
rc = tlv_to_bgp_encap_type_mpls_in_udp (stlv, &tto->bgpinfo.mpls_udp);
rc = tlv_to_bgp_encap_type_mpls_in_udp(stlv,
&tto->bgpinfo.mpls_udp);
break;
case BGP_ENCAP_TYPE_PBB:
rc = tlv_to_bgp_encap_type_pbb (stlv, &tto->bgpinfo.pbb);
rc = tlv_to_bgp_encap_type_pbb(stlv, &tto->bgpinfo.pbb);
break;
default:
vnc_zlog_debug_verbose ("%s: unknown tunnel type %d",
__func__, attr->encap_tunneltype);
vnc_zlog_debug_verbose("%s: unknown tunnel type %d", __func__,
attr->encap_tunneltype);
rc = -1;
break;
}
if (rc)
{
XFREE (MTYPE_RFAPI_UN_OPTION, uo);
if (rc) {
XFREE(MTYPE_RFAPI_UN_OPTION, uo);
uo = NULL;
}
return uo;
@ -261,149 +257,129 @@ rfapi_encap_tlv_to_un_option (struct attr *attr)
* SUBTLV PRINT
***********************************************************************/
static void
subtlv_print_encap_l2tpv3_over_ip (
void *stream,
int column_offset,
static void subtlv_print_encap_l2tpv3_over_ip(
void *stream, int column_offset,
struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
{
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!st)
return;
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)",
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)",
vty_newline);
fp (out, "%*s SessionID: %d%s", column_offset, "", st->sessionid,
vty_newline);
fp (out, "%*s Cookie: (length %d)%s", column_offset, "", st->cookie_length,
fp(out, "%*s SessionID: %d%s", column_offset, "", st->sessionid,
vty_newline);
fp(out, "%*s Cookie: (length %d)%s", column_offset, "",
st->cookie_length, vty_newline);
}
static void
subtlv_print_encap_gre (
void *stream,
int column_offset,
static void subtlv_print_encap_gre(void *stream, int column_offset,
struct bgp_tea_subtlv_encap_gre_key *st)
{
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!st)
return;
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)", vty_newline);
fp (out, "%*s GRE key: %d (0x%x)%s", column_offset, "", st->gre_key,
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)",
vty_newline);
fp(out, "%*s GRE key: %d (0x%x)%s", column_offset, "", st->gre_key,
st->gre_key, vty_newline);
}
static void
subtlv_print_encap_pbb (
void *stream,
int column_offset,
static void subtlv_print_encap_pbb(void *stream, int column_offset,
struct bgp_tea_subtlv_encap_pbb *st)
{
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!st)
return;
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)", vty_newline);
if (st->flag_isid)
{
fp (out, "%*s ISID: %d (0x%x)%s", column_offset, "", st->isid,
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)",
vty_newline);
if (st->flag_isid) {
fp(out, "%*s ISID: %d (0x%x)%s", column_offset, "", st->isid,
st->isid, vty_newline);
}
if (st->flag_vid)
{
fp (out, "%*s VID: %d (0x%x)%s", column_offset, "", st->vid, st->vid,
vty_newline);
if (st->flag_vid) {
fp(out, "%*s VID: %d (0x%x)%s", column_offset, "", st->vid,
st->vid, vty_newline);
}
fp (out, "%*s MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s",
column_offset, "",
st->macaddr[0],
st->macaddr[1],
st->macaddr[2],
st->macaddr[3], st->macaddr[4], st->macaddr[5], vty_newline);
fp(out, "%*s MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s", column_offset,
"", st->macaddr[0], st->macaddr[1], st->macaddr[2], st->macaddr[3],
st->macaddr[4], st->macaddr[5], vty_newline);
}
static void
subtlv_print_proto_type (
void *stream,
int column_offset,
static void subtlv_print_proto_type(void *stream, int column_offset,
struct bgp_tea_subtlv_proto_type *st)
{
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!st)
return;
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)",
vty_newline);
fp (out, "%*s Proto %d (0x%x)%s", column_offset, "", st->proto, st->proto,
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)",
vty_newline);
fp(out, "%*s Proto %d (0x%x)%s", column_offset, "", st->proto,
st->proto, vty_newline);
}
static void
subtlv_print_color (
void *stream,
int column_offset,
static void subtlv_print_color(void *stream, int column_offset,
struct bgp_tea_subtlv_color *st)
{
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!st)
return;
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline);
fp (out, "%*s Color: %d (0x%x)", column_offset, "", st->color, st->color,
vty_newline);
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline);
fp(out, "%*s Color: %d (0x%x)", column_offset, "", st->color,
st->color, vty_newline);
}
static void
subtlv_print_ipsec_ta (
void *stream,
int column_offset,
static void subtlv_print_ipsec_ta(void *stream, int column_offset,
struct bgp_tea_subtlv_ipsec_ta *st)
{
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!st)
return;
fp (out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline);
fp (out, "%*s Authenticator Type: %d (0x%x)", column_offset, "",
fp(out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline);
fp(out, "%*s Authenticator Type: %d (0x%x)", column_offset, "",
st->authenticator_type, st->authenticator_type, vty_newline);
fp (out, "%*s Authenticator: (length %d)", column_offset, "",
fp(out, "%*s Authenticator: (length %d)", column_offset, "",
st->authenticator_length, vty_newline);
}
@ -412,396 +388,358 @@ subtlv_print_ipsec_ta (
***********************************************************************/
static void
print_encap_type_l2tpv3overip (
void *stream,
int column_offset,
print_encap_type_l2tpv3overip(void *stream, int column_offset,
struct bgp_encap_type_l2tpv3_over_ip *bet)
{
const char *type = "L2TPv3 over IP";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
subtlv_print_encap_l2tpv3_over_ip (stream, column_offset + 2,
subtlv_print_encap_l2tpv3_over_ip(stream, column_offset + 2,
&bet->st_encap);
subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto);
subtlv_print_color (stream, column_offset + 2, &bet->st_color);
subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto);
subtlv_print_color(stream, column_offset + 2, &bet->st_color);
}
static void
print_encap_type_gre (
void *stream,
int column_offset,
static void print_encap_type_gre(void *stream, int column_offset,
struct bgp_encap_type_gre *bet)
{
const char *type = "GRE";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
subtlv_print_encap_gre (stream, column_offset + 2, &bet->st_encap);
subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto);
subtlv_print_color (stream, column_offset + 2, &bet->st_color);
subtlv_print_encap_gre(stream, column_offset + 2, &bet->st_encap);
subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto);
subtlv_print_color(stream, column_offset + 2, &bet->st_color);
}
static void
print_encap_type_ip_in_ip (
void *stream,
int column_offset,
static void print_encap_type_ip_in_ip(void *stream, int column_offset,
struct bgp_encap_type_ip_in_ip *bet)
{
const char *type = "IP in IP";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto);
subtlv_print_color (stream, column_offset + 2, &bet->st_color);
subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto);
subtlv_print_color(stream, column_offset + 2, &bet->st_color);
}
static void
print_encap_type_transmit_tunnel_endpoint (
void *stream,
int column_offset,
static void print_encap_type_transmit_tunnel_endpoint(
void *stream, int column_offset,
struct bgp_encap_type_transmit_tunnel_endpoint *bet)
{
const char *type = "Transmit Tunnel Endpoint";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
/* no subtlvs for this type */
}
static void
print_encap_type_ipsec_in_tunnel_mode (
void *stream,
int column_offset,
static void print_encap_type_ipsec_in_tunnel_mode(
void *stream, int column_offset,
struct bgp_encap_type_ipsec_in_tunnel_mode *bet)
{
const char *type = "IPSEC in Tunnel mode";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);
}
static void
print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (
void *stream,
int column_offset,
static void print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
void *stream, int column_offset,
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
{
const char *type = "IP in IP Tunnel with IPSEC transport mode";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta);
subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);
}
static void
print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (
void *stream,
int column_offset,
static void print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
void *stream, int column_offset,
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
{
const char *type = "MPLS in IP Tunnel with IPSEC transport mode";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta);
subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);
}
static void
print_encap_type_pbb (
void *stream,
int column_offset,
static void print_encap_type_pbb(void *stream, int column_offset,
struct bgp_encap_type_pbb *bet)
{
const char *type = "PBB";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
subtlv_print_encap_pbb (stream, column_offset + 2, &bet->st_encap);
subtlv_print_encap_pbb(stream, column_offset + 2, &bet->st_encap);
}
static void
print_encap_type_vxlan (
void *stream,
int column_offset,
static void print_encap_type_vxlan(void *stream, int column_offset,
struct bgp_encap_type_vxlan *bet)
{
const char *type = "VXLAN";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
/* no subtlvs for this type */
}
static void
print_encap_type_nvgre (
void *stream,
int column_offset,
static void print_encap_type_nvgre(void *stream, int column_offset,
struct bgp_encap_type_nvgre *bet)
{
const char *type = "NVGRE";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
/* no subtlvs for this type */
}
static void
print_encap_type_mpls (
void *stream,
int column_offset,
static void print_encap_type_mpls(void *stream, int column_offset,
struct bgp_encap_type_mpls *bet)
{
const char *type = "MPLS";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
/* no subtlvs for this type */
}
static void
print_encap_type_mpls_in_gre (
void *stream,
int column_offset,
static void print_encap_type_mpls_in_gre(void *stream, int column_offset,
struct bgp_encap_type_mpls_in_gre *bet)
{
const char *type = "MPLS in GRE";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
/* no subtlvs for this type */
}
static void
print_encap_type_vxlan_gpe (
void *stream,
int column_offset,
static void print_encap_type_vxlan_gpe(void *stream, int column_offset,
struct bgp_encap_type_vxlan_gpe *bet)
{
const char *type = "VXLAN GPE";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
/* no subtlvs for this type */
}
static void
print_encap_type_mpls_in_udp (
void *stream,
int column_offset,
static void print_encap_type_mpls_in_udp(void *stream, int column_offset,
struct bgp_encap_type_mpls_in_udp *bet)
{
const char *type = "MPLS in UDP";
int (*fp) (void *, const char *, ...);
int (*fp)(void *, const char *, ...);
struct vty *vty;
void *out;
const char *vty_newline;
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bet)
return;
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
/* no subtlvs for this type */
}
void
rfapi_print_tunneltype_option (
void *stream,
int column_offset,
void rfapi_print_tunneltype_option(void *stream, int column_offset,
struct rfapi_tunneltype_option *tto)
{
switch (tto->type)
{
switch (tto->type) {
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
print_encap_type_l2tpv3overip (stream, column_offset,
print_encap_type_l2tpv3overip(stream, column_offset,
&tto->bgpinfo.l2tpv3_ip);
break;
case BGP_ENCAP_TYPE_GRE:
print_encap_type_gre (stream, column_offset, &tto->bgpinfo.gre);
print_encap_type_gre(stream, column_offset, &tto->bgpinfo.gre);
break;
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
print_encap_type_transmit_tunnel_endpoint (stream, column_offset,
print_encap_type_transmit_tunnel_endpoint(
stream, column_offset,
&tto->bgpinfo.transmit_tunnel_endpoint);
break;
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
print_encap_type_ipsec_in_tunnel_mode (stream, column_offset,
&tto->bgpinfo.ipsec_tunnel);
print_encap_type_ipsec_in_tunnel_mode(
stream, column_offset, &tto->bgpinfo.ipsec_tunnel);
break;
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stream,
column_offset,
&tto->bgpinfo.ip_ipsec);
print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
stream, column_offset, &tto->bgpinfo.ip_ipsec);
break;
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (stream,
column_offset,
&tto->bgpinfo.mpls_ipsec);
print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
stream, column_offset, &tto->bgpinfo.mpls_ipsec);
break;
case BGP_ENCAP_TYPE_IP_IN_IP:
print_encap_type_ip_in_ip (stream, column_offset, &tto->bgpinfo.ip_ip);
print_encap_type_ip_in_ip(stream, column_offset,
&tto->bgpinfo.ip_ip);
break;
case BGP_ENCAP_TYPE_VXLAN:
print_encap_type_vxlan (stream, column_offset, &tto->bgpinfo.vxlan);
print_encap_type_vxlan(stream, column_offset,
&tto->bgpinfo.vxlan);
break;
case BGP_ENCAP_TYPE_NVGRE:
print_encap_type_nvgre (stream, column_offset, &tto->bgpinfo.nvgre);
print_encap_type_nvgre(stream, column_offset,
&tto->bgpinfo.nvgre);
break;
case BGP_ENCAP_TYPE_MPLS:
print_encap_type_mpls (stream, column_offset, &tto->bgpinfo.mpls);
print_encap_type_mpls(stream, column_offset,
&tto->bgpinfo.mpls);
break;
case BGP_ENCAP_TYPE_MPLS_IN_GRE:
print_encap_type_mpls_in_gre (stream, column_offset,
print_encap_type_mpls_in_gre(stream, column_offset,
&tto->bgpinfo.mpls_gre);
break;
case BGP_ENCAP_TYPE_VXLAN_GPE:
print_encap_type_vxlan_gpe (stream, column_offset,
print_encap_type_vxlan_gpe(stream, column_offset,
&tto->bgpinfo.vxlan_gpe);
break;
case BGP_ENCAP_TYPE_MPLS_IN_UDP:
print_encap_type_mpls_in_udp (stream, column_offset,
print_encap_type_mpls_in_udp(stream, column_offset,
&tto->bgpinfo.mpls_udp);
break;
case BGP_ENCAP_TYPE_PBB:
print_encap_type_pbb (stream, column_offset, &tto->bgpinfo.pbb);
print_encap_type_pbb(stream, column_offset, &tto->bgpinfo.pbb);
break;
default:
assert (0);
assert(0);
}
}

View File

@ -22,20 +22,13 @@
#define RFAPI_BGP_ENCAP_TYPE_DEFAULT BGP_ENCAP_TYPE_IP_IN_IP
extern bgp_encap_types
rfapi_tunneltype_option_to_tlv (
struct bgp *bgp,
struct rfapi_ip_addr *ea,
rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea,
struct rfapi_tunneltype_option *tto,
struct attr *attr,
int always_add);
struct attr *attr, int always_add);
extern struct rfapi_un_option *
rfapi_encap_tlv_to_un_option (struct attr *attr);
extern struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr);
extern void
rfapi_print_tunneltype_option (
void *stream,
int column_offset,
extern void rfapi_print_tunneltype_option(void *stream, int column_offset,
struct rfapi_tunneltype_option *tto);

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,7 @@
* routes are not segregated by RD - the RD is stored in bgp_info_extra
* and is needed to determine if two prefixes are the same.
*/
struct rfapi_import_table
{
struct rfapi_import_table {
struct rfapi_import_table *next;
struct rfapi_nve_group_cfg *rfg;
struct ecommunity *rt_import_list; /* copied from nve grp */
@ -56,7 +55,8 @@ struct rfapi_import_table
(((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP))
#define RFAPI_DIRECT_IMPORT_BI(bi) \
(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) || ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) \
|| ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \
if (RFAPI_LOCAL_BI(bi)) { \
@ -68,37 +68,25 @@ struct rfapi_import_table
(itable)->remote_count[(afi)] += (cnt); \
}
extern uint8_t
rfapiRfpCost (struct attr *attr);
extern uint8_t rfapiRfpCost(struct attr *attr);
extern void
rfapiDebugBacktrace (void);
extern void rfapiDebugBacktrace(void);
extern void
rfapiCheckRouteCount (void);
extern void rfapiCheckRouteCount(void);
/*
* Print BI in an Import Table
*/
extern void
rfapiPrintBi (void *stream, struct bgp_info *bi);
extern void rfapiPrintBi(void *stream, struct bgp_info *bi);
extern void
rfapiShowImportTable (
void *stream,
const char *label,
struct route_table *rt,
int isvpn);
extern void rfapiShowImportTable(void *stream, const char *label,
struct route_table *rt, int isvpn);
extern struct rfapi_import_table *
rfapiImportTableRefAdd (
struct bgp *bgp,
struct ecommunity *rt_import_list,
rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list,
struct rfapi_nve_group_cfg *rfg);
extern void
rfapiImportTableRefDelByIt (
struct bgp *bgp,
extern void rfapiImportTableRefDelByIt(struct bgp *bgp,
struct rfapi_import_table *it_target);
@ -111,53 +99,41 @@ rfapiImportTableRefDelByIt (
* 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.
*/
extern struct rfapi_next_hop_entry *
rfapiRouteNode2NextHopList (
struct route_node *rn,
uint32_t lifetime, /* put into nexthop entries */
extern struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
struct route_table *rfd_rib_table, /* preload this NVE rib table */
struct prefix *pfx_target_original); /* query target */
extern struct rfapi_next_hop_entry *
rfapiRouteTable2NextHopList (
extern struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList(
struct route_table *rt,
uint32_t lifetime, /* put into nexthop entries */
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
struct route_table *rfd_rib_table, /* preload this NVE rib table */
struct prefix *pfx_target_original); /* query target */
extern struct rfapi_next_hop_entry *
rfapiEthRouteTable2NextHopList (
uint32_t logical_net_id,
struct rfapi_ip_prefix *rprefix,
extern struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList(
uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix,
uint32_t lifetime, /* put into nexthop entries */
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
struct route_table *rib_route_table,/* preload NVE rib node */
struct route_table *rib_route_table, /* preload NVE rib node */
struct prefix *pfx_target_original); /* query target */
extern int
rfapiEcommunitiesIntersect (struct ecommunity *e1, struct ecommunity *e2);
extern int rfapiEcommunitiesIntersect(struct ecommunity *e1,
struct ecommunity *e2);
extern void
rfapiCheckRefcount (struct route_node *rn, safi_t safi, int lockoffset);
extern void rfapiCheckRefcount(struct route_node *rn, safi_t safi,
int lockoffset);
extern int
rfapiHasNonRemovedRoutes (struct route_node *rn);
extern int rfapiHasNonRemovedRoutes(struct route_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_info *bi, struct prefix *p);
extern void
rfapiNexthop2Prefix (struct attr *attr, struct prefix *p);
extern void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p);
extern void
rfapiUnicastNexthop2Prefix (
afi_t afi,
struct attr *attr,
extern void rfapiUnicastNexthop2Prefix(afi_t afi, struct attr *attr,
struct prefix *p);
/* Filtered Import Function actions */
@ -165,52 +141,36 @@ rfapiUnicastNexthop2Prefix (
#define FIF_ACTION_WITHDRAW 1
#define FIF_ACTION_KILL 2
extern void
rfapiBgpInfoFilteredImportVPN (
struct rfapi_import_table *import_table,
int action,
struct peer *peer,
extern void rfapiBgpInfoFilteredImportVPN(
struct rfapi_import_table *import_table, int action, struct peer *peer,
void *rfd, /* set for looped back routes */
struct prefix *p,
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 */
u_char type, /* part of bgp_info */
u_char sub_type, /* part of bgp_info */
uint32_t *label); /* part of bgp_info */
extern struct rfapi_next_hop_entry *
rfapiEthRouteNode2NextHopList (
struct route_node *rn,
struct rfapi_ip_prefix *rprefix,
extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
struct route_node *rn, struct rfapi_ip_prefix *rprefix,
uint32_t lifetime, /* put into nexthop entries */
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
struct route_table *rib_route_table,/* preload NVE rib table */
struct route_table *rib_route_table, /* preload NVE rib table */
struct prefix *pfx_target_original); /* query target */
extern struct rfapi_import_table *
rfapiMacImportTableGetNoAlloc (
struct bgp *bgp,
extern struct rfapi_import_table *rfapiMacImportTableGetNoAlloc(struct bgp *bgp,
uint32_t lni);
extern struct rfapi_import_table *
rfapiMacImportTableGet (
struct bgp *bgp,
extern struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp,
uint32_t lni);
extern int
rfapiGetL2o (
struct attr *attr,
struct rfapi_l2address_option *l2o);
extern int rfapiGetL2o(struct attr *attr, struct rfapi_l2address_option *l2o);
extern int rfapiEcommunityGetLNI (
struct ecommunity *ecom,
uint32_t *lni);
extern int rfapiEcommunityGetLNI(struct ecommunity *ecom, uint32_t *lni);
extern int rfapiEcommunityGetEthernetTag (
struct ecommunity *ecom,
uint16_t * tag_id);
extern int rfapiEcommunityGetEthernetTag(struct ecommunity *ecom,
uint16_t *tag_id);
/* enable for debugging; disable for performance */
#if 0
@ -239,14 +199,10 @@ extern int rfapiEcommunityGetEthernetTag (
* return value:
* void
--------------------------------------------*/
extern void
rfapiDeleteRemotePrefixes (
struct prefix *un,
struct prefix *vn,
extern void rfapiDeleteRemotePrefixes(struct prefix *un, struct prefix *vn,
struct prefix *p,
struct rfapi_import_table *it,
int delete_active,
int delete_holddown,
int delete_active, int delete_holddown,
uint32_t *pARcount, /* active routes */
uint32_t *pAHcount, /* active nves */
uint32_t *pHRcount, /* holddown routes */
@ -267,9 +223,7 @@ rfapiDeleteRemotePrefixes (
* return value:
* void
--------------------------------------------*/
extern void
rfapiCountAllItRoutes (
int *pALRcount, /* active local routes */
extern void rfapiCountAllItRoutes(int *pALRcount, /* active local routes */
int *pARRcount, /* active remote routes */
int *pHRcount, /* holddown routes */
int *pIRcount); /* direct imported routes */
@ -287,7 +241,6 @@ rfapiCountAllItRoutes (
* and RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY
*
--------------------------------------------*/
extern uint32_t
rfapiGetHolddownFromLifetime (uint32_t lifetime);
extern uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime);
#endif /* QUAGGA_HGP_RFAPI_IMPORT_H */

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,7 @@
* These get attached to the nodes in an import table (using "aggregate" ptr)
* to indicate which nves are interested in a prefix/target
*/
struct rfapi_monitor_vpn
{
struct rfapi_monitor_vpn {
struct rfapi_monitor_vpn *next; /* chain from struct route_node */
struct rfapi_descriptor *rfd; /* which NVE requested the route */
struct prefix p; /* constant: pfx in original request */
@ -38,12 +37,11 @@ struct rfapi_monitor_vpn
uint32_t flags;
#define RFAPI_MON_FLAG_NEEDCALLBACK 0x00000001 /* deferred callback */
//int dcount; /* debugging counter */
// int dcount; /* debugging counter */
struct thread *timer;
};
struct rfapi_monitor_encap
{
struct rfapi_monitor_encap {
struct rfapi_monitor_encap *next;
struct rfapi_monitor_encap *prev;
struct route_node *node; /* VPN node */
@ -51,8 +49,7 @@ struct rfapi_monitor_encap
struct route_node *rn; /* parent node */
};
struct rfapi_monitor_eth
{
struct rfapi_monitor_eth {
struct rfapi_monitor_eth *next; /* for use in vpn0_queries list */
struct rfapi_descriptor *rfd; /* which NVE requested the route */
struct ethaddr macaddr;
@ -75,35 +72,36 @@ struct rfapi_monitor_eth
* - one lock per chained struct rfapi_monitor_encap
*
*/
struct rfapi_it_extra
{
union
{
struct
{
struct rfapi_it_extra {
union {
struct {
struct rfapi_monitor_vpn *v;
struct skiplist *idx_rd; /* RD index */
struct skiplist *mon_eth; /* ether queries */
struct
{
/* routes with UN addrs, either cached encap or Encap TLV */
struct {
/* routes with UN addrs, either cached encap or
* Encap TLV */
int valid_interior_count;
/* unicast exterior routes, key=bi, val=allocated prefix */
/* unicast exterior routes, key=bi,
* val=allocated prefix */
struct skiplist *source;
} e;
} vpn;
struct
{
struct {
struct rfapi_monitor_encap *e;
} encap;
} u;
};
#define RFAPI_IT_EXTRA_GET(rn) ((struct rfapi_it_extra *)( \
(rn)->aggregate? (rn)->aggregate: \
(route_lock_node(rn), (rn)->aggregate = \
XCALLOC(MTYPE_RFAPI_IT_EXTRA,sizeof(struct rfapi_it_extra)))))
#define RFAPI_IT_EXTRA_GET(rn) \
((struct rfapi_it_extra \
*)((rn)->aggregate \
? (rn)->aggregate \
: (route_lock_node(rn), \
(rn)->aggregate = XCALLOC( \
MTYPE_RFAPI_IT_EXTRA, \
sizeof(struct rfapi_it_extra)))))
#define RFAPI_RDINDEX(rn) \
((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd : NULL)
@ -127,89 +125,65 @@ struct rfapi_it_extra
#define RFAPI_MONITOR_EXTERIOR(rn) (&(RFAPI_IT_EXTRA_GET(rn)->u.vpn.e))
#define RFAPI_HAS_MONITOR_EXTERIOR(rn) (rn && rn->aggregate && \
((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source && \
!skiplist_first(((struct rfapi_it_extra *)(rn->aggregate))-> \
u.vpn.e.source, NULL, NULL))
#define RFAPI_HAS_MONITOR_EXTERIOR(rn) \
(rn && rn->aggregate \
&& ((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source \
&& !skiplist_first(((struct rfapi_it_extra *)(rn->aggregate)) \
->u.vpn.e.source, \
NULL, NULL))
extern void
rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain);
extern void rfapiMonitorLoopCheck(struct rfapi_monitor_vpn *mchain);
extern void
rfapiMonitorCleanCheck (struct bgp *bgp);
extern void rfapiMonitorCleanCheck(struct bgp *bgp);
extern void
rfapiMonitorCheckAttachAllowed (void);
extern void rfapiMonitorCheckAttachAllowed(void);
extern void
rfapiMonitorExtraFlush (safi_t safi, struct route_node *rn);
extern void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn);
extern struct route_node *
rfapiMonitorGetAttachNode (struct rfapi_descriptor *rfd, struct prefix *p);
rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, struct prefix *p);
extern void
rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd);
extern void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd);
extern struct route_node *
rfapiMonitorAdd (
struct bgp *bgp,
extern struct route_node *rfapiMonitorAdd(struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *p);
extern void
rfapiMonitorDetachImportHd (struct rfapi_descriptor *rfd);
extern void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd);
extern void
rfapiMonitorDel (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
extern void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct prefix *p);
extern int
rfapiMonitorDelHd (struct rfapi_descriptor *rfd);
extern int rfapiMonitorDelHd(struct rfapi_descriptor *rfd);
extern void
rfapiMonitorCallbacksOff (struct bgp *bgp);
extern void rfapiMonitorCallbacksOff(struct bgp *bgp);
extern void
rfapiMonitorCallbacksOn (struct bgp *bgp);
extern void rfapiMonitorCallbacksOn(struct bgp *bgp);
extern void
rfapiMonitorResponseRemovalOff (struct bgp *bgp);
extern void rfapiMonitorResponseRemovalOff(struct bgp *bgp);
extern void
rfapiMonitorResponseRemovalOn (struct bgp *bgp);
extern void rfapiMonitorResponseRemovalOn(struct bgp *bgp);
extern void
rfapiMonitorExtraPrune (safi_t safi, struct route_node *rn);
extern void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn);
extern void
rfapiMonitorTimersRestart (struct rfapi_descriptor *rfd, struct prefix *p);
extern void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd,
struct prefix *p);
extern void
rfapiMonitorItNodeChanged (
struct rfapi_import_table *import_table,
extern void rfapiMonitorItNodeChanged(struct rfapi_import_table *import_table,
struct route_node *it_node,
struct rfapi_monitor_vpn *monitor_list);
extern void
rfapiMonitorMovedUp (
struct rfapi_import_table *import_table,
extern void rfapiMonitorMovedUp(struct rfapi_import_table *import_table,
struct route_node *old_node,
struct route_node *new_node,
struct rfapi_monitor_vpn *monitor_list);
extern struct route_node *
rfapiMonitorEthAdd (
struct bgp *bgp,
extern struct route_node *rfapiMonitorEthAdd(struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct ethaddr *macaddr,
uint32_t logical_net_id);
extern void
rfapiMonitorEthDel (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
extern void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct ethaddr *macaddr,
uint32_t logical_net_id);

View File

@ -41,111 +41,94 @@
#define DEBUG_NVE_ADDR 0
void rfapiNveAddr2Str (struct rfapi_nve_addr *, char *, int);
void rfapiNveAddr2Str(struct rfapi_nve_addr *, char *, int);
#if DEBUG_NVE_ADDR
static void
logdifferent (const char *tag,
struct rfapi_nve_addr *a, struct rfapi_nve_addr *b)
static void logdifferent(const char *tag, struct rfapi_nve_addr *a,
struct rfapi_nve_addr *b)
{
char a_str[BUFSIZ];
char b_str[BUFSIZ];
rfapiNveAddr2Str (a, a_str, BUFSIZ);
rfapiNveAddr2Str (b, b_str, BUFSIZ);
vnc_zlog_debug_verbose ("%s: [%s] [%s]", tag, a_str, b_str);
rfapiNveAddr2Str(a, a_str, BUFSIZ);
rfapiNveAddr2Str(b, b_str, BUFSIZ);
vnc_zlog_debug_verbose("%s: [%s] [%s]", tag, a_str, b_str);
}
#endif
int
rfapi_nve_addr_cmp (void *k1, void *k2)
int rfapi_nve_addr_cmp(void *k1, void *k2)
{
struct rfapi_nve_addr *a = (struct rfapi_nve_addr *) k1;
struct rfapi_nve_addr *b = (struct rfapi_nve_addr *) k2;
struct rfapi_nve_addr *a = (struct rfapi_nve_addr *)k1;
struct rfapi_nve_addr *b = (struct rfapi_nve_addr *)k2;
int ret = 0;
if (!a || !b)
{
if (!a || !b) {
#if DEBUG_NVE_ADDR
vnc_zlog_debug_verbose ("%s: missing address a=%p b=%p", __func__, a, b);
vnc_zlog_debug_verbose("%s: missing address a=%p b=%p",
__func__, a, b);
#endif
return (a - b);
}
if (a->un.addr_family != b->un.addr_family)
{
if (a->un.addr_family != b->un.addr_family) {
#if DEBUG_NVE_ADDR
vnc_zlog_debug_verbose ("diff: UN addr fam a->un.af=%d, b->un.af=%d",
vnc_zlog_debug_verbose(
"diff: UN addr fam a->un.af=%d, b->un.af=%d",
a->un.addr_family, b->un.addr_family);
#endif
return (a->un.addr_family - b->un.addr_family);
}
if (a->un.addr_family == AF_INET)
{
ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4);
if (ret != 0)
{
if (a->un.addr_family == AF_INET) {
ret = IPV4_ADDR_CMP(&a->un.addr.v4, &b->un.addr.v4);
if (ret != 0) {
#if DEBUG_NVE_ADDR
logdifferent ("diff: UN addr", a, b);
logdifferent("diff: UN addr", a, b);
#endif
return ret;
}
}
else if (a->un.addr_family == AF_INET6)
{
ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6);
if (ret == 0)
{
} else if (a->un.addr_family == AF_INET6) {
ret = IPV6_ADDR_CMP(&a->un.addr.v6, &b->un.addr.v6);
if (ret == 0) {
#if DEBUG_NVE_ADDR
logdifferent ("diff: UN addr", a, b);
logdifferent("diff: UN addr", a, b);
#endif
return ret;
}
} else {
assert(0);
}
else
{
assert (0);
}
if (a->vn.addr_family != b->vn.addr_family)
{
if (a->vn.addr_family != b->vn.addr_family) {
#if DEBUG_NVE_ADDR
vnc_zlog_debug_verbose ("diff: pT addr fam a->vn.af=%d, b->vn.af=%d",
vnc_zlog_debug_verbose(
"diff: pT addr fam a->vn.af=%d, b->vn.af=%d",
a->vn.addr_family, b->vn.addr_family);
#endif
return (a->vn.addr_family - b->vn.addr_family);
}
if (a->vn.addr_family == AF_INET)
{
ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4);
if (ret != 0)
{
if (a->vn.addr_family == AF_INET) {
ret = IPV4_ADDR_CMP(&a->vn.addr.v4, &b->vn.addr.v4);
if (ret != 0) {
#if DEBUG_NVE_ADDR
logdifferent ("diff: VN addr", a, b);
logdifferent("diff: VN addr", a, b);
#endif
return ret;
}
}
else if (a->vn.addr_family == AF_INET6)
{
ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6);
if (ret == 0)
{
} else if (a->vn.addr_family == AF_INET6) {
ret = IPV6_ADDR_CMP(&a->vn.addr.v6, &b->vn.addr.v6);
if (ret == 0) {
#if DEBUG_NVE_ADDR
logdifferent ("diff: VN addr", a, b);
logdifferent("diff: VN addr", a, b);
#endif
return ret;
}
}
else
{
assert (0);
} else {
assert(0);
}
return 0;
}
void
rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize)
void rfapiNveAddr2Str(struct rfapi_nve_addr *na, char *buf, int bufsize)
{
char *p = buf;
int r;
@ -156,19 +139,19 @@ rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize)
if (bufsize < 1)
return;
r = snprintf (p, REMAIN, "VN=");
r = snprintf(p, REMAIN, "VN=");
INCP;
if (!rfapiRfapiIpAddr2Str (&na->vn, p, REMAIN))
if (!rfapiRfapiIpAddr2Str(&na->vn, p, REMAIN))
goto done;
buf[bufsize - 1] = 0;
p = buf + strlen (buf);
p = buf + strlen(buf);
r = snprintf (p, REMAIN, ", UN=");
r = snprintf(p, REMAIN, ", UN=");
INCP;
rfapiRfapiIpAddr2Str (&na->un, p, REMAIN);
rfapiRfapiIpAddr2Str(&na->un, p, REMAIN);
done:
buf[bufsize - 1] = 0;

View File

@ -23,20 +23,16 @@
#include "rfapi.h"
struct rfapi_nve_addr
{
struct rfapi_nve_addr {
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
void *info;
};
extern int
rfapi_nve_addr_cmp (void *k1, void *k2);
extern void
rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize);
extern int rfapi_nve_addr_cmp(void *k1, void *k2);
extern void rfapiNveAddr2Str(struct rfapi_nve_addr *na, char *buf, int bufsize);
#endif /* _QUAGGA_BGP_RFAPI_NVE_ADDR_H */

View File

@ -40,15 +40,13 @@
* 1. each is referenced in by_lifetime
* 2. each is referenced by exactly one of: ipN_by_prefix, ip0_by_ether
*/
struct rfapi_advertised_prefixes
{
struct rfapi_advertised_prefixes {
struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */
struct skiplist *ip0_by_ether; /* ip prefix 0/32, 0/128 */
struct skiplist *by_lifetime; /* all */
};
struct rfapi_descriptor
{
struct rfapi_descriptor {
struct route_node *un_node; /* backref to un table */
struct rfapi_descriptor *next; /* next vn_addr */
@ -138,15 +136,17 @@ struct rfapi_descriptor
#define RFAPI_HD_FLAG_IS_VRF 0x00000012
};
#define RFAPI_QUEUED_FLAG(afi) ( \
((afi) == AFI_IP)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP: \
(((afi) == AFI_IP6)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6: \
(((afi) == AFI_L2VPN)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN: \
(assert(0), 0) )))
#define RFAPI_QUEUED_FLAG(afi) \
(((afi) == AFI_IP) \
? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP \
: (((afi) == AFI_IP6) \
? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 \
: (((afi) == AFI_L2VPN) \
? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN \
: (assert(0), 0))))
struct rfapi_global_stats
{
struct rfapi_global_stats {
time_t last_reset;
unsigned int max_descriptors;
@ -170,11 +170,10 @@ struct rfapi_global_stats
* Radix tree is indexed by un address; follow chain and
* check vn address to get exact match.
*/
struct rfapi
{
struct rfapi {
struct route_table un[AFI_MAX];
struct rfapi_import_table *imports; /* IPv4, IPv6 */
struct list descriptors;/* debug & resolve-nve imports */
struct list descriptors; /* debug & resolve-nve imports */
struct rfapi_global_stats stat;
@ -239,144 +238,112 @@ struct rfapi
void *rfp; /* from rfp_start */
};
#define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) do { \
#define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) \
do { \
++(rfd)->rib_prefix_count; \
++(rfapi)->rib_prefix_count_total; \
if ((rfapi)->rib_prefix_count_total > (rfapi)->rib_prefix_count_total_max) \
if ((rfapi)->rib_prefix_count_total \
> (rfapi)->rib_prefix_count_total_max) \
++(rfapi)->rib_prefix_count_total_max; \
} while (0)
#define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi) do { \
#define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi) \
do { \
--(rfd)->rib_prefix_count; \
--(rfapi)->rib_prefix_count_total; \
} while (0)
#define RFAPI_0_PREFIX(prefix) ( \
(((prefix)->family == AF_INET)? (prefix)->u.prefix4.s_addr == 0: \
(((prefix)->family == AF_INET6)? \
(IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) : 0)) \
)
#define RFAPI_0_PREFIX(prefix) \
((((prefix)->family == AF_INET) \
? (prefix)->u.prefix4.s_addr == 0 \
: (((prefix)->family == AF_INET6) \
? (IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) \
: 0)))
#define RFAPI_0_ETHERADDR(ea) ( \
((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | \
(ea)->octet[3] | (ea)->octet[4] | (ea)->octet[5]) == 0)
#define RFAPI_0_ETHERADDR(ea) \
(((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | (ea)->octet[3] \
| (ea)->octet[4] | (ea)->octet[5]) \
== 0)
#define RFAPI_HOST_PREFIX(prefix) ( \
((prefix)->family == AF_INET)? ((prefix)->prefixlen == 32): \
(((prefix)->family == AF_INET6)? ((prefix)->prefixlen == 128): 0) )
#define RFAPI_HOST_PREFIX(prefix) \
(((prefix)->family == AF_INET) \
? ((prefix)->prefixlen == 32) \
: (((prefix)->family == AF_INET6) \
? ((prefix)->prefixlen == 128) \
: 0))
extern void
rfapiQprefix2Rprefix (
struct prefix *qprefix,
extern void rfapiQprefix2Rprefix(struct prefix *qprefix,
struct rfapi_ip_prefix *rprefix);
extern int
rfapi_find_rfd (
struct bgp *bgp,
struct rfapi_ip_addr *vn_addr,
extern int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
struct rfapi_ip_addr *un_addr,
struct rfapi_descriptor **rfd);
extern void
add_vnc_route (
struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */
struct bgp *bgp,
int safi,
struct prefix *p,
struct prefix_rd *prd,
struct rfapi_ip_addr *nexthop,
add_vnc_route(struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */
struct bgp *bgp, int safi, struct prefix *p,
struct prefix_rd *prd, struct rfapi_ip_addr *nexthop,
uint32_t *local_pref, /* host byte order */
uint32_t *lifetime, /* host byte order */
struct bgp_tea_options *rfp_options,
struct rfapi_un_option *options_un,
struct rfapi_vn_option *options_vn,
struct ecommunity *rt_export_list,
uint32_t *med,
uint32_t *label,
uint8_t type,
uint8_t sub_type,
int flags);
struct ecommunity *rt_export_list, uint32_t *med, uint32_t *label,
uint8_t type, uint8_t sub_type, int flags);
#define RFAPI_AHR_NO_TUNNEL_SUBTLV 0x00000001
#define RFAPI_AHR_RFPOPT_IS_VNCTLV 0x00000002 /* hack! */
#if 0 /* unused? */
# define RFAPI_AHR_SET_PFX_TO_NEXTHOP 0x00000004
#endif
extern void
del_vnc_route (
struct rfapi_descriptor *rfd,
struct peer *peer,
struct bgp *bgp,
safi_t safi,
struct prefix *p,
struct prefix_rd *prd,
uint8_t type,
uint8_t sub_type,
struct rfapi_nexthop *lnh,
int kill);
extern void del_vnc_route(struct rfapi_descriptor *rfd, struct peer *peer,
struct bgp *bgp, safi_t safi, struct prefix *p,
struct prefix_rd *prd, uint8_t type, uint8_t sub_type,
struct rfapi_nexthop *lnh, int kill);
extern int
rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p);
extern int rfapiCliGetPrefixAddr(struct vty *vty, const char *str,
struct prefix *p);
extern int
rfapiGetVncLifetime (struct attr *attr, uint32_t * lifetime);
extern int rfapiGetVncLifetime(struct attr *attr, uint32_t *lifetime);
extern int
rfapiGetTunnelType (struct attr *attr, bgp_encap_types *type);
extern int rfapiGetTunnelType(struct attr *attr, bgp_encap_types *type);
extern int
rfapiGetVncTunnelUnAddr (struct attr *attr, struct prefix *p);
extern int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p);
extern int
rfapi_reopen (struct rfapi_descriptor *rfd, struct bgp *bgp);
extern int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp);
extern void
vnc_import_bgp_add_rfp_host_route_mode_resolve_nve (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *prefix);
extern void vnc_import_bgp_add_rfp_host_route_mode_resolve_nve(
struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix);
extern void
vnc_import_bgp_del_rfp_host_route_mode_resolve_nve (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *prefix);
extern void vnc_import_bgp_del_rfp_host_route_mode_resolve_nve(
struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix);
extern void
rfapiFreeBgpTeaOptionChain (struct bgp_tea_options *p);
extern void rfapiFreeBgpTeaOptionChain(struct bgp_tea_options *p);
extern struct rfapi_vn_option *rfapiVnOptionsDup(struct rfapi_vn_option *orig);
extern struct rfapi_un_option *rfapiUnOptionsDup(struct rfapi_un_option *orig);
extern struct bgp_tea_options *rfapiOptionsDup(struct bgp_tea_options *orig);
extern int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1,
struct rfapi_ip_addr *a2);
extern uint32_t rfp_cost_to_localpref(uint8_t cost);
extern int rfapi_set_autord_from_vn(struct prefix_rd *rd,
struct rfapi_ip_addr *vn);
extern struct rfapi_nexthop *rfapi_nexthop_new(struct rfapi_nexthop *copyme);
extern void rfapi_nexthop_free(void *goner);
extern struct rfapi_vn_option *
rfapiVnOptionsDup (struct rfapi_vn_option *orig);
rfapi_vn_options_dup(struct rfapi_vn_option *existing);
extern struct rfapi_un_option *
rfapiUnOptionsDup (struct rfapi_un_option *orig);
extern void rfapi_un_options_free(struct rfapi_un_option *goner);
extern struct bgp_tea_options *
rfapiOptionsDup (struct bgp_tea_options *orig);
extern int
rfapi_ip_addr_cmp (struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2);
extern uint32_t
rfp_cost_to_localpref (uint8_t cost);
extern int
rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn);
extern struct rfapi_nexthop *
rfapi_nexthop_new (struct rfapi_nexthop *copyme);
extern void
rfapi_nexthop_free (void *goner);
extern struct rfapi_vn_option *
rfapi_vn_options_dup (struct rfapi_vn_option *existing);
extern void
rfapi_un_options_free (struct rfapi_un_option *goner);
extern void
rfapi_vn_options_free (struct rfapi_vn_option *goner);
extern void rfapi_vn_options_free(struct rfapi_vn_option *goner);
/*------------------------------------------
* rfapi_extract_l2o
@ -394,8 +361,7 @@ rfapi_vn_options_free (struct rfapi_vn_option *goner);
* 1 no options found
*
--------------------------------------------*/
extern int
rfapi_extract_l2o (
extern int rfapi_extract_l2o(
struct bgp_tea_options *pHop, /* chain of options */
struct rfapi_l2address_option *l2o); /* return extracted value */
@ -404,7 +370,7 @@ rfapi_extract_l2o (
* time_t value in terms of stabilised absolute time.
* replacement for POSIX time()
*/
extern time_t rfapi_time (time_t *t);
extern time_t rfapi_time(time_t *t);
DECLARE_MGROUP(RFAPI)
DECLARE_MTYPE(RFAPI_CFG)
@ -441,10 +407,7 @@ DECLARE_MTYPE(RFAPI_MONITOR_ETH)
* The advertised_prefixes[] array elements should be NULL to
* have this function set them to newly-allocated radix trees.
*/
extern int
rfapi_init_and_open(
struct bgp *bgp,
struct rfapi_descriptor *rfd,
extern int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct rfapi_nve_group_cfg *rfg);
#endif /* _QUAGGA_BGP_RFAPI_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@ -33,8 +33,7 @@
* For L2 RIBs, it is possible to have multiple routes to a given L2
* prefix via a given VN address, but each route having a unique aux_prefix.
*/
struct rfapi_rib_key
{
struct rfapi_rib_key {
struct prefix vn;
struct prefix_rd rd;
@ -51,8 +50,7 @@ struct rfapi_rib_key
*
* Holds NVE prefix advertisement information
*/
struct rfapi_adb
{
struct rfapi_adb {
union {
struct {
struct prefix prefix_ip;
@ -66,8 +64,7 @@ struct rfapi_adb
struct rfapi_l2address_option l2o;
};
struct rfapi_info
{
struct rfapi_info {
struct rfapi_rib_key rk; /* NVE VN addr + aux addr */
struct prefix un;
uint8_t cost;
@ -83,85 +80,59 @@ struct rfapi_info
/*
* Work item for updated responses queue
*/
struct rfapi_updated_responses_queue
{
struct rfapi_updated_responses_queue {
struct rfapi_descriptor *rfd;
afi_t afi;
};
extern void
rfapiRibClear (struct rfapi_descriptor *rfd);
extern void rfapiRibClear(struct rfapi_descriptor *rfd);
extern void
rfapiRibFree (struct rfapi_descriptor *rfd);
extern void rfapiRibFree(struct rfapi_descriptor *rfd);
extern void
rfapiRibUpdatePendingNode (
struct bgp *bgp,
extern void rfapiRibUpdatePendingNode(struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct rfapi_import_table *it,
struct route_node *it_node,
uint32_t lifetime);
extern void
rfapiRibUpdatePendingNodeSubtree (
struct bgp *bgp,
extern void rfapiRibUpdatePendingNodeSubtree(struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct rfapi_import_table *it,
struct route_node *it_node,
struct route_node *omit_subtree,
uint32_t lifetime);
extern int
rfapiRibPreloadBi(
struct route_node *rfd_rib_node,
struct prefix *pfx_vn,
struct prefix *pfx_un,
uint32_t lifetime,
struct bgp_info *bi);
extern int rfapiRibPreloadBi(struct route_node *rfd_rib_node,
struct prefix *pfx_vn, struct prefix *pfx_un,
uint32_t lifetime, struct bgp_info *bi);
extern struct rfapi_next_hop_entry *
rfapiRibPreload (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct rfapi_next_hop_entry *response,
int use_eth_resolution);
rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct rfapi_next_hop_entry *response, int use_eth_resolution);
extern void
rfapiRibPendingDeleteRoute (
struct bgp *bgp,
struct rfapi_import_table *it,
afi_t afi,
extern void rfapiRibPendingDeleteRoute(struct bgp *bgp,
struct rfapi_import_table *it, afi_t afi,
struct route_node *it_node);
extern void
rfapiRibShowResponsesSummary (void *stream);
extern void rfapiRibShowResponsesSummary(void *stream);
extern void
rfapiRibShowResponsesSummaryClear (void);
extern void rfapiRibShowResponsesSummaryClear(void);
extern void
rfapiRibShowResponses (
void *stream,
struct prefix *pfx_match,
extern void rfapiRibShowResponses(void *stream, struct prefix *pfx_match,
int show_removed);
extern int
rfapiRibFTDFilterRecentPrefix(
extern int rfapiRibFTDFilterRecentPrefix(
struct rfapi_descriptor *rfd,
struct route_node *it_rn, /* import table node */
struct prefix *pfx_target_original); /* query target */
extern void
rfapiFreeRfapiUnOptionChain (struct rfapi_un_option *p);
extern void rfapiFreeRfapiUnOptionChain(struct rfapi_un_option *p);
extern void rfapiFreeRfapiVnOptionChain(struct rfapi_vn_option *p);
extern void
rfapiFreeRfapiVnOptionChain (struct rfapi_vn_option *p);
extern void
rfapiRibCheckCounts (
int checkstats, /* validate rfd & global counts */
rfapiRibCheckCounts(int checkstats, /* validate rfd & global counts */
unsigned int offset); /* number of ri's held separately */
/* enable for debugging; disable for performance */
@ -171,16 +142,13 @@ rfapiRibCheckCounts (
#define RFAPI_RIB_CHECK_COUNTS(checkstats, offset)
#endif
extern void
rfapi_rib_key_init (struct prefix *prefix, /* may be NULL */
extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */
struct prefix_rd *rd, /* may be NULL */
struct prefix *aux, /* may be NULL */
struct rfapi_rib_key *rk);
extern int
rfapi_rib_key_cmp (void *k1, void *k2);
extern int rfapi_rib_key_cmp(void *k1, void *k2);
extern void
rfapiAdbFree (struct rfapi_adb *adb);
extern void rfapiAdbFree(struct rfapi_adb *adb);
#endif /* QUAGGA_HGP_RFAPI_RIB_H */

File diff suppressed because it is too large Load Diff

View File

@ -23,8 +23,7 @@
#include "lib/vty.h"
typedef enum
{
typedef enum {
SHOW_NVE_SUMMARY_ACTIVE_NVES,
SHOW_NVE_SUMMARY_UNKNOWN_NVES, /* legacy */
SHOW_NVE_SUMMARY_REGISTERED,
@ -35,52 +34,38 @@ typedef enum
#define VNC_SHOW_STR "VNC information\n"
extern char *
rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len);
extern char *rfapiFormatSeconds(uint32_t seconds, char *buf, size_t len);
extern char *
rfapiFormatAge (time_t age, char *buf, size_t len);
extern char *rfapiFormatAge(time_t age, char *buf, size_t len);
extern void
rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix);
extern void rfapiRprefixApplyMask(struct rfapi_ip_prefix *rprefix);
extern int
rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr);
extern int rfapiQprefix2Raddr(struct prefix *qprefix,
struct rfapi_ip_addr *raddr);
extern void
rfapiQprefix2Rprefix (struct prefix *qprefix,
extern void rfapiQprefix2Rprefix(struct prefix *qprefix,
struct rfapi_ip_prefix *rprefix);
extern int
rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix,
extern int rfapiRprefix2Qprefix(struct rfapi_ip_prefix *rprefix,
struct prefix *qprefix);
extern int
rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx);
extern int rfapiRaddr2Qprefix(struct rfapi_ip_addr *hia, struct prefix *pfx);
extern int
rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2);
extern int rfapiRprefixSame(struct rfapi_ip_prefix *hp1,
struct rfapi_ip_prefix *hp2);
extern void
rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx);
extern void rfapiL2o2Qprefix(struct rfapi_l2address_option *l2o,
struct prefix *pfx);
extern int
rfapiStr2EthAddr (const char *str, struct ethaddr *ea);
extern int rfapiStr2EthAddr(const char *str, struct ethaddr *ea);
extern const char *
rfapi_ntop (
int af,
const void *src,
char *buf,
extern const char *rfapi_ntop(int af, const void *src, char *buf,
socklen_t size);
extern int
rfapiDebugPrintf (void *dummy, const char *format, ...);
extern int rfapiDebugPrintf(void *dummy, const char *format, ...);
extern int
rfapiStream2Vty (
void *stream, /* input */
int (**fp) (void *, const char *, ...), /* output */
extern int rfapiStream2Vty(void *stream, /* input */
int (**fp)(void *, const char *, ...), /* output */
struct vty **vty, /* output */
void **outstream, /* output */
const char **vty_newline); /* output */
@ -101,75 +86,50 @@ rfapiStream2Vty (
* NULL conversion failed
* non-NULL pointer to buf
--------------------------------------------*/
extern const char *
rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize);
extern const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr *a, char *buf,
int bufsize);
extern void
rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a);
extern void rfapiPrintRfapiIpAddr(void *stream, struct rfapi_ip_addr *a);
extern void
rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p);
extern void rfapiPrintRfapiIpPrefix(void *stream, struct rfapi_ip_prefix *p);
void
rfapiPrintRd (struct vty *vty, struct prefix_rd *prd);
void rfapiPrintRd(struct vty *vty, struct prefix_rd *prd);
extern void
rfapiPrintAdvertisedInfo (
struct vty *vty,
struct rfapi_descriptor *rfd,
safi_t safi,
extern void rfapiPrintAdvertisedInfo(struct vty *vty,
struct rfapi_descriptor *rfd, safi_t safi,
struct prefix *p);
extern void
rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd);
extern void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd);
extern void
rfapiPrintMatchingDescriptors (struct vty *vty,
extern void rfapiPrintMatchingDescriptors(struct vty *vty,
struct prefix *vn_prefix,
struct prefix *un_prefix);
extern void
rfapiPrintAttrPtrs (void *stream, struct attr *attr);
extern void rfapiPrintAttrPtrs(void *stream, struct attr *attr);
/*
* Parse an address and put into a struct prefix
*/
extern int
rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p);
extern int rfapiCliGetPrefixAddr(struct vty *vty, const char *str,
struct prefix *p);
extern int
rfapiCliGetRfapiIpAddr (
struct vty *vty,
const char *str,
extern int rfapiCliGetRfapiIpAddr(struct vty *vty, const char *str,
struct rfapi_ip_addr *hai);
extern void
rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops);
extern void rfapiPrintNhl(void *stream, struct rfapi_next_hop_entry *next_hops);
extern char *
rfapiMonitorVpn2Str (
struct rfapi_monitor_vpn *m,
char *buf,
extern char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn *m, char *buf,
int size);
extern const char *
rfapiRfapiIpPrefix2Str (
struct rfapi_ip_prefix *p,
char *buf,
extern const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix *p, char *buf,
int bufsize);
extern void
rfapiShowItNode (void *stream, struct route_node *rn);
extern void rfapiShowItNode(void *stream, struct route_node *rn);
extern char *
rfapiEthAddr2Str (
const struct ethaddr *ea,
char *buf,
int bufsize);
extern char *rfapiEthAddr2Str(const struct ethaddr *ea, char *buf, int bufsize);
/* install vty commands */
extern void
rfapi_vty_init (void);
extern void rfapi_vty_init(void);
/*------------------------------------------
* rfapiShowRemoteRegistrations
@ -189,14 +149,10 @@ rfapi_vty_init (void);
* 0 nothing printed
* >0 something printed
--------------------------------------------*/
extern int
rfapiShowRemoteRegistrations (
void *stream,
extern int rfapiShowRemoteRegistrations(void *stream,
struct prefix *prefix_only,
int show_expiring,
int show_local,
int show_remote,
int show_imported);
int show_expiring, int show_local,
int show_remote, int show_imported);
/*------------------------------------------
* rfapi_monitor_count
@ -212,11 +168,9 @@ rfapiShowRemoteRegistrations (
* return value:
* count of monitors
--------------------------------------------*/
extern uint32_t
rfapi_monitor_count (rfapi_handle);
extern uint32_t rfapi_monitor_count(rfapi_handle);
extern int
rfapiShowVncQueries (void *stream, struct prefix *pfx_match);
extern int rfapiShowVncQueries(void *stream, struct prefix *pfx_match);
#endif

View File

@ -38,8 +38,7 @@ struct vnc_debug {
const char *name;
};
struct vnc_debug vncdebug[] =
{
struct vnc_debug vncdebug[] = {
{VNC_DEBUG_RFAPI_QUERY, "rfapi-query"},
{VNC_DEBUG_IMPORT_BI_ATTACH, "import-bi-attach"},
{VNC_DEBUG_IMPORT_DEL_REMOTE, "import-del-remote"},
@ -67,25 +66,20 @@ DEFUN (debug_bgp_vnc,
{
size_t i;
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
{
if (strmatch(argv[3]->text, vncdebug[i].name))
{
if (vty->node == CONFIG_NODE)
{
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) {
if (strmatch(argv[3]->text, vncdebug[i].name)) {
if (vty->node == CONFIG_NODE) {
conf_vnc_debug |= vncdebug[i].bit;
term_vnc_debug |= vncdebug[i].bit;
}
else
{
} else {
term_vnc_debug |= vncdebug[i].bit;
vty_out (vty, "BGP vnc %s debugging is on\n",
vty_out(vty, "BGP vnc %s debugging is on\n",
vncdebug[i].name);
}
return CMD_SUCCESS;
}
}
vty_out (vty, "Unknown debug flag: %s\n", argv[3]->arg);
vty_out(vty, "Unknown debug flag: %s\n", argv[3]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
@ -106,25 +100,20 @@ DEFUN (no_debug_bgp_vnc,
if (strmatch(argv[0]->text, "no"))
argc--, argv++;
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
{
if (strmatch(argv[3]->text, vncdebug[i].name))
{
if (vty->node == CONFIG_NODE)
{
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) {
if (strmatch(argv[3]->text, vncdebug[i].name)) {
if (vty->node == CONFIG_NODE) {
conf_vnc_debug &= ~vncdebug[i].bit;
term_vnc_debug &= ~vncdebug[i].bit;
}
else
{
} else {
term_vnc_debug &= ~vncdebug[i].bit;
vty_out (vty, "BGP vnc %s debugging is off\n",
vty_out(vty, "BGP vnc %s debugging is off\n",
vncdebug[i].name);
}
return CMD_SUCCESS;
}
}
vty_out (vty, "Unknown debug flag: %s\n", argv[3]->arg);
vty_out(vty, "Unknown debug flag: %s\n", argv[3]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
@ -144,7 +133,7 @@ DEFUN (no_debug_bgp_vnc_all,
VNC_STR)
{
term_vnc_debug = 0;
vty_out (vty, "All possible VNC debugging has been turned off\n");
vty_out(vty, "All possible VNC debugging has been turned off\n");
return CMD_SUCCESS;
}
@ -163,53 +152,42 @@ DEFUN (show_debugging_bgp_vnc,
{
size_t i;
vty_out (vty, "BGP VNC debugging status:\n");
vty_out(vty, "BGP VNC debugging status:\n");
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
{
if (term_vnc_debug & vncdebug[i].bit)
{
vty_out (vty, " BGP VNC %s debugging is on\n",
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) {
if (term_vnc_debug & vncdebug[i].bit) {
vty_out(vty, " BGP VNC %s debugging is on\n",
vncdebug[i].name);
}
}
vty_out (vty, "\n");
vty_out(vty, "\n");
return CMD_SUCCESS;
}
static int
bgp_vnc_config_write_debug (struct vty *vty)
static int bgp_vnc_config_write_debug(struct vty *vty)
{
int write = 0;
size_t i;
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
{
if (conf_vnc_debug & vncdebug[i].bit)
{
vty_out (vty, "debug bgp vnc %s\n", vncdebug[i].name);
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) {
if (conf_vnc_debug & vncdebug[i].bit) {
vty_out(vty, "debug bgp vnc %s\n", vncdebug[i].name);
write++;
}
}
return write;
}
static struct cmd_node debug_node =
static struct cmd_node debug_node = {DEBUG_VNC_NODE, "", 1};
void vnc_debug_init(void)
{
DEBUG_VNC_NODE,
"",
1
};
install_node(&debug_node, bgp_vnc_config_write_debug);
install_element(ENABLE_NODE, &show_debugging_bgp_vnc_cmd);
void
vnc_debug_init (void)
{
install_node (&debug_node, bgp_vnc_config_write_debug);
install_element (ENABLE_NODE, &show_debugging_bgp_vnc_cmd);
install_element(ENABLE_NODE, &debug_bgp_vnc_cmd);
install_element(CONFIG_NODE, &debug_bgp_vnc_cmd);
install_element(ENABLE_NODE, &no_debug_bgp_vnc_cmd);
install_element (ENABLE_NODE, &debug_bgp_vnc_cmd);
install_element (CONFIG_NODE, &debug_bgp_vnc_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_vnc_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_vnc_all_cmd);
install_element(ENABLE_NODE, &no_debug_bgp_vnc_all_cmd);
}

Some files were not shown because too many files have changed in this diff Show More