diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/xfrm/xfrm_state.c | 31 |
1 files changed, 31 insertions, 0 deletions
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; |