Commit bd55775c8dd656fc69b3a42a1c4ab32abb7e8af9
Committed by
David S. Miller
1 parent
bf825f81b4
Exists in
master
and in
39 other branches
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
include/net/xfrm.h
... | ... | @@ -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); |
net/core/pktgen.c
... | ... | @@ -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, |
net/ipv4/ah4.c
... | ... | @@ -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", |
net/ipv4/esp4.c
... | ... | @@ -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", |
net/ipv4/ipcomp.c
... | ... | @@ -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); |
net/ipv6/ah6.c
... | ... | @@ -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 |
net/ipv6/esp6.c
... | ... | @@ -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", |
net/ipv6/ipcomp6.c
... | ... | @@ -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
net/key/af_key.c
... | ... | @@ -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) |