doc: whitespace changes in licenses
[dpdk.git] / app / test-pmd / csumonly.c
index b5bc5eb..abc7a9a 100644 (file)
@@ -1,35 +1,34 @@
 /*-
  *   BSD LICENSE
  * 
- *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
  *   All rights reserved.
  * 
- *   Redistribution and use in source and binary forms, with or without 
- *   modification, are permitted provided that the following conditions 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
  *   are met:
  * 
- *     * Redistributions of source code must retain the above copyright 
+ *     * Redistributions of source code must retain the above copyright
  *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright 
- *       notice, this list of conditions and the following disclaimer in 
- *       the documentation and/or other materials provided with the 
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
  *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its 
- *       contributors may be used to endorse or promote products derived 
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
  * 
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
  */
 
 #include <stdarg.h>
 #define IP_HDRLEN  0x05 /* default IP header length == five 32-bits words. */
 #define IP_VHL_DEF (IP_VERSION | IP_HDRLEN)
 
-/* Pseudo Header for IPv4/UDP/TCP checksum */
-struct psd_header {
-       uint32_t src_addr; /* IP address of source host. */
-       uint32_t dst_addr; /* IP address of destination host(s). */
-       uint8_t  zero;     /* zero. */
-       uint8_t  proto;    /* L4 protocol type. */
-       uint16_t len;      /* L4 length. */
-} __attribute__((__packed__));
-
-
-/* Pseudo Header for IPv6/UDP/TCP checksum */
-struct ipv6_psd_header {
-       uint8_t src_addr[16]; /* IP address of source host. */
-       uint8_t dst_addr[16]; /* IP address of destination host(s). */
-       uint32_t len;         /* L4 length. */
-       uint8_t  zero[3];     /* zero. */
-       uint8_t  proto;       /* L4 protocol. */
-} __attribute__((__packed__));
-
-
 static inline uint16_t
 get_16b_sum(uint16_t *ptr16, uint32_t nr)
 {
@@ -132,33 +111,51 @@ get_ipv4_cksum(struct ipv4_hdr *ipv4_hdr)
 }
 
 
-static inline
-uint16_t get_ipv4_psd_sum (struct ipv4_hdr * ip_hdr)
+static inline uint16_t
+get_ipv4_psd_sum (struct ipv4_hdr * ip_hdr)
 {
-       struct psd_header psd_hdr;
+       /* Pseudo Header for IPv4/UDP/TCP checksum */
+       union ipv4_psd_header {
+               struct {
+                       uint32_t src_addr; /* IP address of source host. */
+                       uint32_t dst_addr; /* IP address of destination host(s). */
+                       uint8_t  zero;     /* zero. */
+                       uint8_t  proto;    /* L4 protocol type. */
+                       uint16_t len;      /* L4 length. */
+               } __attribute__((__packed__));
+               uint16_t u16_arr[0];
+       } psd_hdr;
+
        psd_hdr.src_addr = ip_hdr->src_addr;
        psd_hdr.dst_addr = ip_hdr->dst_addr;
        psd_hdr.zero     = 0;
        psd_hdr.proto    = ip_hdr->next_proto_id;
        psd_hdr.len      = rte_cpu_to_be_16((uint16_t)(rte_be_to_cpu_16(ip_hdr->total_length)
                                - sizeof(struct ipv4_hdr)));
-       return get_16b_sum((uint16_t*)&psd_hdr, sizeof(struct psd_header));
+       return get_16b_sum(psd_hdr.u16_arr, sizeof(psd_hdr));
 }
 
