aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2014-03-11 09:56:05 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-13 15:16:29 -0400
commitf9708b4302733ca023722fddcf9f501a3cb8c98b (patch)
treeb87492efee7b5c7046c29a1422c3159b843ba0c1 /net/core
parent50240dc37e5363cc8e8de34d931392263e38ca7d (diff)
consolidate duplicate code is skb_checksum_setup() helpers
consolidate duplicate code is skb_checksum_setup() helpers Realizing that the skb_maybe_pull_tail() calls in the IP-protocol specific portions of both helpers are terminal ones (i.e. no further pulls are expected), their maximum size to be pulled can be made match their minimal size needed, thus making the code identical and hence possible to be moved into another helper. Signed-off-by: Jan Beulich <jbeulich@suse.com> Cc: Paul Durrant <paul.durrant@citrix.com> Cc: David Miller <davem@davemloft.net> Cc: Eric Dumazet <edumazet@google.com> Reviewed-by: Paul Durrant <paul.durrant@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/skbuff.c140
1 files changed, 50 insertions, 90 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 465a01c97c76..8b52dfc56c0e 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3566,15 +3566,47 @@ static int skb_maybe_pull_tail(struct sk_buff *skb, unsigned int len,
3566 return 0; 3566 return 0;
3567} 3567}
3568 3568
3569#define MAX_TCP_HDR_LEN (15 * 4)
3570
3571static __sum16 *skb_checksum_setup_ip(struct sk_buff *skb,
3572 typeof(IPPROTO_IP) proto,
3573 unsigned int off)
3574{
3575 switch (proto) {
3576 int err;
3577
3578 case IPPROTO_TCP:
3579 err = skb_maybe_pull_tail(skb, off + sizeof(struct tcphdr),
3580 off + MAX_TCP_HDR_LEN);
3581 if (!err && !skb_partial_csum_set(skb, off,
3582 offsetof(struct tcphdr,
3583 check)))
3584 err = -EPROTO;
3585 return err ? ERR_PTR(err) : &tcp_hdr(skb)->check;
3586
3587 case IPPROTO_UDP:
3588 err = skb_maybe_pull_tail(skb, off + sizeof(struct udphdr),
3589 off + sizeof(struct udphdr));
3590 if (!err && !skb_partial_csum_set(skb, off,
3591 offsetof(struct udphdr,
3592 check)))
3593 err = -EPROTO;
3594 return err ? ERR_PTR(err) : &udp_hdr(skb)->check;
3595 }
3596
3597 return ERR_PTR(-EPROTO);
3598}
3599
3569/* This value should be large enough to cover a tagged ethernet header plus 3600/* This value should be large enough to cover a tagged ethernet header plus
3570 * maximally sized IP and TCP or UDP headers. 3601 * maximally sized IP and TCP or UDP headers.
3571 */ 3602 */
3572#define MAX_IP_HDR_LEN 128 3603#define MAX_IP_HDR_LEN 128
3573 3604
3574static int skb_checksum_setup_ip(struct sk_buff *skb, bool recalculate) 3605static int skb_checksum_setup_ipv4(struct sk_buff *skb, bool recalculate)
3575{ 3606{
3576 unsigned int off; 3607 unsigned int off;
3577 bool fragment; 3608 bool fragment;
3609 __sum16 *csum;
3578 int err; 3610 int err;
3579 3611
3580 fragment = false; 3612 fragment = false;
@@ -3595,51 +3627,15 @@ static int skb_checksum_setup_ip(struct sk_buff *skb, bool recalculate)
3595 if (fragment) 3627 if (fragment)
3596 goto out; 3628 goto out;
3597 3629
3598 switch (ip_hdr(skb)->protocol) { 3630 csum = skb_checksum_setup_ip(skb, ip_hdr(skb)->protocol, off);
3599 case IPPROTO_TCP: 3631 if (IS_ERR(csum))
3600 err = skb_maybe_pull_tail(skb, 3632 return PTR_ERR(csum);
3601 off + sizeof(struct tcphdr),
3602 MAX_IP_HDR_LEN);
3603 if (err < 0)
3604 goto out;
3605
3606 if (!skb_partial_csum_set(skb, off,
3607 offsetof(struct tcphdr, check))) {
3608 err = -EPROTO;
3609 goto out;
3610 }
3611
3612 if (recalculate)
3613 tcp_hdr(skb)->check =
3614 ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
3615 ip_hdr(skb)->daddr,
3616 skb->len - off,
3617 IPPROTO_TCP, 0);
3618 break;
3619 case IPPROTO_UDP:
3620 err = skb_maybe_pull_tail(skb,
3621 off + sizeof(struct udphdr),
3622 MAX_IP_HDR_LEN);
3623 if (err < 0)
3624 goto out;
3625
3626 if (!skb_partial_csum_set(skb, off,
3627 offsetof(struct udphdr, check))) {
3628 err = -EPROTO;
3629 goto out;
3630 }
3631
3632 if (recalculate)
3633 udp_hdr(skb)->check =
3634 ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
3635 ip_hdr(skb)->daddr,
3636 skb->len - off,
3637 IPPROTO_UDP, 0);
3638 break;
3639 default:
3640 goto out;
3641 }
3642 3633
3634 if (recalculate)
3635 *csum = ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
3636 ip_hdr(skb)->daddr,
3637 skb->len - off,
3638 ip_hdr(skb)->protocol, 0);
3643 err = 0; 3639 err = 0;
3644 3640
3645out: 3641out:
@@ -3662,6 +3658,7 @@ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
3662 unsigned int len; 3658 unsigned int len;
3663 bool fragment; 3659 bool fragment;
3664 bool done; 3660 bool done;
3661 __sum16 *csum;
3665 3662
3666 fragment = false; 3663 fragment = false;
3667 done = false; 3664 done = false;
@@ -3739,51 +3736,14 @@ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
3739 if (!done || fragment) 3736 if (!done || fragment)
3740 goto out; 3737 goto out;
3741 3738
3742 switch (nexthdr) { 3739 csum = skb_checksum_setup_ip(skb, nexthdr, off);
3743 case IPPROTO_TCP: 3740 if (IS_ERR(csum))
3744 err = skb_maybe_pull_tail(skb, 3741 return PTR_ERR(csum);
3745 off + sizeof(struct tcphdr),
3746 MAX_IPV6_HDR_LEN);
3747 if (err < 0)
3748 goto out;
3749
3750 if (!skb_partial_csum_set(skb, off,
3751 offsetof(struct tcphdr, check))) {
3752 err = -EPROTO;
3753 goto out;
3754 }
3755
3756 if (recalculate)
3757 tcp_hdr(skb)->check =
3758 ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
3759 &ipv6_hdr(skb)->daddr,
3760 skb->len - off,
3761 IPPROTO_TCP, 0);
3762 break;
3763 case IPPROTO_UDP:
3764 err = skb_maybe_pull_tail(skb,
3765 off + sizeof(struct udphdr),
3766 MAX_IPV6_HDR_LEN);
3767 if (err < 0)
3768 goto out;
3769
3770 if (!skb_partial_csum_set(skb, off,
3771 offsetof(struct udphdr, check))) {
3772 err = -EPROTO;
3773 goto out;
3774 }
3775
3776 if (recalculate)
3777 udp_hdr(skb)->check =
3778 ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
3779 &ipv6_hdr(skb)->daddr,
3780 skb->len - off,
3781 IPPROTO_UDP, 0);
3782 break;
3783 default:
3784 goto out;
3785 }
3786 3742
3743 if (recalculate)
3744 *csum = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
3745 &ipv6_hdr(skb)->daddr,
3746 skb->len - off, nexthdr, 0);
3787 err = 0; 3747 err = 0;
3788 3748
3789out: 3749out:
@@ -3801,7 +3761,7 @@ int skb_checksum_setup(struct sk_buff *skb, bool recalculate)
3801 3761
3802 switch (skb->protocol) { 3762 switch (skb->protocol) {
3803 case htons(ETH_P_IP): 3763 case htons(ETH_P_IP):
3804 err = skb_checksum_setup_ip(skb, recalculate); 3764 err = skb_checksum_setup_ipv4(skb, recalculate);
3805 break; 3765 break;
3806 3766
3807 case htons(ETH_P_IPV6): 3767 case htons(ETH_P_IPV6):