diff mbox series

[ovs-dev,v3] dpctl/add-flow: Fix ovs-dpdk crash when add dp flow without in_port field.

Message ID 1614332939-52832-1-git-send-email-maoyingming@baidu.com
State Accepted
Headers show
Series [ovs-dev,v3] dpctl/add-flow: Fix ovs-dpdk crash when add dp flow without in_port field. | expand

Commit Message

Mao,Yingming Feb. 26, 2021, 9:48 a.m. UTC
Fix the following ovs-dpdk crash and add a unit test for this issue
to tests/dpif-netdev.at

$ ovs-appctl dpctl/add-flow netdev@ovs-netdev "eth(),eth_type(0x0800),ipv4()" "3"
unixctl|WARN|error communicating with unix:/usr/local/var/run/openvswitch/ovs-vswitchd.1995.ctl: End of file
ovs-appctl: ovs-vswitchd: transaction error (End of file)

ovs-vswitchd.log record:
util(ovs-vswitchd)|EMER|lib/dpif-netdev.c:3638: assertion match->wc.masks.in_port.odp_port == ODPP_NONE failed in dp_netdev_flow_add()
daemon_unix(monitor)|ERR|2 crashes: pid 1995 died, killed (Aborted), core dumped, restarting

Fix result:

$ ovs-appctl dpctl/add-flow netdev@ovs-netdev "eth(),eth_type(0x0800),ipv4()" "3"
ovs-vswitchd: updating flow table (Invalid argument)
ovs-appctl: ovs-vswitchd: server returned an error

ovs-vswitchd.log record:
dpif_netdev|ERR|failed to put[create] flow: in_port is not an exact match
dpif|WARN|netdev@ovs-netdev: failed to put[create] (Invalid argument) ufid:7ee62592-88ca-4ff2-9e42-38c5d844ffd1 eth(src=00:00:00:00:00:00/00:00:00:00:00:00,dst=00:00:00:00:00:00/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=0.0.0.0/0.0.0.0,dst=0.0.0.0/0.0.0.0,proto=0/0,tos=0/0,ttl=0/0), actions:3

Signed-off-by: Mao YingMing <maoyingming@baidu.com>
---
 lib/dpif-netdev.c    |  9 +++++++++
 tests/dpif-netdev.at | 22 ++++++++++++++++++++++
 2 files changed, 31 insertions(+)

Comments

