* [PATCH net v4 1/1] net: openvswitch: reallocate update replies for mismatched IDs
@ 2026-08-01 11:25 Zhiling Zou
2026-08-01 15:00 ` Ilya Maximets
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Zhiling Zou @ 2026-08-01 11:25 UTC (permalink / raw)
To: netdev, dev, i.maximets
Cc: aconole, echaudro, davem, edumazet, kuba, pabeni, horms, vega,
zhilinz
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;
+
+ 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,
+ 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);
--
2.43.0
^ permalink raw reply related [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
` (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
end of thread, other threads:[~2026-08-08 22:20 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox