From 9810d055628877232f811d684567e203381e10dc Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 28 May 2013 10:44:44 +0200 Subject: Fixes problems with routing table scans on some platforms. Negative bit shifts are definitely undefined oprations. --- sysdep/linux/netlink.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sysdep/linux/netlink.c') diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index d1b203ef..1d24ae0f 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -843,9 +843,11 @@ nl_parse_route(struct nlmsghdr *h, int scan) memcpy(&ra.gw, RTA_DATA(a[RTA_GATEWAY]), sizeof(ra.gw)); ipa_ntoh(ra.gw); +#ifdef IPV6 /* Silently skip strange 6to4 routes */ if (ipa_in_net(ra.gw, IPA_NONE, 96)) return; +#endif ng = neigh_find2(&p->p, &ra.gw, ra.iface, (i->rtm_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0); -- cgit v1.2.3 From c6964c305b425b98aaf0492806a28b578d799d83 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 29 Jun 2013 22:55:41 +0200 Subject: Makes krt.c much more readable. --- sysdep/bsd/krt-sock.c | 9 ++-- sysdep/bsd/krt-sys.h | 4 +- sysdep/linux/krt-sys.h | 4 +- sysdep/linux/netlink.Y | 6 +-- sysdep/linux/netlink.c | 12 ++--- sysdep/unix/krt.c | 144 ++++++++++++++++++++++++++----------------------- sysdep/unix/krt.h | 16 +++--- 7 files changed, 101 insertions(+), 94 deletions(-) (limited to 'sysdep/linux/netlink.c') diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index e970d6bd..cad0cfc9 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -681,15 +681,14 @@ static size_t kif_buflen = 4096; void krt_do_scan(struct krt_proto *p) { - krt_sysctl_scan((struct proto *)p, p->krt_pool, &krt_buffer, &krt_buflen, NET_RT_DUMP); + krt_sysctl_scan(&p->p, p->p.pool, &krt_buffer, &krt_buflen, NET_RT_DUMP); } void kif_do_scan(struct kif_proto *p) { - struct proto *P = (struct proto *)p; if_start_update(); - krt_sysctl_scan(P, P->pool, &kif_buffer, &kif_buflen, NET_RT_IFLIST); + krt_sysctl_scan(&p->p, p->p.pool, &kif_buffer, &kif_buflen, NET_RT_IFLIST); if_end_update(); } @@ -708,7 +707,7 @@ krt_sock_hook(sock *sk, int size UNUSED) } void -krt_sys_start(struct krt_proto *x, int first UNUSED) +krt_sys_start(struct krt_proto *x) { sock *sk_rt; static int ks_open_tried = 0; @@ -733,7 +732,7 @@ krt_sys_start(struct krt_proto *x, int first UNUSED) } void -krt_sys_shutdown(struct krt_proto *x UNUSED, int last UNUSED) +krt_sys_shutdown(struct krt_proto *x UNUSED) { if (!krt_buffer) return; diff --git a/sysdep/bsd/krt-sys.h b/sysdep/bsd/krt-sys.h index 88915dde..5e4529c5 100644 --- a/sysdep/bsd/krt-sys.h +++ b/sysdep/bsd/krt-sys.h @@ -15,7 +15,7 @@ struct kif_params { }; -struct kif_status { +struct kif_state { }; @@ -33,7 +33,7 @@ static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_c struct krt_params { }; -struct krt_status { +struct krt_state { }; diff --git a/sysdep/linux/krt-sys.h b/sysdep/linux/krt-sys.h index cdee7fe3..7b3043a7 100644 --- a/sysdep/linux/krt-sys.h +++ b/sysdep/linux/krt-sys.h @@ -15,7 +15,7 @@ struct kif_params { }; -struct kif_status { +struct kif_state { }; @@ -36,7 +36,7 @@ struct krt_params { int table_id; /* Kernel table ID we sync with */ }; -struct krt_status { +struct krt_state { }; diff --git a/sysdep/linux/netlink.Y b/sysdep/linux/netlink.Y index 51689ff9..b0e35151 100644 --- a/sysdep/linux/netlink.Y +++ b/sysdep/linux/netlink.Y @@ -10,13 +10,13 @@ CF_HDR CF_DECLS -CF_KEYWORDS(ASYNC, KERNEL, TABLE, KRT_PREFSRC, KRT_REALM) +CF_KEYWORDS(KERNEL, TABLE, KRT_PREFSRC, KRT_REALM) CF_GRAMMAR -CF_ADDTO(kern_proto, kern_proto nl_item ';') +CF_ADDTO(kern_proto, kern_proto kern_sys_item ';') -nl_item: +kern_sys_item: KERNEL TABLE expr { if ($3 <= 0 || $3 >= NL_NUM_TABLES) cf_error("Kernel routing table number out of range"); diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index 1d24ae0f..f61e31a5 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -1086,18 +1086,16 @@ nl_open_async(void) static u8 nl_cf_table[(NL_NUM_TABLES+7) / 8]; void -krt_sys_start(struct krt_proto *p, int first) +krt_sys_start(struct krt_proto *p) { nl_table_map[KRT_CF->sys.table_id] = p; - if (first) - { - nl_open(); - nl_open_async(); - } + + nl_open(); + nl_open_async(); } void -krt_sys_shutdown(struct krt_proto *p UNUSED, int last UNUSED) +krt_sys_shutdown(struct krt_proto *p UNUSED) { } diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 3761ace6..54297921 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -69,12 +69,14 @@ pool *krt_pool; static linpool *krt_filter_lp; +static list krt_proto_list; void krt_io_init(void) { krt_pool = rp_new(&root_pool, "Kernel Syncer"); krt_filter_lp = lp_new(krt_pool, 4080); + init_list(&krt_proto_list); } /* @@ -565,12 +567,6 @@ krt_dump_attrs(rte *e) * Routes */ -#ifdef CONFIG_ALL_TABLES_AT_ONCE -static timer *krt_scan_timer; -static int krt_instance_count; -static list krt_instance_list; -#endif - static void krt_flush_routes(struct krt_proto *p) { @@ -812,34 +808,88 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new) * Periodic scanning */ + +#ifdef CONFIG_ALL_TABLES_AT_ONCE + +static timer *krt_scan_timer; +static int krt_scan_count; + static void krt_scan(timer *t UNUSED) { struct krt_proto *p; kif_force_scan(); -#ifdef CONFIG_ALL_TABLES_AT_ONCE + + /* We need some node to decide whether to print the debug messages or not */ + p = SKIP_BACK(struct krt_proto, krt_node, HEAD(krt_proto_list)); + KRT_TRACE(p, D_EVENTS, "Scanning routing table"); + + krt_do_scan(NULL); + + void *q; + WALK_LIST(q, krt_proto_list) { - void *q; - /* We need some node to decide whether to print the debug messages or not */ - p = SKIP_BACK(struct krt_proto, instance_node, HEAD(krt_instance_list)); - if (p->instance_node.next) - KRT_TRACE(p, D_EVENTS, "Scanning routing table"); - krt_do_scan(NULL); - WALK_LIST(q, krt_instance_list) - { - p = SKIP_BACK(struct krt_proto, instance_node, q); - krt_prune(p); - } + p = SKIP_BACK(struct krt_proto, krt_node, q); + krt_prune(p); + } +} + +static void +krt_scan_timer_start(struct krt_proto *p) +{ + if (!krt_scan_count) + { + krt_scan_timer = tm_new_set(krt_pool, krt_scan, NULL, 0, KRT_CF->scan_time); + tm_start(krt_scan_timer, 0); + } + + krt_scan_count++; +} + +static void +krt_scan_timer_stop(struct krt_proto *p) +{ + krt_scan_count--; + + if (!krt_scan_count) + { + rfree(krt_scan_timer); + krt_scan_timer = NULL; } +} + #else - p = t->data; + +static void +krt_scan(timer *t) +{ + struct krt_proto *p = t->data; + + kif_force_scan(); + KRT_TRACE(p, D_EVENTS, "Scanning routing table"); krt_do_scan(p); krt_prune(p); -#endif } +static void +krt_scan_timer_start(struct krt_proto *p) +{ + p->scan_timer = tm_new_set(p->p.pool, krt_scan, p, 0, KRT_CF->scan_time); + tm_start(p->scan_timer, 0); +} + +static void +krt_scan_timer_stop(struct krt_proto *p) +{ + tm_stop(p->scan_timer); +} + +#endif + + + /* * Updates @@ -942,52 +992,20 @@ krt_init(struct proto_config *c) return &p->p; } -static timer * -krt_start_timer(struct krt_proto *p) -{ - timer *t; - - t = tm_new(p->krt_pool); - t->hook = krt_scan; - t->data = p; - t->recurrent = KRT_CF->scan_time; - tm_start(t, 0); - return t; -} - static int krt_start(struct proto *P) { struct krt_proto *p = (struct krt_proto *) P; - int first = 1; -#ifdef CONFIG_ALL_TABLES_AT_ONCE - if (!krt_instance_count++) - init_list(&krt_instance_list); - else - first = 0; - p->krt_pool = krt_pool; - add_tail(&krt_instance_list, &p->instance_node); -#else - p->krt_pool = P->pool; -#endif + add_tail(&krt_proto_list, &p->krt_node); #ifdef KRT_ALLOW_LEARN krt_learn_init(p); #endif - krt_sys_start(p, first); + krt_sys_start(p); - /* Start periodic routing table scanning */ -#ifdef CONFIG_ALL_TABLES_AT_ONCE - if (first) - krt_scan_timer = krt_start_timer(p); - else - tm_start(krt_scan_timer, 0); - p->scan_timer = krt_scan_timer; -#else - p->scan_timer = krt_start_timer(p); -#endif + krt_scan_timer_start(p); return PS_UP; } @@ -996,26 +1014,16 @@ static int krt_shutdown(struct proto *P) { struct krt_proto *p = (struct krt_proto *) P; - int last = 1; -#ifdef CONFIG_ALL_TABLES_AT_ONCE - rem_node(&p->instance_node); - if (--krt_instance_count) - last = 0; - else -#endif - tm_stop(p->scan_timer); + krt_scan_timer_stop(p); /* FIXME we should flush routes even when persist during reconfiguration */ if (p->initialized && !KRT_CF->persist) krt_flush_routes(p); - krt_sys_shutdown(p, last); + krt_sys_shutdown(p); -#ifdef CONFIG_ALL_TABLES_AT_ONCE - if (last) - rfree(krt_scan_timer); -#endif + rem_node(&p->krt_node); return PS_DOWN; } diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index d6fbf721..446914d2 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -52,15 +52,17 @@ struct krt_config { struct krt_proto { struct proto p; - struct krt_status sys; /* Sysdep state */ + struct krt_state sys; /* Sysdep state */ + #ifdef KRT_ALLOW_LEARN struct rtable krt_table; /* Internal table of inherited routes */ #endif - pool *krt_pool; /* Pool used for common krt data */ + +#ifndef CONFIG_ALL_TABLES_AT_ONCE timer *scan_timer; -#ifdef CONFIG_ALL_TABLES_AT_ONCE - node instance_node; /* Node in krt instance list */ #endif + + node krt_node; /* Node in krt_proto_list */ int initialized; /* First scan has already been finished */ }; @@ -103,7 +105,7 @@ struct kif_config { struct kif_proto { struct proto p; - struct kif_status sys; /* Sysdep state */ + struct kif_state sys; /* Sysdep state */ }; #define KIF_CF ((struct kif_config *)p->p.cf) @@ -114,8 +116,8 @@ struct proto_config * krt_init_config(int class); /* krt sysdep */ void krt_sys_init(struct krt_proto *); -void krt_sys_start(struct krt_proto *, int); -void krt_sys_shutdown(struct krt_proto *, int); +void krt_sys_start(struct krt_proto *); +void krt_sys_shutdown(struct krt_proto *); int krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o); void krt_sys_preconfig(struct config *); -- cgit v1.2.3 From f83ce94d5e410d5e5b921121867321c19451896b Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 26 Sep 2013 17:33:00 +0200 Subject: Fixes missing unregister of kernel table handling code. And some minor fixes. Thanks to Sergey Popovich for the patch. --- nest/neighbor.c | 2 +- sysdep/linux/netlink.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sysdep/linux/netlink.c') diff --git a/nest/neighbor.c b/nest/neighbor.c index 9dce8119..11a980b2 100644 --- a/nest/neighbor.c +++ b/nest/neighbor.c @@ -231,7 +231,7 @@ neigh_up(neighbor *n, struct iface *i, int scope) static void neigh_down(neighbor *n) { - DBG("Flushing neighbor %I on %s\n", n->addr, i->name); + DBG("Flushing neighbor %I on %s\n", n->addr, n->iface->name); rem_node(&n->if_n); if (! (n->flags & NEF_BIND)) n->iface = NULL; diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index f61e31a5..08dc11b6 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -1040,11 +1041,9 @@ nl_open_async(void) sock *sk; struct sockaddr_nl sa; int fd; - static int nl_open_tried = 0; - if (nl_open_tried) + if (nl_async_sk) return; - nl_open_tried = 1; DBG("KRT: Opening async netlink socket\n"); @@ -1065,18 +1064,18 @@ nl_open_async(void) if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { log(L_ERR "Unable to bind asynchronous rtnetlink socket: %m"); + close(fd); return; } + nl_async_rx_buffer = xmalloc(NL_RX_SIZE); + sk = nl_async_sk = sk_new(krt_pool); sk->type = SK_MAGIC; sk->rx_hook = nl_async_hook; sk->fd = fd; if (sk_open(sk)) bug("Netlink: sk_open failed"); - - if (!nl_async_rx_buffer) - nl_async_rx_buffer = xmalloc(NL_RX_SIZE); } /* @@ -1097,6 +1096,7 @@ krt_sys_start(struct krt_proto *p) void krt_sys_shutdown(struct krt_proto *p UNUSED) { + nl_table_map[KRT_CF->sys.table_id] = NULL; } int -- cgit v1.2.3