%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
/* 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 ;
;
-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:
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;
}
;
| 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);
}
;
*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)
{
#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
#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),
[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)
{
return 0;
}
-
ip_addr
net_pxmask(const net_addr *a)
{
#define NET_VPN6 4
#define NET_MAX 5
-
typedef struct net_addr {
u8 type;
u8 pxlen;
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 })
%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
}
;
-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)
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 {
;
-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:
| 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, ""); } ;
{
/* 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 */
{
}
struct rt_show_data {
- ip_addr prefix;
- unsigned pxlen;
+ net_addr *prefix;
rtable *table;
struct filter *filter;
int verbose;
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;
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;
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;
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;
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;
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;
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;
#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)
{
.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);
{
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;
}
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
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
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;
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;
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;
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;
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 */
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; }
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);
}
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
}
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;
}
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;
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);
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])
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);
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);
}
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();
}
{
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
}
/*
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;
int
sk_open(sock *s)
{
- int af = BIRD_AF;
int fd = -1;
int do_bind = 0;
int bind_port = 0;
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;
if (fd >= FD_SETSIZE)
ERR2("FD_SETSIZE limit reached");
- s->af = af;
s->fd = fd;
if (sk_setup(s) < 0)
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");
}
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 &&
} 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 */
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)) }; }