aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r--net/xfrm/xfrm_state.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9f8530356b86..17d5b96f2fc8 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -682,6 +682,8 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_ad
682 xfrm_addr_cmp(&x->id.daddr, daddr, family)) 682 xfrm_addr_cmp(&x->id.daddr, daddr, family))
683 continue; 683 continue;
684 684
685 if ((mark & x->mark.m) != x->mark.v)
686 continue;
685 xfrm_state_hold(x); 687 xfrm_state_hold(x);
686 return x; 688 return x;
687 } 689 }
@@ -702,6 +704,8 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark,
702 xfrm_addr_cmp(&x->props.saddr, saddr, family)) 704 xfrm_addr_cmp(&x->props.saddr, saddr, family))
703 continue; 705 continue;
704 706
707 if ((mark & x->mark.m) != x->mark.v)
708 continue;
705 xfrm_state_hold(x); 709 xfrm_state_hold(x);
706 return x; 710 return x;
707 } 711 }
@@ -794,6 +798,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
794 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { 798 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
795 if (x->props.family == family && 799 if (x->props.family == family &&
796 x->props.reqid == tmpl->reqid && 800 x->props.reqid == tmpl->reqid &&
801 (mark & x->mark.m) == x->mark.v &&
797 !(x->props.flags & XFRM_STATE_WILDRECV) && 802 !(x->props.flags & XFRM_STATE_WILDRECV) &&
798 xfrm_state_addr_check(x, daddr, saddr, family) && 803 xfrm_state_addr_check(x, daddr, saddr, family) &&
799 tmpl->mode == x->props.mode && 804 tmpl->mode == x->props.mode &&
@@ -809,6 +814,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
809 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { 814 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) {
810 if (x->props.family == family && 815 if (x->props.family == family &&
811 x->props.reqid == tmpl->reqid && 816 x->props.reqid == tmpl->reqid &&
817 (mark & x->mark.m) == x->mark.v &&
812 !(x->props.flags & XFRM_STATE_WILDRECV) && 818 !(x->props.flags & XFRM_STATE_WILDRECV) &&
813 xfrm_state_addr_check(x, daddr, saddr, family) && 819 xfrm_state_addr_check(x, daddr, saddr, family) &&
814 tmpl->mode == x->props.mode && 820 tmpl->mode == x->props.mode &&
@@ -892,6 +898,7 @@ xfrm_stateonly_find(struct net *net, u32 mark,
892 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { 898 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
893 if (x->props.family == family && 899 if (x->props.family == family &&
894 x->props.reqid == reqid && 900 x->props.reqid == reqid &&
901 (mark & x->mark.m) == x->mark.v &&
895 !(x->props.flags & XFRM_STATE_WILDRECV) && 902 !(x->props.flags & XFRM_STATE_WILDRECV) &&
896 xfrm_state_addr_check(x, daddr, saddr, family) && 903 xfrm_state_addr_check(x, daddr, saddr, family) &&
897 mode == x->props.mode && 904 mode == x->props.mode &&
@@ -954,11 +961,13 @@ static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
954 struct xfrm_state *x; 961 struct xfrm_state *x;
955 struct hlist_node *entry; 962 struct hlist_node *entry;
956 unsigned int h; 963 unsigned int h;
964 u32 mark = xnew->mark.v & xnew->mark.m;
957 965
958 h = xfrm_dst_hash(net, &xnew->id.daddr, &xnew->props.saddr, reqid, family); 966 h = xfrm_dst_hash(net, &xnew->id.daddr, &xnew->props.saddr, reqid, family);
959 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { 967 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
960 if (x->props.family == family && 968 if (x->props.family == family &&
961 x->props.reqid == reqid && 969 x->props.reqid == reqid &&
970 (mark & x->mark.m) == x->mark.v &&
962 !xfrm_addr_cmp(&x->id.daddr, &xnew->id.daddr, family) && 971 !xfrm_addr_cmp(&x->id.daddr, &xnew->id.daddr, family) &&
963 !xfrm_addr_cmp(&x->props.saddr, &xnew->props.saddr, family)) 972 !xfrm_addr_cmp(&x->props.saddr, &xnew->props.saddr, family))
964 x->genid = xfrm_state_genid; 973 x->genid = xfrm_state_genid;
@@ -980,6 +989,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m,
980 unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family); 989 unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
981 struct hlist_node *entry; 990 struct hlist_node *entry;
982 struct xfrm_state *x; 991 struct xfrm_state *x;
992 u32 mark = m->v & m->m;
983 993
984 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { 994 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
985 if (x->props.reqid != reqid || 995 if (x->props.reqid != reqid ||
@@ -988,6 +998,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m,
988 x->km.state != XFRM_STATE_ACQ || 998 x->km.state != XFRM_STATE_ACQ ||
989 x->id.spi != 0 || 999 x->id.spi != 0 ||
990 x->id.proto != proto || 1000 x->id.proto != proto ||
1001 (mark & x->mark.m) != x->mark.v ||
991 xfrm_addr_cmp(&x->id.daddr, daddr, family) || 1002 xfrm_addr_cmp(&x->id.daddr, daddr, family) ||
992 xfrm_addr_cmp(&x->props.saddr, saddr, family)) 1003 xfrm_addr_cmp(&x->props.saddr, saddr, family))
993 continue; 1004 continue;
@@ -1442,6 +1453,7 @@ static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 s
1442 1453
1443 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+i, bydst) { 1454 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+i, bydst) {
1444 if (x->km.seq == seq && 1455 if (x->km.seq == seq &&
1456 (mark & x->mark.m) == x->mark.v &&
1445 x->km.state == XFRM_STATE_ACQ) { 1457 x->km.state == XFRM_STATE_ACQ) {
1446 xfrm_state_hold(x); 1458 xfrm_state_hold(x);
1447 return x; 1459 return x;