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
---
lib/flow.c | 18
tests/system-traffic.at | 177 ++--
2 files changed, 134 insertions(+), 61 deletions(-)
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(>path_hdr, flow->nsh.path_hdr);
+
+if (flow->nsh.mdtype == NSH_M_TYPE1) {
+for (size_t i = 0; i < 4; i++) {
+put_16aligned_be32(>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 "0x: *f2ff * *0002 *f2ff *
*0001 *894f *0fc6" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0103 *0012 *34ff *1122 *3344
* * *" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: * * * *f200 *
*0002 *f200 *" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001
* *4006 *b013" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400
*0800 * *00c8" 2>&1 1>/dev/null])
-OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: * * *5002 *2000 *b85e
*" 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],
+