diff options
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r-- | net/openvswitch/datapath.c | 56 |
1 files changed, 29 insertions, 27 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 0727aaa2c825..5da2534b140a 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -402,6 +402,11 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex, | |||
402 | struct sk_buff *nskb = NULL; | 402 | struct sk_buff *nskb = NULL; |
403 | struct sk_buff *user_skb; /* to be queued to userspace */ | 403 | struct sk_buff *user_skb; /* to be queued to userspace */ |
404 | struct nlattr *nla; | 404 | struct nlattr *nla; |
405 | struct genl_info info = { | ||
406 | .dst_sk = net->genl_sock, | ||
407 | .snd_portid = upcall_info->portid, | ||
408 | }; | ||
409 | size_t len; | ||
405 | int err; | 410 | int err; |
406 | 411 | ||
407 | if (vlan_tx_tag_present(skb)) { | 412 | if (vlan_tx_tag_present(skb)) { |
@@ -422,7 +427,8 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex, | |||
422 | goto out; | 427 | goto out; |
423 | } | 428 | } |
424 | 429 | ||
425 | user_skb = genlmsg_new(upcall_msg_size(skb, upcall_info->userdata), GFP_ATOMIC); | 430 | len = upcall_msg_size(skb, upcall_info->userdata); |
431 | user_skb = genlmsg_new_unicast(len, &info, GFP_ATOMIC); | ||
426 | if (!user_skb) { | 432 | if (!user_skb) { |
427 | err = -ENOMEM; | 433 | err = -ENOMEM; |
428 | goto out; | 434 | goto out; |
@@ -725,27 +731,30 @@ error: | |||
725 | return err; | 731 | return err; |
726 | } | 732 | } |
727 | 733 | ||
728 | static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow) | 734 | static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow, |
735 | struct genl_info *info) | ||
729 | { | 736 | { |
730 | const struct sw_flow_actions *sf_acts; | 737 | size_t len; |
731 | 738 | ||
732 | sf_acts = ovsl_dereference(flow->sf_acts); | 739 | len = ovs_flow_cmd_msg_size(ovsl_dereference(flow->sf_acts)); |
733 | 740 | ||
734 | return genlmsg_new(ovs_flow_cmd_msg_size(sf_acts), GFP_KERNEL); | 741 | return genlmsg_new_unicast(len, info, GFP_KERNEL); |
735 | } | 742 | } |
736 | 743 | ||
737 | static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow, | 744 | static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow, |
738 | struct datapath *dp, | 745 | struct datapath *dp, |
739 | u32 portid, u32 seq, u8 cmd) | 746 | struct genl_info *info, |
747 | u8 cmd) | ||
740 | { | 748 | { |
741 | struct sk_buff *skb; | 749 | struct sk_buff *skb; |
742 | int retval; | 750 | int retval; |
743 | 751 | ||
744 | skb = ovs_flow_cmd_alloc_info(flow); | 752 | skb = ovs_flow_cmd_alloc_info(flow, info); |
745 | if (!skb) | 753 | if (!skb) |
746 | return ERR_PTR(-ENOMEM); | 754 | return ERR_PTR(-ENOMEM); |
747 | 755 | ||
748 | retval = ovs_flow_cmd_fill_info(flow, dp, skb, portid, seq, 0, cmd); | 756 | retval = ovs_flow_cmd_fill_info(flow, dp, skb, info->snd_portid, |
757 | info->snd_seq, 0, cmd); | ||
749 | BUG_ON(retval < 0); | 758 | BUG_ON(retval < 0); |
750 | return skb; | 759 | return skb; |
751 | } | 760 | } |
@@ -826,8 +835,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) | |||
826 | goto err_flow_free; | 835 | goto err_flow_free; |
827 | } | 836 | } |
828 | 837 | ||
829 | reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid, | 838 | reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW); |
830 | info->snd_seq, OVS_FLOW_CMD_NEW); | ||
831 | } else { | 839 | } else { |
832 | /* We found a matching flow. */ | 840 | /* We found a matching flow. */ |
833 | struct sw_flow_actions *old_acts; | 841 | struct sw_flow_actions *old_acts; |
@@ -855,8 +863,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) | |||
855 | rcu_assign_pointer(flow->sf_acts, acts); | 863 | rcu_assign_pointer(flow->sf_acts, acts); |
856 | ovs_nla_free_flow_actions(old_acts); | 864 | ovs_nla_free_flow_actions(old_acts); |
857 | 865 | ||
858 | reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid, | 866 | reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW); |
859 | info->snd_seq, OVS_FLOW_CMD_NEW); | ||
860 | 867 | ||
861 | /* Clear stats. */ | 868 | /* Clear stats. */ |
862 | if (a[OVS_FLOW_ATTR_CLEAR]) { | 869 | if (a[OVS_FLOW_ATTR_CLEAR]) { |
@@ -918,8 +925,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info) | |||
918 | goto unlock; | 925 | goto unlock; |
919 | } | 926 | } |
920 | 927 | ||
921 | reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid, | 928 | reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW); |
922 | info->snd_seq, OVS_FLOW_CMD_NEW); | ||
923 | if (IS_ERR(reply)) { | 929 | if (IS_ERR(reply)) { |
924 | err = PTR_ERR(reply); | 930 | err = PTR_ERR(reply); |
925 | goto unlock; | 931 | goto unlock; |
@@ -966,7 +972,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info) | |||
966 | goto unlock; | 972 | goto unlock; |
967 | } | 973 | } |
968 | 974 | ||
969 | reply = ovs_flow_cmd_alloc_info(flow); | 975 | reply = ovs_flow_cmd_alloc_info(flow, info); |
970 | if (!reply) { | 976 | if (!reply) { |
971 | err = -ENOMEM; | 977 | err = -ENOMEM; |
972 | goto unlock; | 978 | goto unlock; |
@@ -1118,17 +1124,17 @@ error: | |||
1118 | return -EMSGSIZE; | 1124 | return -EMSGSIZE; |
1119 | } | 1125 | } |
1120 | 1126 | ||
1121 | static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 portid, | 1127 | static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, |
1122 | u32 seq, u8 cmd) | 1128 | struct genl_info *info, u8 cmd) |
1123 | { | 1129 | { |
1124 | struct sk_buff *skb; | 1130 | struct sk_buff *skb; |
1125 | int retval; | 1131 | int retval; |
1126 | 1132 | ||
1127 | skb = genlmsg_new(ovs_dp_cmd_msg_size(), GFP_KERNEL); | 1133 | skb = genlmsg_new_unicast(ovs_dp_cmd_msg_size(), info, GFP_KERNEL); |
1128 | if (!skb) | 1134 | if (!skb) |
1129 | return ERR_PTR(-ENOMEM); | 1135 | return ERR_PTR(-ENOMEM); |
1130 | 1136 | ||
1131 | retval = ovs_dp_cmd_fill_info(dp, skb, portid, seq, 0, cmd); | 1137 | retval = ovs_dp_cmd_fill_info(dp, skb, info->snd_portid, info->snd_seq, 0, cmd); |
1132 | if (retval < 0) { | 1138 | if (retval < 0) { |
1133 | kfree_skb(skb); | 1139 | kfree_skb(skb); |
1134 | return ERR_PTR(retval); | 1140 | return ERR_PTR(retval); |
@@ -1223,8 +1229,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1223 | goto err_destroy_ports_array; | 1229 | goto err_destroy_ports_array; |
1224 | } | 1230 | } |
1225 | 1231 | ||
1226 | reply = ovs_dp_cmd_build_info(dp, info->snd_portid, | 1232 | reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW); |
1227 | info->snd_seq, OVS_DP_CMD_NEW); | ||
1228 | err = PTR_ERR(reply); | 1233 | err = PTR_ERR(reply); |
1229 | if (IS_ERR(reply)) | 1234 | if (IS_ERR(reply)) |
1230 | goto err_destroy_local_port; | 1235 | goto err_destroy_local_port; |
@@ -1290,8 +1295,7 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info) | |||
1290 | if (IS_ERR(dp)) | 1295 | if (IS_ERR(dp)) |
1291 | goto unlock; | 1296 | goto unlock; |
1292 | 1297 | ||
1293 | reply = ovs_dp_cmd_build_info(dp, info->snd_portid, | 1298 | reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_DEL); |
1294 | info->snd_seq, OVS_DP_CMD_DEL); | ||
1295 | err = PTR_ERR(reply); | 1299 | err = PTR_ERR(reply); |
1296 | if (IS_ERR(reply)) | 1300 | if (IS_ERR(reply)) |
1297 | goto unlock; | 1301 | goto unlock; |
@@ -1319,8 +1323,7 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
1319 | if (IS_ERR(dp)) | 1323 | if (IS_ERR(dp)) |
1320 | goto unlock; | 1324 | goto unlock; |
1321 | 1325 | ||
1322 | reply = ovs_dp_cmd_build_info(dp, info->snd_portid, | 1326 | reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW); |
1323 | info->snd_seq, OVS_DP_CMD_NEW); | ||
1324 | if (IS_ERR(reply)) { | 1327 | if (IS_ERR(reply)) { |
1325 | err = PTR_ERR(reply); | 1328 | err = PTR_ERR(reply); |
1326 | genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0, | 1329 | genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0, |
@@ -1351,8 +1354,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info) | |||
1351 | goto unlock; | 1354 | goto unlock; |
1352 | } | 1355 | } |
1353 | 1356 | ||
1354 | reply = ovs_dp_cmd_build_info(dp, info->snd_portid, | 1357 | reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW); |
1355 | info->snd_seq, OVS_DP_CMD_NEW); | ||
1356 | if (IS_ERR(reply)) { | 1358 | if (IS_ERR(reply)) { |
1357 | err = PTR_ERR(reply); | 1359 | err = PTR_ERR(reply); |
1358 | goto unlock; | 1360 | goto unlock; |