summaryrefslogtreecommitdiffstats
path: root/core-nfqueue-openvswitch-Orphan-frags-in-skb_zerocopy-and-handle-errors.patch
diff options
context:
space:
mode:
Diffstat (limited to 'core-nfqueue-openvswitch-Orphan-frags-in-skb_zerocopy-and-handle-errors.patch')
-rw-r--r--core-nfqueue-openvswitch-Orphan-frags-in-skb_zerocopy-and-handle-errors.patch163
1 files changed, 0 insertions, 163 deletions
diff --git a/core-nfqueue-openvswitch-Orphan-frags-in-skb_zerocopy-and-handle-errors.patch b/core-nfqueue-openvswitch-Orphan-frags-in-skb_zerocopy-and-handle-errors.patch
deleted file mode 100644
index 804f3a901..000000000
--- a/core-nfqueue-openvswitch-Orphan-frags-in-skb_zerocopy-and-handle-errors.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-Bugzilla: 1079013
-Upstream-status: Queued in netdev tree
-
-From 36d5fe6a000790f56039afe26834265db0a3ad4c Mon Sep 17 00:00:00 2001
-From: Zoltan Kiss <zoltan.kiss@citrix.com>
-Date: Wed, 26 Mar 2014 22:37:45 +0000
-Subject: core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle
- errors
-
-skb_zerocopy can copy elements of the frags array between skbs, but it doesn't
-orphan them. Also, it doesn't handle errors, so this patch takes care of that
-as well, and modify the callers accordingly. skb_tx_error() is also added to
-the callers so they will signal the failed delivery towards the creator of the
-skb.
-
-Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-
-diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
-index 5e1e6f2..15ede6a 100644
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -2451,8 +2451,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, 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 869c7af..97e5a2c 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
--skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
-+int
-+skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen)
- {
- int i, j = 0;
- int plen = 0; /* length of skb->head fragment */
-+ int ret;
- 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);
-- return;
-- }
-+ if (len <= skb_tailroom(to))
-+ return skb_copy_bits(from, 0, skb_put(to, len), len);
-
- if (hlen) {
-- skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
-+ ret = skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
-+ if (unlikely(ret))
-+ return ret;
- len -= hlen;
- } else {
- plen = min_t(int, skb_headlen(from), len);
-@@ -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;
-
-+ if (unlikely(skb_orphan_frags(from, GFP_ATOMIC))) {
-+ skb_tx_error(from);
-+ return -ENOMEM;
-+ }
-+
- for (i = 0; i < skb_shinfo(from)->nr_frags; i++) {
- if (!len)
- break;
-@@ -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);
-
-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);
-- if (!skb)
-+ if (!skb) {
-+ skb_tx_error(entskb);
- return NULL;
-+ }
-
- nlh = nlmsg_put(skb, 0, 0,
- NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET,
- sizeof(struct nfgenmsg), 0);
- if (!nlh) {
-+ skb_tx_error(entskb);
- kfree_skb(skb);
- return NULL;
- }
-@@ -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);
-
-- skb_zerocopy(skb, entskb, data_len, hlen);
-+ if (skb_zerocopy(skb, entskb, data_len, hlen))
-+ goto nla_put_failure;
- }
-
- nlh->nlmsg_len = skb->len;
- return skb;
-
- nla_put_failure:
-+ skb_tx_error(entskb);
- 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 8601b32..270b77d 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;
- }
---
-cgit v0.10.1
-