]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Removed BITS_PER_IP_ADDRESS, MAX_PREFIX_LENGTH, BIRD_AF
authorJan Moskyto Matejka <mq@ucw.cz>
Fri, 11 Dec 2015 14:35:37 +0000 (15:35 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Sat, 19 Dec 2015 14:57:09 +0000 (15:57 +0100)
Explicit setting of AF_INET(6|) in IP socket creation. BFD set to listen
on v6, without setting the V6ONLY flag to catch both v4 and v6 traffic.

Squashing and minor changes by Ondrej Santiago Zajicek

21 files changed:
conf/confbase.Y
filter/config.Y
filter/filter.c
lib/ip.h
lib/net.c
lib/net.h
nest/config.Y
nest/neighbor.c
nest/route.h
nest/rt-table.c
proto/bfd/packets.c
proto/ospf/iface.c
proto/ospf/lsalib.c
proto/ospf/ospf.h
proto/ospf/rt.c
proto/radv/packets.c
proto/rip/packets.c
sysdep/bsd/krt-sock.c
sysdep/linux/netlink.c
sysdep/unix/io.c
sysdep/unix/unix.h

index 3ad0c5f0cc110ff344f43b70dd75a16c1c29cc89..4bf9599bca376312bc03884eb07c1f6379a2d8ef 100644 (file)
@@ -76,11 +76,10 @@ CF_DECLS
 %token <t> TEXT
 %type <iface> ipa_scope
 
-%type <i> expr bool pxlen
+%type <i> expr bool pxlen4 pxlen6
 %type <i32> expr_us
 %type <time> datetime
 %type <a> ipa ipa_raw
-%type <px> prefix
 %type <net> net_ip4 net_ip6 net_ip net_or_ipa
 %type <net_ptr> net_any
 
@@ -175,9 +174,9 @@ ipa_scope:
 
 /* XXXX - symbols and tests */
 
-net_ip4: IP4 pxlen { $$.ip4 = NET_ADDR_IP4($1, $2); }
+net_ip4: IP4 pxlen4 { $$.ip4 = NET_ADDR_IP4($1, $2); }
 
-net_ip6: IP6 pxlen { $$.ip6 = NET_ADDR_IP6($1, $2); }
+net_ip6: IP6 pxlen6 { $$.ip6 = NET_ADDR_IP6($1, $2); }
 
 net_ip: net_ip4 | net_ip6 ;
 
@@ -191,22 +190,22 @@ net_or_ipa:
  ;
 
 
-prefix:
-   ipa pxlen {
-     if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix");
-     $$.addr = $1; $$.len = $2;
+pxlen4:
+   '/' expr {
+     if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
+     $$ = $2;
+   }
+ | ':' IP4 {
+     $$ = ip4_masklen($2);
+     if ($$ < 0) cf_error("Invalid netmask %I", $2);
    }
  ;
 
-pxlen:
+pxlen6:
    '/' expr {
-     if ($2 < 0 || $2 > BITS_PER_IP_ADDRESS) cf_error("Invalid prefix length %d", $2);
+     if ($2 < 0 || $2 > IP6_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
      $$ = $2;
    }
- | ':' ipa {
-     $$ = ipa_masklen($2);
-     if ($$ < 0) cf_error("Invalid netmask %I", $2);
-   }
  ;
 
 datetime:
index 312506c4e2916e05f94c8ff794f2e1d11b76097c..d684475156bb8d602485bca9d4b17d5a356d4ede 100644 (file)
@@ -574,7 +574,7 @@ switch_items:
 
 fprefix_s:
    ipa_raw '/' NUM %prec '/' {
-     if (($3 < 0) || ($3 > MAX_PREFIX_LENGTH) || !ip_is_prefix($1, $3)) cf_error("Invalid network prefix: %I/%d.", $1, $3);
+     if (($3 < 0) || ($3 > (ipa_is_ip4($1) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH)) || !ip_is_prefix($1, $3)) cf_error("Invalid network prefix: %I/%d.", $1, $3);
      $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3;
    }
  ;
@@ -584,7 +584,7 @@ fprefix:
  | fprefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
  | fprefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
  | fprefix_s '{' NUM ',' NUM '}' { 
-     if (! ((0 <= $3) && ($3 <= $5) && ($5 <= MAX_PREFIX_LENGTH))) cf_error("Invalid prefix pattern range: {%d, %d}.", $3, $5);
+     if (! ((0 <= $3) && ($3 <= $5) && ($5 <= (ipa_is_ip4($1.val.px.ip) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH)))) cf_error("Invalid prefix pattern range: {%d, %d}.", $3, $5);
      $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8);
    }
  ;
index 1383961c7b5792dc9f029bc5a7f23fbf7d8cfe3d..0e17a8e58b542d1d76ca37a878e4e3b5be02cc3f 100644 (file)
@@ -218,7 +218,7 @@ fprefix_get_bounds(struct f_prefix *px, int *l, int *h)
     *l = 0;
 
   else if (px->len & LEN_PLUS)
-    *h = MAX_PREFIX_LENGTH;
+    *h = ipa_is_ip4(px->ip) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH;
 
   else if (px->len & LEN_RANGE)
     {
index 66fdd8c2302dd8d354062e97a3979e450bfed310..9706b397715e30c582d15859af4861f8dfe12235 100644 (file)
--- a/lib/ip.h
+++ b/lib/ip.h
 #define UDP_HEADER_LENGTH      8
 
 #ifdef IPV6
-#define MAX_PREFIX_LENGTH 128
-#define BITS_PER_IP_ADDRESS 128
 #define STD_ADDRESS_P_LENGTH 39
 #else
-#define MAX_PREFIX_LENGTH 32
-#define BITS_PER_IP_ADDRESS 32
 #define STD_ADDRESS_P_LENGTH 15
 #endif
 
index df833e0feb5dd5c574f36b77801880290319c80f..21486a9b29fcf352eaa862258981acf3bb8ed832 100644 (file)
--- a/lib/net.c
+++ b/lib/net.c
@@ -3,6 +3,7 @@
 #include "lib/ip.h"
 #include "lib/net.h"
 
+
 const u16 net_addr_length[] = {
   [NET_IP4] = sizeof(net_addr_ip4),
   [NET_IP6] = sizeof(net_addr_ip6),
@@ -10,6 +11,14 @@ const u16 net_addr_length[] = {
   [NET_VPN6] = sizeof(net_addr_vpn6)
 };
 
+const u8 net_max_prefix_length[] = {
+  [NET_IP4] = IP4_MAX_PREFIX_LENGTH,
+  [NET_IP6] = IP6_MAX_PREFIX_LENGTH,
+  [NET_VPN4] = IP4_MAX_PREFIX_LENGTH,
+  [NET_VPN6] = IP4_MAX_PREFIX_LENGTH
+};
+
+
 int
 net_format(const net_addr *N, char *buf, int buflen)
 {
@@ -31,7 +40,6 @@ net_format(const net_addr *N, char *buf, int buflen)
   return 0;
 }
 
-
 ip_addr
 net_pxmask(const net_addr *a)
 {
index 33686fb5107250b778ebc11b81fa548b290eeceb..bc1233bf61610f8b1e86d6bd58e1b8b4eb3b1ffc 100644 (file)
--- a/lib/net.h
+++ b/lib/net.h
@@ -19,7 +19,6 @@
 #define NET_VPN6       4
 #define NET_MAX                5
 
-
 typedef struct net_addr {
   u8 type;
   u8 pxlen;
@@ -69,7 +68,7 @@ typedef union net_addr_union {
 
 
 extern const u16 net_addr_length[];
-
+extern const u8 net_max_prefix_length[];
 
 #define NET_ADDR_IP4(prefix,pxlen) \
   ((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix })
index 537a363c405f2fd09c786ab28590c8d95b51ea08..e5a6e0bbafe2b3cfbd6cc1ff454946c1a9f9a083 100644 (file)
@@ -75,10 +75,8 @@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
 %type <r> rtable
 %type <s> optsym
 %type <ra> r_args
-%type <ro> roa_args
-%type <rot> roa_table_arg
 %type <sd> sym_args
-%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode roa_mode limit_action table_type table_sorted tos
+%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action table_type table_sorted tos
 %type <ps> proto_patt proto_patt2
 %type <g> limit_spec
 
@@ -156,24 +154,6 @@ table: table_type TABLE SYM table_sorted {
    }
  ;
 
-CF_ADDTO(conf, roa_table)
-
-roa_table_start: ROA TABLE SYM {
-  this_roa_table = roa_new_table_config($3);
-};
-
-roa_table_opts:
-   /* empty */
- | roa_table_opts ROA prefix MAX NUM AS NUM ';' {
-     roa_add_item_config(this_roa_table, $3.addr, $3.len, $5, $7);
-   }
- ;
-
-roa_table:
-   roa_table_start
- | roa_table_start '{' roa_table_opts '}'
- ;
-
 /* Definition of protocols */
 
 CF_ADDTO(conf, proto)
@@ -469,20 +449,17 @@ CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filte
 r_args:
    /* empty */ {
      $$ = cfg_allocz(sizeof(struct rt_show_data));
-     $$->pxlen = 256;
      $$->filter = FILTER_ACCEPT;
    }
- | r_args prefix {
+ | r_args net_any {
      $$ = $1;
-     if ($$->pxlen != 256) cf_error("Only one prefix expected");
-     $$->prefix = $2.addr;
-     $$->pxlen = $2.len;
+     if ($$->prefix) cf_error("Only one prefix expected");
+     $$->prefix = $2;
    }
  | r_args FOR net_or_ipa {
      $$ = $1;
-     if ($$->pxlen != 256) cf_error("Only one prefix expected");
-     $$->prefix = IPA_NONE; /* XXXX */
-     $$->pxlen = 0; /* XXXX */
+     if ($$->prefix) cf_error("Only one prefix expected");
+     $$->prefix = &($3.n);
      $$->show_for = 1;
    }
  | r_args TABLE SYM {
@@ -546,45 +523,8 @@ export_mode:
  ;
 
 
-CF_CLI_HELP(SHOW ROA, ..., [[Show ROA table]])
-CF_CLI(SHOW ROA, roa_args, [<prefix> | in <prefix> | for <prefix>] [as <num>] [table <t>], [[Show ROA table]])
-{ roa_show($3); } ;
-
-roa_args:
-   /* empty */ {
-     $$ = cfg_allocz(sizeof(struct roa_show_data));
-     $$->mode = ROA_SHOW_ALL;
-     $$->table = roa_table_default;
-     if (roa_table_default == NULL)
-       cf_error("No ROA table defined");
-   }
- | roa_args roa_mode prefix {
-     $$ = $1;
-     if ($$->mode != ROA_SHOW_ALL) cf_error("Only one prefix expected");
-     $$->prefix = $3.addr;
-     $$->pxlen = $3.len;
-     $$->mode = $2;
-   }
- | roa_args AS NUM {
-     $$ = $1;
-     $$->asn = $3;
-   }
- | roa_args TABLE SYM {
-     $$ = $1;
-     if ($3->class != SYM_ROA) cf_error("%s is not a ROA table", $3->name);
-     $$->table = ((struct roa_table_config *)$3->def)->table;
-   }
- ;
-
-roa_mode:
-       { $$ = ROA_SHOW_PX; }
- | IN  { $$ = ROA_SHOW_IN; }
- | FOR { $$ = ROA_SHOW_FOR; }
- ;
-
-
 CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]])
-CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|roa|<symbol>], [[Show all known symbolic names]])
+CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|<symbol>], [[Show all known symbolic names]])
 { cmd_show_symbols($3); } ;
 
 sym_args:
@@ -596,46 +536,10 @@ sym_args:
  | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
  | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
  | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
- | sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
  | sym_args SYM { $$ = $1; $$->sym = $2; }
  ;
 
 
-roa_table_arg:
-   /* empty */ { 
-     if (roa_table_default == NULL)
-       cf_error("No ROA table defined");
-     $$ = roa_table_default;
-   }
- | TABLE SYM {
-     if ($2->class != SYM_ROA)
-       cf_error("%s is not a ROA table", $2->name);
-     $$ = ((struct roa_table_config *)$2->def)->table;
-   }
- ;
-
-CF_CLI_HELP(ADD, roa ..., [[Add ROA record]])
-CF_CLI(ADD ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Add ROA record]])
-{
-  if (! cli_access_restricted())
-    { roa_add_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
-};
-
-CF_CLI_HELP(DELETE, roa ..., [[Delete ROA record]])
-CF_CLI(DELETE ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Delete ROA record]])
-{
-  if (! cli_access_restricted())
-    { roa_delete_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
-};
-
-CF_CLI_HELP(FLUSH, roa [table <name>], [[Removes all dynamic ROA records]])
-CF_CLI(FLUSH ROA, roa_table_arg, [table <name>], [[Removes all dynamic ROA records]])
-{
-  if (! cli_access_restricted())
-    { roa_flush($3, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
-};
-
-
 CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
 CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
 { rdump(&root_pool); cli_msg(0, ""); } ;
index 14a6b11360730fcfce2cf4c65fab3fcdc7d37a0e..5b525fa95dd79ecc456d93031e71b39d6d29af3a 100644 (file)
@@ -83,7 +83,7 @@ if_connected(ip_addr *a, struct iface *i, struct ifa **ap)
            {
              /* Do not allow IPv4 network and broadcast addresses */
              if (ipa_is_ip4(*a) &&
-                 (net_pxlen(&b->prefix) < (BITS_PER_IP_ADDRESS - 1)) &&
+                 (net_pxlen(&b->prefix) < (IP4_MAX_PREFIX_LENGTH - 1)) &&
                  (ipa_equal(*a, net_prefix(&b->prefix)) ||     /* Network address */
                   ipa_equal(*a, b->brd)))      /* Broadcast */
              {
index 4480d17bbfdaeddec93d09473d2e748233c5f23d..7d9485f17adf4fbf4d35fc921f6d6921853d85e0 100644 (file)
@@ -304,8 +304,7 @@ rt_mark_for_prune(rtable *tab)
 }
 
 struct rt_show_data {
-  ip_addr prefix;
-  unsigned pxlen;
+  net_addr *prefix;
   rtable *table;
   struct filter *filter;
   int verbose;
index 0a148f454a20151ad5f9f6ccbc2127a92dd4d8ed..05073ce0cd2641a9714dd5b048908ad2d7bedfae 100644 (file)
@@ -2293,9 +2293,13 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
       he->igp_metric = rt_get_igp_metric(e);
     }
 
+  /* XXXX */
  done:
   /* Add a prefix range to the trie */
-  trie_add_prefix(tab->hostcache->trie, he->addr, MAX_PREFIX_LENGTH, pxlen, MAX_PREFIX_LENGTH);
+  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);
 
   rta_free(old_src);
   return old_src != he->src;
@@ -2580,7 +2584,7 @@ rt_show(struct rt_show_data *d)
   if (d->filtered && (d->export_mode || d->primary_only))
     cli_msg(0, "");
 
-  if (d->pxlen == 256)
+  if (!d->prefix)
     {
       FIB_ITERATE_INIT(&d->fit, &d->table->fib);
       this_cli->cont = rt_show_cont;
index cb40bcdadfb4193677bde1e28381f9a570a101e5..2200acfa093816e5472872d6d518544810b33165 100644 (file)
@@ -202,9 +202,7 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop)
   sk->priority = sk_priority_control;
   sk->flags = SKF_THREAD | SKF_LADDR_RX | (!multihop ? SKF_TTL_RX : 0);
 
-#ifdef IPV6
-  sk->flags |= SKF_V6ONLY;
-#endif
+  sk->af = AF_INET6;
 
   if (sk_open(sk) < 0)
     goto err;
@@ -237,9 +235,7 @@ bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa)
   sk->ttl = ifa ? 255 : -1;
   sk->flags = SKF_THREAD | SKF_BIND | SKF_HIGH_PORT;
 
-#ifdef IPV6
-  sk->flags |= SKF_V6ONLY;
-#endif
+  sk->af = AF_INET6;
 
   if (sk_open(sk) < 0)
     goto err;
index 5d37b00544a37b762ead2ff3031eb5b36d033832..91e2226658bb7d675c901f5612652a1d8b09b2b0 100644 (file)
@@ -111,6 +111,7 @@ ospf_sk_open(struct ospf_iface *ifa)
   sk->dport = OSPF_PROTO;
   sk->saddr = ifa->addr->ip;
   sk->iface = ifa->iface;
+  sk->af = ospf_is_v2(p) ? AF_INET : AF_INET6;
 
   sk->tos = ifa->cf->tx_tos;
   sk->priority = ifa->cf->tx_priority;
@@ -193,6 +194,7 @@ ospf_open_vlink_sk(struct ospf_proto *p)
   sock *sk = sk_new(p->p.pool);
   sk->type = SK_IP;
   sk->dport = OSPF_PROTO;
+  sk->af = ospf_is_v2(p) ? AF_INET : AF_INET6;
 
   /* FIXME: configurable tos/priority ? */
   sk->tos = IP_PREC_INTERNET_CONTROL;
index 9a6b04570cf7d8c7ee1db0e721687be6569a61cb..5564bee7a1ba0a340b9359da127fcf1bec49ed18 100644 (file)
@@ -493,7 +493,7 @@ lsa_validate_ext3(struct ospf_lsa_header *lsa, struct ospf_lsa_ext3 *body)
     return 0;
 
   int len = IPV6_PREFIX_SPACE(pxl);
-  if (body->metric & LSA_EXT3_FBIT) // forwardinf address
+  if (body->metric & LSA_EXT3_FBIT) // forwarding address
     len += 16;
   if (body->metric & LSA_EXT3_TBIT) // route tag
     len += 4;
index 6291ae1a70aa7b174aef55536e38621a29e3ad2f..3e96b5112cea84b400ec4121f130bcca52cda6f5 100644 (file)
@@ -726,9 +726,16 @@ lsa_net_count(struct ospf_lsa_header *lsa)
 #define IPV6_PREFIX_SPACE(x) ((((x) + 63) / 32) * 4)
 #define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32)
 
-/* FIXME: these four functions should be significantly redesigned w.r.t. integration,
+/* FIXME: these functions should be significantly redesigned w.r.t. integration,
    also should be named as ospf3_* instead of *_ipv6_* */
 
+static inline int
+ospf_valid_prefix(net_addr *n)
+{
+  /* In OSPFv2, prefix is stored as netmask; ip4_masklen() returns 255 for invalid one */
+  return n->pxlen <= IP6_MAX_PREFIX_LENGTH;
+}
+
 static inline u32 *
 ospf_get_ipv6_prefix(u32 *buf, net_addr *N, u8 *pxopts, u16 *rest)
 {
index aee0368a3653bdeadbc1d4f836ded5a31f12b04a..0adc387193dcf8909c8171eb9929cbacbdaa77fc 100644 (file)
@@ -412,7 +412,7 @@ add_network(struct ospf_area *oa, net_addr *net, int metric, struct top_hash_ent
     .nhs = en->nhs
   };
 
-  if (net->pxlen > MAX_PREFIX_LENGTH)
+  if (!ospf_valid_prefix(net))
   {
     log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
        p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
@@ -765,16 +765,16 @@ ospf_rt_sum(struct ospf_area *oa)
     {
       lsa_parse_sum_net(en, ospf_is_v2(p), &net, &pxopts, &metric);
 
-      if (pxopts & OPT_PX_NU)
-       continue;
-
-      if (net.pxlen > MAX_PREFIX_LENGTH)
+      if (!ospf_valid_prefix(&net))
       {
        log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
            p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
        continue;
       }
 
+      if (pxopts & OPT_PX_NU)
+       continue;
+
       options = 0;
       type = ORT_NET;
     }
@@ -862,16 +862,16 @@ ospf_rt_sum_tr(struct ospf_area *oa)
 
       lsa_parse_sum_net(en, ospf_is_v2(p), &net, &pxopts, &metric);
 
-      if (pxopts & OPT_PX_NU)
-       continue;
-
-      if (net.pxlen > MAX_PREFIX_LENGTH)
+      if (!ospf_valid_prefix(&net))
       {
        log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
            p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
        continue;
       }
 
+      if (pxopts & OPT_PX_NU)
+       continue;
+
       re = fib_find(&p->rtf, &net);
     }
     else // en->lsa_type == LSA_T_SUM_RT
@@ -1466,19 +1466,18 @@ ospf_ext_spf(struct ospf_proto *p)
 
     lsa_parse_ext(en, ospf_is_v2(p), &rt);
 
-    if (rt.metric == LSINFINITY)
-      continue;
-
-    if (rt.pxopts & OPT_PX_NU)
-      continue;
-
-    if (rt.net.pxlen > MAX_PREFIX_LENGTH)
+    if (!ospf_valid_prefix(&rt.net))
     {
       log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
          p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
       continue;
     }
 
+    if (rt.metric == LSINFINITY)
+      continue;
+
+    if (rt.pxopts & OPT_PX_NU)
+      continue;
 
     /* 16.4. (3) */
     /* If there are more areas, we already precomputed preferred ASBR
index a38b58b2e511e4e8bbf4da463e4850c102d48edc..3bb38221fe372b966e0fea43e83201e9cfc8ac7a 100644 (file)
@@ -412,6 +412,7 @@ radv_sk_open(struct radv_iface *ifa)
   sk->type = SK_IP;
   sk->dport = ICMPV6_PROTO;
   sk->saddr = ifa->addr->ip;
+  sk->af = AF_INET6;
 
   sk->ttl = 255; /* Mandatory for Neighbor Discovery packets */
   sk->rx_hook = radv_rx_hook;
index 4fc832d564c317e4c0a537df9119018cf99a9667..85f0bea55257966d8d5bac0081378b5db57c7499 100644 (file)
@@ -715,6 +715,7 @@ rip_open_socket(struct rip_iface *ifa)
 
   sock *sk = sk_new(p->p.pool);
   sk->type = SK_UDP;
+  sk->af = rip_is_v2(p) ? AF_INET : AF_INET6;
   sk->sport = ifa->cf->port;
   sk->dport = ifa->cf->port;
   sk->iface = ifa->iface;
index 1db39493dcefcb1f05c632c8ba1c72a8dab0f999..19e82047267cbb2cf0606930aeb27e0e618c3c4c 100644 (file)
@@ -207,7 +207,8 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
   msg.rtm.rtm_addrs = RTA_DST;
   msg.rtm.rtm_flags = RTF_UP | RTF_PROTO1;
 
-  if (net_prefix(net->n.addr) == MAX_PREFIX_LENGTH)
+  /* XXXX */
+  if (net_pxlen(net->n.addr) == net_max_prefix_length[net->n.addr->type])
     msg.rtm.rtm_flags |= RTF_HOST;
   else
     msg.rtm.rtm_addrs |= RTA_NETMASK;
@@ -296,7 +297,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
           return -1;
         }
 
-       sockaddr_fill(&gate, BIRD_AF, i->addr->ip, NULL, 0);
+       sockaddr_fill(&gate, ipa_is_ip4(i->addr->ip) ? AF_INET : AF_INET6, i->addr->ip, NULL, 0);
         msg.rtm.rtm_addrs |= RTA_GATEWAY;
       }
       break;
@@ -383,12 +384,17 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
   GETADDR(&gate, RTA_GATEWAY);
   GETADDR(&mask, RTA_NETMASK);
 
-  if (dst.sa.sa_family != BIRD_AF)
-    SKIP("invalid DST");
+
+  switch (dst.sa.sa_family) {
+    case AF_INET:
+    case AF_INET6: break;
+    default:
+      SKIP("invalid DST");
+  }
 
   idst  = ipa_from_sa(&dst);
-  imask = ipa_from_sa(&mask);
-  igate = (gate.sa.sa_family == BIRD_AF) ? ipa_from_sa(&gate) : IPA_NONE;
+  imask = ipa_from_sa(&mask); /* XXXX broken, see below */
+  igate = (gate.sa.sa_family == dst.sa.sa_family) ? ipa_from_sa(&gate) : IPA_NONE;
 
   /* We do not test family for RTA_NETMASK, because BSD sends us
      some strange values, but interpreting them as IPv4/IPv6 works */
@@ -398,7 +404,7 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
   if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
     SKIP("strange class/scope\n");
 
-  int pxlen = (flags & RTF_HOST) ? MAX_PREFIX_LENGTH : ipa_masklen(imask);
+  int pxlen = (flags & RTF_HOST) ? (ipa_is_ip4(imask) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH) : ipa_masklen(imask);
   if (pxlen < 0)
     { log(L_ERR "%s (%I) - netmask %I", errmsg, idst, imask); return; }
 
@@ -663,9 +669,13 @@ krt_read_addr(struct ks_msg *msg, int scan)
   GETADDR (&null, RTA_AUTHOR);
   GETADDR (&brd, RTA_BRD);
 
-  /* Some other family address */
-  if (addr.sa.sa_family != BIRD_AF)
-    return;
+  /* Is addr family IP4 or IP6? */
+  int ipv6;
+  switch (addr.sa.sa_family) {
+    case AF_INET: ipv6 = 0; break;
+    case AF_INET6: ipv6 = 1; break;
+    default: return;
+  }
 
   iaddr = ipa_from_sa(&addr);
   imask = ipa_from_sa(&mask);
@@ -701,16 +711,16 @@ krt_read_addr(struct ks_msg *msg, int scan)
   }
   ifa.scope = scope & IADDR_SCOPE_MASK;
 
-  if (masklen < BITS_PER_IP_ADDRESS)
+  if (masklen < (ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH))
   {
     net_fill_ipa(&ifa.prefix, ifa.ip, masklen);
     net_normalize(&ifa.prefix);
 
-    if (masklen == (BITS_PER_IP_ADDRESS - 1))
+    if (masklen == ((ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH) - 1))
       ifa.opposite = ipa_opposite_m1(ifa.ip);
 
 #ifndef IPV6
-    if (masklen == (BITS_PER_IP_ADDRESS - 2))
+    if (!ipv6 && masklen == IP4_MAX_PREFIX_LENGTH - 2)
       ifa.opposite = ipa_opposite_m2(ifa.ip);
 #endif
 
@@ -722,13 +732,13 @@ krt_read_addr(struct ks_msg *msg, int scan)
   }
   else if (!(iface->flags & IF_MULTIACCESS) && ipa_nonzero(ibrd))
   {
-    net_fill_ipa(&ifa.prefix, ibrd, BITS_PER_IP_ADDRESS);
+    net_fill_ipa(&ifa.prefix, ibrd, (ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH));
     ifa.opposite = ibrd;
     ifa.flags |= IA_PEER;
   }
   else
   {
-    net_fill_ipa(&ifa.prefix, ifa.ip, BITS_PER_IP_ADDRESS);
+    net_fill_ipa(&ifa.prefix, ifa.ip, (ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH));
     ifa.flags |= IA_HOST;
   }
 
@@ -825,7 +835,12 @@ krt_sysctl_scan(struct proto *p, int cmd, int table_id)
   mib[0] = CTL_NET;
   mib[1] = PF_ROUTE;
   mib[2] = 0;
-  mib[3] = BIRD_AF;
+  /* XXX: This value should be given from the caller */
+#ifdef IPV6
+  mib[3] = AF_INET6;
+#else
+  mib[3] = AF_INET;
+#endif
   mib[4] = cmd;
   mib[5] = 0;
   mcnt = 6;
index 7c4c4b2b6e7d48e1029a5e8728a805dcb18a992c..d5c8a2abc4d276de4a9a4ad9c615cd623a86e3d2 100644 (file)
@@ -646,12 +646,12 @@ nl_parse_addr4(struct ifaddrmsg *i, int scan, int new)
 
   ifa.ip = rta_get_ipa(a[IFA_LOCAL]);
 
-  if (i->ifa_prefixlen > BITS_PER_IP_ADDRESS)
+  if (i->ifa_prefixlen > IP4_MAX_PREFIX_LENGTH)
     {
       log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
       new = 0;
     }
-  if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS)
+  if (i->ifa_prefixlen == IP4_MAX_PREFIX_LENGTH)
     {
       ifa.brd = rta_get_ipa(a[IFA_ADDRESS]);
       net_fill_ip4(&ifa.prefix, rta_get_ip4(a[IFA_ADDRESS]), i->ifa_prefixlen);
@@ -670,10 +670,10 @@ nl_parse_addr4(struct ifaddrmsg *i, int scan, int new)
       net_fill_ip4(&ifa.prefix, ipa_to_ip4(ifa.ip), i->ifa_prefixlen);
       net_normalize(&ifa.prefix);
 
-      if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 1)
+      if (i->ifa_prefixlen == IP4_MAX_PREFIX_LENGTH - 1)
        ifa.opposite = ipa_opposite_m1(ifa.ip);
 
