aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c240
1 files changed, 161 insertions, 79 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 4e9a5f035cbc..ae5e77cdc0ca 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -65,6 +65,8 @@ static struct genl_family dp_packet_genl_family;
65static struct genl_family dp_flow_genl_family; 65static struct genl_family dp_flow_genl_family;
66static struct genl_family dp_datapath_genl_family; 66static struct genl_family dp_datapath_genl_family;
67 67
68static const struct nla_policy flow_policy[];
69
68static const struct genl_multicast_group ovs_dp_flow_multicast_group = { 70static const struct genl_multicast_group ovs_dp_flow_multicast_group = {
69 .name = OVS_FLOW_MCGROUP, 71 .name = OVS_FLOW_MCGROUP,
70}; 72};
@@ -419,7 +421,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
419 if (!dp_ifindex) 421 if (!dp_ifindex)
420 return -ENODEV; 422 return -ENODEV;
421 423
422 if (vlan_tx_tag_present(skb)) { 424 if (skb_vlan_tag_present(skb)) {
423 nskb = skb_clone(skb, GFP_ATOMIC); 425 nskb = skb_clone(skb, GFP_ATOMIC);
424 if (!nskb) 426 if (!nskb)
425 return -ENOMEM; 427 return -ENOMEM;
@@ -461,10 +463,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
461 0, upcall_info->cmd); 463 0, upcall_info->cmd);
462 upcall->dp_ifindex = dp_ifindex; 464 upcall->dp_ifindex = dp_ifindex;
463 465
464 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY); 466 err = ovs_nla_put_key(key, key, OVS_PACKET_ATTR_KEY, false, user_skb);
465 err = ovs_nla_put_flow(key, key, user_skb);
466 BUG_ON(err); 467 BUG_ON(err);
467 nla_nest_end(user_skb, nla);
468 468
469 if (upcall_info->userdata) 469 if (upcall_info->userdata)
470 __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA, 470 __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA,
@@ -524,7 +524,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
524 struct vport *input_vport; 524 struct vport *input_vport;
525 int len; 525 int len;
526 int err; 526 int err;
527 bool log = !a[OVS_FLOW_ATTR_PROBE]; 527 bool log = !a[OVS_PACKET_ATTR_PROBE];
528 528
529 err = -EINVAL; 529 err = -EINVAL;
530 if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] || 530 if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] ||
@@ -610,6 +610,7 @@ static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {
610 [OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN }, 610 [OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN },
611 [OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED }, 611 [OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED },
612 [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED }, 612 [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
613 [OVS_PACKET_ATTR_PROBE] = { .type = NLA_FLAG },
613}; 614};
614 615
615static const struct genl_ops dp_packet_genl_ops[] = { 616static const struct genl_ops dp_packet_genl_ops[] = {
@@ -663,46 +664,48 @@ static void get_dp_stats(const struct datapath *dp, struct ovs_dp_stats *stats,
663 } 664 }
664} 665}
665 666
666static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts) 667static bool should_fill_key(const struct sw_flow_id *sfid, uint32_t ufid_flags)
667{ 668{
668 return NLMSG_ALIGN(sizeof(struct ovs_header)) 669 return ovs_identifier_is_ufid(sfid) &&
669 + nla_total_size(ovs_key_attr_size()) /* OVS_FLOW_ATTR_KEY */ 670 !(ufid_flags & OVS_UFID_F_OMIT_KEY);
670 + nla_total_size(ovs_key_attr_size()) /* OVS_FLOW_ATTR_MASK */
671 + nla_total_size(sizeof(struct ovs_flow_stats)) /* OVS_FLOW_ATTR_STATS */
672 + nla_total_size(1) /* OVS_FLOW_ATTR_TCP_FLAGS */
673 + nla_total_size(8) /* OVS_FLOW_ATTR_USED */
674 + nla_total_size(acts->actions_len); /* OVS_FLOW_ATTR_ACTIONS */
675} 671}
676 672
677/* Called with ovs_mutex or RCU read lock. */ 673static bool should_fill_mask(uint32_t ufid_flags)
678static int ovs_flow_cmd_fill_match(const struct sw_flow *flow,
679 struct sk_buff *skb)
680{ 674{
681 struct nlattr *nla; 675 return !(ufid_flags & OVS_UFID_F_OMIT_MASK);
682 int err; 676}
683 677
684 /* Fill flow key. */ 678static bool should_fill_actions(uint32_t ufid_flags)
685 nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY); 679{
686 if (!nla) 680 return !(ufid_flags & OVS_UFID_F_OMIT_ACTIONS);
687 return -EMSGSIZE; 681}
688 682
689 err = ovs_nla_put_flow(&flow->unmasked_key, &flow->unmasked_key, skb); 683static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts,
690 if (err) 684 const struct sw_flow_id *sfid,
691 return err; 685 uint32_t ufid_flags)
686{
687 size_t len = NLMSG_ALIGN(sizeof(struct ovs_header));
692 688
693 nla_nest_end(skb, nla); 689 /* OVS_FLOW_ATTR_UFID */
690 if (sfid && ovs_identifier_is_ufid(sfid))
691 len += nla_total_size(sfid->ufid_len);
694 692
695 /* Fill flow mask. */ 693 /* OVS_FLOW_ATTR_KEY */
696 nla = nla_nest_start(skb, OVS_FLOW_ATTR_MASK); 694 if (!sfid || should_fill_key(sfid, ufid_flags))
697 if (!nla) 695 len += nla_total_size(ovs_key_attr_size());
698 return -EMSGSIZE;
699 696
700 err = ovs_nla_put_flow(&flow->key, &flow->mask->key, skb); 697 /* OVS_FLOW_ATTR_MASK */
701 if (err) 698 if (should_fill_mask(ufid_flags))
702 return err; 699 len += nla_total_size(ovs_key_attr_size());
703 700
704 nla_nest_end(skb, nla); 701 /* OVS_FLOW_ATTR_ACTIONS */
705 return 0; 702 if (should_fill_actions(ufid_flags))
703 len += nla_total_size(acts->actions_len);
704
705 return len
706 + nla_total_size(sizeof(struct ovs_flow_stats)) /* OVS_FLOW_ATTR_STATS */
707 + nla_total_size(1) /* OVS_FLOW_ATTR_TCP_FLAGS */
708 + nla_total_size(8); /* OVS_FLOW_ATTR_USED */
706} 709}
707 710
708/* Called with ovs_mutex or RCU read lock. */ 711/* Called with ovs_mutex or RCU read lock. */
@@ -773,7 +776,7 @@ static int ovs_flow_cmd_fill_actions(const struct sw_flow *flow,
773/* Called with ovs_mutex or RCU read lock. */ 776/* Called with ovs_mutex or RCU read lock. */
774static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex, 777static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex,
775 struct sk_buff *skb, u32 portid, 778 struct sk_buff *skb, u32 portid,
776 u32 seq, u32 flags, u8 cmd) 779 u32 seq, u32 flags, u8 cmd, u32 ufid_flags)
777{ 780{
778 const int skb_orig_len = skb->len; 781 const int skb_orig_len = skb->len;
779 struct ovs_header *ovs_header; 782 struct ovs_header *ovs_header;
@@ -786,19 +789,34 @@ static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex,
786 789
787 ovs_header->dp_ifindex = dp_ifindex; 790 ovs_header->dp_ifindex = dp_ifindex;
788 791
789 err = ovs_flow_cmd_fill_match(flow, skb); 792 err = ovs_nla_put_identifier(flow, skb);
790 if (err) 793 if (err)
791 goto error; 794 goto error;
792 795
796 if (should_fill_key(&flow->id, ufid_flags)) {
797 err = ovs_nla_put_masked_key(flow, skb);
798 if (err)
799 goto error;
800 }
801
802 if (should_fill_mask(ufid_flags)) {
803 err = ovs_nla_put_mask(flow, skb);
804 if (err)
805 goto error;
806 }
807
793 err = ovs_flow_cmd_fill_stats(flow, skb); 808 err = ovs_flow_cmd_fill_stats(flow, skb);
794 if (err) 809 if (err)
795 goto error; 810 goto error;
796 811
797 err = ovs_flow_cmd_fill_actions(flow, skb, skb_orig_len); 812 if (should_fill_actions(ufid_flags)) {
798 if (err) 813 err = ovs_flow_cmd_fill_actions(flow, skb, skb_orig_len);
799 goto error; 814 if (err)
815 goto error;
816 }
800 817
801 return genlmsg_end(skb, ovs_header); 818 genlmsg_end(skb, ovs_header);
819 return 0;
802 820
803error: 821error:
804 genlmsg_cancel(skb, ovs_header); 822 genlmsg_cancel(skb, ovs_header);
@@ -807,15 +825,19 @@ error:
807 825
808/* May not be called with RCU read lock. */ 826/* May not be called with RCU read lock. */
809static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *acts, 827static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *acts,
828 const struct sw_flow_id *sfid,
810 struct genl_info *info, 829 struct genl_info *info,
811 bool always) 830 bool always,
831 uint32_t ufid_flags)
812{ 832{
813 struct sk_buff *skb; 833 struct sk_buff *skb;
834 size_t len;
814 835
815 if (!always && !ovs_must_notify(&dp_flow_genl_family, info, 0)) 836 if (!always && !ovs_must_notify(&dp_flow_genl_family, info, 0))
816 return NULL; 837 return NULL;
817 838
818 skb = genlmsg_new_unicast(ovs_flow_cmd_msg_size(acts), info, GFP_KERNEL); 839 len = ovs_flow_cmd_msg_size(acts, sfid, ufid_flags);
840 skb = genlmsg_new_unicast(len, info, GFP_KERNEL);
819 if (!skb) 841 if (!skb)
820 return ERR_PTR(-ENOMEM); 842 return ERR_PTR(-ENOMEM);
821 843
@@ -826,19 +848,19 @@ static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *act
826static struct sk_buff *ovs_flow_cmd_build_info(const struct sw_flow *flow, 848static struct sk_buff *ovs_flow_cmd_build_info(const struct sw_flow *flow,
827 int dp_ifindex, 849 int dp_ifindex,
828 struct genl_info *info, u8 cmd, 850 struct genl_info *info, u8 cmd,
829 bool always) 851 bool always, u32 ufid_flags)
830{ 852{
831 struct sk_buff *skb; 853 struct sk_buff *skb;
832 int retval; 854 int retval;
833 855
834 skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts), info, 856 skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts),
835 always); 857 &flow->id, info, always, ufid_flags);
836 if (IS_ERR_OR_NULL(skb)) 858 if (IS_ERR_OR_NULL(skb))
837 return skb; 859 return skb;
838 860
839 retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb, 861 retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb,
840 info->snd_portid, info->snd_seq, 0, 862 info->snd_portid, info->snd_seq, 0,
841 cmd); 863 cmd, ufid_flags);
842 BUG_ON(retval < 0); 864 BUG_ON(retval < 0);
843 return skb; 865 return skb;
844} 866}
@@ -847,12 +869,14 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
847{ 869{
848 struct nlattr **a = info->attrs; 870 struct nlattr **a = info->attrs;
849 struct ovs_header *ovs_header = info->userhdr; 871 struct ovs_header *ovs_header = info->userhdr;
850 struct sw_flow *flow, *new_flow; 872 struct sw_flow *flow = NULL, *new_flow;
851 struct sw_flow_mask mask; 873 struct sw_flow_mask mask;
852 struct sk_buff *reply; 874 struct sk_buff *reply;
853 struct datapath *dp; 875 struct datapath *dp;
876 struct sw_flow_key key;
854 struct sw_flow_actions *acts; 877 struct sw_flow_actions *acts;
855 struct sw_flow_match match; 878 struct sw_flow_match match;
879 u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
856 int error; 880 int error;
857 bool log = !a[OVS_FLOW_ATTR_PROBE]; 881 bool log = !a[OVS_FLOW_ATTR_PROBE];
858 882
@@ -877,13 +901,19 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
877 } 901 }
878 902
879 /* Extract key. */ 903 /* Extract key. */
880 ovs_match_init(&match, &new_flow->unmasked_key, &mask); 904 ovs_match_init(&match, &key, &mask);
881 error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], 905 error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY],
882 a[OVS_FLOW_ATTR_MASK], log); 906 a[OVS_FLOW_ATTR_MASK], log);
883 if (error) 907 if (error)
884 goto err_kfree_flow; 908 goto err_kfree_flow;
885 909
886 ovs_flow_mask_key(&new_flow->key, &new_flow->unmasked_key, &mask); 910 ovs_flow_mask_key(&new_flow->key, &key, &mask);
911
912 /* Extract flow identifier. */
913 error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
914 &key, log);
915 if (error)
916 goto err_kfree_flow;
887 917
888 /* Validate actions. */ 918 /* Validate actions. */
889 error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key, 919 error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key,
@@ -893,7 +923,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
893 goto err_kfree_flow; 923 goto err_kfree_flow;
894 } 924 }
895 925
896 reply = ovs_flow_cmd_alloc_info(acts, info, false); 926 reply = ovs_flow_cmd_alloc_info(acts, &new_flow->id, info, false,
927 ufid_flags);
897 if (IS_ERR(reply)) { 928 if (IS_ERR(reply)) {
898 error = PTR_ERR(reply); 929 error = PTR_ERR(reply);
899 goto err_kfree_acts; 930 goto err_kfree_acts;
@@ -905,8 +936,12 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
905 error = -ENODEV; 936 error = -ENODEV;
906 goto err_unlock_ovs; 937 goto err_unlock_ovs;
907 } 938 }
939
908 /* Check if this is a duplicate flow */ 940 /* Check if this is a duplicate flow */
909 flow = ovs_flow_tbl_lookup(&dp->table, &new_flow->unmasked_key); 941 if (ovs_identifier_is_ufid(&new_flow->id))
942 flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
943 if (!flow)
944 flow = ovs_flow_tbl_lookup(&dp->table, &key);
910 if (likely(!flow)) { 945 if (likely(!flow)) {
911 rcu_assign_pointer(new_flow->sf_acts, acts); 946 rcu_assign_pointer(new_flow->sf_acts, acts);
912 947
@@ -922,7 +957,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
922 ovs_header->dp_ifindex, 957 ovs_header->dp_ifindex,
923 reply, info->snd_portid, 958 reply, info->snd_portid,
924 info->snd_seq, 0, 959 info->snd_seq, 0,
925 OVS_FLOW_CMD_NEW); 960 OVS_FLOW_CMD_NEW,
961 ufid_flags);
926 BUG_ON(error < 0); 962 BUG_ON(error < 0);
927 } 963 }
928 ovs_unlock(); 964 ovs_unlock();
@@ -940,10 +976,15 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
940 error = -EEXIST; 976 error = -EEXIST;
941 goto err_unlock_ovs; 977 goto err_unlock_ovs;
942 } 978 }
943 /* The unmasked key has to be the same for flow updates. */ 979 /* The flow identifier has to be the same for flow updates.
944 if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) { 980 * Look for any overlapping flow.
945 /* Look for any overlapping flow. */ 981 */
946 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); 982 if (unlikely(!ovs_flow_cmp(flow, &match))) {
983 if (ovs_identifier_is_key(&flow->id))
984 flow = ovs_flow_tbl_lookup_exact(&dp->table,
985 &match);
986 else /* UFID matches but key is different */
987 flow = NULL;
947 if (!flow) { 988 if (!flow) {
948 error = -ENOENT; 989 error = -ENOENT;
949 goto err_unlock_ovs; 990 goto err_unlock_ovs;
@@ -958,7 +999,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
958 ovs_header->dp_ifindex, 999 ovs_header->dp_ifindex,
959 reply, info->snd_portid, 1000 reply, info->snd_portid,
960 info->snd_seq, 0, 1001 info->snd_seq, 0,
961 OVS_FLOW_CMD_NEW); 1002 OVS_FLOW_CMD_NEW,
1003 ufid_flags);
962 BUG_ON(error < 0); 1004 BUG_ON(error < 0);
963 } 1005 }
964 ovs_unlock(); 1006 ovs_unlock();
@@ -1014,8 +1056,11 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1014 struct datapath *dp; 1056 struct datapath *dp;
1015 struct sw_flow_actions *old_acts = NULL, *acts = NULL; 1057 struct sw_flow_actions *old_acts = NULL, *acts = NULL;
1016 struct sw_flow_match match; 1058 struct sw_flow_match match;
1059 struct sw_flow_id sfid;
1060 u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
1017 int error; 1061 int error;
1018 bool log = !a[OVS_FLOW_ATTR_PROBE]; 1062 bool log = !a[OVS_FLOW_ATTR_PROBE];
1063 bool ufid_present;
1019 1064
1020 /* Extract key. */ 1065 /* Extract key. */
1021 error = -EINVAL; 1066 error = -EINVAL;
@@ -1024,6 +1069,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1024 goto error; 1069 goto error;
1025 } 1070 }
1026 1071
1072 ufid_present = ovs_nla_get_ufid(&sfid, a[OVS_FLOW_ATTR_UFID], log);
1027 ovs_match_init(&match, &key, &mask); 1073 ovs_match_init(&match, &key, &mask);
1028 error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], 1074 error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY],
1029 a[OVS_FLOW_ATTR_MASK], log); 1075 a[OVS_FLOW_ATTR_MASK], log);
@@ -1040,7 +1086,8 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1040 } 1086 }
1041 1087
1042 /* Can allocate before locking if have acts. */ 1088 /* Can allocate before locking if have acts. */
1043 reply = ovs_flow_cmd_alloc_info(acts, info, false); 1089 reply = ovs_flow_cmd_alloc_info(acts, &sfid, info, false,
1090 ufid_flags);
1044 if (IS_ERR(reply)) { 1091 if (IS_ERR(reply)) {
1045 error = PTR_ERR(reply); 1092 error = PTR_ERR(reply);
1046 goto err_kfree_acts; 1093 goto err_kfree_acts;
@@ -1054,7 +1101,10 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1054 goto err_unlock_ovs; 1101 goto err_unlock_ovs;
1055 } 1102 }
1056 /* Check that the flow exists. */ 1103 /* Check that the flow exists. */
1057 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); 1104 if (ufid_present)
1105 flow = ovs_flow_tbl_lookup_ufid(&dp->table, &sfid);
1106 else
1107 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
1058 if (unlikely(!flow)) { 1108 if (unlikely(!flow)) {
1059 error = -ENOENT; 1109 error = -ENOENT;
1060 goto err_unlock_ovs; 1110 goto err_unlock_ovs;
@@ -1070,13 +1120,16 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1070 ovs_header->dp_ifindex, 1120 ovs_header->dp_ifindex,
1071 reply, info->snd_portid, 1121 reply, info->snd_portid,
1072 info->snd_seq, 0, 1122 info->snd_seq, 0,
1073 OVS_FLOW_CMD_NEW); 1123 OVS_FLOW_CMD_NEW,
1124 ufid_flags);
1074 BUG_ON(error < 0); 1125 BUG_ON(error < 0);
1075 } 1126 }
1076 } else { 1127 } else {
1077 /* Could not alloc without acts before locking. */ 1128 /* Could not alloc without acts before locking. */
1078 reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex, 1129 reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex,
1079 info, OVS_FLOW_CMD_NEW, false); 1130 info, OVS_FLOW_CMD_NEW, false,
1131 ufid_flags);
1132
1080 if (unlikely(IS_ERR(reply))) { 1133 if (unlikely(IS_ERR(reply))) {
1081 error = PTR_ERR(reply); 1134 error = PTR_ERR(reply);
1082 goto err_unlock_ovs; 1135 goto err_unlock_ovs;
@@ -1113,17 +1166,22 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
1113 struct sw_flow *flow; 1166 struct sw_flow *flow;
1114 struct datapath *dp; 1167 struct datapath *dp;
1115 struct sw_flow_match match; 1168 struct sw_flow_match match;
1116 int err; 1169 struct sw_flow_id ufid;
1170 u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
1171 int err = 0;
1117 bool log = !a[OVS_FLOW_ATTR_PROBE]; 1172 bool log = !a[OVS_FLOW_ATTR_PROBE];
1173 bool ufid_present;
1118 1174
1119 if (!a[OVS_FLOW_ATTR_KEY]) { 1175 ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log);
1176 if (a[OVS_FLOW_ATTR_KEY]) {
1177 ovs_match_init(&match, &key, NULL);
1178 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL,
1179 log);
1180 } else if (!ufid_present) {
1120 OVS_NLERR(log, 1181 OVS_NLERR(log,
1121 "Flow get message rejected, Key attribute missing."); 1182 "Flow get message rejected, Key attribute missing.");
1122 return -EINVAL; 1183 err = -EINVAL;
1123 } 1184 }
1124
1125 ovs_match_init(&match, &key, NULL);
1126 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, log);
1127 if (err) 1185 if (err)
1128 return err; 1186 return err;
1129 1187
@@ -1134,14 +1192,17 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
1134 goto unlock; 1192 goto unlock;
1135 } 1193 }
1136 1194
1137 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); 1195 if (ufid_present)
1196 flow = ovs_flow_tbl_lookup_ufid(&dp->table, &ufid);
1197 else
1198 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
1138 if (!flow) { 1199 if (!flow) {
1139 err = -ENOENT; 1200 err = -ENOENT;
1140 goto unlock; 1201 goto unlock;
1141 } 1202 }
1142 1203
1143 reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex, info, 1204 reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex, info,
1144 OVS_FLOW_CMD_NEW, true); 1205 OVS_FLOW_CMD_NEW, true, ufid_flags);
1145 if (IS_ERR(reply)) { 1206 if (IS_ERR(reply)) {
1146 err = PTR_ERR(reply); 1207 err = PTR_ERR(reply);
1147 goto unlock; 1208 goto unlock;
@@ -1160,13 +1221,17 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
1160 struct ovs_header *ovs_header = info->userhdr; 1221 struct ovs_header *ovs_header = info->userhdr;
1161 struct sw_flow_key key; 1222 struct sw_flow_key key;
1162 struct sk_buff *reply; 1223 struct sk_buff *reply;
1163 struct sw_flow *flow; 1224 struct sw_flow *flow = NULL;
1164 struct datapath *dp; 1225 struct datapath *dp;
1165 struct sw_flow_match match; 1226 struct sw_flow_match match;
1227 struct sw_flow_id ufid;
1228 u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
1166 int err; 1229 int err;
1167 bool log = !a[OVS_FLOW_ATTR_PROBE]; 1230 bool log = !a[OVS_FLOW_ATTR_PROBE];
1231 bool ufid_present;
1168 1232
1169 if (likely(a[OVS_FLOW_ATTR_KEY])) { 1233 ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log);
1234 if (a[OVS_FLOW_ATTR_KEY]) {
1170 ovs_match_init(&match, &key, NULL); 1235 ovs_match_init(&match, &key, NULL);
1171 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, 1236 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL,
1172 log); 1237 log);
@@ -1181,12 +1246,15 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
1181 goto unlock; 1246 goto unlock;
1182 } 1247 }
1183 1248
1184 if (unlikely(!a[OVS_FLOW_ATTR_KEY])) { 1249 if (unlikely(!a[OVS_FLOW_ATTR_KEY] && !ufid_present)) {
1185 err = ovs_flow_tbl_flush(&dp->table); 1250 err = ovs_flow_tbl_flush(&dp->table);
1186 goto unlock; 1251 goto unlock;
1187 } 1252 }
1188 1253
1189 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); 1254 if (ufid_present)
1255 flow = ovs_flow_tbl_lookup_ufid(&dp->table, &ufid);
1256 else
1257 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
1190 if (unlikely(!flow)) { 1258 if (unlikely(!flow)) {
1191 err = -ENOENT; 1259 err = -ENOENT;
1192 goto unlock; 1260 goto unlock;
@@ -1196,14 +1264,15 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
1196 ovs_unlock(); 1264 ovs_unlock();
1197 1265
1198 reply = ovs_flow_cmd_alloc_info((const struct sw_flow_actions __force *) flow->sf_acts, 1266 reply = ovs_flow_cmd_alloc_info((const struct sw_flow_actions __force *) flow->sf_acts,
1199 info, false); 1267 &flow->id, info, false, ufid_flags);
1200 if (likely(reply)) { 1268 if (likely(reply)) {
1201 if (likely(!IS_ERR(reply))) { 1269 if (likely(!IS_ERR(reply))) {
1202 rcu_read_lock(); /*To keep RCU checker happy. */ 1270 rcu_read_lock(); /*To keep RCU checker happy. */
1203 err = ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex, 1271 err = ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex,
1204 reply, info->snd_portid, 1272 reply, info->snd_portid,
1205 info->snd_seq, 0, 1273 info->snd_seq, 0,
1206 OVS_FLOW_CMD_DEL); 1274 OVS_FLOW_CMD_DEL,
1275 ufid_flags);
1207 rcu_read_unlock(); 1276 rcu_read_unlock();
1208 BUG_ON(err < 0); 1277 BUG_ON(err < 0);
1209 1278
@@ -1222,9 +1291,18 @@ unlock:
1222 1291
1223static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) 1292static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1224{ 1293{
1294 struct nlattr *a[__OVS_FLOW_ATTR_MAX];
1225 struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh)); 1295 struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
1226 struct table_instance *ti; 1296 struct table_instance *ti;
1227 struct datapath *dp; 1297 struct datapath *dp;
1298 u32 ufid_flags;
1299 int err;
1300
1301 err = genlmsg_parse(cb->nlh, &dp_flow_genl_family, a,
1302 OVS_FLOW_ATTR_MAX, flow_policy);
1303 if (err)
1304 return err;
1305 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
1228 1306
1229 rcu_read_lock(); 1307 rcu_read_lock();
1230 dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex); 1308 dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
@@ -1247,7 +1325,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1247 if (ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex, skb, 1325 if (ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex, skb,
1248 NETLINK_CB(cb->skb).portid, 1326 NETLINK_CB(cb->skb).portid,
1249 cb->nlh->nlmsg_seq, NLM_F_MULTI, 1327 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1250 OVS_FLOW_CMD_NEW) < 0) 1328 OVS_FLOW_CMD_NEW, ufid_flags) < 0)
1251 break; 1329 break;
1252 1330
1253 cb->args[0] = bucket; 1331 cb->args[0] = bucket;
@@ -1263,6 +1341,8 @@ static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = {
1263 [OVS_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED }, 1341 [OVS_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED },
1264 [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG }, 1342 [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG },
1265 [OVS_FLOW_ATTR_PROBE] = { .type = NLA_FLAG }, 1343 [OVS_FLOW_ATTR_PROBE] = { .type = NLA_FLAG },
1344 [OVS_FLOW_ATTR_UFID] = { .type = NLA_UNSPEC, .len = 1 },
1345 [OVS_FLOW_ATTR_UFID_FLAGS] = { .type = NLA_U32 },
1266}; 1346};
1267 1347
1268static const struct genl_ops dp_flow_genl_ops[] = { 1348static const struct genl_ops dp_flow_genl_ops[] = {
@@ -1348,7 +1428,8 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
1348 if (nla_put_u32(skb, OVS_DP_ATTR_USER_FEATURES, dp->user_features)) 1428 if (nla_put_u32(skb, OVS_DP_ATTR_USER_FEATURES, dp->user_features))
1349 goto nla_put_failure; 1429 goto nla_put_failure;
1350 1430
1351 return genlmsg_end(skb, ovs_header); 1431 genlmsg_end(skb, ovs_header);
1432 return 0;
1352 1433
1353nla_put_failure: 1434nla_put_failure:
1354 genlmsg_cancel(skb, ovs_header); 1435 genlmsg_cancel(skb, ovs_header);
@@ -1722,7 +1803,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
1722 if (err == -EMSGSIZE) 1803 if (err == -EMSGSIZE)
1723 goto error; 1804 goto error;
1724 1805
1725 return genlmsg_end(skb, ovs_header); 1806 genlmsg_end(skb, ovs_header);
1807 return 0;
1726 1808
1727nla_put_failure: 1809nla_put_failure:
1728 err = -EMSGSIZE; 1810 err = -EMSGSIZE;