Commit a77702af authored by David S. Miller's avatar David S. Miller

[IPV4]: Do not use skb_linearize() in ARP handling.

parent a116ffd9
...@@ -623,15 +623,20 @@ int arp_process(struct sk_buff *skb) ...@@ -623,15 +623,20 @@ int arp_process(struct sk_buff *skb)
int addr_type; int addr_type;
struct neighbour *n; struct neighbour *n;
/* arp_rcv below verifies the ARP header, verifies the device /* arp_rcv below verifies the ARP header and verifies the device
* is ARP'able, and linearizes the SKB (if needed). * is ARP'able.
*/ */
if (in_dev == NULL) if (in_dev == NULL)
goto out; goto out;
/* ARP header, plus 2 device addresses, plus 2 IP addresses. */
if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
(2 * dev->addr_len) +
(2 * sizeof(u32)))))
goto out;
arp = skb->nh.arph; arp = skb->nh.arph;
arp_ptr= (unsigned char *)(arp+1);
switch (dev_type) { switch (dev_type) {
default: default:
...@@ -693,6 +698,7 @@ int arp_process(struct sk_buff *skb) ...@@ -693,6 +698,7 @@ int arp_process(struct sk_buff *skb)
/* /*
* Extract fields * Extract fields
*/ */
arp_ptr= (unsigned char *)(arp+1);
sha = arp_ptr; sha = arp_ptr;
arp_ptr += dev->addr_len; arp_ptr += dev->addr_len;
memcpy(&sip, arp_ptr, 4); memcpy(&sip, arp_ptr, 4);
...@@ -841,11 +847,6 @@ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) ...@@ -841,11 +847,6 @@ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
goto out_of_mem; goto out_of_mem;
if (skb_is_nonlinear(skb)) {
if (skb_linearize(skb, GFP_ATOMIC) != 0)
goto freeskb;
}
return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process); return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
freeskb: freeskb:
......
...@@ -247,14 +247,16 @@ unsigned int arpt_do_table(struct sk_buff **pskb, ...@@ -247,14 +247,16 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
{ {
static const char nulldevname[IFNAMSIZ] = { 0 }; static const char nulldevname[IFNAMSIZ] = { 0 };
unsigned int verdict = NF_DROP; unsigned int verdict = NF_DROP;
struct arphdr *arp = (*pskb)->nh.arph; struct arphdr *arp;
int hotdrop = 0; int hotdrop = 0;
struct arpt_entry *e, *back; struct arpt_entry *e, *back;
const char *indev, *outdev; const char *indev, *outdev;
void *table_base; void *table_base;
/* FIXME: Push down to extensions --RR */ /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0) if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) +
(2 * (*pskb)->dev->addr_len) +
(2 * sizeof(u32)))))
return NF_DROP; return NF_DROP;
indev = in ? in->name : nulldevname; indev = in ? in->name : nulldevname;
...@@ -267,6 +269,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb, ...@@ -267,6 +269,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
e = get_entry(table_base, table->private->hook_entry[hook]); e = get_entry(table_base, table->private->hook_entry[hook]);
back = get_entry(table_base, table->private->underflow[hook]); back = get_entry(table_base, table->private->underflow[hook]);
arp = (*pskb)->nh.arph;
do { do {
if (arp_packet_match(arp, (*pskb)->dev, indev, outdev, &e->arp)) { if (arp_packet_match(arp, (*pskb)->dev, indev, outdev, &e->arp)) {
struct arpt_entry_target *t; struct arpt_entry_target *t;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment