BSD integration fixes
This commit is contained in:
parent
f9d729ab68
commit
8109eb765f
2 changed files with 60 additions and 62 deletions
|
@ -71,8 +71,6 @@
|
||||||
#define KRT_MAX_TABLES 1
|
#define KRT_MAX_TABLES 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IPV6 1
|
|
||||||
|
|
||||||
|
|
||||||
/* Dynamic max number of tables */
|
/* Dynamic max number of tables */
|
||||||
|
|
||||||
|
@ -137,7 +135,7 @@ extern int setfib(int fib);
|
||||||
/* table_id -> krt_proto map */
|
/* table_id -> krt_proto map */
|
||||||
|
|
||||||
#ifdef KRT_SHARED_SOCKET
|
#ifdef KRT_SHARED_SOCKET
|
||||||
static struct krt_proto *krt_table_map[KRT_MAX_TABLES];
|
static struct krt_proto *krt_table_map[KRT_MAX_TABLES][2];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -247,11 +245,9 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
|
||||||
|
|
||||||
gw = a->gw;
|
gw = a->gw;
|
||||||
|
|
||||||
#ifdef IPV6
|
|
||||||
/* Embed interface ID to link-local address */
|
/* Embed interface ID to link-local address */
|
||||||
if (ipa_is_link_local(gw))
|
if (ipa_is_link_local(gw))
|
||||||
_I0(gw) = 0xfe800000 | (i->index & 0x0000ffff);
|
_I0(gw) = 0xfe800000 | (i->index & 0x0000ffff);
|
||||||
#endif
|
|
||||||
|
|
||||||
int af = AF_UNSPEC;
|
int af = AF_UNSPEC;
|
||||||
|
|
||||||
|
@ -370,46 +366,49 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
|
||||||
if (flags & RTF_LLINFO)
|
if (flags & RTF_LLINFO)
|
||||||
SKIP("link-local\n");
|
SKIP("link-local\n");
|
||||||
|
|
||||||
|
GETADDR(&dst, RTA_DST);
|
||||||
|
GETADDR(&gate, RTA_GATEWAY);
|
||||||
|
GETADDR(&mask, RTA_NETMASK);
|
||||||
|
|
||||||
|
switch (dst.sa.sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
case AF_INET6:
|
||||||
|
/* We do not test family for RTA_NETMASK, because BSD sends us
|
||||||
|
some strange values, but interpreting them as IPv4/IPv6 works */
|
||||||
|
mask.sa.sa_family = dst.sa.sa_family;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SKIP("invalid DST");
|
||||||
|
}
|
||||||
|
|
||||||
|
idst = ipa_from_sa(&dst);
|
||||||
|
imask = ipa_from_sa(&mask);
|
||||||
|
igate = (gate.sa.sa_family == dst.sa.sa_family) ? ipa_from_sa(&gate) : IPA_NONE;
|
||||||
|
|
||||||
#ifdef KRT_SHARED_SOCKET
|
#ifdef KRT_SHARED_SOCKET
|
||||||
if (!scan)
|
if (!scan)
|
||||||
{
|
{
|
||||||
int table_id = msg->rtm.rtm_tableid;
|
int table_id = msg->rtm.rtm_tableid;
|
||||||
p = (table_id < KRT_MAX_TABLES) ? krt_table_map[table_id] : NULL;
|
p = (table_id < KRT_MAX_TABLES) ? krt_table_map[table_id][!ipa_is_ip4(idst)] : NULL;
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
SKIP("unknown table id %d\n", table_id);
|
SKIP("unknown table id %d\n", table_id);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GETADDR(&dst, RTA_DST);
|
|
||||||
GETADDR(&gate, RTA_GATEWAY);
|
|
||||||
GETADDR(&mask, RTA_NETMASK);
|
|
||||||
|
|
||||||
|
|
||||||
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); /* 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 */
|
|
||||||
|
|
||||||
|
|
||||||
int c = ipa_classify_net(idst);
|
int c = ipa_classify_net(idst);
|
||||||
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) ? (ipa_is_ip4(imask) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH) : ipa_masklen(imask);
|
int pxlen;
|
||||||
|
if (ipa_is_ip4(imask))
|
||||||
|
pxlen = (flags & RTF_HOST) ? IP4_MAX_PREFIX_LENGTH : ip4_masklen(ipa_to_ip4(imask));
|
||||||
|
else
|
||||||
|
pxlen = (flags & RTF_HOST) ? IP6_MAX_PREFIX_LENGTH : ip6_masklen(&ipa_to_ip6(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; }
|
||||||
|
|
||||||
/* XXXX */
|
|
||||||
net_fill_ipa(&ndst, idst, pxlen);
|
net_fill_ipa(&ndst, idst, pxlen);
|
||||||
|
|
||||||
if ((flags & RTF_GATEWAY) && ipa_zero(igate))
|
if ((flags & RTF_GATEWAY) && ipa_zero(igate))
|
||||||
|
@ -492,11 +491,9 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
|
||||||
a.dest = RTD_ROUTER;
|
a.dest = RTD_ROUTER;
|
||||||
a.gw = igate;
|
a.gw = igate;
|
||||||
|
|
||||||
#ifdef IPV6
|
|
||||||
/* Clean up embedded interface ID returned in link-local address */
|
/* Clean up embedded interface ID returned in link-local address */
|
||||||
if (ipa_is_link_local(a.gw))
|
if (ipa_is_link_local(a.gw))
|
||||||
_I0(a.gw) = 0xfe800000;
|
_I0(a.gw) = 0xfe800000;
|
||||||
#endif
|
|
||||||
|
|
||||||
ng = neigh_find2(&p->p, &a.gw, a.iface, 0);
|
ng = neigh_find2(&p->p, &a.gw, a.iface, 0);
|
||||||
if (!ng || (ng->scope == SCOPE_HOST))
|
if (!ng || (ng->scope == SCOPE_HOST))
|
||||||
|
@ -682,14 +679,12 @@ krt_read_addr(struct ks_msg *msg, int scan)
|
||||||
imask = ipa_from_sa(&mask);
|
imask = ipa_from_sa(&mask);
|
||||||
ibrd = ipa_from_sa(&brd);
|
ibrd = ipa_from_sa(&brd);
|
||||||
|
|
||||||
/* XXXX */
|
if ((ipv6 ? (masklen = ip6_masklen(&ipa_to_ip6(imask))) : (masklen = ip4_masklen(ipa_to_ip4(imask)))) < 0)
|
||||||
if ((masklen = ipa_masklen(imask)) < 0)
|
|
||||||
{
|
{
|
||||||
log(L_ERR "KIF: Invalid masklen %I for %s", imask, iface->name);
|
log(L_ERR "KIF: Invalid mask %I for %s", imask, iface->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IPV6
|
|
||||||
/* Clean up embedded interface ID returned in link-local address */
|
/* Clean up embedded interface ID returned in link-local address */
|
||||||
|
|
||||||
if (ipa_is_link_local(iaddr))
|
if (ipa_is_link_local(iaddr))
|
||||||
|
@ -697,7 +692,6 @@ krt_read_addr(struct ks_msg *msg, int scan)
|
||||||
|
|
||||||
if (ipa_is_link_local(ibrd))
|
if (ipa_is_link_local(ibrd))
|
||||||
_I0(ibrd) = 0xfe800000;
|
_I0(ibrd) = 0xfe800000;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
bzero(&ifa, sizeof(ifa));
|
bzero(&ifa, sizeof(ifa));
|
||||||
|
@ -720,10 +714,8 @@ krt_read_addr(struct ks_msg *msg, int scan)
|
||||||
if (masklen == ((ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH) - 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
|
if ((!ipv6) && (masklen == IP4_MAX_PREFIX_LENGTH - 2))
|
||||||
if (!ipv6 && masklen == IP4_MAX_PREFIX_LENGTH - 2)
|
|
||||||
ifa.opposite = ipa_opposite_m2(ifa.ip);
|
ifa.opposite = ipa_opposite_m2(ifa.ip);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (iface->flags & IF_BROADCAST)
|
if (iface->flags & IF_BROADCAST)
|
||||||
ifa.brd = ibrd;
|
ifa.brd = ibrd;
|
||||||
|
@ -836,12 +828,7 @@ 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;
|
||||||
/* XXX: This value should be given from the caller */
|
mib[3] = 0; // Set AF to 0 for all available families
|
||||||
#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;
|
||||||
|
@ -978,6 +965,7 @@ krt_sock_open(pool *pool, void *data, int table_id)
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 krt_table_cf[(KRT_MAX_TABLES+31) / 32][2];
|
||||||
|
|
||||||
#ifdef KRT_SHARED_SOCKET
|
#ifdef KRT_SHARED_SOCKET
|
||||||
|
|
||||||
|
@ -1009,7 +997,17 @@ krt_sock_close_shared(void)
|
||||||
int
|
int
|
||||||
krt_sys_start(struct krt_proto *p)
|
krt_sys_start(struct krt_proto *p)
|
||||||
{
|
{
|
||||||
krt_table_map[KRT_CF->sys.table_id] = p;
|
int id = KRT_CF->sys.table_id;
|
||||||
|
|
||||||
|
if (krt_table_cf[id/32][!!(p->af == AF_INET6)] & (1 << (id%32)))
|
||||||
|
{
|
||||||
|
log(L_ERR "%s: Multiple kernel syncers defined for table #%d", p->p.name, id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
krt_table_cf[id/32][!!(p->af == AF_INET6)] |= (1 << (id%32));
|
||||||
|
|
||||||
|
krt_table_map[KRT_CF->sys.table_id][!!(p->af == AF_INET6)] = p;
|
||||||
|
|
||||||
krt_sock_open_shared();
|
krt_sock_open_shared();
|
||||||
p->sys.sk = krt_sock;
|
p->sys.sk = krt_sock;
|
||||||
|
@ -1020,10 +1018,12 @@ krt_sys_start(struct krt_proto *p)
|
||||||
void
|
void
|
||||||
krt_sys_shutdown(struct krt_proto *p)
|
krt_sys_shutdown(struct krt_proto *p)
|
||||||
{
|
{
|
||||||
|
krt_table_cf[(KRT_CF->sys.table_id)/32][!!(p->af == AF_INET6)] &= ~(1 << ((KRT_CF->sys.table_id)%32));
|
||||||
|
|
||||||
krt_sock_close_shared();
|
krt_sock_close_shared();
|
||||||
p->sys.sk = NULL;
|
p->sys.sk = NULL;
|
||||||
|
|
||||||
krt_table_map[KRT_CF->sys.table_id] = NULL;
|
krt_table_map[KRT_CF->sys.table_id][!!(p->af == AF_INET6)] = NULL;
|
||||||
|
|
||||||
krt_buffer_release(&p->p);
|
krt_buffer_release(&p->p);
|
||||||
}
|
}
|
||||||
|
@ -1033,6 +1033,16 @@ krt_sys_shutdown(struct krt_proto *p)
|
||||||
int
|
int
|
||||||
krt_sys_start(struct krt_proto *p)
|
krt_sys_start(struct krt_proto *p)
|
||||||
{
|
{
|
||||||
|
int id = KRT_CF->sys.table_id;
|
||||||
|
|
||||||
|
if (krt_table_cf[id/32][!!(p->af == AF_INET6)] & (1 << (id%32)))
|
||||||
|
{
|
||||||
|
log(L_ERR "%s: Multiple kernel syncers defined for table #%d", p->p.name, id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
krt_table_cf[id/32][!!(p->af == AF_INET6)] |= (1 << (id%32));
|
||||||
|
|
||||||
p->sys.sk = krt_sock_open(p->p.pool, p, KRT_CF->sys.table_id);
|
p->sys.sk = krt_sock_open(p->p.pool, p, KRT_CF->sys.table_id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1040,6 +1050,8 @@ krt_sys_start(struct krt_proto *p)
|
||||||
void
|
void
|
||||||
krt_sys_shutdown(struct krt_proto *p)
|
krt_sys_shutdown(struct krt_proto *p)
|
||||||
{
|
{
|
||||||
|
krt_table_cf[(KRT_CF->sys.table_id)/32][!!(p->af == AF_INET6)] &= ~(1 << ((KRT_CF->sys.table_id)%32));
|
||||||
|
|
||||||
rfree(p->sys.sk);
|
rfree(p->sys.sk);
|
||||||
p->sys.sk = NULL;
|
p->sys.sk = NULL;
|
||||||
|
|
||||||
|
@ -1051,8 +1063,6 @@ krt_sys_shutdown(struct krt_proto *p)
|
||||||
|
|
||||||
/* KRT configuration callbacks */
|
/* KRT configuration callbacks */
|
||||||
|
|
||||||
static u32 krt_table_cf[(KRT_MAX_TABLES+31) / 32];
|
|
||||||
|
|
||||||
int
|
int
|
||||||
krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o)
|
krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o)
|
||||||
{
|
{
|
||||||
|
@ -1066,18 +1076,6 @@ krt_sys_preconfig(struct config *c UNUSED)
|
||||||
bzero(&krt_table_cf, sizeof(krt_table_cf));
|
bzero(&krt_table_cf, sizeof(krt_table_cf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
krt_sys_postconfig(struct krt_config *x)
|
|
||||||
{
|
|
||||||
u32 *tbl = krt_table_cf;
|
|
||||||
int id = x->sys.table_id;
|
|
||||||
|
|
||||||
if (tbl[id/32] & (1 << (id%32)))
|
|
||||||
cf_error("Multiple kernel syncers defined for table #%d", id);
|
|
||||||
|
|
||||||
tbl[id/32] |= (1 << (id%32));
|
|
||||||
}
|
|
||||||
|
|
||||||
void krt_sys_init_config(struct krt_config *c)
|
void krt_sys_init_config(struct krt_config *c)
|
||||||
{
|
{
|
||||||
c->sys.table_id = 0; /* Default table */
|
c->sys.table_id = 0; /* Default table */
|
||||||
|
@ -1106,7 +1104,7 @@ kif_sys_shutdown(struct kif_proto *p)
|
||||||
struct ifa *
|
struct ifa *
|
||||||
kif_get_primary_ip(struct iface *i)
|
kif_get_primary_ip(struct iface *i)
|
||||||
{
|
{
|
||||||
#ifndef IPV6
|
#if 0
|
||||||
static int fd = -1;
|
static int fd = -1;
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
|
|
|
@ -44,8 +44,8 @@ struct krt_state {
|
||||||
|
|
||||||
static inline void krt_sys_io_init(void) { }
|
static inline void krt_sys_io_init(void) { }
|
||||||
static inline void krt_sys_init(struct krt_proto *p UNUSED) { }
|
static inline void krt_sys_init(struct krt_proto *p UNUSED) { }
|
||||||
|
static inline void krt_sys_postconfig(struct krt_config *x UNUSED) { }
|
||||||
|
|
||||||
static inline int krt_sys_get_attr(eattr *a UNUSED, byte *buf UNUSED, int buflen UNUSED) { }
|
static inline int krt_sys_get_attr(eattr *a UNUSED, byte *buf UNUSED, int buflen UNUSED) { }
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue