* [PATCH 1/2] Network Event Notifier Mechanism.
2006-06-21 19:48 [PATCH 0/2][RFC] Network Event Notifier Mechanism Steve Wise
@ 2006-06-21 19:48 ` Steve Wise
2006-06-21 19:48 ` [PATCH 2/2] Core network changes to support network event notification Steve Wise
2006-06-21 20:40 ` [PATCH 0/2][RFC] Network Event Notifier Mechanism David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Steve Wise @ 2006-06-21 19:48 UTC (permalink / raw)
To: swise; +Cc: linux-kernel, openib-general
This patch uses notifier blocks to implement a network event
notifier mechanism.
Clients register their callback function by calling
register_netevent_notifier() like this:
static struct notifier_block nb = {
.notifier_call = my_callback_func
};
...
register_netevent_notifier(&nb);
---
include/net/netevent.h | 41 +++++++++++++++++++++++++++++
net/core/netevent.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+), 0 deletions(-)
diff --git a/include/net/netevent.h b/include/net/netevent.h
new file mode 100644
index 0000000..9ceab27
--- /dev/null
+++ b/include/net/netevent.h
@@ -0,0 +1,41 @@
+#ifndef _NET_EVENT_H
+#define _NET_EVENT_H
+
+/*
+ * Generic netevent notifiers
+ *
+ * Authors:
+ * Tom Tucker <tom@opengridcomputing.com>
+ *
+ * Changes:
+ */
+
+#ifdef __KERNEL__
+
+#include <net/dst.h>
+
+struct netevent_redirect {
+ struct dst_entry *old;
+ struct dst_entry *new;
+};
+
+struct netevent_route_change {
+ int event;
+ struct fib_info *fib_info;
+};
+
+enum netevent_notif_type {
+ NETEVENT_NEIGH_UPDATE = 1, /* arg is * struct neighbour */
+ NETEVENT_ROUTE_UPDATE, /* arg is * netevent_route_change */
+ NETEVENT_PMTU_UPDATE,
+ NETEVENT_REDIRECT, /* arg is * struct netevent_redirect */
+};
+
+extern int register_netevent_notifier(struct notifier_block *nb);
+extern int unregister_netevent_notifier(struct notifier_block *nb);
+extern int call_netevent_notifiers(unsigned long val, void *v);
+
+#endif
+#endif
+
+
diff --git a/net/core/netevent.c b/net/core/netevent.c
new file mode 100644
index 0000000..2261fb3
--- /dev/null
+++ b/net/core/netevent.c
@@ -0,0 +1,67 @@
+/*
+ * Network event notifiers
+ *
+ * Authors:
+ * Tom Tucker <tom@opengridcomputing.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Fixes:
+ */
+
+#include <linux/rtnetlink.h>
+#include <linux/notifier.h>
+
+static struct atomic_notifier_head netevent_notif_chain;
+
+/**
+ * register_netevent_notifier - register a netevent notifier block
+ * @nb: notifier
+ *
+ * Register a notifier to be called when a netevent occurs.
+ * The notifier passed is linked into the kernel structures and must
+ * not be reused until it has been unregistered. A negative errno code
+ * is returned on a failure.
+ */
+int register_netevent_notifier(struct notifier_block *nb)
+{
+ int err;
+
+ err = atomic_notifier_chain_register(&netevent_notif_chain, nb);
+ return err;
+}
+
+/**
+ * netevent_unregister_notifier - unregister a netevent notifier block
+ * @nb: notifier
+ *
+ * Unregister a notifier previously registered by
+ * register_neigh_notifier(). The notifier is unlinked into the
+ * kernel structures and may then be reused. A negative errno code
+ * is returned on a failure.
+ */
+
+int unregister_netevent_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&netevent_notif_chain, nb);
+}
+
+/**
+ * call_netevent_notifiers - call all netevent notifier blocks
+ * @val: value passed unmodified to notifier function
+ * @v: pointer passed unmodified to notifier function
+ *
+ * Call all neighbour notifier blocks. Parameters and return value
+ * are as for notifier_call_chain().
+ */
+
+int call_netevent_notifiers(unsigned long val, void *v)
+{
+ return atomic_notifier_call_chain(&netevent_notif_chain, val, v);
+}
+
+EXPORT_SYMBOL_GPL(register_netevent_notifier);
+EXPORT_SYMBOL_GPL(unregister_netevent_notifier);
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH 2/2] Core network changes to support network event notification.
2006-06-21 19:48 [PATCH 0/2][RFC] Network Event Notifier Mechanism Steve Wise
2006-06-21 19:48 ` [PATCH 1/2] " Steve Wise
@ 2006-06-21 19:48 ` Steve Wise
2006-06-21 20:40 ` [PATCH 0/2][RFC] Network Event Notifier Mechanism David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Steve Wise @ 2006-06-21 19:48 UTC (permalink / raw)
To: swise; +Cc: linux-kernel, openib-general
This patch adds event calls for neighbour change, route update, and
routing redirect events.
TODO: PMTU change events.
---
net/core/Makefile | 2 +-
net/core/neighbour.c | 8 ++++++++
net/ipv4/fib_semantics.c | 7 +++++++
net/ipv4/route.c | 6 ++++++
4 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/net/core/Makefile b/net/core/Makefile
index e9bd246..2645ba4 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -7,7 +7,7 @@ obj-y := sock.o request_sock.o skbuff.o
obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
-obj-y += dev.o ethtool.o dev_mcast.o dst.o \
+obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \
neighbour.o rtnetlink.o utils.o link_watch.o filter.o
obj-$(CONFIG_XFRM) += flow.o
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 50a8c73..c637897 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -30,9 +30,11 @@ #include <linux/times.h>
#include <net/neighbour.h>
#include <net/dst.h>
#include <net/sock.h>
+#include <net/netevent.h>
#include <linux/rtnetlink.h>
#include <linux/random.h>
#include <linux/string.h>
+#include <linux/notifier.h>
#define NEIGH_DEBUG 1
@@ -755,6 +757,7 @@ #endif
neigh->nud_state = NUD_STALE;
neigh->updated = jiffies;
neigh_suspect(neigh);
+ call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
}
} else if (state & NUD_DELAY) {
if (time_before_eq(now,
@@ -763,6 +766,7 @@ #endif
neigh->nud_state = NUD_REACHABLE;
neigh->updated = jiffies;
neigh_connect(neigh);
+ call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
next = neigh->confirmed + neigh->parms->reachable_time;
} else {
NEIGH_PRINTK2("neigh %p is probed.\n", neigh);
@@ -783,6 +787,7 @@ #endif
neigh->nud_state = NUD_FAILED;
neigh->updated = jiffies;
notify = 1;
+ call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
@@ -1056,6 +1061,9 @@ out:
(neigh->flags | NTF_ROUTER) :
(neigh->flags & ~NTF_ROUTER);
}
+
+ call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
+
write_unlock_bh(&neigh->lock);
#ifdef CONFIG_ARPD
if (notify && neigh->parms->app_probes)
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 0f4145b..67a30af 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -45,6 +45,7 @@ #include <net/tcp.h>
#include <net/sock.h>
#include <net/ip_fib.h>
#include <net/ip_mp_alg.h>
+#include <net/netevent.h>
#include "fib_lookup.h"
@@ -278,9 +279,15 @@ void rtmsg_fib(int event, u32 key, struc
struct nlmsghdr *n, struct netlink_skb_parms *req)
{
struct sk_buff *skb;
+ struct netevent_route_change rev;
+
u32 pid = req ? req->pid : n->nlmsg_pid;
int size = NLMSG_SPACE(sizeof(struct rtmsg)+256);
+ rev.event = event;
+ rev.fib_info = fa->fa_info;
+ call_netevent_notifiers(NETEVENT_ROUTE_UPDATE, &rev);
+
skb = alloc_skb(size, GFP_KERNEL);
if (!skb)
return;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index cc9423d..e9ba831 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -105,6 +105,7 @@ #include <net/tcp.h>
#include <net/icmp.h>
#include <net/xfrm.h>
#include <net/ip_mp_alg.h>
+#include <net/netevent.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
@@ -1120,6 +1121,7 @@ void ip_rt_redirect(u32 old_gw, u32 dadd
struct rtable *rth, **rthp;
u32 skeys[2] = { saddr, 0 };
int ikeys[2] = { dev->ifindex, 0 };
+ struct netevent_redirect netevent;
if (!in_dev)
return;
@@ -1211,6 +1213,10 @@ void ip_rt_redirect(u32 old_gw, u32 dadd
rt_drop(rt);
goto do_next;
}
+
+ netevent.old = &rth->u.dst;
+ netevent.new = &rt->u.dst;
+ call_netevent_notifiers(NETEVENT_REDIRECT, &netevent);
rt_del(hash, rth);
if (!rt_intern_hash(hash, rt, &rt))
^ permalink raw reply [flat|nested] 4+ messages in thread