diff mbox

[2/6] mpls: split forwarding path on rx/tx boundary

Message ID 20170816170202.456851-3-equinox@diac24.net
State Changes Requested, archived
Delegated to: David Miller
Headers show

Commit Message

David Lamparter Aug. 16, 2017, 5:01 p.m. UTC
This makes mpls_rt_xmit() available for use in upcoming VPLS code.  Same
for mpls_route_input_rcu().

Signed-off-by: David Lamparter <equinox@diac24.net>
---
 net/mpls/af_mpls.c  | 48 ++++++++++++++++++++++++++++++------------------
 net/mpls/internal.h |  4 ++++
 2 files changed, 34 insertions(+), 18 deletions(-)

Comments

kernel test robot Aug. 19, 2017, 5:10 p.m. UTC | #1
Hi David,

[auto build test WARNING on net-next/master]
[also build test WARNING on next-20170817]
[cannot apply to v4.13-rc5]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/David-Lamparter/bridge-learn-dst-metadata-in-FDB/20170820-001849
config: s390-allmodconfig (attached as .config)
compiler: s390x-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=s390 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   In file included from include/uapi/linux/stddef.h:1:0,
                    from include/linux/stddef.h:4,
                    from include/uapi/linux/posix_types.h:4,
                    from include/uapi/linux/types.h:13,
                    from include/linux/types.h:5,
                    from net/mpls/af_mpls.c:1:
   net/mpls/af_mpls.c: In function 'mpls_rt_xmit':
>> include/linux/compiler.h:239:26: warning: 'out_dev' may be used uninitialized in this function [-Wmaybe-uninitialized]
     case 8: *(__u64 *)res = *(volatile __u64 *)p; break;  \
                             ^
   net/mpls/af_mpls.c:384:21: note: 'out_dev' was declared here
     struct net_device *out_dev;
                        ^~~~~~~
--
   In file included from include/uapi/linux/stddef.h:1:0,
                    from include/linux/stddef.h:4,
                    from include/uapi/linux/posix_types.h:4,
                    from include/uapi/linux/types.h:13,
                    from include/linux/types.h:5,
                    from net//mpls/af_mpls.c:1:
   net//mpls/af_mpls.c: In function 'mpls_rt_xmit':
>> include/linux/compiler.h:239:26: warning: 'out_dev' may be used uninitialized in this function [-Wmaybe-uninitialized]
     case 8: *(__u64 *)res = *(volatile __u64 *)p; break;  \
                             ^
   net//mpls/af_mpls.c:384:21: note: 'out_dev' was declared here
     struct net_device *out_dev;
                        ^~~~~~~

vim +/out_dev +239 include/linux/compiler.h

230fa253 Christian Borntraeger 2014-11-25  232  
d976441f Andrey Ryabinin       2015-10-19  233  #define __READ_ONCE_SIZE						\
d976441f Andrey Ryabinin       2015-10-19  234  ({									\
d976441f Andrey Ryabinin       2015-10-19  235  	switch (size) {							\
d976441f Andrey Ryabinin       2015-10-19  236  	case 1: *(__u8 *)res = *(volatile __u8 *)p; break;		\
d976441f Andrey Ryabinin       2015-10-19  237  	case 2: *(__u16 *)res = *(volatile __u16 *)p; break;		\
d976441f Andrey Ryabinin       2015-10-19  238  	case 4: *(__u32 *)res = *(volatile __u32 *)p; break;		\
d976441f Andrey Ryabinin       2015-10-19 @239  	case 8: *(__u64 *)res = *(volatile __u64 *)p; break;		\
d976441f Andrey Ryabinin       2015-10-19  240  	default:							\
d976441f Andrey Ryabinin       2015-10-19  241  		barrier();						\
d976441f Andrey Ryabinin       2015-10-19  242  		__builtin_memcpy((void *)res, (const void *)p, size);	\
d976441f Andrey Ryabinin       2015-10-19  243  		barrier();						\
d976441f Andrey Ryabinin       2015-10-19  244  	}								\
d976441f Andrey Ryabinin       2015-10-19  245  })
d976441f Andrey Ryabinin       2015-10-19  246  

:::::: The code at line 239 was first introduced by commit
:::::: d976441f44bc5d48635d081d277aa76556ffbf8b compiler, atomics, kasan: Provide READ_ONCE_NOCHECK()

:::::: TO: Andrey Ryabinin <aryabinin@virtuozzo.com>
:::::: CC: Ingo Molnar <mingo@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot Aug. 19, 2017, 5:42 p.m. UTC | #2
Hi David,

[auto build test WARNING on net-next/master]
[also build test WARNING on next-20170817]
[cannot apply to v4.13-rc5]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/David-Lamparter/bridge-learn-dst-metadata-in-FDB/20170820-001849
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   net/mpls/af_mpls.c: In function 'mpls_rt_xmit':
>> net/mpls/af_mpls.c:452:45: warning: 'out_dev' may be used uninitialized in this function [-Wmaybe-uninitialized]
     out_mdev = out_dev ? mpls_dev_get(out_dev) : NULL;
                                                ^

vim +/out_dev +452 net/mpls/af_mpls.c

679ee57f David Lamparter   2017-08-16  379  
679ee57f David Lamparter   2017-08-16  380  int mpls_rt_xmit(struct sk_buff *skb, struct mpls_route *rt,
679ee57f David Lamparter   2017-08-16  381  		 struct mpls_entry_decoded dec)
679ee57f David Lamparter   2017-08-16  382  {
679ee57f David Lamparter   2017-08-16  383  	struct mpls_nh *nh;
679ee57f David Lamparter   2017-08-16  384  	struct net_device *out_dev;
679ee57f David Lamparter   2017-08-16  385  	struct mpls_dev *out_mdev;
679ee57f David Lamparter   2017-08-16  386  	unsigned int hh_len;
679ee57f David Lamparter   2017-08-16  387  	unsigned int new_header_size;
679ee57f David Lamparter   2017-08-16  388  	unsigned int mtu;
679ee57f David Lamparter   2017-08-16  389  	int err;
679ee57f David Lamparter   2017-08-16  390  
679ee57f David Lamparter   2017-08-16  391  	nh = mpls_select_multipath(rt, skb);
679ee57f David Lamparter   2017-08-16  392  	if (!nh)
679ee57f David Lamparter   2017-08-16  393  		goto tx_err;
679ee57f David Lamparter   2017-08-16  394  
27d69105 Robert Shearman   2017-01-16  395  	/* Find the output device */
27d69105 Robert Shearman   2017-01-16  396  	out_dev = rcu_dereference(nh->nh_dev);
27d69105 Robert Shearman   2017-01-16  397  	if (!mpls_output_possible(out_dev))
27d69105 Robert Shearman   2017-01-16  398  		goto tx_err;
27d69105 Robert Shearman   2017-01-16  399  
0189197f Eric W. Biederman 2015-03-03  400  	/* Verify the destination can hold the packet */
f8efb73c Roopa Prabhu      2015-10-23  401  	new_header_size = mpls_nh_header_size(nh);
0189197f Eric W. Biederman 2015-03-03  402  	mtu = mpls_dev_mtu(out_dev);
0189197f Eric W. Biederman 2015-03-03  403  	if (mpls_pkt_too_big(skb, mtu - new_header_size))
27d69105 Robert Shearman   2017-01-16  404  		goto tx_err;
0189197f Eric W. Biederman 2015-03-03  405  
0189197f Eric W. Biederman 2015-03-03  406  	hh_len = LL_RESERVED_SPACE(out_dev);
0189197f Eric W. Biederman 2015-03-03  407  	if (!out_dev->header_ops)
0189197f Eric W. Biederman 2015-03-03  408  		hh_len = 0;
0189197f Eric W. Biederman 2015-03-03  409  
0189197f Eric W. Biederman 2015-03-03  410  	/* Ensure there is enough space for the headers in the skb */
0189197f Eric W. Biederman 2015-03-03  411  	if (skb_cow(skb, hh_len + new_header_size))
27d69105 Robert Shearman   2017-01-16  412  		goto tx_err;
0189197f Eric W. Biederman 2015-03-03  413  
0189197f Eric W. Biederman 2015-03-03  414  	skb->dev = out_dev;
0189197f Eric W. Biederman 2015-03-03  415  	skb->protocol = htons(ETH_P_MPLS_UC);
0189197f Eric W. Biederman 2015-03-03  416  
0189197f Eric W. Biederman 2015-03-03  417  	if (unlikely(!new_header_size && dec.bos)) {
0189197f Eric W. Biederman 2015-03-03  418  		/* Penultimate hop popping */
5b441ac8 Robert Shearman   2017-03-10  419  		if (!mpls_egress(dev_net(out_dev), rt, skb, dec))
679ee57f David Lamparter   2017-08-16  420  			goto tx_err;
0189197f Eric W. Biederman 2015-03-03  421  	} else {
679ee57f David Lamparter   2017-08-16  422  		struct mpls_shim_hdr *hdr;
0189197f Eric W. Biederman 2015-03-03  423  		bool bos;
0189197f Eric W. Biederman 2015-03-03  424  		int i;
0189197f Eric W. Biederman 2015-03-03  425  		skb_push(skb, new_header_size);
0189197f Eric W. Biederman 2015-03-03  426  		skb_reset_network_header(skb);
0189197f Eric W. Biederman 2015-03-03  427  		/* Push the new labels */
0189197f Eric W. Biederman 2015-03-03  428  		hdr = mpls_hdr(skb);
0189197f Eric W. Biederman 2015-03-03  429  		bos = dec.bos;
f8efb73c Roopa Prabhu      2015-10-23  430  		for (i = nh->nh_labels - 1; i >= 0; i--) {
f8efb73c Roopa Prabhu      2015-10-23  431  			hdr[i] = mpls_entry_encode(nh->nh_label[i],
f8efb73c Roopa Prabhu      2015-10-23  432  						   dec.ttl, 0, bos);
0189197f Eric W. Biederman 2015-03-03  433  			bos = false;
0189197f Eric W. Biederman 2015-03-03  434  		}
0189197f Eric W. Biederman 2015-03-03  435  	}
0189197f Eric W. Biederman 2015-03-03  436  
27d69105 Robert Shearman   2017-01-16  437  	mpls_stats_inc_outucastpkts(out_dev, skb);
27d69105 Robert Shearman   2017-01-16  438  
eb7809f0 Robert Shearman   2015-12-10  439  	/* If via wasn't specified then send out using device address */
eb7809f0 Robert Shearman   2015-12-10  440  	if (nh->nh_via_table == MPLS_NEIGH_TABLE_UNSPEC)
eb7809f0 Robert Shearman   2015-12-10  441  		err = neigh_xmit(NEIGH_LINK_TABLE, out_dev,
eb7809f0 Robert Shearman   2015-12-10  442  				 out_dev->dev_addr, skb);
eb7809f0 Robert Shearman   2015-12-10  443  	else
eb7809f0 Robert Shearman   2015-12-10  444  		err = neigh_xmit(nh->nh_via_table, out_dev,
eb7809f0 Robert Shearman   2015-12-10  445  				 mpls_nh_via(rt, nh), skb);
0189197f Eric W. Biederman 2015-03-03  446  	if (err)
0189197f Eric W. Biederman 2015-03-03  447  		net_dbg_ratelimited("%s: packet transmission failed: %d\n",
0189197f Eric W. Biederman 2015-03-03  448  				    __func__, err);
0189197f Eric W. Biederman 2015-03-03  449  	return 0;
0189197f Eric W. Biederman 2015-03-03  450  
27d69105 Robert Shearman   2017-01-16  451  tx_err:
27d69105 Robert Shearman   2017-01-16 @452  	out_mdev = out_dev ? mpls_dev_get(out_dev) : NULL;
27d69105 Robert Shearman   2017-01-16  453  	if (out_mdev)
27d69105 Robert Shearman   2017-01-16  454  		MPLS_INC_STATS(out_mdev, tx_errors);
679ee57f David Lamparter   2017-08-16  455  	return -1;
0189197f Eric W. Biederman 2015-03-03  456  }
0189197f Eric W. Biederman 2015-03-03  457  