-      if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 2)
+      if (i->ifa_prefixlen == IP4_MAX_PREFIX_LENGTH - 2)
        ifa.opposite = ipa_opposite_m2(ifa.ip);
 
       if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
@@ -746,12 +746,12 @@ nl_parse_addr6(struct ifaddrmsg *i, int scan, int new)
 
   ifa.ip = rta_get_ipa(a[IFA_LOCAL] ? : a[IFA_ADDRESS]);
 
-  if (i->ifa_prefixlen > BITS_PER_IP_ADDRESS)
+  if (i->ifa_prefixlen > IP6_MAX_PREFIX_LENGTH)
     {
       log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
       new = 0;
     }
-  if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS)
+  if (i->ifa_prefixlen == IP6_MAX_PREFIX_LENGTH)
     {
       ifa.brd = rta_get_ipa(a[IFA_ADDRESS]);
       net_fill_ip6(&ifa.prefix, rta_get_ip6(a[IFA_ADDRESS]), i->ifa_prefixlen);
@@ -770,7 +770,7 @@ nl_parse_addr6(struct ifaddrmsg *i, int scan, int new)
       net_fill_ip6(&ifa.prefix, ipa_to_ip6(ifa.ip), i->ifa_prefixlen);
       net_normalize(&ifa.prefix);
 
-      if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 1)
+      if (i->ifa_prefixlen == IP6_MAX_PREFIX_LENGTH - 1)
        ifa.opposite = ipa_opposite_m1(ifa.ip);
     }
 
@@ -831,14 +831,21 @@ kif_do_scan(struct kif_proto *p UNUSED)
       nl_parse_link(h, 1);
     else
       log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
-
-  nl_request_dump(BIRD_AF, RTM_GETADDR);
+#ifndef IPV6
+  nl_request_dump(AF_INET, RTM_GETADDR);
   while (h = nl_get_scan())
     if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
       nl_parse_addr(h, 1);
     else
       log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
-
+#else
+  nl_request_dump(AF_INET6, RTM_GETADDR);
+  while (h = nl_get_scan())
+    if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
+      nl_parse_addr(h, 1);
+    else
+      log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
+#endif
   if_end_update();
 }
 
@@ -1280,12 +1287,21 @@ krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NUL
 {
   struct nlmsghdr *h;
 
-  nl_request_dump(BIRD_AF, RTM_GETROUTE);
+#ifndef IPV6
+  nl_request_dump(AF_INET, RTM_GETROUTE);
   while (h = nl_get_scan())
     if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
       nl_parse_route(h, 1);
     else
       log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
+#else
+  nl_request_dump(AF_INET6, RTM_GETROUTE);
+  while (h = nl_get_scan())
+    if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
+      nl_parse_route(h, 1);
+    else
+      log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
+#endif
 }
 
 /*
index b636e7997ea2288361919414d800976a7b0f8c7b..bc00def9a80737fa6a13b78d13f588e9334bed48 100644 (file)
@@ -1311,8 +1311,8 @@ sk_passive_connected(sock *s, int type)
 
   sock *t = sk_new(s->pool);
   t->type = type;
-  t->fd = fd;
   t->af = s->af;
+  t->fd = fd;
   t->ttl = s->ttl;
   t->tos = s->tos;
   t->rbsize = s->rbsize;
@@ -1371,7 +1371,6 @@ sk_passive_connected(sock *s, int type)
 int
 sk_open(sock *s)
 {
-  int af = BIRD_AF;
   int fd = -1;
   int do_bind = 0;
   int bind_port = 0;
@@ -1384,28 +1383,28 @@ sk_open(sock *s)
     s->ttx = "";                       /* Force s->ttx != s->tpos */
     /* Fall thru */
   case SK_TCP_PASSIVE:
-    fd = socket(af, SOCK_STREAM, IPPROTO_TCP);
+    fd = socket(s->af, SOCK_STREAM, IPPROTO_TCP);
     bind_port = s->sport;
     bind_addr = s->saddr;
     do_bind = bind_port || ipa_nonzero(bind_addr);
     break;
 
   case SK_UDP:
-    fd = socket(af, SOCK_DGRAM, IPPROTO_UDP);
+    fd = socket(s->af, SOCK_DGRAM, IPPROTO_UDP);
     bind_port = s->sport;
     bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE;
     do_bind = 1;
     break;
 
   case SK_IP:
-    fd = socket(af, SOCK_RAW, s->dport);
+    fd = socket(s->af, SOCK_RAW, s->dport);
     bind_port = 0;
     bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE;
     do_bind = ipa_nonzero(bind_addr);
     break;
 
   case SK_MAGIC:
-    af = 0;
+    s->af = 0;
     fd = s->fd;
     break;
 
@@ -1419,7 +1418,6 @@ sk_open(sock *s)
   if (fd >= FD_SETSIZE)
     ERR2("FD_SETSIZE limit reached");
 
-  s->af = af;
   s->fd = fd;
 
   if (sk_setup(s) < 0)
@@ -1448,7 +1446,7 @@ sk_open(sock *s)
        if (sk_set_high_port(s) < 0)
          log(L_WARN "Socket error: %s%#m", s->err);
 
-    sockaddr_fill(&sa, af, bind_addr, s->iface, bind_port);
+    sockaddr_fill(&sa, s->af, bind_addr, s->iface, bind_port);
     if (bind(fd, &sa.sa, SA_LEN(sa)) < 0)
       ERR2("bind");
   }
@@ -1460,7 +1458,7 @@ sk_open(sock *s)
   switch (s->type)
   {
   case SK_TCP_ACTIVE:
-    sockaddr_fill(&sa, af, s->daddr, s->iface, s->dport);
+    sockaddr_fill(&sa, s->af, s->daddr, s->iface, s->dport);
     if (connect(fd, &sa.sa, SA_LEN(sa)) >= 0)
       sk_tcp_connected(s);
     else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS &&
index 4e0ff84110e17cb7b87ea95fef8b44dfb5ba8f69..58ceab1efacf2e1c015fb6a97b5f160db75fc6b6 100644 (file)
@@ -47,14 +47,6 @@ typedef struct sockaddr_bird {
 } sockaddr;
 
 
-#ifdef IPV6
-#define BIRD_AF AF_INET6
-#define ipa_from_sa(x) ipa_from_sa6(x)
-#else
-#define BIRD_AF AF_INET
-#define ipa_from_sa(x) ipa_from_sa4(x)
-#endif
-
 
 /* This is sloppy hack, it should be detected by configure script */
 /* Linux systems have it defined so this is definition for BSD systems */
@@ -75,6 +67,16 @@ static inline ip_addr ipa_from_sa4(sockaddr *sa)
 static inline ip_addr ipa_from_sa6(sockaddr *sa)
 { return ipa_from_in6(((struct sockaddr_in6 *) sa)->sin6_addr); }
 
+static inline ip_addr ipa_from_sa(sockaddr *sa)
+{
+  switch (sa->sa.sa_family)
+  {
+  case AF_INET:                return ipa_from_sa4(sa);
+  case AF_INET6:       return ipa_from_sa6(sa);
+  default:             return IPA_NONE;
+  }
+}
+
 static inline struct in_addr ipa_to_in4(ip_addr a)
 { return (struct in_addr) { htonl(ipa_to_u32(a)) }; }