summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Moskyto Matejka <mq@ucw.cz>2015-12-11 15:35:37 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2015-12-19 15:57:09 +0100
commitd7661fbe9dea980c61daa01a11a9aa59fa7be426 (patch)
treeba6c715e5b4cb1ba638dc5b75e14008a0e6f5e84
parent9b136840d90cce887cd139054c3f0a7d8b9f57d2 (diff)
Removed BITS_PER_IP_ADDRESS, MAX_PREFIX_LENGTH, BIRD_AF
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
-rw-r--r--conf/confbase.Y27
-rw-r--r--filter/config.Y4
-rw-r--r--filter/filter.c2
-rw-r--r--lib/ip.h4
-rw-r--r--lib/net.c10
-rw-r--r--lib/net.h3
-rw-r--r--nest/config.Y110
-rw-r--r--nest/neighbor.c2
-rw-r--r--nest/route.h3
-rw-r--r--nest/rt-table.c8
-rw-r--r--proto/bfd/packets.c8
-rw-r--r--proto/ospf/iface.c2
-rw-r--r--proto/ospf/lsalib.c2
-rw-r--r--proto/ospf/ospf.h9
-rw-r--r--proto/ospf/rt.c31
-rw-r--r--proto/radv/packets.c1
-rw-r--r--proto/rip/packets.c1
-rw-r--r--sysdep/bsd/krt-sock.c47
-rw-r--r--sysdep/linux/netlink.c38
-rw-r--r--sysdep/unix/io.c16
-rw-r--r--sysdep/unix/unix.h18
21 files changed, 146 insertions, 200 deletions
diff --git a/conf/confbase.Y b/conf/confbase.Y
index 3ad0c5f0..4bf9599b 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -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:
diff --git a/filter/config.Y b/filter/config.Y
index 312506c4..d6844751 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -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);
}
;
diff --git a/filter/filter.c b/filter/filter.c
index 1383961c..0e17a8e5 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -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)
{
diff --git a/lib/ip.h b/lib/ip.h
index 66fdd8c2..9706b397 100644
--- a/lib/ip.h
+++ b/lib/ip.h
@@ -43,12 +43,8 @@
#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
diff --git a/lib/net.c b/lib/net.c
index df833e0f..21486a9b 100644
--- 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)
{
diff --git a/lib/net.h b/lib/net.h
index 33686fb5..bc1233bf 100644
--- 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 })
diff --git a/nest/config.Y b/nest/config.Y
index 537a363c..e5a6e0bb 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -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, ""); } ;
diff --git a/nest/neighbor.c b/nest/neighbor.c
index 14a6b113..5b525fa9 100644
--- a/nest/neighbor.c
+++ b/nest/neighbor.c
@@ -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 */
{
diff --git a/nest/route.h b/nest/route.h
index 4480d17b..7d9485f1 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -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;
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 0a148f45..05073ce0 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -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;
diff --git a/proto/bfd/packets.c b/proto/bfd/packets.c
index cb40bcda..2200acfa 100644
--- a/proto/bfd/packets.c
+++ b/proto/bfd/packets.c
@@ -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;
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c
index 5d37b005..91e22266 100644
--- a/proto/ospf/iface.c
+++ b/proto/ospf/iface.c
@@ -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;
diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c
index 9a6b0457..5564bee7 100644
--- a/proto/ospf/lsalib.c
+++ b/proto/ospf/lsalib.c
@@ -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;
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index 6291ae1a..3e96b511 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -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)
{
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index aee0368a..0adc3871 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -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
diff --git a/proto/radv/packets.c b/proto/radv/packets.c
index a38b58b2..3bb38221 100644
--- a/proto/radv/packets.c
+++ b/proto/radv/packets.c
@@ -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;
diff --git a/proto/rip/packets.c b/proto/rip/packets.c
index 4fc832d5..85f0bea5 100644
--- a/proto/rip/packets.c
+++ b/proto/rip/packets.c
@@ -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;
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c
index 1db39493..19e82047 100644
--- a/sysdep/bsd/krt-sock.c
+++ b/sysdep/bsd/krt-sock.c
@@ -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;
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index 7c4c4b2b..d5c8a2ab 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -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
}
/*
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index b636e799..bc00def9 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -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 &&
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index 4e0ff841..58ceab1e 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -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)) }; }