linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH linux-next] mpls: don't build sysctl related code when sysctl is disabled
@ 2019-06-06 23:57 Matteo Croce
  2019-06-07  0:30 ` Randy Dunlap
  0 siblings, 1 reply; 2+ messages in thread
From: Matteo Croce @ 2019-06-06 23:57 UTC (permalink / raw)
  To: netdev, linux-next, akpm, Randy Dunlap; +Cc: linux-kernel, linux-fsdevel

Some sysctl related code and data structures are never referenced
when CONFIG_SYSCTL is not set.
While this is usually harmless, it produces a build failure since sysctl
shared variables exist, due to missing sysctl_vals symbol:

    ld: net/mpls/af_mpls.o: in function `mpls_platform_labels':
    af_mpls.c:(.text+0x162a): undefined reference to `sysctl_vals'
    ld: net/mpls/af_mpls.o:(.rodata+0x830): undefined reference to `sysctl_vals'
    ld: net/mpls/af_mpls.o:(.rodata+0x838): undefined reference to `sysctl_vals'
    ld: net/mpls/af_mpls.o:(.rodata+0x870): undefined reference to `sysctl_vals'

Fix this by moving all sysctl related code under #ifdef CONFIG_SYSCTL

Reported-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Matteo Croce <mcroce@redhat.com>
---
 net/mpls/af_mpls.c | 389 ++++++++++++++++++++++++---------------------
 1 file changed, 204 insertions(+), 185 deletions(-)

diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index c312741df2ce..5aacbf129ec5 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -37,9 +37,6 @@
 
 #define MPLS_NEIGH_TABLE_UNSPEC (NEIGH_LINK_TABLE + 1)
 
-static int label_limit = (1 << 20) - 1;
-static int ttl_max = 255;
-
 #if IS_ENABLED(CONFIG_NET_IP_TUNNEL)
 static size_t ipgre_mpls_encap_hlen(struct ip_tunnel_encap *e)
 {
@@ -1179,31 +1176,6 @@ static int mpls_netconf_msgsize_devconf(int type)
 	return size;
 }
 
-static void mpls_netconf_notify_devconf(struct net *net, int event,
-					int type, struct mpls_dev *mdev)
-{
-	struct sk_buff *skb;
-	int err = -ENOBUFS;
-
-	skb = nlmsg_new(mpls_netconf_msgsize_devconf(type), GFP_KERNEL);
-	if (!skb)
-		goto errout;
-
-	err = mpls_netconf_fill_devconf(skb, mdev, 0, 0, event, 0, type);
-	if (err < 0) {
-		/* -EMSGSIZE implies BUG in mpls_netconf_msgsize_devconf() */
-		WARN_ON(err == -EMSGSIZE);
-		kfree_skb(skb);
-		goto errout;
-	}
-
-	rtnl_notify(skb, net, 0, RTNLGRP_MPLS_NETCONF, NULL, GFP_KERNEL);
-	return;
-errout:
-	if (err < 0)
-		rtnl_set_sk_err(net, RTNLGRP_MPLS_NETCONF, err);
-}
-
 static const struct nla_policy devconf_mpls_policy[NETCONFA_MAX + 1] = {
 	[NETCONFA_IFINDEX]	= { .len = sizeof(int) },
 };
@@ -1362,6 +1334,36 @@ static int mpls_netconf_dump_devconf(struct sk_buff *skb,
 #define MPLS_PERDEV_SYSCTL_OFFSET(field)	\
 	(&((struct mpls_dev *)0)->field)
 
+#ifdef CONFIG_SYSCTL
+
+static int label_limit = (1 << 20) - 1;
+static int ttl_max = 255;
+
+static void mpls_netconf_notify_devconf(struct net *net, int event,
+					int type, struct mpls_dev *mdev)
+{
+	struct sk_buff *skb;
+	int err = -ENOBUFS;
+
+	skb = nlmsg_new(mpls_netconf_msgsize_devconf(type), GFP_KERNEL);
+	if (!skb)
+		goto errout;
+
+	err = mpls_netconf_fill_devconf(skb, mdev, 0, 0, event, 0, type);
+	if (err < 0) {
+		/* -EMSGSIZE implies BUG in mpls_netconf_msgsize_devconf() */
+		WARN_ON(err == -EMSGSIZE);
+		kfree_skb(skb);
+		goto errout;
+	}
+
+	rtnl_notify(skb, net, 0, RTNLGRP_MPLS_NETCONF, NULL, GFP_KERNEL);
+	return;
+errout:
+	if (err < 0)
+		rtnl_set_sk_err(net, RTNLGRP_MPLS_NETCONF, err);
+}
+
 static int mpls_conf_proc(struct ctl_table *ctl, int write,
 			  void __user *buffer,
 			  size_t *lenp, loff_t *ppos)
@@ -1445,6 +1447,173 @@ static void mpls_dev_sysctl_unregister(struct net_device *dev,
 	mpls_netconf_notify_devconf(net, RTM_DELNETCONF, 0, mdev);
 }
 
+static int resize_platform_label_table(struct net *net, size_t limit)
+{
+	size_t size = sizeof(struct mpls_route *) * limit;
+	size_t old_limit;
+	size_t cp_size;
+	struct mpls_route __rcu **labels = NULL, **old;
+	struct mpls_route *rt0 = NULL, *rt2 = NULL;
+	unsigned index;
+
+	if (size) {
+		labels = kvzalloc(size, GFP_KERNEL);
+		if (!labels)
+			goto nolabels;
+	}
+
+	/* In case the predefined labels need to be populated */
+	if (limit > MPLS_LABEL_IPV4NULL) {
+		struct net_device *lo = net->loopback_dev;
+		rt0 = mpls_rt_alloc(1, lo->addr_len, 0);
+		if (IS_ERR(rt0))
+			goto nort0;
+		RCU_INIT_POINTER(rt0->rt_nh->nh_dev, lo);
+		rt0->rt_protocol = RTPROT_KERNEL;
+		rt0->rt_payload_type = MPT_IPV4;
+		rt0->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT;
+		rt0->rt_nh->nh_via_table = NEIGH_LINK_TABLE;
+		rt0->rt_nh->nh_via_alen = lo->addr_len;
+		memcpy(__mpls_nh_via(rt0, rt0->rt_nh), lo->dev_addr,
+		       lo->addr_len);
+	}
+	if (limit > MPLS_LABEL_IPV6NULL) {
+		struct net_device *lo = net->loopback_dev;
+		rt2 = mpls_rt_alloc(1, lo->addr_len, 0);
+		if (IS_ERR(rt2))
+			goto nort2;
+		RCU_INIT_POINTER(rt2->rt_nh->nh_dev, lo);
+		rt2->rt_protocol = RTPROT_KERNEL;
+		rt2->rt_payload_type = MPT_IPV6;
+		rt2->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT;
+		rt2->rt_nh->nh_via_table = NEIGH_LINK_TABLE;
+		rt2->rt_nh->nh_via_alen = lo->addr_len;
+		memcpy(__mpls_nh_via(rt2, rt2->rt_nh), lo->dev_addr,
+		       lo->addr_len);
+	}
+
+	rtnl_lock();
+	/* Remember the original table */
+	old = rtnl_dereference(net->mpls.platform_label);
+	old_limit = net->mpls.platform_labels;
+
+	/* Free any labels beyond the new table */
+	for (index = limit; index < old_limit; index++)
+		mpls_route_update(net, index, NULL, NULL);
+
+	/* Copy over the old labels */
+	cp_size = size;
+	if (old_limit < limit)
+		cp_size = old_limit * sizeof(struct mpls_route *);
+
+	memcpy(labels, old, cp_size);
+
+	/* If needed set the predefined labels */
+	if ((old_limit <= MPLS_LABEL_IPV6NULL) &&
+	    (limit > MPLS_LABEL_IPV6NULL)) {
+		RCU_INIT_POINTER(labels[MPLS_LABEL_IPV6NULL], rt2);
+		rt2 = NULL;
+	}
+
+	if ((old_limit <= MPLS_LABEL_IPV4NULL) &&
+	    (limit > MPLS_LABEL_IPV4NULL)) {
+		RCU_INIT_POINTER(labels[MPLS_LABEL_IPV4NULL], rt0);
+		rt0 = NULL;
+	}
+
+	/* Update the global pointers */
+	net->mpls.platform_labels = limit;
+	rcu_assign_pointer(net->mpls.platform_label, labels);
+
+	rtnl_unlock();
+
+	mpls_rt_free(rt2);
+	mpls_rt_free(rt0);
+
+	if (old) {
+		synchronize_rcu();
+		kvfree(old);
+	}
+	return 0;
+
+nort2:
+	mpls_rt_free(rt0);
+nort0:
+	kvfree(labels);
+nolabels:
+	return -ENOMEM;
+}
+
+static int mpls_platform_labels(struct ctl_table *table, int write,
+				void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	struct net *net = table->data;
+	int platform_labels = net->mpls.platform_labels;
+	int ret;
+	struct ctl_table tmp = {
+		.procname	= table->procname,
+		.data		= &platform_labels,
+		.maxlen		= sizeof(int),
+		.mode		= table->mode,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= &label_limit,
+	};
+
+	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+	if (write && ret == 0)
+		ret = resize_platform_label_table(net, platform_labels);
+
+	return ret;
+}
+
+#define MPLS_NS_SYSCTL_OFFSET(field)		\
+	(&((struct net *)0)->field)
+
+static const struct ctl_table mpls_table[] = {
+	{
+		.procname	= "platform_labels",
+		.data		= NULL,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= mpls_platform_labels,
+	},
+	{
+		.procname	= "ip_ttl_propagate",
+		.data		= MPLS_NS_SYSCTL_OFFSET(mpls.ip_ttl_propagate),
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= SYSCTL_ONE,
+	},
+	{
+		.procname	= "default_ttl",
+		.data		= MPLS_NS_SYSCTL_OFFSET(mpls.default_ttl),
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= SYSCTL_ONE,
+		.extra2		= &ttl_max,
+	},
+	{ }
+};
+
+#else
+
+static int mpls_dev_sysctl_register(struct net_device *dev,
+				    struct mpls_dev *mdev)
+{
+	return 0;
+}
+
+static void mpls_dev_sysctl_unregister(struct net_device *dev,
+				       struct mpls_dev *mdev)
+{
+}
+
+#endif
+
 static struct mpls_dev *mpls_add_dev(struct net_device *dev)
 {
 	struct mpls_dev *mdev;
@@ -2497,168 +2666,12 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
 	return err;
 }
 
-static int resize_platform_label_table(struct net *net, size_t limit)
-{
-	size_t size = sizeof(struct mpls_route *) * limit;
-	size_t old_limit;
-	size_t cp_size;
-	struct mpls_route __rcu **labels = NULL, **old;
-	struct mpls_route *rt0 = NULL, *rt2 = NULL;
-	unsigned index;
-
-	if (size) {
-		labels = kvzalloc(size, GFP_KERNEL);
-		if (!labels)
-			goto nolabels;
-	}
-
-	/* In case the predefined labels need to be populated */
-	if (limit > MPLS_LABEL_IPV4NULL) {
-		struct net_device *lo = net->loopback_dev;
-		rt0 = mpls_rt_alloc(1, lo->addr_len, 0);
-		if (IS_ERR(rt0))
-			goto nort0;
-		RCU_INIT_POINTER(rt0->rt_nh->nh_dev, lo);
-		rt0->rt_protocol = RTPROT_KERNEL;
-		rt0->rt_payload_type = MPT_IPV4;
-		rt0->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT;
-		rt0->rt_nh->nh_via_table = NEIGH_LINK_TABLE;
-		rt0->rt_nh->nh_via_alen = lo->addr_len;
-		memcpy(__mpls_nh_via(rt0, rt0->rt_nh), lo->dev_addr,
-		       lo->addr_len);
-	}
-	if (limit > MPLS_LABEL_IPV6NULL) {
-		struct net_device *lo = net->loopback_dev;
-		rt2 = mpls_rt_alloc(1, lo->addr_len, 0);
-		if (IS_ERR(rt2))
-			goto nort2;
-		RCU_INIT_POINTER(rt2->rt_nh->nh_dev, lo);
-		rt2->rt_protocol = RTPROT_KERNEL;
-		rt2->rt_payload_type = MPT_IPV6;
-		rt2->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT;
-		rt2->rt_nh->nh_via_table = NEIGH_LINK_TABLE;
-		rt2->rt_nh->nh_via_alen = lo->addr_len;
-		memcpy(__mpls_nh_via(rt2, rt2->rt_nh), lo->dev_addr,
-		       lo->addr_len);
-	}
-
-	rtnl_lock();
-	/* Remember the original table */
-	old = rtnl_dereference(net->mpls.platform_label);
-	old_limit = net->mpls.platform_labels;
-
-	/* Free any labels beyond the new table */
-	for (index = limit; index < old_limit; index++)
-		mpls_route_update(net, index, NULL, NULL);
-
-	/* Copy over the old labels */
-	cp_size = size;
-	if (old_limit < limit)
-		cp_size = old_limit * sizeof(struct mpls_route *);
-
-	memcpy(labels, old, cp_size);
-
-	/* If needed set the predefined labels */
-	if ((old_limit <= MPLS_LABEL_IPV6NULL) &&
-	    (limit > MPLS_LABEL_IPV6NULL)) {
-		RCU_INIT_POINTER(labels[MPLS_LABEL_IPV6NULL], rt2);
-		rt2 = NULL;
-	}
-
-	if ((old_limit <= MPLS_LABEL_IPV4NULL) &&
-	    (limit > MPLS_LABEL_IPV4NULL)) {
-		RCU_INIT_POINTER(labels[MPLS_LABEL_IPV4NULL], rt0);
-		rt0 = NULL;
-	}
-
-	/* Update the global pointers */
-	net->mpls.platform_labels = limit;
-	rcu_assign_pointer(net->mpls.platform_label, labels);
-
-	rtnl_unlock();
-
-	mpls_rt_free(rt2);
-	mpls_rt_free(rt0);
-
-	if (old) {
-		synchronize_rcu();
-		kvfree(old);
-	}
-	return 0;
-
-nort2:
-	mpls_rt_free(rt0);
-nort0:
-	kvfree(labels);
-nolabels:
-	return -ENOMEM;
-}
-
-static int mpls_platform_labels(struct ctl_table *table, int write,
-				void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-	struct net *net = table->data;
-	int platform_labels = net->mpls.platform_labels;
-	int ret;
-	struct ctl_table tmp = {
-		.procname	= table->procname,
-		.data		= &platform_labels,
-		.maxlen		= sizeof(int),
-		.mode		= table->mode,
-		.extra1		= SYSCTL_ZERO,
-		.extra2		= &label_limit,
-	};
-
-	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
-
-	if (write && ret == 0)
-		ret = resize_platform_label_table(net, platform_labels);
-
-	return ret;
-}
-
-#define MPLS_NS_SYSCTL_OFFSET(field)		\
-	(&((struct net *)0)->field)
-
-static const struct ctl_table mpls_table[] = {
-	{
-		.procname	= "platform_labels",
-		.data		= NULL,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= mpls_platform_labels,
-	},
-	{
-		.procname	= "ip_ttl_propagate",
-		.data		= MPLS_NS_SYSCTL_OFFSET(mpls.ip_ttl_propagate),
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= SYSCTL_ZERO,
-		.extra2		= SYSCTL_ONE,
-	},
-	{
-		.procname	= "default_ttl",
-		.data		= MPLS_NS_SYSCTL_OFFSET(mpls.default_ttl),
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= SYSCTL_ONE,
-		.extra2		= &ttl_max,
-	},
-	{ }
-};
-
 static int mpls_net_init(struct net *net)
 {
+#ifdef CONFIG_SYSCTL
 	struct ctl_table *table;
 	int i;
 
-	net->mpls.platform_labels = 0;
-	net->mpls.platform_label = NULL;
-	net->mpls.ip_ttl_propagate = 1;
-	net->mpls.default_ttl = 255;
-
 	table = kmemdup(mpls_table, sizeof(mpls_table), GFP_KERNEL);
 	if (table == NULL)
 		return -ENOMEM;
@@ -2674,6 +2687,12 @@ static int mpls_net_init(struct net *net)
 		kfree(table);
 		return -ENOMEM;
 	}
+#endif
+
+	net->mpls.platform_labels = 0;
+	net->mpls.platform_label = NULL;
+	net->mpls.ip_ttl_propagate = 1;
+	net->mpls.default_ttl = 255;
 
 	return 0;
 }
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH linux-next] mpls: don't build sysctl related code when sysctl is disabled
  2019-06-06 23:57 [PATCH linux-next] mpls: don't build sysctl related code when sysctl is disabled Matteo Croce
@ 2019-06-07  0:30 ` Randy Dunlap
  0 siblings, 0 replies; 2+ messages in thread
From: Randy Dunlap @ 2019-06-07  0:30 UTC (permalink / raw)
  To: Matteo Croce, netdev, linux-next, akpm; +Cc: linux-kernel, linux-fsdevel

On 6/6/19 4:57 PM, Matteo Croce wrote:
> Some sysctl related code and data structures are never referenced
> when CONFIG_SYSCTL is not set.
> While this is usually harmless, it produces a build failure since sysctl
> shared variables exist, due to missing sysctl_vals symbol:
> 
>     ld: net/mpls/af_mpls.o: in function `mpls_platform_labels':
>     af_mpls.c:(.text+0x162a): undefined reference to `sysctl_vals'
>     ld: net/mpls/af_mpls.o:(.rodata+0x830): undefined reference to `sysctl_vals'
>     ld: net/mpls/af_mpls.o:(.rodata+0x838): undefined reference to `sysctl_vals'
>     ld: net/mpls/af_mpls.o:(.rodata+0x870): undefined reference to `sysctl_vals'
> 
> Fix this by moving all sysctl related code under #ifdef CONFIG_SYSCTL
> 
> Reported-by: Randy Dunlap <rdunlap@infradead.org>
> Signed-off-by: Matteo Croce <mcroce@redhat.com>

Builds for me.  Thanks.

Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested

> ---
>  net/mpls/af_mpls.c | 389 ++++++++++++++++++++++++---------------------
>  1 file changed, 204 insertions(+), 185 deletions(-)
> 
> diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
> index c312741df2ce..5aacbf129ec5 100644
> --- a/net/mpls/af_mpls.c
> +++ b/net/mpls/af_mpls.c
> @@ -37,9 +37,6 @@
>  
>  #define MPLS_NEIGH_TABLE_UNSPEC (NEIGH_LINK_TABLE + 1)
>  
> -static int label_limit = (1 << 20) - 1;
> -static int ttl_max = 255;
> -
>  #if IS_ENABLED(CONFIG_NET_IP_TUNNEL)
>  static size_t ipgre_mpls_encap_hlen(struct ip_tunnel_encap *e)
>  {
> @@ -1179,31 +1176,6 @@ static int mpls_netconf_msgsize_devconf(int type)
>  	return size;
>  }
>  
> -static void mpls_netconf_notify_devconf(struct net *net, int event,
> -					int type, struct mpls_dev *mdev)
> -{
> -	struct sk_buff *skb;
> -	int err = -ENOBUFS;
> -
> -	skb = nlmsg_new(mpls_netconf_msgsize_devconf(type), GFP_KERNEL);
> -	if (!skb)
> -		goto errout;
> -
> -	err = mpls_netconf_fill_devconf(skb, mdev, 0, 0, event, 0, type);
> -	if (err < 0) {
> -		/* -EMSGSIZE implies BUG in mpls_netconf_msgsize_devconf() */
> -		WARN_ON(err == -EMSGSIZE);
> -		kfree_skb(skb);
> -		goto errout;
> -	}
> -
> -	rtnl_notify(skb, net, 0, RTNLGRP_MPLS_NETCONF, NULL, GFP_KERNEL);
> -	return;
> -errout:
> -	if (err < 0)
> -		rtnl_set_sk_err(net, RTNLGRP_MPLS_NETCONF, err);
> -}
> -
>  static const struct nla_policy devconf_mpls_policy[NETCONFA_MAX + 1] = {
>  	[NETCONFA_IFINDEX]	= { .len = sizeof(int) },
>  };
> @@ -1362,6 +1334,36 @@ static int mpls_netconf_dump_devconf(struct sk_buff *skb,
>  #define MPLS_PERDEV_SYSCTL_OFFSET(field)	\
>  	(&((struct mpls_dev *)0)->field)
>  
> +#ifdef CONFIG_SYSCTL
> +
> +static int label_limit = (1 << 20) - 1;
> +static int ttl_max = 255;
> +
> +static void mpls_netconf_notify_devconf(struct net *net, int event,
> +					int type, struct mpls_dev *mdev)
> +{
> +	struct sk_buff *skb;
> +	int err = -ENOBUFS;
> +
> +	skb = nlmsg_new(mpls_netconf_msgsize_devconf(type), GFP_KERNEL);
> +	if (!skb)
> +		goto errout;
> +
> +	err = mpls_netconf_fill_devconf(skb, mdev, 0, 0, event, 0, type);
> +	if (err < 0) {
> +		/* -EMSGSIZE implies BUG in mpls_netconf_msgsize_devconf() */
> +		WARN_ON(err == -EMSGSIZE);
> +		kfree_skb(skb);
> +		goto errout;
> +	}
> +
> +	rtnl_notify(skb, net, 0, RTNLGRP_MPLS_NETCONF, NULL, GFP_KERNEL);
> +	return;
> +errout:
> +	if (err < 0)
> +		rtnl_set_sk_err(net, RTNLGRP_MPLS_NETCONF, err);
> +}
> +
>  static int mpls_conf_proc(struct ctl_table *ctl, int write,
>  			  void __user *buffer,
>  			  size_t *lenp, loff_t *ppos)
> @@ -1445,6 +1447,173 @@ static void mpls_dev_sysctl_unregister(struct net_device *dev,
>  	mpls_netconf_notify_devconf(net, RTM_DELNETCONF, 0, mdev);
>  }
>  
> +static int resize_platform_label_table(struct net *net, size_t limit)
> +{
> +	size_t size = sizeof(struct mpls_route *) * limit;
> +	size_t old_limit;
> +	size_t cp_size;
> +	struct mpls_route __rcu **labels = NULL, **old;
> +	struct mpls_route *rt0 = NULL, *rt2 = NULL;
> +	unsigned index;
> +
> +	if (size) {
> +		labels = kvzalloc(size, GFP_KERNEL);
> +		if (!labels)
> +			goto nolabels;
> +	}
> +
> +	/* In case the predefined labels need to be populated */
> +	if (limit > MPLS_LABEL_IPV4NULL) {
> +		struct net_device *lo = net->loopback_dev;
> +		rt0 = mpls_rt_alloc(1, lo->addr_len, 0);
> +		if (IS_ERR(rt0))
> +			goto nort0;
> +		RCU_INIT_POINTER(rt0->rt_nh->nh_dev, lo);
> +		rt0->rt_protocol = RTPROT_KERNEL;
> +		rt0->rt_payload_type = MPT_IPV4;
> +		rt0->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT;
> +		rt0->rt_nh->nh_via_table = NEIGH_LINK_TABLE;
> +		rt0->rt_nh->nh_via_alen = lo->addr_len;
> +		memcpy(__mpls_nh_via(rt0, rt0->rt_nh), lo->dev_addr,
> +		       lo->addr_len);
> +	}
> +	if (limit > MPLS_LABEL_IPV6NULL) {
> +		struct net_device *lo = net->loopback_dev;
> +		rt2 = mpls_rt_alloc(1, lo->addr_len, 0);
> +		if (IS_ERR(rt2))
> +			goto nort2;
> +		RCU_INIT_POINTER(rt2->rt_nh->nh_dev, lo);
> +		rt2->rt_protocol = RTPROT_KERNEL;
> +		rt2->rt_payload_type = MPT_IPV6;
> +		rt2->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT;
> +		rt2->rt_nh->nh_via_table = NEIGH_LINK_TABLE;
> +		rt2->rt_nh->nh_via_alen = lo->addr_len;
> +		memcpy(__mpls_nh_via(rt2, rt2->rt_nh), lo->dev_addr,
> +		       lo->addr_len);
> +	}
> +
> +	rtnl_lock();
> +	/* Remember the original table */
> +	old = rtnl_dereference(net->mpls.platform_label);
> +	old_limit = net->mpls.platform_labels;
> +
> +	/* Free any labels beyond the new table */
> +	for (index = limit; index < old_limit; index++)
> +		mpls_route_update(net, index, NULL, NULL);
> +
> +	/* Copy over the old labels */
> +	cp_size = size;
> +	if (old_limit < limit)
> +		cp_size = old_limit * sizeof(struct mpls_route *);
> +
> +	memcpy(labels, old, cp_size);
> +
> +	/* If needed set the predefined labels */
> +	if ((old_limit <= MPLS_LABEL_IPV6NULL) &&
> +	    (limit > MPLS_LABEL_IPV6NULL)) {
> +		RCU_INIT_POINTER(labels[MPLS_LABEL_IPV6NULL], rt2);
> +		rt2 = NULL;
> +	}
> +
> +	if ((old_limit <= MPLS_LABEL_IPV4NULL) &&
> +	    (limit > MPLS_LABEL_IPV4NULL)) {
> +		RCU_INIT_POINTER(labels[MPLS_LABEL_IPV4NULL], rt0);
> +		rt0 = NULL;
> +	}
> +
> +	/* Update the global pointers */
> +	net->mpls.platform_labels = limit;
> +	rcu_assign_pointer(net->mpls.platform_label, labels);
> +
> +	rtnl_unlock();
> +
> +	mpls_rt_free(rt2);
> +	mpls_rt_free(rt0);
> +
> +	if (old) {
> +		synchronize_rcu();
> +		kvfree(old);
> +	}
> +	return 0;
> +
> +nort2:
> +	mpls_rt_free(rt0);
> +nort0:
> +	kvfree(labels);
> +nolabels:
> +	return -ENOMEM;
> +}
> +
> +static int mpls_platform_labels(struct ctl_table *table, int write,
> +				void __user *buffer, size_t *lenp, loff_t *ppos)
> +{
> +	struct net *net = table->data;
> +	int platform_labels = net->mpls.platform_labels;
> +	int ret;
> +	struct ctl_table tmp = {
> +		.procname	= table->procname,
> +		.data		= &platform_labels,
> +		.maxlen		= sizeof(int),
> +		.mode		= table->mode,
> +		.extra1		= SYSCTL_ZERO,
> +		.extra2		= &label_limit,
> +	};
> +
> +	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
> +
> +	if (write && ret == 0)
> +		ret = resize_platform_label_table(net, platform_labels);
> +
> +	return ret;
> +}
> +
> +#define MPLS_NS_SYSCTL_OFFSET(field)		\
> +	(&((struct net *)0)->field)
> +
> +static const struct ctl_table mpls_table[] = {
> +	{
> +		.procname	= "platform_labels",
> +		.data		= NULL,
> +		.maxlen		= sizeof(int),
> +		.mode		= 0644,
> +		.proc_handler	= mpls_platform_labels,
> +	},
> +	{
> +		.procname	= "ip_ttl_propagate",
> +		.data		= MPLS_NS_SYSCTL_OFFSET(mpls.ip_ttl_propagate),
> +		.maxlen		= sizeof(int),
> +		.mode		= 0644,
> +		.proc_handler	= proc_dointvec_minmax,
> +		.extra1		= SYSCTL_ZERO,
> +		.extra2		= SYSCTL_ONE,
> +	},
> +	{
> +		.procname	= "default_ttl",
> +		.data		= MPLS_NS_SYSCTL_OFFSET(mpls.default_ttl),
> +		.maxlen		= sizeof(int),
> +		.mode		= 0644,
> +		.proc_handler	= proc_dointvec_minmax,
> +		.extra1		= SYSCTL_ONE,
> +		.extra2		= &ttl_max,
> +	},
> +	{ }
> +};
> +
> +#else
> +
> +static int mpls_dev_sysctl_register(struct net_device *dev,
> +				    struct mpls_dev *mdev)
> +{
> +	return 0;
> +}
> +
> +static void mpls_dev_sysctl_unregister(struct net_device *dev,
> +				       struct mpls_dev *mdev)
> +{
> +}
> +
> +#endif
> +
>  static struct mpls_dev *mpls_add_dev(struct net_device *dev)
>  {
>  	struct mpls_dev *mdev;
> @@ -2497,168 +2666,12 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
>  	return err;
>  }
>  
> -static int resize_platform_label_table(struct net *net, size_t limit)
> -{
> -	size_t size = sizeof(struct mpls_route *) * limit;
> -	size_t old_limit;
> -	size_t cp_size;
> -	struct mpls_route __rcu **labels = NULL, **old;
> -	struct mpls_route *rt0 = NULL, *rt2 = NULL;
> -	unsigned index;
> -
> -	if (size) {
> -		labels = kvzalloc(size, GFP_KERNEL);
> -		if (!labels)
> -			goto nolabels;
> -	}
> -
> -	/* In case the predefined labels need to be populated */
> -	if (limit > MPLS_LABEL_IPV4NULL) {
> -		struct net_device *lo = net->loopback_dev;
> -		rt0 = mpls_rt_alloc(1, lo->addr_len, 0);
> -		if (IS_ERR(rt0))
> -			goto nort0;
> -		RCU_INIT_POINTER(rt0->rt_nh->nh_dev, lo);
> -		rt0->rt_protocol = RTPROT_KERNEL;
> -		rt0->rt_payload_type = MPT_IPV4;
> -		rt0->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT;
> -		rt0->rt_nh->nh_via_table = NEIGH_LINK_TABLE;
> -		rt0->rt_nh->nh_via_alen = lo->addr_len;
> -		memcpy(__mpls_nh_via(rt0, rt0->rt_nh), lo->dev_addr,
> -		       lo->addr_len);
> -	}
> -	if (limit > MPLS_LABEL_IPV6NULL) {
> -		struct net_device *lo = net->loopback_dev;
> -		rt2 = mpls_rt_alloc(1, lo->addr_len, 0);
> -		if (IS_ERR(rt2))
> -			goto nort2;
> -		RCU_INIT_POINTER(rt2->rt_nh->nh_dev, lo);
> -		rt2->rt_protocol = RTPROT_KERNEL;
> -		rt2->rt_payload_type = MPT_IPV6;
> -		rt2->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT;
> -		rt2->rt_nh->nh_via_table = NEIGH_LINK_TABLE;
> -		rt2->rt_nh->nh_via_alen = lo->addr_len;
> -		memcpy(__mpls_nh_via(rt2, rt2->rt_nh), lo->dev_addr,
> -		       lo->addr_len);
> -	}
> -
> -	rtnl_lock();
> -	/* Remember the original table */
> -	old = rtnl_dereference(net->mpls.platform_label);
> -	old_limit = net->mpls.platform_labels;
> -
> -	/* Free any labels beyond the new table */
> -	for (index = limit; index < old_limit; index++)
> -		mpls_route_update(net, index, NULL, NULL);
> -
> -	/* Copy over the old labels */
> -	cp_size = size;
> -	if (old_limit < limit)
> -		cp_size = old_limit * sizeof(struct mpls_route *);
> -
> -	memcpy(labels, old, cp_size);
> -
> -	/* If needed set the predefined labels */
> -	if ((old_limit <= MPLS_LABEL_IPV6NULL) &&
> -	    (limit > MPLS_LABEL_IPV6NULL)) {
> -		RCU_INIT_POINTER(labels[MPLS_LABEL_IPV6NULL], rt2);
> -		rt2 = NULL;
> -	}
> -
> -	if ((old_limit <= MPLS_LABEL_IPV4NULL) &&
> -	    (limit > MPLS_LABEL_IPV4NULL)) {
> -		RCU_INIT_POINTER(labels[MPLS_LABEL_IPV4NULL], rt0);
> -		rt0 = NULL;
> -	}
> -
> -	/* Update the global pointers */
> -	net->mpls.platform_labels = limit;
> -	rcu_assign_pointer(net->mpls.platform_label, labels);
> -
> -	rtnl_unlock();
> -
> -	mpls_rt_free(rt2);
> -	mpls_rt_free(rt0);
> -
> -	if (old) {
> -		synchronize_rcu();
> -		kvfree(old);
> -	}
> -	return 0;
> -
> -nort2:
> -	mpls_rt_free(rt0);
> -nort0:
> -	kvfree(labels);
> -nolabels:
> -	return -ENOMEM;
> -}
> -
> -static int mpls_platform_labels(struct ctl_table *table, int write,
> -				void __user *buffer, size_t *lenp, loff_t *ppos)
> -{
> -	struct net *net = table->data;
> -	int platform_labels = net->mpls.platform_labels;
> -	int ret;
> -	struct ctl_table tmp = {
> -		.procname	= table->procname,
> -		.data		= &platform_labels,
> -		.maxlen		= sizeof(int),
> -		.mode		= table->mode,
> -		.extra1		= SYSCTL_ZERO,
> -		.extra2		= &label_limit,
> -	};
> -
> -	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
> -
> -	if (write && ret == 0)
> -		ret = resize_platform_label_table(net, platform_labels);
> -
> -	return ret;
> -}
> -
> -#define MPLS_NS_SYSCTL_OFFSET(field)		\
> -	(&((struct net *)0)->field)
> -
> -static const struct ctl_table mpls_table[] = {
> -	{
> -		.procname	= "platform_labels",
> -		.data		= NULL,
> -		.maxlen		= sizeof(int),
> -		.mode		= 0644,
> -		.proc_handler	= mpls_platform_labels,
> -	},
> -	{
> -		.procname	= "ip_ttl_propagate",
> -		.data		= MPLS_NS_SYSCTL_OFFSET(mpls.ip_ttl_propagate),
> -		.maxlen		= sizeof(int),
> -		.mode		= 0644,
> -		.proc_handler	= proc_dointvec_minmax,
> -		.extra1		= SYSCTL_ZERO,
> -		.extra2		= SYSCTL_ONE,
> -	},
> -	{
> -		.procname	= "default_ttl",
> -		.data		= MPLS_NS_SYSCTL_OFFSET(mpls.default_ttl),
> -		.maxlen		= sizeof(int),
> -		.mode		= 0644,
> -		.proc_handler	= proc_dointvec_minmax,
> -		.extra1		= SYSCTL_ONE,
> -		.extra2		= &ttl_max,
> -	},
> -	{ }
> -};
> -
>  static int mpls_net_init(struct net *net)
>  {
> +#ifdef CONFIG_SYSCTL
>  	struct ctl_table *table;
>  	int i;
>  
> -	net->mpls.platform_labels = 0;
> -	net->mpls.platform_label = NULL;
> -	net->mpls.ip_ttl_propagate = 1;
> -	net->mpls.default_ttl = 255;
> -
>  	table = kmemdup(mpls_table, sizeof(mpls_table), GFP_KERNEL);
>  	if (table == NULL)
>  		return -ENOMEM;
> @@ -2674,6 +2687,12 @@ static int mpls_net_init(struct net *net)
>  		kfree(table);
>  		return -ENOMEM;
>  	}
> +#endif
> +
> +	net->mpls.platform_labels = 0;
> +	net->mpls.platform_label = NULL;
> +	net->mpls.ip_ttl_propagate = 1;
> +	net->mpls.default_ttl = 255;
>  
>  	return 0;
>  }
> 


-- 
~Randy

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-06-07  0:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-06 23:57 [PATCH linux-next] mpls: don't build sysctl related code when sysctl is disabled Matteo Croce
2019-06-07  0:30 ` Randy Dunlap

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).