aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/xfrm4_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/xfrm4_input.c')
-rw-r--r--net/ipv4/xfrm4_input.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 850d919591d1..3e174c83bfe7 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -37,8 +37,6 @@ static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
37{ 37{
38 switch (nexthdr) { 38 switch (nexthdr) {
39 case IPPROTO_IPIP: 39 case IPPROTO_IPIP:
40 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
41 return -EINVAL;
42 *spi = skb->nh.iph->saddr; 40 *spi = skb->nh.iph->saddr;
43 *seq = 0; 41 *seq = 0;
44 return 0; 42 return 0;
@@ -68,7 +66,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
68{ 66{
69 int err; 67 int err;
70 u32 spi, seq; 68 u32 spi, seq;
71 struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; 69 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
72 struct xfrm_state *x; 70 struct xfrm_state *x;
73 int xfrm_nr = 0; 71 int xfrm_nr = 0;
74 int decaps = 0; 72 int decaps = 0;
@@ -90,14 +88,16 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
90 if (unlikely(x->km.state != XFRM_STATE_VALID)) 88 if (unlikely(x->km.state != XFRM_STATE_VALID))
91 goto drop_unlock; 89 goto drop_unlock;
92 90
91 if ((x->encap ? x->encap->encap_type : 0) != encap_type)
92 goto drop_unlock;
93
93 if (x->props.replay_window && xfrm_replay_check(x, seq)) 94 if (x->props.replay_window && xfrm_replay_check(x, seq))
94 goto drop_unlock; 95 goto drop_unlock;
95 96
96 if (xfrm_state_check_expire(x)) 97 if (xfrm_state_check_expire(x))
97 goto drop_unlock; 98 goto drop_unlock;
98 99
99 xfrm_vec[xfrm_nr].decap.decap_type = encap_type; 100 if (x->type->input(x, skb))
100 if (x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb))
101 goto drop_unlock; 101 goto drop_unlock;
102 102
103 /* only the first xfrm gets the encap type */ 103 /* only the first xfrm gets the encap type */
@@ -111,7 +111,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
111 111
112 spin_unlock(&x->lock); 112 spin_unlock(&x->lock);
113 113
114 xfrm_vec[xfrm_nr++].xvec = x; 114 xfrm_vec[xfrm_nr++] = x;
115 115
116 iph = skb->nh.iph; 116 iph = skb->nh.iph;
117 117
@@ -153,7 +153,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
153 if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) 153 if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
154 goto drop; 154 goto drop;
155 155
156 memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state)); 156 memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
157 xfrm_nr * sizeof(xfrm_vec[0]));
157 skb->sp->len += xfrm_nr; 158 skb->sp->len += xfrm_nr;
158 159
159 nf_reset(skb); 160 nf_reset(skb);
@@ -184,7 +185,7 @@ drop_unlock:
184 xfrm_state_put(x); 185 xfrm_state_put(x);
185drop: 186drop:
186 while (--xfrm_nr >= 0) 187 while (--xfrm_nr >= 0)
187 xfrm_state_put(xfrm_vec[xfrm_nr].xvec); 188 xfrm_state_put(xfrm_vec[xfrm_nr]);
188 189
189 kfree_skb(skb); 190 kfree_skb(skb);
190 return 0; 191 return 0;