0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

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
This commit is contained in:
Jan Moskyto Matejka 2015-12-11 15:35:37 +01:00 committed by Ondrej Zajicek (work)
parent 9b136840d9
commit d7661fbe9d
21 changed files with 146 additions and 200 deletions

View File

@ -76,11 +76,10 @@ CF_DECLS
%token <t> TEXT %token <t> TEXT
%type <iface> ipa_scope %type <iface> ipa_scope
%type <i> expr bool pxlen %type <i> expr bool pxlen4 pxlen6
%type <i32> expr_us %type <i32> expr_us
%type <time> datetime %type <time> datetime
%type <a> ipa ipa_raw %type <a> ipa ipa_raw
%type <px> prefix
%type <net> net_ip4 net_ip6 net_ip net_or_ipa %type <net> net_ip4 net_ip6 net_ip net_or_ipa
%type <net_ptr> net_any %type <net_ptr> net_any
@ -175,9 +174,9 @@ ipa_scope:
/* XXXX - symbols and tests */ /* 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 ; net_ip: net_ip4 | net_ip6 ;
@ -191,22 +190,22 @@ net_or_ipa:
; ;
prefix: pxlen4:
ipa pxlen { '/' expr {
if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix"); if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
$$.addr = $1; $$.len = $2; $$ = $2;
}
| ':' IP4 {
$$ = ip4_masklen($2);
if ($$ < 0) cf_error("Invalid netmask %I", $2);
} }
; ;
pxlen: pxlen6:
'/' expr { '/' 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; $$ = $2;
} }
| ':' ipa {
$$ = ipa_masklen($2);
if ($$ < 0) cf_error("Invalid netmask %I", $2);
}
; ;
datetime: datetime:

View File

@ -574,7 +574,7 @@ switch_items:
fprefix_s: fprefix_s:
ipa_raw '/' NUM %prec '/' { 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; $$.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_PLUS; }
| fprefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; } | fprefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
| fprefix_s '{' NUM ',' NUM '}' { | 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); $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8);
} }
; ;

View File

@ -218,7 +218,7 @@ fprefix_get_bounds(struct f_prefix *px, int *l, int *h)
*l = 0; *l = 0;
else if (px->len & LEN_PLUS) 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) else if (px->len & LEN_RANGE)
{ {

View File

@ -43,12 +43,8 @@
#define UDP_HEADER_LENGTH 8 #define UDP_HEADER_LENGTH 8
#ifdef IPV6 #ifdef IPV6
#define MAX_PREFIX_LENGTH 128
#define BITS_PER_IP_ADDRESS 128
#define STD_ADDRESS_P_LENGTH 39 #define STD_ADDRESS_P_LENGTH 39
#else #else
#define MAX_PREFIX_LENGTH 32
#define BITS_PER_IP_ADDRESS 32
#define STD_ADDRESS_P_LENGTH 15 #define STD_ADDRESS_P_LENGTH 15
#endif #endif

View File

@ -3,6 +3,7 @@
#include "lib/ip.h" #include "lib/ip.h"
#include "lib/net.h" #include "lib/net.h"
const u16 net_addr_length[] = { const u16 net_addr_length[] = {
[NET_IP4] = sizeof(net_addr_ip4), [NET_IP4] = sizeof(net_addr_ip4),
[NET_IP6] = sizeof(net_addr_ip6), [NET_IP6] = sizeof(net_addr_ip6),
@ -10,6 +11,14 @@ const u16 net_addr_length[] = {
[NET_VPN6] = sizeof(net_addr_vpn6) [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 int
net_format(const net_addr *N, char *buf, int buflen) 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; return 0;
} }
ip_addr ip_addr
net_pxmask(const net_addr *a) net_pxmask(const net_addr *a)
{ {

View File

@ -19,7 +19,6 @@
#define NET_VPN6 4 #define NET_VPN6 4
#define NET_MAX 5 #define NET_MAX 5
typedef struct net_addr { typedef struct net_addr {
u8 type; u8 type;
u8 pxlen; u8 pxlen;
@ -69,7 +68,7 @@ typedef union net_addr_union {
extern const u16 net_addr_length[]; extern const u16 net_addr_length[];
extern const u8 net_max_prefix_length[];
#define NET_ADDR_IP4(prefix,pxlen) \ #define NET_ADDR_IP4(prefix,pxlen) \
((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix }) ((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix })

View File

@ -75,10 +75,8 @@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
%type <r> rtable %type <r> rtable
%type <s> optsym %type <s> optsym
%type <ra> r_args %type <ra> r_args
%type <ro> roa_args
%type <rot> roa_table_arg
%type <sd> sym_args %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 <ps> proto_patt proto_patt2
%type <g> limit_spec %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 */ /* Definition of protocols */
CF_ADDTO(conf, proto) CF_ADDTO(conf, proto)
@ -469,20 +449,17 @@ CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filte
r_args: r_args:
/* empty */ { /* empty */ {
$$ = cfg_allocz(sizeof(struct rt_show_data)); $$ = cfg_allocz(sizeof(struct rt_show_data));
$$->pxlen = 256;
$$->filter = FILTER_ACCEPT; $$->filter = FILTER_ACCEPT;
} }
| r_args prefix { | r_args net_any {
$$ = $1; $$ = $1;
if ($$->pxlen != 256) cf_error("Only one prefix expected"); if ($$->prefix) cf_error("Only one prefix expected");
$$->prefix = $2.addr; $$->prefix = $2;
$$->pxlen = $2.len;
} }
| r_args FOR net_or_ipa { | r_args FOR net_or_ipa {
$$ = $1; $$ = $1;
if ($$->pxlen != 256) cf_error("Only one prefix expected"); if ($$->prefix) cf_error("Only one prefix expected");
$$->prefix = IPA_NONE; /* XXXX */ $$->prefix = &($3.n);
$$->pxlen = 0; /* XXXX */
$$->show_for = 1; $$->show_for = 1;
} }
| r_args TABLE SYM { | 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_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); } ; { cmd_show_symbols($3); } ;
sym_args: sym_args:
@ -596,46 +536,10 @@ sym_args:
| sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; } | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
| sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; } | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
| sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; } | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
| sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
| sym_args SYM { $$ = $1; $$->sym = $2; } | 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_HELP(DUMP, ..., [[Dump debugging information]])
CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]]) CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
{ rdump(&root_pool); cli_msg(0, ""); } ; { rdump(&root_pool); cli_msg(0, ""); } ;

View File

@ -83,7 +83,7 @@ if_connected(ip_addr *a, struct iface *i, struct ifa **ap)
{ {
/* Do not allow IPv4 network and broadcast addresses */ /* Do not allow IPv4 network and broadcast addresses */
if (ipa_is_ip4(*a) && 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, net_prefix(&b->prefix)) || /* Network address */
ipa_equal(*a, b->brd))) /* Broadcast */ ipa_equal(*a, b->brd))) /* Broadcast */
{ {

View File

@ -304,8 +304,7 @@ rt_mark_for_prune(rtable *tab)
} }
struct rt_show_data { struct rt_show_data {
ip_addr prefix; net_addr *prefix;
unsigned pxlen;
rtable *table; rtable *table;
struct filter *filter; struct filter *filter;
int verbose; int verbose;

View File

@ -2293,9 +2293,13 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
he->igp_metric = rt_get_igp_metric(e); he->igp_metric = rt_get_igp_metric(e);
} }
/* XXXX */
done: done:
/* Add a prefix range to the trie */ /* 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); rta_free(old_src);
return old_src != he->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)) if (d->filtered && (d->export_mode || d->primary_only))
cli_msg(0, ""); cli_msg(0, "");
if (d->pxlen == 256) if (!d->prefix)
{ {
FIB_ITERATE_INIT(&d->fit, &d->table->fib); FIB_ITERATE_INIT(&d->fit, &d->table->fib);
this_cli->cont = rt_show_cont; this_cli->cont = rt_show_cont;

View File

@ -202,9 +202,7 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop)
sk->priority = sk_priority_control; sk->priority = sk_priority_control;
sk->flags = SKF_THREAD | SKF_LADDR_RX | (!multihop ? SKF_TTL_RX : 0); sk->flags = SKF_THREAD | SKF_LADDR_RX | (!multihop ? SKF_TTL_RX : 0);
#ifdef IPV6 sk->af = AF_INET6;
sk->flags |= SKF_V6ONLY;
#endif
if (sk_open(sk) < 0) if (sk_open(sk) < 0)
goto err; 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->ttl = ifa ? 255 : -1;
sk->flags = SKF_THREAD | SKF_BIND | SKF_HIGH_PORT; sk->flags = SKF_THREAD | SKF_BIND | SKF_HIGH_PORT;
#ifdef IPV6 sk->af = AF_INET6;
sk->flags |= SKF_V6ONLY;
#endif
if (sk_open(sk) < 0) if (sk_open(sk) < 0)
goto err; goto err;

View File

@ -111,6 +111,7 @@ ospf_sk_open(struct ospf_iface *ifa)
sk->dport = OSPF_PROTO; sk->dport = OSPF_PROTO;
sk->saddr = ifa->addr->ip; sk->saddr = ifa->addr->ip;
sk->iface = ifa->iface; sk->iface = ifa->iface;
sk->af = ospf_is_v2(p) ? AF_INET : AF_INET6;
sk->tos = ifa->cf->tx_tos; sk->tos = ifa->cf->tx_tos;
sk->priority = ifa->cf->tx_priority; 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); sock *sk = sk_new(p->p.pool);
sk->type = SK_IP; sk->type = SK_IP;
sk->dport = OSPF_PROTO; sk->dport = OSPF_PROTO;
sk->af = ospf_is_v2(p) ? AF_INET : AF_INET6;
/* FIXME: configurable tos/priority ? */ /* FIXME: configurable tos/priority ? */
sk->tos = IP_PREC_INTERNET_CONTROL; sk->tos = IP_PREC_INTERNET_CONTROL;

