aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/xfrm4_mode_beet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/xfrm4_mode_beet.c')
-rw-r--r--net/ipv4/xfrm4_mode_beet.c37
1 files changed, 17 insertions, 20 deletions
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index d419e15d9803..a73e710740c2 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -29,20 +29,21 @@
29 */ 29 */
30static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) 30static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
31{ 31{
32 struct iphdr *iph, *top_iph = NULL; 32 struct iphdr *iph, *top_iph;
33 int hdrlen, optlen; 33 int hdrlen, optlen;
34 34
35 iph = skb->nh.iph; 35 iph = ip_hdr(skb);
36 skb->h.ipiph = iph; 36 skb->transport_header = skb->network_header;
37 37
38 hdrlen = 0; 38 hdrlen = 0;
39 optlen = iph->ihl * 4 - sizeof(*iph); 39 optlen = iph->ihl * 4 - sizeof(*iph);
40 if (unlikely(optlen)) 40 if (unlikely(optlen))
41 hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4); 41 hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
42 42
43 skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen); 43 skb_push(skb, x->props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);
44 top_iph = skb->nh.iph; 44 skb_reset_network_header(skb);
45 skb->h.raw += sizeof(*iph) - hdrlen; 45 top_iph = ip_hdr(skb);
46 skb->transport_header += sizeof(*iph) - hdrlen;
46 47
47 memmove(top_iph, iph, sizeof(*iph)); 48 memmove(top_iph, iph, sizeof(*iph));
48 if (unlikely(optlen)) { 49 if (unlikely(optlen)) {
@@ -50,7 +51,7 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
50 51
51 BUG_ON(optlen < 0); 52 BUG_ON(optlen < 0);
52 53
53 ph = (struct ip_beet_phdr *)skb->h.raw; 54 ph = (struct ip_beet_phdr *)skb_transport_header(skb);
54 ph->padlen = 4 - (optlen & 4); 55 ph->padlen = 4 - (optlen & 4);
55 ph->hdrlen = optlen / 8; 56 ph->hdrlen = optlen / 8;
56 ph->nexthdr = top_iph->protocol; 57 ph->nexthdr = top_iph->protocol;
@@ -69,20 +70,18 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
69 70
70static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) 71static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
71{ 72{
72 struct iphdr *iph = skb->nh.iph; 73 struct iphdr *iph = ip_hdr(skb);
73 int phlen = 0; 74 int phlen = 0;
74 int optlen = 0; 75 int optlen = 0;
75 __u8 ph_nexthdr = 0, protocol = 0; 76 u8 ph_nexthdr = 0;
76 int err = -EINVAL; 77 int err = -EINVAL;
77 78
78 protocol = iph->protocol;
79
80 if (unlikely(iph->protocol == IPPROTO_BEETPH)) { 79 if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
81 struct ip_beet_phdr *ph; 80 struct ip_beet_phdr *ph;
82 81
83 if (!pskb_may_pull(skb, sizeof(*ph))) 82 if (!pskb_may_pull(skb, sizeof(*ph)))
84 goto out; 83 goto out;
85 ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1); 84 ph = (struct ip_beet_phdr *)(ipip_hdr(skb) + 1);
86 85
87 phlen = sizeof(*ph) + ph->padlen; 86 phlen = sizeof(*ph) + ph->padlen;
88 optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen); 87 optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);
@@ -96,22 +95,20 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
96 ph_nexthdr = ph->nexthdr; 95 ph_nexthdr = ph->nexthdr;
97 } 96 }
98 97
99 skb->nh.raw = skb->data + (phlen - sizeof(*iph)); 98 skb_set_network_header(skb, phlen - sizeof(*iph));
100 memmove(skb->nh.raw, iph, sizeof(*iph)); 99 memmove(skb_network_header(skb), iph, sizeof(*iph));
101 skb->h.raw = skb->data + (phlen + optlen); 100 skb_set_transport_header(skb, phlen + optlen);
102 skb->data = skb->h.raw; 101 skb->data = skb_transport_header(skb);
103 102
104 iph = skb->nh.iph; 103 iph = ip_hdr(skb);
105 iph->ihl = (sizeof(*iph) + optlen) / 4; 104 iph->ihl = (sizeof(*iph) + optlen) / 4;
106 iph->tot_len = htons(skb->len + iph->ihl * 4); 105 iph->tot_len = htons(skb->len + iph->ihl * 4);
107 iph->daddr = x->sel.daddr.a4; 106 iph->daddr = x->sel.daddr.a4;
108 iph->saddr = x->sel.saddr.a4; 107 iph->saddr = x->sel.saddr.a4;
109 if (ph_nexthdr) 108 if (ph_nexthdr)
110 iph->protocol = ph_nexthdr; 109 iph->protocol = ph_nexthdr;
111 else
112 iph->protocol = protocol;
113 iph->check = 0; 110 iph->check = 0;
114 iph->check = ip_fast_csum(skb->nh.raw, iph->ihl); 111 iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
115 err = 0; 112 err = 0;
116out: 113out:
117 return err; 114 return err;