aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-07-03 04:01:51 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-05 05:21:55 -0400
commit1d248b1cf4e09dbec8cef5f7fbeda5874248bd09 (patch)
treee65714ecde4e590dbadb01e94bd2cdbe5f3789c8
parentfccd7d5c77ff61d5283e7ce8242791d5f00dcc17 (diff)
net: Pass neighbours and dest address into NETEVENT_REDIRECT events.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c23
-rw-r--r--include/net/netevent.h4
-rw-r--r--net/ipv6/route.c7
3 files changed, 19 insertions, 15 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 55cf72af69ce..633c6029e53c 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -62,7 +62,8 @@ static const unsigned int MAX_ATIDS = 64 * 1024;
62static const unsigned int ATID_BASE = 0x10000; 62static const unsigned int ATID_BASE = 0x10000;
63 63
64static void cxgb_neigh_update(struct neighbour *neigh); 64static void cxgb_neigh_update(struct neighbour *neigh);
65static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new); 65static void cxgb_redirect(struct dst_entry *old, struct neighbour *old_neigh,
66 struct dst_entry *new, struct neighbour *new_neigh);
66 67
67static inline int offload_activated(struct t3cdev *tdev) 68static inline int offload_activated(struct t3cdev *tdev)
68{ 69{
@@ -968,8 +969,9 @@ static int nb_callback(struct notifier_block *self, unsigned long event,
968 } 969 }
969 case (NETEVENT_REDIRECT):{ 970 case (NETEVENT_REDIRECT):{
970 struct netevent_redirect *nr = ctx; 971 struct netevent_redirect *nr = ctx;
971 cxgb_redirect(nr->old, nr->new); 972 cxgb_redirect(nr->old, nr->old_neigh,
972 cxgb_neigh_update(dst_get_neighbour_noref(nr->new)); 973 nr->new, nr->new_neigh);
974 cxgb_neigh_update(nr->new_neigh);
973 break; 975 break;
974 } 976 }
975 default: 977 default:
@@ -1107,10 +1109,10 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
1107 tdev->send(tdev, skb); 1109 tdev->send(tdev, skb);
1108} 1110}
1109 1111
1110static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) 1112static void cxgb_redirect(struct dst_entry *old, struct neighbour *old_neigh,
1113 struct dst_entry *new, struct neighbour *new_neigh)
1111{ 1114{
1112 struct net_device *olddev, *newdev; 1115 struct net_device *olddev, *newdev;
1113 struct neighbour *n;
1114 struct tid_info *ti; 1116 struct tid_info *ti;
1115 struct t3cdev *tdev; 1117 struct t3cdev *tdev;
1116 u32 tid; 1118 u32 tid;
@@ -1118,15 +1120,8 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
1118 struct l2t_entry *e; 1120 struct l2t_entry *e;
1119 struct t3c_tid_entry *te; 1121 struct t3c_tid_entry *te;
1120 1122
1121 n = dst_get_neighbour_noref(old); 1123 olddev = old_neigh->dev;
1122 if (!n) 1124 newdev = new_neigh->dev;
1123 return;
1124 olddev = n->dev;
1125
1126 n = dst_get_neighbour_noref(new);
1127 if (!n)
1128 return;
1129 newdev = n->dev;
1130 1125
1131 if (!is_offloading(olddev)) 1126 if (!is_offloading(olddev))
1132 return; 1127 return;
diff --git a/include/net/netevent.h b/include/net/netevent.h
index 086f8a5b59dc..3ce4988c9c08 100644
--- a/include/net/netevent.h
+++ b/include/net/netevent.h
@@ -12,10 +12,14 @@
12 */ 12 */
13 13
14struct dst_entry; 14struct dst_entry;
15struct neighbour;
15 16
16struct netevent_redirect { 17struct netevent_redirect {
17 struct dst_entry *old; 18 struct dst_entry *old;
19 struct neighbour *old_neigh;
18 struct dst_entry *new; 20 struct dst_entry *new;
21 struct neighbour *new_neigh;
22 const void *daddr;
19}; 23};
20 24
21enum netevent_notif_type { 25enum netevent_notif_type {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4b581c675bb2..34b29881e22d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1687,6 +1687,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1687 struct rt6_info *rt, *nrt = NULL; 1687 struct rt6_info *rt, *nrt = NULL;
1688 struct netevent_redirect netevent; 1688 struct netevent_redirect netevent;
1689 struct net *net = dev_net(neigh->dev); 1689 struct net *net = dev_net(neigh->dev);
1690 struct neighbour *old_neigh;
1690 1691
1691 rt = ip6_route_redirect(dest, src, saddr, neigh->dev); 1692 rt = ip6_route_redirect(dest, src, saddr, neigh->dev);
1692 1693
@@ -1714,7 +1715,8 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1714 dst_confirm(&rt->dst); 1715 dst_confirm(&rt->dst);
1715 1716
1716 /* Duplicate redirect: silently ignore. */ 1717 /* Duplicate redirect: silently ignore. */
1717 if (neigh == dst_get_neighbour_noref_raw(&rt->dst)) 1718 old_neigh = dst_get_neighbour_noref_raw(&rt->dst);
1719 if (neigh == old_neigh)
1718 goto out; 1720 goto out;
1719 1721
1720 nrt = ip6_rt_copy(rt, dest); 1722 nrt = ip6_rt_copy(rt, dest);
@@ -1732,7 +1734,10 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1732 goto out; 1734 goto out;
1733 1735
1734 netevent.old = &rt->dst; 1736 netevent.old = &rt->dst;
1737 netevent.old_neigh = old_neigh;
1735 netevent.new = &nrt->dst; 1738 netevent.new = &nrt->dst;
1739 netevent.new_neigh = neigh;
1740 netevent.daddr = dest;
1736 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); 1741 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent);
1737 1742
1738 if (rt->rt6i_flags & RTF_CACHE) { 1743 if (rt->rt6i_flags & RTF_CACHE) {