View File

@ -493,7 +493,7 @@ lsa_validate_ext3(struct ospf_lsa_header *lsa, struct ospf_lsa_ext3 *body)
return 0; return 0;
int len = IPV6_PREFIX_SPACE(pxl); int len = IPV6_PREFIX_SPACE(pxl);
if (body->metric & LSA_EXT3_FBIT) // forwardinf address if (body->metric & LSA_EXT3_FBIT) // forwarding address
len += 16; len += 16;
if (body->metric & LSA_EXT3_TBIT) // route tag if (body->metric & LSA_EXT3_TBIT) // route tag
len += 4; len += 4;

View 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_SPACE(x) ((((x) + 63) / 32) * 4)
#define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32) #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_* */ 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 * static inline u32 *
ospf_get_ipv6_prefix(u32 *buf, net_addr *N, u8 *pxopts, u16 *rest) ospf_get_ipv6_prefix(u32 *buf, net_addr *N, u8 *pxopts, u16 *rest)
{ {

View File

@ -412,7 +412,7 @@ add_network(struct ospf_area *oa, net_addr *net, int metric, struct top_hash_ent
.nhs = en->nhs .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)", 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); 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); lsa_parse_sum_net(en, ospf_is_v2(p), &net, &pxopts, &metric);
if (pxopts & OPT_PX_NU) if (!ospf_valid_prefix(&net))
continue;
if (net.pxlen > MAX_PREFIX_LENGTH)
{ {
log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)", 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); p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
continue; continue;
} }
if (pxopts & OPT_PX_NU)
continue;
options = 0; options = 0;
type = ORT_NET; 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); lsa_parse_sum_net(en, ospf_is_v2(p), &net, &pxopts, &metric);
if (pxopts & OPT_PX_NU) if (!ospf_valid_prefix(&net))
continue;
if (net.pxlen > MAX_PREFIX_LENGTH)
{ {
log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)", 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); p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
continue; continue;
} }
if (pxopts & OPT_PX_NU)
continue;
re = fib_find(&p->rtf, &net); re = fib_find(&p->rtf, &net);
} }
else // en->lsa_type == LSA_T_SUM_RT 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); lsa_parse_ext(en, ospf_is_v2(p), &rt);
if (rt.metric == LSINFINITY) if (!ospf_valid_prefix(&rt.net))
continue;
if (rt.pxopts & OPT_PX_NU)
continue;
if (rt.net.pxlen > MAX_PREFIX_LENGTH)
{ {
log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)", 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); p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
continue; continue;
} }
if (rt.metric == LSINFINITY)
continue;
if (rt.pxopts & OPT_PX_NU)
continue;
/* 16.4. (3) */ /* 16.4. (3) */
/* If there are more areas, we already precomputed preferred ASBR /* If there are more areas, we already precomputed preferred ASBR

View File

@ -412,6 +412,7 @@ radv_sk_open(struct radv_iface *ifa)
sk->type = SK_IP; sk->type = SK_IP;
sk->dport = ICMPV6_PROTO; sk->dport = ICMPV6_PROTO;
sk->saddr = ifa->addr->ip; sk->saddr = ifa->addr->ip;
sk->af = AF_INET6;
sk->ttl = 255; /* Mandatory for Neighbor Discovery packets */ sk->ttl = 255; /* Mandatory for Neighbor Discovery packets */
sk->rx_hook = radv_rx_hook; sk->rx_hook = radv_rx_hook;

