diff options
Diffstat (limited to 'net/xfrm/xfrm_input.c')
-rw-r--r-- | net/xfrm/xfrm_input.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 8624cbdb2a1e..493243fc5fe5 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -119,8 +119,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
119 | struct sec_path *sp; | 119 | struct sec_path *sp; |
120 | 120 | ||
121 | sp = secpath_dup(skb->sp); | 121 | sp = secpath_dup(skb->sp); |
122 | if (!sp) | 122 | if (!sp) { |
123 | XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); | ||
123 | goto drop; | 124 | goto drop; |
125 | } | ||
124 | if (skb->sp) | 126 | if (skb->sp) |
125 | secpath_put(skb->sp); | 127 | secpath_put(skb->sp); |
126 | skb->sp = sp; | 128 | skb->sp = sp; |
@@ -131,31 +133,45 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
131 | family = XFRM_SPI_SKB_CB(skb)->family; | 133 | family = XFRM_SPI_SKB_CB(skb)->family; |
132 | 134 | ||
133 | seq = 0; | 135 | seq = 0; |
134 | if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) | 136 | if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) { |
137 | XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); | ||
135 | goto drop; | 138 | goto drop; |
139 | } | ||
136 | 140 | ||
137 | do { | 141 | do { |
138 | if (skb->sp->len == XFRM_MAX_DEPTH) | 142 | if (skb->sp->len == XFRM_MAX_DEPTH) { |
143 | XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); | ||
139 | goto drop; | 144 | goto drop; |
145 | } | ||
140 | 146 | ||
141 | x = xfrm_state_lookup(daddr, spi, nexthdr, family); | 147 | x = xfrm_state_lookup(daddr, spi, nexthdr, family); |
142 | if (x == NULL) | 148 | if (x == NULL) { |
149 | XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); | ||
143 | goto drop; | 150 | goto drop; |
151 | } | ||
144 | 152 | ||
145 | skb->sp->xvec[skb->sp->len++] = x; | 153 | skb->sp->xvec[skb->sp->len++] = x; |
146 | 154 | ||
147 | spin_lock(&x->lock); | 155 | spin_lock(&x->lock); |
148 | if (unlikely(x->km.state != XFRM_STATE_VALID)) | 156 | if (unlikely(x->km.state != XFRM_STATE_VALID)) { |
157 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); | ||
149 | goto drop_unlock; | 158 | goto drop_unlock; |
159 | } | ||
150 | 160 | ||
151 | if ((x->encap ? x->encap->encap_type : 0) != encap_type) | 161 | if ((x->encap ? x->encap->encap_type : 0) != encap_type) { |
162 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); | ||
152 | goto drop_unlock; | 163 | goto drop_unlock; |
164 | } | ||
153 | 165 | ||
154 | if (x->props.replay_window && xfrm_replay_check(x, seq)) | 166 | if (x->props.replay_window && xfrm_replay_check(x, seq)) { |
167 | XFRM_INC_STATS(LINUX_MIB_XFRMINSEQOUTOFWINDOW); | ||
155 | goto drop_unlock; | 168 | goto drop_unlock; |
169 | } | ||
156 | 170 | ||
157 | if (xfrm_state_check_expire(x)) | 171 | if (xfrm_state_check_expire(x)) { |
172 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED); | ||
158 | goto drop_unlock; | 173 | goto drop_unlock; |
174 | } | ||
159 | 175 | ||
160 | spin_unlock(&x->lock); | 176 | spin_unlock(&x->lock); |
161 | 177 | ||
@@ -171,6 +187,7 @@ resume: | |||
171 | if (nexthdr <= 0) { | 187 | if (nexthdr <= 0) { |
172 | if (nexthdr == -EBADMSG) | 188 | if (nexthdr == -EBADMSG) |
173 | x->stats.integrity_failed++; | 189 | x->stats.integrity_failed++; |
190 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR); | ||
174 | goto drop_unlock; | 191 | goto drop_unlock; |
175 | } | 192 | } |
176 | 193 | ||
@@ -187,8 +204,10 @@ resume: | |||
187 | 204 | ||
188 | XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; | 205 | XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; |
189 | 206 | ||
190 | if (x->inner_mode->input(x, skb)) | 207 | if (x->inner_mode->input(x, skb)) { |
208 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR); | ||
191 | goto drop; | 209 | goto drop; |
210 | } | ||
192 | 211 | ||
193 | if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { | 212 | if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { |
194 | decaps = 1; | 213 | decaps = 1; |
@@ -203,8 +222,10 @@ resume: | |||
203 | family = x->outer_mode->afinfo->family; | 222 | family = x->outer_mode->afinfo->family; |
204 | 223 | ||
205 | err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); | 224 | err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); |
206 | if (err < 0) | 225 | if (err < 0) { |
226 | XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); | ||
207 | goto drop; | 227 | goto drop; |
228 | } | ||
208 | } while (!err); | 229 | } while (!err); |
209 | 230 | ||
210 | nf_reset(skb); | 231 | nf_reset(skb); |