Commit d7661fbe authored by Jan Moskyto Matejka's avatar Jan Moskyto Matejka Committed by Ondřej Zajíček

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
parent 9b136840
......@@ -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:
......
......@@ -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);
}
;
......
......@@ -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)
{
......
......@@ -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
......
......@@ -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)
{
......
......@@ -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 })
......
......@@ -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, ""); } ;
......
......@@ -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 */
{
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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)
{
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
}
/*
......
......@@ -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 :