diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-05-10 07:32:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-05-17 20:18:51 -0400 |
commit | 407eadd996dc62a827db85f1d0c286a98fd5d336 (patch) | |
tree | 199b695cd045650b939aab61cbb55c31d9165b4e | |
parent | 7fee226ad2397b635e2fd565a59ca3ae08a164cd (diff) |
net: implements ip_route_input_noref()
ip_route_input() is the version returning a refcounted dst, while
ip_route_input_noref() returns a non refcounted one.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/route.h | 17 | ||||
-rw-r--r-- | net/ipv4/route.c | 15 |
2 files changed, 26 insertions, 6 deletions
diff --git a/include/net/route.h b/include/net/route.h index 2c9fba7f7731..af6cf4b4c9dc 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -112,7 +112,22 @@ extern void rt_cache_flush_batch(void); | |||
112 | extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); | 112 | extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); |
113 | extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); | 113 | extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); |
114 | extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); | 114 | extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); |
115 | extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin); | 115 | |
116 | extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, | ||
117 | u8 tos, struct net_device *devin, bool noref); | ||
118 | |||
119 | static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, | ||
120 | u8 tos, struct net_device *devin) | ||
121 | { | ||
122 | return ip_route_input_common(skb, dst, src, tos, devin, false); | ||
123 | } | ||
124 | |||
125 | static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src, | ||
126 | u8 tos, struct net_device *devin) | ||
127 | { | ||
128 | return ip_route_input_common(skb, dst, src, tos, devin, true); | ||
129 | } | ||
130 | |||
116 | extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev); | 131 | extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev); |
117 | extern void ip_rt_send_redirect(struct sk_buff *skb); | 132 | extern void ip_rt_send_redirect(struct sk_buff *skb); |
118 | 133 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 705eccfb4769..560acc677ce4 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2277,8 +2277,8 @@ martian_source: | |||
2277 | goto e_inval; | 2277 | goto e_inval; |
2278 | } | 2278 | } |
2279 | 2279 | ||
2280 | int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | 2280 | int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, |
2281 | u8 tos, struct net_device *dev) | 2281 | u8 tos, struct net_device *dev, bool noref) |
2282 | { | 2282 | { |
2283 | struct rtable * rth; | 2283 | struct rtable * rth; |
2284 | unsigned hash; | 2284 | unsigned hash; |
@@ -2304,10 +2304,15 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2304 | rth->fl.mark == skb->mark && | 2304 | rth->fl.mark == skb->mark && |
2305 | net_eq(dev_net(rth->u.dst.dev), net) && | 2305 | net_eq(dev_net(rth->u.dst.dev), net) && |
2306 | !rt_is_expired(rth)) { | 2306 | !rt_is_expired(rth)) { |
2307 | dst_use(&rth->u.dst, jiffies); | 2307 | if (noref) { |
2308 | dst_use_noref(&rth->u.dst, jiffies); | ||
2309 | skb_dst_set_noref(skb, &rth->u.dst); | ||
2310 | } else { | ||
2311 | dst_use(&rth->u.dst, jiffies); | ||
2312 | skb_dst_set(skb, &rth->u.dst); | ||
2313 | } | ||
2308 | RT_CACHE_STAT_INC(in_hit); | 2314 | RT_CACHE_STAT_INC(in_hit); |
2309 | rcu_read_unlock(); | 2315 | rcu_read_unlock(); |
2310 | skb_dst_set(skb, &rth->u.dst); | ||
2311 | return 0; | 2316 | return 0; |
2312 | } | 2317 | } |
2313 | RT_CACHE_STAT_INC(in_hlist_search); | 2318 | RT_CACHE_STAT_INC(in_hlist_search); |
@@ -2350,6 +2355,7 @@ skip_cache: | |||
2350 | } | 2355 | } |
2351 | return ip_route_input_slow(skb, daddr, saddr, tos, dev); | 2356 | return ip_route_input_slow(skb, daddr, saddr, tos, dev); |
2352 | } | 2357 | } |
2358 | EXPORT_SYMBOL(ip_route_input_common); | ||
2353 | 2359 | ||
2354 | static int __mkroute_output(struct rtable **result, | 2360 | static int __mkroute_output(struct rtable **result, |
2355 | struct fib_result *res, | 2361 | struct fib_result *res, |
@@ -3361,5 +3367,4 @@ void __init ip_static_sysctl_init(void) | |||
3361 | #endif | 3367 | #endif |
3362 | 3368 | ||
3363 | EXPORT_SYMBOL(__ip_select_ident); | 3369 | EXPORT_SYMBOL(__ip_select_ident); |
3364 | EXPORT_SYMBOL(ip_route_input); | ||
3365 | EXPORT_SYMBOL(ip_route_output_key); | 3370 | EXPORT_SYMBOL(ip_route_output_key); |