:::::: The code at line 452 was first introduced by commit
:::::: 27d691056bde4a6feca5e83fd92b787332c46302 mpls: Packet stats

:::::: TO: Robert Shearman <rshearma@brocade.com>
:::::: CC: David S. Miller <davem@davemloft.net>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index c5b9ce41d66f..0c5953e5d5bd 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -43,7 +43,7 @@  static void rtmsg_lfib(int event, u32 label, struct mpls_route *rt,
 		       struct nlmsghdr *nlh, struct net *net, u32 portid,
 		       unsigned int nlm_flags);
 
-static struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned index)
+struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned index)
 {
 	struct mpls_route *rt = NULL;
 
@@ -313,15 +313,8 @@  static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
 	struct net *net = dev_net(dev);
 	struct mpls_shim_hdr *hdr;
 	struct mpls_route *rt;
-	struct mpls_nh *nh;
 	struct mpls_entry_decoded dec;
-	struct net_device *out_dev;
-	struct mpls_dev *out_mdev;
 	struct mpls_dev *mdev;
-	unsigned int hh_len;
-	unsigned int new_header_size;
-	unsigned int mtu;
-	int err;
 
 	/* Careful this entire function runs inside of an rcu critical section */
 
@@ -356,9 +349,6 @@  static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
 		goto drop;
 	}
 
-	nh = mpls_select_multipath(rt, skb);
-	if (!nh)
-		goto err;
 
 	/* Pop the label */
 	skb_pull(skb, sizeof(*hdr));
@@ -376,6 +366,32 @@  static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
 		goto err;
 	dec.ttl -= 1;
 
+	if (mpls_rt_xmit(skb, rt, dec))
+		goto drop;
+	return 0;
+
+err:
+	MPLS_INC_STATS(mdev, rx_errors);
+drop:
+	kfree_skb(skb);
+	return NET_RX_DROP;
+}
+
+int mpls_rt_xmit(struct sk_buff *skb, struct mpls_route *rt,
+		 struct mpls_entry_decoded dec)
+{
+	struct mpls_nh *nh;
+	struct net_device *out_dev;
+	struct mpls_dev *out_mdev;
+	unsigned int hh_len;
+	unsigned int new_header_size;
+	unsigned int mtu;
+	int err;
+
+	nh = mpls_select_multipath(rt, skb);
+	if (!nh)
+		goto tx_err;
+
 	/* Find the output device */
 	out_dev = rcu_dereference(nh->nh_dev);
 	if (!mpls_output_possible(out_dev))
@@ -401,8 +417,9 @@  static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
 	if (unlikely(!new_header_size && dec.bos)) {
 		/* Penultimate hop popping */
 		if (!mpls_egress(dev_net(out_dev), rt, skb, dec))
-			goto err;
+			goto tx_err;
 	} else {
+		struct mpls_shim_hdr *hdr;
 		bool bos;
 		int i;
 		skb_push(skb, new_header_size);
@@ -435,12 +452,7 @@  static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
 	out_mdev = out_dev ? mpls_dev_get(out_dev) : NULL;
 	if (out_mdev)
 		MPLS_INC_STATS(out_mdev, tx_errors);
-	goto drop;
-err:
-	MPLS_INC_STATS(mdev, rx_errors);
-drop:
-	kfree_skb(skb);
-	return NET_RX_DROP;
+	return -1;
 }
 
 static struct packet_type mpls_packet_type __read_mostly = {
diff --git a/net/mpls/internal.h b/net/mpls/internal.h
index cf65aec2e551..b70c6663d4f3 100644
--- a/net/mpls/internal.h
+++ b/net/mpls/internal.h
@@ -210,4 +210,8 @@  bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu);
 void mpls_stats_inc_outucastpkts(struct net_device *dev,
 				 const struct sk_buff *skb);
 
+struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned index);
+int mpls_rt_xmit(struct sk_buff *skb, struct mpls_route *rt,
+		 struct mpls_entry_decoded dec);
+
 #endif /* MPLS_INTERNAL_H */