lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 21 Aug 2008 17:51:24 -0700
From:	Jeff Kirsher <jeffrey.t.kirsher@...el.com>
To:	davem@...emloft.net
Cc:	jeff@...zik.org, netdev@...r.kernel.org,
	Jesse Brandeburg <jesse.brandeburg@...el.com>,
	Jeff Kirsher <jeffrey.t.kirsher@...el.com>
Subject: [PATCH 1/3] LRO: fix return code propogation

From: Jesse Brandeburg <jesse.brandeburg@...el.com>

LRO code needs to propogate the return values from the netif_rx and
netif_receive_skb calls specifically to allow drivers that need that
information to react correctly.  Some places in the code couldn't
return the result of the upcall to the stack, so I added the dropped
counter, which just completes the cache line of the stats struct (on
64-bit), so shouldn't be a big deal.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@...el.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@...el.com>
---

 include/linux/inet_lro.h |    9 +++---
 net/ipv4/inet_lro.c      |   68 +++++++++++++++++++++++++++-------------------
 2 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/include/linux/inet_lro.h b/include/linux/inet_lro.h
index c4335fa..06380ec 100644
--- a/include/linux/inet_lro.h
+++ b/include/linux/inet_lro.h
@@ -39,6 +39,7 @@ struct net_lro_stats {
 	unsigned long aggregated;
 	unsigned long flushed;
 	unsigned long no_desc;
+	unsigned long dropped;
 };
 
 /*
@@ -132,7 +133,7 @@ struct net_lro_mgr {
  *        (for example get_tcp_ip_hdr)
  */
 
-void lro_receive_skb(struct net_lro_mgr *lro_mgr,
+int lro_receive_skb(struct net_lro_mgr *lro_mgr,
 		     struct sk_buff *skb,
 		     void *priv);
 
@@ -140,7 +141,7 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr,
  * Processes a SKB with VLAN HW acceleration support
  */
 
-void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
+int lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
 				  struct sk_buff *skb,
 				  struct vlan_group *vgrp,
 				  u16 vlan_tag,
@@ -161,11 +162,11 @@ void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
  *        (for example get_tcp_ip_hdr)
  */
 
-void lro_receive_frags(struct net_lro_mgr *lro_mgr,
+int lro_receive_frags(struct net_lro_mgr *lro_mgr,
 		       struct skb_frag_struct *frags,
 		       int len, int true_size, void *priv, __wsum sum);
 
-void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
+int lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
 				    struct skb_frag_struct *frags,
 				    int len, int true_size,
 				    struct vlan_group *vgrp,
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c
index cfd034a..918a3a1 100644
--- a/net/ipv4/inet_lro.c
+++ b/net/ipv4/inet_lro.c
@@ -301,9 +301,11 @@ out:
 	return lro_desc;
 }
 
-static void lro_flush(struct net_lro_mgr *lro_mgr,
+static int lro_flush(struct net_lro_mgr *lro_mgr,
 		      struct net_lro_desc *lro_desc)
 {
+	int ret = NET_RX_SUCCESS;
+
 	if (lro_desc->pkt_aggr_cnt > 1)
 		lro_update_tcp_ip_header(lro_desc);
 
@@ -311,23 +313,25 @@ static void lro_flush(struct net_lro_mgr *lro_mgr,
 
 	if (lro_desc->vgrp) {
 		if (lro_mgr->features & LRO_F_NAPI)
-			vlan_hwaccel_receive_skb(lro_desc->parent,
-						 lro_desc->vgrp,
-						 lro_desc->vlan_tag);
+			ret = vlan_hwaccel_receive_skb(lro_desc->parent,
+						       lro_desc->vgrp,
+						       lro_desc->vlan_tag);
 		else
-			vlan_hwaccel_rx(lro_desc->parent,
-					lro_desc->vgrp,
-					lro_desc->vlan_tag);
+			ret = vlan_hwaccel_rx(lro_desc->parent,
+					      lro_desc->vgrp,
+					      lro_desc->vlan_tag);
 
 	} else {
 		if (lro_mgr->features & LRO_F_NAPI)
-			netif_receive_skb(lro_desc->parent);
+			ret = netif_receive_skb(lro_desc->parent);
 		else
-			netif_rx(lro_desc->parent);
+			ret = netif_rx(lro_desc->parent);
 	}
 
 	LRO_INC_STATS(lro_mgr, flushed);
 	lro_clear_desc(lro_desc);
+
+	return ret;
 }
 
 static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
@@ -376,12 +380,14 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
 
 	if ((lro_desc->pkt_aggr_cnt >= lro_mgr->max_aggr) ||
 	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))
-		lro_flush(lro_mgr, lro_desc);
+		if (lro_flush(lro_mgr, lro_desc) == NET_RX_DROP)
+			LRO_INC_STATS(lro_mgr, dropped);
 
 	return 0;
 
 out2: /* send aggregated SKBs to stack */
-	lro_flush(lro_mgr, lro_desc);
+	if (lro_flush(lro_mgr, lro_desc) == NET_RX_DROP)
+		LRO_INC_STATS(lro_mgr, dropped);
 
 out:
 	return 1;
@@ -401,8 +407,10 @@ static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr,
 	int hdr_len = min(len, hlen);
 
 	skb = netdev_alloc_skb(lro_mgr->dev, hlen + lro_mgr->frag_align_pad);
-	if (!skb)
+	if (!skb) {
+		LRO_INC_STATS(lro_mgr, dropped);
 		return NULL;
+	}
 
 	skb_reserve(skb, lro_mgr->frag_align_pad);
 	skb->len = len;
@@ -496,12 +504,14 @@ static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr,
 
 	if ((skb_shinfo(lro_desc->parent)->nr_frags >= lro_mgr->max_aggr) ||
 	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))
-		lro_flush(lro_mgr, lro_desc);
+		if (lro_flush(lro_mgr, lro_desc) == NET_RX_DROP)
+			LRO_INC_STATS(lro_mgr, dropped);
 
 	return NULL;
 
 out2: /* send aggregated packets to the stack */
-	lro_flush(lro_mgr, lro_desc);
+	if (lro_flush(lro_mgr, lro_desc) == NET_RX_DROP)
+		LRO_INC_STATS(lro_mgr, dropped);
 
 out1:  /* Original packet has to be posted to the stack */
 	skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,
@@ -510,20 +520,21 @@ out:
 	return skb;
 }
 
