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:
parent
9b136840d9
commit
d7661fbe9d
21 changed files with 146 additions and 200 deletions
|
@ -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)
|
||||
{
|
||||
|
|
4
lib/ip.h
4
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
|
||||
|
||||
|
|
10
lib/net.c
10
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)
|
||||
{
|
||||
|
|
|
@ -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 })
|
||||
|
|
110
nest/config.Y
110
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, ""); } ;
|
||||
|
|
|
@ -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)
|
||||
|
||||
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 : 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 &&
|
||||
|
|
|
@ -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)) }; }
|
||||
|
||||
|
|
Loading…
Reference in a new issue