Date: Wed, 29 Dec 2010 04:17:50 +0000 (UTC) From: Jeff Roberson <jeff@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r216789 - in projects/ofed/head/sys/ofed: drivers/infiniband/core include/linux include/net Message-ID: <201012290417.oBT4HoQ2086985@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201012290417.oBT4HoQ2086985>