diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-02 05:02:15 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-05 04:02:12 -0400 |
commit | a263b3093641fb1ec377582c90986a7fd0625184 (patch) | |
tree | 691fdb4703bb88611272bf958d9de1a461f1492a /net/ipv4/ip_output.c | |
parent | 11604721a3c4bea60e2ddd9e4e30d741ecdba7b0 (diff) |
ipv4: Make neigh lookups directly in output packet path.
Do not use the dst cached neigh, we'll be getting rid of that.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r-- | net/ipv4/ip_output.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 2630900e480a..6e9a266a0535 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -170,6 +170,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
170 | struct net_device *dev = dst->dev; | 170 | struct net_device *dev = dst->dev; |
171 | unsigned int hh_len = LL_RESERVED_SPACE(dev); | 171 | unsigned int hh_len = LL_RESERVED_SPACE(dev); |
172 | struct neighbour *neigh; | 172 | struct neighbour *neigh; |
173 | u32 nexthop; | ||
173 | 174 | ||
174 | if (rt->rt_type == RTN_MULTICAST) { | 175 | if (rt->rt_type == RTN_MULTICAST) { |
175 | IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len); | 176 | IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len); |
@@ -191,15 +192,18 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
191 | skb = skb2; | 192 | skb = skb2; |
192 | } | 193 | } |
193 | 194 | ||
194 | rcu_read_lock(); | 195 | rcu_read_lock_bh(); |
195 | neigh = dst_get_neighbour_noref(dst); | 196 | nexthop = rt->rt_gateway ? rt->rt_gateway : ip_hdr(skb)->daddr; |
197 | neigh = __ipv4_neigh_lookup_noref(dev, nexthop); | ||
198 | if (unlikely(!neigh)) | ||
199 | neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); | ||
196 | if (neigh) { | 200 | if (neigh) { |
197 | int res = neigh_output(neigh, skb); | 201 | int res = neigh_output(neigh, skb); |
198 | 202 | ||
199 | rcu_read_unlock(); | 203 | rcu_read_unlock_bh(); |
200 | return res; | 204 | return res; |
201 | } | 205 | } |
202 | rcu_read_unlock(); | 206 | rcu_read_unlock_bh(); |
203 | 207 | ||
204 | net_dbg_ratelimited("%s: No header cache and no neighbour!\n", | 208 | net_dbg_ratelimited("%s: No header cache and no neighbour!\n", |
205 | __func__); | 209 | __func__); |