0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/export.h>
0010 #include <net/xfrm.h>
0011
0012 u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq)
0013 {
0014 u32 seq, seq_hi, bottom;
0015 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0016
0017 if (!(x->props.flags & XFRM_STATE_ESN))
0018 return 0;
0019
0020 seq = ntohl(net_seq);
0021 seq_hi = replay_esn->seq_hi;
0022 bottom = replay_esn->seq - replay_esn->replay_window + 1;
0023
0024 if (likely(replay_esn->seq >= replay_esn->replay_window - 1)) {
0025
0026 if (unlikely(seq < bottom))
0027 seq_hi++;
0028 } else {
0029
0030 if (unlikely(seq >= bottom))
0031 seq_hi--;
0032 }
0033
0034 return seq_hi;
0035 }
0036 EXPORT_SYMBOL(xfrm_replay_seqhi);
0037
0038 static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event);
0039 static void xfrm_replay_notify_esn(struct xfrm_state *x, int event);
0040
0041 void xfrm_replay_notify(struct xfrm_state *x, int event)
0042 {
0043 struct km_event c;
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 switch (x->repl_mode) {
0055 case XFRM_REPLAY_MODE_LEGACY:
0056 break;
0057 case XFRM_REPLAY_MODE_BMP:
0058 xfrm_replay_notify_bmp(x, event);
0059 return;
0060 case XFRM_REPLAY_MODE_ESN:
0061 xfrm_replay_notify_esn(x, event);
0062 return;
0063 }
0064
0065 switch (event) {
0066 case XFRM_REPLAY_UPDATE:
0067 if (!x->replay_maxdiff ||
0068 ((x->replay.seq - x->preplay.seq < x->replay_maxdiff) &&
0069 (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff))) {
0070 if (x->xflags & XFRM_TIME_DEFER)
0071 event = XFRM_REPLAY_TIMEOUT;
0072 else
0073 return;
0074 }
0075
0076 break;
0077
0078 case XFRM_REPLAY_TIMEOUT:
0079 if (memcmp(&x->replay, &x->preplay,
0080 sizeof(struct xfrm_replay_state)) == 0) {
0081 x->xflags |= XFRM_TIME_DEFER;
0082 return;
0083 }
0084
0085 break;
0086 }
0087
0088 memcpy(&x->preplay, &x->replay, sizeof(struct xfrm_replay_state));
0089 c.event = XFRM_MSG_NEWAE;
0090 c.data.aevent = event;
0091 km_state_notify(x, &c);
0092
0093 if (x->replay_maxage &&
0094 !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
0095 x->xflags &= ~XFRM_TIME_DEFER;
0096 }
0097
0098 static int __xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
0099 {
0100 int err = 0;
0101 struct net *net = xs_net(x);
0102
0103 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
0104 XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq;
0105 XFRM_SKB_CB(skb)->seq.output.hi = 0;
0106 if (unlikely(x->replay.oseq == 0) &&
0107 !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
0108 x->replay.oseq--;
0109 xfrm_audit_state_replay_overflow(x, skb);
0110 err = -EOVERFLOW;
0111
0112 return err;
0113 }
0114 if (xfrm_aevent_is_on(net))
0115 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0116 }
0117
0118 return err;
0119 }
0120
0121 static int xfrm_replay_check_legacy(struct xfrm_state *x,
0122 struct sk_buff *skb, __be32 net_seq)
0123 {
0124 u32 diff;
0125 u32 seq = ntohl(net_seq);
0126
0127 if (!x->props.replay_window)
0128 return 0;
0129
0130 if (unlikely(seq == 0))
0131 goto err;
0132
0133 if (likely(seq > x->replay.seq))
0134 return 0;
0135
0136 diff = x->replay.seq - seq;
0137 if (diff >= x->props.replay_window) {
0138 x->stats.replay_window++;
0139 goto err;
0140 }
0141
0142 if (x->replay.bitmap & (1U << diff)) {
0143 x->stats.replay++;
0144 goto err;
0145 }
0146 return 0;
0147
0148 err:
0149 xfrm_audit_state_replay(x, skb, net_seq);
0150 return -EINVAL;
0151 }
0152
0153 static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq);
0154 static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq);
0155
0156 void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
0157 {
0158 u32 diff, seq;
0159
0160 switch (x->repl_mode) {
0161 case XFRM_REPLAY_MODE_LEGACY:
0162 break;
0163 case XFRM_REPLAY_MODE_BMP:
0164 return xfrm_replay_advance_bmp(x, net_seq);
0165 case XFRM_REPLAY_MODE_ESN:
0166 return xfrm_replay_advance_esn(x, net_seq);
0167 }
0168
0169 if (!x->props.replay_window)
0170 return;
0171
0172 seq = ntohl(net_seq);
0173 if (seq > x->replay.seq) {
0174 diff = seq - x->replay.seq;
0175 if (diff < x->props.replay_window)
0176 x->replay.bitmap = ((x->replay.bitmap) << diff) | 1;
0177 else
0178 x->replay.bitmap = 1;
0179 x->replay.seq = seq;
0180 } else {
0181 diff = x->replay.seq - seq;
0182 x->replay.bitmap |= (1U << diff);
0183 }
0184
0185 if (xfrm_aevent_is_on(xs_net(x)))
0186 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0187 }
0188
0189 static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
0190 {
0191 int err = 0;
0192 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0193 struct net *net = xs_net(x);
0194
0195 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
0196 XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq;
0197 XFRM_SKB_CB(skb)->seq.output.hi = 0;
0198 if (unlikely(replay_esn->oseq == 0) &&
0199 !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
0200 replay_esn->oseq--;
0201 xfrm_audit_state_replay_overflow(x, skb);
0202 err = -EOVERFLOW;
0203
0204 return err;
0205 }
0206 if (xfrm_aevent_is_on(net))
0207 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0208 }
0209
0210 return err;
0211 }
0212
0213 static int xfrm_replay_check_bmp(struct xfrm_state *x,
0214 struct sk_buff *skb, __be32 net_seq)
0215 {
0216 unsigned int bitnr, nr;
0217 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0218 u32 pos;
0219 u32 seq = ntohl(net_seq);
0220 u32 diff = replay_esn->seq - seq;
0221
0222 if (!replay_esn->replay_window)
0223 return 0;
0224
0225 if (unlikely(seq == 0))
0226 goto err;
0227
0228 if (likely(seq > replay_esn->seq))
0229 return 0;
0230
0231 if (diff >= replay_esn->replay_window) {
0232 x->stats.replay_window++;
0233 goto err;
0234 }
0235
0236 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
0237
0238 if (pos >= diff)
0239 bitnr = (pos - diff) % replay_esn->replay_window;
0240 else
0241 bitnr = replay_esn->replay_window - (diff - pos);
0242
0243 nr = bitnr >> 5;
0244 bitnr = bitnr & 0x1F;
0245 if (replay_esn->bmp[nr] & (1U << bitnr))
0246 goto err_replay;
0247
0248 return 0;
0249
0250 err_replay:
0251 x->stats.replay++;
0252 err:
0253 xfrm_audit_state_replay(x, skb, net_seq);
0254 return -EINVAL;
0255 }
0256
0257 static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq)
0258 {
0259 unsigned int bitnr, nr, i;
0260 u32 diff;
0261 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0262 u32 seq = ntohl(net_seq);
0263 u32 pos;
0264
0265 if (!replay_esn->replay_window)
0266 return;
0267
0268 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
0269
0270 if (seq > replay_esn->seq) {
0271 diff = seq - replay_esn->seq;
0272
0273 if (diff < replay_esn->replay_window) {
0274 for (i = 1; i < diff; i++) {
0275 bitnr = (pos + i) % replay_esn->replay_window;
0276 nr = bitnr >> 5;
0277 bitnr = bitnr & 0x1F;
0278 replay_esn->bmp[nr] &= ~(1U << bitnr);
0279 }
0280 } else {
0281 nr = (replay_esn->replay_window - 1) >> 5;
0282 for (i = 0; i <= nr; i++)
0283 replay_esn->bmp[i] = 0;
0284 }
0285
0286 bitnr = (pos + diff) % replay_esn->replay_window;
0287 replay_esn->seq = seq;
0288 } else {
0289 diff = replay_esn->seq - seq;
0290
0291 if (pos >= diff)
0292 bitnr = (pos - diff) % replay_esn->replay_window;
0293 else
0294 bitnr = replay_esn->replay_window - (diff - pos);
0295 }
0296
0297 nr = bitnr >> 5;
0298 bitnr = bitnr & 0x1F;
0299 replay_esn->bmp[nr] |= (1U << bitnr);
0300
0301 if (xfrm_aevent_is_on(xs_net(x)))
0302 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0303 }
0304
0305 static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
0306 {
0307 struct km_event c;
0308 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0309 struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn;
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321 switch (event) {
0322 case XFRM_REPLAY_UPDATE:
0323 if (!x->replay_maxdiff ||
0324 ((replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) &&
0325 (replay_esn->oseq - preplay_esn->oseq
0326 < x->replay_maxdiff))) {
0327 if (x->xflags & XFRM_TIME_DEFER)
0328 event = XFRM_REPLAY_TIMEOUT;
0329 else
0330 return;
0331 }
0332
0333 break;
0334
0335 case XFRM_REPLAY_TIMEOUT:
0336 if (memcmp(x->replay_esn, x->preplay_esn,
0337 xfrm_replay_state_esn_len(replay_esn)) == 0) {
0338 x->xflags |= XFRM_TIME_DEFER;
0339 return;
0340 }
0341
0342 break;
0343 }
0344
0345 memcpy(x->preplay_esn, x->replay_esn,
0346 xfrm_replay_state_esn_len(replay_esn));
0347 c.event = XFRM_MSG_NEWAE;
0348 c.data.aevent = event;
0349 km_state_notify(x, &c);
0350
0351 if (x->replay_maxage &&
0352 !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
0353 x->xflags &= ~XFRM_TIME_DEFER;
0354 }
0355
0356 static void xfrm_replay_notify_esn(struct xfrm_state *x, int event)
0357 {
0358 u32 seq_diff, oseq_diff;
0359 struct km_event c;
0360 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0361 struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn;
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373 switch (event) {
0374 case XFRM_REPLAY_UPDATE:
0375 if (x->replay_maxdiff) {
0376 if (replay_esn->seq_hi == preplay_esn->seq_hi)
0377 seq_diff = replay_esn->seq - preplay_esn->seq;
0378 else
0379 seq_diff = ~preplay_esn->seq + replay_esn->seq
0380 + 1;
0381
0382 if (replay_esn->oseq_hi == preplay_esn->oseq_hi)
0383 oseq_diff = replay_esn->oseq
0384 - preplay_esn->oseq;
0385 else
0386 oseq_diff = ~preplay_esn->oseq
0387 + replay_esn->oseq + 1;
0388
0389 if (seq_diff >= x->replay_maxdiff ||
0390 oseq_diff >= x->replay_maxdiff)
0391 break;
0392 }
0393
0394 if (x->xflags & XFRM_TIME_DEFER)
0395 event = XFRM_REPLAY_TIMEOUT;
0396 else
0397 return;
0398
0399 break;
0400
0401 case XFRM_REPLAY_TIMEOUT:
0402 if (memcmp(x->replay_esn, x->preplay_esn,
0403 xfrm_replay_state_esn_len(replay_esn)) == 0) {
0404 x->xflags |= XFRM_TIME_DEFER;
0405 return;
0406 }
0407
0408 break;
0409 }
0410
0411 memcpy(x->preplay_esn, x->replay_esn,
0412 xfrm_replay_state_esn_len(replay_esn));
0413 c.event = XFRM_MSG_NEWAE;
0414 c.data.aevent = event;
0415 km_state_notify(x, &c);
0416
0417 if (x->replay_maxage &&
0418 !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
0419 x->xflags &= ~XFRM_TIME_DEFER;
0420 }
0421
0422 static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb)
0423 {
0424 int err = 0;
0425 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0426 struct net *net = xs_net(x);
0427
0428 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
0429 XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq;
0430 XFRM_SKB_CB(skb)->seq.output.hi = replay_esn->oseq_hi;
0431
0432 if (unlikely(replay_esn->oseq == 0)) {
0433 XFRM_SKB_CB(skb)->seq.output.hi = ++replay_esn->oseq_hi;
0434
0435 if (replay_esn->oseq_hi == 0) {
0436 replay_esn->oseq--;
0437 replay_esn->oseq_hi--;
0438 xfrm_audit_state_replay_overflow(x, skb);
0439 err = -EOVERFLOW;
0440
0441 return err;
0442 }
0443 }
0444 if (xfrm_aevent_is_on(net))
0445 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0446 }
0447
0448 return err;
0449 }
0450
0451 static int xfrm_replay_check_esn(struct xfrm_state *x,
0452 struct sk_buff *skb, __be32 net_seq)
0453 {
0454 unsigned int bitnr, nr;
0455 u32 diff;
0456 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0457 u32 pos;
0458 u32 seq = ntohl(net_seq);
0459 u32 wsize = replay_esn->replay_window;
0460 u32 top = replay_esn->seq;
0461 u32 bottom = top - wsize + 1;
0462
0463 if (!wsize)
0464 return 0;
0465
0466 if (unlikely(seq == 0 && replay_esn->seq_hi == 0 &&
0467 (replay_esn->seq < replay_esn->replay_window - 1)))
0468 goto err;
0469
0470 diff = top - seq;
0471
0472 if (likely(top >= wsize - 1)) {
0473
0474 if (likely(seq > top) || seq < bottom)
0475 return 0;
0476 } else {
0477
0478 if (likely(seq > top && seq < bottom))
0479 return 0;
0480 if (seq >= bottom)
0481 diff = ~seq + top + 1;
0482 }
0483
0484 if (diff >= replay_esn->replay_window) {
0485 x->stats.replay_window++;
0486 goto err;
0487 }
0488
0489 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
0490
0491 if (pos >= diff)
0492 bitnr = (pos - diff) % replay_esn->replay_window;
0493 else
0494 bitnr = replay_esn->replay_window - (diff - pos);
0495
0496 nr = bitnr >> 5;
0497 bitnr = bitnr & 0x1F;
0498 if (replay_esn->bmp[nr] & (1U << bitnr))
0499 goto err_replay;
0500
0501 return 0;
0502
0503 err_replay:
0504 x->stats.replay++;
0505 err:
0506 xfrm_audit_state_replay(x, skb, net_seq);
0507 return -EINVAL;
0508 }
0509
0510 int xfrm_replay_check(struct xfrm_state *x,
0511 struct sk_buff *skb, __be32 net_seq)
0512 {
0513 switch (x->repl_mode) {
0514 case XFRM_REPLAY_MODE_LEGACY:
0515 break;
0516 case XFRM_REPLAY_MODE_BMP:
0517 return xfrm_replay_check_bmp(x, skb, net_seq);
0518 case XFRM_REPLAY_MODE_ESN:
0519 return xfrm_replay_check_esn(x, skb, net_seq);
0520 }
0521
0522 return xfrm_replay_check_legacy(x, skb, net_seq);
0523 }
0524
0525 static int xfrm_replay_recheck_esn(struct xfrm_state *x,
0526 struct sk_buff *skb, __be32 net_seq)
0527 {
0528 if (unlikely(XFRM_SKB_CB(skb)->seq.input.hi !=
0529 htonl(xfrm_replay_seqhi(x, net_seq)))) {
0530 x->stats.replay_window++;
0531 return -EINVAL;
0532 }
0533
0534 return xfrm_replay_check_esn(x, skb, net_seq);
0535 }
0536
0537 int xfrm_replay_recheck(struct xfrm_state *x,
0538 struct sk_buff *skb, __be32 net_seq)
0539 {
0540 switch (x->repl_mode) {
0541 case XFRM_REPLAY_MODE_LEGACY:
0542 break;
0543 case XFRM_REPLAY_MODE_BMP:
0544
0545 return xfrm_replay_check_bmp(x, skb, net_seq);
0546 case XFRM_REPLAY_MODE_ESN:
0547 return xfrm_replay_recheck_esn(x, skb, net_seq);
0548 }
0549
0550 return xfrm_replay_check_legacy(x, skb, net_seq);
0551 }
0552
0553 static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
0554 {
0555 unsigned int bitnr, nr, i;
0556 int wrap;
0557 u32 diff, pos, seq, seq_hi;
0558 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0559
0560 if (!replay_esn->replay_window)
0561 return;
0562
0563 seq = ntohl(net_seq);
0564 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
0565 seq_hi = xfrm_replay_seqhi(x, net_seq);
0566 wrap = seq_hi - replay_esn->seq_hi;
0567
0568 if ((!wrap && seq > replay_esn->seq) || wrap > 0) {
0569 if (likely(!wrap))
0570 diff = seq - replay_esn->seq;
0571 else
0572 diff = ~replay_esn->seq + seq + 1;
0573
0574 if (diff < replay_esn->replay_window) {
0575 for (i = 1; i < diff; i++) {
0576 bitnr = (pos + i) % replay_esn->replay_window;
0577 nr = bitnr >> 5;
0578 bitnr = bitnr & 0x1F;
0579 replay_esn->bmp[nr] &= ~(1U << bitnr);
0580 }
0581 } else {
0582 nr = (replay_esn->replay_window - 1) >> 5;
0583 for (i = 0; i <= nr; i++)
0584 replay_esn->bmp[i] = 0;
0585 }
0586
0587 bitnr = (pos + diff) % replay_esn->replay_window;
0588 replay_esn->seq = seq;
0589
0590 if (unlikely(wrap > 0))
0591 replay_esn->seq_hi++;
0592 } else {
0593 diff = replay_esn->seq - seq;
0594
0595 if (pos >= diff)
0596 bitnr = (pos - diff) % replay_esn->replay_window;
0597 else
0598 bitnr = replay_esn->replay_window - (diff - pos);
0599 }
0600
0601 xfrm_dev_state_advance_esn(x);
0602
0603 nr = bitnr >> 5;
0604 bitnr = bitnr & 0x1F;
0605 replay_esn->bmp[nr] |= (1U << bitnr);
0606
0607 if (xfrm_aevent_is_on(xs_net(x)))
0608 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0609 }
0610
0611 #ifdef CONFIG_XFRM_OFFLOAD
0612 static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *skb)
0613 {
0614 int err = 0;
0615 struct net *net = xs_net(x);
0616 struct xfrm_offload *xo = xfrm_offload(skb);
0617 __u32 oseq = x->replay.oseq;
0618
0619 if (!xo)
0620 return __xfrm_replay_overflow(x, skb);
0621
0622 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
0623 if (!skb_is_gso(skb)) {
0624 XFRM_SKB_CB(skb)->seq.output.low = ++oseq;
0625 xo->seq.low = oseq;
0626 } else {
0627 XFRM_SKB_CB(skb)->seq.output.low = oseq + 1;
0628 xo->seq.low = oseq + 1;
0629 oseq += skb_shinfo(skb)->gso_segs;
0630 }
0631
0632 XFRM_SKB_CB(skb)->seq.output.hi = 0;
0633 xo->seq.hi = 0;
0634 if (unlikely(oseq < x->replay.oseq) &&
0635 !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
0636 xfrm_audit_state_replay_overflow(x, skb);
0637 err = -EOVERFLOW;
0638
0639 return err;
0640 }
0641
0642 x->replay.oseq = oseq;
0643
0644 if (xfrm_aevent_is_on(net))
0645 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0646 }
0647
0648 return err;
0649 }
0650
0651 static int xfrm_replay_overflow_offload_bmp(struct xfrm_state *x, struct sk_buff *skb)
0652 {
0653 int err = 0;
0654 struct xfrm_offload *xo = xfrm_offload(skb);
0655 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0656 struct net *net = xs_net(x);
0657 __u32 oseq = replay_esn->oseq;
0658
0659 if (!xo)
0660 return xfrm_replay_overflow_bmp(x, skb);
0661
0662 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
0663 if (!skb_is_gso(skb)) {
0664 XFRM_SKB_CB(skb)->seq.output.low = ++oseq;
0665 xo->seq.low = oseq;
0666 } else {
0667 XFRM_SKB_CB(skb)->seq.output.low = oseq + 1;
0668 xo->seq.low = oseq + 1;
0669 oseq += skb_shinfo(skb)->gso_segs;
0670 }
0671
0672 XFRM_SKB_CB(skb)->seq.output.hi = 0;
0673 xo->seq.hi = 0;
0674 if (unlikely(oseq < replay_esn->oseq) &&
0675 !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
0676 xfrm_audit_state_replay_overflow(x, skb);
0677 err = -EOVERFLOW;
0678
0679 return err;
0680 } else {
0681 replay_esn->oseq = oseq;
0682 }
0683
0684 if (xfrm_aevent_is_on(net))
0685 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0686 }
0687
0688 return err;
0689 }
0690
0691 static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff *skb)
0692 {
0693 int err = 0;
0694 struct xfrm_offload *xo = xfrm_offload(skb);
0695 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0696 struct net *net = xs_net(x);
0697 __u32 oseq = replay_esn->oseq;
0698 __u32 oseq_hi = replay_esn->oseq_hi;
0699
0700 if (!xo)
0701 return xfrm_replay_overflow_esn(x, skb);
0702
0703 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
0704 if (!skb_is_gso(skb)) {
0705 XFRM_SKB_CB(skb)->seq.output.low = ++oseq;
0706 XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi;
0707 xo->seq.low = oseq;
0708 xo->seq.hi = oseq_hi;
0709 } else {
0710 XFRM_SKB_CB(skb)->seq.output.low = oseq + 1;
0711 XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi;
0712 xo->seq.low = oseq + 1;
0713 xo->seq.hi = oseq_hi;
0714 oseq += skb_shinfo(skb)->gso_segs;
0715 }
0716
0717 if (unlikely(oseq < replay_esn->oseq)) {
0718 XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi;
0719 xo->seq.hi = oseq_hi;
0720 replay_esn->oseq_hi = oseq_hi;
0721 if (replay_esn->oseq_hi == 0) {
0722 replay_esn->oseq--;
0723 replay_esn->oseq_hi--;
0724 xfrm_audit_state_replay_overflow(x, skb);
0725 err = -EOVERFLOW;
0726
0727 return err;
0728 }
0729 }
0730
0731 replay_esn->oseq = oseq;
0732
0733 if (xfrm_aevent_is_on(net))
0734 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
0735 }
0736
0737 return err;
0738 }
0739
0740 int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
0741 {
0742 switch (x->repl_mode) {
0743 case XFRM_REPLAY_MODE_LEGACY:
0744 break;
0745 case XFRM_REPLAY_MODE_BMP:
0746 return xfrm_replay_overflow_offload_bmp(x, skb);
0747 case XFRM_REPLAY_MODE_ESN:
0748 return xfrm_replay_overflow_offload_esn(x, skb);
0749 }
0750
0751 return xfrm_replay_overflow_offload(x, skb);
0752 }
0753 #else
0754 int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
0755 {
0756 switch (x->repl_mode) {
0757 case XFRM_REPLAY_MODE_LEGACY:
0758 break;
0759 case XFRM_REPLAY_MODE_BMP:
0760 return xfrm_replay_overflow_bmp(x, skb);
0761 case XFRM_REPLAY_MODE_ESN:
0762 return xfrm_replay_overflow_esn(x, skb);
0763 }
0764
0765 return __xfrm_replay_overflow(x, skb);
0766 }
0767 #endif
0768
0769 int xfrm_init_replay(struct xfrm_state *x)
0770 {
0771 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
0772
0773 if (replay_esn) {
0774 if (replay_esn->replay_window >
0775 replay_esn->bmp_len * sizeof(__u32) * 8)
0776 return -EINVAL;
0777
0778 if (x->props.flags & XFRM_STATE_ESN) {
0779 if (replay_esn->replay_window == 0)
0780 return -EINVAL;
0781 x->repl_mode = XFRM_REPLAY_MODE_ESN;
0782 } else {
0783 x->repl_mode = XFRM_REPLAY_MODE_BMP;
0784 }
0785 } else {
0786 x->repl_mode = XFRM_REPLAY_MODE_LEGACY;
0787 }
0788
0789 return 0;
0790 }
0791 EXPORT_SYMBOL(xfrm_init_replay);