-void lro_receive_skb(struct net_lro_mgr *lro_mgr,
+int lro_receive_skb(struct net_lro_mgr *lro_mgr,
 		     struct sk_buff *skb,
 		     void *priv)
 {
 	if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) {
 		if (lro_mgr->features & LRO_F_NAPI)
-			netif_receive_skb(skb);
+			return netif_receive_skb(skb);
 		else
-			netif_rx(skb);
+			return netif_rx(skb);
 	}
+	return NET_RX_SUCCESS;
 }
 EXPORT_SYMBOL(lro_receive_skb);
 
-void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
+int lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
 				  struct sk_buff *skb,
 				  struct vlan_group *vgrp,
 				  u16 vlan_tag,
@@ -531,14 +542,15 @@ void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
 {
 	if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) {
 		if (lro_mgr->features & LRO_F_NAPI)
-			vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
+			return vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
 		else
-			vlan_hwaccel_rx(skb, vgrp, vlan_tag);
+			return vlan_hwaccel_rx(skb, vgrp, vlan_tag);
 	}
+	return NET_RX_SUCCESS;
 }
 EXPORT_SYMBOL(lro_vlan_hwaccel_receive_skb);
 
-void lro_receive_frags(struct net_lro_mgr *lro_mgr,
+int lro_receive_frags(struct net_lro_mgr *lro_mgr,
 		       struct skb_frag_struct *frags,
 		       int len, int true_size, void *priv, __wsum sum)
 {
@@ -547,16 +559,16 @@ void lro_receive_frags(struct net_lro_mgr *lro_mgr,
 	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, NULL, 0,
 				 priv, sum);
 	if (!skb)
-		return;
+		return NET_RX_SUCCESS;
 
 	if (lro_mgr->features & LRO_F_NAPI)
-		netif_receive_skb(skb);
+		return netif_receive_skb(skb);
 	else
-		netif_rx(skb);
+		return netif_rx(skb);
 }
 EXPORT_SYMBOL(lro_receive_frags);
 
-void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
+int lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
 				    struct skb_frag_struct *frags,
 				    int len, int true_size,
 				    struct vlan_group *vgrp,
@@ -567,12 +579,12 @@ void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
 	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, vgrp,
 				 vlan_tag, priv, sum);
 	if (!skb)
-		return;
+		return NET_RX_SUCCESS;
 
 	if (lro_mgr->features & LRO_F_NAPI)
-		vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
+		return vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
 	else
-		vlan_hwaccel_rx(skb, vgrp, vlan_tag);
+		return vlan_hwaccel_rx(skb, vgrp, vlan_tag);
 }
 EXPORT_SYMBOL(lro_vlan_hwaccel_receive_frags);
 

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