diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-09-29 23:31:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-01 00:16:05 -0400 |
commit | 82efee1499a27c06f5afb11b07db384fdb3f7004 (patch) | |
tree | c329e037ddf4e13cd824c131eab3bd3a2e67a0fc /net/ipv4/fib_frontend.c | |
parent | 828bac87bb074f3366621724fdfbe314f98ccc7e (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.c | 32 |
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 | 158 | struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) | |
154 | struct 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); |
173 | out: | 179 | out: |
174 | fib_res_put(&res); | 180 | fib_res_put(&res); |
175 | return dev; | 181 | return dev; |
176 | } | 182 | } |
177 | EXPORT_SYMBOL(ip_dev_find); | 183 | EXPORT_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 |