diff options
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r-- | net/openvswitch/datapath.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e9a48baf8551..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); |
480 | out: | 482 | out: |
483 | if (err) | ||
484 | skb_tx_error(skb); | ||
481 | kfree_skb(nskb); | 485 | kfree_skb(nskb); |
482 | return err; | 486 | return err; |
483 | } | 487 | } |
@@ -1174,7 +1178,7 @@ static void ovs_dp_reset_user_features(struct sk_buff *skb, struct genl_info *in | |||
1174 | struct datapath *dp; | 1178 | struct datapath *dp; |
1175 | 1179 | ||
1176 | dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); | 1180 | dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); |
1177 | if (!dp) | 1181 | if (IS_ERR(dp)) |
1178 | return; | 1182 | return; |
1179 | 1183 | ||
1180 | WARN(dp->user_features, "Dropping previously announced user features\n"); | 1184 | WARN(dp->user_features, "Dropping previously announced user features\n"); |
@@ -1762,11 +1766,12 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1762 | int bucket = cb->args[0], skip = cb->args[1]; | 1766 | int bucket = cb->args[0], skip = cb->args[1]; |
1763 | int i, j = 0; | 1767 | int i, j = 0; |
1764 | 1768 | ||
1769 | rcu_read_lock(); | ||
1765 | dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); | 1770 | dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); |
1766 | if (!dp) | 1771 | if (!dp) { |
1772 | rcu_read_unlock(); | ||
1767 | return -ENODEV; | 1773 | return -ENODEV; |
1768 | 1774 | } | |
1769 | rcu_read_lock(); | ||
1770 | for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) { | 1775 | for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) { |
1771 | struct vport *vport; | 1776 | struct vport *vport; |
1772 | 1777 | ||