[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL V4 22/31] net: improve UDP/TCP checksum computation.
From: |
Jason Wang |
Subject: |
[Qemu-devel] [PULL V4 22/31] net: improve UDP/TCP checksum computation. |
Date: |
Thu, 2 Jun 2016 14:48:13 +0800 |
From: Jean-Christophe Dubois <address@hidden>
* based on Eth, UDP, TCP struct present in eth.h instead of hardcoded
indexes and sizes.
* based on various macros present in eth.h.
Signed-off-by: Jean-Christophe Dubois <address@hidden>
Signed-off-by: Jason Wang <address@hidden>
---
net/checksum.c | 94 +++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 67 insertions(+), 27 deletions(-)
diff --git a/net/checksum.c b/net/checksum.c
index 196aaa3..39ad73f 100644
--- a/net/checksum.c
+++ b/net/checksum.c
@@ -18,9 +18,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "net/checksum.h"
-
-#define PROTO_TCP 6
-#define PROTO_UDP 17
+#include "net/eth.h"
uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq)
{
@@ -57,40 +55,82 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t
proto,
void net_checksum_calculate(uint8_t *data, int length)
{
- int hlen, plen, proto, csum_offset;
- uint16_t csum;
+ int ip_len;
+ struct ip_header *ip;
+
+ /*
+ * Note: We cannot assume "data" is aligned, so the all code uses
+ * some macros that take care of possible unaligned access for
+ * struct members (just in case).
+ */
/* Ensure data has complete L2 & L3 headers. */
- if (length < 14 + 20) {
+ if (length < (sizeof(struct eth_header) + sizeof(struct ip_header))) {
return;
}
- if ((data[14] & 0xf0) != 0x40)
- return; /* not IPv4 */
- hlen = (data[14] & 0x0f) * 4;
- plen = (data[16] << 8 | data[17]) - hlen;
- proto = data[23];
-
- switch (proto) {
- case PROTO_TCP:
- csum_offset = 16;
- break;
- case PROTO_UDP:
- csum_offset = 6;
- break;
- default:
- return;
+ ip = (struct ip_header *)(data + sizeof(struct eth_header));
+
+ if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
+ return; /* not IPv4 */
}
- if (plen < csum_offset + 2 || 14 + hlen + plen > length) {
+ ip_len = lduw_be_p(&ip->ip_len);
+
+ /* Last, check that we have enough data for the all IP frame */
+ if (length < ip_len) {
return;
}
- data[14+hlen+csum_offset] = 0;
- data[14+hlen+csum_offset+1] = 0;
- csum = net_checksum_tcpudp(plen, proto, data+14+12, data+14+hlen);
- data[14+hlen+csum_offset] = csum >> 8;
- data[14+hlen+csum_offset+1] = csum & 0xff;
+ ip_len -= IP_HDR_GET_LEN(ip);
+
+ switch (ip->ip_p) {
+ case IP_PROTO_TCP:
+ {
+ uint16_t csum;
+ tcp_header *tcp = (tcp_header *)(ip + 1);
+
+ if (ip_len < sizeof(tcp_header)) {
+ return;
+ }
+
+ /* Set csum to 0 */
+ stw_he_p(&tcp->th_sum, 0);
+
+ csum = net_checksum_tcpudp(ip_len, ip->ip_p,
+ (uint8_t *)&ip->ip_src,
+ (uint8_t *)tcp);
+
+ /* Store computed csum */
+ stw_be_p(&tcp->th_sum, csum);
+
+ break;
+ }
+ case IP_PROTO_UDP:
+ {
+ uint16_t csum;
+ udp_header *udp = (udp_header *)(ip + 1);
+
+ if (ip_len < sizeof(udp_header)) {
+ return;
+ }
+
+ /* Set csum to 0 */
+ stw_he_p(&udp->uh_sum, 0);
+
+ csum = net_checksum_tcpudp(ip_len, ip->ip_p,
+ (uint8_t *)&ip->ip_src,
+ (uint8_t *)udp);
+
+ /* Store computed csum */
+ stw_be_p(&udp->uh_sum, csum);
+
+ break;
+ }
+ default:
+ /* Can't handle any other protocol */
+ break;
+ }
}
uint32_t
--
2.7.4
- [Qemu-devel] [PULL V4 09/31] pcie: Introduce function for DSN capability creation, (continued)
- [Qemu-devel] [PULL V4 09/31] pcie: Introduce function for DSN capability creation, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 11/31] net: Introduce Toeplitz hash calculator, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 12/31] net: Add macros for MAC address tracing, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 13/31] vmxnet3: Use common MAC address tracing macros, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 15/31] rtl8139: Move more TCP definitions to common header, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 14/31] net_pkt: Name vmxnet3 packet abstractions more generic, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 17/31] vmxnet3: Use pci_dma_* API instead of cpu_physical_memory_*, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 16/31] net_pkt: Extend packet abstraction as required by e1000e functionality, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 18/31] e1000_regs: Add definitions for Intel 82574-specific bits, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 19/31] e1000: Move out code that will be reused in e1000e, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 22/31] net: improve UDP/TCP checksum computation.,
Jason Wang <=
- [Qemu-devel] [PULL V4 21/31] e1000e: Introduce qtest for e1000e device, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 24/31] i.MX: Fix FEC code for MDIO operation selection, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 23/31] net: handle optional VLAN header in checksum computation., Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 26/31] i.MX: Fix FEC code for ECR register reset value., Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 25/31] i.MX: Fix FEC code for MDIO address selection, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 27/31] i.MX: reset TX/RX descriptors when FEC is disabled., Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 28/31] i.MX: Rename i.MX FEC defines to ENET_XXX, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 20/31] net: Introduce e1000e device emulation, Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 29/31] i.MX: move FEC device to a register array structure., Jason Wang, 2016/06/02
- [Qemu-devel] [PULL V4 31/31] Add ENET device to i.MX6 SOC., Jason Wang, 2016/06/02