Commit c9500d7b authored by Florian Westphal's avatar Florian Westphal Committed by Steffen Klassert

xfrm: store xfrm_mode directly, not its address

This structure is now only 4 bytes, so its more efficient
to cache a copy rather than its address.

No significant size difference in allmodconfig vmlinux.

With non-modular kernel that has all XFRM options enabled, this
series reduces vmlinux image size by ~11kb. All xfrm_mode
indirections are gone and all modes are built-in.

before (ipsec-next master):
    text      data      bss         dec   filename
21071494   7233140 11104324    39408958   vmlinux.master

after this series:
21066448   7226772 11104324    39397544   vmlinux.patched

With allmodconfig kernel, the size increase is only 362 bytes,
even all the xfrm config options removed in this series are
modular.

before:
    text      data     bss      dec   filename
15731286   6936912 4046908 26715106   vmlinux.master

after this series:
15731492   6937068  4046908  26715468 vmlinux
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Reviewed-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 4c145dce
...@@ -132,6 +132,17 @@ struct xfrm_state_offload { ...@@ -132,6 +132,17 @@ struct xfrm_state_offload {
u8 flags; u8 flags;
}; };
struct xfrm_mode {
u8 encap;
u8 family;
u8 flags;
};
/* Flags for xfrm_mode. */
enum {
XFRM_MODE_FLAG_TUNNEL = 1,
};
/* Full description of state of transformer. */ /* Full description of state of transformer. */
struct xfrm_state { struct xfrm_state {
possible_net_t xs_net; possible_net_t xs_net;
...@@ -234,9 +245,9 @@ struct xfrm_state { ...@@ -234,9 +245,9 @@ struct xfrm_state {
/* Reference to data common to all the instances of this /* Reference to data common to all the instances of this
* transformer. */ * transformer. */
const struct xfrm_type *type; const struct xfrm_type *type;
const struct xfrm_mode *inner_mode; struct xfrm_mode inner_mode;
const struct xfrm_mode *inner_mode_iaf; struct xfrm_mode inner_mode_iaf;
const struct xfrm_mode *outer_mode; struct xfrm_mode outer_mode;
const struct xfrm_type_offload *type_offload; const struct xfrm_type_offload *type_offload;
...@@ -421,17 +432,6 @@ struct xfrm_type_offload { ...@@ -421,17 +432,6 @@ struct xfrm_type_offload {
int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family); int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
int xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family); int xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
struct xfrm_mode {
u8 encap;
u8 family;
u8 flags;
};
/* Flags for xfrm_mode. */
enum {
XFRM_MODE_FLAG_TUNNEL = 1,
};
static inline int xfrm_af2proto(unsigned int family) static inline int xfrm_af2proto(unsigned int family)
{ {
switch(family) { switch(family) {
...@@ -448,9 +448,9 @@ static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, i ...@@ -448,9 +448,9 @@ static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, i
{ {
if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
(ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6)) (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
return x->inner_mode; return &x->inner_mode;
else else
return x->inner_mode_iaf; return &x->inner_mode_iaf;
} }
struct xfrm_tmpl { struct xfrm_tmpl {
...@@ -1990,7 +1990,7 @@ static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x, ...@@ -1990,7 +1990,7 @@ static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
tunnel = true; tunnel = true;
break; break;
} }
if (tunnel && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)) if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
return -EINVAL; return -EINVAL;
return 0; return 0;
......
...@@ -135,7 +135,7 @@ static struct sk_buff *xfrm4_outer_mode_gso_segment(struct xfrm_state *x, ...@@ -135,7 +135,7 @@ static struct sk_buff *xfrm4_outer_mode_gso_segment(struct xfrm_state *x,
struct sk_buff *skb, struct sk_buff *skb,
netdev_features_t features) netdev_features_t features)
{ {
switch (x->outer_mode->encap) { switch (x->outer_mode.encap) {
case XFRM_MODE_TUNNEL: case XFRM_MODE_TUNNEL:
return xfrm4_tunnel_gso_segment(x, skb, features); return xfrm4_tunnel_gso_segment(x, skb, features);
case XFRM_MODE_TRANSPORT: case XFRM_MODE_TRANSPORT:
......
...@@ -126,7 +126,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) ...@@ -126,7 +126,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err)
x = xfrm_input_state(skb); x = xfrm_input_state(skb);
inner_mode = x->inner_mode; inner_mode = &x->inner_mode;
if (x->sel.family == AF_UNSPEC) { if (x->sel.family == AF_UNSPEC) {
inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
......
...@@ -83,7 +83,7 @@ static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) ...@@ -83,7 +83,7 @@ static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
#endif #endif
rcu_read_lock(); rcu_read_lock();
afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode->family); afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family);
if (likely(afinfo)) if (likely(afinfo))
ret = afinfo->output_finish(sk, skb); ret = afinfo->output_finish(sk, skb);
else else
......
...@@ -162,7 +162,7 @@ static struct sk_buff *xfrm6_outer_mode_gso_segment(struct xfrm_state *x, ...@@ -162,7 +162,7 @@ static struct sk_buff *xfrm6_outer_mode_gso_segment(struct xfrm_state *x,
struct sk_buff *skb, struct sk_buff *skb,
netdev_features_t features) netdev_features_t features)
{ {
switch (x->outer_mode->encap) { switch (x->outer_mode.encap) {
case XFRM_MODE_TUNNEL: case XFRM_MODE_TUNNEL:
return xfrm6_tunnel_gso_segment(x, skb, features); return xfrm6_tunnel_gso_segment(x, skb, features);
case XFRM_MODE_TRANSPORT: case XFRM_MODE_TRANSPORT:
......
...@@ -361,7 +361,7 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) ...@@ -361,7 +361,7 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err)
x = xfrm_input_state(skb); x = xfrm_input_state(skb);
inner_mode = x->inner_mode; inner_mode = &x->inner_mode;
if (x->sel.family == AF_UNSPEC) { if (x->sel.family == AF_UNSPEC) {
inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
......
...@@ -129,7 +129,7 @@ static int __xfrm6_output_state_finish(struct xfrm_state *x, struct sock *sk, ...@@ -129,7 +129,7 @@ static int __xfrm6_output_state_finish(struct xfrm_state *x, struct sock *sk,
int ret = -EAFNOSUPPORT; int ret = -EAFNOSUPPORT;
rcu_read_lock(); rcu_read_lock();
afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode->family); afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family);
if (likely(afinfo)) if (likely(afinfo))
ret = afinfo->output_finish(sk, skb); ret = afinfo->output_finish(sk, skb);
else else
......
...@@ -53,20 +53,20 @@ static void __xfrm_mode_tunnel_prep(struct xfrm_state *x, struct sk_buff *skb, ...@@ -53,20 +53,20 @@ static void __xfrm_mode_tunnel_prep(struct xfrm_state *x, struct sk_buff *skb,
/* Adjust pointers into the packet when IPsec is done at layer2 */ /* Adjust pointers into the packet when IPsec is done at layer2 */
static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb) static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
{ {
switch (x->outer_mode->encap) { switch (x->outer_mode.encap) {
case XFRM_MODE_TUNNEL: case XFRM_MODE_TUNNEL:
if (x->outer_mode->family == AF_INET) if (x->outer_mode.family == AF_INET)
return __xfrm_mode_tunnel_prep(x, skb, return __xfrm_mode_tunnel_prep(x, skb,
sizeof(struct iphdr)); sizeof(struct iphdr));
if (x->outer_mode->family == AF_INET6) if (x->outer_mode.family == AF_INET6)
return __xfrm_mode_tunnel_prep(x, skb, return __xfrm_mode_tunnel_prep(x, skb,
sizeof(struct ipv6hdr)); sizeof(struct ipv6hdr));
break; break;
case XFRM_MODE_TRANSPORT: case XFRM_MODE_TRANSPORT:
if (x->outer_mode->family == AF_INET) if (x->outer_mode.family == AF_INET)
return __xfrm_transport_prep(x, skb, return __xfrm_transport_prep(x, skb,
sizeof(struct iphdr)); sizeof(struct iphdr));
if (x->outer_mode->family == AF_INET6) if (x->outer_mode.family == AF_INET6)
return __xfrm_transport_prep(x, skb, return __xfrm_transport_prep(x, skb,
sizeof(struct ipv6hdr)); sizeof(struct ipv6hdr));
break; break;
......
...@@ -351,12 +351,12 @@ xfrm_inner_mode_encap_remove(struct xfrm_state *x, ...@@ -351,12 +351,12 @@ xfrm_inner_mode_encap_remove(struct xfrm_state *x,
static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
{ {
const struct xfrm_mode *inner_mode = x->inner_mode; const struct xfrm_mode *inner_mode = &x->inner_mode;
const struct xfrm_state_afinfo *afinfo; const struct xfrm_state_afinfo *afinfo;
int err = -EAFNOSUPPORT; int err = -EAFNOSUPPORT;
rcu_read_lock(); rcu_read_lock();
afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode->family); afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family);
if (likely(afinfo)) if (likely(afinfo))
err = afinfo->extract_input(x, skb); err = afinfo->extract_input(x, skb);
...@@ -482,7 +482,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) ...@@ -482,7 +482,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop; goto drop;
} }
family = x->outer_mode->family; family = x->outer_mode.family;
/* An encap_type of -1 indicates async resumption. */ /* An encap_type of -1 indicates async resumption. */
if (encap_type == -1) { if (encap_type == -1) {
...@@ -666,7 +666,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) ...@@ -666,7 +666,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; XFRM_MODE_SKB_CB(skb)->protocol = nexthdr;
inner_mode = x->inner_mode; inner_mode = &x->inner_mode;
if (x->sel.family == AF_UNSPEC) { if (x->sel.family == AF_UNSPEC) {
inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
...@@ -681,7 +681,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) ...@@ -681,7 +681,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop; goto drop;
} }
if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { if (x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL) {
decaps = 1; decaps = 1;
break; break;
} }
...@@ -691,7 +691,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) ...@@ -691,7 +691,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
* transport mode so the outer address is identical. * transport mode so the outer address is identical.
*/ */
daddr = &x->id.daddr; daddr = &x->id.daddr;
family = x->outer_mode->family; family = x->outer_mode.family;
err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
if (err < 0) { if (err < 0) {
...@@ -721,7 +721,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) ...@@ -721,7 +721,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
err = -EAFNOSUPPORT; err = -EAFNOSUPPORT;
rcu_read_lock(); rcu_read_lock();
afinfo = xfrm_state_afinfo_get_rcu(x->inner_mode->family); afinfo = xfrm_state_afinfo_get_rcu(x->inner_mode.family);
if (likely(afinfo)) if (likely(afinfo))
err = afinfo->transport_finish(skb, xfrm_gro || async); err = afinfo->transport_finish(skb, xfrm_gro || async);
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -273,7 +273,7 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err) ...@@ -273,7 +273,7 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
xnet = !net_eq(xi->net, dev_net(skb->dev)); xnet = !net_eq(xi->net, dev_net(skb->dev));
if (xnet) { if (xnet) {
inner_mode = x->inner_mode; inner_mode = &x->inner_mode;
if (x->sel.family == AF_UNSPEC) { if (x->sel.family == AF_UNSPEC) {
inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
......
...@@ -334,7 +334,7 @@ static int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -334,7 +334,7 @@ static int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
skb->protocol = htons(ETH_P_IP); skb->protocol = htons(ETH_P_IP);
switch (x->outer_mode->encap) { switch (x->outer_mode.encap) {
case XFRM_MODE_BEET: case XFRM_MODE_BEET:
return xfrm4_beet_encap_add(x, skb); return xfrm4_beet_encap_add(x, skb);
case XFRM_MODE_TUNNEL: case XFRM_MODE_TUNNEL:
...@@ -357,7 +357,7 @@ static int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -357,7 +357,7 @@ static int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
skb->ignore_df = 1; skb->ignore_df = 1;
skb->protocol = htons(ETH_P_IPV6); skb->protocol = htons(ETH_P_IPV6);
switch (x->outer_mode->encap) { switch (x->outer_mode.encap) {
case XFRM_MODE_BEET: case XFRM_MODE_BEET:
return xfrm6_beet_encap_add(x, skb); return xfrm6_beet_encap_add(x, skb);
case XFRM_MODE_TUNNEL: case XFRM_MODE_TUNNEL:
...@@ -373,22 +373,22 @@ static int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -373,22 +373,22 @@ static int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb) static int xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb)
{ {
switch (x->outer_mode->encap) { switch (x->outer_mode.encap) {
case XFRM_MODE_BEET: case XFRM_MODE_BEET:
case XFRM_MODE_TUNNEL: case XFRM_MODE_TUNNEL:
if (x->outer_mode->family == AF_INET) if (x->outer_mode.family == AF_INET)
return xfrm4_prepare_output(x, skb); return xfrm4_prepare_output(x, skb);
if (x->outer_mode->family == AF_INET6) if (x->outer_mode.family == AF_INET6)
return xfrm6_prepare_output(x, skb); return xfrm6_prepare_output(x, skb);
break; break;
case XFRM_MODE_TRANSPORT: case XFRM_MODE_TRANSPORT:
if (x->outer_mode->family == AF_INET) if (x->outer_mode.family == AF_INET)
return xfrm4_transport_output(x, skb); return xfrm4_transport_output(x, skb);
if (x->outer_mode->family == AF_INET6) if (x->outer_mode.family == AF_INET6)
return xfrm6_transport_output(x, skb); return xfrm6_transport_output(x, skb);
break; break;
case XFRM_MODE_ROUTEOPTIMIZATION: case XFRM_MODE_ROUTEOPTIMIZATION:
if (x->outer_mode->family == AF_INET6) if (x->outer_mode.family == AF_INET6)
return xfrm6_ro_output(x, skb); return xfrm6_ro_output(x, skb);
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
break; break;
...@@ -489,7 +489,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) ...@@ -489,7 +489,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
} }
skb_dst_set(skb, dst); skb_dst_set(skb, dst);
x = dst->xfrm; x = dst->xfrm;
} while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); } while (x && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL));
return 0; return 0;
...@@ -626,7 +626,7 @@ static int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -626,7 +626,7 @@ static int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb)
inner_mode = xfrm_ip2inner_mode(x, inner_mode = xfrm_ip2inner_mode(x,
xfrm_af2proto(skb_dst(skb)->ops->family)); xfrm_af2proto(skb_dst(skb)->ops->family));
else else
inner_mode = x->inner_mode; inner_mode = &x->inner_mode;
if (inner_mode == NULL) if (inner_mode == NULL)
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
......
...@@ -2595,7 +2595,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, ...@@ -2595,7 +2595,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
goto put_states; goto put_states;
} }
} else } else
inner_mode = xfrm[i]->inner_mode; inner_mode = &xfrm[i]->inner_mode;
xdst->route = dst; xdst->route = dst;
dst_copy_metrics(dst1, dst); dst_copy_metrics(dst1, dst);
......
...@@ -551,8 +551,6 @@ struct xfrm_state *xfrm_state_alloc(struct net *net) ...@@ -551,8 +551,6 @@ struct xfrm_state *xfrm_state_alloc(struct net *net)
x->lft.hard_packet_limit = XFRM_INF; x->lft.hard_packet_limit = XFRM_INF;
x->replay_maxage = 0; x->replay_maxage = 0;
x->replay_maxdiff = 0; x->replay_maxdiff = 0;
x->inner_mode = NULL;
x->inner_mode_iaf = NULL;
spin_lock_init(&x->lock); spin_lock_init(&x->lock);
} }
return x; return x;
...@@ -2204,8 +2202,9 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu) ...@@ -2204,8 +2202,9 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu)
int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
{ {
const struct xfrm_mode *inner_mode;
const struct xfrm_state_afinfo *afinfo; const struct xfrm_state_afinfo *afinfo;
const struct xfrm_mode *inner_mode;
const struct xfrm_mode *outer_mode;
int family = x->props.family; int family = x->props.family;
int err; int err;
...@@ -2234,7 +2233,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) ...@@ -2234,7 +2233,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
family != x->sel.family) family != x->sel.family)
goto error; goto error;
x->inner_mode = inner_mode; x->inner_mode = *inner_mode;
} else { } else {
const struct xfrm_mode *inner_mode_iaf; const struct xfrm_mode *inner_mode_iaf;
int iafamily = AF_INET; int iafamily = AF_INET;
...@@ -2246,7 +2245,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) ...@@ -2246,7 +2245,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL))
goto error; goto error;
x->inner_mode = inner_mode; x->inner_mode = *inner_mode;
if (x->props.family == AF_INET) if (x->props.family == AF_INET)
iafamily = AF_INET6; iafamily = AF_INET6;
...@@ -2254,7 +2253,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) ...@@ -2254,7 +2253,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
inner_mode_iaf = xfrm_get_mode(x->props.mode, iafamily); inner_mode_iaf = xfrm_get_mode(x->props.mode, iafamily);
if (inner_mode_iaf) { if (inner_mode_iaf) {
if (inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL) if (inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL)
x->inner_mode_iaf = inner_mode_iaf; x->inner_mode_iaf = *inner_mode_iaf;
} }
} }
...@@ -2268,12 +2267,13 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) ...@@ -2268,12 +2267,13 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
if (err) if (err)
goto error; goto error;
x->outer_mode = xfrm_get_mode(x->props.mode, family); outer_mode = xfrm_get_mode(x->props.mode, family);
if (x->outer_mode == NULL) { if (!outer_mode) {
err = -EPROTONOSUPPORT; err = -EPROTONOSUPPORT;
goto error; goto error;
} }
x->outer_mode = *outer_mode;
if (init_replay) { if (init_replay) {
err = xfrm_init_replay(x); err = xfrm_init_replay(x);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment