aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_frontend.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-09-29 23:31:56 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-01 00:16:05 -0400
commit82efee1499a27c06f5afb11b07db384fdb3f7004 (patch)
treec329e037ddf4e13cd824c131eab3bd3a2e67a0fc /net/ipv4/fib_frontend.c
parent828bac87bb074f3366621724fdfbe314f98ccc7e (diff)
ipv4: introduce __ip_dev_find()
ip_dev_find(net, addr) finds a device given an IPv4 source address and takes a reference on it. Introduce __ip_dev_find(), taking a third argument, to optionally take the device reference. Callers not asking the reference to be taken should be in an rcu_read_lock() protected section. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_frontend.c')
-rw-r--r--net/ipv4/fib_frontend.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 981f3c59b334..4a69a957872b 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -147,34 +147,40 @@ static void fib_flush(struct net *net)
147 rt_cache_flush(net, -1); 147 rt_cache_flush(net, -1);
148} 148}
149 149
150/* 150/**
151 * Find the first device with a given source address. 151 * __ip_dev_find - find the first device with a given source address.
152 * @net: the net namespace
153 * @addr: the source address
154 * @devref: if true, take a reference on the found device
155 *
156 * If a caller uses devref=false, it should be protected by RCU
152 */ 157 */
153 158struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
154struct net_device * ip_dev_find(struct net *net, __be32 addr)
155{ 159{
156 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } }, 160 struct flowi fl = {
157 .flags = FLOWI_FLAG_MATCH_ANY_IIF }; 161 .nl_u = {
158 struct fib_result res; 162 .ip4_u = {
163 .daddr = addr
164 }
165 },
166 .flags = FLOWI_FLAG_MATCH_ANY_IIF
167 };
168 struct fib_result res = { 0 };
159 struct net_device *dev = NULL; 169 struct net_device *dev = NULL;
160 170
161#ifdef CONFIG_IP_MULTIPLE_TABLES
162 res.r = NULL;
163#endif
164
165 if (fib_lookup(net, &fl, &res)) 171 if (fib_lookup(net, &fl, &res))
166 return NULL; 172 return NULL;
167 if (res.type != RTN_LOCAL) 173 if (res.type != RTN_LOCAL)
168 goto out; 174 goto out;
169 dev = FIB_RES_DEV(res); 175 dev = FIB_RES_DEV(res);
170 176
171 if (dev) 177 if (dev && devref)
172 dev_hold(dev); 178 dev_hold(dev);
173out: 179out:
174 fib_res_put(&res); 180 fib_res_put(&res);
175 return dev; 181 return dev;
176} 182}
177EXPORT_SYMBOL(ip_dev_find); 183EXPORT_SYMBOL(__ip_dev_find);
178 184
179/* 185/*
180 * Find address type as if only "dev" was present in the system. If 186 * Find address type as if only "dev" was present in the system. If