This patch adds a new function dev_skb_segment() that generalises
the existing dev_gso_segment() by allowing to give a segmentation
function. mac80211 will use that function using the segmentation
function skb_segment().
This patch also changes dev_gso_skb_destructor() to be safe when
the skb no longer has any segments, this will happen when mac80211
has internally passed off all the fragments to the driver instead
of asking dev_hard_start_xmit() to do it (which protects against
this by resetting the destructor if it has sent all fragments.)
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
---
include/linux/netdevice.h | 1 +
net/core/dev.c | 38 ++++++++++++++++++++++++++++++--------
2 files changed, 31 insertions(+), 8 deletions(-)
--- everything.orig/net/core/dev.c 2008-04-30 01:52:23.000000000 +0200
+++ everything/net/core/dev.c 2008-04-30 03:46:33.000000000 +0200
@@ -1491,13 +1491,13 @@ static void dev_gso_skb_destructor(struc
{
struct dev_gso_cb *cb;
- do {
+ while (skb->next) {
struct sk_buff *nskb = skb->next;
skb->next = nskb->next;
nskb->next = NULL;
kfree_skb(nskb);
- } while (skb->next);
+ }
cb = DEV_GSO_CB(skb);
if (cb->destructor)
@@ -1505,22 +1505,31 @@ static void dev_gso_skb_destructor(struc
}
/**
- * dev_gso_segment - Perform emulated hardware segmentation on skb.
+ * dev_skb_segment - Perform segmentation on skb.
* @skb: buffer to segment
+ * @segmfn: function that does the actual segmentation
*
- * This function segments the given skb and stores the list of segments
- * in skb->next.
+ * This function segments the given skb and stores the list
+ * of segments in skb->next. The segmentation function is
+ * used to do the actual segmentation, it must return the
+ * list of segments as chained via the returned skb's @next
+ * pointer. The segmentation function is given the skb to
+ * segment and the features of the device the skb is going
+ * to. The segmentation function needs to return an ERR_PTR
+ * or a valid sk_buff pointer (or NULL for no segments.)
+ *
+ * Note that segmentation needs the skbs @cb data.
*/
-static int dev_gso_segment(struct sk_buff *skb)
+int dev_skb_segment(struct sk_buff *skb, struct sk_buff *(segmfn)(struct sk_buff *skb, int feat))
{
struct net_device *dev = skb->dev;
struct sk_buff *segs;
int features = dev->features & ~(illegal_highdma(dev, skb) ?
NETIF_F_SG : 0);
- segs = skb_gso_segment(skb, features);
+ segs = segmfn(skb, features);
- /* Verifying header integrity only. */
+ /* Verifying header integrity only/no segments required. */
if (!segs)
return 0;
@@ -1533,6 +1542,19 @@ static int dev_gso_segment(struct sk_buf
return 0;
}
+EXPORT_SYMBOL_GPL(dev_skb_segment);
+
+/**
+ * dev_gso_segment - Perform emulated hardware segmentation on skb.
+ * @skb: buffer to segment
+ *
+ * This function segments the given skb and stores the list of segments
+ * in skb->next.
+ */
+static int dev_gso_segment(struct sk_buff *skb)
+{
+ return dev_skb_segment(skb, skb_gso_segment);
+}
int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
--- everything.orig/include/linux/netdevice.h 2008-04-30 01:52:23.000000000 +0200
+++ everything/include/linux/netdevice.h 2008-04-30 01:52:26.000000000 +0200
@@ -1454,6 +1454,7 @@ extern int weight_p;
extern int netdev_set_master(struct net_device *dev, struct net_device *master);
extern int skb_checksum_help(struct sk_buff *skb);
extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
+extern int dev_skb_segment(struct sk_buff *skb, struct sk_buff *(segmfn)(struct sk_buff *skb, int feat));
#ifdef CONFIG_BUG
extern void netdev_rx_csum_fault(struct net_device *dev);
#else
--
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html| Davide Libenzi | [patch 7/8] fdmap v2 - implement sys_socket2 |
| Greg Kroah-Hartman | [PATCH 018/196] coda: convert struct class_device to struct device |
| Bart Van Assche | Integration of SCST in the mainstream Linux kernel |
| David Newall | Re: Slow DOWN, please!!! |
git: | |
| Christoph Lameter | Network latency regressions from 2.6.22 to 2.6.29 |
| David Miller | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Arjan van de Ven | Re: [GIT]: Networking |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
