arp: correct return value of arp_rcv
Currently, arp_rcv() always return zero on a packet delivery upcall. To make its behavior more compliant with the way this API should be used, this patch changes this to let it return NET_RX_SUCCESS when the packet is proper handled, and NET_RX_DROP otherwise. v1->v2: If sanity check is failed, call kfree_skb() instead of consume_skb(), then return the correct return value. Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8303394d81
commit
8dfd329fbc
|
@ -665,7 +665,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!in_dev)
|
if (!in_dev)
|
||||||
goto out;
|
goto out_free_skb;
|
||||||
|
|
||||||
arp = arp_hdr(skb);
|
arp = arp_hdr(skb);
|
||||||
|
|
||||||
|
@ -673,7 +673,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
default:
|
default:
|
||||||
if (arp->ar_pro != htons(ETH_P_IP) ||
|
if (arp->ar_pro != htons(ETH_P_IP) ||
|
||||||
htons(dev_type) != arp->ar_hrd)
|
htons(dev_type) != arp->ar_hrd)
|
||||||
goto out;
|
goto out_free_skb;
|
||||||
break;
|
break;
|
||||||
case ARPHRD_ETHER:
|
case ARPHRD_ETHER:
|
||||||
case ARPHRD_FDDI:
|
case ARPHRD_FDDI:
|
||||||
|
@ -690,17 +690,17 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
|
if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
|
||||||
arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
|
arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
|
||||||
arp->ar_pro != htons(ETH_P_IP))
|
arp->ar_pro != htons(ETH_P_IP))
|
||||||
goto out;
|
goto out_free_skb;
|
||||||
break;
|
break;
|
||||||
case ARPHRD_AX25:
|
case ARPHRD_AX25:
|
||||||
if (arp->ar_pro != htons(AX25_P_IP) ||
|
if (arp->ar_pro != htons(AX25_P_IP) ||
|
||||||
arp->ar_hrd != htons(ARPHRD_AX25))
|
arp->ar_hrd != htons(ARPHRD_AX25))
|
||||||
goto out;
|
goto out_free_skb;
|
||||||
break;
|
break;
|
||||||
case ARPHRD_NETROM:
|
case ARPHRD_NETROM:
|
||||||
if (arp->ar_pro != htons(AX25_P_IP) ||
|
if (arp->ar_pro != htons(AX25_P_IP) ||
|
||||||
arp->ar_hrd != htons(ARPHRD_NETROM))
|
arp->ar_hrd != htons(ARPHRD_NETROM))
|
||||||
goto out;
|
goto out_free_skb;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,7 +708,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
|
|
||||||
if (arp->ar_op != htons(ARPOP_REPLY) &&
|
if (arp->ar_op != htons(ARPOP_REPLY) &&
|
||||||
arp->ar_op != htons(ARPOP_REQUEST))
|
arp->ar_op != htons(ARPOP_REQUEST))
|
||||||
goto out;
|
goto out_free_skb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extract fields
|
* Extract fields
|
||||||
|
@ -733,7 +733,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
*/
|
*/
|
||||||
if (ipv4_is_multicast(tip) ||
|
if (ipv4_is_multicast(tip) ||
|
||||||
(!IN_DEV_ROUTE_LOCALNET(in_dev) && ipv4_is_loopback(tip)))
|
(!IN_DEV_ROUTE_LOCALNET(in_dev) && ipv4_is_loopback(tip)))
|
||||||
goto out;
|
goto out_free_skb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For some 802.11 wireless deployments (and possibly other networks),
|
* For some 802.11 wireless deployments (and possibly other networks),
|
||||||
|
@ -741,7 +741,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
* and thus should not be accepted.
|
* and thus should not be accepted.
|
||||||
*/
|
*/
|
||||||
if (sip == tip && IN_DEV_ORCONF(in_dev, DROP_GRATUITOUS_ARP))
|
if (sip == tip && IN_DEV_ORCONF(in_dev, DROP_GRATUITOUS_ARP))
|
||||||
goto out;
|
goto out_free_skb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special case: We must set Frame Relay source Q.922 address
|
* Special case: We must set Frame Relay source Q.922 address
|
||||||
|
@ -778,7 +778,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
!arp_ignore(in_dev, sip, tip))
|
!arp_ignore(in_dev, sip, tip))
|
||||||
arp_send_dst(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip,
|
arp_send_dst(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip,
|
||||||
sha, dev->dev_addr, sha, reply_dst);
|
sha, dev->dev_addr, sha, reply_dst);
|
||||||
goto out;
|
goto out_consume_skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arp->ar_op == htons(ARPOP_REQUEST) &&
|
if (arp->ar_op == htons(ARPOP_REQUEST) &&
|
||||||
|
@ -803,7 +803,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto out;
|
goto out_consume_skb;
|
||||||
} else if (IN_DEV_FORWARD(in_dev)) {
|
} else if (IN_DEV_FORWARD(in_dev)) {
|
||||||
if (addr_type == RTN_UNICAST &&
|
if (addr_type == RTN_UNICAST &&
|
||||||
(arp_fwd_proxy(in_dev, dev, rt) ||
|
(arp_fwd_proxy(in_dev, dev, rt) ||
|
||||||
|
@ -826,7 +826,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
in_dev->arp_parms, skb);
|
in_dev->arp_parms, skb);
|
||||||
goto out_free_dst;
|
goto out_free_dst;
|
||||||
}
|
}
|
||||||
goto out;
|
goto out_consume_skb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -876,11 +876,16 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out_consume_skb:
|
||||||
consume_skb(skb);
|
consume_skb(skb);
|
||||||
|
|
||||||
out_free_dst:
|
out_free_dst:
|
||||||
dst_release(reply_dst);
|
dst_release(reply_dst);
|
||||||
return 0;
|
return NET_RX_SUCCESS;
|
||||||
|
|
||||||
|
out_free_skb:
|
||||||
|
kfree_skb(skb);
|
||||||
|
return NET_RX_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parp_redo(struct sk_buff *skb)
|
static void parp_redo(struct sk_buff *skb)
|
||||||
|
@ -924,11 +929,11 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||||
|
|
||||||
consumeskb:
|
consumeskb:
|
||||||
consume_skb(skb);
|
consume_skb(skb);
|
||||||
return 0;
|
return NET_RX_SUCCESS;
|
||||||
freeskb:
|
freeskb:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
out_of_mem:
|
out_of_mem:
|
||||||
return 0;
|
return NET_RX_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue