]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Follow-up work on integration
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 24 Dec 2015 14:52:03 +0000 (15:52 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 24 Dec 2015 14:56:04 +0000 (15:56 +0100)
20 files changed:
conf/confbase.Y
filter/config.Y
filter/filter.h
filter/test.conf
lib/ip.c
lib/ip.h
lib/net.h
nest/config.Y
nest/neighbor.c
nest/route.h
nest/rt-attr.c
nest/rt-fib.c
nest/rt-table.c
proto/bfd/bfd.c
proto/ospf/config.Y
proto/ospf/iface.c
proto/ospf/neighbor.c
proto/ospf/packet.c
proto/radv/config.Y
sysdep/unix/krt.Y

index 467ce5a42e6bf2d12451190e541ef53d1e4d9f89..06698833766bc2dd7c1a328ee05e6ae63d0bbd17 100644 (file)
@@ -41,7 +41,7 @@ CF_DECLS
   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;
@@ -76,12 +76,12 @@ CF_DECLS
 %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
 
@@ -151,15 +151,12 @@ bool:
  | /* 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;
@@ -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_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);
index 7e9f4104ed9e2ec58d6dc29ae410d57fef9be76a..6efc14f5e0d22009450001155e6104eade025d18 100644 (file)
@@ -475,7 +475,8 @@ block:
  * 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); }
  ;
 
 
@@ -571,19 +572,19 @@ switch_items:
  ;
 
 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; }
@@ -635,7 +636,7 @@ constant:
  | 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; }
index 1052f8c8e65fdcb615adcdf933538b575891d025..c100a79aac6cb83211ca4da79c15926ff9a59561 100644 (file)
@@ -39,7 +39,7 @@ struct f_inst_roa_check {
 };
 
 struct f_prefix {
-  net_addr_union net;
+  net_addr net;
   u8 lo, hi;
 };
 
index a99d0a516ce28045013648dc6bad234d98b7516d..c3f74d94dc233414fc32cffc9f51ba613d1820b9 100644 (file)
@@ -16,6 +16,10 @@ define ten = 10;
 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;
@@ -55,6 +59,7 @@ function fifteen()
        return 15;
 }
 
+/*
 roa table rl
 {
        roa 10.110.0.0/16 max 16 as 1000;
@@ -80,6 +85,7 @@ function test_roa()
              " ", 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;
@@ -232,7 +238,7 @@ function __test2()
 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, ",",
@@ -312,12 +318,12 @@ string st;
 
        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);
@@ -397,7 +403,7 @@ string st;
        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);
index 6205915af5ba309dc44a4fbeefb596b63427de51..5e039c12c65cedaa02b34bf81bcfd759341f95d1 100644 (file)
--- a/lib/ip.c
+++ b/lib/ip.c
@@ -67,7 +67,7 @@ ip6_masklen(ip6_addr *a)
     if (a->addr[i] != ~0U)
     {
       j = u32_masklen(a->addr[i]);
-      if (j < 0)
+      if (j == 255)
        return j;
       n += j;
       while (++i < 4)
index 60a9a7b2bd2a13bcd5f2249574c7227b3f4b42b5..3191e307344bf070296d4db35b7f4e5018dada25 100644 (file)
--- a/lib/ip.h
+++ b/lib/ip.h
@@ -91,6 +91,9 @@ typedef ip6_addr ip_addr;
 
 #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
@@ -180,16 +183,7 @@ static inline int ipa_nonzero2(ip_addr a)
  *     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);
@@ -198,14 +192,7 @@ static inline u32 ip4_hash32(ip4_addr 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);
@@ -218,7 +205,6 @@ static inline int ip4_compare(ip4_addr a, ip4_addr b)
 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)
 
 
index 9439c6dbe538a625b4af8c1d6959985df5671296..b0ab2153c360b2af67fb3e33287885b3506cc7e1 100644 (file)
--- a/lib/net.h
+++ b/lib/net.h
@@ -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);
 }
 
+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; }
@@ -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)
-{ 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)
index 9d20dd48f954aa67b75103234696a7f83f520191..963393cc0697ac10f40cbc179babcfed8b013b69 100644 (file)
@@ -30,7 +30,7 @@ iface_patt_check(void)
   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");
 }
 
@@ -85,7 +85,7 @@ CF_GRAMMAR
 
 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; }
  ;
@@ -261,8 +261,8 @@ iface_patt_node_init:
  ;
 
 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:
@@ -271,7 +271,7 @@ 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
  ;
 
 
@@ -450,14 +450,15 @@ r_args:
    }
  | 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;
index 5b525fa95dd79ecc456d93031e71b39d6d29af3a..74c3c6640453608e4de313be90a7d7d7e3833ad5 100644 (file)
@@ -45,6 +45,7 @@
 #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];
@@ -52,7 +53,7 @@ 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
index a30a3880b61b8a89f90d9429283253be9965f21b..fbafe293961477de72b688e3c9a51cf4ef15e28d 100644 (file)
@@ -56,7 +56,7 @@ struct fib {
   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 */
@@ -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_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);
@@ -313,7 +308,7 @@ rt_mark_for_prune(rtable *tab)
 }
 
 struct rt_show_data {
-  net_addr *prefix;
+  net_addr *addr;
   rtable *table;
   struct filter *filter;
   int verbose;
index 7fa05d6dc70a5397a931912b1b60ac2a31e8334f..d100c537930444dd30b2928c2fb118e85fff823e 100644 (file)
@@ -195,10 +195,10 @@ rt_prune_sources(void)
  *     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);
 
@@ -1008,8 +1008,9 @@ rta_alloc_hash(void)
 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
index c12d05197b49bbad77148f9e96fa3abd79016e00..c83ae171c97bff1731782ba54d40a34d61078dc4 100644 (file)
@@ -43,7 +43,7 @@
 #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
@@ -266,38 +266,32 @@ fib_get(struct fib *f, const net_addr *a)
   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;
 }
 
 /**
@@ -314,21 +308,25 @@ fib_route(struct fib *f, 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 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)
 {
@@ -398,7 +396,12 @@ fib_delete(struct fib *f, void *E)
                }
              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;
index 963c8fbd724856eba123d478ef942a99ea1e799f..7c72aa4a328401739bd1d852ada0030cbda09061 100644 (file)
@@ -68,25 +68,60 @@ make_tmp_attrs(struct rte *rt, struct linpool *pool)
   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
@@ -2040,10 +2075,10 @@ ptr_hash(void *ptr)
   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
@@ -2077,7 +2112,7 @@ hc_alloc_table(struct hostcache *hc, unsigned order)
 {
   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);
 
@@ -2178,14 +2213,11 @@ rt_free_hostcache(rtable *tab)
 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
@@ -2235,15 +2267,15 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
   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;
@@ -2285,12 +2317,7 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
 
  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;
@@ -2331,7 +2358,7 @@ rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep)
   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))
@@ -2575,7 +2602,7 @@ rt_show(struct rt_show_data *d)
   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;
@@ -2584,13 +2611,10 @@ rt_show(struct rt_show_data *d)
     }
   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);
index 7a0857915292ca114fc43c5c8f49b01e553483d9..3ba3a5d967bc42a3f9ac0d508685ec342dafe142 100644 (file)
 #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;
index 5673ef6088c693785b7fb426326e5da80d652919..881ec7818d26d13e802e8beeadfd09ffa4b81394 100644 (file)
@@ -220,7 +220,7 @@ ospf_stubnet_start:
    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;
    }
  ;
@@ -330,7 +330,7 @@ pref_base: net_ip
  {
    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;
  }
 ;
 
index 442cec3a676c482e1dfe9e15112dde7e859a6360..8c997ced922c2dd1eed45f858f053fda10c3df28 100644 (file)
@@ -581,6 +581,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
   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);
 
@@ -1333,7 +1334,7 @@ ospf_iface_info(struct ospf_iface *ifa)
     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);
index c5d44dec85093be5c3e1919d81c9156ba5ae42fd..b30b0438ef59bcd9ca5967e6c65f2058c4f70eb5 100644 (file)
@@ -506,13 +506,14 @@ ospf_dr_election(struct ospf_iface *ifa)
 
   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);
 
index 9690c28a01efe0105e39d93073e5ed5695d94eaf..35ef7c6ecc6c66ea90c9ee3912c1962d19438a22 100644 (file)
@@ -500,8 +500,8 @@ ospf_send_to_agt(struct ospf_iface *ifa, u8 state)
 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);
 }
index efb474a60302b983772ffc2c8d92a98d4f6f1e9f..5e655de40cd15de4f5382cd29100290387201fa2 100644 (file)
@@ -150,7 +150,7 @@ radv_iface:
 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;
index eb0ae1097406ff001261d54dac230b2441652e00..80bf97ecb601920dd6e0c169fb31bdb2fbaf33db 100644 (file)
@@ -69,7 +69,7 @@ kif_item:
    }
  | 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);
    }
  ;