diff options
Diffstat (limited to 'net/ipv6/xfrm6_state.c')
-rw-r--r-- | net/ipv6/xfrm6_state.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 2fb07850449f..9c95b9d3e110 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -64,6 +64,26 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | |||
64 | } | 64 | } |
65 | 65 | ||
66 | static struct xfrm_state * | 66 | static struct xfrm_state * |
67 | __xfrm6_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
68 | u8 proto) | ||
69 | { | ||
70 | struct xfrm_state *x = NULL; | ||
71 | unsigned h; | ||
72 | |||
73 | h = __xfrm6_src_hash(saddr); | ||
74 | list_for_each_entry(x, xfrm6_state_afinfo.state_bysrc+h, bysrc) { | ||
75 | if (x->props.family == AF_INET6 && | ||
76 | ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)x->id.daddr.a6) && | ||
77 | ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)x->props.saddr.a6) && | ||
78 | proto == x->id.proto) { | ||
79 | xfrm_state_hold(x); | ||
80 | return x; | ||
81 | } | ||
82 | } | ||
83 | return NULL; | ||
84 | } | ||
85 | |||
86 | static struct xfrm_state * | ||
67 | __xfrm6_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto) | 87 | __xfrm6_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto) |
68 | { | 88 | { |
69 | unsigned h = __xfrm6_spi_hash(daddr, spi, proto); | 89 | unsigned h = __xfrm6_spi_hash(daddr, spi, proto); |
@@ -140,6 +160,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = { | |||
140 | .family = AF_INET6, | 160 | .family = AF_INET6, |
141 | .init_tempsel = __xfrm6_init_tempsel, | 161 | .init_tempsel = __xfrm6_init_tempsel, |
142 | .state_lookup = __xfrm6_state_lookup, | 162 | .state_lookup = __xfrm6_state_lookup, |
163 | .state_lookup_byaddr = __xfrm6_state_lookup_byaddr, | ||
143 | .find_acq = __xfrm6_find_acq, | 164 | .find_acq = __xfrm6_find_acq, |
144 | }; | 165 | }; |
145 | 166 | ||