Use original version of "core, nfqueue, openvswitch: Orphan frags..." for 3.14
svn path=/dists/trunk/linux/; revision=21194
This commit is contained in:
parent
057e9d9557
commit
96aad69f88
|
@ -11,19 +11,39 @@ skb.
|
|||
|
||||
Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com>
|
||||
Acked-by: Thomas Graf <tgraf@redhat.com>
|
||||
[bwh: skb_zerocopy() is new in 3.14, but was moved from a static function
|
||||
in nfnetlink_queue. We need to patch that and its caller, but not
|
||||
openvswitch.]
|
||||
---
|
||||
--- a/net/netfilter/nfnetlink_queue_core.c
|
||||
+++ b/net/netfilter/nfnetlink_queue_core.c
|
||||
@@ -235,22 +235,23 @@ nfqnl_flush(struct nfqnl_instance *queue
|
||||
spin_unlock_bh(&queue->lock);
|
||||
}
|
||||
|
||||
-static void
|
||||
+static int
|
||||
nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
|
||||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
|
||||
index 03db95a..35c4e85 100644
|
||||
--- a/include/linux/skbuff.h
|
||||
+++ b/include/linux/skbuff.h
|
||||
@@ -2508,8 +2508,8 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
|
||||
unsigned int flags);
|
||||
void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);
|
||||
unsigned int skb_zerocopy_headlen(const struct sk_buff *from);
|
||||
-void skb_zerocopy(struct sk_buff *to, const struct sk_buff *from,
|
||||
- int len, int hlen);
|
||||
+int skb_zerocopy(struct sk_buff *to, const struct sk_buff *from,
|
||||
+ int len, int hlen);
|
||||
void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len);
|
||||
int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen);
|
||||
void skb_scrub_packet(struct sk_buff *skb, bool xnet);
|
||||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
index 3f14c63..4cf0ee5 100644
|
||||
--- a/net/core/skbuff.c
|
||||
+++ b/net/core/skbuff.c
|
||||
@@ -2127,25 +2127,31 @@ EXPORT_SYMBOL_GPL(skb_zerocopy_headlen);
|
||||
*
|
||||
* The `hlen` as calculated by skb_zerocopy_headlen() specifies the
|
||||
* headroom in the `to` buffer.
|
||||
+ *
|
||||
+ * Return value:
|
||||
+ * 0: everything is OK
|
||||
+ * -ENOMEM: couldn't orphan frags of @from due to lack of memory
|
||||
+ * -EFAULT: skb_copy_bits() found some problem with skb geometry
|
||||
*/
|
||||
-void
|
||||
+int
|
||||
skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
|
||||
{
|
||||
int i, j = 0;
|
||||
int plen = 0; /* length of skb->head fragment */
|
||||
|
@ -31,6 +51,8 @@ Acked-by: Thomas Graf <tgraf@redhat.com>
|
|||
struct page *page;
|
||||
unsigned int offset;
|
||||
|
||||
BUG_ON(!from->head_frag && !hlen);
|
||||
|
||||
/* dont bother with small payloads */
|
||||
- if (len <= skb_tailroom(to)) {
|
||||
- skb_copy_bits(from, 0, skb_put(to, len), len);
|
||||
|
@ -47,7 +69,7 @@ Acked-by: Thomas Graf <tgraf@redhat.com>
|
|||
len -= hlen;
|
||||
} else {
|
||||
plen = min_t(int, skb_headlen(from), len);
|
||||
@@ -268,6 +269,11 @@ nfqnl_zcopy(struct sk_buff *to, const st
|
||||
@@ -2163,6 +2169,11 @@ skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
|
||||
to->len += len + plen;
|
||||
to->data_len += len + plen;
|
||||
|
||||
|
@ -59,16 +81,20 @@ Acked-by: Thomas Graf <tgraf@redhat.com>
|
|||
for (i = 0; i < skb_shinfo(from)->nr_frags; i++) {
|
||||
if (!len)
|
||||
break;
|
||||
@@ -278,6 +284,8 @@ nfqnl_zcopy(struct sk_buff *to, const st
|
||||
@@ -2173,6 +2184,8 @@ skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
|
||||
j++;
|
||||
}
|
||||
skb_shinfo(to)->nr_frags = j;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(skb_zerocopy);
|
||||
|
||||
static int
|
||||
@@ -374,13 +382,16 @@ nfqnl_build_packet_message(struct net *n
|
||||
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
|
||||
index f072fe8..108120f 100644
|
||||
--- a/net/netfilter/nfnetlink_queue_core.c
|
||||
+++ b/net/netfilter/nfnetlink_queue_core.c
|
||||
@@ -354,13 +354,16 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
|
||||
skb = nfnetlink_alloc_skb(net, size, queue->peer_portid,
|
||||
GFP_ATOMIC);
|
||||
|
@ -86,12 +112,12 @@ Acked-by: Thomas Graf <tgraf@redhat.com>
|
|||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
@@ -504,13 +515,15 @@ nfqnl_build_packet_message(struct net *n
|
||||
@@ -488,13 +491,15 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
nla->nla_type = NFQA_PAYLOAD;
|
||||
nla->nla_len = nla_attr_size(data_len);
|
||||
|
||||
- nfqnl_zcopy(skb, entskb, data_len, hlen);
|
||||
+ if (nfqnl_zcopy(skb, entskb, data_len, hlen))
|
||||
- skb_zerocopy(skb, entskb, data_len, hlen);
|
||||
+ if (skb_zerocopy(skb, entskb, data_len, hlen))
|
||||
+ goto nla_put_failure;
|
||||
}
|
||||
|
||||
|
@ -103,3 +129,27 @@ Acked-by: Thomas Graf <tgraf@redhat.com>
|
|||
kfree_skb(skb);
|
||||
net_err_ratelimited("nf_queue: error creating packet message\n");
|
||||
return NULL;
|
||||
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
|
||||
index c53fe0c..9230223 100644
|
||||
--- a/net/openvswitch/datapath.c
|
||||
+++ b/net/openvswitch/datapath.c
|
||||
@@ -464,7 +464,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
|
||||
}
|
||||
nla->nla_len = nla_attr_size(skb->len);
|
||||
|
||||
- skb_zerocopy(user_skb, skb, skb->len, hlen);
|
||||
+ err = skb_zerocopy(user_skb, skb, skb->len, hlen);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
|
||||
/* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */
|
||||
if (!(dp->user_features & OVS_DP_F_UNALIGNED)) {
|
||||
@@ -478,6 +480,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
|
||||
|
||||
err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid);
|
||||
out:
|
||||
+ if (err)
|
||||
+ skb_tx_error(skb);
|
||||
kfree_skb(nskb);
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue