ip_addr a;
ip4_addr ip4;
ip6_addr ip6;
- net_addr_union net;
+ net_addr net;
net_addr *net_ptr;
struct symbol *s;
char *t;
%token <t> TEXT
%type <iface> ipa_scope
-%type <i> expr bool pxlen4 pxlen6
+%type <i> expr bool pxlen4
%type <i32> expr_us
%type <time> datetime
-%type <a> ipa ipa_raw
-%type <net> net_ip4 net_ip6 net_ip net_or_ipa
-%type <net_ptr> net_any
+%type <a> ipa
+%type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
+%type <net_ptr> net_ net_any
%type <t> text opttext
| /* Silence means agreement */ { $$ = 1; }
;
-/* Addresses, prefixes and netmasks */
-ipa_raw:
- IP4 { $$ = ipa_from_ip4($1); }
- | IP6 { $$ = ipa_from_ip6($1); }
- ;
+/* Addresses */
ipa:
- ipa_raw
+ IP4 { $$ = ipa_from_ip4($1); }
+ | IP6 { $$ = ipa_from_ip6($1); }
| SYM {
if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected");
$$ = SYM_VAL($1).ip;
;
-/* XXXX - symbols and tests */
+/* Networks - internal */
-net_ip4: IP4 pxlen4 { $$.ip4 = NET_ADDR_IP4($1, $2); }
+pxlen4:
+ '/' NUM {
+ if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
+ $$ = $2;
+ }
+ | ':' IP4 {
+ $$ = ip4_masklen($2);
+ if ($$ == 255) cf_error("Invalid netmask %I", $2); /* XXXX */
+ }
+ ;
-net_ip6: IP6 pxlen6 { $$.ip6 = NET_ADDR_IP6($1, $2); }
+net_ip4_: IP4 pxlen4
+{
+ net_fill_ip4(&($$), $1, $2);
+ if (!net_validate_ip4((net_addr_ip4 *) &($$)))
+ cf_error("Invalid IPv4 prefix");
+};
-net_ip: net_ip4 | net_ip6 ;
+net_ip6_: IP6 '/' NUM
+{
+ net_fill_ip6(&($$), $1, $3);
+ if ($3 < 0 || $3 > IP6_MAX_PREFIX_LENGTH)
+ cf_error("Invalid prefix length %d", $3);
+ if (!net_validate_ip6((net_addr_ip6 *) &($$)))
+ cf_error("Invalid IPv6 prefix");
+};
-net_any: net_ip { $$ = cfg_alloc($1.n.length); net_copy($$, &($1.n)); }
+net_ip_: net_ip4_ | net_ip6_ ;
-net_or_ipa:
- net_ip4
- | net_ip6
- | IP4 { $$.ip4 = NET_ADDR_IP4($1, IP4_MAX_PREFIX_LENGTH); }
- | IP6 { $$.ip6 = NET_ADDR_IP6($1, IP6_MAX_PREFIX_LENGTH); }
- ;
+net_: net_ip_ { $$ = cfg_alloc($1.length); net_copy($$, &($1)); } ;
-pxlen4:
- '/' expr {
- if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
- $$ = $2;
+/* Networks - regular */
+
+net_ip6:
+ net_ip6_
+ | SYM {
+ if (($1->class != (SYM_CONSTANT | T_NET)) || (SYM_VAL($1).net->type != NET_IP6))
+ cf_error("IPv6 network expected");
+ $$ = * SYM_VAL($1).net;
}
- | ':' IP4 {
- $$ = ip4_masklen($2);
- if ($$ < 0) cf_error("Invalid netmask %I", $2);
+ ;
+
+net_ip:
+ net_ip_
+ | SYM {
+ if (($1->class != (SYM_CONSTANT | T_NET)) || !net_is_ip(SYM_VAL($1).net))
+ cf_error("IP network expected");
+ $$ = * SYM_VAL($1).net;
}
;
-pxlen6:
- '/' expr {
- if ($2 < 0 || $2 > IP6_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
- $$ = $2;
+net_any:
+ net_
+ | SYM {
+ if ($1->class != (SYM_CONSTANT | T_NET))
+ cf_error("Network expected");
+ $$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */
+ }
+ ;
+
+net_or_ipa:
+ net_ip4_
+ | net_ip6_
+ | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); }
+ | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); }
+ | SYM {
+ if ($1->class == (SYM_CONSTANT | T_IP))
+ net_fill_ip_host(&($$), SYM_VAL($1).ip);
+ else if (($1->class == (SYM_CONSTANT | T_NET)) && net_is_ip(SYM_VAL($1).net))
+ $$ = * SYM_VAL($1).net;
+ else
+ cf_error("IP address or network expected");
}
;
+
datetime:
TEXT {
$$ = tm_parse_datetime($1);
* Complex types, their bison value is struct f_val
*/
fipa:
- ipa_raw %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.ip = $1; }
+ IP4 %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.ip = ipa_from_ip4($1); }
+ | IP6 %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.ip = ipa_from_ip6($1); }
;
;
fprefix:
- net_ip { $$.net = $1; $$.lo = $1.n.pxlen; $$.hi = $1.n.pxlen; }
- | net_ip '+' { $$.net = $1; $$.lo = $1.n.pxlen; $$.hi = net_max_prefix_length[$1.n.type]; }
- | net_ip '-' { $$.net = $1; $$.lo = 0; $$.hi = $1.n.pxlen; }
- | net_ip '{' NUM ',' NUM '}' {
+ net_ip_ { $$.net = $1; $$.lo = $1.pxlen; $$.hi = $1.pxlen; }
+ | net_ip_ '+' { $$.net = $1; $$.lo = $1.pxlen; $$.hi = net_max_prefix_length[$1.type]; }
+ | net_ip_ '-' { $$.net = $1; $$.lo = 0; $$.hi = $1.pxlen; }
+ | net_ip_ '{' NUM ',' NUM '}' {
$$.net = $1; $$.lo = $3; $$.hi = $5;
- if ((0 > $3) || ($3 > $5) || ($5 > net_max_prefix_length[$1.n.type]))
+ if ((0 > $3) || ($3 > $5) || ($5 > net_max_prefix_length[$1.type]))
cf_error("Invalid prefix pattern range: {%d, %d}", $3, $5);
}
;
fprefix_set:
- fprefix { $$ = f_new_trie(cfg_mem, sizeof(struct f_trie_node)); trie_add_prefix($$, &($1.net.n), $1.lo, $1.hi); }
- | fprefix_set ',' fprefix { $$ = $1; trie_add_prefix($$, &($3.net.n), $3.lo, $3.hi); }
+ fprefix { $$ = f_new_trie(cfg_mem, sizeof(struct f_trie_node)); trie_add_prefix($$, &($1.net), $1.lo, $1.hi); }
+ | fprefix_set ',' fprefix { $$ = $1; trie_add_prefix($$, &($3.net), $3.lo, $3.hi); }
;
switch_body: /* EMPTY */ { $$ = NULL; }
| FALSE { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_BOOL; $$->a2.i = 0; }
| TEXT { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_STRING; $$->a2.p = $1; }
| fipa { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
- | net_any { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; val->type = T_NET; val->val.net = $1; $$->a1.p = val; }
+ | net_ { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; val->type = T_NET; val->val.net = $1; $$->a1.p = val; }
| '[' set_items ']' { DBG( "We've got a set here..." ); $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_SET; $$->a2.p = build_tree($2); DBG( "ook\n" ); }
| '[' fprefix_set ']' { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PREFIX_SET; $$->a2.p = $2; }
| ENUM { $$ = f_new_inst(); $$->code = 'c'; $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; }
};
struct f_prefix {
- net_addr_union net;
+ net_addr net;
u8 lo, hi;
};
define p23 = (2, 3);
define ip1222 = 1.2.2.2;
+define net10 = 10.0.0.0/8;
+define netdoc = 2001:db8::/32;
+
+
function onef(int a)
{
return 1;
return 15;
}
+/*
roa table rl
{
roa 10.110.0.0/16 max 16 as 1000;
" ", roa_check(rl, 10.130.30.0/24, 3000) = ROA_INVALID,
" ", roa_check(rl, 10.130.130.0/24, 3000) = ROA_VALID;
}
+*/
function path_test()
bgpmask pm1;
function test_pxset(prefix set pxs)
{
print pxs;
- print " must be true: ", 10.0.0.0/8 ~ pxs, ",", 10.0.0.0/10 ~ pxs, ",", 10.0.0.0/12 ~ pxs, ",",
+ print " must be true: ", net10 ~ pxs, ",", 10.0.0.0/10 ~ pxs, ",", 10.0.0.0/12 ~ pxs, ",",
20.0.0.0/24 ~ pxs, ",", 20.0.40.0/24 ~ pxs, ",", 20.0.0.0/26 ~ pxs, ",",
20.0.100.0/26 ~ pxs, ",", 20.0.0.0/28 ~ pxs, ",", 20.0.255.0/28 ~ pxs;
print " must be false: ", 10.0.0.0/7 ~ pxs, ",", 10.0.0.0/13 ~ pxs, ",", 10.0.0.0/16 ~ pxs, ",",
px = 1.2.0.0/18;
print "Testing prefixes: 1.2.0.0/18 = ", px;
- print " must be true: ", 192.168.0.0/16 ~ 192.168.0.0/16, " ", 192.168.0.0/17 ~ 192.168.0.0/16, " ", 192.168.254.0/24 ~ 192.168.0.0/16;
- print " must be false: ", 192.168.0.0/15 ~ 192.168.0.0/16, " ", 192.160.0.0/17 ~ 192.168.0.0/16;
+ print " must be true: ", 192.168.0.0/16 ~ 192.168.0.0/16, " ", 192.168.0.0/17 ~ 192.168.0.0/16, " ", 192.168.254.0/24 ~ 192.168.0.0/16, " ", netdoc ~ 2001::/16;
+ print " must be false: ", 192.168.0.0/15 ~ 192.168.0.0/16, " ", 192.160.0.0/17 ~ 192.168.0.0/16, " ", px ~ netdoc;
p = 127.1.2.3;
print "Testing mask : 127.0.0.0 = ", p.mask(8);
-
+
pp = (1, 2);
print "Testing pairs: (1,2) = ", (1,2), " = ", pp, " = ", (1,1+1), " = ", 'mkpair-a'(2);
print " must be true: ", (1,2) = (1,1+1);
print "1.2.3.4 = ", onetwo;
i = 4200000000;
- print "4200000000 = ", i, " false: ", i = 4200000000, " ", i > 4100000000, " false: ", i > 4250000000;
+ print "4200000000 = ", i, " true: ", i = 4200000000, " ", i > 4100000000, " false: ", i > 4250000000;
test_undef(2);
test_undef(3);
if (a->addr[i] != ~0U)
{
j = u32_masklen(a->addr[i]);
- if (j < 0)
+ if (j == 255)
return j;
n += j;
while (++i < 4)
#define ipa_is_ip4(a) ip6_is_v4mapped(a)
+#define IPA_NONE4 ipa_from_ip4(IP4_NONE)
+#define IPA_NONE6 ipa_from_ip6(IP6_NONE)
+
/*
* Public constructors
* Hash and compare functions
*/
-static inline uint ip4_hash(ip4_addr a)
-{
- /* Returns a 16-bit value */
- u32 x = _I(a);
- x ^= x >> 16;
- x ^= x << 10;
- return x & 0xffff;
-}
-
-static inline u32 ip4_hash32(ip4_addr a)
+static inline u32 ip4_hash(ip4_addr a)
{
/* Returns a 32-bit value, although low-order bits are not mixed */
u32 x = _I(a);
return x;
}
-static inline uint ip6_hash(ip6_addr a)
-{
- /* Returns a 16-bit hash key */
- u32 x = _I0(a) ^ _I1(a) ^ _I2(a) ^ _I3(a);
- return (x ^ (x >> 16) ^ (x >> 8)) & 0xffff;
-}
-
-static inline u32 ip6_hash32(ip6_addr a)
+static inline u32 ip6_hash(ip6_addr a)
{
/* Returns a 32-bit hash key, although low-order bits are not mixed */
u32 x = _I0(a) ^ _I1(a) ^ _I2(a) ^ _I3(a);
int ip6_compare(ip6_addr a, ip6_addr b);
#define ipa_hash(x) ip6_hash(x)
-#define ipa_hash32(x) ip6_hash32(x)
#define ipa_compare(x,y) ip6_compare(x,y)
net_fill_ip6(a, ipa_to_ip6(prefix), pxlen);
}
+static inline void net_fill_ip_host(net_addr *a, ip_addr prefix)
+{
+ if (ipa_is_ip4(prefix))
+ net_fill_ip4(a, ipa_to_ip4(prefix), IP4_MAX_PREFIX_LENGTH);
+ else
+ net_fill_ip6(a, ipa_to_ip6(prefix), IP6_MAX_PREFIX_LENGTH);
+}
+
+static inline int net_is_ip(const net_addr *a)
+{ return (a->type == NET_IP4) || (a->type == NET_IP6); }
+
static inline ip4_addr net4_prefix(const net_addr *a)
{ return ((net_addr_ip4 *) a)->prefix; }
static inline u32 net_hash_ip4(const net_addr_ip4 *n)
-{ return ip4_hash32(n->prefix) ^ ((u32) n->pxlen << 26); }
+{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
static inline u32 net_hash_ip6(const net_addr_ip6 *n)
-{ return ip6_hash32(n->prefix) ^ ((u32) n->pxlen << 26); }
+{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
/* XXXX */
-static inline u32 u64_hash(u32 a)
+static inline u32 u64_hash(u64 a)
{ return u32_hash(a); }
static inline u32 net_hash_vpn4(const net_addr_vpn4 *n)
-{ return ip4_hash32(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
+{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
static inline u32 net_hash_vpn6(const net_addr_vpn6 *n)
-{ return ip6_hash32(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
+{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
static inline int net_validate_ip4(const net_addr_ip4 *n)
struct iface_patt_node *pn;
WALK_LIST(pn, this_ipatt->ipn_list)
- if (!pn->pattern || pn->prefix.pxlen) /* XXXX */
+ if (!pn->pattern || pn->prefix.type)
cf_error("Interface name/mask expected, not IP prefix");
}
CF_ADDTO(conf, rtrid)
-rtrid:
+rtrid:
ROUTER ID idval ';' { new_config->router_id = $3; }
| ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; }
;
;
iface_patt_node_body:
- TEXT { this_ipn->pattern = $1; net_fill_ip6(&this_ipn->prefix, IP6_NONE, 0); /* XXXX */ }
- | opttext net_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.n; }
+ TEXT { this_ipn->pattern = $1; /* this_ipn->prefix stays zero */ }
+ | opttext net_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2; }
;
iface_negate:
;
iface_patt_node:
- iface_patt_node_init iface_negate iface_patt_node_body
+ iface_patt_node_init iface_negate iface_patt_node_body
;
}
| r_args net_any {
$$ = $1;
- if ($$->prefix) cf_error("Only one prefix expected");
- $$->prefix = $2;
+ if ($$->addr) cf_error("Only one prefix expected");
+ $$->addr = $2;
}
| r_args FOR net_or_ipa {
$$ = $1;
- if ($$->prefix) cf_error("Only one prefix expected");
- $$->prefix = &($3.n);
+ if ($$->addr) cf_error("Only one prefix expected");
$$->show_for = 1;
+ $$->addr = cfg_alloc($3.length);
+ net_copy($$->addr, &($3));
}
| r_args TABLE SYM {
$$ = $1;
#include "lib/resource.h"
#define NEIGH_HASH_SIZE 256
+#define NEIGH_HASH_OFFSET 24
static slab *neigh_slab;
static list sticky_neigh_list, neigh_hash_table[NEIGH_HASH_SIZE];
static inline uint
neigh_hash(struct proto *p, ip_addr *a)
{
- return (p->hash_key ^ ipa_hash(*a)) & (NEIGH_HASH_SIZE-1);
+ return (p->hash_key ^ ipa_hash(*a)) >> NEIGH_HASH_OFFSET;
}
static int
struct fib_node **hash_table; /* Node hash table */
uint hash_size; /* Number of hash table entries (a power of two) */
uint hash_order; /* Binary logarithm of hash_size */
- uint hash_shift; /* 16 - hash_log */
+ uint hash_shift; /* 32 - hash_order */
uint addr_type; /* Type of address data stored in fib (NET_*) */
uint node_size; /* XXXX */
uint node_offset; /* XXXX */
static inline net *net_find(rtable *tab, net_addr *addr) { return (net *) fib_find(&tab->fib, addr); }
static inline net *net_get(rtable *tab, net_addr *addr) { return (net *) fib_get(&tab->fib, addr); }
-static inline net *net_find_ipa(rtable *tab, ip_addr px, uint pxlen)
-{ net_addr addr; net_fill_ipa(&addr, px, pxlen); return (net *) fib_find(&tab->fib, &addr); }
-static inline net *net_get_ipa(rtable *tab, ip_addr px, uint pxlen)
-{ net_addr addr; net_fill_ipa(&addr, px, pxlen); return (net *) fib_get(&tab->fib, &addr); }
-
rte *rte_find(net *net, struct rte_src *src);
rte *rte_get_temp(struct rta *);
void rte_update2(struct announce_hook *ah, net *net, rte *new, struct rte_src *src);
}
struct rt_show_data {
- net_addr *prefix;
+ net_addr *addr;
rtable *table;
struct filter *filter;
int verbose;
* Multipath Next Hop
*/
-static inline uint
+static inline u32
mpnh_hash(struct mpnh *x)
{
- uint h = 0;
+ u32 h = 0;
for (; x; x = x->next)
h ^= ipa_hash(x->gw);
static inline uint
rta_hash(rta *a)
{
- return (((uint) (uintptr_t) a->src) ^ ipa_hash(a->gw) ^
- mpnh_hash(a->nexthops) ^ ea_hash(a->eattrs)) & 0xffff;
+ /* XXXX fully convert to u32 hashing */
+ return (((uint) (uintptr_t) a->src) ^ (ipa_hash(a->gw) >> 16) ^
+ (mpnh_hash(a->nexthops) >> 16) ^ ea_hash(a->eattrs)) & 0xffff;
}
static inline int
#define HASH_DEF_ORDER 10
#define HASH_HI_MARK *4
#define HASH_HI_STEP 2
-#define HASH_HI_MAX 16 /* Must be at most 16 */
+#define HASH_HI_MAX 16
#define HASH_LO_MARK /5
#define HASH_LO_STEP 2
#define HASH_LO_MIN 10
return b;
}
-static void *
-fib_route_ip4(struct fib *f, const net_addr *n0)
+static inline void *
+fib_route_ip4(struct fib *f, net_addr_ip4 *n)
{
- net_addr net;
- net_addr_ip4 *n = (net_addr_ip4 *) &net;
- void *b;
+ void *r;
- net_copy(&net, n0);
- while (!(b = fib_find(f, &net)) && (n->pxlen > 0))
+ while (!(r = fib_find(f, (net_addr *) n)) && (n->pxlen > 0))
{
n->pxlen--;
ip4_clrbit(&n->prefix, n->pxlen);
}
- return b;
+ return r;
}
-static void *
-fib_route_ip6(struct fib *f, const net_addr *n0)
+static inline void *
+fib_route_ip6(struct fib *f, net_addr_ip6 *n)
{
- net_addr net;
- net_addr_ip6 *n = (net_addr_ip6 *) &net;
- void *b;
+ void *r;
- net_copy(&net, n0);
- while (!(b = fib_find(f, &net)) && (n->pxlen > 0))
+ while (!(r = fib_find(f, (net_addr *) n)) && (n->pxlen > 0))
{
n->pxlen--;
ip6_clrbit(&n->prefix, n->pxlen);
}
- return b;
+ return r;
}
/**
{
ASSERT(f->addr_type == n->type);
+ net_addr *n0 = alloca(n->length);
+ net_copy(n0, n);
+
switch (n->type)
{
case NET_IP4:
case NET_VPN4:
- return fib_route_ip4(f, n);
+ return fib_route_ip4(f, (net_addr_ip4 *) n0);
case NET_IP6:
case NET_VPN6:
- return fib_route_ip6(f, n);
+ return fib_route_ip6(f, (net_addr_ip6 *) n0);
default:
return NULL;
}
}
+
static inline void
fib_merge_readers(struct fib_iterator *i, struct fib_node *to)
{
}
fib_merge_readers(it, l);
}
- sl_free(f->fib_slab, e);
+
+ if (f->fib_slab)
+ sl_free(f->fib_slab, E);
+ else
+ mb_free(E);
+
if (f->entries-- < f->entries_min)
fib_rehash(f, -HASH_LO_STEP);
return;
return mta ? mta(rt, rte_update_pool) : NULL;
}
+
/* Like fib_route(), but skips empty net entries */
-/*
-static net *
-net_route(rtable *tab, ip_addr a, int len)
+static inline void *
+net_route_ip4(struct fib *f, net_addr_ip4 *n)
{
- ip_addr a0;
- net *n;
+ net *r;
- while (len >= 0)
- {
- a0 = ipa_and(a, ipa_mkmask(len));
- n = fib_find(&tab->fib, &a0, len);
- if (n && rte_is_valid(n->routes))
- return n;
- len--;
- }
- return NULL;
+ while (r = fib_find(f, (net_addr *) n),
+ !(r && rte_is_valid(r->routes)) && (n->pxlen > 0))
+ {
+ n->pxlen--;
+ ip4_clrbit(&n->prefix, n->pxlen);
+ }
+
+ return r;
+}
+
+static inline void *
+net_route_ip6(struct fib *f, net_addr_ip6 *n)
+{
+ net *r;
+
+ while (r = fib_find(f, (net_addr *) n),
+ !(r && rte_is_valid(r->routes)) && (n->pxlen > 0))
+ {
+ n->pxlen--;
+ ip6_clrbit(&n->prefix, n->pxlen);
+ }
+
+ return r;
+}
+
+void *
+net_route(rtable *tab, const net_addr *n)
+{
+ ASSERT(f->addr_type == n->type);
+
+ net_addr *n0 = alloca(n->length);
+ net_copy(n0, n);
+
+ switch (n->type)
+ {
+ case NET_IP4:
+ case NET_VPN4:
+ return net_route_ip4(&tab->fib, (net_addr_ip4 *) n0);
+
+ case NET_IP6:
+ case NET_VPN6:
+ return net_route_ip6(&tab->fib, (net_addr_ip6 *) n0);
+
+ default:
+ return NULL;
+ }
}
-*/
/**
* rte_find - find a route
return p ^ (p << 8) ^ (p >> 16);
}
-static inline unsigned
+static inline u32
hc_hash(ip_addr a, rtable *dep)
{
- return (ipa_hash(a) ^ ptr_hash(dep)) & 0xffff;
+ return ipa_hash(a) ^ ptr_hash(dep);
}
static inline void
{
unsigned hsize = 1 << order;
hc->hash_order = order;
- hc->hash_shift = 16 - order;
+ hc->hash_shift = 32 - order;
hc->hash_max = (order >= HC_HI_ORDER) ? ~0 : (hsize HC_HI_MARK);
hc->hash_min = (order <= HC_LO_ORDER) ? 0 : (hsize HC_LO_MARK);
static void
rt_notify_hostcache(rtable *tab, net *net)
{
- struct hostcache *hc = tab->hostcache;
-
if (tab->hcu_scheduled)
return;
- // XXXX
- // if (trie_match_prefix(hc->trie, net->n.prefix, net->n.pxlen))
- // rt_schedule_hcu(tab);
+ if (trie_match_net(tab->hostcache->trie, net->n.addr))
+ rt_schedule_hcu(tab);
}
static int
rta *old_src = he->src;
int pxlen = 0;
- /* Reset the hostentry */
+ /* Reset the hostentry */
he->src = NULL;
he->gw = IPA_NONE;
he->dest = RTD_UNREACHABLE;
he->igp_metric = 0;
- // XXXX
- // net *n = net_route(tab, he->addr, MAX_PREFIX_LENGTH);
- net *n = NULL;
+ net_addr he_addr;
+ net_fill_ip_host(&he_addr, he->addr);
+ net *n = net_route(tab, &he_addr);
if (n)
{
rte *e = n->routes;
done:
/* Add a prefix range to the trie */
- /* XXXX
- if (ipa_is_ip4(he->addr))
- trie_add_prefix(tab->hostcache->trie, he->addr, IP4_MAX_PREFIX_LENGTH, pxlen, IP4_MAX_PREFIX_LENGTH);
- else
- trie_add_prefix(tab->hostcache->trie, he->addr, IP6_MAX_PREFIX_LENGTH, pxlen, IP6_MAX_PREFIX_LENGTH);
- */
+ trie_add_prefix(tab->hostcache->trie, &he_addr, pxlen, he_addr.pxlen);
rta_free(old_src);
return old_src != he->src;
if (!tab->hostcache)
rt_init_hostcache(tab);
- uint k = hc_hash(a, dep);
+ u32 k = hc_hash(a, dep);
struct hostcache *hc = tab->hostcache;
for (he = hc->hash_table[k >> hc->hash_shift]; he != NULL; he = he->next)
if (ipa_equal(he->addr, a) && (he->tab == dep))
if (d->filtered && (d->export_mode || d->primary_only))
cli_msg(0, "");
- if (!d->prefix)
+ if (!d->addr)
{
FIB_ITERATE_INIT(&d->fit, &d->table->fib);
this_cli->cont = rt_show_cont;
}
else
{
- /* XXXX
if (d->show_for)
- n = net_route(d->table, d->prefix, d->pxlen);
+ n = net_route(d->table, d->addr);
else
- n = net_find(d->table, d->prefix, d->pxlen);
- */
- n = NULL;
+ n = net_find(d->table, d->addr);
if (n)
rt_show_net(this_cli, n, d);
#define HASH_IP_KEY(n) n->addr
#define HASH_IP_NEXT(n) n->next_ip
#define HASH_IP_EQ(a,b) ipa_equal(a,b)
-#define HASH_IP_FN(k) ipa_hash32(k)
+#define HASH_IP_FN(k) ipa_hash(k)
static list bfd_proto_list;
static list bfd_wait_list;
net_ip {
this_stubnet = cfg_allocz(sizeof(struct ospf_stubnet_config));
add_tail(&this_area->stubnet_list, NODE this_stubnet);
- this_stubnet->prefix = $1.n;
+ this_stubnet->prefix = $1;
this_stubnet->cost = COST_D;
}
;
{
this_pref = cfg_allocz(sizeof(struct area_net_config));
add_tail(this_nets, NODE this_pref);
- this_pref->prefix = $1.n;
+ this_pref->prefix = $1;
}
;
if (ip->ptp_netmask < 2)
ifa->ptp_netmask = ip->ptp_netmask;
+ ifa->drip = ifa->bdrip = ospf_is_v2(p) ? IPA_NONE4 : IPA_NONE6;
ifa->type = ospf_iface_classify(ip->type, addr);
else if (ifa->addr->flags & IA_PEER)
cli_msg(-1015, "Interface %s (peer %I)", ifa->ifname, ifa->addr->opposite);
else
- cli_msg(-1015, "Interface %s (%N)", ifa->ifname, ifa->addr->prefix);
+ cli_msg(-1015, "Interface %s (%N)", ifa->ifname, &ifa->addr->prefix);
cli_msg(-1015, "\tType: %s%s", ospf_it[ifa->type], more);
cli_msg(-1015, "\tArea: %R (%u)", ifa->oa->areaid, ifa->oa->areaid);
u32 old_drid = ifa->drid;
u32 old_bdrid = ifa->bdrid;
+ ip_addr none = ospf_is_v2(p) ? IPA_NONE4 : IPA_NONE6;
ifa->drid = ndr ? ndr->rid : 0;
- ifa->drip = ndr ? ndr->ip : IPA_NONE;
+ ifa->drip = ndr ? ndr->ip : none;
ifa->dr_iface_id = ndr ? ndr->iface_id : 0;
ifa->bdrid = nbdr ? nbdr->rid : 0;
- ifa->bdrip = nbdr ? nbdr->ip : IPA_NONE;
+ ifa->bdrip = nbdr ? nbdr->ip : none;
DBG("DR=%R, BDR=%R\n", ifa->drid, ifa->bdrid);
void
ospf_send_to_bdr(struct ospf_iface *ifa)
{
- if (ipa_nonzero(ifa->drip))
+ if (ipa_nonzero2(ifa->drip))
ospf_send_to(ifa, ifa->drip);
- if (ipa_nonzero(ifa->bdrip))
+ if (ipa_nonzero2(ifa->bdrip))
ospf_send_to(ifa, ifa->bdrip);
}
radv_prefix_start: net_ip6
{
this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config));
- RADV_PREFIX->prefix = $1.ip6;
+ RADV_PREFIX->prefix = *(net_addr_ip6 *) &($1);
RADV_PREFIX->onlink = 1;
RADV_PREFIX->autonomous = 1;
}
| PRIMARY opttext net_or_ipa {
struct kif_primary_item *kpi = cfg_alloc(sizeof (struct kif_primary_item));
- kpi->addr = $3.n;
+ kpi->addr = $3;
add_tail(&THIS_KIF->primary, &kpi->n);
}
;