2017-12-15 07:09:50 -08:00
|
|
|
AT_BANNER([system-inteface])
|
|
|
|
|
|
|
|
dnl add a veth interface to br0, then delete and re-create
|
|
|
|
dnl the veth interface with the same name in the system
|
|
|
|
AT_SETUP([interface - add delete add same interface])
|
|
|
|
|
|
|
|
OVS_TRAFFIC_VSWITCHD_START()
|
|
|
|
|
|
|
|
AT_CHECK([ip link add ovs-veth0 type veth peer name ovs-veth1])
|
|
|
|
on_exit 'ip link del ovs-veth0'
|
|
|
|
|
|
|
|
AT_CHECK([ovs-vsctl add-port br0 ovs-veth0])
|
|
|
|
|
|
|
|
AT_CHECK([ip link del ovs-veth0])
|
|
|
|
AT_CHECK([ip link add ovs-veth0 type veth peer name ovs-veth1])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-vsctl del-port br0 ovs-veth0])
|
|
|
|
|
|
|
|
OVS_TRAFFIC_VSWITCHD_STOP(["dnl
|
|
|
|
/could not open network device ovs-veth0/d
|
|
|
|
/cannot get .*STP status on nonexistent port/d
|
|
|
|
/ethtool command .*on network device ovs-veth0 failed/d
|
|
|
|
/error receiving .*ovs-veth0/d
|
|
|
|
/ovs-veth0: removing policing failed/d"])
|
|
|
|
|
|
|
|
AT_CLEANUP
|
|
|
|
|
bridge: Clean leaking netdevs when route is added.
When adding a route to a bridge, by executing "$appctl ovs/route/add
$IP/$MASK $BR", a reference to the existing netdev is taken and stored
in an instantiated ip_dev struct which is then stored in an addr_list
list in tnl-ports.c. When OvS is signaled to exit, as a result of a
"$appctl $OVS_PID exit --cleanup", for example, the bridge takes care of
destroying its allocated port and iface structs. While destroying and
freeing an iface, the netdev associated with it is also destroyed.
However, for this to happen its ref_cnt must be 0. Otherwise the
destructor of the netdev (specific to each datapath) won't be called. On
the userspace datapath this means a system interface, such as "br0",
wouldn't get deleted upon exit of OvS (when a route happens to be
assocaited).
This was first observed in the "ptap - triangle bridge setup with L2 and
L3 GRE tunnels" test, which runs as part of the system userspace
testsuite and uses the netdev datapath (as opoosed to several tests
which use the dummy datapath, where this issue isn't seen). The test
would pass every other time and fail the rest of the times because the
needed system interfaces (br-p1, br-p2 and br-p3) were already present
(from the previous successfull run which didn't clean up properly),
leading to a failure.
To fix the leak and clean up the interfaces upon exit, on its final
stage before destroying a netdev, in iface_destroy__(), the bridge calls
tnl_port_map_delete_ipdev() which takes care of freeing the instatiated
ip_dev structs that refer to a specific netdev.
An extra test is also introduced which verifies that the resources used
by OvS netdev datapath have been correctly cleaned up between
OVS_TRAFFIC_VSWITCHD_STOP and AT_CLEANUP.
Signed-off-by: Tiago Lam <tiago.lam@intel.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
2018-06-21 18:39:16 +01:00
|
|
|
dnl add a p1-0 interface to br-p1, then add a route to br-p1 and stop the OvS
|
|
|
|
dnl instance. Confirm br-p1 interface has been deleted from the system.
|
|
|
|
AT_SETUP([interface - add route to br and verify clean-up])
|
|
|
|
|
|
|
|
OVS_TRAFFIC_VSWITCHD_START()
|
|
|
|
|
|
|
|
HWADDR_BRP1=aa:55:00:00:00:01
|
|
|
|
|
|
|
|
dnl Create tap port to later add to br-p1
|
|
|
|
AT_CHECK([ip tuntap add name p1-0 mode tap])
|
|
|
|
AT_CHECK([ip link set p1-0 up])
|
|
|
|
on_exit 'ip link del p1-0'
|
|
|
|
|
|
|
|
AT_CHECK([
|
|
|
|
ovs-vsctl add-br br-p1 -- \
|
|
|
|
set bridge br-p1 datapath_type=netdev fail-mode=standalone other-config:hwaddr=$HWADDR_BRP1
|
|
|
|
|
|
|
|
ovs-vsctl add-port br-p1 p1-0
|
|
|
|
|
|
|
|
ovs-ofctl del-flows br-p1
|
|
|
|
], [0])
|
|
|
|
|
|
|
|
AT_CHECK([
|
|
|
|
ip addr add 10.0.0.1/24 dev br-p1
|
|
|
|
ip link set br-p1 up
|
|
|
|
], [0], [stdout])
|
|
|
|
|
|
|
|
AT_CHECK([
|
|
|
|
ovs-appctl ovs/route/add 10.0.0.0/24 br-p1
|
|
|
|
ovs-appctl tnl/arp/set br-p1 10.0.0.1 $HWADDR_BRP1
|
|
|
|
], [0], [stdout])
|
|
|
|
|
|
|
|
OVS_TRAFFIC_VSWITCHD_STOP
|
|
|
|
AT_CHECK([
|
|
|
|
ip link show br-p1], [1],
|
|
|
|
[stdout], [Device "br-p1" does not exist.]
|
|
|
|
)
|
|
|
|
AT_CLEANUP
|
ofproto: Fix re-creation of tunnel backing interfaces on restart.
Tunnel OpenFlow ports do not exist in the datapath, instead there is a
tunnel backing interface that serves all the tunnels of the same type.
For example, if the geneve port 'my_tunnel' is added to OVS, it will
create 'geneve_sys_6041' datapath port, if it doesn't already exist,
and use this port as a tunnel output.
However, while creating/opening a new datapath after re-start,
ovs-vswitchd only has a list of names of OpenFlow interfaces. And it
thinks that each datapath port, that is not on the list, is a stale
port that needs to be removed. This is obviously not correct for
tunnel backing interfaces that can serve multiple tunnel ports and do
not match OpenFlow port names.
This is causing removal and re-creation of all the tunnel backing
interfaces in the datapath on OVS restart, causing disruption in
existing connections.
It's hard to tell by only having a name of the interface if this
interface is a tunnel backing interface, or someone just named a
normal interface this way. So, instead of trying to determine that,
not removing any interfaces at all, while we don't know types of
actual ports we need.
Assuming that all the ports that are currently not in the list of OF
ports are tunnel backing ports. Later, revalidation of tunnel backing
ports in type_run() will determine which ports are still needed and
which should be removed.
It's OK to add even a non-tunnel stale ports into tnl_backers, they
will be cleaned up the same way as stale tunnel backers.
Reported-at: https://mail.openvswitch.org/pipermail/ovs-discuss/2023-February/052215.html
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2023-02-22 22:12:46 +01:00
|
|
|
|
|
|
|
AT_SETUP([interface - datapath ports garbage collection])
|
|
|
|
OVS_CHECK_GENEVE()
|
|
|
|
OVS_TRAFFIC_VSWITCHD_START()
|
|
|
|
|
|
|
|
dnl Not relevant for userspace datapath.
|
|
|
|
AT_SKIP_IF([! ovs-appctl dpctl/show | grep -q ovs-system])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-vsctl add-port br0 tunnel_port dnl
|
|
|
|
-- set Interface tunnel_port dnl
|
|
|
|
type=geneve options:remote_ip=flow options:key=123])
|
|
|
|
|
|
|
|
AT_CHECK([ip link add ovs-veth0 type veth peer name ovs-veth1])
|
|
|
|
on_exit 'ip link del ovs-veth0'
|
|
|
|
|
|
|
|
AT_CHECK([ovs-vsctl add-port br0 ovs-veth0])
|
|
|
|
|
|
|
|
OVS_WAIT_UNTIL([ip link show | grep -q " genev_sys_[[0-9]]*: .* ovs-system "])
|
|
|
|
|
|
|
|
dnl Store the output of ip link for geneve port to compare ifindex later.
|
|
|
|
AT_CHECK([ip link show | grep " genev_sys_[[0-9]]*: .* ovs-system " > geneve.0])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl
|
|
|
|
port 0: ovs-system (internal)
|
|
|
|
port 1: br0 (internal)
|
|
|
|
port 2: genev_sys_6081 (geneve: packet_type=ptap)
|
|
|
|
port 3: ovs-veth0
|
|
|
|
])
|
|
|
|
|
|
|
|
OVS_APP_EXIT_AND_WAIT_BY_TARGET([ovs-vswitchd], [ovs-vswitchd.pid])
|
|
|
|
|
|
|
|
dnl Check that geneve backing interface is still in the datapath.
|
|
|
|
AT_CHECK([ip link show | grep " genev_sys_[[0-9]]*: .* ovs-system " | diff -u - geneve.0])
|
|
|
|
|
|
|
|
dnl Remove the veth port from the database while ovs-vswitchd is down.
|
|
|
|
AT_CHECK([ovs-vsctl --no-wait del-port ovs-veth0])
|
|
|
|
|
|
|
|
dnl Check that it is still tied to the OVS datapath.
|
|
|
|
AT_CHECK([ip link show ovs-veth0 | grep -q ovs-system])
|
|
|
|
|
|
|
|
dnl Bring ovs-vswitchd back up.
|
|
|
|
AT_CHECK([ovs-vswitchd --detach --no-chdir --pidfile --log-file -vdpif:dbg],
|
|
|
|
[0], [], [stderr])
|
|
|
|
|
|
|
|
dnl Wait for the veth port to be removed from the datapath.
|
|
|
|
OVS_WAIT_WHILE([ip link show ovs-veth0 | grep -q ovs-system])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl
|
|
|
|
port 0: ovs-system (internal)
|
|
|
|
port 1: br0 (internal)
|
|
|
|
port 2: genev_sys_6081 (geneve: packet_type=ptap)
|
|
|
|
])
|
|
|
|
|
|
|
|
dnl Check that geneve backing interface is still in the datapath and it wasn't
|
|
|
|
dnl re-created, i.e. the ifindex is the same.
|
|
|
|
AT_CHECK([ip link show | grep " genev_sys_[[0-9]]*: .* ovs-system " | diff -u - geneve.0])
|
|
|
|
|
|
|
|
OVS_TRAFFIC_VSWITCHD_STOP
|
|
|
|
AT_CLEANUP
|
2023-07-17 10:08:11 +02:00
|
|
|
|
2023-07-19 18:14:04 +02:00
|
|
|
AT_SETUP([interface - datapath port rename])
|
|
|
|
OVS_TRAFFIC_VSWITCHD_START()
|
|
|
|
|
|
|
|
dnl Not relevant for userspace datapath.
|
|
|
|
AT_SKIP_IF([! ovs-appctl dpctl/show | grep -q ovs-system])
|
|
|
|
|
|
|
|
AT_CHECK([ip link add ovs-veth0 type veth peer name ovs-veth1])
|
|
|
|
dnl We will rename ovs-veth0, so removing the peer on exit.
|
|
|
|
on_exit 'ip link del ovs-veth1'
|
|
|
|
|
|
|
|
AT_CHECK([ovs-vsctl add-port br0 ovs-veth0])
|
|
|
|
|
|
|
|
OVS_WAIT_UNTIL([ip link show | grep -q "ovs-veth0.* ovs-system "])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl
|
|
|
|
port 0: ovs-system (internal)
|
|
|
|
port 1: br0 (internal)
|
|
|
|
port 2: ovs-veth0
|
|
|
|
])
|
|
|
|
|
|
|
|
dnl Rename the interface while attached to OVS.
|
|
|
|
AT_CHECK([ip l set ovs-veth0 name ovs-new-port])
|
|
|
|
|
|
|
|
dnl Wait for the port to be detached from the OVS datapath.
|
|
|
|
OVS_WAIT_UNTIL([ip link show | grep "ovs-new-port" | grep -v "ovs-system"])
|
|
|
|
|
|
|
|
dnl Check that database indicates the error.
|
|
|
|
AT_CHECK([ovs-vsctl get interface ovs-veth0 error], [0], [dnl
|
|
|
|
"could not open network device ovs-veth0 (No such device)"
|
|
|
|
])
|
|
|
|
|
|
|
|
dnl Check that the port is no longer in the datapath.
|
|
|
|
AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl
|
|
|
|
port 0: ovs-system (internal)
|
|
|
|
port 1: br0 (internal)
|
|
|
|
])
|
|
|
|
|
|
|
|
dnl Rename the interface back and check that it is in use again.
|
|
|
|
AT_CHECK([ip l set ovs-new-port name ovs-veth0])
|
|
|
|
|
|
|
|
OVS_WAIT_UNTIL([ip link show | grep -q "ovs-veth0.* ovs-system "])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-vsctl get interface ovs-veth0 error], [0], [dnl
|
|
|
|
[[]]
|
|
|
|
])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl
|
|
|
|
port 0: ovs-system (internal)
|
|
|
|
port 1: br0 (internal)
|
|
|
|
port 2: ovs-veth0
|
|
|
|
])
|
|
|
|
|
|
|
|
OVS_TRAFFIC_VSWITCHD_STOP(["
|
|
|
|
/could not open network device ovs-veth0 (No such device)/d
|
|
|
|
"])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
2023-07-17 10:08:11 +02:00
|
|
|
AT_SETUP([interface - current speed])
|
|
|
|
AT_SKIP_IF([test $HAVE_ETHTOOL = "no"])
|
|
|
|
OVS_TRAFFIC_VSWITCHD_START()
|
|
|
|
|
|
|
|
AT_CHECK([ip tuntap add tap0 mode tap])
|
|
|
|
on_exit 'ip tuntap del tap0 mode tap'
|
|
|
|
|
|
|
|
AT_CHECK([ip link set dev tap0 address aa:55:aa:55:00:01])
|
|
|
|
AT_CHECK([ethtool -s tap0 speed 50000 duplex full])
|
|
|
|
AT_CHECK([ip link set dev tap0 up])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-vsctl add-port br0 tap0 -- set int tap0 type=tap])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-ports-desc br0 tap0], [0], [stdout])
|
|
|
|
AT_CHECK([strip_xids < stdout], [0], [dnl
|
|
|
|
OFPST_PORT_DESC reply (OF1.5):
|
|
|
|
1(tap0): addr:aa:55:aa:55:00:01
|
|
|
|
config: 0
|
|
|
|
state: LIVE
|
|
|
|
current: COPPER
|
|
|
|
speed: 50000 Mbps now, 0 Mbps max
|
|
|
|
])
|
|
|
|
|
|
|
|
AT_CHECK([ovs-vsctl get interface tap0 link_speed], [0], [dnl
|
|
|
|
50000000000
|
|
|
|
])
|
|
|
|
|
|
|
|
OVS_TRAFFIC_VSWITCHD_STOP
|
|
|
|
AT_CLEANUP
|