diff options
Diffstat (limited to 'drivers/net/macvtap.c')
-rw-r--r-- | drivers/net/macvtap.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 2513939bf245..52a9d811be06 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -491,7 +491,13 @@ static int macvtap_newlink(struct net *src_net, | |||
491 | /* Don't put anything that may fail after macvlan_common_newlink | 491 | /* Don't put anything that may fail after macvlan_common_newlink |
492 | * because we can't undo what it does. | 492 | * because we can't undo what it does. |
493 | */ | 493 | */ |
494 | return macvlan_common_newlink(src_net, dev, tb, data); | 494 | err = macvlan_common_newlink(src_net, dev, tb, data); |
495 | if (err) { | ||
496 | netdev_rx_handler_unregister(dev); | ||
497 | return err; | ||
498 | } | ||
499 | |||
500 | return 0; | ||
495 | } | 501 | } |
496 | 502 | ||
497 | static void macvtap_dellink(struct net_device *dev, | 503 | static void macvtap_dellink(struct net_device *dev, |
@@ -736,13 +742,8 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | |||
736 | 742 | ||
737 | if (zerocopy) | 743 | if (zerocopy) |
738 | err = zerocopy_sg_from_iter(skb, from); | 744 | err = zerocopy_sg_from_iter(skb, from); |
739 | else { | 745 | else |
740 | err = skb_copy_datagram_from_iter(skb, 0, from, len); | 746 | err = skb_copy_datagram_from_iter(skb, 0, from, len); |
741 | if (!err && m && m->msg_control) { | ||
742 | struct ubuf_info *uarg = m->msg_control; | ||
743 | uarg->callback(uarg, false); | ||
744 | } | ||
745 | } | ||
746 | 747 | ||
747 | if (err) | 748 | if (err) |
748 | goto err_kfree; | 749 | goto err_kfree; |
@@ -773,7 +774,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | |||
773 | skb_shinfo(skb)->destructor_arg = m->msg_control; | 774 | skb_shinfo(skb)->destructor_arg = m->msg_control; |
774 | skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; | 775 | skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; |
775 | skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; | 776 | skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; |
777 | } else if (m && m->msg_control) { | ||
778 | struct ubuf_info *uarg = m->msg_control; | ||
779 | uarg->callback(uarg, false); | ||
776 | } | 780 | } |
781 | |||
777 | if (vlan) { | 782 | if (vlan) { |
778 | skb->dev = vlan->dev; | 783 | skb->dev = vlan->dev; |
779 | dev_queue_xmit(skb); | 784 | dev_queue_xmit(skb); |