diff mbox series

[ovs-dev,3/3] nsh: Add support to compose-packet and use it in system tests.

Message ID 20240531214635.2084937-4-i.maximets@ovn.org
State Accepted
Commit ac4df0c8dbb78e516f3481612d130deb34a8c216
Delegated to: Ilya Maximets
Headers show
Series tests: Use compose-packet for sendpkt calls. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Ilya Maximets May 31, 2024, 9:45 p.m. UTC
OVS can parse NSH, but can't compose.  Fix that and get rid of plain
hex NSH packets in system tests as they are hard to read or modify.

Tcpdump calls modified to write actual pcaps instead of text output,
so ovs-pcap can be used while checking the results.

While at it, replacing sleeps with more robust waiting for tcpdump
to start listening.

M4 macros are better than shell variables, because we can see the
substitution result in the test log.  So, using m4_define and m4_join
extensively.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 lib/flow.c              |  18 ++++
 tests/system-traffic.at | 177 ++++++++++++++++++++++++++--------------
 2 files changed, 134 insertions(+), 61 deletions(-)

Comments

Simon Horman June 3, 2024, 3:09 p.m. UTC | #1
On Fri, May 31, 2024 at 11:45:12PM +0200, Ilya Maximets wrote:
> OVS can parse NSH, but can't compose.  Fix that and get rid of plain
> hex NSH packets in system tests as they are hard to read or modify.
> 
> Tcpdump calls modified to write actual pcaps instead of text output,
> so ovs-pcap can be used while checking the results.
> 
> While at it, replacing sleeps with more robust waiting for tcpdump
> to start listening.

I might have separated a) adding NSH compose support
b) more robust tcpdump waiting, and c) using text rather than hex,
into 3 patches. But I don't feel strongly about it.

> M4 macros are better than shell variables, because we can see the
> substitution result in the test log.  So, using m4_define and m4_join
> extensively.
> 
> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>

Acked-by: Simon Horman <horms@ovn.org>
Eelco Chaudron June 5, 2024, 1:45 p.m. UTC | #2
On 31 May 2024, at 23:45, Ilya Maximets wrote:

> OVS can parse NSH, but can't compose.  Fix that and get rid of plain
> hex NSH packets in system tests as they are hard to read or modify.
>
> Tcpdump calls modified to write actual pcaps instead of text output,
> so ovs-pcap can be used while checking the results.
>
> While at it, replacing sleeps with more robust waiting for tcpdump
> to start listening.
>
> M4 macros are better than shell variables, because we can see the
> substitution result in the test log.  So, using m4_define and m4_join
> extensively.
>
> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>

Thanks for cleaning this up! This patch looks good to me.

Acked-by: Eelco Chaudron <echaudro@redhat.com>
Ilya Maximets June 5, 2024, 10:29 p.m. UTC | #3
On 6/3/24 17:09, Simon Horman wrote:
> On Fri, May 31, 2024 at 11:45:12PM +0200, Ilya Maximets wrote:
>> OVS can parse NSH, but can't compose.  Fix that and get rid of plain
>> hex NSH packets in system tests as they are hard to read or modify.
>>
>> Tcpdump calls modified to write actual pcaps instead of text output,
>> so ovs-pcap can be used while checking the results.
>>
>> While at it, replacing sleeps with more robust waiting for tcpdump
>> to start listening.
> 
> I might have separated a) adding NSH compose support

The tests in the patch provide some test coverage for this as well,
so I didn't want to split for that reason.

> b) more robust tcpdump waiting,

We still need to change '>' to '-w' in very same lines, so I though
it's better to not touch the same code twice and just combine the
change, since it's fairly minor.

> and c) using text rather than hex,
> into 3 patches. But I don't feel strongly about it.

For now, I kept the patches as they are for reasons stated above.
Mostly to avoid touching the same code multiple times.

> 
>> M4 macros are better than shell variables, because we can see the
>> substitution result in the test log.  So, using m4_define and m4_join
>> extensively.
>>
>> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
> 
> Acked-by: Simon Horman <horms@ovn.org>
> 

Thanks, Simon and Eelco!  I applied the set and backported to all
branches, so we can backport tests for future fixes without trouble
of re-working them for each branch.

Best regards, Ilya Maximets.
diff mbox series

Patch

diff --git a/lib/flow.c b/lib/flow.c
index 8e3402388..dc5fb328d 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -3420,6 +3420,24 @@  flow_compose(struct dp_packet *p, const struct flow *flow,
             arp->ar_sha = flow->arp_sha;
             arp->ar_tha = flow->arp_tha;
         }
+    } else if (flow->dl_type == htons(ETH_TYPE_NSH)) {
+        struct nsh_hdr *nsh;
+
+        nsh = dp_packet_put_zeros(p, sizeof *nsh);
+        dp_packet_set_l3(p, nsh);
+
+        nsh_set_flags_ttl_len(nsh, flow->nsh.flags, flow->nsh.ttl,
+                              flow->nsh.mdtype == NSH_M_TYPE1
+                              ? NSH_M_TYPE1_LEN : NSH_BASE_HDR_LEN);
+        nsh->next_proto = flow->nsh.np;
+        nsh->md_type = flow->nsh.mdtype;
+        put_16aligned_be32(&nsh->path_hdr, flow->nsh.path_hdr);
+
+        if (flow->nsh.mdtype == NSH_M_TYPE1) {
+            for (size_t i = 0; i < 4; i++) {
+                put_16aligned_be32(&nsh->md1.context[i], flow->nsh.context[i]);
+            }
+        }
     }
 
     if (eth_type_mpls(flow->dl_type)) {
diff --git a/tests/system-traffic.at b/tests/system-traffic.at
index c4cebb0a3..3f1a15445 100644
--- a/tests/system-traffic.at
+++ b/tests/system-traffic.at
@@ -8920,21 +8920,29 @@  dnl The flow will encap a nsh header to the TCP syn packet
 dnl eth/ip/tcp --> OVS --> eth/nsh/eth/ip/tcp
 AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,ip,actions=encap(nsh(md_type=1)),set_field:0x1234->nsh_spi,set_field:0x11223344->nsh_c1,encap(ethernet),set_field:f2:ff:00:00:00:02->dl_dst,set_field:f2:ff:00:00:00:01->dl_src,ovs-p1"])
 
-NETNS_DAEMONIZE([at_ns1], [tcpdump -l -n -xx -U -i p1 > p1.pcap], [tcpdump.pid])
-sleep 1
+NETNS_DAEMONIZE([at_ns1],
+  [tcpdump -l -n -xx -U -i p1 -w p1.pcap 2>tcpdump_err], [tcpdump.pid])
+OVS_WAIT_UNTIL([grep "listening" tcpdump_err])
 
-dnl The hex dump is a TCP syn packet. pkt=eth/ip/tcp
-dnl The packet is sent from p0(at_ns0) interface directed to
-dnl p1(at_ns1) interface
-NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
+m4_define([TCP_SYN_PKT], [m4_join([,],
+  [eth_src=f2:00:00:00:00:01,eth_dst=f2:00:00:00:00:02,eth_type=0x0800],
+  [nw_src=192.168.0.10,nw_dst=10.0.0.10],
+  [nw_proto=6,nw_ttl=64,nw_frag=no],
+  [tcp_src=1024,tcp_dst=2048,tcp_flags=syn])])
 
-dnl Check the expected nsh encapsulated packet on the egress interface
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *0fc6" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0103 *0012 *34ff *1122 *3344 *0000 *0000 *0000" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *0000 *0000 *0000 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null])
+dnl Send the TCP SYN packet from p0(at_ns0) interface directed to
+dnl p1(at_ns1) interface.
+NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 \
+    $(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT')], [0], [ignore])
+
+m4_define([NSH_HEADER], [m4_join([,],
+  [eth_src=f2:ff:00:00:00:01,eth_dst=f2:ff:00:00:00:02,eth_type=0x894f],
+  [nsh_ttl=63,nsh_np=3,nsh_spi=0x1234,nsh_si=255],
+  [nsh_mdtype=1,nsh_c1=0x11223344])])
+
+OVS_WAIT_UNTIL([ovs-pcap p1.pcap | grep -q "m4_join([], [^],
+    $(ovs-ofctl compose-packet --bare 'NSH_HEADER'),
+    $(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT'), [\$])"])
 
 OVS_TRAFFIC_VSWITCHD_STOP
 AT_CLEANUP
@@ -8952,19 +8960,31 @@  dnl The flow will decap a nsh header which in turn carries a TCP syn packet
 dnl eth/nsh/eth/ip/tcp --> OVS --> eth/ip/tcp
 AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,dl_type=0x894f, actions=decap(),decap(), ovs-p1"])
 
-NETNS_DAEMONIZE([at_ns1], [tcpdump -l -n -xx -U -i p1 > p1.pcap], [tcpdump.pid])
-sleep 1
+NETNS_DAEMONIZE([at_ns1],
+  [tcpdump -l -n -xx -U -i p1 -w p1.pcap 2>tcpdump_err], [tcpdump.pid])
+OVS_WAIT_UNTIL([grep "listening" tcpdump_err])
 
-dnl The hex dump is NSH packet with TCP syn payload. pkt=eth/nsh/eth/ip/tcp
-dnl The packet is sent from p0(at_ns0) interface directed to
-dnl p1(at_ns1) interface
-NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 00 64 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
+m4_define([TCP_SYN_PKT], [m4_join([,],
+  [eth_src=f2:00:00:00:00:01,eth_dst=f2:00:00:00:00:02,eth_type=0x0800],
+  [nw_src=192.168.0.10,nw_dst=10.0.0.10],
+  [nw_proto=6,nw_ttl=64,nw_frag=no],
+  [tcp_src=1024,tcp_dst=2048,tcp_flags=syn])])
+
+m4_define([NSH_HEADER], [m4_join([,],
+  [eth_src=f2:ff:00:00:00:01,eth_dst=f2:ff:00:00:00:02,eth_type=0x894f],
+  [nsh_ttl=63,nsh_np=3,nsh_spi=0x1234,nsh_si=255],
+  [nsh_mdtype=1,nsh_c1=0x11223344])])
+
+dnl Send the NSH packet with TCP SYN payload from p0(at_ns0) interface directed
+dnl to p1(at_ns1) interface.
+NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 \
+    "$(ovs-ofctl compose-packet --bare 'NSH_HEADER')" \
+    "$(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT')"],
+  [0], [ignore])
 
 dnl Check the expected de-capsulated TCP packet on the egress interface
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *f200 *0000 *0002 *f200 *0000 *0001 *0800 *4500" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0028 *0001 *0000 *4006 *b013 *c0a8 *000a *0a00" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *000a *0400 *0800 *0000 *00c8 *0000 *0000 *5002" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *2000 *b85e *0000" 2>&1 1>/dev/null])
+OVS_WAIT_UNTIL([ovs-pcap p1.pcap | grep -q \
+    "^$(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT')\$"])
 
 OVS_TRAFFIC_VSWITCHD_STOP
 AT_CLEANUP
@@ -8984,22 +9004,38 @@  dnl The flow will add another NSH header with nsh_spi=0x101, nsh_si=4,
 dnl nsh_ttl=7 and change the md1 context
 AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x03,actions=decap(),decap(),encap(nsh(md_type=1)),set_field:0x07->nsh_ttl,set_field:0x0101->nsh_spi,set_field:0x04->nsh_si,set_field:0x100f0e0d->nsh_c1,set_field:0x0c0b0a09->nsh_c2,set_field:0x08070605->nsh_c3,set_field:0x04030201->nsh_c4,encap(ethernet),set_field:f2:ff:00:00:00:02->dl_dst,set_field:f2:ff:00:00:00:01->dl_src,ovs-p1"])
 
-NETNS_DAEMONIZE([at_ns1], [tcpdump -l -n -xx -U -i p1 > p1.pcap], [tcpdump.pid])
-sleep 1
+NETNS_DAEMONIZE([at_ns1],
+  [tcpdump -l -n -xx -U -i p1 -w p1.pcap 2>tcpdump_err], [tcpdump.pid])
+OVS_WAIT_UNTIL([grep "listening" tcpdump_err])
 
-dnl The hex dump is NSH packet with TCP syn payload. pkt=eth/nsh/eth/ip/tcp
-dnl The nsh_ttl is 8, nsh_spi is 0x100 and nsh_si is 3
-dnl The packet is sent from p0(at_ns0) interface directed to
-dnl p1(at_ns1) interface
-NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
+m4_define([TCP_SYN_PKT], [m4_join([,],
+  [eth_src=f2:00:00:00:00:01,eth_dst=f2:00:00:00:00:02,eth_type=0x0800],
+  [nw_src=192.168.0.10,nw_dst=10.0.0.10],
+  [nw_proto=6,nw_ttl=64,nw_frag=no],
+  [tcp_src=1024,tcp_dst=2048,tcp_flags=syn])])
+
+m4_define([NSH_HEADER_1], [m4_join([,],
+  [eth_src=f2:ff:00:00:00:01,eth_dst=f2:ff:00:00:00:02,eth_type=0x894f],
+  [nsh_ttl=8,nsh_np=3,nsh_spi=0x100,nsh_si=3,nsh_mdtype=1],
+  [nsh_c1=0x01020304,nsh_c2=0x05060708,nsh_c3=0x090a0b0c,nsh_c4=0x0d0e0f10])])
 