Ilya Maximets March 2, 2021, 9:52 a.m. UTC | #1
On 2/26/21 10:48 AM, Mao YingMing wrote:
> Fix the following ovs-dpdk crash and add a unit test for this issue
> to tests/dpif-netdev.at
> 
> $ ovs-appctl dpctl/add-flow netdev@ovs-netdev "eth(),eth_type(0x0800),ipv4()" "3"
> unixctl|WARN|error communicating with unix:/usr/local/var/run/openvswitch/ovs-vswitchd.1995.ctl: End of file
> ovs-appctl: ovs-vswitchd: transaction error (End of file)
> 
> ovs-vswitchd.log record:
> util(ovs-vswitchd)|EMER|lib/dpif-netdev.c:3638: assertion match->wc.masks.in_port.odp_port == ODPP_NONE failed in dp_netdev_flow_add()
> daemon_unix(monitor)|ERR|2 crashes: pid 1995 died, killed (Aborted), core dumped, restarting
> 
> Fix result:
> 
> $ ovs-appctl dpctl/add-flow netdev@ovs-netdev "eth(),eth_type(0x0800),ipv4()" "3"
> ovs-vswitchd: updating flow table (Invalid argument)
> ovs-appctl: ovs-vswitchd: server returned an error
> 
> ovs-vswitchd.log record:
> dpif_netdev|ERR|failed to put[create] flow: in_port is not an exact match
> dpif|WARN|netdev@ovs-netdev: failed to put[create] (Invalid argument) ufid:7ee62592-88ca-4ff2-9e42-38c5d844ffd1 eth(src=00:00:00:00:00:00/00:00:00:00:00:00,dst=00:00:00:00:00:00/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=0.0.0.0/0.0.0.0,dst=0.0.0.0/0.0.0.0,proto=0/0,tos=0/0,ttl=0/0), actions:3
> 
> Signed-off-by: Mao YingMing <maoyingming@baidu.com>
> ---
>  lib/dpif-netdev.c    |  9 +++++++++
>  tests/dpif-netdev.at | 22 ++++++++++++++++++++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> index e3fd0a0..d4561e2 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -3834,6 +3834,15 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put)
>          return error;
>      }
>  
> +    if (match.wc.masks.in_port.odp_port != ODPP_NONE) {
> +        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> +
> +        VLOG_ERR_RL(&rl, "failed to put%s flow: in_port is not an exact match",
> +                (put->flags & DPIF_FP_CREATE) ? "[create]"
> +                : (put->flags & DPIF_FP_MODIFY) ? "[modify]" : "[zero]");
> +        return EINVAL;
> +    }
> +
>      if (put->ufid) {
>          ufid = *put->ufid;
>      } else {
> diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at
> index 2862a3c..433ed5f 100644
> --- a/tests/dpif-netdev.at
> +++ b/tests/dpif-netdev.at
> @@ -589,3 +589,25 @@ arp,in_port=ANY,dl_vlan=11,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:
>  
>  DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy])
>  DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy-pmd])
> +
> +m4_define([DPIF_NETDEV_CHECK_IN_PORT_EXACT_MATCH],
> +  [AT_SETUP([dpif-netdev - check dpctl/add-flow in_port exact match - $1])
> +   OVS_VSWITCHD_START(
> +     [add-port br0 p1 \
> +      -- set interface p1 type=$1 options:pstream=punix:$OVS_RUNDIR/p0.sock \
> +      -- set bridge br0 datapath-type=dummy \
> +                        other-config:datapath-id=1234 fail-mode=secure], [], [],
> +      [m4_if([$1], [dummy-pmd], [--dummy-numa="0,0,0,0,1,1,1,1"], [])])
> +
> +   AT_CHECK([ovs-appctl dpctl/add-flow "eth(),eth_type(0x0800),ipv4()" "3"], [2], [],
> +     [ovs-vswitchd: updating flow table (Invalid argument)
> +ovs-appctl: ovs-vswitchd: server returned an error
> +])
> +   OVS_WAIT_UNTIL([grep "flow: in_port is not an exact match" ovs-vswitchd.log])
> +
> +   AT_CHECK([grep 'flow: in_port is not an exact match' ovs-vswitchd.log],[0], [ignore], [ignore])
> +   OVS_VSWITCHD_STOP(["/flow: in_port is not an exact match/d
> +/failed to put/d"])
> +   AT_CLEANUP])
> +
> +DPIF_NETDEV_CHECK_IN_PORT_EXACT_MATCH([dummy-pmd])
> 

Thanks!
I simplified the test a bit (we don't really need m4_define() since there
is no need to test this with different port types) and applied to master.
Also backported down to 2.13.

Best regards, Ilya Maximets.
Mao,Yingming March 2, 2021, 10:24 a.m. UTC | #2
Hi Ilya,

   Thanks for the review.

Best regards, Mao Yingming.

-----邮件原件-----
发件人: Ilya Maximets <i.maximets@ovn.org> 
发送时间: 2021年3月2日 17:53
收件人: Mao,Yingming <maoyingming@baidu.com>; ovs-dev@openvswitch.org
抄送: Ilya Maximets <i.maximets@ovn.org>
主题: Re: [ovs-dev] [PATCH v3] dpctl/add-flow: Fix ovs-dpdk crash when add dp flow without in_port field.

On 2/26/21 10:48 AM, Mao YingMing wrote:
> Fix the following ovs-dpdk crash and add a unit test for this issue to 
> tests/dpif-netdev.at
> 
> $ ovs-appctl dpctl/add-flow netdev@ovs-netdev "eth(),eth_type(0x0800),ipv4()" "3"
> unixctl|WARN|error communicating with 
> unixctl|WARN|unix:/usr/local/var/run/openvswitch/ovs-vswitchd.1995.ctl
> unixctl|WARN|: End of file
> ovs-appctl: ovs-vswitchd: transaction error (End of file)
> 
> ovs-vswitchd.log record:
> util(ovs-vswitchd)|EMER|lib/dpif-netdev.c:3638: assertion 
> match->wc.masks.in_port.odp_port == ODPP_NONE failed in 
> dp_netdev_flow_add()
> daemon_unix(monitor)|ERR|2 crashes: pid 1995 died, killed (Aborted), 
> core dumped, restarting
> 
> Fix result:
> 
> $ ovs-appctl dpctl/add-flow netdev@ovs-netdev "eth(),eth_type(0x0800),ipv4()" "3"
> ovs-vswitchd: updating flow table (Invalid argument)
> ovs-appctl: ovs-vswitchd: server returned an error
> 
> ovs-vswitchd.log record:
> dpif_netdev|ERR|failed to put[create] flow: in_port is not an exact 
> match
> dpif|WARN|netdev@ovs-netdev: failed to put[create] (Invalid argument) 
> dpif|WARN|ufid:7ee62592-88ca-4ff2-9e42-38c5d844ffd1 
> dpif|WARN|eth(src=00:00:00:00:00:00/00:00:00:00:00:00,dst=00:00:00:00:
> dpif|WARN|00:00/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=0.0.0.0/0
> dpif|WARN|.0.0.0,dst=0.0.0.0/0.0.0.0,proto=0/0,tos=0/0,ttl=0/0), 
> dpif|WARN|actions:3
> 
> Signed-off-by: Mao YingMing <maoyingming@baidu.com>
> ---
>  lib/dpif-netdev.c    |  9 +++++++++
>  tests/dpif-netdev.at | 22 ++++++++++++++++++++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 
> e3fd0a0..d4561e2 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -3834,6 +3834,15 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put)
>          return error;
>      }
>  
> +    if (match.wc.masks.in_port.odp_port != ODPP_NONE) {
> +        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 
> + 5);
> +
> +        VLOG_ERR_RL(&rl, "failed to put%s flow: in_port is not an exact match",
> +                (put->flags & DPIF_FP_CREATE) ? "[create]"
> +                : (put->flags & DPIF_FP_MODIFY) ? "[modify]" : "[zero]");
> +        return EINVAL;
> +    }
> +
>      if (put->ufid) {
>          ufid = *put->ufid;
>      } else {
> diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at index 
> 2862a3c..433ed5f 100644
> --- a/tests/dpif-netdev.at
> +++ b/tests/dpif-netdev.at
> @@ -589,3 +589,25 @@ arp,in_port=ANY,dl_vlan=11,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:
>  
>  DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy])
>  DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy-pmd])
> +
> +m4_define([DPIF_NETDEV_CHECK_IN_PORT_EXACT_MATCH],
> +  [AT_SETUP([dpif-netdev - check dpctl/add-flow in_port exact match - $1])
> +   OVS_VSWITCHD_START(
> +     [add-port br0 p1 \
> +      -- set interface p1 type=$1 options:pstream=punix:$OVS_RUNDIR/p0.sock \
> +      -- set bridge br0 datapath-type=dummy \
> +                        other-config:datapath-id=1234 fail-mode=secure], [], [],
> +      [m4_if([$1], [dummy-pmd], [--dummy-numa="0,0,0,0,1,1,1,1"], 
> +[])])
> +
> +   AT_CHECK([ovs-appctl dpctl/add-flow "eth(),eth_type(0x0800),ipv4()" "3"], [2], [],
> +     [ovs-vswitchd: updating flow table (Invalid argument)
> +ovs-appctl: ovs-vswitchd: server returned an error
> +])
> +   OVS_WAIT_UNTIL([grep "flow: in_port is not an exact match" 
> +ovs-vswitchd.log])
> +
> +   AT_CHECK([grep 'flow: in_port is not an exact match' ovs-vswitchd.log],[0], [ignore], [ignore])
> +   OVS_VSWITCHD_STOP(["/flow: in_port is not an exact match/d /failed 
> +to put/d"])
> +   AT_CLEANUP])
> +
> +DPIF_NETDEV_CHECK_IN_PORT_EXACT_MATCH([dummy-pmd])
> 

Thanks!
I simplified the test a bit (we don't really need m4_define() since there is no need to test this with different port types) and applied to master.
Also backported down to 2.13.

Best regards, Ilya Maximets.
diff mbox series

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index e3fd0a0..d4561e2 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -3834,6 +3834,15 @@  dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put)
         return error;
     }
 
+    if (match.wc.masks.in_port.odp_port != ODPP_NONE) {
+        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+
+        VLOG_ERR_RL(&rl, "failed to put%s flow: in_port is not an exact match",
+                (put->flags & DPIF_FP_CREATE) ? "[create]"
+                : (put->flags & DPIF_FP_MODIFY) ? "[modify]" : "[zero]");
+        return EINVAL;
+    }
+
     if (put->ufid) {
         ufid = *put->ufid;
     } else {
diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at
index 2862a3c..433ed5f 100644
--- a/tests/dpif-netdev.at
+++ b/tests/dpif-netdev.at
@@ -589,3 +589,25 @@  arp,in_port=ANY,dl_vlan=11,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:
 
 DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy])
 DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy-pmd])
+
+m4_define([DPIF_NETDEV_CHECK_IN_PORT_EXACT_MATCH],
+  [AT_SETUP([dpif-netdev - check dpctl/add-flow in_port exact match - $1])
+   OVS_VSWITCHD_START(
+     [add-port br0 p1 \
+      -- set interface p1 type=$1 options:pstream=punix:$OVS_RUNDIR/p0.sock \
+      -- set bridge br0 datapath-type=dummy \
+                        other-config:datapath-id=1234 fail-mode=secure], [], [],
+      [m4_if([$1], [dummy-pmd], [--dummy-numa="0,0,0,0,1,1,1,1"], [])])
+
+   AT_CHECK([ovs-appctl dpctl/add-flow "eth(),eth_type(0x0800),ipv4()" "3"], [2], [],
+     [ovs-vswitchd: updating flow table (Invalid argument)
+ovs-appctl: ovs-vswitchd: server returned an error
+])
+   OVS_WAIT_UNTIL([grep "flow: in_port is not an exact match" ovs-vswitchd.log])
+
+   AT_CHECK([grep 'flow: in_port is not an exact match' ovs-vswitchd.log],[0], [ignore], [ignore])
+   OVS_VSWITCHD_STOP(["/flow: in_port is not an exact match/d
+/failed to put/d"])
+   AT_CLEANUP])
+
+DPIF_NETDEV_CHECK_IN_PORT_EXACT_MATCH([dummy-pmd])