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