Commit 04632fd7 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Follow-up work on integration

parent 70b90dde
...@@ -41,7 +41,7 @@ CF_DECLS ...@@ -41,7 +41,7 @@ CF_DECLS
ip_addr a; ip_addr a;
ip4_addr ip4; ip4_addr ip4;
ip6_addr ip6; ip6_addr ip6;
net_addr_union net; net_addr net;
net_addr *net_ptr; net_addr *net_ptr;
struct symbol *s; struct symbol *s;
char *t; char *t;
...@@ -76,12 +76,12 @@ CF_DECLS ...@@ -76,12 +76,12 @@ CF_DECLS
%token <t> TEXT %token <t> TEXT
%type <iface> ipa_scope %type <iface> ipa_scope
%type <i> expr bool pxlen4 pxlen6 %type <i> expr bool pxlen4
%type <i32> expr_us %type <i32> expr_us
%type <time> datetime %type <time> datetime
%type <a> ipa ipa_raw %type <a> ipa
%type <net> net_ip4 net_ip6 net_ip net_or_ipa %type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
%type <net_ptr> net_any %type <net_ptr> net_ net_any
%type <t> text opttext %type <t> text opttext
...@@ -151,15 +151,12 @@ bool: ...@@ -151,15 +151,12 @@ bool:
| /* Silence means agreement */ { $$ = 1; } | /* Silence means agreement */ { $$ = 1; }
; ;
/* Addresses, prefixes and netmasks */
ipa_raw: /* Addresses */
IP4 { $$ = ipa_from_ip4($1); }
| IP6 { $$ = ipa_from_ip6($1); }
;
ipa: ipa:
ipa_raw IP4 { $$ = ipa_from_ip4($1); }
| IP6 { $$ = ipa_from_ip6($1); }
| SYM { | SYM {
if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected"); if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected");
$$ = SYM_VAL($1).ip; $$ = SYM_VAL($1).ip;
...@@ -172,42 +169,85 @@ ipa_scope: ...@@ -172,42 +169,85 @@ ipa_scope:
; ;
/* 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_: net_ip_ { $$ = cfg_alloc($1.length); net_copy($$, &($1)); } ;
net_ip4
| net_ip6
| IP4 { $$.ip4 = NET_ADDR_IP4($1, IP4_MAX_PREFIX_LENGTH); }
| IP6 { $$.ip6 = NET_ADDR_IP6($1, IP6_MAX_PREFIX_LENGTH); }
;
pxlen4: /* Networks - regular */
'/' expr {
if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2); net_ip6:
$$ = $2; 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: net_any:
'/' expr { net_
if ($2 < 0 || $2 > IP6_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2); | SYM {
$$ = $2; 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: datetime:
TEXT { TEXT {
$$ = tm_parse_datetime($1); $$ = tm_parse_datetime($1);
......
...@@ -475,7 +475,8 @@ block: ...@@ -475,7 +475,8 @@ block:
* Complex types, their bison value is struct f_val * Complex types, their bison value is struct f_val
*/ */
fipa: 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); }
; ;
...@@ -571,19 +572,19 @@ switch_items: ...@@ -571,19 +572,19 @@ switch_items:
; ;
fprefix: fprefix:
net_ip { $$.net = $1; $$.lo = $1.n.pxlen; $$.hi = $1.n.pxlen; } net_ip_ { $$.net = $1; $$.lo = $1.pxlen; $$.hi = $1.pxlen; }
| net_ip '+' { $$.net = $1; $$.lo = $1.n.pxlen; $$.hi = net_max_prefix_length[$1.n.type]; } | net_ip_ '+' { $$.net = $1; $$.lo = $1.pxlen; $$.hi = net_max_prefix_length[$1.type]; }
| net_ip '-' { $$.net = $1; $$.lo = 0; $$.hi = $1.n.pxlen; } | net_ip_ '-' { $$.net = $1; $$.lo = 0; $$.hi = $1.pxlen; }
| net_ip '{' NUM ',' NUM '}' { | net_ip_ '{' NUM ',' NUM '}' {
$$.net = $1; $$.lo = $3; $$.hi = $5; $$.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); cf_error("Invalid prefix pattern range: {%d, %d}", $3, $5);
} }
; ;
fprefix_set: fprefix_set:
fprefix { $$ = f_new_trie(cfg_mem, sizeof(struct f_trie_node)); trie_add_prefix($$, &($1.net.n), $1.lo, $1.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.n), $3.lo, $3.hi); } | fprefix_set ',' fprefix { $$ = $1; trie_add_prefix($$, &($3.net), $3.lo, $3.hi); }
; ;
switch_body: /* EMPTY */ { $$ = NULL; } switch_body: /* EMPTY */ { $$ = NULL; }
...@@ -635,7 +636,7 @@ constant: ...@@ -635,7 +636,7 @@ constant:
| FALSE { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_BOOL; $$->a2.i = 0; } | FALSE { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_BOOL; $$->a2.i = 0; }
| TEXT { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_STRING; $$->a2.p = $1; } | 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; } | 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" ); } | '[' 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; } | '[' 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; } | ENUM { $$ = f_new_inst(); $$->code = 'c'; $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; }
......
...@@ -39,7 +39,7 @@ struct f_inst_roa_check { ...@@ -39,7 +39,7 @@ struct f_inst_roa_check {
}; };
struct f_prefix { struct f_prefix {
net_addr_union net; net_addr net;
u8 lo, hi; u8 lo, hi;
}; };
......
...@@ -16,6 +16,10 @@ define ten = 10; ...@@ -16,6 +16,10 @@ define ten = 10;
define p23 = (2, 3); define p23 = (2, 3);
define ip1222 = 1.2.2.2; define ip1222 = 1.2.2.2;
define net10 = 10.0.0.0/8;
define netdoc = 2001:db8::/32;
function onef(int a) function onef(int a)
{ {
return 1; return 1;
...@@ -55,6 +59,7 @@ function fifteen() ...@@ -55,6 +59,7 @@ function fifteen()
return 15; return 15;
} }
/*
roa table rl roa table rl
{ {
roa 10.110.0.0/16 max 16 as 1000; roa 10.110.0.0/16 max 16 as 1000;
...@@ -80,6 +85,7 @@ function test_roa() ...@@ -80,6 +85,7 @@ function test_roa()
" ", roa_check(rl, 10.130.30.0/24, 3000) = ROA_INVALID, " ", roa_check(rl, 10.130.30.0/24, 3000) = ROA_INVALID,
" ", roa_check(rl, 10.130.130.0/24, 3000) = ROA_VALID; " ", roa_check(rl, 10.130.130.0/24, 3000) = ROA_VALID;
} }
*/
function path_test() function path_test()
bgpmask pm1; bgpmask pm1;
...@@ -232,7 +238,7 @@ function __test2() ...@@ -232,7 +238,7 @@ function __test2()
function test_pxset(prefix set pxs) function test_pxset(prefix set pxs)
{ {
print 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.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; 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, ",", print " must be false: ", 10.0.0.0/7 ~ pxs, ",", 10.0.0.0/13 ~ pxs, ",", 10.0.0.0/16 ~ pxs, ",",
...@@ -312,12 +318,12 @@ string st; ...@@ -312,12 +318,12 @@ string st;
px = 1.2.0.0/18; px = 1.2.0.0/18;
print "Testing prefixes: 1.2.0.0/18 = ", px; 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 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; 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; p = 127.1.2.3;
print "Testing mask : 127.0.0.0 = ", p.mask(8); print "Testing mask : 127.0.0.0 = ", p.mask(8);
pp = (1, 2); pp = (1, 2);
print "Testing pairs: (1,2) = ", (1,2), " = ", pp, " = ", (1,1+1), " = ", 'mkpair-a'(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 " must be true: ", (1,2) = (1,1+1);
...@@ -397,7 +403,7 @@ string st; ...@@ -397,7 +403,7 @@ string st;
print "1.2.3.4 = ", onetwo; print "1.2.3.4 = ", onetwo;
i = 4200000000; 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(2);
test_undef(3); test_undef(3);
......
...@@ -67,7 +67,7 @@ ip6_masklen(ip6_addr *a) ...@@ -67,7 +67,7 @@ ip6_masklen(ip6_addr *a)
if (a->addr[i] != ~0U) if (a->addr[i] != ~0U)
{ {
j = u32_masklen(a->addr[i]); j = u32_masklen(a->addr[i]);
if (j < 0) if (j == 255)
return j; return j;
n += j; n += j;
while (++i < 4) while (++i < 4)
......
...@@ -91,6 +91,9 @@ typedef ip6_addr ip_addr; ...@@ -91,6 +91,9 @@ typedef ip6_addr ip_addr;
#define ipa_is_ip4(a) ip6_is_v4mapped(a) #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 * Public constructors
...@@ -180,16 +183,7 @@ static inline int ipa_nonzero2(ip_addr a) ...@@ -180,16 +183,7 @@ static inline int ipa_nonzero2(ip_addr a)
* Hash and compare functions * Hash and compare functions
*/ */
static inline uint ip4_hash(ip4_addr a) static inline u32 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)
{ {
/* Returns a 32-bit value, although low-order bits are not mixed */ /* Returns a 32-bit value, although low-order bits are not mixed */
u32 x = _I(a); u32 x = _I(a);
...@@ -198,14 +192,7 @@ static inline u32 ip4_hash32(ip4_addr a) ...@@ -198,14 +192,7 @@ static inline u32 ip4_hash32(ip4_addr a)
return x; return x;
} }
static inline uint ip6_hash(ip6_addr a) static inline u32 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)
{ {
/* Returns a 32-bit hash key, although low-order bits are not mixed */ /* Returns a 32-bit hash key, although low-order bits are not mixed */
u32 x = _I0(a) ^ _I1(a) ^ _I2(a) ^ _I3(a); u32 x = _I0(a) ^ _I1(a) ^ _I2(a) ^ _I3(a);
...@@ -218,7 +205,6 @@ static inline int ip4_compare(ip4_addr a, ip4_addr b) ...@@ -218,7 +205,6 @@ static inline int ip4_compare(ip4_addr a, ip4_addr b)
int ip6_compare(ip6_addr a, ip6_addr b); int ip6_compare(ip6_addr a, ip6_addr b);
#define ipa_hash(x) ip6_hash(x) #define ipa_hash(x) ip6_hash(x)
#define ipa_hash32(x) ip6_hash32(x)
#define ipa_compare(x,y) ip6_compare(x,y) #define ipa_compare(x,y) ip6_compare(x,y)
......
...@@ -107,6 +107,17 @@ static inline void net_fill_ipa(net_addr *a, ip_addr prefix, uint pxlen) ...@@ -107,6 +107,17 @@ static inline void net_fill_ipa(net_addr *a, ip_addr prefix, uint pxlen)
net_fill_ip6(a, ipa_to_ip6(prefix), pxlen); 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) static inline ip4_addr net4_prefix(const net_addr *a)
{ return ((net_addr_ip4 *) a)->prefix; } { return ((net_addr_ip4 *) a)->prefix; }
...@@ -199,20 +210,20 @@ static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src) ...@@ -199,20 +210,20 @@ static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src)
static inline u32 net_hash_ip4(const net_addr_ip4 *n) 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) 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 */ /* XXXX */
static inline u32 u64_hash(u32 a) static inline u32 u64_hash(u64 a)
{ return u32_hash(a); } { return u32_hash(a); }
static inline u32 net_hash_vpn4(const net_addr_vpn4 *n) 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) 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) static inline int net_validate_ip4(const net_addr_ip4 *n)
......
...@@ -30,7 +30,7 @@ iface_patt_check(void) ...@@ -30,7 +30,7 @@ iface_patt_check(void)
struct iface_patt_node *pn; struct iface_patt_node *pn;
WALK_LIST(pn, this_ipatt->ipn_list) 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_error("Interface name/mask expected, not IP prefix");
} }
...@@ -85,7 +85,7 @@ CF_GRAMMAR ...@@ -85,7 +85,7 @@ CF_GRAMMAR
CF_ADDTO(conf, rtrid) CF_ADDTO(conf, rtrid)
rtrid: rtrid:
ROUTER ID idval ';' { new_config->router_id = $3; } ROUTER ID idval ';' { new_config->router_id = $3; }
| ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; } | ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; }
; ;
...@@ -261,8 +261,8 @@ iface_patt_node_init: ...@@ -261,8 +261,8 @@ iface_patt_node_init:
; ;
iface_patt_node_body: iface_patt_node_body:
TEXT { this_ipn->pattern = $1; net_fill_ip6(&this_ipn->prefix, IP6_NONE, 0); /* XXXX */ } TEXT { this_ipn->pattern = $1; /* this_ipn->prefix stays zero */ }
| opttext net_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.n; } | opttext net_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2; }
; ;
iface_negate: iface_negate:
...@@ -271,7 +271,7 @@ iface_negate: ...@@ -271,7 +271,7 @@ iface_negate:
; ;
iface_patt_node: iface_patt_node:
iface_patt_node_init iface_negate iface_patt_node_body iface_patt_node_init iface_negate iface_patt_node_body
; ;
...@@ -450,14 +450,15 @@ r_args: ...@@ -450,14 +450,15 @@ r_args:
} }
| r_args net_any { | r_args net_any {
$$ = $1; $$ = $1;
if ($$->prefix) cf_error("Only one prefix expected"); if ($$->addr) cf_error("Only one prefix expected");
$$->prefix = $2; $$->addr = $2;
} }
| r_args FOR net_or_ipa { | r_args FOR net_or_ipa {
$$ = $1; $$ = $1;
if ($$->prefix) cf_error("Only one prefix expected"); if ($$->addr) cf_error("Only one prefix expected");
$$->prefix = &($3.n);
$$->show_for = 1; $$->show_for = 1;
$$->addr = cfg_alloc($3.length);
net_copy($$->addr, &($3));
} }
| r_args TABLE SYM { | r_args TABLE SYM {
$$ = $1; $$ = $1;
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "lib/resource.h" #include "lib/resource.h"
#define NEIGH_HASH_SIZE 256 #define NEIGH_HASH_SIZE 256
#define NEIGH_HASH_OFFSET 24
static slab *neigh_slab; static slab *neigh_slab;
static list sticky_neigh_list, neigh_hash_table[NEIGH_HASH_SIZE]; static list sticky_neigh_list, neigh_hash_table[NEIGH_HASH_SIZE];
...@@ -52,7 +53,7 @@ static list sticky_neigh_list, neigh_hash_table[NEIGH_HASH_SIZE]; ...@@ -52,7 +53,7 @@ static list sticky_neigh_list, neigh_hash_table[NEIGH_HASH_SIZE];
static inline uint static inline uint
neigh_hash(struct proto *p, ip_addr *a) 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 static int
......
...@@ -56,7 +56,7 @@ struct fib { ...@@ -56,7 +56,7 @@ struct fib {
struct fib_node **hash_table; /* Node hash table */ struct fib_node **hash_table; /* Node hash table */
uint hash_size; /* Number of hash table entries (a power of two) */ uint hash_size; /* Number of hash table entries (a power of two) */
uint hash_order; /* Binary logarithm of hash_size */ 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 addr_type; /* Type of address data stored in fib (NET_*) */
uint node_size; /* XXXX */ uint node_size; /* XXXX */
uint node_offset; /* XXXX */ uint node_offset; /* XXXX */
...@@ -277,11 +277,6 @@ void rt_setup(pool *, rtable *, char *, struct rtable_config *); ...@@ -277,11 +277,6 @@ void rt_setup(pool *, rtable *, char *, struct rtable_config *);
static inline net *net_find(rtable *tab, net_addr *addr) { return (net *) fib_find(&tab->fib, addr); } 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_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_find(net *net, struct rte_src *src);
rte *rte_get_temp(struct rta *); rte *rte_get_temp(struct rta *);
void rte_update2(struct announce_hook *ah, net *net, rte *new, struct rte_src *src); void rte_update2(struct announce_hook *ah, net *net, rte *new, struct rte_src *src);
...@@ -313,7 +308,7 @@ rt_mark_for_prune(rtable *tab) ...@@ -313,7 +308,7 @@ rt_mark_for_prune(rtable *tab)
} }
struct rt_show_data { struct rt_show_data {
net_addr *prefix; net_addr *addr;
rtable *table; rtable *table;
struct filter *filter; struct filter *filter;
int verbose; int verbose;
......
...@@ -195,10 +195,10 @@ rt_prune_sources(void) ...@@ -195,10 +195,10 @@ rt_prune_sources(void)
* Multipath Next Hop * Multipath Next Hop
*/ */
static inline uint static inline u32
mpnh_hash(struct mpnh *x) mpnh_hash(struct mpnh *x)
{ {
uint h = 0; u32 h = 0;
for (; x; x = x->next) for (; x; x = x->next)
h ^= ipa_hash(x->gw); h ^= ipa_hash(x->gw);
...@@ -1008,8 +1008,9 @@ rta_alloc_hash(void) ...@@ -1008,8 +1008,9 @@ rta_alloc_hash(void)
static inline uint static inline uint
rta_hash(rta *a) rta_hash(rta *a)
{ {
return (((uint) (uintptr_t) a->src) ^ ipa_hash(a->gw) ^ /* XXXX fully convert to u32 hashing */
mpnh_hash(a->nexthops) ^ ea_hash(a->eattrs)) & 0xffff; return (((uint) (uintptr_t) a->src) ^ (ipa_hash(a->gw) >> 16) ^
(mpnh_hash(a->nexthops) >> 16) ^ ea_hash(a->eattrs)) & 0xffff;
} }
static inline int static inline int
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#define HASH_DEF_ORDER 10 #define HASH_DEF_ORDER 10
#define HASH_HI_MARK *4 #define HASH_HI_MARK *4
#define HASH_HI_STEP 2 #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_MARK /5
#define HASH_LO_STEP 2 #define HASH_LO_STEP 2
#define HASH_LO_MIN 10 #define HASH_LO_MIN 10
...@@ -266,38 +266,32 @@ fib_get(struct fib *f, const net_addr *a) ...@@ -266,38 +266,32 @@ fib_get(struct fib *f, const net_addr *a)
return b; return b;
} }
static void * static inline void *
fib_route_ip4(struct fib *f, const net_addr *n0) fib_route_ip4(struct fib *f, net_addr_ip4 *n)
{ {
net_addr net; void *r;
net_addr_ip4 *n = (net_addr_ip4 *) &net;
void *b;
net_copy(&net, n0); while (!(r = fib_find(f, (net_addr *) n)) && (n->pxlen > 0))
while (!(b = fib_find(f, &net)) && (n->pxlen > 0))
{ {
n->pxlen--; n->pxlen--;
ip4_clrbit(&n->prefix, n->pxlen); ip4_clrbit(&n->prefix, n->pxlen);
} }
return b; return r;
} }
static void * static inline void *
fib_route_ip6(struct fib *f, const net_addr *n0) fib_route_ip6(struct fib *f, net_addr_ip6 *n)
{ {
net_addr net; void *r;
net_addr_ip6 *n = (net_addr_ip6 *) &net;
void *b;
net_copy(&net, n0); while (!(r = fib_find(f, (net_addr *) n)) && (n->pxlen > 0))
while (!(b = fib_find(f, &net)) && (n->pxlen > 0))
{ {
n->pxlen--; n->pxlen--;
ip6_clrbit(&n->prefix, n->pxlen); ip6_clrbit(&n->prefix, n->pxlen);
} }
return b; return r;
} }
/** /**
...@@ -314,21 +308,25 @@ fib_route(struct fib *f, const net_addr *n) ...@@ -314,21 +308,25 @@ fib_route(struct fib *f, const net_addr *n)
{ {
ASSERT(f->addr_type == n->type); ASSERT(f->addr_type == n->type);
net_addr *n0 = alloca(n->length);
net_copy(n0, n);