summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Conole <aconole@redhat.com>2022-10-05 16:06:23 -0400
committerAaron Conole <aconole@redhat.com>2022-10-05 16:19:17 -0400
commita72c284ba19329cc530287f16b0f65bbed768ee5 (patch)
tree045a0139afc4f2983c656c3aeda27dd78804f6d3
parent2c6c2fdbf956e2338eaf8c9c7e5f137a4db9130a (diff)
helper: Add a test case for ovs helper action
Signed-off-by: Aaron Conole <aconole@redhat.com>
-rwxr-xr-xopenvswitch.sh81
-rw-r--r--ovs-dpctl.py27
2 files changed, 101 insertions, 7 deletions
diff --git a/openvswitch.sh b/openvswitch.sh
index 43636f6..82808ec 100755
--- a/openvswitch.sh
+++ b/openvswitch.sh
@@ -18,6 +18,7 @@ tests="
arp_ping eth-arp: Basic ping between two NS
connect_v4 ipv4: Basic forwarding test case with ICMP
ct_connect_v4 ipv4: Basic IP ct action test
+ ct_helper_v4 ipv4: Test using FTP helper for IPv4
mismatched_mtu_with_conntrack ipv4: IP Fragmentation with conntrack
netlink_validation netlink: mismatched fields in flows
vport_upcall vport: upcall testing via vport"
@@ -151,7 +152,12 @@ ovs_add_if_upcalls () {
ovs_add_flow () {
info "Adding flow to DP: sbx:$1 br:$2 flow:$3 act:$4"
- ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-flow "$2" "$3" "$4" || return 1
+ ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-flow "$2" "$3" "$4"
+ if [ $? -ne 0 ]; then
+ echo "Flow [ $3 : $4 ] failed" >> ${ovs_dir}/debug.log
+ return 1
+ fi
+ return 0
}
ovs_test_dump_setup () {
@@ -422,6 +428,79 @@ test_ct_connect_v4 () {
return 0
}
+# requires pyftpd library
+test_ct_helper_v4 () {
+ python3 -m pyftpdlib -h >/dev/null 2>&1 || return $ksft_skip
+
+ sbx_add "test_ct_helper_v4" || return $?
+
+ info "create namespaces"
+ for ns in client server; do
+ ip netns add $ns || return 1
+ [ $TRACING -eq 1 ] && ovs_spawn_daemon "test_ct_helper_v4" "$ns" \
+ tcpdump -i any -s 65535
+ on_exit "ip netns del $ns"
+ done
+
+ ovs_add_dp "test_ct_helper_v4" cth || return 1
+
+ # Setup client namespace
+ ip link add c0 type veth peer name c1 || return 1
+ on_exit "ip link del c0 >/dev/null 2>&1"
+ ip link set c0 up
+ ip link set c1 netns client || return 1
+ ip netns exec client ip addr add 172.31.110.10/24 dev c1
+ ip netns exec client ip link set c1 up
+ ovs_add_if_upcalls "test_ct_helper_v4" cth c0 || return 1
+
+ # Setup server namespace
+ ip link add s0 type veth peer name s1 || return 1
+ on_exit "ip link del s0 >/dev/null 2>&1"
+ ip link set s0 up
+ ip link set s1 netns server || return 1
+ ip netns exec server ip addr add 172.31.110.20/24 dev s1
+ ip netns exec server ip link set s1 up
+ ovs_add_if_upcalls "test_ct_helper_v4" cth s0 || return 1
+
+ # Add forwarding for ARP and ip packets - completely wildcarded
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'ct_state(-trk),in_port(2),eth(),eth_type(0x0800),ip()' \
+ 'recirc(0x1)' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'ct_state(-trk),in_port(1),eth(),eth_type(0x0800),ip(proto=6),tcp(),tcp_flags(0x1)' 'ct(commit,helper=ftp),recirc(0x1)' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'ct_state(-trk),eth(),eth_type(0x0800),ip(proto=6),tcp(),tcp_flags(0x2)' 'ct(commit,helper=ftp),recirc(0x1)' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'ct_state(-trk),eth(),eth_type(0x0800),ip(proto=6),tcp(),tcp_flags(0x4)' 'ct(commit,helper=ftp),recirc(0x1)' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'ct_state(-trk),eth(),eth_type(0x0800),ip(proto=6),tcp(),tcp_flags(0x10)' 'ct(commit,helper=ftp),recirc(0x1)' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'recirc_id(0x1),ct_state(+trk+new),in_port(1),eth(),eth_type(0x0800),ip(src=172.31.110.10)' '2' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'recirc_id(0x1),ct_state(+trk+est),in_port(1),eth(),eth_type(0x0800),ip(src=172.31.110.10)' '2' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'recirc_id(0x1),ct_state(+trk+est),in_port(2),eth(),eth_type(0x0800),ip(dst=172.31.110.10)' '1' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'recirc_id(0x1),ct_state(+trk+est),in_port(1),eth(),eth_type(0x0800),ip(src=172.31.110.10)' '2' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'recirc_id(0x1),ct_state(+trk+rel),in_port(2),eth(),eth_type(0x0800),ip(src=172.31.110.20)' 'ct(commit),1' || return 1
+ ovs_add_flow "test_ct_helper_v4" cth \
+ 'recirc_id(0x1),ct_state(+trk+inv),eth(),eth_type(0x0800),ip()' 'drop' || return 1
+
+ # spawn an FTP server
+ ovs_spawn_daemon "test_ct_helper_v4" "server" \
+ python3 -m pyftpdlib -i 172.31.110.20 -d ${ovs_dir}
+
+ # launch client
+ ip netns exec client curl -P - "ftp://172.31.110.20:2121/" --user "anonymous:foo@bar.com" > /dev/null 2>${ovs_dir}/curl.err || return 1
+
+ return 0
+}
+
test_vport_upcall () {
sbx_add "test_vport_upcall" || return $?
diff --git a/ovs-dpctl.py b/ovs-dpctl.py
index c1cb1bf..fe8d147 100644
--- a/ovs-dpctl.py
+++ b/ovs-dpctl.py
@@ -583,6 +583,8 @@ def nla_put_key_mask(msg, key_str, mask=True, forceUfid=True):
key_str = key_block(key_str, ",", True)
key_str, tha = key_extract_field(key_str, "tha=", "([0-9a-fA-F:]+)",
None, False)
+ key_str = key_block(key_str, ")", True)
+ key_str = key_block(key_str, ",", True)
arpblock = convert_ipv4(sip)
arpmask = convert_ipv4("255.255.255.255" if sip is not None else sip)
@@ -620,13 +622,26 @@ def nla_put_key_mask(msg, key_str, mask=True, forceUfid=True):
tcp_mask = struct.pack("!H", int(0xffff) if sport is not None else 0)
tcp_mask += struct.pack("!H", int(0xffff) if dport is not None else 0)
- nla_put_u16(key_msg, OVS_KEY_ATTR_TCP, tcp_block)
- nla_put_u16(mask_msg, OVS_KEY_ATTR_TCP, tcp_mask)
+ nla_put(key_msg, OVS_KEY_ATTR_TCP, len(tcp_block), tcp_block)
+ nla_put(mask_msg, OVS_KEY_ATTR_TCP, len(tcp_mask), tcp_mask)
if key_block(key_str, "tcp_flags(", False):
- key_str = key_str_scan_single(key_msg, key_str, "tcp_flags(", "([+-]?\d+)",
- int, nla_put_u16, OVS_KEY_ATTR_TCP_FLAGS)
- nla_put_u16(mask_msg, OVS_KEY_ATTR_TCP_FLAGS, 0xffff)
+ key_str = key_block(key_str, "tcp_flags(", True)
+
+ mask_bits=None
+ key_str, flag_bits = key_extract_field(key_str, None,
+ "(([0-9a-fA-Fx]+))",
+ lambda x: int(x, 0),
+ False, 0)
+ if key_block(key_str, "/", False):
+ key_str = key_block(key_str, "/", True)
+ key_str, mask_bits = key_extract_field(key_str, None,
+ "(([0-9a-fA-Fx]+))",
+ lambda x: int(x, 0),
+ False, 0)
+ nla_put_u16(key_msg, OVS_KEY_ATTR_TCP_FLAGS, flag_bits)
+ if mask_bits is not None:
+ nla_put_u16(mask_msg, OVS_KEY_ATTR_TCP_FLAGS, mask_bits)
nla_put_nested(msg, OVS_FLOW_ATTR_KEY, key_msg)
@@ -854,7 +869,7 @@ def nla_put_actions(msg, action_str):
if helper is not None:
nla_put_string(ct_actions, OVS_CT_ATTR_HELPER,
- helper)
+ helper.encode("utf-8"))
if timeout is not None:
nla_put_string(ct_actions, OVS_CT_ATTR_TIMEOUT,