[NET]: Replace skb_pull/skb_postpull_rcsum with skb_pull_rcsum
We're now starting to have quite a number of places that do skb_pull followed immediately by an skb_postpull_rcsum. We can merge these two operations into one function with skb_pull_rcsum. This makes sense since most pull operations on receive skb's need to update the checksum. I've decided to make this out-of-line since it is fairly big and the fast path where hardware checksums are enabled need to call csum_partial anyway. Since this is a brand new function we get to add an extra check on the len argument. As it is most callers of skb_pull ignore its return value which essentially means that there is no check on the len argument. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
ecba320f2e
commit
cbb042f9e1
@ -1691,8 +1691,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
|
|||||||
|| ppp->npmode[npi] != NPMODE_PASS) {
|
|| ppp->npmode[npi] != NPMODE_PASS) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
} else {
|
} else {
|
||||||
skb_pull(skb, 2); /* chop off protocol */
|
/* chop off protocol */
|
||||||
skb_postpull_rcsum(skb, skb->data - 2, 2);
|
skb_pull_rcsum(skb, 2);
|
||||||
skb->dev = ppp->dev;
|
skb->dev = ppp->dev;
|
||||||
skb->protocol = htons(npindex_to_ethertype[npi]);
|
skb->protocol = htons(npindex_to_ethertype[npi]);
|
||||||
skb->mac.raw = skb->data;
|
skb->mac.raw = skb->data;
|
||||||
|
@ -337,8 +337,7 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
|
|||||||
if (sk->sk_state & PPPOX_BOUND) {
|
if (sk->sk_state & PPPOX_BOUND) {
|
||||||
struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw;
|
struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw;
|
||||||
int len = ntohs(ph->length);
|
int len = ntohs(ph->length);
|
||||||
skb_pull(skb, sizeof(struct pppoe_hdr));
|
skb_pull_rcsum(skb, sizeof(struct pppoe_hdr));
|
||||||
skb_postpull_rcsum(skb, ph, sizeof(*ph));
|
|
||||||
if (pskb_trim_rcsum(skb, len))
|
if (pskb_trim_rcsum(skb, len))
|
||||||
goto abort_kfree;
|
goto abort_kfree;
|
||||||
|
|
||||||
|
@ -1159,12 +1159,14 @@ static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void skb_postpull_rcsum(struct sk_buff *skb,
|
static inline void skb_postpull_rcsum(struct sk_buff *skb,
|
||||||
const void *start, int len)
|
const void *start, unsigned int len)
|
||||||
{
|
{
|
||||||
if (skb->ip_summed == CHECKSUM_HW)
|
if (skb->ip_summed == CHECKSUM_HW)
|
||||||
skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0));
|
skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pskb_trim_rcsum - trim received skb and update checksum
|
* pskb_trim_rcsum - trim received skb and update checksum
|
||||||
* @skb: buffer to trim
|
* @skb: buffer to trim
|
||||||
|
@ -61,8 +61,7 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
|
|||||||
/* Pass the frame on. */
|
/* Pass the frame on. */
|
||||||
u8 *hdr = skb->data;
|
u8 *hdr = skb->data;
|
||||||
skb->h.raw += 5;
|
skb->h.raw += 5;
|
||||||
skb_pull(skb, 5);
|
skb_pull_rcsum(skb, 5);
|
||||||
skb_postpull_rcsum(skb, hdr, 5);
|
|
||||||
rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
|
rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
|
||||||
} else {
|
} else {
|
||||||
skb->sk = NULL;
|
skb->sk = NULL;
|
||||||
|
@ -163,10 +163,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
|||||||
stats->rx_packets++;
|
stats->rx_packets++;
|
||||||
stats->rx_bytes += skb->len;
|
stats->rx_bytes += skb->len;
|
||||||
|
|
||||||
skb_pull(skb, VLAN_HLEN); /* take off the VLAN header (4 bytes currently) */
|
/* Take off the VLAN header (4 bytes currently) */
|
||||||
|
skb_pull_rcsum(skb, VLAN_HLEN);
|
||||||
/* Need to correct hardware checksum */
|
|
||||||
skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
|
|
||||||
|
|
||||||
/* Ok, lets check to make sure the device (dev) we
|
/* Ok, lets check to make sure the device (dev) we
|
||||||
* came in on is what this VLAN is attached to.
|
* came in on is what this VLAN is attached to.
|
||||||
|
@ -425,8 +425,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
|||||||
|
|
||||||
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
||||||
u8 *vhdr = skb->data;
|
u8 *vhdr = skb->data;
|
||||||
skb_pull(skb, VLAN_HLEN);
|
skb_pull_rcsum(skb, VLAN_HLEN);
|
||||||
skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
|
|
||||||
skb->nh.raw += VLAN_HLEN;
|
skb->nh.raw += VLAN_HLEN;
|
||||||
}
|
}
|
||||||
return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
|
return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
|
||||||
@ -444,8 +443,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
|||||||
|
|
||||||
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
||||||
u8 *vhdr = skb->data;
|
u8 *vhdr = skb->data;
|
||||||
skb_pull(skb, VLAN_HLEN);
|
skb_pull_rcsum(skb, VLAN_HLEN);
|
||||||
skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
|
|
||||||
skb->nh.raw += VLAN_HLEN;
|
skb->nh.raw += VLAN_HLEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1795,6 +1795,27 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* skb_pull_rcsum - pull skb and update receive checksum
|
||||||
|
* @skb: buffer to update
|
||||||
|
* @start: start of data before pull
|
||||||
|
* @len: length of data pulled
|
||||||
|
*
|
||||||
|
* This function performs an skb_pull on the packet and updates
|
||||||
|
* update the CHECKSUM_HW checksum. It should be used on receive
|
||||||
|
* path processing instead of skb_pull unless you know that the
|
||||||
|
* checksum difference is zero (e.g., a valid IP header) or you
|
||||||
|
* are setting ip_summed to CHECKSUM_NONE.
|
||||||
|
*/
|
||||||
|
unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
|
||||||
|
{
|
||||||
|
BUG_ON(len > skb->len);
|
||||||
|
skb->len -= len;
|
||||||
|
BUG_ON(skb->len < skb->data_len);
|
||||||
|
skb_postpull_rcsum(skb, skb->data, len);
|
||||||
|
return skb->data += len;
|
||||||
|
}
|
||||||
|
|
||||||
void __init skb_init(void)
|
void __init skb_init(void)
|
||||||
{
|
{
|
||||||
skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
|
skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
|
||||||
|
Reference in New Issue
Block a user