svn commit: r216789 - in projects/ofed/head/sys/ofed:
drivers/infiniband/core include/linux include/net
Jeff Roberson
jeff at FreeBSD.org
Wed Dec 29 04:17:50 UTC 2010
Author: jeff
Date: Wed Dec 29 04:17:50 2010
New Revision: 216789
URL: http://svn.freebsd.org/changeset/base/216789
Log:
- Solve a bug in addr.c where ifp could end up NULL.
Reported/Tested by: gnn
- Add support for Linux netevents via BSD eventhandlers.
Sponsored by: Isilon Systems, iX Systems, and Panasas.
Modified:
projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c
projects/ofed/head/sys/ofed/include/linux/notifier.h
projects/ofed/head/sys/ofed/include/net/netevent.h
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c Wed Dec 29 04:16:12 2010 (r216788)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c Wed Dec 29 04:17:50 2010 (r216789)
@@ -427,17 +427,21 @@ static int addr_resolve(struct sockaddr
}
/*
* If it's not multicast or broadcast and the route doesn't match the
- * requested interface return unreachable.
+ * requested interface return unreachable. Otherwise fetch the
+ * correct interface pointer and unlock the route.
*/
if (multi || bcast) {
+ if (ifp == NULL)
+ ifp = rte->rt_ifp;
RTFREE_LOCKED(rte);
} else if (ifp && ifp != rte->rt_ifp) {
RTFREE_LOCKED(rte);
return -ENETUNREACH;
- } else
+ } else {
+ if (ifp == NULL)
+ ifp = rte->rt_ifp;
RT_UNLOCK(rte);
- if (ifp == NULL)
- ifp = rte->rt_ifp;
+ }
mcast:
if (bcast)
return rdma_copy_addr(addr, ifp, ifp->if_broadcastaddr);
@@ -584,17 +588,19 @@ void rdma_addr_cancel(struct rdma_dev_ad
}
EXPORT_SYMBOL(rdma_addr_cancel);
-#ifdef __linux__
-/* XXX Need this callback to reduce timeout time. */
static int netevent_callback(struct notifier_block *self, unsigned long event,
void *ctx)
{
if (event == NETEVENT_NEIGH_UPDATE) {
+#ifdef __linux__
struct neighbour *neigh = ctx;
if (neigh->nud_state & NUD_VALID) {
set_timeout(jiffies);
}
+#else
+ set_timeout(jiffies);
+#endif
}
return 0;
}
@@ -602,7 +608,6 @@ static int netevent_callback(struct noti
static struct notifier_block nb = {
.notifier_call = netevent_callback
};
-#endif
static int addr_init(void)
{
@@ -611,17 +616,13 @@ static int addr_init(void)
if (!addr_wq)
return -ENOMEM;
-#ifdef __linux__
register_netevent_notifier(&nb);
-#endif
return 0;
}
static void addr_cleanup(void)
{
-#ifdef __linux__
unregister_netevent_notifier(&nb);
-#endif
destroy_workqueue(addr_wq);
}
Modified: projects/ofed/head/sys/ofed/include/linux/notifier.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/notifier.h Wed Dec 29 04:16:12 2010 (r216788)
+++ projects/ofed/head/sys/ofed/include/linux/notifier.h Wed Dec 29 04:17:50 2010 (r216789)
@@ -29,10 +29,18 @@
#ifndef _LINUX_NOTIFIER_H_
#define _LINUX_NOTIFIER_H_
+#include <sys/eventhandler.h>
+
+/*
+ * Max number of FreeBSD events to map to Linux events per notify type.
+ */
+#define NB_COUNT 5
+
struct notifier_block {
int (*notifier_call)(struct notifier_block *, unsigned long, void *);
struct notifier_block *next;
int priority;
+ eventhandler_tag tags[NB_COUNT];
};
#endif /* _LINUX_NOTIFIER_H_ */
Modified: projects/ofed/head/sys/ofed/include/net/netevent.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/net/netevent.h Wed Dec 29 04:16:12 2010 (r216788)
+++ projects/ofed/head/sys/ofed/include/net/netevent.h Wed Dec 29 04:17:50 2010 (r216789)
@@ -25,3 +25,47 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+#ifndef _LINUX_NET_NETEVENT_H_
+#define _LINUX_NET_NETEVENT_H_
+
+#include <netinet/if_ether.h>
+
+enum netevent_notif_type {
+ NETEVENT_NEIGH_UPDATE = 0,
+#if 0 /* Unsupported events. */
+ NETEVENT_PMTU_UPDATE,
+ NETEVENT_REDIRECT,
+#endif
+};
+
+struct llentry;
+
+static inline void
+_handle_arp_update_event(void *arg, struct llentry *lle)
+{
+ struct notifier_block *nb;
+
+ nb = arg;
+ nb->notifier_call(nb, NETEVENT_NEIGH_UPDATE, lle);
+}
+
+static inline int
+register_netevent_notifier(struct notifier_block *nb)
+{
+ nb->tags[NETEVENT_NEIGH_UPDATE] = EVENTHANDLER_REGISTER(
+ arp_update_event, _handle_arp_update_event, nb, 0);
+ return (0);
+}
+
+static inline int
+unregister_netevent_notifier(struct notifier_block *nb)
+{
+
+ EVENTHANDLER_DEREGISTER(arp_update_event,
+ nb->tags[NETEVENT_NEIGH_UPDATE]);
+
+ return (0);
+}
+
+#endif /* _LINUX_NET_NETEVENT_H_ */
More information about the svn-src-projects
mailing list