diff options
-rw-r--r-- | include/net/xfrm.h | 4 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 31 |
2 files changed, 35 insertions, 0 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index ee3827f053d7..d3a898b18fb4 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -928,6 +928,10 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t | |||
928 | struct flowi *fl, struct xfrm_tmpl *tmpl, | 928 | struct flowi *fl, struct xfrm_tmpl *tmpl, |
929 | struct xfrm_policy *pol, int *err, | 929 | struct xfrm_policy *pol, int *err, |
930 | unsigned short family); | 930 | unsigned short family); |
931 | extern struct xfrm_state * xfrm_stateonly_find(xfrm_address_t *daddr, | ||
932 | xfrm_address_t *saddr, | ||
933 | unsigned short family, | ||
934 | u8 mode, u8 proto, u32 reqid); | ||
931 | extern int xfrm_state_check_expire(struct xfrm_state *x); | 935 | extern int xfrm_state_check_expire(struct xfrm_state *x); |
932 | extern void xfrm_state_insert(struct xfrm_state *x); | 936 | extern void xfrm_state_insert(struct xfrm_state *x); |
933 | extern int xfrm_state_add(struct xfrm_state *x); | 937 | extern int xfrm_state_add(struct xfrm_state *x); |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index dfacb9c2a6e3..e070c3f938fb 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -686,6 +686,37 @@ out: | |||
686 | return x; | 686 | return x; |
687 | } | 687 | } |
688 | 688 | ||
689 | struct xfrm_state * | ||
690 | xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
691 | unsigned short family, u8 mode, u8 proto, u32 reqid) | ||
692 | { | ||
693 | unsigned int h = xfrm_dst_hash(daddr, saddr, reqid, family); | ||
694 | struct xfrm_state *rx = NULL, *x = NULL; | ||
695 | struct hlist_node *entry; | ||
696 | |||
697 | spin_lock(&xfrm_state_lock); | ||
698 | hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) { | ||
699 | if (x->props.family == family && | ||
700 | x->props.reqid == reqid && | ||
701 | !(x->props.flags & XFRM_STATE_WILDRECV) && | ||
702 | xfrm_state_addr_check(x, daddr, saddr, family) && | ||
703 | mode == x->props.mode && | ||
704 | proto == x->id.proto && | ||
705 | x->km.state == XFRM_STATE_VALID) { | ||
706 | rx = x; | ||
707 | break; | ||
708 | } | ||
709 | } | ||
710 | |||
711 | if (rx) | ||
712 | xfrm_state_hold(rx); | ||
713 | spin_unlock(&xfrm_state_lock); | ||
714 | |||
715 | |||
716 | return rx; | ||
717 | } | ||
718 | EXPORT_SYMBOL(xfrm_stateonly_find); | ||
719 | |||
689 | static void __xfrm_state_insert(struct xfrm_state *x) | 720 | static void __xfrm_state_insert(struct xfrm_state *x) |
690 | { | 721 | { |
691 | unsigned int h; | 722 | unsigned int h; |