summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2019-03-28 04:53:58 +0100
committerDavid S. Miller <davem@davemloft.net>2019-03-29 18:48:04 +0100
commit979e276ebebd537782797c439c9cb42b6d3aba27 (patch)
treee1b340126841f37f96730a0e84d9428344612273 /net/ipv4
parentnet: Add fib_nh_common and update fib_nh and fib6_nh (diff)
downloadlinux-979e276ebebd537782797c439c9cb42b6d3aba27.tar.xz
linux-979e276ebebd537782797c439c9cb42b6d3aba27.zip
net: Use common nexthop init and release helpers
With fib_nh_common in place, move common initialization and release code into helpers used by both ipv4 and ipv6. For the moment, the init is just the lwt encap and the release is both the netdev reference and the the lwt state reference. More will be added later. Signed-off-by: David Ahern <dsahern@gmail.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_semantics.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index e9992407863e..df777af7e278 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -204,16 +204,22 @@ static void rt_fibinfo_free_cpus(struct rtable __rcu * __percpu *rtp)
free_percpu(rtp);
}
+void fib_nh_common_release(struct fib_nh_common *nhc)
+{
+ if (nhc->nhc_dev)
+ dev_put(nhc->nhc_dev);
+
+ lwtstate_put(nhc->nhc_lwtstate);
+}
+EXPORT_SYMBOL_GPL(fib_nh_common_release);
+
void fib_nh_release(struct net *net, struct fib_nh *fib_nh)
{
#ifdef CONFIG_IP_ROUTE_CLASSID
if (fib_nh->nh_tclassid)
net->ipv4.fib_num_tclassid_users--;
#endif
- if (fib_nh->fib_nh_dev)
- dev_put(fib_nh->fib_nh_dev);
-
- lwtstate_put(fib_nh->fib_nh_lws);
+ fib_nh_common_release(&fib_nh->nh_common);
free_nh_exceptions(fib_nh);
rt_fibinfo_free_cpus(fib_nh->nh_pcpu_rth_output);
rt_fibinfo_free(&fib_nh->nh_rth_input);
@@ -462,6 +468,30 @@ static int fib_detect_death(struct fib_info *fi, int order,
return 1;
}
+int fib_nh_common_init(struct fib_nh_common *nhc, struct nlattr *encap,
+ u16 encap_type, void *cfg, gfp_t gfp_flags,
+ struct netlink_ext_ack *extack)
+{
+ if (encap) {
+ struct lwtunnel_state *lwtstate;
+ int err;
+
+ if (encap_type == LWTUNNEL_ENCAP_NONE) {
+ NL_SET_ERR_MSG(extack, "LWT encap type not specified");
+ return -EINVAL;
+ }
+ err = lwtunnel_build_state(encap_type, encap, nhc->nhc_family,
+ cfg, &lwtstate, extack);
+ if (err)
+ return err;
+
+ nhc->nhc_lwtstate = lwtstate_get(lwtstate);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fib_nh_common_init);
+
int fib_nh_init(struct net *net, struct fib_nh *nh,
struct fib_config *cfg, int nh_weight,
struct netlink_ext_ack *extack)
@@ -474,22 +504,10 @@ int fib_nh_init(struct net *net, struct fib_nh *nh,
if (!nh->nh_pcpu_rth_output)
goto err_out;
- if (cfg->fc_encap) {
- struct lwtunnel_state *lwtstate;
-
- err = -EINVAL;
- if (cfg->fc_encap_type == LWTUNNEL_ENCAP_NONE) {
- NL_SET_ERR_MSG(extack, "LWT encap type not specified");
- goto lwt_failure;
- }
- err = lwtunnel_build_state(cfg->fc_encap_type,
- cfg->fc_encap, AF_INET, cfg,
- &lwtstate, extack);
- if (err)
- goto lwt_failure;
-
- nh->fib_nh_lws = lwtstate_get(lwtstate);
- }
+ err = fib_nh_common_init(&nh->nh_common, cfg->fc_encap,
+ cfg->fc_encap_type, cfg, GFP_KERNEL, extack);
+ if (err)
+ goto init_failure;
nh->fib_nh_oif = cfg->fc_oif;
if (cfg->fc_gw) {
@@ -508,7 +526,7 @@ int fib_nh_init(struct net *net, struct fib_nh *nh,
#endif
return 0;
-lwt_failure:
+init_failure:
rt_fibinfo_free_cpus(nh->nh_pcpu_rth_output);
nh->nh_pcpu_rth_output = NULL;
err_out: