diff mbox series

[net-next] ipv6: report errors for iftoken via netlink extack

Message ID 20210406233954.217139-1-sthemmin@microsoft.com
State Superseded
Headers show
Series [net-next] ipv6: report errors for iftoken via netlink extack | expand

Commit Message

Stephen Hemminger April 6, 2021, 11:39 p.m. UTC
From: Stephen Hemminger <stephen@networkplumber.org>

Setting iftoken can fail for several different reasons but there
and there was no report to user as to the cause. Add netlink
extended errors to the processing of the request.

This requires adding additional argument through rtnl_af_ops
set_link_af callback.

Reported-by: Hongren Zheng <li@zenithal.me>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 include/net/rtnetlink.h |  4 ++--
 net/core/rtnetlink.c    |  2 +-
 net/ipv4/devinet.c      |  3 ++-
 net/ipv6/addrconf.c     | 32 ++++++++++++++++++++++++++------
 4 files changed, 31 insertions(+), 10 deletions(-)

Comments

kernel test robot April 7, 2021, 2:50 a.m. UTC | #1
Hi Stephen,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Stephen-Hemminger/ipv6-report-errors-for-iftoken-via-netlink-extack/20210407-074055
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git cc0626c2aaed8e475efdd85fa374b497a7192e35
config: arm64-randconfig-r012-20210406 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project c060945b23a1c54d4b2a053ff4b093a2277b303d)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/a956d0358f015f0aaac67cb9279199dce74cda56
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Stephen-Hemminger/ipv6-report-errors-for-iftoken-via-netlink-extack/20210407-074055
        git checkout a956d0358f015f0aaac67cb9279199dce74cda56
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> net/ipv6/addrconf.c:5707:55: error: expected ';' after do/while statement
                                  "Router solicitation is disabled on device"));
                                                                              ^
                                                                              ;
   1 error generated.


vim +5707 net/ipv6/addrconf.c

  5674	
  5675	static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token,
  5676				     struct netlink_ext_ack *extack)
  5677	{
  5678		struct inet6_ifaddr *ifp;
  5679		struct net_device *dev = idev->dev;
  5680		bool clear_token, update_rs = false;
  5681		struct in6_addr ll_addr;
  5682	
  5683		ASSERT_RTNL();
  5684	
  5685		if (!token)
  5686			return -EINVAL;
  5687	
  5688		if (dev->flags & IFF_LOOPBACK) {
  5689			NL_SET_ERR_MSG_MOD(extack, "Device is loopback");
  5690			return -EINVAL;
  5691		}
  5692	
  5693		if (dev->flags & IFF_NOARP) {
  5694			NL_SET_ERR_MSG_MOD(extack,
  5695					   "Device does not do neighbour discovery");
  5696			return -EINVAL;
  5697		}
  5698	
  5699		if (!ipv6_accept_ra(idev)) {
  5700			NL_SET_ERR_MSG_MOD(extack,
  5701					   "Router advertisement is disabled on device");
  5702			return -EINVAL;
  5703		}
  5704	
  5705		if (idev->cnf.rtr_solicits == 0) {
  5706			NL_SET_ERR_MSG(extack,
> 5707				       "Router solicitation is disabled on device"));
  5708			return -EINVAL;
  5709		}
  5710	
  5711		write_lock_bh(&idev->lock);
  5712	
  5713		BUILD_BUG_ON(sizeof(token->s6_addr) != 16);
  5714		memcpy(idev->token.s6_addr + 8, token->s6_addr + 8, 8);
  5715	
  5716		write_unlock_bh(&idev->lock);
  5717	
  5718		clear_token = ipv6_addr_any(token);
  5719		if (clear_token)
  5720			goto update_lft;
  5721	
  5722		if (!idev->dead && (idev->if_flags & IF_READY) &&
  5723		    !ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE |
  5724				     IFA_F_OPTIMISTIC)) {
  5725			/* If we're not ready, then normal ifup will take care
  5726			 * of this. Otherwise, we need to request our rs here.
  5727			 */
  5728			ndisc_send_rs(dev, &ll_addr, &in6addr_linklocal_allrouters);
  5729			update_rs = true;
  5730		}
  5731	
  5732	update_lft:
  5733		write_lock_bh(&idev->lock);
  5734	
  5735		if (update_rs) {
  5736			idev->if_flags |= IF_RS_SENT;
  5737			idev->rs_interval = rfc3315_s14_backoff_init(
  5738				idev->cnf.rtr_solicit_interval);
  5739			idev->rs_probes = 1;
  5740			addrconf_mod_rs_timer(idev, idev->rs_interval);
  5741		}
  5742	
  5743		/* Well, that's kinda nasty ... */
  5744		list_for_each_entry(ifp, &idev->addr_list, if_list) {
  5745			spin_lock(&ifp->lock);
  5746			if (ifp->tokenized) {
  5747				ifp->valid_lft = 0;
  5748				ifp->prefered_lft = 0;
  5749			}
  5750			spin_unlock(&ifp->lock);
  5751		}
  5752	
  5753		write_unlock_bh(&idev->lock);
  5754		inet6_ifinfo_notify(RTM_NEWLINK, idev);
  5755		addrconf_verify_rtnl();
  5756		return 0;
  5757	}
  5758	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 4da61c950e93..479f60ef54c0 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -147,8 +147,8 @@  struct rtnl_af_ops {
 	int			(*validate_link_af)(const struct net_device *dev,
 						    const struct nlattr *attr);
 	int			(*set_link_af)(struct net_device *dev,
-					       const struct nlattr *attr);
-
+					       const struct nlattr *attr,
+					       struct netlink_ext_ack *extack);
 	int			(*fill_stats_af)(struct sk_buff *skb,
 						 const struct net_device *dev);
 	size_t			(*get_stats_af_size)(const struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d51252afde0a..641c2bd0e221 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2874,7 +2874,7 @@  static int do_setlink(const struct sk_buff *skb,
 
 			BUG_ON(!(af_ops = rtnl_af_lookup(nla_type(af))));
 
-			err = af_ops->set_link_af(dev, af);
+			err = af_ops->set_link_af(dev, af, extack);
 			if (err < 0) {
 				rcu_read_unlock();
 				goto errout;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 75f67994fc85..2e35f68da40a 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1978,7 +1978,8 @@  static int inet_validate_link_af(const struct net_device *dev,
 	return 0;
 }
 
-static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
+static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla,
+			    struct netlink_ext_ack *extack)
 {
 	struct in_device *in_dev = __in_dev_get_rcu(dev);
 	struct nlattr *a, *tb[IFLA_INET_MAX+1];
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 120073ffb666..1afd4bdc0d5b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5672,7 +5672,8 @@  static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
 	return 0;
 }
 
-static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
+static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token,
+			     struct netlink_ext_ack *extack)
 {
 	struct inet6_ifaddr *ifp;
 	struct net_device *dev = idev->dev;
@@ -5683,12 +5684,29 @@  static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
 
 	if (!token)
 		return -EINVAL;
-	if (dev->flags & (IFF_LOOPBACK | IFF_NOARP))
+
+	if (dev->flags & IFF_LOOPBACK) {
+		NL_SET_ERR_MSG_MOD(extack, "Device is loopback");
 		return -EINVAL;
-	if (!ipv6_accept_ra(idev))
+	}
+
+	if (dev->flags & IFF_NOARP) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Device does not do neighbour discovery");
+		return -EINVAL;
+	}
+
+	if (!ipv6_accept_ra(idev)) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Router advertisement is disabled on device");
 		return -EINVAL;
-	if (idev->cnf.rtr_solicits == 0)
+	}
+
+	if (idev->cnf.rtr_solicits == 0) {
+		NL_SET_ERR_MSG(extack,
+			       "Router solicitation is disabled on device"));
 		return -EINVAL;
+	}
 
 	write_lock_bh(&idev->lock);
 
@@ -5796,7 +5814,8 @@  static int inet6_validate_link_af(const struct net_device *dev,
 	return 0;
 }
 
-static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
+static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla,
+			     struct netlink_ext_ack *extack)
 {
 	struct inet6_dev *idev = __in6_dev_get(dev);
 	struct nlattr *tb[IFLA_INET6_MAX + 1];
@@ -5809,7 +5828,8 @@  static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
 		BUG();
 
 	if (tb[IFLA_INET6_TOKEN]) {
-		err = inet6_set_iftoken(idev, nla_data(tb[IFLA_INET6_TOKEN]));
+		err = inet6_set_iftoken(idev, nla_data(tb[IFLA_INET6_TOKEN]),
+					extack);
 		if (err)
 			return err;
 	}