aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-02-17 18:42:37 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-17 18:42:37 -0500
commit0c4dcd58fd69aded93b0dc6917cd88b262c8aa3f (patch)
treed410498acb93dee35b8da0092d9db5e8b226fc08 /net/ipv4/route.c
parent010c2708e536938a2f84d51d625f603b9a8f80ac (diff)
ipv4: Consolidate ipv4 dst allocation logic.
This also allows us to combine all the dst->flags settings and avoid read/modify/write sequences to this struct member. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c52
1 files changed, 21 insertions, 31 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index b2b3c9e0a618..79a287181025 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1816,6 +1816,21 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
1816 rt->rt_type = res->type; 1816 rt->rt_type = res->type;
1817} 1817}
1818 1818
1819static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm)
1820{
1821 struct rtable *rt = dst_alloc(&ipv4_dst_ops);
1822 if (rt) {
1823 rt->dst.obsolete = -1;
1824
1825 atomic_set(&rt->dst.__refcnt, 1);
1826
1827 rt->dst.flags = DST_HOST |
1828 (nopolicy ? DST_NOPOLICY : 0) |
1829 (noxfrm ? DST_NOXFRM : 0);
1830 }
1831 return rt;
1832}
1833
1819/* called in rcu_read_lock() section */ 1834/* called in rcu_read_lock() section */
1820static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, 1835static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1821 u8 tos, struct net_device *dev, int our) 1836 u8 tos, struct net_device *dev, int our)
@@ -1846,17 +1861,12 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1846 if (err < 0) 1861 if (err < 0)
1847 goto e_err; 1862 goto e_err;
1848 } 1863 }
1849 rth = dst_alloc(&ipv4_dst_ops); 1864 rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
1850 if (!rth) 1865 if (!rth)
1851 goto e_nobufs; 1866 goto e_nobufs;
1852 1867
1853 rth->dst.output = ip_rt_bug; 1868 rth->dst.output = ip_rt_bug;
1854 rth->dst.obsolete = -1;
1855 1869
1856 atomic_set(&rth->dst.__refcnt, 1);
1857 rth->dst.flags= DST_HOST;
1858 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
1859 rth->dst.flags |= DST_NOPOLICY;
1860 rth->fl.fl4_dst = daddr; 1870 rth->fl.fl4_dst = daddr;
1861 rth->rt_dst = daddr; 1871 rth->rt_dst = daddr;
1862 rth->fl.fl4_tos = tos; 1872 rth->fl.fl4_tos = tos;
@@ -1985,19 +1995,13 @@ static int __mkroute_input(struct sk_buff *skb,
1985 } 1995 }
1986 } 1996 }
1987 1997
1988 1998 rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY),
1989 rth = dst_alloc(&ipv4_dst_ops); 1999 IN_DEV_CONF_GET(out_dev, NOXFRM));
1990 if (!rth) { 2000 if (!rth) {
1991 err = -ENOBUFS; 2001 err = -ENOBUFS;
1992 goto cleanup; 2002 goto cleanup;
1993 } 2003 }
1994 2004
1995 atomic_set(&rth->dst.__refcnt, 1);
1996 rth->dst.flags= DST_HOST;
1997 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
1998 rth->dst.flags |= DST_NOPOLICY;
1999 if (IN_DEV_CONF_GET(out_dev, NOXFRM))
2000 rth->dst.flags |= DST_NOXFRM;
2001 rth->fl.fl4_dst = daddr; 2005 rth->fl.fl4_dst = daddr;
2002 rth->rt_dst = daddr; 2006 rth->rt_dst = daddr;
2003 rth->fl.fl4_tos = tos; 2007 rth->fl.fl4_tos = tos;
@@ -2012,7 +2016,6 @@ static int __mkroute_input(struct sk_buff *skb,
2012 rth->fl.oif = 0; 2016 rth->fl.oif = 0;
2013 rth->rt_spec_dst= spec_dst; 2017 rth->rt_spec_dst= spec_dst;
2014 2018
2015 rth->dst.obsolete = -1;
2016 rth->dst.input = ip_forward; 2019 rth->dst.input = ip_forward;
2017 rth->dst.output = ip_output; 2020 rth->dst.output = ip_output;
2018 rth->rt_genid = rt_genid(dev_net(rth->dst.dev)); 2021 rth->rt_genid = rt_genid(dev_net(rth->dst.dev));
@@ -2162,18 +2165,13 @@ brd_input:
2162 RT_CACHE_STAT_INC(in_brd); 2165 RT_CACHE_STAT_INC(in_brd);
2163 2166
2164local_input: 2167local_input:
2165 rth = dst_alloc(&ipv4_dst_ops); 2168 rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
2166 if (!rth) 2169 if (!rth)
2167 goto e_nobufs; 2170 goto e_nobufs;
2168 2171
2169 rth->dst.output= ip_rt_bug; 2172 rth->dst.output= ip_rt_bug;
2170 rth->dst.obsolete = -1;
2171 rth->rt_genid = rt_genid(net); 2173 rth->rt_genid = rt_genid(net);
2172 2174
2173 atomic_set(&rth->dst.__refcnt, 1);
2174 rth->dst.flags= DST_HOST;
2175 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
2176 rth->dst.flags |= DST_NOPOLICY;
2177 rth->fl.fl4_dst = daddr; 2175 rth->fl.fl4_dst = daddr;
2178 rth->rt_dst = daddr; 2176 rth->rt_dst = daddr;
2179 rth->fl.fl4_tos = tos; 2177 rth->fl.fl4_tos = tos;
@@ -2366,18 +2364,11 @@ static struct rtable *__mkroute_output(struct fib_result *res,
2366 res->fi = NULL; 2364 res->fi = NULL;
2367 } 2365 }
2368 2366
2369 2367 rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY),
2370 rth = dst_alloc(&ipv4_dst_ops); 2368 IN_DEV_CONF_GET(in_dev, NOXFRM));
2371 if (!rth) 2369 if (!rth)
2372 return ERR_PTR(-ENOBUFS); 2370 return ERR_PTR(-ENOBUFS);
2373 2371
2374 atomic_set(&rth->dst.__refcnt, 1);
2375 rth->dst.flags= DST_HOST;
2376 if (IN_DEV_CONF_GET(in_dev, NOXFRM))
2377 rth->dst.flags |= DST_NOXFRM;
2378 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
2379 rth->dst.flags |= DST_NOPOLICY;
2380
2381 rth->fl.fl4_dst = oldflp->fl4_dst; 2372 rth->fl.fl4_dst = oldflp->fl4_dst;
2382 rth->fl.fl4_tos = tos; 2373 rth->fl.fl4_tos = tos;
2383 rth->fl.fl4_src = oldflp->fl4_src; 2374 rth->fl.fl4_src = oldflp->fl4_src;
@@ -2394,7 +2385,6 @@ static struct rtable *__mkroute_output(struct fib_result *res,
2394 rth->rt_spec_dst= fl->fl4_src; 2385 rth->rt_spec_dst= fl->fl4_src;
2395 2386
2396 rth->dst.output=ip_output; 2387 rth->dst.output=ip_output;
2397 rth->dst.obsolete = -1;
2398 rth->rt_genid = rt_genid(dev_net(dev_out)); 2388 rth->rt_genid = rt_genid(dev_net(dev_out));
2399 2389
2400 RT_CACHE_STAT_INC(out_slow_tot); 2390 RT_CACHE_STAT_INC(out_slow_tot);