View File

@ -715,6 +715,7 @@ rip_open_socket(struct rip_iface *ifa)
sock *sk = sk_new(p->p.pool); sock *sk = sk_new(p->p.pool);
sk->type = SK_UDP; sk->type = SK_UDP;
sk->af = rip_is_v2(p) ? AF_INET : AF_INET6;
sk->sport = ifa->cf->port; sk->sport = ifa->cf->port;
sk->dport = ifa->cf->port; sk->dport = ifa->cf->port;
sk->iface = ifa->iface; sk->iface = ifa->iface;

View 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_addrs = RTA_DST;
msg.rtm.rtm_flags = RTF_UP | RTF_PROTO1; 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; msg.rtm.rtm_flags |= RTF_HOST;
else else
msg.rtm.rtm_addrs |= RTA_NETMASK; msg.rtm.rtm_addrs |= RTA_NETMASK;
@ -296,7 +297,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
return -1; 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; msg.rtm.rtm_addrs |= RTA_GATEWAY;
} }
break; break;
@ -383,12 +384,17 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
GETADDR(&gate, RTA_GATEWAY); GETADDR(&gate, RTA_GATEWAY);
GETADDR(&mask, RTA_NETMASK); GETADDR(&mask, RTA_NETMASK);
if (dst.sa.sa_family != BIRD_AF)
switch (dst.sa.sa_family) {
case AF_INET:
case AF_INET6: break;
default:
SKIP("invalid DST"); SKIP("invalid DST");
}
idst = ipa_from_sa(&dst); idst = ipa_from_sa(&dst);
imask = ipa_from_sa(&mask); imask = ipa_from_sa(&mask); /* XXXX broken, see below */
igate = (gate.sa.sa_family == BIRD_AF) ? ipa_from_sa(&gate) : IPA_NONE; 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 /* We do not test family for RTA_NETMASK, because BSD sends us
some strange values, but interpreting them as IPv4/IPv6 works */ 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)) if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
SKIP("strange class/scope\n"); 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) if (pxlen < 0)
{ log(L_ERR "%s (%I) - netmask %I", errmsg, idst, imask); return; } { 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 (&null, RTA_AUTHOR);
GETADDR (&brd, RTA_BRD); GETADDR (&brd, RTA_BRD);
/* Some other family address */ /* Is addr family IP4 or IP6? */
if (addr.sa.sa_family != BIRD_AF) int ipv6;
return; switch (addr.sa.sa_family) {
case AF_INET: ipv6 = 0; break;
case AF_INET6: ipv6 = 1; break;
default: return;
}
iaddr = ipa_from_sa(&addr); iaddr = ipa_from_sa(&addr);
imask = ipa_from_sa(&mask); imask = ipa_from_sa(&mask);
@ -701,16 +711,16 @@ krt_read_addr(struct ks_msg *msg, int scan)
} }
ifa.scope = scope & IADDR_SCOPE_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_fill_ipa(&ifa.prefix, ifa.ip, masklen);
net_normalize(&ifa.prefix); 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); ifa.opposite = ipa_opposite_m1(ifa.ip);
#ifndef IPV6 #ifndef IPV6
if (masklen == (BITS_PER_IP_ADDRESS - 2)) if (!ipv6 && masklen == IP4_MAX_PREFIX_LENGTH - 2)
ifa.opposite = ipa_opposite_m2(ifa.ip); ifa.opposite = ipa_opposite_m2(ifa.ip);
#endif #endif
@ -722,13 +732,13 @@ krt_read_addr(struct ks_msg *msg, int scan)
} }
else if (!(iface->flags & IF_MULTIACCESS) && ipa_nonzero(ibrd)) 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.opposite = ibrd;
ifa.flags |= IA_PEER; ifa.flags |= IA_PEER;
} }
else 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; ifa.flags |= IA_HOST;
} }
@ -825,7 +835,12 @@ krt_sysctl_scan(struct proto *p, int cmd, int table_id)
mib[0] = CTL_NET; mib[0] = CTL_NET;
mib[1] = PF_ROUTE; mib[1] = PF_ROUTE;
mib[2] = 0; 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[4] = cmd;
mib[5] = 0; mib[5] = 0;
mcnt = 6; mcnt = 6;

View File

@ -646,12 +646,12 @@ nl_parse_addr4(struct ifaddrmsg *i, int scan, int new)
ifa.ip = rta_get_ipa(a[IFA_LOCAL]); 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); log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
new = 0; 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]); 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, 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_fill_ip4(&ifa.prefix, ipa_to_ip4(ifa.ip), i->ifa_prefixlen);
net_normalize(&ifa.prefix); 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); 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); ifa.opposite = ipa_opposite_m2(ifa.ip);
if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST]) 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]); 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); log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
new = 0; 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]); 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, 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_fill_ip6(&ifa.prefix, ipa_to_ip6(ifa.ip), i->ifa_prefixlen);
net_normalize(&ifa.prefix); 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); ifa.opposite = ipa_opposite_m1(ifa.ip);
} }
@ -831,14 +831,21 @@ kif_do_scan(struct kif_proto *p UNUSED)
nl_parse_link(h, 1); nl_parse_link(h, 1);
else else
log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type); log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
#ifndef IPV6
nl_request_dump(BIRD_AF, RTM_GETADDR); nl_request_dump(AF_INET, RTM_GETADDR);
while (h = nl_get_scan()) while (h = nl_get_scan())
if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
nl_parse_addr(h, 1); nl_parse_addr(h, 1);
else else
log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type); 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(); 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; struct nlmsghdr *h;
nl_request_dump(BIRD_AF, RTM_GETROUTE); #ifndef IPV6
nl_request_dump(AF_INET, RTM_GETROUTE);
while (h = nl_get_scan()) while (h = nl_get_scan())
if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE) if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
nl_parse_route(h, 1); nl_parse_route(h, 1);
else else
log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type); 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
} }
/* /*

View File

@ -1311,8 +1311,8 @@ sk_passive_connected(sock *s, int type)
sock *t = sk_new(s->pool); sock *t = sk_new(s->pool);
t->type = type; t->type = type;
t->fd = fd;
t->af = s->af; t->af = s->af;
t->fd = fd;
t->ttl = s->ttl; t->ttl = s->ttl;
t->tos = s->tos; t->tos = s->tos;
t->rbsize = s->rbsize; t->rbsize = s->rbsize;
@ -1371,7 +1371,6 @@ sk_passive_connected(sock *s, int type)
int int
sk_open(sock *s) sk_open(sock *s)
{ {
int af = BIRD_AF;
int fd = -1; int fd = -1;
int do_bind = 0; int do_bind = 0;
int bind_port = 0; int bind_port = 0;
@ -1384,28 +1383,28 @@ sk_open(sock *s)
s->ttx = ""; /* Force s->ttx != s->tpos */ s->ttx = ""; /* Force s->ttx != s->tpos */
/* Fall thru */ /* Fall thru */
case SK_TCP_PASSIVE: case SK_TCP_PASSIVE:
fd = socket(af, SOCK_STREAM, IPPROTO_TCP); fd = socket(s->af, SOCK_STREAM, IPPROTO_TCP);
bind_port = s->sport; bind_port = s->sport;
bind_addr = s->saddr; bind_addr = s->saddr;
do_bind = bind_port || ipa_nonzero(bind_addr); do_bind = bind_port || ipa_nonzero(bind_addr);
break; break;
case SK_UDP: case SK_UDP:
fd = socket(af, SOCK_DGRAM, IPPROTO_UDP); fd = socket(s->af, SOCK_DGRAM, IPPROTO_UDP);
bind_port = s->sport; bind_port = s->sport;
bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE; bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE;
do_bind = 1; do_bind = 1;
break; break;
case SK_IP: case SK_IP:
fd = socket(af, SOCK_RAW, s->dport); fd = socket(s->af, SOCK_RAW, s->dport);
bind_port = 0; bind_port = 0;
bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE; bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE;
do_bind = ipa_nonzero(bind_addr); do_bind = ipa_nonzero(bind_addr);
break; break;
case SK_MAGIC: case SK_MAGIC:
af = 0; s->af = 0;
fd = s->fd; fd = s->fd;
break; break;
@ -1419,7 +1418,6 @@ sk_open(sock *s)
if (fd >= FD_SETSIZE) if (fd >= FD_SETSIZE)
ERR2("FD_SETSIZE limit reached"); ERR2("FD_SETSIZE limit reached");
s->af = af;
s->fd = fd; s->fd = fd;
if (sk_setup(s) < 0) if (sk_setup(s) < 0)
@ -1448,7 +1446,7 @@ sk_open(sock *s)
if (sk_set_high_port(s) < 0) if (sk_set_high_port(s) < 0)
log(L_WARN "Socket error: %s%#m", s->err); 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) if (bind(fd, &sa.sa, SA_LEN(sa)) < 0)
ERR2("bind"); ERR2("bind");
} }
@ -1460,7 +1458,7 @@ sk_open(sock *s)
switch (s->type) switch (s->type)
{ {
case SK_TCP_ACTIVE: 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) if (connect(fd, &sa.sa, SA_LEN(sa)) >= 0)
sk_tcp_connected(s); sk_tcp_connected(s);
else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS &&

View File

@ -47,14 +47,6 @@ typedef struct sockaddr_bird {
} sockaddr; } 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 */ /* This is sloppy hack, it should be detected by configure script */
/* Linux systems have it defined so this is definition for BSD systems */ /* 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) static inline ip_addr ipa_from_sa6(sockaddr *sa)
{ return ipa_from_in6(((struct sockaddr_in6 *) sa)->sin6_addr); } { 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) static inline struct in_addr ipa_to_in4(ip_addr a)
{ return (struct in_addr) { htonl(ipa_to_u32(a)) }; } { return (struct in_addr) { htonl(ipa_to_u32(a)) }; }