mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
[IPV4]: Move ip options parsing out of ip_rcv_finish()
Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e9c6042273
commit
d245407e75
@ -279,6 +279,58 @@ int ip_local_deliver(struct sk_buff *skb)
|
||||
ip_local_deliver_finish);
|
||||
}
|
||||
|
||||
static inline int ip_rcv_options(struct sk_buff *skb)
|
||||
{
|
||||
struct ip_options *opt;
|
||||
struct iphdr *iph;
|
||||
struct net_device *dev = skb->dev;
|
||||
|
||||
/* It looks as overkill, because not all
|
||||
IP options require packet mangling.
|
||||
But it is the easiest for now, especially taking
|
||||
into account that combination of IP options
|
||||
and running sniffer is extremely rare condition.
|
||||
--ANK (980813)
|
||||
*/
|
||||
if (skb_cow(skb, skb_headroom(skb))) {
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
iph = skb->nh.iph;
|
||||
|
||||
if (ip_options_compile(NULL, skb)) {
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
opt = &(IPCB(skb)->opt);
|
||||
if (unlikely(opt->srr)) {
|
||||
struct in_device *in_dev = in_dev_get(dev);
|
||||
if (in_dev) {
|
||||
if (!IN_DEV_SOURCE_ROUTE(in_dev)) {
|
||||
if (IN_DEV_LOG_MARTIANS(in_dev) &&
|
||||
net_ratelimit())
|
||||
printk(KERN_INFO "source route option "
|
||||
"%u.%u.%u.%u -> %u.%u.%u.%u\n",
|
||||
NIPQUAD(iph->saddr),
|
||||
NIPQUAD(iph->daddr));
|
||||
in_dev_put(in_dev);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
in_dev_put(in_dev);
|
||||
}
|
||||
|
||||
if (ip_options_rcv_srr(skb))
|
||||
goto drop;
|
||||
}
|
||||
|
||||
return 0;
|
||||
drop:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int ip_rcv_finish(struct sk_buff *skb)
|
||||
{
|
||||
struct net_device *dev = skb->dev;
|
||||
@ -308,48 +360,11 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (iph->ihl > 5) {
|
||||
struct ip_options *opt;
|
||||
|
||||
/* It looks as overkill, because not all
|
||||
IP options require packet mangling.
|
||||
But it is the easiest for now, especially taking
|
||||
into account that combination of IP options
|
||||
and running sniffer is extremely rare condition.
|
||||
--ANK (980813)
|
||||
*/
|
||||
|
||||
if (skb_cow(skb, skb_headroom(skb))) {
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
|
||||
goto drop;
|
||||
}
|
||||
iph = skb->nh.iph;
|
||||
|
||||
if (ip_options_compile(NULL, skb))
|
||||
goto inhdr_error;
|
||||
|
||||
opt = &(IPCB(skb)->opt);
|
||||
if (opt->srr) {
|
||||
struct in_device *in_dev = in_dev_get(dev);
|
||||
if (in_dev) {
|
||||
if (!IN_DEV_SOURCE_ROUTE(in_dev)) {
|
||||
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
|
||||
printk(KERN_INFO "source route option %u.%u.%u.%u -> %u.%u.%u.%u\n",
|
||||
NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
|
||||
in_dev_put(in_dev);
|
||||
goto drop;
|
||||
}
|
||||
in_dev_put(in_dev);
|
||||
}
|
||||
if (ip_options_rcv_srr(skb))
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
if (iph->ihl > 5 && ip_rcv_options(skb))
|
||||
goto drop;
|
||||
|
||||
return dst_input(skb);
|
||||
|
||||
inhdr_error:
|
||||
IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
return NET_RX_DROP;
|
||||
|
Loading…
Reference in New Issue
Block a user