diff options
author | David S. Miller <davem@davemloft.net> | 2012-06-28 06:59:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-28 06:59:11 -0400 |
commit | 35ebf65e851c6d9731abc6362b189858eb59f4d3 (patch) | |
tree | 2e78c2c81bc72aeeb172484996cdff268f0111a2 /net/ipv4/fib_frontend.c | |
parent | 70e7341673a47fb1525cfc7d6651cc98b5348928 (diff) |
ipv4: Create and use fib_compute_spec_dst() helper.
The specific destination is the host we direct unicast replies to.
Usually this is the original packet source address, but if we are
responding to a multicast or broadcast packet we have to use something
different.
Specifically we must use the source address we would use if we were to
send a packet to the unicast source of the original packet.
The routing cache precomputes this value, but we want to remove that
precomputation because it creates a hard dependency on the expensive
rpfilter source address validation which we'd like to make cheaper.
There are only three places where this matters:
1) ICMP replies.
2) pktinfo CMSG
3) IP options
Now there will be no real users of rt->rt_spec_dst and we can simply
remove it altogether.
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 | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 3854411fa37c..451939b60c54 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -180,6 +180,35 @@ unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, | |||
180 | } | 180 | } |
181 | EXPORT_SYMBOL(inet_dev_addr_type); | 181 | EXPORT_SYMBOL(inet_dev_addr_type); |
182 | 182 | ||
183 | __be32 fib_compute_spec_dst(struct sk_buff *skb) | ||
184 | { | ||
185 | struct net_device *dev = skb->dev; | ||
186 | struct in_device *in_dev; | ||
187 | struct fib_result res; | ||
188 | struct flowi4 fl4; | ||
189 | struct net *net; | ||
190 | |||
191 | if (skb->pkt_type != PACKET_BROADCAST && | ||
192 | skb->pkt_type != PACKET_MULTICAST) | ||
193 | return ip_hdr(skb)->daddr; | ||
194 | |||
195 | in_dev = __in_dev_get_rcu(dev); | ||
196 | BUG_ON(!in_dev); | ||
197 | fl4.flowi4_oif = 0; | ||
198 | fl4.flowi4_iif = 0; | ||
199 | fl4.daddr = ip_hdr(skb)->saddr; | ||
200 | fl4.saddr = ip_hdr(skb)->daddr; | ||
201 | fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); | ||
202 | fl4.flowi4_scope = RT_SCOPE_UNIVERSE; | ||
203 | fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0; | ||
204 | |||
205 | net = dev_net(dev); | ||
206 | if (!fib_lookup(net, &fl4, &res)) | ||
207 | return FIB_RES_PREFSRC(net, res); | ||
208 | else | ||
209 | return inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); | ||
210 | } | ||
211 | |||
183 | /* Given (packet source, input interface) and optional (dst, oif, tos): | 212 | /* Given (packet source, input interface) and optional (dst, oif, tos): |
184 | * - (main) check, that source is valid i.e. not broadcast or our local | 213 | * - (main) check, that source is valid i.e. not broadcast or our local |
185 | * address. | 214 | * address. |