summaryrefslogtreecommitdiff
path: root/sysdep/unix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdep/unix')
-rw-r--r--sysdep/unix/config.Y1
-rw-r--r--sysdep/unix/io.c42
-rw-r--r--sysdep/unix/krt.Y33
-rw-r--r--sysdep/unix/krt.c164
-rw-r--r--sysdep/unix/krt.h5
-rw-r--r--sysdep/unix/main.c2
-rw-r--r--sysdep/unix/unix.h25
7 files changed, 145 insertions, 127 deletions
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index d6ab8cab..f9a92900 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -92,6 +92,7 @@ timeformat_which:
| PROTOCOL { $$ = &new_config->tf_proto; }
| BASE { $$ = &new_config->tf_base; }
| LOG { $$ = &new_config->tf_log; }
+ ;
timeformat_spec:
timeformat_which TEXT { *$1 = (struct timeformat){$2, NULL, 0}; }
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 5955dbfe..37e26c9b 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -586,6 +586,7 @@ sockaddr_read(sockaddr *sa, int af, ip_addr *a, struct iface **ifa, uint *port)
return -1;
}
+const int fam_to_af[] = { [SK_FAM_IPV4] = AF_INET, [SK_FAM_IPV6] = AF_INET6 };
/*
* IPv6 multicast syscalls
@@ -1183,7 +1184,7 @@ sk_setup(sock *s)
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
ERR("O_NONBLOCK");
- if (!s->af)
+ if (!s->fam)
return 0;
if (ipa_nonzero(s->saddr) && !(s->flags & SKF_BIND))
@@ -1202,7 +1203,7 @@ sk_setup(sock *s)
if (s->iface)
{
#ifdef SO_BINDTODEVICE
- struct ifreq ifr;
+ struct ifreq ifr = {};
strcpy(ifr.ifr_name, s->iface->name);
if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0)
ERR("SO_BINDTODEVICE");
@@ -1284,7 +1285,7 @@ sk_tcp_connected(sock *s)
int sa_len = sizeof(sa);
if ((getsockname(s->fd, &sa.sa, &sa_len) < 0) ||
- (sockaddr_read(&sa, s->af, &s->saddr, &s->iface, &s->sport) < 0))
+ (sockaddr_read(&sa, fam_to_af[s->fam], &s->saddr, &s->iface, &s->sport) < 0))
log(L_WARN "SOCK: Cannot get local IP address for TCP>");
s->type = SK_TCP;
@@ -1309,8 +1310,8 @@ sk_passive_connected(sock *s, int type)
sock *t = sk_new(s->pool);
t->type = type;
+ t->fam = s->fam;
t->fd = fd;
- t->af = s->af;
t->ttl = s->ttl;
t->tos = s->tos;
t->rbsize = s->rbsize;
@@ -1319,10 +1320,10 @@ sk_passive_connected(sock *s, int type)
if (type == SK_TCP)
{
if ((getsockname(fd, &loc_sa.sa, &loc_sa_len) < 0) ||
- (sockaddr_read(&loc_sa, s->af, &t->saddr, &t->iface, &t->sport) < 0))
+ (sockaddr_read(&loc_sa, fam_to_af[s->fam], &t->saddr, &t->iface, &t->sport) < 0))
log(L_WARN "SOCK: Cannot get local IP address for TCP<");
- if (sockaddr_read(&rem_sa, s->af, &t->daddr, &t->iface, &t->dport) < 0)
+ if (sockaddr_read(&rem_sa, fam_to_af[s->fam], &t->daddr, &t->iface, &t->dport) < 0)
log(L_WARN "SOCK: Cannot get remote IP address for TCP<");
}
@@ -1357,7 +1358,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;
@@ -1370,28 +1370,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(fam_to_af[s->fam], 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(fam_to_af[s->fam], 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(fam_to_af[s->fam], 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->fam = SK_FAM_NONE;
fd = s->fd;
break;
@@ -1402,7 +1402,6 @@ sk_open(sock *s)
if (fd < 0)
ERR("socket");
- s->af = af;
s->fd = fd;
if (sk_setup(s) < 0)
@@ -1431,7 +1430,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, fam_to_af[s->fam], bind_addr, s->iface, bind_port);
if (bind(fd, &sa.sa, SA_LEN(sa)) < 0)
ERR2("bind");
}
@@ -1443,7 +1442,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, fam_to_af[s->fam], 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 &&
@@ -1548,9 +1547,10 @@ sk_sendmsg(sock *s)
{
struct iovec iov = {s->tbuf, s->tpos - s->tbuf};
byte cmsg_buf[CMSG_TX_SPACE];
- sockaddr dst;
+ bzero(cmsg_buf, sizeof(cmsg_buf));
+ sockaddr dst = {};
- sockaddr_fill(&dst, s->af, s->daddr, s->iface, s->dport);
+ sockaddr_fill(&dst, fam_to_af[s->fam], s->daddr, s->iface, s->dport);
struct msghdr msg = {
.msg_name = &dst.sa,
@@ -1603,7 +1603,7 @@ sk_recvmsg(sock *s)
// rv = ipv4_skip_header(pbuf, rv);
//endif
- sockaddr_read(&src, s->af, &s->faddr, NULL, &s->fport);
+ sockaddr_read(&src, fam_to_af[s->fam], &s->faddr, NULL, &s->fport);
sk_process_cmsgs(s, &msg);
if (msg.msg_flags & MSG_TRUNC)
@@ -1823,7 +1823,7 @@ sk_write(sock *s)
case SK_TCP_ACTIVE:
{
sockaddr sa;
- sockaddr_fill(&sa, s->af, s->daddr, s->iface, s->dport);
+ sockaddr_fill(&sa, fam_to_af[s->fam], s->daddr, s->iface, s->dport);
if (connect(s->fd, &sa.sa, SA_LEN(sa)) >= 0 || errno == EISCONN)
sk_tcp_connected(s);
@@ -1843,6 +1843,12 @@ sk_write(sock *s)
}
}
+int sk_is_ipv4(sock *s)
+{ return s->fam == SK_FAM_IPV4; }
+
+int sk_is_ipv6(sock *s)
+{ return s->fam == SK_FAM_IPV6; }
+
void
sk_dump_all(void)
{
diff --git a/sysdep/unix/krt.Y b/sysdep/unix/krt.Y
index e036081d..1cd73502 100644
--- a/sysdep/unix/krt.Y
+++ b/sysdep/unix/krt.Y
@@ -15,6 +15,16 @@ CF_DEFINES
#define THIS_KRT ((struct krt_config *) this_proto)
#define THIS_KIF ((struct kif_config *) this_proto)
+static void
+krt_set_merge_paths(struct channel_config *cc, uint merge, uint limit)
+{
+ if ((limit <= 0) || (limit > 255))
+ cf_error("Merge paths limit must be in range 1-255");
+
+ cc->ra_mode = merge ? RA_MERGED : RA_OPTIMAL;
+ cc->merge_limit = limit;
+}
+
CF_DECLS
CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, GRACEFUL, RESTART, KRT_SOURCE, KRT_METRIC, MERGE, PATHS)
@@ -25,15 +35,18 @@ CF_GRAMMAR
CF_ADDTO(proto, kern_proto '}')
-kern_proto_start: proto_start KERNEL { this_proto = krt_init_config($1); }
+kern_proto_start: proto_start KERNEL {
+ this_proto = krt_init_config($1);
+}
;
CF_ADDTO(kern_proto, kern_proto_start proto_name '{')
-CF_ADDTO(kern_proto, kern_proto proto_item ';')
CF_ADDTO(kern_proto, kern_proto kern_item ';')
kern_item:
- PERSIST bool { THIS_KRT->persist = $2; }
+ proto_item
+ | proto_channel { this_proto->net_type = $1->net_type; }
+ | PERSIST bool { THIS_KRT->persist = $2; }
| SCAN TIME expr {
/* Scan time of 0 means scan on startup only */
THIS_KRT->scan_time = $3;
@@ -47,8 +60,8 @@ kern_item:
}
| DEVICE ROUTES bool { THIS_KRT->devroutes = $3; }
| GRACEFUL RESTART bool { THIS_KRT->graceful_restart = $3; }
- | MERGE PATHS bool { THIS_KRT->merge_paths = $3 ? KRT_DEFAULT_ECMP_LIMIT : 0; }
- | MERGE PATHS bool LIMIT expr { THIS_KRT->merge_paths = $3 ? $5 : 0; if (($5 <= 0) || ($5 > 255)) cf_error("Merge paths limit must be in range 1-255"); }
+ | MERGE PATHS bool { krt_set_merge_paths(this_channel, $3, KRT_DEFAULT_ECMP_LIMIT); }
+ | MERGE PATHS bool LIMIT expr { krt_set_merge_paths(this_channel, $3, $5); }
;
/* Kernel interface protocol */
@@ -59,19 +72,17 @@ kif_proto_start: proto_start DEVICE { this_proto = kif_init_config($1); }
;
CF_ADDTO(kif_proto, kif_proto_start proto_name '{')
-CF_ADDTO(kif_proto, kif_proto proto_item ';')
CF_ADDTO(kif_proto, kif_proto kif_item ';')
kif_item:
- SCAN TIME expr {
+ proto_item
+ | SCAN TIME expr {
/* Scan time of 0 means scan on startup only */
THIS_KIF->scan_time = $3;
}
- | PRIMARY text_or_none prefix_or_ipa {
+ | PRIMARY opttext net_or_ipa {
struct kif_primary_item *kpi = cfg_alloc(sizeof (struct kif_primary_item));
- kpi->pattern = $2;
- kpi->prefix = $3.addr;
- kpi->pxlen = $3.len;
+ kpi->addr = $3;
add_tail(&THIS_KIF->primary, &kpi->n);
}
;
diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
index f5dee877..b0a96613 100644
--- a/sysdep/unix/krt.c
+++ b/sysdep/unix/krt.c
@@ -131,14 +131,14 @@ prefer_addr(struct ifa *a, struct ifa *b)
}
static inline struct ifa *
-find_preferred_ifa(struct iface *i, ip_addr prefix, ip_addr mask)
+find_preferred_ifa(struct iface *i, const net_addr *n)
{
struct ifa *a, *b = NULL;
WALK_LIST(a, i->addrs)
{
if (!(a->flags & IA_SECONDARY) &&
- ipa_equal(ipa_and(a->ip, mask), prefix) &&
+ (!n || ipa_in_netX(a->ip, n)) &&
(!b || prefer_addr(a, b)))
b = a;
}
@@ -156,21 +156,21 @@ kif_choose_primary(struct iface *i)
WALK_LIST(it, cf->primary)
{
if (!it->pattern || patmatch(it->pattern, i->name))
- if (a = find_preferred_ifa(i, it->prefix, ipa_mkmask(it->pxlen)))
+ if (a = find_preferred_ifa(i, &it->addr))
return a;
}
if (a = kif_get_primary_ip(i))
return a;
- return find_preferred_ifa(i, IPA_NONE, IPA_NONE);
+ return find_preferred_ifa(i, NULL);
}
static struct proto *
kif_init(struct proto_config *c)
{
- struct kif_proto *p = proto_new(c, sizeof(struct kif_proto));
+ struct kif_proto *p = proto_new(c);
kif_sys_init(p);
return &p->p;
@@ -266,9 +266,6 @@ kif_copy_config(struct proto_config *dest, struct proto_config *src)
struct kif_config *d = (struct kif_config *) dest;
struct kif_config *s = (struct kif_config *) src;
- /* Shallow copy of everything (just scan_time currently) */
- proto_copy_rest(dest, src, sizeof(struct kif_config));
-
/* Copy primary addr list */
cfg_copy_list(&d->primary, &s->primary, sizeof(struct kif_primary_item));
@@ -280,7 +277,7 @@ kif_copy_config(struct proto_config *dest, struct proto_config *src)
struct protocol proto_unix_iface = {
.name = "Device",
.template = "device%d",
- .preference = DEF_PREF_DIRECT,
+ .proto_size = sizeof(struct kif_proto),
.config_size = sizeof(struct kif_config),
.preconfig = kif_preconfig,
.init = kif_init,
@@ -298,14 +295,14 @@ static inline void
krt_trace_in(struct krt_proto *p, rte *e, char *msg)
{
if (p->p.debug & D_PACKETS)
- log(L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg);
+ log(L_TRACE "%s: %N: %s", p->p.name, e->net->n.addr, msg);
}
static inline void
krt_trace_in_rl(struct tbf *f, struct krt_proto *p, rte *e, char *msg)
{
if (p->p.debug & D_PACKETS)
- log_rl(f, L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg);
+ log_rl(f, L_TRACE "%s: %N: %s", p->p.name, e->net->n.addr, msg);
}
/*
@@ -348,10 +345,9 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
net *n = e->net;
rta *aa = rta_clone(e->attrs);
rte *ee = rte_get_temp(aa);
- net *nn = net_get(p->p.table, n->n.prefix, n->n.pxlen);
+ net *nn = net_get(p->p.main_channel->table, n->n.addr);
ee->net = nn;
ee->pflags = 0;
- ee->pref = p->p.preference;
ee->u.krt = e->u.krt;
rte_update(&p->p, nn, ee);
}
@@ -359,7 +355,7 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
static void
krt_learn_announce_delete(struct krt_proto *p, net *n)
{
- n = net_find(p->p.table, n->n.prefix, n->n.pxlen);
+ n = net_find(p->p.main_channel->table, n->n.addr);
rte_update(&p->p, n, NULL);
}
@@ -368,7 +364,7 @@ static void
krt_learn_scan(struct krt_proto *p, rte *e)
{
net *n0 = e->net;
- net *n = net_get(&p->krt_table, n0->n.prefix, n0->n.pxlen);
+ net *n = net_get(&p->krt_table, n0->n.addr);
rte *m, **mm;
e->attrs = rta_lookup(e->attrs);
@@ -412,9 +408,8 @@ krt_learn_prune(struct krt_proto *p)
FIB_ITERATE_INIT(&fit, fib);
again:
- FIB_ITERATE_START(fib, &fit, f)
+ FIB_ITERATE_START(fib, &fit, net, n)
{
- net *n = (net *) f;
rte *e, **ee, *best, **pbest, *old_best;
/*
@@ -455,8 +450,8 @@ again:
if (old_best)
krt_learn_announce_delete(p, n);
- FIB_ITERATE_PUT(&fit, f);
- fib_delete(fib, f);
+ FIB_ITERATE_PUT(&fit);
+ fib_delete(fib, n);
goto again;
}
@@ -473,7 +468,7 @@ again:
else
DBG("%I/%d: uptodate (metric=%d)\n", n->n.prefix, n->n.pxlen, best->u.krt.metric);
}
- FIB_ITERATE_END(f);
+ FIB_ITERATE_END;
p->reload = 0;
}
@@ -482,7 +477,7 @@ static void
krt_learn_async(struct krt_proto *p, rte *e, int new)
{
net *n0 = e->net;
- net *n = net_get(&p->krt_table, n0->n.prefix, n0->n.pxlen);
+ net *n = net_get(&p->krt_table, n0->n.addr);
rte *g, **gg, *best, **bestp, *old_best;
e->attrs = rta_lookup(e->attrs);
@@ -588,12 +583,11 @@ krt_dump_attrs(rte *e)
static void
krt_flush_routes(struct krt_proto *p)
{
- struct rtable *t = p->p.table;
+ struct rtable *t = p->p.main_channel->table;
KRT_TRACE(p, D_EVENTS, "Flushing kernel routes");
- FIB_WALK(&t->fib, f)
+ FIB_WALK(&t->fib, net, n)
{
- net *n = (net *) f;
rte *e = n->routes;
if (rte_is_valid(e) && (n->n.flags & KRF_INSTALLED))
{
@@ -608,12 +602,12 @@ krt_flush_routes(struct krt_proto *p)
static struct rte *
krt_export_net(struct krt_proto *p, net *net, rte **rt_free, ea_list **tmpa)
{
- struct announce_hook *ah = p->p.main_ahook;
- struct filter *filter = ah->out_filter;
+ struct channel *c = p->p.main_channel;
+ struct filter *filter = c->out_filter;
rte *rt;
- if (p->p.accept_ra_types == RA_MERGED)
- return rt_export_merged(ah, net, rt_free, tmpa, 1);
+ if (c->ra_mode == RA_MERGED)
+ return rt_export_merged(c, net, rt_free, tmpa, 1);
rt = net->routes;
*rt_free = NULL;
@@ -760,13 +754,12 @@ krt_got_route(struct krt_proto *p, rte *e)
static void
krt_prune(struct krt_proto *p)
{
- struct rtable *t = p->p.table;
+ struct rtable *t = p->p.main_channel->table;
KRT_TRACE(p, D_EVENTS, "Pruning table %s", t->name);
- FIB_WALK(&t->fib, f)
+ FIB_WALK(&t->fib, net, n)
{
- net *n = (net *) f;
- int verdict = f->flags & KRF_VERDICT_MASK;
+ int verdict = n->n.flags & KRF_VERDICT_MASK;
rte *new, *old, *rt_free = NULL;
ea_list *tmpa = NULL;
@@ -795,7 +788,7 @@ krt_prune(struct krt_proto *p)
switch (verdict)
{
case KRF_CREATE:
- if (new && (f->flags & KRF_INSTALLED))
+ if (new && (n->n.flags & KRF_INSTALLED))
{
krt_trace_in(p, new, "reinstalling");
krt_replace_rte(p, n, new, NULL, tmpa);
@@ -822,7 +815,7 @@ krt_prune(struct krt_proto *p)
if (rt_free)
rte_free(rt_free);
lp_flush(krt_filter_lp);
- f->flags &= ~KRF_VERDICT_MASK;
+ n->n.flags &= ~KRF_VERDICT_MASK;
}
FIB_WALK_END;
@@ -1033,7 +1026,7 @@ krt_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool *
}
static void
-krt_rt_notify(struct proto *P, struct rtable *table UNUSED, net *net,
+krt_rt_notify(struct proto *P, struct channel *ch UNUSED, net *net,
rte *new, rte *old, struct ea_list *eattrs)
{
struct krt_proto *p = (struct krt_proto *) P;
@@ -1067,10 +1060,10 @@ krt_if_notify(struct proto *P, uint flags, struct iface *iface UNUSED)
krt_scan_timer_kick(p);
}
-static int
-krt_reload_routes(struct proto *P)
+static void
+krt_reload_routes(struct channel *C)
{
- struct krt_proto *p = (struct krt_proto *) P;
+ struct krt_proto *p = (void *) C->proto;
/* Although we keep learned routes in krt_table, we rather schedule a scan */
@@ -1079,14 +1072,12 @@ krt_reload_routes(struct proto *P)
p->reload = 1;
krt_scan_timer_kick(p);
}
-
- return 1;
}
static void
-krt_feed_end(struct proto *P)
+krt_feed_end(struct channel *C)
{
- struct krt_proto *p = (struct krt_proto *) P;
+ struct krt_proto *p = (void *) C->proto;
p->ready = 1;
krt_scan_timer_kick(p);
@@ -1107,14 +1098,42 @@ krt_rte_same(rte *a, rte *b)
struct krt_config *krt_cf;
+static void
+krt_preconfig(struct protocol *P UNUSED, struct config *c)
+{
+ krt_cf = NULL;
+ krt_sys_preconfig(c);
+}
+
+static void
+krt_postconfig(struct proto_config *CF)
+{
+ struct krt_config *cf = (void *) CF;
+
+ if (EMPTY_LIST(CF->channels))
+ cf_error("Channel not specified");
+
+#ifdef CONFIG_ALL_TABLES_AT_ONCE
+ if (krt_cf->scan_time != cf->scan_time)
+ cf_error("All kernel syncers must use the same table scan interval");
+#endif
+
+ struct rtable_config *tab = proto_cf_main_channel(CF)->table;
+ if (tab->krt_attached)
+ cf_error("Kernel syncer (%s) already attached to table %s", tab->krt_attached->name, tab->name);
+ tab->krt_attached = CF;
+
+ krt_sys_postconfig(cf);
+}
+
static struct proto *
-krt_init(struct proto_config *C)
+krt_init(struct proto_config *CF)
{
- struct krt_proto *p = proto_new(C, sizeof(struct krt_proto));
- struct krt_config *c = (struct krt_config *) C;
+ struct krt_proto *p = proto_new(CF);
+ // struct krt_config *cf = (void *) CF;
+
+ p->p.main_channel = proto_add_channel(&p->p, proto_cf_main_channel(CF));
- p->p.accept_ra_types = c->merge_paths ? RA_MERGED : RA_OPTIMAL;
- p->p.merge_limit = c->merge_paths;
p->p.import_control = krt_import_control;
p->p.rt_notify = krt_rt_notify;
p->p.if_notify = krt_if_notify;
@@ -1133,6 +1152,13 @@ krt_start(struct proto *P)
{
struct krt_proto *p = (struct krt_proto *) P;
+ switch (p->p.net_type)
+ {
+ case NET_IP4: p->af = AF_INET; break;
+ case NET_IP6: p->af = AF_INET6; break;
+ default: ASSERT(0);
+ }
+
add_tail(&krt_proto_list, &p->krt_node);
#ifdef KRT_ALLOW_LEARN
@@ -1147,8 +1173,8 @@ krt_start(struct proto *P)
krt_scan_timer_start(p);
- if (P->gr_recovery && KRT_CF->graceful_restart)
- P->gr_wait = 1;
+ if (p->p.gr_recovery && KRT_CF->graceful_restart)
+ p->p.main_channel->gr_wait = 1;
return PS_UP;
}
@@ -1177,40 +1203,19 @@ krt_shutdown(struct proto *P)
}
static int
-krt_reconfigure(struct proto *p, struct proto_config *new)
+krt_reconfigure(struct proto *p, struct proto_config *CF)
{
- struct krt_config *o = (struct krt_config *) p->cf;
- struct krt_config *n = (struct krt_config *) new;
+ struct krt_config *o = (void *) p->cf;
+ struct krt_config *n = (void *) CF;
+
+ if (!proto_configure_channel(p, &p->main_channel, proto_cf_main_channel(CF)))
+ return 0;
if (!krt_sys_reconfigure((struct krt_proto *) p, n, o))
return 0;
/* persist, graceful restart need not be the same */
- return o->scan_time == n->scan_time && o->learn == n->learn &&
- o->devroutes == n->devroutes && o->merge_paths == n->merge_paths;
-}
-
-static void
-krt_preconfig(struct protocol *P UNUSED, struct config *c)
-{
- krt_cf = NULL;
- krt_sys_preconfig(c);
-}
-
-static void
-krt_postconfig(struct proto_config *C)
-{
- struct krt_config *c = (struct krt_config *) C;
-
-#ifdef CONFIG_ALL_TABLES_AT_ONCE
- if (krt_cf->scan_time != c->scan_time)
- cf_error("All kernel syncers must use the same table scan interval");
-#endif
-
- if (C->table->krt_attached)
- cf_error("Kernel syncer (%s) already attached to table %s", C->table->krt_attached->name, C->table->name);
- C->table->krt_attached = C;
- krt_sys_postconfig(c);
+ return o->scan_time == n->scan_time && o->learn == n->learn && o->devroutes == n->devroutes;
}
struct proto_config *
@@ -1234,9 +1239,6 @@ krt_copy_config(struct proto_config *dest, struct proto_config *src)
struct krt_config *d = (struct krt_config *) dest;
struct krt_config *s = (struct krt_config *) src;
- /* Shallow copy of everything */
- proto_copy_rest(dest, src, sizeof(struct krt_config));
-
/* Fix sysdep parts */
krt_sys_copy_config(d, s);
}
@@ -1265,6 +1267,8 @@ struct protocol proto_unix_kernel = {
.template = "kernel%d",
.attr_class = EAP_KRT,
.preference = DEF_PREF_INHERITED,
+ .channel_mask = NB_IP,
+ .proto_size = sizeof(struct krt_proto),
.config_size = sizeof(struct krt_config),
.preconfig = krt_preconfig,
.postconfig = krt_postconfig,
diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h
index d4a8717e..e968ad57 100644
--- a/sysdep/unix/krt.h
+++ b/sysdep/unix/krt.h
@@ -49,7 +49,6 @@ struct krt_config {
int learn; /* Learn routes from other sources */
int devroutes; /* Allow export of device routes */
int graceful_restart; /* Regard graceful restart recovery */
- int merge_paths; /* Exported routes are merged for ECMP */
};
struct krt_proto {
@@ -65,6 +64,7 @@ struct krt_proto {
#endif
node krt_node; /* Node in krt_proto_list */
+ byte af; /* Kernel address family (AF_*) */
byte ready; /* Initial feed has been finished */
byte initialized; /* First scan has been finished */
byte reload; /* Next scan is doing reload */
@@ -96,8 +96,7 @@ extern struct protocol proto_unix_iface;
struct kif_primary_item {
node n;
byte *pattern;
- ip_addr prefix;
- int pxlen;
+ net_addr addr;
};
struct kif_config {
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index 5d5586a0..f95bd968 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -770,7 +770,7 @@ main(int argc, char **argv)
io_init();
rt_init();
if_init();
- roa_init();
+// roa_init();
config_init();
uid_t use_uid = get_uid(use_user);
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index 4e0ff841..414b6ca4 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -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,17 +67,21 @@ 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)) }; }
-#ifdef IPV6
static inline struct in6_addr ipa_to_in6(ip_addr a)
{ return (struct in6_addr) { .s6_addr32 = { htonl(_I0(a)), htonl(_I1(a)), htonl(_I2(a)), htonl(_I3(a)) } }; }
-#else
-/* Temporary dummy */
-static inline struct in6_addr ipa_to_in6(ip_addr a)
-{ return (struct in6_addr) { .s6_addr32 = { 0, 0, 0, 0 } }; }
-#endif
void sockaddr_fill(sockaddr *sa, int af, ip_addr a, struct iface *ifa, uint port);
int sockaddr_read(sockaddr *sa, int af, ip_addr *a, struct iface **ifa, uint *port);
@@ -106,6 +102,7 @@ int sk_open_unix(struct birdsock *s, char *name);
void *tracked_fopen(struct pool *, char *name, char *mode);
void test_old_bird(char *path);
+extern const int fam_to_af[];
/* krt.c bits */