-dnl Check the expected NSH packet with new fields in the header
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *f2ff *0000 *0002 *f2ff *0000* 0001 *894f *01c6" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0103 *0001 *0104 *100f *0e0d *0c0b *0a09 *0807" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *0605 *0403 *0201 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null])
+dnl Send the NSH packet with TCP SYN payload from p0(at_ns0) interface directed
+dnl to p1(at_ns1) interface.
+dnl The nsh_ttl is 8, nsh_spi is 0x100 and nsh_si is 3.
+NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 \
+    "$(ovs-ofctl compose-packet --bare 'NSH_HEADER_1')" \
+    "$(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT')"],
+  [0], [ignore])
+
+m4_define([NSH_HEADER_2], [m4_join([,],
+  [eth_src=f2:ff:00:00:00:01,eth_dst=f2:ff:00:00:00:02,eth_type=0x894f],
+  [nsh_ttl=7,nsh_np=3,nsh_spi=0x101,nsh_si=4,nsh_mdtype=1],
+  [nsh_c1=0x100f0e0d,nsh_c2=0x0c0b0a09,nsh_c3=0x08070605,nsh_c4=0x04030201])])
+
+dnl Check the expected NSH packet with new fields in the header.
+OVS_WAIT_UNTIL([ovs-pcap p1.pcap | grep -q "m4_join([], [^],
+    $(ovs-ofctl compose-packet --bare 'NSH_HEADER_2'),
+    $(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT'), [\$])"])
 
 OVS_TRAFFIC_VSWITCHD_STOP
 AT_CLEANUP
@@ -9020,31 +9056,50 @@  dnl packet to to at_ns2.
 AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x02,actions=ovs-p1"])
 AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x01,actions=ovs-p2"])
 
-NETNS_DAEMONIZE([at_ns1], [tcpdump -l -n -xx -U -i p1 > p1.pcap], [tcpdump.pid])
-NETNS_DAEMONIZE([at_ns2], [tcpdump -l -n -xx -U -i p2 > p2.pcap], [tcpdump2.pid])
-sleep 1
+NETNS_DAEMONIZE([at_ns1],
+  [tcpdump -l -n -xx -U -i p1 -w p1.pcap 2>tcpdump_err], [tcpdump.pid])
+OVS_WAIT_UNTIL([grep "listening" tcpdump_err])
+NETNS_DAEMONIZE([at_ns2],
+  [tcpdump -l -n -xx -U -i p2 -w p2.pcap 2>tcpdump2_err], [tcpdump2.pid])
+OVS_WAIT_UNTIL([grep "listening" tcpdump2_err])
+
+m4_define([TCP_SYN_PKT], [m4_join([,],
+  [eth_src=f2:00:00:00:00:01,eth_dst=f2:00:00:00:00:02,eth_type=0x0800],
+  [nw_src=192.168.0.10,nw_dst=10.0.0.10],
+  [nw_proto=6,nw_ttl=64,nw_frag=no],
+  [tcp_src=1024,tcp_dst=2048,tcp_flags=syn])])
+
+dnl First send packet from at_ns0 --> OVS with SPI=0x100 and SI=2.
+m4_define([NSH_HEADER_1], [m4_join([,],
+  [eth_src=f2:ff:00:00:00:01,eth_dst=f2:ff:00:00:00:02,eth_type=0x894f],
+  [nsh_ttl=8,nsh_np=3,nsh_spi=0x100,nsh_si=2,nsh_mdtype=1],
+  [nsh_c1=0x01020304,nsh_c2=0x05060708,nsh_c3=0x090a0b0c,nsh_c4=0x0d0e0f10])])
+
+NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 \
+    "$(ovs-ofctl compose-packet --bare 'NSH_HEADER_1')" \
+    "$(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT')"],
+  [0], [ignore])
+
+dnl Check for the above packet on p1 interface.
+OVS_WAIT_UNTIL([ovs-pcap p1.pcap | grep -q "m4_join([], [^],
+    $(ovs-ofctl compose-packet --bare 'NSH_HEADER_1'),
+    $(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT'), [\$])"])
+
+dnl Send the second packet from at_ns1 --> OVS with SPI=0x100 and SI=1.
+m4_define([NSH_HEADER_2], [m4_join([,],
+  [eth_src=f2:ff:00:00:00:01,eth_dst=f2:ff:00:00:00:02,eth_type=0x894f],
+  [nsh_ttl=8,nsh_np=3,nsh_spi=0x100,nsh_si=1,nsh_mdtype=1],
+  [nsh_c1=0x01020304,nsh_c2=0x05060708,nsh_c3=0x090a0b0c,nsh_c4=0x0d0e0f10])])
+
+NS_CHECK_EXEC([at_ns1], [$PYTHON3 $srcdir/sendpkt.py p1 \
+    "$(ovs-ofctl compose-packet --bare 'NSH_HEADER_2')" \
+    "$(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT')"],
+  [0], [ignore])
 
-dnl First send packet from at_ns0 --> OVS with SPI=0x100 and SI=2
-NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 02 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
-
-dnl Check for the above packet on p1 interface
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *0206" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0103 *0001 *0002 *0102 *0304 *0506 *0708 *090a" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *0b0c *0d0e *0f10 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null])
-
-dnl Send the second packet from at_ns1 --> OVS with SPI=0x100 and SI=1
-NS_CHECK_EXEC([at_ns1], [$PYTHON3 $srcdir/sendpkt.py p1 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 01 c6 01 03 00 01 00 01 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null])
-
-dnl Check for the above packet on p2 interface
-OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *01c6" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0010: *0103 *0001 *0001 *0102 *0304 *0506 *0708 *090a" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0020: *0b0c *0d0e *0f10 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null])
+dnl Check for the above packet on p2 interface.
+OVS_WAIT_UNTIL([ovs-pcap p2.pcap | grep -q "m4_join([], [^],
+    $(ovs-ofctl compose-packet --bare 'NSH_HEADER_2'),
+    $(ovs-ofctl compose-packet --bare 'TCP_SYN_PKT'), [\$])"])
 
 OVS_TRAFFIC_VSWITCHD_STOP
 AT_CLEANUP