Commit 407eadd996dc62a827db85f1d0c286a98fd5d336
Committed by
David S. Miller
1 parent
7fee226ad2
Exists in
master
and in
39 other branches
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>
Showing 2 changed files with 26 additions and 6 deletions Side-by-side Diff
include/net/route.h
... | ... | @@ -112,7 +112,22 @@ |
112 | 112 | extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); |
113 | 113 | extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); |
114 | 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 | 131 | extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev); |
117 | 132 | extern void ip_rt_send_redirect(struct sk_buff *skb); |
118 | 133 |
net/ipv4/route.c
... | ... | @@ -2277,8 +2277,8 @@ |
2277 | 2277 | goto e_inval; |
2278 | 2278 | } |
2279 | 2279 | |
2280 | -int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |
2281 | - u8 tos, struct net_device *dev) | |
2280 | +int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |
2281 | + u8 tos, struct net_device *dev, bool noref) | |
2282 | 2282 | { |
2283 | 2283 | struct rtable * rth; |
2284 | 2284 | unsigned hash; |
2285 | 2285 | |
... | ... | @@ -2304,10 +2304,15 @@ |
2304 | 2304 | rth->fl.mark == skb->mark && |
2305 | 2305 | net_eq(dev_net(rth->u.dst.dev), net) && |
2306 | 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 | 2314 | RT_CACHE_STAT_INC(in_hit); |
2309 | 2315 | rcu_read_unlock(); |
2310 | - skb_dst_set(skb, &rth->u.dst); | |
2311 | 2316 | return 0; |
2312 | 2317 | } |
2313 | 2318 | RT_CACHE_STAT_INC(in_hlist_search); |
... | ... | @@ -2350,6 +2355,7 @@ |
2350 | 2355 | } |
2351 | 2356 | return ip_route_input_slow(skb, daddr, saddr, tos, dev); |
2352 | 2357 | } |
2358 | +EXPORT_SYMBOL(ip_route_input_common); | |
2353 | 2359 | |
2354 | 2360 | static int __mkroute_output(struct rtable **result, |
2355 | 2361 | struct fib_result *res, |
... | ... | @@ -3361,6 +3367,5 @@ |
3361 | 3367 | #endif |
3362 | 3368 | |
3363 | 3369 | EXPORT_SYMBOL(__ip_select_ident); |
3364 | -EXPORT_SYMBOL(ip_route_input); | |
3365 | 3370 | EXPORT_SYMBOL(ip_route_output_key); |