aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
authorZoltan Kiss <zoltan.kiss@citrix.com>2014-03-26 18:37:45 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-27 15:29:38 -0400
commit36d5fe6a000790f56039afe26834265db0a3ad4c (patch)
tree391de83f18ede9ca651ed347112ce4400e4645d5 /net/openvswitch/datapath.c
parentfc0d48b8fb449ca007b2057328abf736cb516168 (diff)
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>
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 8601b320b443..270b77dfac30 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,
464 } 464 }
465 nla->nla_len = nla_attr_size(skb->len); 465 nla->nla_len = nla_attr_size(skb->len);
466 466
467 skb_zerocopy(user_skb, skb, skb->len, hlen); 467 err = skb_zerocopy(user_skb, skb, skb->len, hlen);
468 if (err)
469 goto out;
468 470
469 /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */ 471 /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */
470 if (!(dp->user_features & OVS_DP_F_UNALIGNED)) { 472 if (!(dp->user_features & OVS_DP_F_UNALIGNED)) {
@@ -478,6 +480,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
478 480
479 err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); 481 err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid);
480out: 482out:
483 if (err)
484 skb_tx_error(skb);
481 kfree_skb(nskb); 485 kfree_skb(nskb);
482 return err; 486 return err;
483} 487}