[PATCH v7 net-next 03/13] selftests/net: gro: add self-test for TCP CWR flag
From: Chia-Yu Chang
Currently, GRO does not flush packets when the CWR bit is set.
A corresponding self-test is being added, in which the CWR flag
is set for two consecutive packets, but the first packet with the
CWR flag set will not be flushed immediately.
+===+==+===+===+
| Packet id | CWR flag |Payload| Flushing? |
+===+==+===+===+
| 0 | 0| PAYLOAD_LEN | 0 |
|...| 0| PAYLOAD_LEN | 1 |
+---+--+---+---+
| NUM_PACKETS/2 - 1 | 1| payload_len | 0 |
| NUM_PACKETS/2 | 1| payload_len | 1 |
+---+--+---+---+
|...| 0| PAYLOAD_LEN | 0 |
| NUM_PACKETS | 0| PAYLOAD_LEN | 1 |
+===+==+===+===+
Signed-off-by: Chia-Yu Chang
Acked-by: Paolo Abeni
---
v7:
- Update comments
---
tools/testing/selftests/drivers/net/gro.c | 81 ---
1 file changed, 58 insertions(+), 23 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/gro.c
b/tools/testing/selftests/drivers/net/gro.c
index e894037d2e3e..736da13f85a0 100644
--- a/tools/testing/selftests/drivers/net/gro.c
+++ b/tools/testing/selftests/drivers/net/gro.c
@@ -11,8 +11,8 @@
* 2.ack
* Pure ACK does not coalesce.
* 3.flags
- * Specific test cases: no packets with PSH, SYN, URG, RST set will
- * be coalesced.
+ * Specific test cases: no packets with PSH, SYN, URG, RST, CWR set
+ * will be coalesced.
* 4.tcp
* Packets with incorrect checksum, non-consecutive seqno and
* different TCP header options shouldn't coalesce. Nit: given that
@@ -333,32 +333,58 @@ static void create_packet(void *buf, int seq_offset, int
ack_offset,
fill_datalinklayer(buf);
}
-/* send one extra flag, not first and not last pkt */
-static void send_flags(int fd, struct sockaddr_ll *daddr, int psh, int syn,
- int rst, int urg)
+#ifndef TH_CWR
+#define TH_CWR 0x80
+#endif
+static void set_flags(struct tcphdr *tcph, int payload_len, int psh, int syn,
+ int rst, int urg, int cwr)
{
- static char flag_buf[MAX_HDR_LEN + PAYLOAD_LEN];
- static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
- int payload_len, pkt_size, flag, i;
- struct tcphdr *tcph;
-
- payload_len = PAYLOAD_LEN * psh;
- pkt_size = total_hdr_len + payload_len;
- flag = NUM_PACKETS / 2;
-
- create_packet(flag_buf, flag * payload_len, 0, payload_len, 0);
-
- tcph = (struct tcphdr *)(flag_buf + tcp_offset);
tcph->psh = psh;
tcph->syn = syn;
tcph->rst = rst;
tcph->urg = urg;
+ if (cwr)
+ tcph->th_flags |= TH_CWR;
+ else
+ tcph->th_flags &= ~TH_CWR;
tcph->check = 0;
tcph->check = tcp_checksum(tcph, payload_len);
+}
+
+/* send extra flags of the (NUM_PACKETS / 2) and (NUM_PACKETS / 2 - 1)
+ * pkts, not first and not last pkt
+ */
+static void send_flags(int fd, struct sockaddr_ll *daddr, int psh, int syn,
+ int rst, int urg, int cwr)
+{
+ static char flag_buf[2][MAX_HDR_LEN + PAYLOAD_LEN];
+ static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
+ int payload_len, pkt_size, i;
+ struct tcphdr *tcph;
+ int flag[2];
+
+ payload_len = PAYLOAD_LEN * (psh || cwr);
+ pkt_size = total_hdr_len + payload_len;
+ flag[0] = NUM_PACKETS / 2;
+ flag[1] = NUM_PACKETS / 2 - 1;
+
+ /* Create and configure packets with flags
+*/
+ for (i = 0; i < 2; i++) {
+ if (flag[i] > 0) {
+ create_packet(flag_buf[i], flag[i] * payload_len, 0,
+ payload_len, 0);
+ tcph = (struct tcphdr *)(flag_buf[i] + tcp_offset);
+ set_flags(tcph, payload_len, psh, syn, rst, urg, cwr);
+ }
+ }
for (i = 0; i < NUM_PACKETS + 1; i++) {
- if (i == flag) {
- write_packet(fd, flag_buf, pkt_size, daddr);
+ if (i == flag[0]) {
+ write_packet(fd, flag_buf[0], pkt_size, daddr);
+ continue;
+ } else if (i == flag[1] && cwr) {
+ write_packet(fd, flag_buf[1], pkt_size, daddr);
continue;
}
create_packet(buf, i * PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
@@ -1021,16 +1047,19 @@ static void gro_sender(void)
send_ack(txfd, &daddr);
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
} else if (strcmp(testname, "flags") == 0) {
- send_flags(txfd, &daddr, 1, 0, 0, 0);
+ send_flags(txfd, &daddr, 1, 0, 0, 0, 0);
[PATCH v7 net-next 03/13] selftests/net: gro: add self-test for TCP CWR flag
From: Chia-Yu Chang
Currently, GRO does not flush packets when the CWR bit is set.
A corresponding self-test is being added, in which the CWR flag
is set for two consecutive packets, but the first packet with the
CWR flag set will not be flushed immediately.
+===+==+===+===+
| Packet id | CWR flag |Payload| Flushing? |
+===+==+===+===+
| 0 | 0| PAYLOAD_LEN | 0 |
|...| 0| PAYLOAD_LEN | 1 |
+---+--+---+---+
| NUM_PACKETS/2 - 1 | 1| payload_len | 0 |
| NUM_PACKETS/2 | 1| payload_len | 1 |
+---+--+---+---+
|...| 0| PAYLOAD_LEN | 0 |
| NUM_PACKETS | 0| PAYLOAD_LEN | 1 |
+===+==+===+===+
Signed-off-by: Chia-Yu Chang
Acked-by: Paolo Abeni
---
v7:
- Update comments
---
tools/testing/selftests/drivers/net/gro.c | 81 ---
1 file changed, 58 insertions(+), 23 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/gro.c
b/tools/testing/selftests/drivers/net/gro.c
index 995b492f5bcb..00fef326efdf 100644
--- a/tools/testing/selftests/drivers/net/gro.c
+++ b/tools/testing/selftests/drivers/net/gro.c
@@ -11,8 +11,8 @@
* 2.ack
* Pure ACK does not coalesce.
* 3.flags
- * Specific test cases: no packets with PSH, SYN, URG, RST set will
- * be coalesced.
+ * Specific test cases: no packets with PSH, SYN, URG, RST, CWR set
+ * will be coalesced.
* 4.tcp
* Packets with incorrect checksum, non-consecutive seqno and
* different TCP header options shouldn't coalesce. Nit: given that
@@ -333,32 +333,58 @@ static void create_packet(void *buf, int seq_offset, int
ack_offset,
fill_datalinklayer(buf);
}
-/* send one extra flag, not first and not last pkt */
-static void send_flags(int fd, struct sockaddr_ll *daddr, int psh, int syn,
- int rst, int urg)
+#ifndef TH_CWR
+#define TH_CWR 0x80
+#endif
+static void set_flags(struct tcphdr *tcph, int payload_len, int psh, int syn,
+ int rst, int urg, int cwr)
{
- static char flag_buf[MAX_HDR_LEN + PAYLOAD_LEN];
- static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
- int payload_len, pkt_size, flag, i;
- struct tcphdr *tcph;
-
- payload_len = PAYLOAD_LEN * psh;
- pkt_size = total_hdr_len + payload_len;
- flag = NUM_PACKETS / 2;
-
- create_packet(flag_buf, flag * payload_len, 0, payload_len, 0);
-
- tcph = (struct tcphdr *)(flag_buf + tcp_offset);
tcph->psh = psh;
tcph->syn = syn;
tcph->rst = rst;
tcph->urg = urg;
+ if (cwr)
+ tcph->th_flags |= TH_CWR;
+ else
+ tcph->th_flags &= ~TH_CWR;
tcph->check = 0;
tcph->check = tcp_checksum(tcph, payload_len);
+}
+
+/* send extra flags of the (NUM_PACKETS / 2) and (NUM_PACKETS / 2 - 1)
+ * pkts, not first and not last pkt
+ */
+static void send_flags(int fd, struct sockaddr_ll *daddr, int psh, int syn,
+ int rst, int urg, int cwr)
+{
+ static char flag_buf[2][MAX_HDR_LEN + PAYLOAD_LEN];
+ static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
+ int payload_len, pkt_size, i;
+ struct tcphdr *tcph;
+ int flag[2];
+
+ payload_len = PAYLOAD_LEN * (psh || cwr);
+ pkt_size = total_hdr_len + payload_len;
+ flag[0] = NUM_PACKETS / 2;
+ flag[1] = NUM_PACKETS / 2 - 1;
+
+ /* Create and configure packets with flags
+*/
+ for (i = 0; i < 2; i++) {
+ if (flag[i] > 0) {
+ create_packet(flag_buf[i], flag[i] * payload_len, 0,
+ payload_len, 0);
+ tcph = (struct tcphdr *)(flag_buf[i] + tcp_offset);
+ set_flags(tcph, payload_len, psh, syn, rst, urg, cwr);
+ }
+ }
for (i = 0; i < NUM_PACKETS + 1; i++) {
- if (i == flag) {
- write_packet(fd, flag_buf, pkt_size, daddr);
+ if (i == flag[0]) {
+ write_packet(fd, flag_buf[0], pkt_size, daddr);
+ continue;
+ } else if (i == flag[1] && cwr) {
+ write_packet(fd, flag_buf[1], pkt_size, daddr);
continue;
}
create_packet(buf, i * PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
@@ -1021,16 +1047,19 @@ static void gro_sender(void)
send_ack(txfd, &daddr);
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
} else if (strcmp(testname, "flags") == 0) {
- send_flags(txfd, &daddr, 1, 0, 0, 0);
+ send_flags(txfd, &daddr, 1, 0, 0, 0, 0);
