diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2014-10-14 17:23:34 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2014-10-14 17:23:34 +0200 |
commit | 78342404ff573e85e396f0611014b90cea9b4c0a (patch) | |
tree | 39fd70db506dc05d83528b7afab258b07b8ac482 /sysdep/unix | |
parent | 178a197afb77770d8a90765e39065679936a45d1 (diff) | |
parent | cfdea7b85f6c520cc5a62eb907d2190db14c9900 (diff) |
Merge remote-tracking branch 'origin/master' into soft-int
Diffstat (limited to 'sysdep/unix')
-rw-r--r-- | sysdep/unix/io.c | 6 | ||||
-rw-r--r-- | sysdep/unix/krt.c | 64 | ||||
-rw-r--r-- | sysdep/unix/log.c | 28 |
3 files changed, 59 insertions, 39 deletions
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 5a0c07e5..164038ec 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -705,6 +705,7 @@ sk_prepare_cmsgs6(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen) { struct cmsghdr *cm; struct in6_pktinfo *pi; + int controllen = 0; msg->msg_control = cbuf; msg->msg_controllen = cbuflen; @@ -713,12 +714,13 @@ sk_prepare_cmsgs6(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen) cm->cmsg_level = SOL_IPV6; cm->cmsg_type = IPV6_PKTINFO; cm->cmsg_len = CMSG_LEN(sizeof(*pi)); + controllen += CMSG_SPACE(sizeof(*pi)); pi = (struct in6_pktinfo *) CMSG_DATA(cm); pi->ipi6_ifindex = s->iface ? s->iface->index : 0; pi->ipi6_addr = ipa_to_in6(s->saddr); - msg->msg_controllen = cm->cmsg_len; + msg->msg_controllen = controllen; } @@ -1965,7 +1967,7 @@ io_loop(void) while (current_sock && count < MAX_RX_STEPS) { sock *s = current_sock; - int e; + int e UNUSED; if ((s->type < SK_MAGIC) && FD_ISSET(s->fd, &rd) && s->rx_hook) { diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index bff3001f..a2fb83d9 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -36,7 +36,7 @@ * only once for all the instances. * * The code uses OS-dependent parts for kernel updates and scans. These parts are - * in more specific sysdep directories (e.g. sysdep/linux) in functions krt_sys_* + * in more specific sysdep directories (e.g. sysdep/linux) in functions krt_sys_* * and kif_sys_* (and some others like krt_replace_rte()) and krt-sys.h header file. * This is also used for platform specific protocol options and route attributes. * @@ -117,7 +117,7 @@ kif_request_scan(void) static inline int prefer_addr(struct ifa *a, struct ifa *b) -{ +{ int sa = a->scope > SCOPE_LINK; int sb = b->scope > SCOPE_LINK; @@ -300,10 +300,10 @@ krt_trace_in(struct krt_proto *p, rte *e, char *msg) } static inline void -krt_trace_in_rl(struct rate_limit *rl, struct krt_proto *p, rte *e, char *msg) +krt_trace_in_rl(struct tbf *f, struct krt_proto *p, rte *e, char *msg) { if (p->p.debug & D_PACKETS) - log_rl(rl, L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg); + log_rl(f, L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg); } /* @@ -312,7 +312,7 @@ krt_trace_in_rl(struct rate_limit *rl, struct krt_proto *p, rte *e, char *msg) #ifdef KRT_ALLOW_LEARN -static struct rate_limit rl_alien_seen, rl_alien_updated, rl_alien_created, rl_alien_ignored; +static struct tbf rl_alien = TBF_DEFAULT_LOG_LIMITS; /* * krt_same_key() specifies what (aside from the net) is the key in @@ -378,20 +378,20 @@ krt_learn_scan(struct krt_proto *p, rte *e) { if (krt_uptodate(m, e)) { - krt_trace_in_rl(&rl_alien_seen, p, e, "[alien] seen"); + krt_trace_in_rl(&rl_alien, p, e, "[alien] seen"); rte_free(e); m->u.krt.seen = 1; } else { - krt_trace_in_rl(&rl_alien_updated, p, e, "[alien] updated"); + krt_trace_in(p, e, "[alien] updated"); *mm = m->next; rte_free(m); m = NULL; } } else - krt_trace_in_rl(&rl_alien_created, p, e, "[alien] created"); + krt_trace_in(p, e, "[alien] created"); if (!m) { e->next = n->routes; @@ -637,7 +637,7 @@ krt_got_route(struct krt_proto *p, rte *e) krt_learn_scan(p, e); else { - krt_trace_in_rl(&rl_alien_ignored, p, e, "[alien] ignored"); + krt_trace_in_rl(&rl_alien, p, e, "[alien] ignored"); rte_free(e); } return; @@ -737,7 +737,7 @@ krt_prune(struct krt_proto *p) if (! krt_export_rte(p, &new, &tmpa)) { /* Route rejected, should not happen (KRF_INSTALLED) but to be sure .. */ - verdict = (verdict == KRF_CREATE) ? KRF_IGNORE : KRF_DELETE; + verdict = (verdict == KRF_CREATE) ? KRF_IGNORE : KRF_DELETE; } else { @@ -910,7 +910,7 @@ krt_scan_timer_stop(struct krt_proto *p) } static void -krt_scan_timer_kick(struct krt_proto *p UNUSED) +krt_scan_timer_kick(struct krt_proto *p) { tm_start(p->scan_timer, 0); } @@ -962,8 +962,8 @@ krt_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool * if (e->attrs->src->proto == P) return -1; - if (!KRT_CF->devroutes && - (e->attrs->dest == RTD_DEVICE) && + if (!KRT_CF->devroutes && + (e->attrs->dest == RTD_DEVICE) && (e->attrs->source != RTS_STATIC_DEVICE)) return -1; @@ -974,8 +974,8 @@ krt_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool * } static void -krt_notify(struct proto *P, struct rtable *table UNUSED, net *net, - rte *new, rte *old, struct ea_list *eattrs) +krt_rt_notify(struct proto *P, struct rtable *table UNUSED, net *net, + rte *new, rte *old, struct ea_list *eattrs) { struct krt_proto *p = (struct krt_proto *) P; @@ -992,6 +992,36 @@ krt_notify(struct proto *P, struct rtable *table UNUSED, net *net, } static void +krt_if_notify(struct proto *P, uint flags, struct iface *iface UNUSED) +{ + struct krt_proto *p = (struct krt_proto *) P; + + /* + * When interface went down, we should remove routes to it. In the ideal world, + * OS kernel would send us route removal notifications in such cases, but we + * cannot rely on it as it is often not true. E.g. Linux kernel removes related + * routes when an interface went down, but it does not notify userspace about + * that. To be sure, we just schedule a scan to ensure synchronization. + */ + + if ((flags & IF_CHANGE_DOWN) && KRT_CF->learn) + krt_scan_timer_kick(p); +} + +static int +krt_reload_routes(struct proto *P) +{ + struct krt_proto *p = (struct krt_proto *) P; + + /* Although we keep learned routes in krt_table, we rather schedule a scan */ + + if (KRT_CF->learn) + krt_scan_timer_kick(p); + + return 1; +} + +static void krt_feed_done(struct proto *P) { struct krt_proto *p = (struct krt_proto *) P; @@ -1022,7 +1052,9 @@ krt_init(struct proto_config *c) p->p.accept_ra_types = RA_OPTIMAL; p->p.import_control = krt_import_control; - p->p.rt_notify = krt_notify; + p->p.rt_notify = krt_rt_notify; + p->p.if_notify = krt_if_notify; + p->p.reload_routes = krt_reload_routes; p->p.feed_done = krt_feed_done; p->p.make_tmp_attrs = krt_make_tmp_attrs; p->p.store_tmp_attrs = krt_store_tmp_attrs; diff --git a/sysdep/unix/log.c b/sysdep/unix/log.c index 66a5581c..ccf35bf3 100644 --- a/sysdep/unix/log.c +++ b/sysdep/unix/log.c @@ -32,9 +32,6 @@ static FILE *dbgf; static list *current_log_list; static char *current_syslog_name; /* NULL -> syslog closed */ -static const bird_clock_t rate_limit_time = 5; -static const int rate_limit_count = 5; - #ifdef USE_PTHREADS @@ -154,7 +151,6 @@ vlog(int class, const char *msg, va_list args) } - /** * log - log a message * @msg: printf-like formatting string with message class information @@ -180,31 +176,21 @@ log_msg(char *msg, ...) } void -log_rl(struct rate_limit *rl, char *msg, ...) +log_rl(struct tbf *f, char *msg, ...) { + int last_hit = f->mark; int class = 1; va_list args; - bird_clock_t delta = now - rl->timestamp; - if ((0 <= delta) && (delta < rate_limit_time)) - { - rl->count++; - } - else - { - rl->timestamp = now; - rl->count = 1; - } - - if (rl->count > rate_limit_count) + /* Rate limiting is a bit tricky here as it also logs '...' during the first hit */ + if (tbf_limit(f) && last_hit) return; - va_start(args, msg); if (*msg >= 1 && *msg <= 8) class = *msg++; - vlog(class, msg, args); - if (rl->count == rate_limit_count) - vlog(class, "...", args); + + va_start(args, msg); + vlog(class, (f->mark ? "..." : msg), args); va_end(args); } |