summaryrefslogtreecommitdiff
path: root/sysdep
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2012-01-23 03:15:12 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2012-01-23 03:15:12 +0100
commit09686693d35bd71187847c95c0967d4125215b97 (patch)
tree842c54fdb63daad9015af1da09e710c0bc52b3b0 /sysdep
parent732a0a257d180a95a02587203555b8552b6128ac (diff)
Implements handling of BSD iface arrival/departure notifications.
Thanks to Alexander V. Chernikov for original patch.
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/bsd/krt-sock.c32
-rw-r--r--sysdep/unix/krt.c7
-rw-r--r--sysdep/unix/krt.h1
3 files changed, 39 insertions, 1 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c
index f831327b..4ee5495f 100644
--- a/sysdep/bsd/krt-sock.c
+++ b/sysdep/bsd/krt-sock.c
@@ -410,6 +410,33 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
}
static void
+krt_read_ifannounce(struct ks_msg *msg)
+{
+ struct if_announcemsghdr *ifam = (struct if_announcemsghdr *)&msg->rtm;
+
+ if (ifam->ifan_what == IFAN_ARRIVAL)
+ {
+ /* Not enough info to create the iface, so we just trigger iface scan */
+ kif_request_scan();
+ }
+ else if (ifam->ifan_what == IFAN_DEPARTURE)
+ {
+ struct iface *iface = if_find_by_index(ifam->ifan_index);
+
+ /* Interface is destroyed */
+ if (!iface)
+ {
+ DBG("KRT: unknown interface (%s, #%d) going down. Ignoring\n", ifam->ifan_name, ifam->ifan_index);
+ return;
+ }
+
+ if_delete(iface);
+ }
+
+ DBG("KRT: IFANNOUNCE what: %d index %d name %s\n", ifam->ifan_what, ifam->ifan_index, ifam->ifan_name);
+}
+
+static void
krt_read_ifinfo(struct ks_msg *msg)
{
struct if_msghdr *ifm = (struct if_msghdr *)&msg->rtm;
@@ -435,7 +462,7 @@ krt_read_ifinfo(struct ks_msg *msg)
if (dl && (dl->sdl_family != AF_LINK))
{
- log("Ignoring strange IFINFO");
+ log(L_WARN "Ignoring strange IFINFO");
return;
}
@@ -599,6 +626,9 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan)
case RTM_DELETE:
krt_read_rt(msg, (struct krt_proto *)p, scan);
break;
+ case RTM_IFANNOUNCE:
+ krt_read_ifannounce(msg);
+ break;
case RTM_IFINFO:
krt_read_ifinfo(msg);
break;
diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
index e5a8ce17..ad8ea6b6 100644
--- a/sysdep/unix/krt.c
+++ b/sysdep/unix/krt.c
@@ -104,6 +104,13 @@ kif_force_scan(void)
}
}
+void
+kif_request_scan(void)
+{
+ if (kif_proto && kif_scan_timer->expires > now)
+ tm_start(kif_scan_timer, 1);
+}
+
static struct proto *
kif_init(struct proto_config *c)
{
diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h
index 7bb4fe70..b0c4dc5e 100644
--- a/sysdep/unix/krt.h
+++ b/sysdep/unix/krt.h
@@ -77,6 +77,7 @@ extern pool *krt_pool;
if (pr->p.debug & fl) \
{ log(L_TRACE "%s: " msg, pr->p.name , ## args); } } while(0)
+void kif_request_scan(void);
void krt_got_route(struct krt_proto *p, struct rte *e);
void krt_got_route_async(struct krt_proto *p, struct rte *e, int new);