-static inline
-uint16_t get_ipv6_psd_sum (struct ipv6_hdr * ip_hdr)
+static inline uint16_t
+get_ipv6_psd_sum (struct ipv6_hdr * ip_hdr)
 {
-       struct ipv6_psd_header psd_hdr;
-       rte_memcpy(psd_hdr.src_addr, ip_hdr->src_addr, sizeof(ip_hdr->src_addr)
-                       + sizeof(ip_hdr->dst_addr));
-
-       psd_hdr.zero[0]   = 0;
-       psd_hdr.zero[1]   = 0;
-       psd_hdr.zero[2]   = 0;
-       psd_hdr.proto     = ip_hdr->proto;
+       /* Pseudo Header for IPv6/UDP/TCP checksum */
+       union ipv6_psd_header {
+               struct {
+                       uint8_t src_addr[16]; /* IP address of source host. */
+                       uint8_t dst_addr[16]; /* IP address of destination host(s). */
+                       uint32_t len;         /* L4 length. */
+                       uint32_t proto;       /* L4 protocol - top 3 bytes must be zero */
+               } __attribute__((__packed__));
+
+               uint16_t u16_arr[0]; /* allow use as 16-bit values with safe aliasing */
+       } psd_hdr;
+
+       rte_memcpy(&psd_hdr.src_addr, ip_hdr->src_addr,
+                       sizeof(ip_hdr->src_addr) + sizeof(ip_hdr->dst_addr));
        psd_hdr.len       = ip_hdr->payload_len;
+       psd_hdr.proto     = (ip_hdr->proto << 24);
 
-       return get_16b_sum((uint16_t*)&psd_hdr, sizeof(struct ipv6_psd_header));
+       return get_16b_sum(psd_hdr.u16_arr, sizeof(psd_hdr));
 }
 
 static inline uint16_t
@@ -224,6 +221,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
        uint16_t pkt_ol_flags;
        uint16_t tx_ol_flags;
        uint16_t l4_proto;
+       uint16_t eth_type;
        uint8_t  l2_len;
        uint8_t  l3_len;
 
@@ -266,15 +264,30 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
                ol_flags = (uint16_t) (pkt_ol_flags & (~PKT_TX_L4_MASK));
 
                eth_hdr = (struct ether_hdr *) mb->pkt.data;
-               if (rte_be_to_cpu_16(eth_hdr->ether_type) == ETHER_TYPE_VLAN) {
+               eth_type = rte_be_to_cpu_16(eth_hdr->ether_type);
+               if (eth_type == ETHER_TYPE_VLAN) {
                        /* Only allow single VLAN label here */
                        l2_len  += sizeof(struct vlan_hdr);
+                        eth_type = rte_be_to_cpu_16(*(uint16_t *)
+                               ((uintptr_t)&eth_hdr->ether_type +
+                               sizeof(struct vlan_hdr)));
                }
 
                /* Update the L3/L4 checksum error packet count  */
                rx_bad_ip_csum += (uint16_t) ((pkt_ol_flags & PKT_RX_IP_CKSUM_BAD) != 0);
                rx_bad_l4_csum += (uint16_t) ((pkt_ol_flags & PKT_RX_L4_CKSUM_BAD) != 0);
 
+               /*
+                * Try to figure out L3 packet type by SW.
+                */
+               if ((pkt_ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_IPV4_HDR_EXT |
+                               PKT_RX_IPV6_HDR | PKT_RX_IPV6_HDR_EXT)) == 0) {
+                       if (eth_type == ETHER_TYPE_IPv4)
+                               pkt_ol_flags |= PKT_RX_IPV4_HDR;
+                       else if (eth_type == ETHER_TYPE_IPv6)
+                               pkt_ol_flags |= PKT_RX_IPV6_HDR;
+               }
+
                /*
                 * Simplify the protocol parsing
                 * Assuming the incoming packets format as
@@ -354,8 +367,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
                        }
                        /* End of L4 Handling*/
                }
+               else if (pkt_ol_flags & PKT_RX_IPV6_HDR) {
 
-               else {
                        ipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,
                                        unsigned char *) + l2_len);
                        l3_len = sizeof(struct ipv6_hdr) ;
@@ -409,7 +422,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
                        } else {
                                printf("Test flow control for 1G PMD \n");
                        }
-                       /* End of L4 Handling*/
+                       /* End of L6 Handling*/
+               }
+               else {
+                       l3_len = 0;
+                       printf("Unhandled packet type: %#hx\n", eth_type);
                }
 
                /* Combine the packet header write. VLAN is not consider here */