* Re: [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs
2026-08-01 11:25 [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs Zhiling Zou
@ 2026-08-01 15:00 ` Ilya Maximets
2026-08-08 14:23 ` kernel test robot
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Ilya Maximets @ 2026-08-01 15:00 UTC (permalink / raw)
To: Zhiling Zou, netdev, dev, i.maximets
Cc: aconole, echaudro, davem, edumazet, kuba, pabeni, horms, vega
On 8/1/26 1:25 PM, Zhiling Zou wrote:
> ovs_flow_cmd_new() preallocates the optional reply skb before it takes
> ovs_mutex and before it knows which existing flow will be updated.
>
> That is normally fine because the skb is sized from the request flow
> identifier. That identifier also becomes the inserted flow's identifier.
> For updates, however, a request with a UFID may miss the UFID lookup and
> then fall back to the flow key lookup. That lookup can legitimately find
> an existing key-identified flow. UFIDs are optional and the flow key is
> the primary identifier.
>
> For echoed replies, ovs_flow_cmd_fill_info() writes the matched flow's
> identifier, not the request identifier used for the preallocation. A short
> request UFID can therefore leave too little room for the key identifier.
> The fill can then fail with -EMSGSIZE and hit the BUG_ON(error < 0) in the
> update path.
>
> Once the update target has been resolved, reallocate the reply skb if the
> matched flow needs a larger reply than the request identifier allowed. Do
> this before replacing the actions so the request can still fail cleanly if
> the rare extra allocation fails.
>
> Fixes: 74ed7ab9264c ("openvswitch: Add support for unique flow IDs.")
> Cc: stable@vger.kernel.org
> Reported-by: Vega <vega@nebusec.ai>
> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
> ---
> changes in v4:
> - Split the reply size comparison into current and desired variables as
> requested by Ilya Maximets.
> - v3 Link: https://lore.kernel.org/all/c773b2726dda8d90eed6d42b2f9741810a7a46e1.1785288876.git.zhilinz@nebusec.ai/
>
> changes in v3:
> - Compare computed reply sizes instead of UFID contents.
> - Inline the rare reallocation check and add spacing around the update checks.
> - v2 Link: https://lore.kernel.org/all/71380bcfbf3aed9a6a8a9daeef6592fa5a4fb245.1785211788.git.zhilinz@nebusec.ai/
>
> changes in v2:
> - Preserve valid key/UFID mixed flow updates as requested by Ilya Maximets.
> - Reallocate the echoed reply skb with the matched flow identifier before replacing actions.
> - v1 Link: https://lore.kernel.org/all/fa4f85fe7becb164a8a1849aa77ceeb1c08b078c.1784881178.git.zhilinz@nebusec.ai/
>
> net/openvswitch/datapath.c | 28 +++++++++++++++++++++++++---
> 1 file changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
> index eaf332b156d73..d73d729176e1f 100644
> --- a/net/openvswitch/datapath.c
> +++ b/net/openvswitch/datapath.c
> @@ -1113,9 +1113,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
> error = -EEXIST;
> goto err_unlock_ovs;
> }
> - /* The flow identifier has to be the same for flow updates.
> - * Look for any overlapping flow.
> - */
> +
> + /* Look for any overlapping flow. */
> if (unlikely(!ovs_flow_cmp(flow, &match))) {
> if (ovs_identifier_is_key(&flow->id))
> flow = ovs_flow_tbl_lookup_exact(&dp->table,
> @@ -1127,6 +1126,29 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
> goto err_unlock_ovs;
> }
> }
> +
> + if (unlikely(reply)) {
> + size_t current, desired;
Unfortunately, this breaks the build. Please, make sure the code
compiles without warnings before posting patches, don't just copy
suggestions.
Let's rename these into 'cur' and 'req' (required).
> +
> + current = ovs_flow_cmd_msg_size(acts, &new_flow->id,
> + ufid_flags);
> + desired = ovs_flow_cmd_msg_size(acts, &flow->id,
> + ufid_flags);
> + if (current < desired) {
> + struct sk_buff *resized;
> +
> + resized = ovs_flow_cmd_alloc_info(acts, &flow->id,
This line is too long. The line length check for netdev patches
is 80. Move the id to the next line.
> + info, false,
> + ufid_flags);
> + if (IS_ERR(resized)) {
> + error = PTR_ERR(resized);
> + goto err_unlock_ovs;
> + }
> + kfree_skb(reply);
> + reply = resized;
> + }
> + }
> +
> /* Update actions. */
> old_acts = ovsl_dereference(flow->sf_acts);
> rcu_assign_pointer(flow->sf_acts, acts);
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs
2026-08-01 11:25 [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs Zhiling Zou
2026-08-01 15:00 ` Ilya Maximets
@ 2026-08-08 14:23 ` kernel test robot
2026-08-08 17:33 ` kernel test robot
2026-08-08 22:19 ` kernel test robot
3 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2026-08-08 14:23 UTC (permalink / raw)
To: Zhiling Zou, netdev, dev, i.maximets
Cc: oe-kbuild-all, aconole, echaudro, davem, edumazet, kuba, pabeni,
horms, vega, zhilinz
Hi Zhiling,
kernel test robot noticed the following build errors:
[auto build test ERROR on horms-ipvs/master]
[also build test ERROR on v7.2-rc6]
[cannot apply to net/main net-next/main linus/master next-20260807]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Zhiling-Zou/net-openvswitch-reallocate-update-replies-for-mismatched-IDs/20260808-205431
base: https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git master
patch link: https://lore.kernel.org/r/3b76cbe50252a5650c3b69c789ed36481d0bbee4.1785583308.git.zhilinz%40nebusec.ai
patch subject: [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs
config: alpha-allmodconfig (https://download.01.org/0day-ci/archive/20260808/202608082248.euvm5RXc-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 16.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260808/202608082248.euvm5RXc-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608082248.euvm5RXc-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from ./arch/alpha/include/generated/asm/current.h:1,
from arch/alpha/include/asm/spinlock.h:6,
from include/linux/spinlock.h:94,
from include/linux/kref.h:16,
from include/linux/mm_types.h:8,
from include/linux/buildid.h:5,
from include/linux/module.h:14,
from net/openvswitch/datapath.c:9:
net/openvswitch/datapath.c: In function 'ovs_flow_cmd_new':
>> include/asm-generic/current.h:7:45: error: expected ')' before '->' token
7 | #define get_current() (current_thread_info()->task)
| ^~
include/asm-generic/current.h:8:17: note: in expansion of macro 'get_current'
8 | #define current get_current()
| ^~~~~~~~~~~
net/openvswitch/datapath.c:1100:32: note: in expansion of macro 'current'
1100 | size_t current, desired;
| ^~~~~~~
>> net/openvswitch/datapath.c:1102:33: error: assignment to 'struct task_struct *' from 'size_t' {aka 'long unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
1102 | current = ovs_flow_cmd_msg_size(acts, &new_flow->id,
| ^
>> net/openvswitch/datapath.c:1104:25: error: 'desired' undeclared (first use in this function)
1104 | desired = ovs_flow_cmd_msg_size(acts, &flow->id,
| ^~~~~~~
net/openvswitch/datapath.c:1104:25: note: each undeclared identifier is reported only once for each function it appears in
vim +1102 net/openvswitch/datapath.c
966
967 static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
968 {
969 struct net *net = sock_net(skb->sk);
970 struct nlattr **a = info->attrs;
971 struct ovs_header *ovs_header = info->userhdr;
972 struct sw_flow *flow = NULL, *new_flow;
973 struct sw_flow_mask mask;
974 struct sk_buff *reply;
975 struct datapath *dp;
976 struct sw_flow_key *key;
977 struct sw_flow_actions *acts;
978 struct sw_flow_match match;
979 u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
980 int error;
981 bool log = !a[OVS_FLOW_ATTR_PROBE];
982
983 /* Must have key and actions. */
984 error = -EINVAL;
985 if (!a[OVS_FLOW_ATTR_KEY]) {
986 OVS_NLERR(log, "Flow key attr not present in new flow.");
987 goto error;
988 }
989 if (!a[OVS_FLOW_ATTR_ACTIONS]) {
990 OVS_NLERR(log, "Flow actions attr not present in new flow.");
991 goto error;
992 }
993
994 /* Most of the time we need to allocate a new flow, do it before
995 * locking.
996 */
997 new_flow = ovs_flow_alloc();
998 if (IS_ERR(new_flow)) {
999 error = PTR_ERR(new_flow);
1000 goto error;
1001 }
1002
1003 /* Extract key. */
1004 key = kzalloc(sizeof(*key), GFP_KERNEL);
1005 if (!key) {
1006 error = -ENOMEM;
1007 goto err_kfree_flow;
1008 }
1009
1010 ovs_match_init(&match, key, false, &mask);
1011 error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
1012 a[OVS_FLOW_ATTR_MASK], log);
1013 if (error)
1014 goto err_kfree_key;
1015
1016 ovs_flow_mask_key(&new_flow->key, key, true, &mask);
1017
1018 /* Extract flow identifier. */
1019 error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
1020 key, log);
1021 if (error)
1022 goto err_kfree_key;
1023
1024 /* Validate actions. */
1025 error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
1026 &new_flow->key, &acts, log);
1027 if (error) {
1028 OVS_NLERR(log, "Flow actions may not be safe on all matching packets.");
1029 goto err_kfree_key;
1030 }
1031
1032 reply = ovs_flow_cmd_alloc_info(acts, &new_flow->id, info, false,
1033 ufid_flags);
1034 if (IS_ERR(reply)) {
1035 error = PTR_ERR(reply);
1036 goto err_kfree_acts;
1037 }
1038
1039 ovs_lock();
1040 dp = get_dp(net, ovs_header->dp_ifindex);
1041 if (unlikely(!dp)) {
1042 error = -ENODEV;
1043 goto err_unlock_ovs;
1044 }
1045
1046 /* Check if this is a duplicate flow */
1047 if (ovs_identifier_is_ufid(&new_flow->id))
1048 flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
1049 if (!flow)
1050 flow = ovs_flow_tbl_lookup(&dp->table, key);
1051 if (likely(!flow)) {
1052 rcu_assign_pointer(new_flow->sf_acts, acts);
1053
1054 /* Put flow in bucket. */
1055 error = ovs_flow_tbl_insert(&dp->table, new_flow, &mask);
1056 if (unlikely(error)) {
1057 acts = NULL;
1058 goto err_unlock_ovs;
1059 }
1060
1061 if (unlikely(reply)) {
1062 error = ovs_flow_cmd_fill_info(new_flow,
1063 ovs_header->dp_ifindex,
1064 reply, info->snd_portid,
1065 info->snd_seq, 0,
1066 OVS_FLOW_CMD_NEW,
1067 ufid_flags);
1068 BUG_ON(error < 0);
1069 }
1070 ovs_unlock();
1071 } else {
1072 struct sw_flow_actions *old_acts;
1073
1074 /* Bail out if we're not allowed to modify an existing flow.
1075 * We accept NLM_F_CREATE in place of the intended NLM_F_EXCL
1076 * because Generic Netlink treats the latter as a dump
1077 * request. We also accept NLM_F_EXCL in case that bug ever
1078 * gets fixed.
1079 */
1080 if (unlikely(info->nlhdr->nlmsg_flags & (NLM_F_CREATE
1081 | NLM_F_EXCL))) {
1082 error = -EEXIST;
1083 goto err_unlock_ovs;
1084 }
1085
1086 /* Look for any overlapping flow. */
1087 if (unlikely(!ovs_flow_cmp(flow, &match))) {
1088 if (ovs_identifier_is_key(&flow->id))
1089 flow = ovs_flow_tbl_lookup_exact(&dp->table,
1090 &match);
1091 else /* UFID matches but key is different */
1092 flow = NULL;
1093 if (!flow) {
1094 error = -ENOENT;
1095 goto err_unlock_ovs;
1096 }
1097 }
1098
1099 if (unlikely(reply)) {
> 1100 size_t current, desired;
1101
> 1102 current = ovs_flow_cmd_msg_size(acts, &new_flow->id,
1103 ufid_flags);
> 1104 desired = ovs_flow_cmd_msg_size(acts, &flow->id,
1105 ufid_flags);
1106 if (current < desired) {
1107 struct sk_buff *resized;
1108
1109 resized = ovs_flow_cmd_alloc_info(acts, &flow->id,
1110 info, false,
1111 ufid_flags);
1112 if (IS_ERR(resized)) {
1113 error = PTR_ERR(resized);
1114 goto err_unlock_ovs;
1115 }
1116 kfree_skb(reply);
1117 reply = resized;
1118 }
1119 }
1120
1121 /* Update actions. */
1122 old_acts = ovsl_dereference(flow->sf_acts);
1123 rcu_assign_pointer(flow->sf_acts, acts);
1124
1125 if (unlikely(reply)) {
1126 error = ovs_flow_cmd_fill_info(flow,
1127 ovs_header->dp_ifindex,
1128 reply, info->snd_portid,
1129 info->snd_seq, 0,
1130 OVS_FLOW_CMD_NEW,
1131 ufid_flags);
1132 BUG_ON(error < 0);
1133 }
1134 ovs_unlock();
1135
1136 ovs_nla_free_flow_actions_rcu(old_acts);
1137 ovs_flow_free(new_flow, false);
1138 }
1139
1140 if (reply)
1141 ovs_notify(&dp_flow_genl_family, reply, info);
1142
1143 kfree(key);
1144 return 0;
1145
1146 err_unlock_ovs:
1147 ovs_unlock();
1148 kfree_skb(reply);
1149 err_kfree_acts:
1150 ovs_nla_free_flow_actions(acts);
1151 err_kfree_key:
1152 kfree(key);
1153 err_kfree_flow:
1154 ovs_flow_free(new_flow, false);
1155 error:
1156 return error;
1157 }
1158
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs
2026-08-01 11:25 [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs Zhiling Zou
2026-08-01 15:00 ` Ilya Maximets
2026-08-08 14:23 ` kernel test robot
@ 2026-08-08 17:33 ` kernel test robot
2026-08-08 22:19 ` kernel test robot
3 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2026-08-08 17:33 UTC (permalink / raw)
To: Zhiling Zou, netdev, dev, i.maximets
Cc: oe-kbuild-all, aconole, echaudro, davem, edumazet, kuba, pabeni,
horms, vega, zhilinz
Hi Zhiling,
kernel test robot noticed the following build errors:
[auto build test ERROR on horms-ipvs/master]
[also build test ERROR on v7.2-rc6]
[cannot apply to net/main net-next/main linus/master next-20260807]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Zhiling-Zou/net-openvswitch-reallocate-update-replies-for-mismatched-IDs/20260808-205431
base: https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git master
patch link: https://lore.kernel.org/r/3b76cbe50252a5650c3b69c789ed36481d0bbee4.1785583308.git.zhilinz%40nebusec.ai
patch subject: [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs
config: powerpc-allmodconfig (https://download.01.org/0day-ci/archive/20260809/202608090140.jJdhfFjc-lkp@intel.com/config)
compiler: powerpc64-linux-gcc (GCC) 16.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260809/202608090140.jJdhfFjc-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608090140.jJdhfFjc-lkp@intel.com/
All errors (new ones prefixed by >>):
net/openvswitch/datapath.c: In function 'ovs_flow_cmd_new':
>> net/openvswitch/datapath.c:1100:25: error: function declaration isn't a prototype [-Werror=strict-prototypes]
1100 | size_t current, desired;
| ^~~~~~
In file included from include/linux/thread_info.h:23,
from include/asm-generic/preempt.h:5,
from ./arch/powerpc/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/kref.h:16,
from include/linux/mm_types.h:8,
from include/linux/buildid.h:5,
from include/linux/module.h:14,
from net/openvswitch/datapath.c:9:
>> arch/powerpc/include/asm/current.h:26:17: error: conflicting types for 'get_current'; have 'size_t()' {aka 'long unsigned int()'}
26 | #define current get_current()
| ^~~~~~~~~~~
net/openvswitch/datapath.c:1100:32: note: in expansion of macro 'current'
1100 | size_t current, desired;
| ^~~~~~~
arch/powerpc/include/asm/current.h:15:35: note: previous definition of 'get_current' with type 'struct task_struct *(void)'
15 | static inline struct task_struct *get_current(void)
| ^~~~~~~~~~~
>> net/openvswitch/datapath.c:1102:33: error: lvalue required as left operand of assignment
1102 | current = ovs_flow_cmd_msg_size(acts, &new_flow->id,
| ^
cc1: some warnings being treated as errors
vim +1100 net/openvswitch/datapath.c
966
967 static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
968 {
969 struct net *net = sock_net(skb->sk);
970 struct nlattr **a = info->attrs;
971 struct ovs_header *ovs_header = info->userhdr;
972 struct sw_flow *flow = NULL, *new_flow;
973 struct sw_flow_mask mask;
974 struct sk_buff *reply;
975 struct datapath *dp;
976 struct sw_flow_key *key;
977 struct sw_flow_actions *acts;
978 struct sw_flow_match match;
979 u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
980 int error;
981 bool log = !a[OVS_FLOW_ATTR_PROBE];
982
983 /* Must have key and actions. */
984 error = -EINVAL;
985 if (!a[OVS_FLOW_ATTR_KEY]) {
986 OVS_NLERR(log, "Flow key attr not present in new flow.");
987 goto error;
988 }
989 if (!a[OVS_FLOW_ATTR_ACTIONS]) {
990 OVS_NLERR(log, "Flow actions attr not present in new flow.");
991 goto error;
992 }
993
994 /* Most of the time we need to allocate a new flow, do it before
995 * locking.
996 */
997 new_flow = ovs_flow_alloc();
998 if (IS_ERR(new_flow)) {
999 error = PTR_ERR(new_flow);
1000 goto error;
1001 }
1002
1003 /* Extract key. */
1004 key = kzalloc(sizeof(*key), GFP_KERNEL);
1005 if (!key) {
1006 error = -ENOMEM;
1007 goto err_kfree_flow;
1008 }
1009
1010 ovs_match_init(&match, key, false, &mask);
1011 error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
1012 a[OVS_FLOW_ATTR_MASK], log);
1013 if (error)
1014 goto err_kfree_key;
1015
1016 ovs_flow_mask_key(&new_flow->key, key, true, &mask);
1017
1018 /* Extract flow identifier. */
1019 error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
1020 key, log);
1021 if (error)
1022 goto err_kfree_key;
1023
1024 /* Validate actions. */
1025 error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
1026 &new_flow->key, &acts, log);
1027 if (error) {
1028 OVS_NLERR(log, "Flow actions may not be safe on all matching packets.");
1029 goto err_kfree_key;
1030 }
1031
1032 reply = ovs_flow_cmd_alloc_info(acts, &new_flow->id, info, false,
1033 ufid_flags);
1034 if (IS_ERR(reply)) {
1035 error = PTR_ERR(reply);
1036 goto err_kfree_acts;
1037 }
1038
1039 ovs_lock();
1040 dp = get_dp(net, ovs_header->dp_ifindex);
1041 if (unlikely(!dp)) {
1042 error = -ENODEV;
1043 goto err_unlock_ovs;
1044 }
1045
1046 /* Check if this is a duplicate flow */
1047 if (ovs_identifier_is_ufid(&new_flow->id))
1048 flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
1049 if (!flow)
1050 flow = ovs_flow_tbl_lookup(&dp->table, key);
1051 if (likely(!flow)) {
1052 rcu_assign_pointer(new_flow->sf_acts, acts);
1053
1054 /* Put flow in bucket. */
1055 error = ovs_flow_tbl_insert(&dp->table, new_flow, &mask);
1056 if (unlikely(error)) {
1057 acts = NULL;
1058 goto err_unlock_ovs;
1059 }
1060
1061 if (unlikely(reply)) {
1062 error = ovs_flow_cmd_fill_info(new_flow,
1063 ovs_header->dp_ifindex,
1064 reply, info->snd_portid,
1065 info->snd_seq, 0,
1066 OVS_FLOW_CMD_NEW,
1067 ufid_flags);
1068 BUG_ON(error < 0);
1069 }
1070 ovs_unlock();
1071 } else {
1072 struct sw_flow_actions *old_acts;
1073
1074 /* Bail out if we're not allowed to modify an existing flow.
1075 * We accept NLM_F_CREATE in place of the intended NLM_F_EXCL
1076 * because Generic Netlink treats the latter as a dump
1077 * request. We also accept NLM_F_EXCL in case that bug ever
1078 * gets fixed.
1079 */
1080 if (unlikely(info->nlhdr->nlmsg_flags & (NLM_F_CREATE
1081 | NLM_F_EXCL))) {
1082 error = -EEXIST;
1083 goto err_unlock_ovs;
1084 }
1085
1086 /* Look for any overlapping flow. */
1087 if (unlikely(!ovs_flow_cmp(flow, &match))) {
1088 if (ovs_identifier_is_key(&flow->id))
1089 flow = ovs_flow_tbl_lookup_exact(&dp->table,
1090 &match);
1091 else /* UFID matches but key is different */
1092 flow = NULL;
1093 if (!flow) {
1094 error = -ENOENT;
1095 goto err_unlock_ovs;
1096 }
1097 }
1098
1099 if (unlikely(reply)) {
> 1100 size_t current, desired;
1101
> 1102 current = ovs_flow_cmd_msg_size(acts, &new_flow->id,
1103 ufid_flags);
1104 desired = ovs_flow_cmd_msg_size(acts, &flow->id,
1105 ufid_flags);
1106 if (current < desired) {
1107 struct sk_buff *resized;
1108
1109 resized = ovs_flow_cmd_alloc_info(acts, &flow->id,
1110 info, false,
1111 ufid_flags);
1112 if (IS_ERR(resized)) {
1113 error = PTR_ERR(resized);
1114 goto err_unlock_ovs;
1115 }
1116 kfree_skb(reply);
1117 reply = resized;
1118 }
1119 }
1120
1121 /* Update actions. */
1122 old_acts = ovsl_dereference(flow->sf_acts);
1123 rcu_assign_pointer(flow->sf_acts, acts);
1124
1125 if (unlikely(reply)) {
1126 error = ovs_flow_cmd_fill_info(flow,
1127 ovs_header->dp_ifindex,
1128 reply, info->snd_portid,
1129 info->snd_seq, 0,
1130 OVS_FLOW_CMD_NEW,
1131 ufid_flags);
1132 BUG_ON(error < 0);
1133 }
1134 ovs_unlock();
1135
1136 ovs_nla_free_flow_actions_rcu(old_acts);
1137 ovs_flow_free(new_flow, false);
1138 }
1139
1140 if (reply)
1141 ovs_notify(&dp_flow_genl_family, reply, info);
1142
1143 kfree(key);
1144 return 0;
1145
1146 err_unlock_ovs:
1147 ovs_unlock();
1148 kfree_skb(reply);
1149 err_kfree_acts:
1150 ovs_nla_free_flow_actions(acts);
1151 err_kfree_key:
1152 kfree(key);
1153 err_kfree_flow:
1154 ovs_flow_free(new_flow, false);
1155 error:
1156 return error;
1157 }
1158
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs
2026-08-01 11:25 [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs Zhiling Zou
` (2 preceding siblings ...)
2026-08-08 17:33 ` kernel test robot
@ 2026-08-08 22:19 ` kernel test robot
3 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2026-08-08 22:19 UTC (permalink / raw)
To: Zhiling Zou, netdev, dev, i.maximets
Cc: oe-kbuild-all, aconole, echaudro, davem, edumazet, kuba, pabeni,
horms, vega, zhilinz
Hi Zhiling,
kernel test robot noticed the following build warnings:
[auto build test WARNING on horms-ipvs/master]
[also build test WARNING on v7.2-rc6]
[cannot apply to net/main net-next/main linus/master next-20260807]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Zhiling-Zou/net-openvswitch-reallocate-update-replies-for-mismatched-IDs/20260808-205431
base: https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git master
patch link: https://lore.kernel.org/r/3b76cbe50252a5650c3b69c789ed36481d0bbee4.1785583308.git.zhilinz%40nebusec.ai
patch subject: [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs
config: nios2-allmodconfig (https://download.01.org/0day-ci/archive/20260809/202608090656.Aevl8bsK-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260809/202608090656.Aevl8bsK-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608090656.Aevl8bsK-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from ./arch/nios2/include/generated/asm/current.h:1,
from include/linux/wait.h:11,
from include/linux/swait.h:8,
from include/linux/completion.h:12,
from include/linux/mm_types.h:14,
from include/linux/buildid.h:5,
from include/linux/module.h:14,
from net/openvswitch/datapath.c:9:
net/openvswitch/datapath.c: In function 'ovs_flow_cmd_new':
include/asm-generic/current.h:7:45: error: expected ')' before '->' token
7 | #define get_current() (current_thread_info()->task)
| ^~
include/asm-generic/current.h:8:17: note: in expansion of macro 'get_current'
8 | #define current get_current()
| ^~~~~~~~~~~
net/openvswitch/datapath.c:1100:32: note: in expansion of macro 'current'
1100 | size_t current, desired;
| ^~~~~~~
>> net/openvswitch/datapath.c:1102:33: warning: assignment to 'struct task_struct *' from 'size_t' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
1102 | current = ovs_flow_cmd_msg_size(acts, &new_flow->id,
| ^
net/openvswitch/datapath.c:1104:25: error: 'desired' undeclared (first use in this function)
1104 | desired = ovs_flow_cmd_msg_size(acts, &flow->id,
| ^~~~~~~
net/openvswitch/datapath.c:1104:25: note: each undeclared identifier is reported only once for each function it appears in
vim +1102 net/openvswitch/datapath.c
966
967 static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
968 {
969 struct net *net = sock_net(skb->sk);
970 struct nlattr **a = info->attrs;
971 struct ovs_header *ovs_header = info->userhdr;
972 struct sw_flow *flow = NULL, *new_flow;
973 struct sw_flow_mask mask;
974 struct sk_buff *reply;
975 struct datapath *dp;
976 struct sw_flow_key *key;
977 struct sw_flow_actions *acts;
978 struct sw_flow_match match;
979 u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
980 int error;
981 bool log = !a[OVS_FLOW_ATTR_PROBE];
982
983 /* Must have key and actions. */
984 error = -EINVAL;
985 if (!a[OVS_FLOW_ATTR_KEY]) {
986 OVS_NLERR(log, "Flow key attr not present in new flow.");
987 goto error;
988 }
989 if (!a[OVS_FLOW_ATTR_ACTIONS]) {
990 OVS_NLERR(log, "Flow actions attr not present in new flow.");
991 goto error;
992 }
993
994 /* Most of the time we need to allocate a new flow, do it before
995 * locking.
996 */
997 new_flow = ovs_flow_alloc();
998 if (IS_ERR(new_flow)) {
999 error = PTR_ERR(new_flow);
1000 goto error;
1001 }
1002
1003 /* Extract key. */
1004 key = kzalloc(sizeof(*key), GFP_KERNEL);
1005 if (!key) {
1006 error = -ENOMEM;
1007 goto err_kfree_flow;
1008 }
1009
1010 ovs_match_init(&match, key, false, &mask);
1011 error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
1012 a[OVS_FLOW_ATTR_MASK], log);
1013 if (error)
1014 goto err_kfree_key;
1015
1016 ovs_flow_mask_key(&new_flow->key, key, true, &mask);
1017
1018 /* Extract flow identifier. */
1019 error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
1020 key, log);
1021 if (error)
1022 goto err_kfree_key;
1023
1024 /* Validate actions. */
1025 error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
1026 &new_flow->key, &acts, log);
1027 if (error) {
1028 OVS_NLERR(log, "Flow actions may not be safe on all matching packets.");
1029 goto err_kfree_key;
1030 }
1031
1032 reply = ovs_flow_cmd_alloc_info(acts, &new_flow->id, info, false,
1033 ufid_flags);
1034 if (IS_ERR(reply)) {
1035 error = PTR_ERR(reply);
1036 goto err_kfree_acts;
1037 }
1038
1039 ovs_lock();
1040 dp = get_dp(net, ovs_header->dp_ifindex);
1041 if (unlikely(!dp)) {
1042 error = -ENODEV;
1043 goto err_unlock_ovs;
1044 }
1045
1046 /* Check if this is a duplicate flow */
1047 if (ovs_identifier_is_ufid(&new_flow->id))
1048 flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
1049 if (!flow)
1050 flow = ovs_flow_tbl_lookup(&dp->table, key);
1051 if (likely(!flow)) {
1052 rcu_assign_pointer(new_flow->sf_acts, acts);
1053
1054 /* Put flow in bucket. */
1055 error = ovs_flow_tbl_insert(&dp->table, new_flow, &mask);
1056 if (unlikely(error)) {
1057 acts = NULL;
1058 goto err_unlock_ovs;
1059 }
1060
1061 if (unlikely(reply)) {
1062 error = ovs_flow_cmd_fill_info(new_flow,
1063 ovs_header->dp_ifindex,
1064 reply, info->snd_portid,
1065 info->snd_seq, 0,
1066 OVS_FLOW_CMD_NEW,
1067 ufid_flags);
1068 BUG_ON(error < 0);
1069 }
1070 ovs_unlock();
1071 } else {
1072 struct sw_flow_actions *old_acts;
1073
1074 /* Bail out if we're not allowed to modify an existing flow.
1075 * We accept NLM_F_CREATE in place of the intended NLM_F_EXCL
1076 * because Generic Netlink treats the latter as a dump
1077 * request. We also accept NLM_F_EXCL in case that bug ever
1078 * gets fixed.
1079 */
1080 if (unlikely(info->nlhdr->nlmsg_flags & (NLM_F_CREATE
1081 | NLM_F_EXCL))) {
1082 error = -EEXIST;
1083 goto err_unlock_ovs;
1084 }
1085
1086 /* Look for any overlapping flow. */
1087 if (unlikely(!ovs_flow_cmp(flow, &match))) {
1088 if (ovs_identifier_is_key(&flow->id))
1089 flow = ovs_flow_tbl_lookup_exact(&dp->table,
1090 &match);
1091 else /* UFID matches but key is different */
1092 flow = NULL;
1093 if (!flow) {
1094 error = -ENOENT;
1095 goto err_unlock_ovs;
1096 }
1097 }
1098
1099 if (unlikely(reply)) {
1100 size_t current, desired;
1101
> 1102 current = ovs_flow_cmd_msg_size(acts, &new_flow->id,
1103 ufid_flags);
1104 desired = ovs_flow_cmd_msg_size(acts, &flow->id,
1105 ufid_flags);
1106 if (current < desired) {
1107 struct sk_buff *resized;
1108
1109 resized = ovs_flow_cmd_alloc_info(acts, &flow->id,
1110 info, false,
1111 ufid_flags);
1112 if (IS_ERR(resized)) {
1113 error = PTR_ERR(resized);
1114 goto err_unlock_ovs;
1115 }
1116 kfree_skb(reply);
1117 reply = resized;
1118 }
1119 }
1120
1121 /* Update actions. */
1122 old_acts = ovsl_dereference(flow->sf_acts);
1123 rcu_assign_pointer(flow->sf_acts, acts);
1124
1125 if (unlikely(reply)) {
1126 error = ovs_flow_cmd_fill_info(flow,
1127 ovs_header->dp_ifindex,
1128 reply, info->snd_portid,
1129 info->snd_seq, 0,
1130 OVS_FLOW_CMD_NEW,
1131 ufid_flags);
1132 BUG_ON(error < 0);
1133 }
1134 ovs_unlock();
1135
1136 ovs_nla_free_flow_actions_rcu(old_acts);
1137 ovs_flow_free(new_flow, false);
1138 }
1139
1140 if (reply)
1141 ovs_notify(&dp_flow_genl_family, reply, info);
1142
1143 kfree(key);
1144 return 0;
1145
1146 err_unlock_ovs:
1147 ovs_unlock();
1148 kfree_skb(reply);
1149 err_kfree_acts:
1150 ovs_nla_free_flow_actions(acts);
1151 err_kfree_key:
1152 kfree(key);
1153 err_kfree_flow:
1154 ovs_flow_free(new_flow, false);
1155 error:
1156 return error;
1157 }
1158
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread