Commit bd55775c8dd656fc69b3a42a1c4ab32abb7e8af9

Authored by Jamal Hadi Salim
Committed by David S. Miller
1 parent bf825f81b4

xfrm: SA lookups signature with mark

pass mark to all SA lookups to prepare them for when we add code
to have them search.

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 13 changed files with 84 additions and 55 deletions Side-by-side Diff

... ... @@ -1319,7 +1319,7 @@
1319 1319 struct flowi *fl, struct xfrm_tmpl *tmpl,
1320 1320 struct xfrm_policy *pol, int *err,
1321 1321 unsigned short family);
1322   -extern struct xfrm_state * xfrm_stateonly_find(struct net *net,
  1322 +extern struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark,
1323 1323 xfrm_address_t *daddr,
1324 1324 xfrm_address_t *saddr,
1325 1325 unsigned short family,
... ... @@ -1328,8 +1328,14 @@
1328 1328 extern void xfrm_state_insert(struct xfrm_state *x);
1329 1329 extern int xfrm_state_add(struct xfrm_state *x);
1330 1330 extern int xfrm_state_update(struct xfrm_state *x);
1331   -extern struct xfrm_state *xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family);
1332   -extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family);
  1331 +extern struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
  1332 + xfrm_address_t *daddr, __be32 spi,
  1333 + u8 proto, unsigned short family);
  1334 +extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
  1335 + xfrm_address_t *daddr,
  1336 + xfrm_address_t *saddr,
  1337 + u8 proto,
  1338 + unsigned short family);
1333 1339 #ifdef CONFIG_XFRM_SUB_POLICY
1334 1340 extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
1335 1341 int n, unsigned short family);
... ... @@ -1366,7 +1372,8 @@
1366 1372 u32 spdhmcnt;
1367 1373 };
1368 1374  
1369   -extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq);
  1375 +extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark,
  1376 + u32 seq);
1370 1377 extern int xfrm_state_delete(struct xfrm_state *x);
1371 1378 extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info);
1372 1379 extern void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
... ... @@ -1451,9 +1458,11 @@
1451 1458 int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info);
1452 1459 u32 xfrm_get_acqseq(void);
1453 1460 extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
1454   -struct xfrm_state * xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
1455   - xfrm_address_t *daddr, xfrm_address_t *saddr,
1456   - int create, unsigned short family);
  1461 +struct xfrm_state *xfrm_find_acq(struct net *net, struct xfrm_mark *mark,
  1462 + u8 mode, u32 reqid, u8 proto,
  1463 + xfrm_address_t *daddr,
  1464 + xfrm_address_t *saddr, int create,
  1465 + unsigned short family);
1457 1466 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
1458 1467 extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
1459 1468 struct flowi *fl, int family, int strict);
... ... @@ -2188,12 +2188,13 @@
2188 2188 /* If there was already an IPSEC SA, we keep it as is, else
2189 2189 * we go look for it ...
2190 2190 */
  2191 +#define DUMMY_MARK 0
2191 2192 static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
2192 2193 {
2193 2194 struct xfrm_state *x = pkt_dev->flows[flow].x;
2194 2195 if (!x) {
2195 2196 /*slow path: we dont already have xfrm_state*/
2196   - x = xfrm_stateonly_find(&init_net,
  2197 + x = xfrm_stateonly_find(&init_net, DUMMY_MARK,
2197 2198 (xfrm_address_t *)&pkt_dev->cur_daddr,
2198 2199 (xfrm_address_t *)&pkt_dev->cur_saddr,
2199 2200 AF_INET,
... ... @@ -393,7 +393,7 @@
393 393 icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
394 394 return;
395 395  
396   - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
  396 + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
397 397 if (!x)
398 398 return;
399 399 printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n",
... ... @@ -422,7 +422,7 @@
422 422 icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
423 423 return;
424 424  
425   - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
  425 + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
426 426 if (!x)
427 427 return;
428 428 NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n",
... ... @@ -36,7 +36,7 @@
36 36 return;
37 37  
38 38 spi = htonl(ntohs(ipch->cpi));
39   - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr,
  39 + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr,
40 40 spi, IPPROTO_COMP, AF_INET);
41 41 if (!x)
42 42 return;
... ... @@ -63,6 +63,7 @@
63 63 t->props.mode = x->props.mode;
64 64 t->props.saddr.a4 = x->props.saddr.a4;
65 65 t->props.flags = x->props.flags;
  66 + memcpy(&t->mark, &x->mark, sizeof(t->mark));
66 67  
67 68 if (xfrm_init_state(t))
68 69 goto error;
69 70  
... ... @@ -87,8 +88,9 @@
87 88 struct net *net = xs_net(x);
88 89 int err = 0;
89 90 struct xfrm_state *t;
  91 + u32 mark = x->mark.v & x->mark.m;
90 92  
91   - t = xfrm_state_lookup(net, (xfrm_address_t *)&x->id.daddr.a4,
  93 + t = xfrm_state_lookup(net, mark, (xfrm_address_t *)&x->id.daddr.a4,
92 94 x->props.saddr.a4, IPPROTO_IPIP, AF_INET);
93 95 if (!t) {
94 96 t = ipcomp_tunnel_create(x);
... ... @@ -614,7 +614,7 @@
614 614 type != ICMPV6_PKT_TOOBIG)
615 615 return;
616 616  
617   - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
  617 + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
618 618 if (!x)
619 619 return;
620 620  
... ... @@ -365,7 +365,7 @@
365 365 type != ICMPV6_PKT_TOOBIG)
366 366 return;
367 367  
368   - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
  368 + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
369 369 if (!x)
370 370 return;
371 371 printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
... ... @@ -64,7 +64,7 @@
64 64 return;
65 65  
66 66 spi = htonl(ntohs(ipcomph->cpi));
67   - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
  67 + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
68 68 if (!x)
69 69 return;
70 70  
... ... @@ -92,6 +92,7 @@
92 92 t->props.family = AF_INET6;
93 93 t->props.mode = x->props.mode;
94 94 memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
  95 + memcpy(&t->mark, &x->mark, sizeof(t->mark));
95 96  
96 97 if (xfrm_init_state(t))
97 98 goto error;
98 99  
... ... @@ -114,10 +115,11 @@
114 115 int err = 0;
115 116 struct xfrm_state *t = NULL;
116 117 __be32 spi;
  118 + u32 mark = x->mark.m & x->mark.v;
117 119  
118 120 spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&x->props.saddr);
119 121 if (spi)
120   - t = xfrm_state_lookup(net, (xfrm_address_t *)&x->id.daddr,
  122 + t = xfrm_state_lookup(net, mark, (xfrm_address_t *)&x->id.daddr,
121 123 spi, IPPROTO_IPV6, AF_INET6);
122 124 if (!t) {
123 125 t = ipcomp6_tunnel_create(x);
net/ipv6/xfrm6_input.c
... ... @@ -101,7 +101,7 @@
101 101 break;
102 102 }
103 103  
104   - x = xfrm_state_lookup_byaddr(net, dst, src, proto, AF_INET6);
  104 + x = xfrm_state_lookup_byaddr(net, skb->mark, dst, src, proto, AF_INET6);
105 105 if (!x)
106 106 continue;
107 107  
... ... @@ -43,6 +43,8 @@
43 43 };
44 44 static DEFINE_MUTEX(pfkey_mutex);
45 45  
  46 +#define DUMMY_MARK 0
  47 +static struct xfrm_mark dummy_mark = {0, 0};
46 48 struct pfkey_sock {
47 49 /* struct sock must be the first member of struct pfkey_sock */
48 50 struct sock sk;
... ... @@ -647,7 +649,7 @@
647 649 if (!xaddr)
648 650 return NULL;
649 651  
650   - return xfrm_state_lookup(net, xaddr, sa->sadb_sa_spi, proto, family);
  652 + return xfrm_state_lookup(net, DUMMY_MARK, xaddr, sa->sadb_sa_spi, proto, family);
651 653 }
652 654  
653 655 #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
... ... @@ -1316,7 +1318,7 @@
1316 1318 }
1317 1319  
1318 1320 if (hdr->sadb_msg_seq) {
1319   - x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq);
  1321 + x = xfrm_find_acq_byseq(net, DUMMY_MARK, hdr->sadb_msg_seq);
1320 1322 if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) {
1321 1323 xfrm_state_put(x);
1322 1324 x = NULL;
... ... @@ -1324,7 +1326,7 @@
1324 1326 }
1325 1327  
1326 1328 if (!x)
1327   - x = xfrm_find_acq(net, mode, reqid, proto, xdaddr, xsaddr, 1, family);
  1329 + x = xfrm_find_acq(net, &dummy_mark, mode, reqid, proto, xdaddr, xsaddr, 1, family);
1328 1330  
1329 1331 if (x == NULL)
1330 1332 return -ENOENT;
... ... @@ -1373,7 +1375,7 @@
1373 1375 if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0)
1374 1376 return 0;
1375 1377  
1376   - x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq);
  1378 + x = xfrm_find_acq_byseq(net, DUMMY_MARK, hdr->sadb_msg_seq);
1377 1379 if (x == NULL)
1378 1380 return 0;
1379 1381  
... ... @@ -2572,8 +2574,8 @@
2572 2574 return -EINVAL;
2573 2575  
2574 2576 delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2);
2575   - xp = xfrm_policy_byid(net, XFRM_POLICY_TYPE_MAIN, dir,
2576   - pol->sadb_x_policy_id, delete, &err);
  2577 + xp = xfrm_policy_byid(net, XFRM_POLICY_TYPE_MAIN,
  2578 + dir, pol->sadb_x_policy_id, delete, &err);
2577 2579 if (xp == NULL)
2578 2580 return -ENOENT;
2579 2581  
net/xfrm/xfrm_input.c
... ... @@ -152,7 +152,7 @@
152 152 goto drop;
153 153 }
154 154  
155   - x = xfrm_state_lookup(net, daddr, spi, nexthdr, family);
  155 + x = xfrm_state_lookup(net, skb->mark, daddr, spi, nexthdr, family);
156 156 if (x == NULL) {
157 157 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
158 158 xfrm_audit_state_notfound(skb, family, spi, seq);
net/xfrm/xfrm_state.c
... ... @@ -669,7 +669,7 @@
669 669 return 0;
670 670 }
671 671  
672   -static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
  672 +static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
673 673 {
674 674 unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family);
675 675 struct xfrm_state *x;
... ... @@ -689,7 +689,7 @@
689 689 return NULL;
690 690 }
691 691  
692   -static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
  692 +static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
693 693 {
694 694 unsigned int h = xfrm_src_hash(net, daddr, saddr, family);
695 695 struct xfrm_state *x;
696 696  
697 697  
... ... @@ -713,12 +713,14 @@
713 713 __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
714 714 {
715 715 struct net *net = xs_net(x);
  716 + u32 mark = x->mark.v & x->mark.m;
716 717  
717 718 if (use_spi)
718   - return __xfrm_state_lookup(net, &x->id.daddr, x->id.spi,
719   - x->id.proto, family);
  719 + return __xfrm_state_lookup(net, mark, &x->id.daddr,
  720 + x->id.spi, x->id.proto, family);
720 721 else
721   - return __xfrm_state_lookup_byaddr(net, &x->id.daddr,
  722 + return __xfrm_state_lookup_byaddr(net, mark,
  723 + &x->id.daddr,
722 724 &x->props.saddr,
723 725 x->id.proto, family);
724 726 }
... ... @@ -783,6 +785,7 @@
783 785 int acquire_in_progress = 0;
784 786 int error = 0;
785 787 struct xfrm_state *best = NULL;
  788 + u32 mark = pol->mark.v & pol->mark.m;
786 789  
787 790 to_put = NULL;
788 791  
... ... @@ -819,7 +822,7 @@
819 822 x = best;
820 823 if (!x && !error && !acquire_in_progress) {
821 824 if (tmpl->id.spi &&
822   - (x0 = __xfrm_state_lookup(net, daddr, tmpl->id.spi,
  825 + (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi,
823 826 tmpl->id.proto, family)) != NULL) {
824 827 to_put = x0;
825 828 error = -EEXIST;
... ... @@ -833,6 +836,7 @@
833 836 /* Initialize temporary selector matching only
834 837 * to current session. */
835 838 xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family);
  839 + memcpy(&x->mark, &pol->mark, sizeof(x->mark));
836 840  
837 841 error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
838 842 if (error) {
... ... @@ -875,7 +879,7 @@
875 879 }
876 880  
877 881 struct xfrm_state *
878   -xfrm_stateonly_find(struct net *net,
  882 +xfrm_stateonly_find(struct net *net, u32 mark,
879 883 xfrm_address_t *daddr, xfrm_address_t *saddr,
880 884 unsigned short family, u8 mode, u8 proto, u32 reqid)
881 885 {
... ... @@ -971,7 +975,7 @@
971 975 EXPORT_SYMBOL(xfrm_state_insert);
972 976  
973 977 /* xfrm_state_lock is held */
974   -static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create)
  978 +static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create)
975 979 {
976 980 unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
977 981 struct hlist_node *entry;
... ... @@ -1026,6 +1030,8 @@
1026 1030 x->props.family = family;
1027 1031 x->props.mode = mode;
1028 1032 x->props.reqid = reqid;
  1033 + x->mark.v = m->v;
  1034 + x->mark.m = m->m;
1029 1035 x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
1030 1036 xfrm_state_hold(x);
1031 1037 tasklet_hrtimer_start(&x->mtimer, ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL);
... ... @@ -1042,7 +1048,7 @@
1042 1048 return x;
1043 1049 }
1044 1050  
1045   -static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq);
  1051 +static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1046 1052  
1047 1053 int xfrm_state_add(struct xfrm_state *x)
1048 1054 {
... ... @@ -1050,6 +1056,7 @@
1050 1056 struct xfrm_state *x1, *to_put;
1051 1057 int family;
1052 1058 int err;
  1059 + u32 mark = x->mark.v & x->mark.m;
1053 1060 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
1054 1061  
1055 1062 family = x->props.family;
... ... @@ -1067,7 +1074,7 @@
1067 1074 }
1068 1075  
1069 1076 if (use_spi && x->km.seq) {
1070   - x1 = __xfrm_find_acq_byseq(net, x->km.seq);
  1077 + x1 = __xfrm_find_acq_byseq(net, mark, x->km.seq);
1071 1078 if (x1 && ((x1->id.proto != x->id.proto) ||
1072 1079 xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
1073 1080 to_put = x1;
... ... @@ -1076,8 +1083,8 @@
1076 1083 }
1077 1084  
1078 1085 if (use_spi && !x1)
1079   - x1 = __find_acq_core(net, family, x->props.mode, x->props.reqid,
1080   - x->id.proto,
  1086 + x1 = __find_acq_core(net, &x->mark, family, x->props.mode,
  1087 + x->props.reqid, x->id.proto,
1081 1088 &x->id.daddr, &x->props.saddr, 0);
1082 1089  
1083 1090 __xfrm_state_bump_genids(x);
... ... @@ -1151,6 +1158,8 @@
1151 1158 goto error;
1152 1159 }
1153 1160  
  1161 + memcpy(&x->mark, &orig->mark, sizeof(x->mark));
  1162 +
1154 1163 err = xfrm_init_state(x);
1155 1164 if (err)
1156 1165 goto error;
1157 1166  
1158 1167  
1159 1168  
1160 1169  
1161 1170  
... ... @@ -1342,41 +1351,41 @@
1342 1351 EXPORT_SYMBOL(xfrm_state_check_expire);
1343 1352  
1344 1353 struct xfrm_state *
1345   -xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto,
1346   - unsigned short family)
  1354 +xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi,
  1355 + u8 proto, unsigned short family)
1347 1356 {
1348 1357 struct xfrm_state *x;
1349 1358  
1350 1359 spin_lock_bh(&xfrm_state_lock);
1351   - x = __xfrm_state_lookup(net, daddr, spi, proto, family);
  1360 + x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
1352 1361 spin_unlock_bh(&xfrm_state_lock);
1353 1362 return x;
1354 1363 }
1355 1364 EXPORT_SYMBOL(xfrm_state_lookup);
1356 1365  
1357 1366 struct xfrm_state *
1358   -xfrm_state_lookup_byaddr(struct net *net,
  1367 +xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1359 1368 xfrm_address_t *daddr, xfrm_address_t *saddr,
1360 1369 u8 proto, unsigned short family)
1361 1370 {
1362 1371 struct xfrm_state *x;
1363 1372  
1364 1373 spin_lock_bh(&xfrm_state_lock);
1365   - x = __xfrm_state_lookup_byaddr(net, daddr, saddr, proto, family);
  1374 + x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
1366 1375 spin_unlock_bh(&xfrm_state_lock);
1367 1376 return x;
1368 1377 }
1369 1378 EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
1370 1379  
1371 1380 struct xfrm_state *
1372   -xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
  1381 +xfrm_find_acq(struct net *net, struct xfrm_mark *mark, u8 mode, u32 reqid, u8 proto,
1373 1382 xfrm_address_t *daddr, xfrm_address_t *saddr,
1374 1383 int create, unsigned short family)
1375 1384 {
1376 1385 struct xfrm_state *x;
1377 1386  
1378 1387 spin_lock_bh(&xfrm_state_lock);
1379   - x = __find_acq_core(net, family, mode, reqid, proto, daddr, saddr, create);
  1388 + x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
1380 1389 spin_unlock_bh(&xfrm_state_lock);
1381 1390  
1382 1391 return x;
... ... @@ -1423,7 +1432,7 @@
1423 1432  
1424 1433 /* Silly enough, but I'm lazy to build resolution list */
1425 1434  
1426   -static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq)
  1435 +static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
1427 1436 {
1428 1437 int i;
1429 1438  
1430 1439  
... ... @@ -1442,12 +1451,12 @@
1442 1451 return NULL;
1443 1452 }
1444 1453  
1445   -struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq)
  1454 +struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
1446 1455 {
1447 1456 struct xfrm_state *x;
1448 1457  
1449 1458 spin_lock_bh(&xfrm_state_lock);
1450   - x = __xfrm_find_acq_byseq(net, seq);
  1459 + x = __xfrm_find_acq_byseq(net, mark, seq);
1451 1460 spin_unlock_bh(&xfrm_state_lock);
1452 1461 return x;
1453 1462 }
... ... @@ -1474,6 +1483,7 @@
1474 1483 int err = -ENOENT;
1475 1484 __be32 minspi = htonl(low);
1476 1485 __be32 maxspi = htonl(high);
  1486 + u32 mark = x->mark.v & x->mark.m;
1477 1487  
1478 1488 spin_lock_bh(&x->lock);
1479 1489 if (x->km.state == XFRM_STATE_DEAD)
... ... @@ -1486,7 +1496,7 @@
1486 1496 err = -ENOENT;
1487 1497  
1488 1498 if (minspi == maxspi) {
1489   - x0 = xfrm_state_lookup(net, &x->id.daddr, minspi, x->id.proto, x->props.family);
  1499 + x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family);
1490 1500 if (x0) {
1491 1501 xfrm_state_put(x0);
1492 1502 goto unlock;
... ... @@ -1496,7 +1506,7 @@
1496 1506 u32 spi = 0;
1497 1507 for (h=0; h<high-low+1; h++) {
1498 1508 spi = low + net_random()%(high-low+1);
1499   - x0 = xfrm_state_lookup(net, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
  1509 + x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
1500 1510 if (x0 == NULL) {
1501 1511 x->id.spi = htonl(spi);
1502 1512 break;
net/xfrm/xfrm_user.c
... ... @@ -31,6 +31,9 @@
31 31 #include <linux/in6.h>
32 32 #endif
33 33  
  34 +#define DUMMY_MARK 0
  35 +static struct xfrm_mark dummy_mark = {0, 0};
  36 +
34 37 static inline int aead_len(struct xfrm_algo_aead *alg)
35 38 {
36 39 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
... ... @@ -530,7 +533,7 @@
530 533  
531 534 if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) {
532 535 err = -ESRCH;
533   - x = xfrm_state_lookup(net, &p->daddr, p->spi, p->proto, p->family);
  536 + x = xfrm_state_lookup(net, DUMMY_MARK, &p->daddr, p->spi, p->proto, p->family);
534 537 } else {
535 538 xfrm_address_t *saddr = NULL;
536 539  
... ... @@ -541,7 +544,7 @@
541 544 }
542 545  
543 546 err = -ESRCH;
544   - x = xfrm_state_lookup_byaddr(net, &p->daddr, saddr,
  547 + x = xfrm_state_lookup_byaddr(net, DUMMY_MARK, &p->daddr, saddr,
545 548 p->proto, p->family);
546 549 }
547 550  
... ... @@ -958,7 +961,7 @@
958 961  
959 962 x = NULL;
960 963 if (p->info.seq) {
961   - x = xfrm_find_acq_byseq(net, p->info.seq);
  964 + x = xfrm_find_acq_byseq(net, DUMMY_MARK, p->info.seq);
962 965 if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) {
963 966 xfrm_state_put(x);
964 967 x = NULL;
... ... @@ -966,7 +969,7 @@
966 969 }
967 970  
968 971 if (!x)
969   - x = xfrm_find_acq(net, p->info.mode, p->info.reqid,
  972 + x = xfrm_find_acq(net, &dummy_mark, p->info.mode, p->info.reqid,
970 973 p->info.id.proto, daddr,
971 974 &p->info.saddr, 1,
972 975 family);
... ... @@ -1598,7 +1601,7 @@
1598 1601 if (r_skb == NULL)
1599 1602 return -ENOMEM;
1600 1603  
1601   - x = xfrm_state_lookup(net, &id->daddr, id->spi, id->proto, id->family);
  1604 + x = xfrm_state_lookup(net, DUMMY_MARK, &id->daddr, id->spi, id->proto, id->family);
1602 1605 if (x == NULL) {
1603 1606 kfree_skb(r_skb);
1604 1607 return -ESRCH;
... ... @@ -1640,7 +1643,7 @@
1640 1643 if (!(nlh->nlmsg_flags&NLM_F_REPLACE))
1641 1644 return err;
1642 1645  
1643   - x = xfrm_state_lookup(net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
  1646 + x = xfrm_state_lookup(net, DUMMY_MARK, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
1644 1647 if (x == NULL)
1645 1648 return -ESRCH;
1646 1649  
... ... @@ -1767,7 +1770,7 @@
1767 1770 struct xfrm_user_expire *ue = nlmsg_data(nlh);
1768 1771 struct xfrm_usersa_info *p = &ue->state;
1769 1772  
1770   - x = xfrm_state_lookup(net, &p->id.daddr, p->id.spi, p->id.proto, p->family);
  1773 + x = xfrm_state_lookup(net, DUMMY_MARK, &p->id.daddr, p->id.spi, p->id.proto, p->family);
1771 1774  
1772 1775 err = -ENOENT;
1773 1776 if (x == NULL)