diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/act_tunnel_key.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index 9104b8e36482..3404af72b4c1 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c @@ -321,12 +321,18 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, goto err_out; } +#ifdef CONFIG_DST_CACHE + ret = dst_cache_init(&metadata->u.tun_info.dst_cache, GFP_KERNEL); + if (ret) + goto release_tun_meta; +#endif + if (opts_len) { ret = tunnel_key_opts_set(tb[TCA_TUNNEL_KEY_ENC_OPTS], &metadata->u.tun_info, opts_len, extack); if (ret < 0) - goto release_tun_meta; + goto release_dst_cache; } metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX; @@ -342,14 +348,14 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, &act_tunnel_key_ops, bind, true); if (ret) { NL_SET_ERR_MSG(extack, "Cannot create TC IDR"); - goto release_tun_meta; + goto release_dst_cache; } ret = ACT_P_CREATED; } else if (!ovr) { NL_SET_ERR_MSG(extack, "TC IDR already exists"); ret = -EEXIST; - goto release_tun_meta; + goto release_dst_cache; } t = to_tunnel_key(*a); @@ -359,7 +365,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, NL_SET_ERR_MSG(extack, "Cannot allocate tunnel key parameters"); ret = -ENOMEM; exists = true; - goto release_tun_meta; + goto release_dst_cache; } params_new->tcft_action = parm->t_action; params_new->tcft_enc_metadata = metadata; @@ -376,6 +382,10 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, return ret; +release_dst_cache: +#ifdef CONFIG_DST_CACHE + dst_cache_destroy(&metadata->u.tun_info.dst_cache); +#endif release_tun_meta: dst_release(&metadata->dst); @@ -391,8 +401,15 @@ static void tunnel_key_release(struct tc_action *a) { struct tcf_tunnel_key *t = to_tunnel_key(a); struct tcf_tunnel_key_params *params; +#ifdef CONFIG_DST_CACHE + struct ip_tunnel_info *info; +#endif params = rcu_dereference_protected(t->params, 1); +#ifdef CONFIG_DST_CACHE + info = ¶ms->tcft_enc_metadata->u.tun_info; + dst_cache_destroy(&info->dst_cache); +#endif tunnel_key_release_params(params); } |