Merge branch 'master' into int-new
This commit is contained in:
commit
c259669fa3
12 changed files with 71 additions and 15 deletions
7
NEWS
7
NEWS
|
@ -14,6 +14,13 @@ Version 2.0.0-pre0 (2016-12-07)
|
||||||
doc/bird.conf.example2 for configuration examples.
|
doc/bird.conf.example2 for configuration examples.
|
||||||
|
|
||||||
|
|
||||||
|
Version 1.6.3 (2016-12-21)
|
||||||
|
o Large BGP communities
|
||||||
|
o BFD authentication (MD5, SHA1)
|
||||||
|
o SHA1 and SHA2 authentication for RIP and OSPF
|
||||||
|
o Improved documentation
|
||||||
|
o Several bug fixes
|
||||||
|
|
||||||
Version 1.6.2 (2016-09-29)
|
Version 1.6.2 (2016-09-29)
|
||||||
o Fixes serious bug introduced in the previous version
|
o Fixes serious bug introduced in the previous version
|
||||||
|
|
||||||
|
|
|
@ -1579,6 +1579,7 @@ i_same(struct f_inst *f1, struct f_inst *f2)
|
||||||
case P('<','='): TWOARGS; break;
|
case P('<','='): TWOARGS; break;
|
||||||
|
|
||||||
case '!': ONEARG; break;
|
case '!': ONEARG; break;
|
||||||
|
case P('!', '~'):
|
||||||
case '~': TWOARGS; break;
|
case '~': TWOARGS; break;
|
||||||
case P('d','e'): ONEARG; break;
|
case P('d','e'): ONEARG; break;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,12 @@
|
||||||
(v).data = mb_allocz(pool, HASH_SIZE(v) * sizeof(* (v).data)); \
|
(v).data = mb_allocz(pool, HASH_SIZE(v) * sizeof(* (v).data)); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define HASH_FREE(v) \
|
||||||
|
({ \
|
||||||
|
mb_free((v).data); \
|
||||||
|
(v) = (typeof(v)){ }; \
|
||||||
|
})
|
||||||
|
|
||||||
#define HASH_FIND(v,id,key...) \
|
#define HASH_FIND(v,id,key...) \
|
||||||
({ \
|
({ \
|
||||||
u32 _h = HASH_FN(v, id, key); \
|
u32 _h = HASH_FN(v, id, key); \
|
||||||
|
|
23
nest/a-set.c
23
nest/a-set.c
|
@ -233,6 +233,26 @@ lc_set_contains(struct adata *list, lcomm val)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct adata *
|
||||||
|
int_set_prepend(struct linpool *pool, struct adata *list, u32 val)
|
||||||
|
{
|
||||||
|
struct adata *res;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (int_set_contains(list, val))
|
||||||
|
return list;
|
||||||
|
|
||||||
|
len = list ? list->length : 0;
|
||||||
|
res = lp_alloc(pool, sizeof(struct adata) + len + 4);
|
||||||
|
res->length = len + 4;
|
||||||
|
|
||||||
|
if (list)
|
||||||
|
memcpy(res->data + 4, list->data, list->length);
|
||||||
|
|
||||||
|
* (u32 *) res->data = val;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
struct adata *
|
struct adata *
|
||||||
int_set_add(struct linpool *pool, struct adata *list, u32 val)
|
int_set_add(struct linpool *pool, struct adata *list, u32 val)
|
||||||
|
@ -250,8 +270,7 @@ int_set_add(struct linpool *pool, struct adata *list, u32 val)
|
||||||
if (list)
|
if (list)
|
||||||
memcpy(res->data, list->data, list->length);
|
memcpy(res->data, list->data, list->length);
|
||||||
|
|
||||||
u32 *c = (u32 *) (res->data + len);
|
* (u32 *) (res->data + len) = val;
|
||||||
*c = val;
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,6 +181,7 @@ int lc_set_format(struct adata *set, int from, byte *buf, uint size);
|
||||||
int int_set_contains(struct adata *list, u32 val);
|
int int_set_contains(struct adata *list, u32 val);
|
||||||
int ec_set_contains(struct adata *list, u64 val);
|
int ec_set_contains(struct adata *list, u64 val);
|
||||||
int lc_set_contains(struct adata *list, lcomm val);
|
int lc_set_contains(struct adata *list, lcomm val);
|
||||||
|
struct adata *int_set_prepend(struct linpool *pool, struct adata *list, u32 val);
|
||||||
struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val);
|
struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val);
|
||||||
struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val);
|
struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val);
|
||||||
struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val);
|
struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val);
|
||||||
|
|
|
@ -1224,6 +1224,15 @@ bgp_init_prefix_table(struct bgp_channel *c)
|
||||||
c->prefix_slab = alen ? sl_new(c->pool, sizeof(struct bgp_prefix) + alen) : NULL;
|
c->prefix_slab = alen ? sl_new(c->pool, sizeof(struct bgp_prefix) + alen) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bgp_free_prefix_table(struct bgp_channel *c)
|
||||||
|
{
|
||||||
|
HASH_FREE(c->prefix_hash);
|
||||||
|
|
||||||
|
rfree(c->prefix_slab);
|
||||||
|
c->prefix_slab = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct bgp_prefix *
|
static struct bgp_prefix *
|
||||||
bgp_get_prefix(struct bgp_channel *c, net_addr *net, u32 path_id)
|
bgp_get_prefix(struct bgp_channel *c, net_addr *net, u32 path_id)
|
||||||
{
|
{
|
||||||
|
@ -1323,6 +1332,7 @@ bgp_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct li
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static adata null_adata; /* adata of length 0 */
|
static adata null_adata; /* adata of length 0 */
|
||||||
|
|
||||||
static ea_list *
|
static ea_list *
|
||||||
|
@ -1394,11 +1404,11 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
|
||||||
|
|
||||||
/* Prepend src cluster ID */
|
/* Prepend src cluster ID */
|
||||||
if (src->rr_cluster_id)
|
if (src->rr_cluster_id)
|
||||||
ad = int_set_add(pool, ad, src->rr_cluster_id);
|
ad = int_set_prepend(pool, ad, src->rr_cluster_id);
|
||||||
|
|
||||||
/* Prepend dst cluster ID if src and dst clusters are different */
|
/* Prepend dst cluster ID if src and dst clusters are different */
|
||||||
if (p->rr_cluster_id && (src->rr_cluster_id != p->rr_cluster_id))
|
if (p->rr_cluster_id && (src->rr_cluster_id != p->rr_cluster_id))
|
||||||
ad = int_set_add(pool, ad, p->rr_cluster_id);
|
ad = int_set_prepend(pool, ad, p->rr_cluster_id);
|
||||||
|
|
||||||
/* Should be at least one prepended cluster ID */
|
/* Should be at least one prepended cluster ID */
|
||||||
bgp_set_attr_ptr(&attrs, pool, BA_CLUSTER_LIST, 0, ad);
|
bgp_set_attr_ptr(&attrs, pool, BA_CLUSTER_LIST, 0, ad);
|
||||||
|
|
|
@ -559,6 +559,10 @@ bgp_conn_leave_established_state(struct bgp_proto *p)
|
||||||
BGP_TRACE(D_EVENTS, "BGP session closed");
|
BGP_TRACE(D_EVENTS, "BGP session closed");
|
||||||
p->conn = NULL;
|
p->conn = NULL;
|
||||||
|
|
||||||
|
// XXXX free these tables to avoid memory leak during graceful restart
|
||||||
|
// bgp_free_prefix_table(p);
|
||||||
|
// bgp_free_bucket_table(p);
|
||||||
|
|
||||||
if (p->p.proto_state == PS_UP)
|
if (p->p.proto_state == PS_UP)
|
||||||
bgp_stop(p, 0);
|
bgp_stop(p, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,10 +422,9 @@ add_network(struct ospf_area *oa, net_addr *net, int metric, struct top_hash_ent
|
||||||
if (en == oa->rt)
|
if (en == oa->rt)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Local stub networks does not have proper iface in en->nhi
|
* Local stub networks do not have proper iface in en->nhi (because they all
|
||||||
* (because they all have common top_hash_entry en).
|
* have common top_hash_entry en). We have to find iface responsible for
|
||||||
* We have to find iface responsible for that stub network.
|
* that stub network. Configured stubnets do not have any iface. They will
|
||||||
* Configured stubnets does not have any iface. They will
|
|
||||||
* be removed in rt_sync().
|
* be removed in rt_sync().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1429,7 +1428,6 @@ ospf_ext_spf(struct ospf_proto *p)
|
||||||
struct top_hash_entry *en;
|
struct top_hash_entry *en;
|
||||||
struct ospf_lsa_ext_local rt;
|
struct ospf_lsa_ext_local rt;
|
||||||
ort *nf1, *nf2;
|
ort *nf1, *nf2;
|
||||||
orta nfa = {};
|
|
||||||
u32 br_metric;
|
u32 br_metric;
|
||||||
struct ospf_area *atmp;
|
struct ospf_area *atmp;
|
||||||
|
|
||||||
|
@ -1437,6 +1435,8 @@ ospf_ext_spf(struct ospf_proto *p)
|
||||||
|
|
||||||
WALK_SLIST(en, p->lsal)
|
WALK_SLIST(en, p->lsal)
|
||||||
{
|
{
|
||||||
|
orta nfa = {};
|
||||||
|
|
||||||
/* 16.4. (1) */
|
/* 16.4. (1) */
|
||||||
if ((en->lsa_type != LSA_T_EXT) && (en->lsa_type != LSA_T_NSSA))
|
if ((en->lsa_type != LSA_T_EXT) && (en->lsa_type != LSA_T_NSSA))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1578,6 +1578,7 @@ ospf_rt_reset(struct ospf_proto *p)
|
||||||
FIB_WALK(&p->rtf, ort, ri)
|
FIB_WALK(&p->rtf, ort, ri)
|
||||||
{
|
{
|
||||||
ri->area_net = 0;
|
ri->area_net = 0;
|
||||||
|
ri->keep = 0;
|
||||||
reset_ri(ri);
|
reset_ri(ri);
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
|
@ -1941,9 +1942,12 @@ again1:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove configured stubnets */
|
/* Remove configured stubnets but keep the entries */
|
||||||
if (!nf->n.nhs)
|
if (nf->n.type && !nf->n.nhs)
|
||||||
|
{
|
||||||
reset_ri(nf);
|
reset_ri(nf);
|
||||||
|
nf->keep = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (nf->n.type) /* Add the route */
|
if (nf->n.type) /* Add the route */
|
||||||
{
|
{
|
||||||
|
@ -1999,7 +2003,7 @@ again1:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove unused rt entry, some special entries are persistent */
|
/* Remove unused rt entry, some special entries are persistent */
|
||||||
if (!nf->n.type && !nf->external_rte && !nf->area_net)
|
if (!nf->n.type && !nf->external_rte && !nf->area_net && !nf->keep)
|
||||||
{
|
{
|
||||||
if (nf->lsa_id)
|
if (nf->lsa_id)
|
||||||
idm_free(&p->idm, nf->lsa_id);
|
idm_free(&p->idm, nf->lsa_id);
|
||||||
|
|
|
@ -84,6 +84,7 @@ typedef struct ort
|
||||||
u32 lsa_id;
|
u32 lsa_id;
|
||||||
u8 external_rte;
|
u8 external_rte;
|
||||||
u8 area_net;
|
u8 area_net;
|
||||||
|
u8 keep;
|
||||||
|
|
||||||
struct fib_node fn;
|
struct fib_node fn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
#include <netinet/in_systm.h> // Workaround for some BSDs
|
#include <netinet/in_systm.h> // Workaround for some BSDs
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
|
@ -179,8 +180,8 @@ sk_prepare_ip_header(sock *s, void *hdr, int dlen)
|
||||||
ip->ip_src = ipa_to_in4(s->saddr);
|
ip->ip_src = ipa_to_in4(s->saddr);
|
||||||
ip->ip_dst = ipa_to_in4(s->daddr);
|
ip->ip_dst = ipa_to_in4(s->daddr);
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
#if (defined __OpenBSD__) || (defined __DragonFly__) || (defined __FreeBSD__ && (__FreeBSD_version >= 1100030))
|
||||||
/* OpenBSD expects ip_len in network order, other BSDs expect host order */
|
/* Different BSDs have different expectations of ip_len endianity */
|
||||||
ip->ip_len = htons(ip->ip_len);
|
ip->ip_len = htons(ip->ip_len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1608,6 +1608,7 @@ nl_async_hook(sock *sk, uint size UNUSED)
|
||||||
* One day we might react to it by asking for route table
|
* One day we might react to it by asking for route table
|
||||||
* scan in near future.
|
* scan in near future.
|
||||||
*/
|
*/
|
||||||
|
log(L_WARN "Kernel dropped some netlink messages, will resync on next scan.");
|
||||||
return 1; /* More data are likely to be ready */
|
return 1; /* More data are likely to be ready */
|
||||||
}
|
}
|
||||||
else if (errno != EWOULDBLOCK)
|
else if (errno != EWOULDBLOCK)
|
||||||
|
|
|
@ -2631,7 +2631,8 @@ io_loop(void)
|
||||||
if (pfd[s->index].revents & (POLLHUP | POLLERR))
|
if (pfd[s->index].revents & (POLLHUP | POLLERR))
|
||||||
{
|
{
|
||||||
sk_err(s, pfd[s->index].revents);
|
sk_err(s, pfd[s->index].revents);
|
||||||
goto next2;
|
if (s != current_sock)
|
||||||
|
goto next2;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_sock = sk_next(s);
|
current_sock = sk_next(s);
|
||||||
|
|
Loading…
Reference in a new issue