Message ID | 20180712215545.21410-4-blp@ovn.org |
---|---|
State | Accepted |
Headers | show |
Series | [ovs-dev,1/5] netdev-dpdk: Fix incorrect byte order conversion in log message. | expand |
On 7/12/2018 10:55 PM, Ben Pfaff wrote: > This allows netdev-dpdk.c to compile cleanly with sparse. > Thanks for this Ben, much appreciated, I hadn't seen that sparse was broken for OVS with DPDK. I was under the impression that travis builds with sparse enabled so typically I look there for sparse errors when testing patches. However testing on my own system with sparse now I can see that it's failing before this patch is applied. below looks ok to me, I'll add this to the next pull request. Thanks Ian > Signed-off-by: Ben Pfaff <blp@ovn.org> > --- > Makefile.am | 2 +- > build-aux/initial-tab-whitelist | 1 + > include/sparse/automake.mk | 9 + > include/sparse/rte_byteorder.h | 281 ++++++++ > include/sparse/rte_esp.h | 65 ++ > include/sparse/rte_flow.h | 1483 +++++++++++++++++++++++++++++++++++++++ > include/sparse/rte_icmp.h | 106 +++ > include/sparse/rte_ip.h | 490 +++++++++++++ > include/sparse/rte_sctp.h | 103 +++ > include/sparse/rte_tcp.h | 108 +++ > include/sparse/rte_udp.h | 103 +++ > include/sparse/xmmintrin.h | 24 + > 12 files changed, 2774 insertions(+), 1 deletion(-) > create mode 100644 include/sparse/rte_byteorder.h > create mode 100644 include/sparse/rte_esp.h > create mode 100644 include/sparse/rte_flow.h > create mode 100644 include/sparse/rte_icmp.h > create mode 100644 include/sparse/rte_ip.h > create mode 100644 include/sparse/rte_sctp.h > create mode 100644 include/sparse/rte_tcp.h > create mode 100644 include/sparse/rte_udp.h > create mode 100644 include/sparse/xmmintrin.h > > diff --git a/Makefile.am b/Makefile.am > index e02799a90fab..bf3a29a84c06 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -295,7 +295,7 @@ check-endian: > @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1 && \ > (cd $(srcdir) && git --no-pager grep -l -E \ > -e 'BIG_ENDIAN|LITTLE_ENDIAN' --and --not -e 'BYTE_ORDER' | \ > - $(EGREP) -v '^datapath/'); \ > + $(EGREP) -v '^datapath/|^include/sparse/rte_'); \ > then \ > echo "See above for list of files that misuse LITTLE""_ENDIAN"; \ > echo "or BIG""_ENDIAN. Please use WORDS_BIGENDIAN instead."; \ > diff --git a/build-aux/initial-tab-whitelist b/build-aux/initial-tab-whitelist > index cde3ec4f6428..1e9573c697c8 100644 > --- a/build-aux/initial-tab-whitelist > +++ b/build-aux/initial-tab-whitelist > @@ -5,6 +5,7 @@ > \.sln$ > ^datapath/ > ^include/linux/ > +^include/sparse/rte_ > ^include/windows/ > ^lib/sflow > ^lib/getopt_long\.c$ > diff --git a/include/sparse/automake.mk b/include/sparse/automake.mk > index ce445fab1e5c..79ce0b7d9ffa 100644 > --- a/include/sparse/automake.mk > +++ b/include/sparse/automake.mk > @@ -1,4 +1,13 @@ > noinst_HEADERS += \ > + include/sparse/rte_byteorder.h \ > + include/sparse/rte_esp.h \ > + include/sparse/rte_flow.h \ > + include/sparse/rte_icmp.h \ > + include/sparse/rte_ip.h \ > + include/sparse/rte_sctp.h \ > + include/sparse/rte_tcp.h \ > + include/sparse/rte_udp.h \ > + include/sparse/xmmintrin.h \ > include/sparse/arpa/inet.h \ > include/sparse/bits/floatn.h \ > include/sparse/assert.h \ > diff --git a/include/sparse/rte_byteorder.h b/include/sparse/rte_byteorder.h > new file mode 100644 > index 000000000000..d32b5e69150f > --- /dev/null > +++ b/include/sparse/rte_byteorder.h > @@ -0,0 +1,281 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright(c) 2010-2014 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 > + * are met: > + * > + * * 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 > + * distribution. > + * * 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 > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef __CHECKER__ > +#error "Use this header only with sparse. It is not a correct implementation." > +#endif > + > +#ifndef _RTE_BYTEORDER_H_ > +#define _RTE_BYTEORDER_H_ > + > +/** > + * @file > + * > + * Byte Swap Operations > + * > + * This file defines a generic API for byte swap operations. Part of > + * the implementation is architecture-specific. > + */ > + > +#include "openvswitch/types.h" > +#include <stdint.h> > +#ifdef RTE_EXEC_ENV_BSDAPP > +#include <sys/endian.h> > +#else > +#include <endian.h> > +#endif > + > +#include <rte_common.h> > +#include <rte_config.h> > + > +/* > + * Compile-time endianness detection > + */ > +#define RTE_BIG_ENDIAN 1 > +#define RTE_LITTLE_ENDIAN 2 > +#if defined __BYTE_ORDER__ > +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ > +#define RTE_BYTE_ORDER RTE_BIG_ENDIAN > +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ > +#define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN > +#endif /* __BYTE_ORDER__ */ > +#elif defined __BYTE_ORDER > +#if __BYTE_ORDER == __BIG_ENDIAN > +#define RTE_BYTE_ORDER RTE_BIG_ENDIAN > +#elif __BYTE_ORDER == __LITTLE_ENDIAN > +#define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN > +#endif /* __BYTE_ORDER */ > +#elif defined __BIG_ENDIAN__ > +#define RTE_BYTE_ORDER RTE_BIG_ENDIAN > +#elif defined __LITTLE_ENDIAN__ > +#define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN > +#endif > +#if !defined(RTE_BYTE_ORDER) > +#error Unknown endianness. > +#endif > + > +#define RTE_STATIC_BSWAP16(v) \ > + ((((uint16_t)(v) & UINT16_C(0x00ff)) << 8) | \ > + (((uint16_t)(v) & UINT16_C(0xff00)) >> 8)) > + > +#define RTE_STATIC_BSWAP32(v) \ > + ((((uint32_t)(v) & UINT32_C(0x000000ff)) << 24) | \ > + (((uint32_t)(v) & UINT32_C(0x0000ff00)) << 8) | \ > + (((uint32_t)(v) & UINT32_C(0x00ff0000)) >> 8) | \ > + (((uint32_t)(v) & UINT32_C(0xff000000)) >> 24)) > + > +#define RTE_STATIC_BSWAP64(v) \ > + ((((uint64_t)(v) & UINT64_C(0x00000000000000ff)) << 56) | \ > + (((uint64_t)(v) & UINT64_C(0x000000000000ff00)) << 40) | \ > + (((uint64_t)(v) & UINT64_C(0x0000000000ff0000)) << 24) | \ > + (((uint64_t)(v) & UINT64_C(0x00000000ff000000)) << 8) | \ > + (((uint64_t)(v) & UINT64_C(0x000000ff00000000)) >> 8) | \ > + (((uint64_t)(v) & UINT64_C(0x0000ff0000000000)) >> 24) | \ > + (((uint64_t)(v) & UINT64_C(0x00ff000000000000)) >> 40) | \ > + (((uint64_t)(v) & UINT64_C(0xff00000000000000)) >> 56)) > + > +/* > + * These macros are functionally similar to rte_cpu_to_(be|le)(16|32|64)(), > + * they take values in host CPU order and return them converted to the > + * intended endianness. > + * > + * They resolve at compilation time to integer constants which can safely be > + * used with static initializers, since those cannot involve function calls. > + * > + * On the other hand, they are not as optimized as their rte_cpu_to_*() > + * counterparts, therefore applications should refrain from using them on > + * variable values, particularly inside performance-sensitive code. > + */ > +#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN > +#define RTE_BE16(v) (OVS_FORCE rte_be16_t)(v) > +#define RTE_BE32(v) (OVS_FORCE rte_be32_t)(v) > +#define RTE_BE64(v) (OVS_FORCE rte_be64_t)(v) > +#define RTE_LE16(v) (OVS_FORCE rte_le16_t)(RTE_STATIC_BSWAP16(v)) > +#define RTE_LE32(v) (OVS_FORCE rte_le32_t)(RTE_STATIC_BSWAP32(v)) > +#define RTE_LE64(v) (OVS_FORCE rte_le64_t)(RTE_STATIC_BSWAP64(v)) > +#elif RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN > +#define RTE_BE16(v) (OVS_FORCE rte_be16_t)(RTE_STATIC_BSWAP16(v)) > +#define RTE_BE32(v) (OVS_FORCE rte_be32_t)(RTE_STATIC_BSWAP32(v)) > +#define RTE_BE64(v) (OVS_FORCE rte_be64_t)(RTE_STATIC_BSWAP64(v)) > +#define RTE_LE16(v) (OVS_FORCE rte_be16_t)(v) > +#define RTE_LE32(v) (OVS_FORCE rte_be32_t)(v) > +#define RTE_LE64(v) (OVS_FORCE rte_be64_t)(v) > +#else > +#error Unsupported endianness. > +#endif > + > +/* > + * The following types should be used when handling values according to a > + * specific byte ordering, which may differ from that of the host CPU. > + * > + * Libraries, public APIs and applications are encouraged to use them for > + * documentation purposes. > + */ > +typedef ovs_be16 rte_be16_t; /**< 16-bit big-endian value. */ > +typedef ovs_be32 rte_be32_t; /**< 32-bit big-endian value. */ > +typedef ovs_be64 rte_be64_t; /**< 64-bit big-endian value. */ > +typedef uint16_t rte_le16_t; /**< 16-bit little-endian value. */ > +typedef uint32_t rte_le32_t; /**< 32-bit little-endian value. */ > +typedef uint64_t rte_le64_t; /**< 64-bit little-endian value. */ > + > +/* > + * An internal function to swap bytes in a 16-bit value. > + * > + * It is used by rte_bswap16() when the value is constant. Do not use > + * this function directly; rte_bswap16() is preferred. > + */ > +static inline uint16_t > +rte_constant_bswap16(uint16_t x) > +{ > + return RTE_STATIC_BSWAP16(x); > +} > + > +/* > + * An internal function to swap bytes in a 32-bit value. > + * > + * It is used by rte_bswap32() when the value is constant. Do not use > + * this function directly; rte_bswap32() is preferred. > + */ > +static inline uint32_t > +rte_constant_bswap32(uint32_t x) > +{ > + return RTE_STATIC_BSWAP32(x); > +} > + > +/* > + * An internal function to swap bytes of a 64-bit value. > + * > + * It is used by rte_bswap64() when the value is constant. Do not use > + * this function directly; rte_bswap64() is preferred. > + */ > +static inline uint64_t > +rte_constant_bswap64(uint64_t x) > +{ > + return RTE_STATIC_BSWAP64(x); > +} > + > + > +#ifdef __DOXYGEN__ > + > +/** > + * Swap bytes in a 16-bit value. > + */ > +static uint16_t rte_bswap16(uint16_t _x); > + > +/** > + * Swap bytes in a 32-bit value. > + */ > +static uint32_t rte_bswap32(uint32_t x); > + > +/** > + * Swap bytes in a 64-bit value. > + */ > +static uint64_t rte_bswap64(uint64_t x); > + > +/** > + * Convert a 16-bit value from CPU order to little endian. > + */ > +static rte_le16_t rte_cpu_to_le_16(uint16_t x); > + > +/** > + * Convert a 32-bit value from CPU order to little endian. > + */ > +static rte_le32_t rte_cpu_to_le_32(uint32_t x); > + > +/** > + * Convert a 64-bit value from CPU order to little endian. > + */ > +static rte_le64_t rte_cpu_to_le_64(uint64_t x); > + > + > +/** > + * Convert a 16-bit value from CPU order to big endian. > + */ > +static rte_be16_t rte_cpu_to_be_16(uint16_t x); > + > +/** > + * Convert a 32-bit value from CPU order to big endian. > + */ > +static rte_be32_t rte_cpu_to_be_32(uint32_t x); > + > +/** > + * Convert a 64-bit value from CPU order to big endian. > + */ > +static rte_be64_t rte_cpu_to_be_64(uint64_t x); > + > + > +/** > + * Convert a 16-bit value from little endian to CPU order. > + */ > +static uint16_t rte_le_to_cpu_16(rte_le16_t x); > + > +/** > + * Convert a 32-bit value from little endian to CPU order. > + */ > +static uint32_t rte_le_to_cpu_32(rte_le32_t x); > + > +/** > + * Convert a 64-bit value from little endian to CPU order. > + */ > +static uint64_t rte_le_to_cpu_64(rte_le64_t x); > + > + > +/** > + * Convert a 16-bit value from big endian to CPU order. > + */ > +static uint16_t rte_be_to_cpu_16(rte_be16_t x); > + > +/** > + * Convert a 32-bit value from big endian to CPU order. > + */ > +static uint32_t rte_be_to_cpu_32(rte_be32_t x); > + > +/** > + * Convert a 64-bit value from big endian to CPU order. > + */ > +static uint64_t rte_be_to_cpu_64(rte_be64_t x); > + > +#endif /* __DOXYGEN__ */ > + > +#ifdef RTE_FORCE_INTRINSICS > +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) > +#define rte_bswap16(x) __builtin_bswap16(x) > +#endif > + > +#define rte_bswap32(x) __builtin_bswap32(x) > + > +#define rte_bswap64(x) __builtin_bswap64(x) > + > +#endif > + > +#endif /* _RTE_BYTEORDER_H_ */ > diff --git a/include/sparse/rte_esp.h b/include/sparse/rte_esp.h > new file mode 100644 > index 000000000000..d3fc19e32a6b > --- /dev/null > +++ b/include/sparse/rte_esp.h > @@ -0,0 +1,65 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved. > + * > + * 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 > + * 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 > + * distribution. > + * * 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 > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef __CHECKER__ > +#error "Use this header only with sparse. It is not a correct implementation." > +#endif > + > +#ifndef _RTE_ESP_H_ > +#define _RTE_ESP_H_ > + > +/** > + * @file > + * > + * ESP-related defines > + */ > + > +#include "openvswitch/types.h" > +#include <stdint.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * ESP Header > + */ > +struct esp_hdr { > + ovs_be32 spi; /**< Security Parameters Index */ > + ovs_be32 seq; /**< packet sequence number */ > +} __attribute__((__packed__)); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* RTE_ESP_H_ */ > diff --git a/include/sparse/rte_flow.h b/include/sparse/rte_flow.h > new file mode 100644 > index 000000000000..a36ab45e7ca2 > --- /dev/null > +++ b/include/sparse/rte_flow.h > @@ -0,0 +1,1483 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright 2016 6WIND S.A. > + * Copyright 2016 Mellanox. > + * > + * 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 > + * 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 > + * distribution. > + * * Neither the name of 6WIND S.A. 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 > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef __CHECKER__ > +#error "Use this header only with sparse. It is not a correct implementation." > +#endif > + > +#ifndef RTE_FLOW_H_ > +#define RTE_FLOW_H_ > + > +/** > + * @file > + * RTE generic flow API > + * > + * This interface provides the ability to program packet matching and > + * associated actions in hardware through flow rules. > + */ > + > +#include <rte_arp.h> > +#include <rte_ether.h> > +#include <rte_icmp.h> > +#include <rte_ip.h> > +#include <rte_sctp.h> > +#include <rte_tcp.h> > +#include <rte_udp.h> > +#include <rte_byteorder.h> > +#include <rte_esp.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * Flow rule attributes. > + * > + * Priorities are set on two levels: per group and per rule within groups. > + * > + * Lower values denote higher priority, the highest priority for both levels > + * is 0, so that a rule with priority 0 in group 8 is always matched after a > + * rule with priority 8 in group 0. > + * > + * Although optional, applications are encouraged to group similar rules as > + * much as possible to fully take advantage of hardware capabilities > + * (e.g. optimized matching) and work around limitations (e.g. a single > + * pattern type possibly allowed in a given group). > + * > + * Group and priority levels are arbitrary and up to the application, they > + * do not need to be contiguous nor start from 0, however the maximum number > + * varies between devices and may be affected by existing flow rules. > + * > + * If a packet is matched by several rules of a given group for a given > + * priority level, the outcome is undefined. It can take any path, may be > + * duplicated or even cause unrecoverable errors. > + * > + * Note that support for more than a single group and priority level is not > + * guaranteed. > + * > + * Flow rules can apply to inbound and/or outbound traffic (ingress/egress). > + * > + * Several pattern items and actions are valid and can be used in both > + * directions. Those valid for only one direction are described as such. > + * > + * At least one direction must be specified. > + * > + * Specifying both directions at once for a given rule is not recommended > + * but may be valid in a few cases (e.g. shared counter). > + */ > +struct rte_flow_attr { > + uint32_t group; /**< Priority group. */ > + uint32_t priority; /**< Priority level within group. */ > + uint32_t ingress:1; /**< Rule applies to ingress traffic. */ > + uint32_t egress:1; /**< Rule applies to egress traffic. */ > + uint32_t reserved:30; /**< Reserved, must be zero. */ > +}; > + > +/** > + * Matching pattern item types. > + * > + * Pattern items fall in two categories: > + * > + * - Matching protocol headers and packet data (ANY, RAW, ETH, VLAN, IPV4, > + * IPV6, ICMP, UDP, TCP, SCTP, VXLAN and so on), usually associated with a > + * specification structure. These must be stacked in the same order as the > + * protocol layers to match, starting from the lowest. > + * > + * - Matching meta-data or affecting pattern processing (END, VOID, INVERT, > + * PF, VF, PORT and so on), often without a specification structure. Since > + * they do not match packet contents, these can be specified anywhere > + * within item lists without affecting others. > + * > + * See the description of individual types for more information. Those > + * marked with [META] fall into the second category. > + */ > +enum rte_flow_item_type { > + /** > + * [META] > + * > + * End marker for item lists. Prevents further processing of items, > + * thereby ending the pattern. > + * > + * No associated specification structure. > + */ > + RTE_FLOW_ITEM_TYPE_END, > + > + /** > + * [META] > + * > + * Used as a placeholder for convenience. It is ignored and simply > + * discarded by PMDs. > + * > + * No associated specification structure. > + */ > + RTE_FLOW_ITEM_TYPE_VOID, > + > + /** > + * [META] > + * > + * Inverted matching, i.e. process packets that do not match the > + * pattern. > + * > + * No associated specification structure. > + */ > + RTE_FLOW_ITEM_TYPE_INVERT, > + > + /** > + * Matches any protocol in place of the current layer, a single ANY > + * may also stand for several protocol layers. > + * > + * See struct rte_flow_item_any. > + */ > + RTE_FLOW_ITEM_TYPE_ANY, > + > + /** > + * [META] > + * > + * Matches packets addressed to the physical function of the device. > + * > + * If the underlying device function differs from the one that would > + * normally receive the matched traffic, specifying this item > + * prevents it from reaching that device unless the flow rule > + * contains a PF action. Packets are not duplicated between device > + * instances by default. > + * > + * No associated specification structure. > + */ > + RTE_FLOW_ITEM_TYPE_PF, > + > + /** > + * [META] > + * > + * Matches packets addressed to a virtual function ID of the device. > + * > + * If the underlying device function differs from the one that would > + * normally receive the matched traffic, specifying this item > + * prevents it from reaching that device unless the flow rule > + * contains a VF action. Packets are not duplicated between device > + * instances by default. > + * > + * See struct rte_flow_item_vf. > + */ > + RTE_FLOW_ITEM_TYPE_VF, > + > + /** > + * [META] > + * > + * Matches packets coming from the specified physical port of the > + * underlying device. > + * > + * The first PORT item overrides the physical port normally > + * associated with the specified DPDK input port (port_id). This > + * item can be provided several times to match additional physical > + * ports. > + * > + * See struct rte_flow_item_port. > + */ > + RTE_FLOW_ITEM_TYPE_PORT, > + > + /** > + * Matches a byte string of a given length at a given offset. > + * > + * See struct rte_flow_item_raw. > + */ > + RTE_FLOW_ITEM_TYPE_RAW, > + > + /** > + * Matches an Ethernet header. > + * > + * See struct rte_flow_item_eth. > + */ > + RTE_FLOW_ITEM_TYPE_ETH, > + > + /** > + * Matches an 802.1Q/ad VLAN tag. > + * > + * See struct rte_flow_item_vlan. > + */ > + RTE_FLOW_ITEM_TYPE_VLAN, > + > + /** > + * Matches an IPv4 header. > + * > + * See struct rte_flow_item_ipv4. > + */ > + RTE_FLOW_ITEM_TYPE_IPV4, > + > + /** > + * Matches an IPv6 header. > + * > + * See struct rte_flow_item_ipv6. > + */ > + RTE_FLOW_ITEM_TYPE_IPV6, > + > + /** > + * Matches an ICMP header. > + * > + * See struct rte_flow_item_icmp. > + */ > + RTE_FLOW_ITEM_TYPE_ICMP, > + > + /** > + * Matches a UDP header. > + * > + * See struct rte_flow_item_udp. > + */ > + RTE_FLOW_ITEM_TYPE_UDP, > + > + /** > + * Matches a TCP header. > + * > + * See struct rte_flow_item_tcp. > + */ > + RTE_FLOW_ITEM_TYPE_TCP, > + > + /** > + * Matches a SCTP header. > + * > + * See struct rte_flow_item_sctp. > + */ > + RTE_FLOW_ITEM_TYPE_SCTP, > + > + /** > + * Matches a VXLAN header. > + * > + * See struct rte_flow_item_vxlan. > + */ > + RTE_FLOW_ITEM_TYPE_VXLAN, > + > + /** > + * Matches a E_TAG header. > + * > + * See struct rte_flow_item_e_tag. > + */ > + RTE_FLOW_ITEM_TYPE_E_TAG, > + > + /** > + * Matches a NVGRE header. > + * > + * See struct rte_flow_item_nvgre. > + */ > + RTE_FLOW_ITEM_TYPE_NVGRE, > + > + /** > + * Matches a MPLS header. > + * > + * See struct rte_flow_item_mpls. > + */ > + RTE_FLOW_ITEM_TYPE_MPLS, > + > + /** > + * Matches a GRE header. > + * > + * See struct rte_flow_item_gre. > + */ > + RTE_FLOW_ITEM_TYPE_GRE, > + > + /** > + * [META] > + * > + * Fuzzy pattern match, expect faster than default. > + * > + * This is for device that support fuzzy matching option. > + * Usually a fuzzy matching is fast but the cost is accuracy. > + * > + * See struct rte_flow_item_fuzzy. > + */ > + RTE_FLOW_ITEM_TYPE_FUZZY, > + > + /** > + * Matches a GTP header. > + * > + * Configure flow for GTP packets. > + * > + * See struct rte_flow_item_gtp. > + */ > + RTE_FLOW_ITEM_TYPE_GTP, > + > + /** > + * Matches a GTP header. > + * > + * Configure flow for GTP-C packets. > + * > + * See struct rte_flow_item_gtp. > + */ > + RTE_FLOW_ITEM_TYPE_GTPC, > + > + /** > + * Matches a GTP header. > + * > + * Configure flow for GTP-U packets. > + * > + * See struct rte_flow_item_gtp. > + */ > + RTE_FLOW_ITEM_TYPE_GTPU, > + > + /** > + * Matches a ESP header. > + * > + * See struct rte_flow_item_esp. > + */ > + RTE_FLOW_ITEM_TYPE_ESP, > +}; > + > +/** > + * RTE_FLOW_ITEM_TYPE_ANY > + * > + * Matches any protocol in place of the current layer, a single ANY may also > + * stand for several protocol layers. > + * > + * This is usually specified as the first pattern item when looking for a > + * protocol anywhere in a packet. > + * > + * A zeroed mask stands for any number of layers. > + */ > +struct rte_flow_item_any { > + uint32_t num; /**< Number of layers covered. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_ANY. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_any rte_flow_item_any_mask = { > + .num = 0x00000000, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_VF > + * > + * Matches packets addressed to a virtual function ID of the device. > + * > + * If the underlying device function differs from the one that would > + * normally receive the matched traffic, specifying this item prevents it > + * from reaching that device unless the flow rule contains a VF > + * action. Packets are not duplicated between device instances by default. > + * > + * - Likely to return an error or never match any traffic if this causes a > + * VF device to match traffic addressed to a different VF. > + * - Can be specified multiple times to match traffic addressed to several > + * VF IDs. > + * - Can be combined with a PF item to match both PF and VF traffic. > + * > + * A zeroed mask can be used to match any VF ID. > + */ > +struct rte_flow_item_vf { > + uint32_t id; /**< Destination VF ID. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_VF. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_vf rte_flow_item_vf_mask = { > + .id = 0x00000000, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_PORT > + * > + * Matches packets coming from the specified physical port of the underlying > + * device. > + * > + * The first PORT item overrides the physical port normally associated with > + * the specified DPDK input port (port_id). This item can be provided > + * several times to match additional physical ports. > + * > + * Note that physical ports are not necessarily tied to DPDK input ports > + * (port_id) when those are not under DPDK control. Possible values are > + * specific to each device, they are not necessarily indexed from zero and > + * may not be contiguous. > + * > + * As a device property, the list of allowed values as well as the value > + * associated with a port_id should be retrieved by other means. > + * > + * A zeroed mask can be used to match any port index. > + */ > +struct rte_flow_item_port { > + uint32_t index; /**< Physical port index. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_PORT. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_port rte_flow_item_port_mask = { > + .index = 0x00000000, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_RAW > + * > + * Matches a byte string of a given length at a given offset. > + * > + * Offset is either absolute (using the start of the packet) or relative to > + * the end of the previous matched item in the stack, in which case negative > + * values are allowed. > + * > + * If search is enabled, offset is used as the starting point. The search > + * area can be delimited by setting limit to a nonzero value, which is the > + * maximum number of bytes after offset where the pattern may start. > + * > + * Matching a zero-length pattern is allowed, doing so resets the relative > + * offset for subsequent items. > + * > + * This type does not support ranges (struct rte_flow_item.last). > + */ > +struct rte_flow_item_raw { > + uint32_t relative:1; /**< Look for pattern after the previous item. */ > + uint32_t search:1; /**< Search pattern from offset (see also limit). */ > + uint32_t reserved:30; /**< Reserved, must be set to zero. */ > + int32_t offset; /**< Absolute or relative offset for pattern. */ > + uint16_t limit; /**< Search area limit for start of pattern. */ > + uint16_t length; /**< Pattern length. */ > + uint8_t pattern[]; /**< Byte string to look for. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_RAW. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_raw rte_flow_item_raw_mask = { > + .relative = 1, > + .search = 1, > + .reserved = 0x3fffffff, > + .offset = 0xffffffff, > + .limit = 0xffff, > + .length = 0xffff, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_ETH > + * > + * Matches an Ethernet header. > + */ > +struct rte_flow_item_eth { > + struct ether_addr dst; /**< Destination MAC. */ > + struct ether_addr src; /**< Source MAC. */ > + rte_be16_t type; /**< EtherType. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_ETH. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_eth rte_flow_item_eth_mask = { > + .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff", > + .src.addr_bytes = "\xff\xff\xff\xff\xff\xff", > + .type = RTE_BE16(0x0000), > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_VLAN > + * > + * Matches an 802.1Q/ad VLAN tag. > + * > + * This type normally follows either RTE_FLOW_ITEM_TYPE_ETH or > + * RTE_FLOW_ITEM_TYPE_VLAN. > + */ > +struct rte_flow_item_vlan { > + rte_be16_t tpid; /**< Tag protocol identifier. */ > + rte_be16_t tci; /**< Tag control information. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_VLAN. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_vlan rte_flow_item_vlan_mask = { > + .tpid = RTE_BE16(0x0000), > + .tci = RTE_BE16(0xffff), > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_IPV4 > + * > + * Matches an IPv4 header. > + * > + * Note: IPv4 options are handled by dedicated pattern items. > + */ > +struct rte_flow_item_ipv4 { > + struct ipv4_hdr hdr; /**< IPv4 header definition. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_IPV4. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_ipv4 rte_flow_item_ipv4_mask = { > + .hdr = { > + .src_addr = RTE_BE32(0xffffffff), > + .dst_addr = RTE_BE32(0xffffffff), > + }, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_IPV6. > + * > + * Matches an IPv6 header. > + * > + * Note: IPv6 options are handled by dedicated pattern items. > + */ > +struct rte_flow_item_ipv6 { > + struct ipv6_hdr hdr; /**< IPv6 header definition. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = { > + .hdr = { > + .src_addr = > + "\xff\xff\xff\xff\xff\xff\xff\xff" > + "\xff\xff\xff\xff\xff\xff\xff\xff", > + .dst_addr = > + "\xff\xff\xff\xff\xff\xff\xff\xff" > + "\xff\xff\xff\xff\xff\xff\xff\xff", > + }, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_ICMP. > + * > + * Matches an ICMP header. > + */ > +struct rte_flow_item_icmp { > + struct icmp_hdr hdr; /**< ICMP header definition. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_icmp rte_flow_item_icmp_mask = { > + .hdr = { > + .icmp_type = 0xff, > + .icmp_code = 0xff, > + }, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_UDP. > + * > + * Matches a UDP header. > + */ > +struct rte_flow_item_udp { > + struct udp_hdr hdr; /**< UDP header definition. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_UDP. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_udp rte_flow_item_udp_mask = { > + .hdr = { > + .src_port = RTE_BE16(0xffff), > + .dst_port = RTE_BE16(0xffff), > + }, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_TCP. > + * > + * Matches a TCP header. > + */ > +struct rte_flow_item_tcp { > + struct tcp_hdr hdr; /**< TCP header definition. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_TCP. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_tcp rte_flow_item_tcp_mask = { > + .hdr = { > + .src_port = RTE_BE16(0xffff), > + .dst_port = RTE_BE16(0xffff), > + }, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_SCTP. > + * > + * Matches a SCTP header. > + */ > +struct rte_flow_item_sctp { > + struct sctp_hdr hdr; /**< SCTP header definition. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_SCTP. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_sctp rte_flow_item_sctp_mask = { > + .hdr = { > + .src_port = RTE_BE16(0xffff), > + .dst_port = RTE_BE16(0xffff), > + }, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_VXLAN. > + * > + * Matches a VXLAN header (RFC 7348). > + */ > +struct rte_flow_item_vxlan { > + uint8_t flags; /**< Normally 0x08 (I flag). */ > + uint8_t rsvd0[3]; /**< Reserved, normally 0x000000. */ > + uint8_t vni[3]; /**< VXLAN identifier. */ > + uint8_t rsvd1; /**< Reserved, normally 0x00. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_VXLAN. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_vxlan rte_flow_item_vxlan_mask = { > + .vni = "\xff\xff\xff", > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_E_TAG. > + * > + * Matches a E-tag header. > + */ > +struct rte_flow_item_e_tag { > + rte_be16_t tpid; /**< Tag protocol identifier (0x893F). */ > + /** > + * E-Tag control information (E-TCI). > + * E-PCP (3b), E-DEI (1b), ingress E-CID base (12b). > + */ > + rte_be16_t epcp_edei_in_ecid_b; > + /** Reserved (2b), GRP (2b), E-CID base (12b). */ > + rte_be16_t rsvd_grp_ecid_b; > + uint8_t in_ecid_e; /**< Ingress E-CID ext. */ > + uint8_t ecid_e; /**< E-CID ext. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_E_TAG. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_e_tag rte_flow_item_e_tag_mask = { > + .rsvd_grp_ecid_b = RTE_BE16(0x3fff), > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_NVGRE. > + * > + * Matches a NVGRE header. > + */ > +struct rte_flow_item_nvgre { > + /** > + * Checksum (1b), undefined (1b), key bit (1b), sequence number (1b), > + * reserved 0 (9b), version (3b). > + * > + * c_k_s_rsvd0_ver must have value 0x2000 according to RFC 7637. > + */ > + rte_be16_t c_k_s_rsvd0_ver; > + rte_be16_t protocol; /**< Protocol type (0x6558). */ > + uint8_t tni[3]; /**< Virtual subnet ID. */ > + uint8_t flow_id; /**< Flow ID. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_NVGRE. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_nvgre rte_flow_item_nvgre_mask = { > + .tni = "\xff\xff\xff", > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_MPLS. > + * > + * Matches a MPLS header. > + */ > +struct rte_flow_item_mpls { > + /** > + * Label (20b), TC (3b), Bottom of Stack (1b). > + */ > + uint8_t label_tc_s[3]; > + uint8_t ttl; /** Time-to-Live. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_MPLS. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_mpls rte_flow_item_mpls_mask = { > + .label_tc_s = "\xff\xff\xf0", > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_GRE. > + * > + * Matches a GRE header. > + */ > +struct rte_flow_item_gre { > + /** > + * Checksum (1b), reserved 0 (12b), version (3b). > + * Refer to RFC 2784. > + */ > + rte_be16_t c_rsvd0_ver; > + rte_be16_t protocol; /**< Protocol type. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_GRE. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_gre rte_flow_item_gre_mask = { > + .protocol = RTE_BE16(0xffff), > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_FUZZY > + * > + * Fuzzy pattern match, expect faster than default. > + * > + * This is for device that support fuzzy match option. > + * Usually a fuzzy match is fast but the cost is accuracy. > + * i.e. Signature Match only match pattern's hash value, but it is > + * possible two different patterns have the same hash value. > + * > + * Matching accuracy level can be configure by threshold. > + * Driver can divide the range of threshold and map to different > + * accuracy levels that device support. > + * > + * Threshold 0 means perfect match (no fuzziness), while threshold > + * 0xffffffff means fuzziest match. > + */ > +struct rte_flow_item_fuzzy { > + uint32_t thresh; /**< Accuracy threshold. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_FUZZY. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_fuzzy rte_flow_item_fuzzy_mask = { > + .thresh = 0xffffffff, > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_GTP. > + * > + * Matches a GTPv1 header. > + */ > +struct rte_flow_item_gtp { > + /** > + * Version (3b), protocol type (1b), reserved (1b), > + * Extension header flag (1b), > + * Sequence number flag (1b), > + * N-PDU number flag (1b). > + */ > + uint8_t v_pt_rsv_flags; > + uint8_t msg_type; /**< Message type. */ > + rte_be16_t msg_len; /**< Message length. */ > + rte_be32_t teid; /**< Tunnel endpoint identifier. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_GTP. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_gtp rte_flow_item_gtp_mask = { > + .teid = RTE_BE32(0xffffffff), > +}; > +#endif > + > +/** > + * RTE_FLOW_ITEM_TYPE_ESP > + * > + * Matches an ESP header. > + */ > +struct rte_flow_item_esp { > + struct esp_hdr hdr; /**< ESP header definition. */ > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_ESP. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_esp rte_flow_item_esp_mask = { > + .hdr = { > + .spi = OVS_BE32_MAX, > + }, > +}; > +#endif > + > +/** > + * Matching pattern item definition. > + * > + * A pattern is formed by stacking items starting from the lowest protocol > + * layer to match. This stacking restriction does not apply to meta items > + * which can be placed anywhere in the stack without affecting the meaning > + * of the resulting pattern. > + * > + * Patterns are terminated by END items. > + * > + * The spec field should be a valid pointer to a structure of the related > + * item type. It may remain unspecified (NULL) in many cases to request > + * broad (nonspecific) matching. In such cases, last and mask must also be > + * set to NULL. > + * > + * Optionally, last can point to a structure of the same type to define an > + * inclusive range. This is mostly supported by integer and address fields, > + * may cause errors otherwise. Fields that do not support ranges must be set > + * to 0 or to the same value as the corresponding fields in spec. > + * > + * Only the fields defined to nonzero values in the default masks (see > + * rte_flow_item_{name}_mask constants) are considered relevant by > + * default. This can be overridden by providing a mask structure of the > + * same type with applicable bits set to one. It can also be used to > + * partially filter out specific fields (e.g. as an alternate mean to match > + * ranges of IP addresses). > + * > + * Mask is a simple bit-mask applied before interpreting the contents of > + * spec and last, which may yield unexpected results if not used > + * carefully. For example, if for an IPv4 address field, spec provides > + * 10.1.2.3, last provides 10.3.4.5 and mask provides 255.255.0.0, the > + * effective range becomes 10.1.0.0 to 10.3.255.255. > + */ > +struct rte_flow_item { > + enum rte_flow_item_type type; /**< Item type. */ > + const void *spec; /**< Pointer to item specification structure. */ > + const void *last; /**< Defines an inclusive range (spec to last). */ > + const void *mask; /**< Bit-mask applied to spec and last. */ > +}; > + > +/** > + * Action types. > + * > + * Each possible action is represented by a type. Some have associated > + * configuration structures. Several actions combined in a list can be > + * affected to a flow rule. That list is not ordered. > + * > + * They fall in three categories: > + * > + * - Terminating actions (such as QUEUE, DROP, RSS, PF, VF) that prevent > + * processing matched packets by subsequent flow rules, unless overridden > + * with PASSTHRU. > + * > + * - Non terminating actions (PASSTHRU, DUP) that leave matched packets up > + * for additional processing by subsequent flow rules. > + * > + * - Other non terminating meta actions that do not affect the fate of > + * packets (END, VOID, MARK, FLAG, COUNT). > + * > + * When several actions are combined in a flow rule, they should all have > + * different types (e.g. dropping a packet twice is not possible). > + * > + * Only the last action of a given type is taken into account. PMDs still > + * perform error checking on the entire list. > + * > + * Note that PASSTHRU is the only action able to override a terminating > + * rule. > + */ > +enum rte_flow_action_type { > + /** > + * [META] > + * > + * End marker for action lists. Prevents further processing of > + * actions, thereby ending the list. > + * > + * No associated configuration structure. > + */ > + RTE_FLOW_ACTION_TYPE_END, > + > + /** > + * [META] > + * > + * Used as a placeholder for convenience. It is ignored and simply > + * discarded by PMDs. > + * > + * No associated configuration structure. > + */ > + RTE_FLOW_ACTION_TYPE_VOID, > + > + /** > + * Leaves packets up for additional processing by subsequent flow > + * rules. This is the default when a rule does not contain a > + * terminating action, but can be specified to force a rule to > + * become non-terminating. > + * > + * No associated configuration structure. > + */ > + RTE_FLOW_ACTION_TYPE_PASSTHRU, > + > + /** > + * [META] > + * > + * Attaches an integer value to packets and sets PKT_RX_FDIR and > + * PKT_RX_FDIR_ID mbuf flags. > + * > + * See struct rte_flow_action_mark. > + */ > + RTE_FLOW_ACTION_TYPE_MARK, > + > + /** > + * [META] > + * > + * Flags packets. Similar to MARK without a specific value; only > + * sets the PKT_RX_FDIR mbuf flag. > + * > + * No associated configuration structure. > + */ > + RTE_FLOW_ACTION_TYPE_FLAG, > + > + /** > + * Assigns packets to a given queue index. > + * > + * See struct rte_flow_action_queue. > + */ > + RTE_FLOW_ACTION_TYPE_QUEUE, > + > + /** > + * Drops packets. > + * > + * PASSTHRU overrides this action if both are specified. > + * > + * No associated configuration structure. > + */ > + RTE_FLOW_ACTION_TYPE_DROP, > + > + /** > + * [META] > + * > + * Enables counters for this rule. > + * > + * These counters can be retrieved and reset through rte_flow_query(), > + * see struct rte_flow_query_count. > + * > + * No associated configuration structure. > + */ > + RTE_FLOW_ACTION_TYPE_COUNT, > + > + /** > + * Duplicates packets to a given queue index. > + * > + * This is normally combined with QUEUE, however when used alone, it > + * is actually similar to QUEUE + PASSTHRU. > + * > + * See struct rte_flow_action_dup. > + */ > + RTE_FLOW_ACTION_TYPE_DUP, > + > + /** > + * Similar to QUEUE, except RSS is additionally performed on packets > + * to spread them among several queues according to the provided > + * parameters. > + * > + * See struct rte_flow_action_rss. > + */ > + RTE_FLOW_ACTION_TYPE_RSS, > + > + /** > + * Redirects packets to the physical function (PF) of the current > + * device. > + * > + * No associated configuration structure. > + */ > + RTE_FLOW_ACTION_TYPE_PF, > + > + /** > + * Redirects packets to the virtual function (VF) of the current > + * device with the specified ID. > + * > + * See struct rte_flow_action_vf. > + */ > + RTE_FLOW_ACTION_TYPE_VF, > + > + /** > + * Traffic metering and policing (MTR). > + * > + * See struct rte_flow_action_meter. > + * See file rte_mtr.h for MTR object configuration. > + */ > + RTE_FLOW_ACTION_TYPE_METER, > + > + /** > + * Redirects packets to security engine of current device for security > + * processing as specified by security session. > + * > + * See struct rte_flow_action_security. > + */ > + RTE_FLOW_ACTION_TYPE_SECURITY > +}; > + > +/** > + * RTE_FLOW_ACTION_TYPE_MARK > + * > + * Attaches an integer value to packets and sets PKT_RX_FDIR and > + * PKT_RX_FDIR_ID mbuf flags. > + * > + * This value is arbitrary and application-defined. Maximum allowed value > + * depends on the underlying implementation. It is returned in the > + * hash.fdir.hi mbuf field. > + */ > +struct rte_flow_action_mark { > + uint32_t id; /**< Integer value to return with packets. */ > +}; > + > +/** > + * RTE_FLOW_ACTION_TYPE_QUEUE > + * > + * Assign packets to a given queue index. > + * > + * Terminating by default. > + */ > +struct rte_flow_action_queue { > + uint16_t index; /**< Queue index to use. */ > +}; > + > +/** > + * RTE_FLOW_ACTION_TYPE_COUNT (query) > + * > + * Query structure to retrieve and reset flow rule counters. > + */ > +struct rte_flow_query_count { > + uint32_t reset:1; /**< Reset counters after query [in]. */ > + uint32_t hits_set:1; /**< hits field is set [out]. */ > + uint32_t bytes_set:1; /**< bytes field is set [out]. */ > + uint32_t reserved:29; /**< Reserved, must be zero [in, out]. */ > + uint64_t hits; /**< Number of hits for this rule [out]. */ > + uint64_t bytes; /**< Number of bytes through this rule [out]. */ > +}; > + > +/** > + * RTE_FLOW_ACTION_TYPE_DUP > + * > + * Duplicates packets to a given queue index. > + * > + * This is normally combined with QUEUE, however when used alone, it is > + * actually similar to QUEUE + PASSTHRU. > + * > + * Non-terminating by default. > + */ > +struct rte_flow_action_dup { > + uint16_t index; /**< Queue index to duplicate packets to. */ > +}; > + > +/** > + * RTE_FLOW_ACTION_TYPE_RSS > + * > + * Similar to QUEUE, except RSS is additionally performed on packets to > + * spread them among several queues according to the provided parameters. > + * > + * Note: RSS hash result is stored in the hash.rss mbuf field which overlaps > + * hash.fdir.lo. Since the MARK action sets the hash.fdir.hi field only, > + * both can be requested simultaneously. > + * > + * Terminating by default. > + */ > +struct rte_flow_action_rss { > + const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */ > + uint16_t num; /**< Number of entries in queue[]. */ > + uint16_t queue[]; /**< Queues indices to use. */ > +}; > + > +/** > + * RTE_FLOW_ACTION_TYPE_VF > + * > + * Redirects packets to a virtual function (VF) of the current device. > + * > + * Packets matched by a VF pattern item can be redirected to their original > + * VF ID instead of the specified one. This parameter may not be available > + * and is not guaranteed to work properly if the VF part is matched by a > + * prior flow rule or if packets are not addressed to a VF in the first > + * place. > + * > + * Terminating by default. > + */ > +struct rte_flow_action_vf { > + uint32_t original:1; /**< Use original VF ID if possible. */ > + uint32_t reserved:31; /**< Reserved, must be zero. */ > + uint32_t id; /**< VF ID to redirect packets to. */ > +}; > + > +/** > + * RTE_FLOW_ACTION_TYPE_METER > + * > + * Traffic metering and policing (MTR). > + * > + * Packets matched by items of this type can be either dropped or passed to the > + * next item with their color set by the MTR object. > + * > + * Non-terminating by default. > + */ > +struct rte_flow_action_meter { > + uint32_t mtr_id; /**< MTR object ID created with rte_mtr_create(). */ > +}; > + > +/** > + * RTE_FLOW_ACTION_TYPE_SECURITY > + * > + * Perform the security action on flows matched by the pattern items > + * according to the configuration of the security session. > + * > + * This action modifies the payload of matched flows. For INLINE_CRYPTO, the > + * security protocol headers and IV are fully provided by the application as > + * specified in the flow pattern. The payload of matching packets is > + * encrypted on egress, and decrypted and authenticated on ingress. > + * For INLINE_PROTOCOL, the security protocol is fully offloaded to HW, > + * providing full encapsulation and decapsulation of packets in security > + * protocols. The flow pattern specifies both the outer security header fields > + * and the inner packet fields. The security session specified in the action > + * must match the pattern parameters. > + * > + * The security session specified in the action must be created on the same > + * port as the flow action that is being specified. > + * > + * The ingress/egress flow attribute should match that specified in the > + * security session if the security session supports the definition of the > + * direction. > + * > + * Multiple flows can be configured to use the same security session. > + * > + * Non-terminating by default. > + */ > +struct rte_flow_action_security { > + void *security_session; /**< Pointer to security session structure. */ > +}; > + > +/** > + * Definition of a single action. > + * > + * A list of actions is terminated by a END action. > + * > + * For simple actions without a configuration structure, conf remains NULL. > + */ > +struct rte_flow_action { > + enum rte_flow_action_type type; /**< Action type. */ > + const void *conf; /**< Pointer to action configuration structure. */ > +}; > + > +/** > + * Opaque type returned after successfully creating a flow. > + * > + * This handle can be used to manage and query the related flow (e.g. to > + * destroy it or retrieve counters). > + */ > +struct rte_flow; > + > +/** > + * Verbose error types. > + * > + * Most of them provide the type of the object referenced by struct > + * rte_flow_error.cause. > + */ > +enum rte_flow_error_type { > + RTE_FLOW_ERROR_TYPE_NONE, /**< No error. */ > + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, /**< Cause unspecified. */ > + RTE_FLOW_ERROR_TYPE_HANDLE, /**< Flow rule (handle). */ > + RTE_FLOW_ERROR_TYPE_ATTR_GROUP, /**< Group field. */ > + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, /**< Priority field. */ > + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, /**< Ingress field. */ > + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, /**< Egress field. */ > + RTE_FLOW_ERROR_TYPE_ATTR, /**< Attributes structure. */ > + RTE_FLOW_ERROR_TYPE_ITEM_NUM, /**< Pattern length. */ > + RTE_FLOW_ERROR_TYPE_ITEM, /**< Specific pattern item. */ > + RTE_FLOW_ERROR_TYPE_ACTION_NUM, /**< Number of actions. */ > + RTE_FLOW_ERROR_TYPE_ACTION, /**< Specific action. */ > +}; > + > +/** > + * Verbose error structure definition. > + * > + * This object is normally allocated by applications and set by PMDs, the > + * message points to a constant string which does not need to be freed by > + * the application, however its pointer can be considered valid only as long > + * as its associated DPDK port remains configured. Closing the underlying > + * device or unloading the PMD invalidates it. > + * > + * Both cause and message may be NULL regardless of the error type. > + */ > +struct rte_flow_error { > + enum rte_flow_error_type type; /**< Cause field and error types. */ > + const void *cause; /**< Object responsible for the error. */ > + const char *message; /**< Human-readable error message. */ > +}; > + > +/** > + * Check whether a flow rule can be created on a given port. > + * > + * The flow rule is validated for correctness and whether it could be accepted > + * by the device given sufficient resources. The rule is checked against the > + * current device mode and queue configuration. The flow rule may also > + * optionally be validated against existing flow rules and device resources. > + * This function has no effect on the target device. > + * > + * The returned value is guaranteed to remain valid only as long as no > + * successful calls to rte_flow_create() or rte_flow_destroy() are made in > + * the meantime and no device parameter affecting flow rules in any way are > + * modified, due to possible collisions or resource limitations (although in > + * such cases EINVAL should not be returned). > + * > + * @param port_id > + * Port identifier of Ethernet device. > + * @param[in] attr > + * Flow rule attributes. > + * @param[in] pattern > + * Pattern specification (list terminated by the END pattern item). > + * @param[in] actions > + * Associated actions (list terminated by the END action). > + * @param[out] error > + * Perform verbose error reporting if not NULL. PMDs initialize this > + * structure in case of error only. > + * > + * @return > + * 0 if flow rule is valid and can be created. A negative errno value > + * otherwise (rte_errno is also set), the following errors are defined: > + * > + * -ENOSYS: underlying device does not support this functionality. > + * > + * -EINVAL: unknown or invalid rule specification. > + * > + * -ENOTSUP: valid but unsupported rule specification (e.g. partial > + * bit-masks are unsupported). > + * > + * -EEXIST: collision with an existing rule. Only returned if device > + * supports flow rule collision checking and there was a flow rule > + * collision. Not receiving this return code is no guarantee that creating > + * the rule will not fail due to a collision. > + * > + * -ENOMEM: not enough memory to execute the function, or if the device > + * supports resource validation, resource limitation on the device. > + * > + * -EBUSY: action cannot be performed due to busy device resources, may > + * succeed if the affected queues or even the entire port are in a stopped > + * state (see rte_eth_dev_rx_queue_stop() and rte_eth_dev_stop()). > + */ > +int > +rte_flow_validate(uint16_t port_id, > + const struct rte_flow_attr *attr, > + const struct rte_flow_item pattern[], > + const struct rte_flow_action actions[], > + struct rte_flow_error *error); > + > +/** > + * Create a flow rule on a given port. > + * > + * @param port_id > + * Port identifier of Ethernet device. > + * @param[in] attr > + * Flow rule attributes. > + * @param[in] pattern > + * Pattern specification (list terminated by the END pattern item). > + * @param[in] actions > + * Associated actions (list terminated by the END action). > + * @param[out] error > + * Perform verbose error reporting if not NULL. PMDs initialize this > + * structure in case of error only. > + * > + * @return > + * A valid handle in case of success, NULL otherwise and rte_errno is set > + * to the positive version of one of the error codes defined for > + * rte_flow_validate(). > + */ > +struct rte_flow * > +rte_flow_create(uint16_t port_id, > + const struct rte_flow_attr *attr, > + const struct rte_flow_item pattern[], > + const struct rte_flow_action actions[], > + struct rte_flow_error *error); > + > +/** > + * Destroy a flow rule on a given port. > + * > + * Failure to destroy a flow rule handle may occur when other flow rules > + * depend on it, and destroying it would result in an inconsistent state. > + * > + * This function is only guaranteed to succeed if handles are destroyed in > + * reverse order of their creation. > + * > + * @param port_id > + * Port identifier of Ethernet device. > + * @param flow > + * Flow rule handle to destroy. > + * @param[out] error > + * Perform verbose error reporting if not NULL. PMDs initialize this > + * structure in case of error only. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set. > + */ > +int > +rte_flow_destroy(uint16_t port_id, > + struct rte_flow *flow, > + struct rte_flow_error *error); > + > +/** > + * Destroy all flow rules associated with a port. > + * > + * In the unlikely event of failure, handles are still considered destroyed > + * and no longer valid but the port must be assumed to be in an inconsistent > + * state. > + * > + * @param port_id > + * Port identifier of Ethernet device. > + * @param[out] error > + * Perform verbose error reporting if not NULL. PMDs initialize this > + * structure in case of error only. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set. > + */ > +int > +rte_flow_flush(uint16_t port_id, > + struct rte_flow_error *error); > + > +/** > + * Query an existing flow rule. > + * > + * This function allows retrieving flow-specific data such as counters. > + * Data is gathered by special actions which must be present in the flow > + * rule definition. > + * > + * \see RTE_FLOW_ACTION_TYPE_COUNT > + * > + * @param port_id > + * Port identifier of Ethernet device. > + * @param flow > + * Flow rule handle to query. > + * @param action > + * Action type to query. > + * @param[in, out] data > + * Pointer to storage for the associated query data type. > + * @param[out] error > + * Perform verbose error reporting if not NULL. PMDs initialize this > + * structure in case of error only. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set. > + */ > +int > +rte_flow_query(uint16_t port_id, > + struct rte_flow *flow, > + enum rte_flow_action_type action, > + void *data, > + struct rte_flow_error *error); > + > +/** > + * Restrict ingress traffic to the defined flow rules. > + * > + * Isolated mode guarantees that all ingress traffic comes from defined flow > + * rules only (current and future). > + * > + * Besides making ingress more deterministic, it allows PMDs to safely reuse > + * resources otherwise assigned to handle the remaining traffic, such as > + * global RSS configuration settings, VLAN filters, MAC address entries, > + * legacy filter API rules and so on in order to expand the set of possible > + * flow rule types. > + * > + * Calling this function as soon as possible after device initialization, > + * ideally before the first call to rte_eth_dev_configure(), is recommended > + * to avoid possible failures due to conflicting settings. > + * > + * Once effective, leaving isolated mode may not be possible depending on > + * PMD implementation. > + * > + * Additionally, the following functionality has no effect on the underlying > + * port and may return errors such as ENOTSUP ("not supported"): > + * > + * - Toggling promiscuous mode. > + * - Toggling allmulticast mode. > + * - Configuring MAC addresses. > + * - Configuring multicast addresses. > + * - Configuring VLAN filters. > + * - Configuring Rx filters through the legacy API (e.g. FDIR). > + * - Configuring global RSS settings. > + * > + * @param port_id > + * Port identifier of Ethernet device. > + * @param set > + * Nonzero to enter isolated mode, attempt to leave it otherwise. > + * @param[out] error > + * Perform verbose error reporting if not NULL. PMDs initialize this > + * structure in case of error only. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set. > + */ > +int > +rte_flow_isolate(uint16_t port_id, int set, struct rte_flow_error *error); > + > +/** > + * Initialize flow error structure. > + * > + * @param[out] error > + * Pointer to flow error structure (may be NULL). > + * @param code > + * Related error code (rte_errno). > + * @param type > + * Cause field and error types. > + * @param cause > + * Object responsible for the error. > + * @param message > + * Human-readable error message. > + * > + * @return > + * Negative error code (errno value) and rte_errno is set. > + */ > +int > +rte_flow_error_set(struct rte_flow_error *error, > + int code, > + enum rte_flow_error_type type, > + const void *cause, > + const char *message); > + > +/** > + * Generic flow representation. > + * > + * This form is sufficient to describe an rte_flow independently from any > + * PMD implementation and allows for replayability and identification. > + */ > +struct rte_flow_desc { > + size_t size; /**< Allocated space including data[]. */ > + struct rte_flow_attr attr; /**< Attributes. */ > + struct rte_flow_item *items; /**< Items. */ > + struct rte_flow_action *actions; /**< Actions. */ > + uint8_t data[]; /**< Storage for items/actions. */ > +}; > + > +/** > + * Copy an rte_flow rule description. > + * > + * @param[in] fd > + * Flow rule description. > + * @param[in] len > + * Total size of allocated data for the flow description. > + * @param[in] attr > + * Flow rule attributes. > + * @param[in] items > + * Pattern specification (list terminated by the END pattern item). > + * @param[in] actions > + * Associated actions (list terminated by the END action). > + * > + * @return > + * If len is greater or equal to the size of the flow, the total size of the > + * flow description and its data. > + * If len is lower than the size of the flow, the number of bytes that would > + * have been written to desc had it been sufficient. Nothing is written. > + */ > +size_t > +rte_flow_copy(struct rte_flow_desc *fd, size_t len, > + const struct rte_flow_attr *attr, > + const struct rte_flow_item *items, > + const struct rte_flow_action *actions); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* RTE_FLOW_H_ */ > diff --git a/include/sparse/rte_icmp.h b/include/sparse/rte_icmp.h > new file mode 100644 > index 000000000000..62e8b0400303 > --- /dev/null > +++ b/include/sparse/rte_icmp.h > @@ -0,0 +1,106 @@ > +/* BSD LICENSE > + * > + * Copyright(c) 2013 6WIND. > + * > + * 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 > + * 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 > + * distribution. > + * * Neither the name of 6WIND S.A. 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 > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > +/* > + * Copyright (c) 1982, 1986, 1990, 1993 > + * The Regents of the University of California. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. 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. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the University of > + * California, Berkeley and its contributors. > + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. > + * > + * @(#)in.h 8.3 (Berkeley) 1/3/94 > + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ > + */ > + > +#ifndef __CHECKER__ > +#error "Use this header only with sparse. It is not a correct implementation." > +#endif > + > +#ifndef _RTE_ICMP_H_ > +#define _RTE_ICMP_H_ > + > +/** > + * @file > + * > + * ICMP-related defines > + */ > + > +#include "openvswitch/types.h" > +#include <stdint.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * ICMP Header > + */ > +struct icmp_hdr { > + uint8_t icmp_type; /* ICMP packet type. */ > + uint8_t icmp_code; /* ICMP packet code. */ > + ovs_be16 icmp_cksum; /* ICMP packet checksum. */ > + ovs_be16 icmp_ident; /* ICMP packet identifier. */ > + ovs_be16 icmp_seq_nb; /* ICMP packet sequence number. */ > +} __attribute__((__packed__)); > + > +/* ICMP packet types */ > +#define IP_ICMP_ECHO_REPLY 0 > +#define IP_ICMP_ECHO_REQUEST 8 > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* RTE_ICMP_H_ */ > diff --git a/include/sparse/rte_ip.h b/include/sparse/rte_ip.h > new file mode 100644 > index 000000000000..b171308c09cd > --- /dev/null > +++ b/include/sparse/rte_ip.h > @@ -0,0 +1,490 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. > + * Copyright 2014 6WIND S.A. > + * All rights reserved. > + * > + * 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 > + * 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 > + * distribution. > + * * 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 > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * Copyright (c) 1982, 1986, 1990, 1993 > + * The Regents of the University of California. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. 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. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the University of > + * California, Berkeley and its contributors. > + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. > + * > + * @(#)in.h 8.3 (Berkeley) 1/3/94 > + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ > + */ > + > +#ifndef _RTE_IP_H_ > +#define _RTE_IP_H_ > + > +/** > + * @file > + * > + * IP-related defines > + */ > + > +#include <stdint.h> > +#include <netinet/in.h> > + > +#include <rte_byteorder.h> > +#include <rte_mbuf.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * IPv4 Header > + */ > +struct ipv4_hdr { > + uint8_t version_ihl; /**< version and header length */ > + uint8_t type_of_service; /**< type of service */ > + ovs_be16 total_length; /**< length of packet */ > + ovs_be16 packet_id; /**< packet ID */ > + ovs_be16 fragment_offset; /**< fragmentation offset */ > + uint8_t time_to_live; /**< time to live */ > + uint8_t next_proto_id; /**< protocol ID */ > + ovs_be16 hdr_checksum; /**< header checksum */ > + ovs_be32 src_addr; /**< source address */ > + ovs_be32 dst_addr; /**< destination address */ > +} __attribute__((__packed__)); > + > +/** Create IPv4 address */ > +#define IPv4(a,b,c,d) ((uint32_t)(((a) & 0xff) << 24) | \ > + (((b) & 0xff) << 16) | \ > + (((c) & 0xff) << 8) | \ > + ((d) & 0xff)) > + > +/** Maximal IPv4 packet length (including a header) */ > +#define IPV4_MAX_PKT_LEN 65535 > + > +/** Internet header length mask for version_ihl field */ > +#define IPV4_HDR_IHL_MASK (0x0f) > +/** > + * Internet header length field multiplier (IHL field specifies overall header > + * length in number of 4-byte words) > + */ > +#define IPV4_IHL_MULTIPLIER (4) > + > +/* Fragment Offset * Flags. */ > +#define IPV4_HDR_DF_SHIFT 14 > +#define IPV4_HDR_MF_SHIFT 13 > +#define IPV4_HDR_FO_SHIFT 3 > + > +#define IPV4_HDR_DF_FLAG (1 << IPV4_HDR_DF_SHIFT) > +#define IPV4_HDR_MF_FLAG (1 << IPV4_HDR_MF_SHIFT) > + > +#define IPV4_HDR_OFFSET_MASK ((1 << IPV4_HDR_MF_SHIFT) - 1) > + > +#define IPV4_HDR_OFFSET_UNITS 8 > + > +/* > + * IPv4 address types > + */ > +#define IPV4_ANY ((uint32_t)0x00000000) /**< 0.0.0.0 */ > +#define IPV4_LOOPBACK ((uint32_t)0x7f000001) /**< 127.0.0.1 */ > +#define IPV4_BROADCAST ((uint32_t)0xe0000000) /**< 224.0.0.0 */ > +#define IPV4_ALLHOSTS_GROUP ((uint32_t)0xe0000001) /**< 224.0.0.1 */ > +#define IPV4_ALLRTRS_GROUP ((uint32_t)0xe0000002) /**< 224.0.0.2 */ > +#define IPV4_MAX_LOCAL_GROUP ((uint32_t)0xe00000ff) /**< 224.0.0.255 */ > + > +/* > + * IPv4 Multicast-related macros > + */ > +#define IPV4_MIN_MCAST IPv4(224, 0, 0, 0) /**< Minimal IPv4-multicast address */ > +#define IPV4_MAX_MCAST IPv4(239, 255, 255, 255) /**< Maximum IPv4 multicast address */ > + > +#define IS_IPV4_MCAST(x) \ > + ((x) >= IPV4_MIN_MCAST && (x) <= IPV4_MAX_MCAST) /**< check if IPv4 address is multicast */ > + > +/** > + * @internal Calculate a sum of all words in the buffer. > + * Helper routine for the rte_raw_cksum(). > + * > + * @param buf > + * Pointer to the buffer. > + * @param len > + * Length of the buffer. > + * @param sum > + * Initial value of the sum. > + * @return > + * sum += Sum of all words in the buffer. > + */ > +static inline uint32_t > +__rte_raw_cksum(const void *buf, size_t len, uint32_t sum) > +{ > + /* workaround gcc strict-aliasing warning */ > + uintptr_t ptr = (uintptr_t)buf; > + typedef uint16_t __attribute__((__may_alias__)) u16_p; > + const u16_p *u16 = (const u16_p *)ptr; > + > + while (len >= (sizeof(*u16) * 4)) { > + sum += u16[0]; > + sum += u16[1]; > + sum += u16[2]; > + sum += u16[3]; > + len -= sizeof(*u16) * 4; > + u16 += 4; > + } > + while (len >= sizeof(*u16)) { > + sum += *u16; > + len -= sizeof(*u16); > + u16 += 1; > + } > + > + /* if length is in odd bytes */ > + if (len == 1) > + sum += *((const uint8_t *)u16); > + > + return sum; > +} > + > +/** > + * @internal Reduce a sum to the non-complemented checksum. > + * Helper routine for the rte_raw_cksum(). > + * > + * @param sum > + * Value of the sum. > + * @return > + * The non-complemented checksum. > + */ > +static inline uint16_t > +__rte_raw_cksum_reduce(uint32_t sum) > +{ > + sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff); > + sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff); > + return (uint16_t)sum; > +} > + > +/** > + * Process the non-complemented checksum of a buffer. > + * > + * @param buf > + * Pointer to the buffer. > + * @param len > + * Length of the buffer. > + * @return > + * The non-complemented checksum. > + */ > +static inline uint16_t > +rte_raw_cksum(const void *buf, size_t len) > +{ > + uint32_t sum; > + > + sum = __rte_raw_cksum(buf, len, 0); > + return __rte_raw_cksum_reduce(sum); > +} > + > +/** > + * Compute the raw (non complemented) checksum of a packet. > + * > + * @param m > + * The pointer to the mbuf. > + * @param off > + * The offset in bytes to start the checksum. > + * @param len > + * The length in bytes of the data to checksum. > + * @param cksum > + * A pointer to the checksum, filled on success. > + * @return > + * 0 on success, -1 on error (bad length or offset). > + */ > +static inline int > +rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, > + uint16_t *cksum) > +{ > + const struct rte_mbuf *seg; > + const char *buf; > + uint32_t sum, tmp; > + uint32_t seglen, done; > + > + /* easy case: all data in the first segment */ > + if (off + len <= rte_pktmbuf_data_len(m)) { > + *cksum = rte_raw_cksum(rte_pktmbuf_mtod_offset(m, > + const char *, off), len); > + return 0; > + } > + > + if (unlikely(off + len > rte_pktmbuf_pkt_len(m))) > + return -1; /* invalid params, return a dummy value */ > + > + /* else browse the segment to find offset */ > + seglen = 0; > + for (seg = m; seg != NULL; seg = seg->next) { > + seglen = rte_pktmbuf_data_len(seg); > + if (off < seglen) > + break; > + off -= seglen; > + } > + seglen -= off; > + buf = rte_pktmbuf_mtod_offset(seg, const char *, off); > + if (seglen >= len) { > + /* all in one segment */ > + *cksum = rte_raw_cksum(buf, len); > + return 0; > + } > + > + /* hard case: process checksum of several segments */ > + sum = 0; > + done = 0; > + for (;;) { > + tmp = __rte_raw_cksum(buf, seglen, 0); > + if (done & 1) > + tmp = rte_bswap16(tmp); > + sum += tmp; > + done += seglen; > + if (done == len) > + break; > + seg = seg->next; > + buf = rte_pktmbuf_mtod(seg, const char *); > + seglen = rte_pktmbuf_data_len(seg); > + if (seglen > len - done) > + seglen = len - done; > + } > + > + *cksum = __rte_raw_cksum_reduce(sum); > + return 0; > +} > + > +/** > + * Process the IPv4 checksum of an IPv4 header. > + * > + * The checksum field must be set to 0 by the caller. > + * > + * @param ipv4_hdr > + * The pointer to the contiguous IPv4 header. > + * @return > + * The complemented checksum to set in the IP packet. > + */ > +static inline uint16_t > +rte_ipv4_cksum(const struct ipv4_hdr *ipv4_hdr) > +{ > + uint16_t cksum; > + cksum = rte_raw_cksum(ipv4_hdr, sizeof(struct ipv4_hdr)); > + return (cksum == 0xffff) ? cksum : ~cksum; > +} > + > +/** > + * Process the pseudo-header checksum of an IPv4 header. > + * > + * The checksum field must be set to 0 by the caller. > + * > + * Depending on the ol_flags, the pseudo-header checksum expected by the > + * drivers is not the same. For instance, when TSO is enabled, the IP > + * payload length must not be included in the packet. > + * > + * When ol_flags is 0, it computes the standard pseudo-header checksum. > + * > + * @param ipv4_hdr > + * The pointer to the contiguous IPv4 header. > + * @param ol_flags > + * The ol_flags of the associated mbuf. > + * @return > + * The non-complemented checksum to set in the L4 header. > + */ > +static inline uint16_t > +rte_ipv4_phdr_cksum(const struct ipv4_hdr *ipv4_hdr, uint64_t ol_flags) > +{ > + struct ipv4_psd_header { > + ovs_be32 src_addr; /* IP address of source host. */ > + ovs_be32 dst_addr; /* IP address of destination host. */ > + uint8_t zero; /* zero. */ > + uint8_t proto; /* L4 protocol type. */ > + uint16_t len; /* L4 length. */ > + } psd_hdr; > + > + psd_hdr.src_addr = ipv4_hdr->src_addr; > + psd_hdr.dst_addr = ipv4_hdr->dst_addr; > + psd_hdr.zero = 0; > + psd_hdr.proto = ipv4_hdr->next_proto_id; > + if (ol_flags & PKT_TX_TCP_SEG) { > + psd_hdr.len = 0; > + } else { > + psd_hdr.len = rte_cpu_to_be_16( > + (uint16_t)(rte_be_to_cpu_16(ipv4_hdr->total_length) > + - sizeof(struct ipv4_hdr))); > + } > + return rte_raw_cksum(&psd_hdr, sizeof(psd_hdr)); > +} > + > +/** > + * Process the IPv4 UDP or TCP checksum. > + * > + * The IPv4 header should not contains options. The IP and layer 4 > + * checksum must be set to 0 in the packet by the caller. > + * > + * @param ipv4_hdr > + * The pointer to the contiguous IPv4 header. > + * @param l4_hdr > + * The pointer to the beginning of the L4 header. > + * @return > + * The complemented checksum to set in the IP packet. > + */ > +static inline uint16_t > +rte_ipv4_udptcp_cksum(const struct ipv4_hdr *ipv4_hdr, const void *l4_hdr) > +{ > + uint32_t cksum; > + uint32_t l4_len; > + > + l4_len = rte_be_to_cpu_16(ipv4_hdr->total_length) - > + sizeof(struct ipv4_hdr); > + > + cksum = rte_raw_cksum(l4_hdr, l4_len); > + cksum += rte_ipv4_phdr_cksum(ipv4_hdr, 0); > + > + cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff); > + cksum = (~cksum) & 0xffff; > + if (cksum == 0) > + cksum = 0xffff; > + > + return cksum; > +} > + > +/** > + * IPv6 Header > + */ > +struct ipv6_hdr { > + ovs_be32 vtc_flow; /**< IP version, traffic class & flow label. */ > + ovs_be16 payload_len; /**< IP packet length - includes sizeof(ip_header). */ > + uint8_t proto; /**< Protocol, next header. */ > + uint8_t hop_limits; /**< Hop limits. */ > + uint8_t src_addr[16]; /**< IP address of source host. */ > + uint8_t dst_addr[16]; /**< IP address of destination host(s). */ > +} __attribute__((__packed__)); > + > +/* IPv6 vtc_flow: IPv / TC / flow_label */ > +#define IPV6_HDR_FL_SHIFT 0 > +#define IPV6_HDR_TC_SHIFT 20 > +#define IPV6_HDR_FL_MASK ((1u << IPV6_HDR_TC_SHIFT) - 1) > +#define IPV6_HDR_TC_MASK (0xf << IPV6_HDR_TC_SHIFT) > + > +/** > + * Process the pseudo-header checksum of an IPv6 header. > + * > + * Depending on the ol_flags, the pseudo-header checksum expected by the > + * drivers is not the same. For instance, when TSO is enabled, the IPv6 > + * payload length must not be included in the packet. > + * > + * When ol_flags is 0, it computes the standard pseudo-header checksum. > + * > + * @param ipv6_hdr > + * The pointer to the contiguous IPv6 header. > + * @param ol_flags > + * The ol_flags of the associated mbuf. > + * @return > + * The non-complemented checksum to set in the L4 header. > + */ > +static inline uint16_t > +rte_ipv6_phdr_cksum(const struct ipv6_hdr *ipv6_hdr, uint64_t ol_flags) > +{ > + uint32_t sum; > + struct { > + ovs_be32 len; /* L4 length. */ > + ovs_be32 proto; /* L4 protocol - top 3 bytes must be zero */ > + } psd_hdr; > + > + psd_hdr.proto = (ipv6_hdr->proto << 24); > + if (ol_flags & PKT_TX_TCP_SEG) { > + psd_hdr.len = 0; > + } else { > + psd_hdr.len = ipv6_hdr->payload_len; > + } > + > + sum = __rte_raw_cksum(ipv6_hdr->src_addr, > + sizeof(ipv6_hdr->src_addr) + sizeof(ipv6_hdr->dst_addr), > + 0); > + sum = __rte_raw_cksum(&psd_hdr, sizeof(psd_hdr), sum); > + return __rte_raw_cksum_reduce(sum); > +} > + > +/** > + * Process the IPv6 UDP or TCP checksum. > + * > + * The IPv4 header should not contains options. The layer 4 checksum > + * must be set to 0 in the packet by the caller. > + * > + * @param ipv6_hdr > + * The pointer to the contiguous IPv6 header. > + * @param l4_hdr > + * The pointer to the beginning of the L4 header. > + * @return > + * The complemented checksum to set in the IP packet. > + */ > +static inline uint16_t > +rte_ipv6_udptcp_cksum(const struct ipv6_hdr *ipv6_hdr, const void *l4_hdr) > +{ > + uint32_t cksum; > + uint32_t l4_len; > + > + l4_len = rte_be_to_cpu_16(ipv6_hdr->payload_len); > + > + cksum = rte_raw_cksum(l4_hdr, l4_len); > + cksum += rte_ipv6_phdr_cksum(ipv6_hdr, 0); > + > + cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff); > + cksum = (~cksum) & 0xffff; > + if (cksum == 0) > + cksum = 0xffff; > + > + return cksum; > +} > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _RTE_IP_H_ */ > diff --git a/include/sparse/rte_sctp.h b/include/sparse/rte_sctp.h > new file mode 100644 > index 000000000000..74287905dcc9 > --- /dev/null > +++ b/include/sparse/rte_sctp.h > @@ -0,0 +1,103 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright(c) 2010-2014 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 > + * are met: > + * > + * * 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 > + * distribution. > + * * 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 > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * Copyright (c) 1982, 1986, 1990, 1993 > + * The Regents of the University of California. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. 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. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the University of > + * California, Berkeley and its contributors. > + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. > + * > + * @(#)in.h 8.3 (Berkeley) 1/3/94 > + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ > + */ > + > +/** > + * @file > + * > + * SCTP-related defines > + */ > + > +#ifndef __CHECKER__ > +#error "Use this header only with sparse. It is not a correct implementation." > +#endif > + > +#ifndef _RTE_SCTP_H_ > +#define _RTE_SCTP_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include <stdint.h> > + > +/** > + * SCTP Header > + */ > +struct sctp_hdr { > + ovs_be16 src_port; /**< Source port. */ > + ovs_be16 dst_port; /**< Destin port. */ > + ovs_be32 tag; /**< Validation tag. */ > + ovs_be32 cksum; /**< Checksum. */ > +} __attribute__((__packed__)); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* RTE_SCTP_H_ */ > diff --git a/include/sparse/rte_tcp.h b/include/sparse/rte_tcp.h > new file mode 100644 > index 000000000000..729529695f34 > --- /dev/null > +++ b/include/sparse/rte_tcp.h > @@ -0,0 +1,108 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright(c) 2010-2014 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 > + * are met: > + * > + * * 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 > + * distribution. > + * * 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 > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * Copyright (c) 1982, 1986, 1990, 1993 > + * The Regents of the University of California. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. 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. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the University of > + * California, Berkeley and its contributors. > + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. > + * > + * @(#)in.h 8.3 (Berkeley) 1/3/94 > + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ > + */ > + > +#ifndef __CHECKER__ > +#error "Use this header only with sparse. It is not a correct implementation." > +#endif > + > +#ifndef _RTE_TCP_H_ > +#define _RTE_TCP_H_ > + > +/** > + * @file > + * > + * TCP-related defines > + */ > + > +#include <stdint.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * TCP Header > + */ > +struct tcp_hdr { > + ovs_be16 src_port; /**< TCP source port. */ > + ovs_be16 dst_port; /**< TCP destination port. */ > + ovs_be32 sent_seq; /**< TX data sequence number. */ > + ovs_be32 recv_ack; /**< RX data acknowledgement sequence number. */ > + uint8_t data_off; /**< Data offset. */ > + uint8_t tcp_flags; /**< TCP flags */ > + ovs_be16 rx_win; /**< RX flow control window. */ > + ovs_be16 cksum; /**< TCP checksum. */ > + ovs_be16 tcp_urp; /**< TCP urgent pointer, if any. */ > +} __attribute__((__packed__)); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* RTE_TCP_H_ */ > diff --git a/include/sparse/rte_udp.h b/include/sparse/rte_udp.h > new file mode 100644 > index 000000000000..8694a1dcfd3c > --- /dev/null > +++ b/include/sparse/rte_udp.h > @@ -0,0 +1,103 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright(c) 2010-2014 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 > + * are met: > + * > + * * 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 > + * distribution. > + * * 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 > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * Copyright (c) 1982, 1986, 1990, 1993 > + * The Regents of the University of California. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. 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. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the University of > + * California, Berkeley and its contributors. > + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. > + * > + * @(#)in.h 8.3 (Berkeley) 1/3/94 > + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ > + */ > + > +#ifndef __CHECKER__ > +#error "Use this header only with sparse. It is not a correct implementation." > +#endif > + > +#ifndef _RTE_UDP_H_ > +#define _RTE_UDP_H_ > + > +/** > + * @file > + * > + * UDP-related defines > + */ > + > +#include <stdint.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * UDP Header > + */ > +struct udp_hdr { > + ovs_be16 src_port; /**< UDP source port. */ > + ovs_be16 dst_port; /**< UDP destination port. */ > + ovs_be16 dgram_len; /**< UDP datagram length */ > + ovs_be16 dgram_cksum; /**< UDP datagram checksum */ > +} __attribute__((__packed__)); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* RTE_UDP_H_ */ > diff --git a/include/sparse/xmmintrin.h b/include/sparse/xmmintrin.h > new file mode 100644 > index 000000000000..5d311b9117bc > --- /dev/null > +++ b/include/sparse/xmmintrin.h > @@ -0,0 +1,24 @@ > +/* Copyright (c) 2015 Nicira, Inc. > + * > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at: > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +#ifndef __CHECKER__ > +#error "Use this header only with sparse. It is not a correct implementation." > +#endif > + > +/* sparse doesn't know about this builtin function yet. */ > +#define __builtin_ia32_pause() (void) 0 > + > +/* Get actual <xmmintrin.h> definitions for us to annotate and build on. */ > +#include_next <xmmintrin.h> >
diff --git a/Makefile.am b/Makefile.am index e02799a90fab..bf3a29a84c06 100644 --- a/Makefile.am +++ b/Makefile.am @@ -295,7 +295,7 @@ check-endian: @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1 && \ (cd $(srcdir) && git --no-pager grep -l -E \ -e 'BIG_ENDIAN|LITTLE_ENDIAN' --and --not -e 'BYTE_ORDER' | \ - $(EGREP) -v '^datapath/'); \ + $(EGREP) -v '^datapath/|^include/sparse/rte_'); \ then \ echo "See above for list of files that misuse LITTLE""_ENDIAN"; \ echo "or BIG""_ENDIAN. Please use WORDS_BIGENDIAN instead."; \ diff --git a/build-aux/initial-tab-whitelist b/build-aux/initial-tab-whitelist index cde3ec4f6428..1e9573c697c8 100644 --- a/build-aux/initial-tab-whitelist +++ b/build-aux/initial-tab-whitelist @@ -5,6 +5,7 @@ \.sln$ ^datapath/ ^include/linux/ +^include/sparse/rte_ ^include/windows/ ^lib/sflow ^lib/getopt_long\.c$ diff --git a/include/sparse/automake.mk b/include/sparse/automake.mk index ce445fab1e5c..79ce0b7d9ffa 100644 --- a/include/sparse/automake.mk +++ b/include/sparse/automake.mk @@ -1,4 +1,13 @@ noinst_HEADERS += \ + include/sparse/rte_byteorder.h \ + include/sparse/rte_esp.h \ + include/sparse/rte_flow.h \ + include/sparse/rte_icmp.h \ + include/sparse/rte_ip.h \ + include/sparse/rte_sctp.h \ + include/sparse/rte_tcp.h \ + include/sparse/rte_udp.h \ + include/sparse/xmmintrin.h \ include/sparse/arpa/inet.h \ include/sparse/bits/floatn.h \ include/sparse/assert.h \ diff --git a/include/sparse/rte_byteorder.h b/include/sparse/rte_byteorder.h new file mode 100644 index 000000000000..d32b5e69150f --- /dev/null +++ b/include/sparse/rte_byteorder.h @@ -0,0 +1,281 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 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 + * are met: + * + * * 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 + * distribution. + * * 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 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +#ifndef _RTE_BYTEORDER_H_ +#define _RTE_BYTEORDER_H_ + +/** + * @file + * + * Byte Swap Operations + * + * This file defines a generic API for byte swap operations. Part of + * the implementation is architecture-specific. + */ + +#include "openvswitch/types.h" +#include <stdint.h> +#ifdef RTE_EXEC_ENV_BSDAPP +#include <sys/endian.h> +#else +#include <endian.h> +#endif + +#include <rte_common.h> +#include <rte_config.h> + +/* + * Compile-time endianness detection + */ +#define RTE_BIG_ENDIAN 1 +#define RTE_LITTLE_ENDIAN 2 +#if defined __BYTE_ORDER__ +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define RTE_BYTE_ORDER RTE_BIG_ENDIAN +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN +#endif /* __BYTE_ORDER__ */ +#elif defined __BYTE_ORDER +#if __BYTE_ORDER == __BIG_ENDIAN +#define RTE_BYTE_ORDER RTE_BIG_ENDIAN +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN +#endif /* __BYTE_ORDER */ +#elif defined __BIG_ENDIAN__ +#define RTE_BYTE_ORDER RTE_BIG_ENDIAN +#elif defined __LITTLE_ENDIAN__ +#define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN +#endif +#if !defined(RTE_BYTE_ORDER) +#error Unknown endianness. +#endif + +#define RTE_STATIC_BSWAP16(v) \ + ((((uint16_t)(v) & UINT16_C(0x00ff)) << 8) | \ + (((uint16_t)(v) & UINT16_C(0xff00)) >> 8)) + +#define RTE_STATIC_BSWAP32(v) \ + ((((uint32_t)(v) & UINT32_C(0x000000ff)) << 24) | \ + (((uint32_t)(v) & UINT32_C(0x0000ff00)) << 8) | \ + (((uint32_t)(v) & UINT32_C(0x00ff0000)) >> 8) | \ + (((uint32_t)(v) & UINT32_C(0xff000000)) >> 24)) + +#define RTE_STATIC_BSWAP64(v) \ + ((((uint64_t)(v) & UINT64_C(0x00000000000000ff)) << 56) | \ + (((uint64_t)(v) & UINT64_C(0x000000000000ff00)) << 40) | \ + (((uint64_t)(v) & UINT64_C(0x0000000000ff0000)) << 24) | \ + (((uint64_t)(v) & UINT64_C(0x00000000ff000000)) << 8) | \ + (((uint64_t)(v) & UINT64_C(0x000000ff00000000)) >> 8) | \ + (((uint64_t)(v) & UINT64_C(0x0000ff0000000000)) >> 24) | \ + (((uint64_t)(v) & UINT64_C(0x00ff000000000000)) >> 40) | \ + (((uint64_t)(v) & UINT64_C(0xff00000000000000)) >> 56)) + +/* + * These macros are functionally similar to rte_cpu_to_(be|le)(16|32|64)(), + * they take values in host CPU order and return them converted to the + * intended endianness. + * + * They resolve at compilation time to integer constants which can safely be + * used with static initializers, since those cannot involve function calls. + * + * On the other hand, they are not as optimized as their rte_cpu_to_*() + * counterparts, therefore applications should refrain from using them on + * variable values, particularly inside performance-sensitive code. + */ +#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN +#define RTE_BE16(v) (OVS_FORCE rte_be16_t)(v) +#define RTE_BE32(v) (OVS_FORCE rte_be32_t)(v) +#define RTE_BE64(v) (OVS_FORCE rte_be64_t)(v) +#define RTE_LE16(v) (OVS_FORCE rte_le16_t)(RTE_STATIC_BSWAP16(v)) +#define RTE_LE32(v) (OVS_FORCE rte_le32_t)(RTE_STATIC_BSWAP32(v)) +#define RTE_LE64(v) (OVS_FORCE rte_le64_t)(RTE_STATIC_BSWAP64(v)) +#elif RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN +#define RTE_BE16(v) (OVS_FORCE rte_be16_t)(RTE_STATIC_BSWAP16(v)) +#define RTE_BE32(v) (OVS_FORCE rte_be32_t)(RTE_STATIC_BSWAP32(v)) +#define RTE_BE64(v) (OVS_FORCE rte_be64_t)(RTE_STATIC_BSWAP64(v)) +#define RTE_LE16(v) (OVS_FORCE rte_be16_t)(v) +#define RTE_LE32(v) (OVS_FORCE rte_be32_t)(v) +#define RTE_LE64(v) (OVS_FORCE rte_be64_t)(v) +#else +#error Unsupported endianness. +#endif + +/* + * The following types should be used when handling values according to a + * specific byte ordering, which may differ from that of the host CPU. + * + * Libraries, public APIs and applications are encouraged to use them for + * documentation purposes. + */ +typedef ovs_be16 rte_be16_t; /**< 16-bit big-endian value. */ +typedef ovs_be32 rte_be32_t; /**< 32-bit big-endian value. */ +typedef ovs_be64 rte_be64_t; /**< 64-bit big-endian value. */ +typedef uint16_t rte_le16_t; /**< 16-bit little-endian value. */ +typedef uint32_t rte_le32_t; /**< 32-bit little-endian value. */ +typedef uint64_t rte_le64_t; /**< 64-bit little-endian value. */ + +/* + * An internal function to swap bytes in a 16-bit value. + * + * It is used by rte_bswap16() when the value is constant. Do not use + * this function directly; rte_bswap16() is preferred. + */ +static inline uint16_t +rte_constant_bswap16(uint16_t x) +{ + return RTE_STATIC_BSWAP16(x); +} + +/* + * An internal function to swap bytes in a 32-bit value. + * + * It is used by rte_bswap32() when the value is constant. Do not use + * this function directly; rte_bswap32() is preferred. + */ +static inline uint32_t +rte_constant_bswap32(uint32_t x) +{ + return RTE_STATIC_BSWAP32(x); +} + +/* + * An internal function to swap bytes of a 64-bit value. + * + * It is used by rte_bswap64() when the value is constant. Do not use + * this function directly; rte_bswap64() is preferred. + */ +static inline uint64_t +rte_constant_bswap64(uint64_t x) +{ + return RTE_STATIC_BSWAP64(x); +} + + +#ifdef __DOXYGEN__ + +/** + * Swap bytes in a 16-bit value. + */ +static uint16_t rte_bswap16(uint16_t _x); + +/** + * Swap bytes in a 32-bit value. + */ +static uint32_t rte_bswap32(uint32_t x); + +/** + * Swap bytes in a 64-bit value. + */ +static uint64_t rte_bswap64(uint64_t x); + +/** + * Convert a 16-bit value from CPU order to little endian. + */ +static rte_le16_t rte_cpu_to_le_16(uint16_t x); + +/** + * Convert a 32-bit value from CPU order to little endian. + */ +static rte_le32_t rte_cpu_to_le_32(uint32_t x); + +/** + * Convert a 64-bit value from CPU order to little endian. + */ +static rte_le64_t rte_cpu_to_le_64(uint64_t x); + + +/** + * Convert a 16-bit value from CPU order to big endian. + */ +static rte_be16_t rte_cpu_to_be_16(uint16_t x); + +/** + * Convert a 32-bit value from CPU order to big endian. + */ +static rte_be32_t rte_cpu_to_be_32(uint32_t x); + +/** + * Convert a 64-bit value from CPU order to big endian. + */ +static rte_be64_t rte_cpu_to_be_64(uint64_t x); + + +/** + * Convert a 16-bit value from little endian to CPU order. + */ +static uint16_t rte_le_to_cpu_16(rte_le16_t x); + +/** + * Convert a 32-bit value from little endian to CPU order. + */ +static uint32_t rte_le_to_cpu_32(rte_le32_t x); + +/** + * Convert a 64-bit value from little endian to CPU order. + */ +static uint64_t rte_le_to_cpu_64(rte_le64_t x); + + +/** + * Convert a 16-bit value from big endian to CPU order. + */ +static uint16_t rte_be_to_cpu_16(rte_be16_t x); + +/** + * Convert a 32-bit value from big endian to CPU order. + */ +static uint32_t rte_be_to_cpu_32(rte_be32_t x); + +/** + * Convert a 64-bit value from big endian to CPU order. + */ +static uint64_t rte_be_to_cpu_64(rte_be64_t x); + +#endif /* __DOXYGEN__ */ + +#ifdef RTE_FORCE_INTRINSICS +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +#define rte_bswap16(x) __builtin_bswap16(x) +#endif + +#define rte_bswap32(x) __builtin_bswap32(x) + +#define rte_bswap64(x) __builtin_bswap64(x) + +#endif + +#endif /* _RTE_BYTEORDER_H_ */ diff --git a/include/sparse/rte_esp.h b/include/sparse/rte_esp.h new file mode 100644 index 000000000000..d3fc19e32a6b --- /dev/null +++ b/include/sparse/rte_esp.h @@ -0,0 +1,65 @@ +/*- + * BSD LICENSE + * + * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved. + * + * 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 + * 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 + * distribution. + * * 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 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +#ifndef _RTE_ESP_H_ +#define _RTE_ESP_H_ + +/** + * @file + * + * ESP-related defines + */ + +#include "openvswitch/types.h" +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * ESP Header + */ +struct esp_hdr { + ovs_be32 spi; /**< Security Parameters Index */ + ovs_be32 seq; /**< packet sequence number */ +} __attribute__((__packed__)); + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_ESP_H_ */ diff --git a/include/sparse/rte_flow.h b/include/sparse/rte_flow.h new file mode 100644 index 000000000000..a36ab45e7ca2 --- /dev/null +++ b/include/sparse/rte_flow.h @@ -0,0 +1,1483 @@ +/*- + * BSD LICENSE + * + * Copyright 2016 6WIND S.A. + * Copyright 2016 Mellanox. + * + * 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 + * 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 + * distribution. + * * Neither the name of 6WIND S.A. 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 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +#ifndef RTE_FLOW_H_ +#define RTE_FLOW_H_ + +/** + * @file + * RTE generic flow API + * + * This interface provides the ability to program packet matching and + * associated actions in hardware through flow rules. + */ + +#include <rte_arp.h> +#include <rte_ether.h> +#include <rte_icmp.h> +#include <rte_ip.h> +#include <rte_sctp.h> +#include <rte_tcp.h> +#include <rte_udp.h> +#include <rte_byteorder.h> +#include <rte_esp.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Flow rule attributes. + * + * Priorities are set on two levels: per group and per rule within groups. + * + * Lower values denote higher priority, the highest priority for both levels + * is 0, so that a rule with priority 0 in group 8 is always matched after a + * rule with priority 8 in group 0. + * + * Although optional, applications are encouraged to group similar rules as + * much as possible to fully take advantage of hardware capabilities + * (e.g. optimized matching) and work around limitations (e.g. a single + * pattern type possibly allowed in a given group). + * + * Group and priority levels are arbitrary and up to the application, they + * do not need to be contiguous nor start from 0, however the maximum number + * varies between devices and may be affected by existing flow rules. + * + * If a packet is matched by several rules of a given group for a given + * priority level, the outcome is undefined. It can take any path, may be + * duplicated or even cause unrecoverable errors. + * + * Note that support for more than a single group and priority level is not + * guaranteed. + * + * Flow rules can apply to inbound and/or outbound traffic (ingress/egress). + * + * Several pattern items and actions are valid and can be used in both + * directions. Those valid for only one direction are described as such. + * + * At least one direction must be specified. + * + * Specifying both directions at once for a given rule is not recommended + * but may be valid in a few cases (e.g. shared counter). + */ +struct rte_flow_attr { + uint32_t group; /**< Priority group. */ + uint32_t priority; /**< Priority level within group. */ + uint32_t ingress:1; /**< Rule applies to ingress traffic. */ + uint32_t egress:1; /**< Rule applies to egress traffic. */ + uint32_t reserved:30; /**< Reserved, must be zero. */ +}; + +/** + * Matching pattern item types. + * + * Pattern items fall in two categories: + * + * - Matching protocol headers and packet data (ANY, RAW, ETH, VLAN, IPV4, + * IPV6, ICMP, UDP, TCP, SCTP, VXLAN and so on), usually associated with a + * specification structure. These must be stacked in the same order as the + * protocol layers to match, starting from the lowest. + * + * - Matching meta-data or affecting pattern processing (END, VOID, INVERT, + * PF, VF, PORT and so on), often without a specification structure. Since + * they do not match packet contents, these can be specified anywhere + * within item lists without affecting others. + * + * See the description of individual types for more information. Those + * marked with [META] fall into the second category. + */ +enum rte_flow_item_type { + /** + * [META] + * + * End marker for item lists. Prevents further processing of items, + * thereby ending the pattern. + * + * No associated specification structure. + */ + RTE_FLOW_ITEM_TYPE_END, + + /** + * [META] + * + * Used as a placeholder for convenience. It is ignored and simply + * discarded by PMDs. + * + * No associated specification structure. + */ + RTE_FLOW_ITEM_TYPE_VOID, + + /** + * [META] + * + * Inverted matching, i.e. process packets that do not match the + * pattern. + * + * No associated specification structure. + */ + RTE_FLOW_ITEM_TYPE_INVERT, + + /** + * Matches any protocol in place of the current layer, a single ANY + * may also stand for several protocol layers. + * + * See struct rte_flow_item_any. + */ + RTE_FLOW_ITEM_TYPE_ANY, + + /** + * [META] + * + * Matches packets addressed to the physical function of the device. + * + * If the underlying device function differs from the one that would + * normally receive the matched traffic, specifying this item + * prevents it from reaching that device unless the flow rule + * contains a PF action. Packets are not duplicated between device + * instances by default. + * + * No associated specification structure. + */ + RTE_FLOW_ITEM_TYPE_PF, + + /** + * [META] + * + * Matches packets addressed to a virtual function ID of the device. + * + * If the underlying device function differs from the one that would + * normally receive the matched traffic, specifying this item + * prevents it from reaching that device unless the flow rule + * contains a VF action. Packets are not duplicated between device + * instances by default. + * + * See struct rte_flow_item_vf. + */ + RTE_FLOW_ITEM_TYPE_VF, + + /** + * [META] + * + * Matches packets coming from the specified physical port of the + * underlying device. + * + * The first PORT item overrides the physical port normally + * associated with the specified DPDK input port (port_id). This + * item can be provided several times to match additional physical + * ports. + * + * See struct rte_flow_item_port. + */ + RTE_FLOW_ITEM_TYPE_PORT, + + /** + * Matches a byte string of a given length at a given offset. + * + * See struct rte_flow_item_raw. + */ + RTE_FLOW_ITEM_TYPE_RAW, + + /** + * Matches an Ethernet header. + * + * See struct rte_flow_item_eth. + */ + RTE_FLOW_ITEM_TYPE_ETH, + + /** + * Matches an 802.1Q/ad VLAN tag. + * + * See struct rte_flow_item_vlan. + */ + RTE_FLOW_ITEM_TYPE_VLAN, + + /** + * Matches an IPv4 header. + * + * See struct rte_flow_item_ipv4. + */ + RTE_FLOW_ITEM_TYPE_IPV4, + + /** + * Matches an IPv6 header. + * + * See struct rte_flow_item_ipv6. + */ + RTE_FLOW_ITEM_TYPE_IPV6, + + /** + * Matches an ICMP header. + * + * See struct rte_flow_item_icmp. + */ + RTE_FLOW_ITEM_TYPE_ICMP, + + /** + * Matches a UDP header. + * + * See struct rte_flow_item_udp. + */ + RTE_FLOW_ITEM_TYPE_UDP, + + /** + * Matches a TCP header. + * + * See struct rte_flow_item_tcp. + */ + RTE_FLOW_ITEM_TYPE_TCP, + + /** + * Matches a SCTP header. + * + * See struct rte_flow_item_sctp. + */ + RTE_FLOW_ITEM_TYPE_SCTP, + + /** + * Matches a VXLAN header. + * + * See struct rte_flow_item_vxlan. + */ + RTE_FLOW_ITEM_TYPE_VXLAN, + + /** + * Matches a E_TAG header. + * + * See struct rte_flow_item_e_tag. + */ + RTE_FLOW_ITEM_TYPE_E_TAG, + + /** + * Matches a NVGRE header. + * + * See struct rte_flow_item_nvgre. + */ + RTE_FLOW_ITEM_TYPE_NVGRE, + + /** + * Matches a MPLS header. + * + * See struct rte_flow_item_mpls. + */ + RTE_FLOW_ITEM_TYPE_MPLS, + + /** + * Matches a GRE header. + * + * See struct rte_flow_item_gre. + */ + RTE_FLOW_ITEM_TYPE_GRE, + + /** + * [META] + * + * Fuzzy pattern match, expect faster than default. + * + * This is for device that support fuzzy matching option. + * Usually a fuzzy matching is fast but the cost is accuracy. + * + * See struct rte_flow_item_fuzzy. + */ + RTE_FLOW_ITEM_TYPE_FUZZY, + + /** + * Matches a GTP header. + * + * Configure flow for GTP packets. + * + * See struct rte_flow_item_gtp. + */ + RTE_FLOW_ITEM_TYPE_GTP, + + /** + * Matches a GTP header. + * + * Configure flow for GTP-C packets. + * + * See struct rte_flow_item_gtp. + */ + RTE_FLOW_ITEM_TYPE_GTPC, + + /** + * Matches a GTP header. + * + * Configure flow for GTP-U packets. + * + * See struct rte_flow_item_gtp. + */ + RTE_FLOW_ITEM_TYPE_GTPU, + + /** + * Matches a ESP header. + * + * See struct rte_flow_item_esp. + */ + RTE_FLOW_ITEM_TYPE_ESP, +}; + +/** + * RTE_FLOW_ITEM_TYPE_ANY + * + * Matches any protocol in place of the current layer, a single ANY may also + * stand for several protocol layers. + * + * This is usually specified as the first pattern item when looking for a + * protocol anywhere in a packet. + * + * A zeroed mask stands for any number of layers. + */ +struct rte_flow_item_any { + uint32_t num; /**< Number of layers covered. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ANY. */ +#ifndef __cplusplus +static const struct rte_flow_item_any rte_flow_item_any_mask = { + .num = 0x00000000, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_VF + * + * Matches packets addressed to a virtual function ID of the device. + * + * If the underlying device function differs from the one that would + * normally receive the matched traffic, specifying this item prevents it + * from reaching that device unless the flow rule contains a VF + * action. Packets are not duplicated between device instances by default. + * + * - Likely to return an error or never match any traffic if this causes a + * VF device to match traffic addressed to a different VF. + * - Can be specified multiple times to match traffic addressed to several + * VF IDs. + * - Can be combined with a PF item to match both PF and VF traffic. + * + * A zeroed mask can be used to match any VF ID. + */ +struct rte_flow_item_vf { + uint32_t id; /**< Destination VF ID. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_VF. */ +#ifndef __cplusplus +static const struct rte_flow_item_vf rte_flow_item_vf_mask = { + .id = 0x00000000, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_PORT + * + * Matches packets coming from the specified physical port of the underlying + * device. + * + * The first PORT item overrides the physical port normally associated with + * the specified DPDK input port (port_id). This item can be provided + * several times to match additional physical ports. + * + * Note that physical ports are not necessarily tied to DPDK input ports + * (port_id) when those are not under DPDK control. Possible values are + * specific to each device, they are not necessarily indexed from zero and + * may not be contiguous. + * + * As a device property, the list of allowed values as well as the value + * associated with a port_id should be retrieved by other means. + * + * A zeroed mask can be used to match any port index. + */ +struct rte_flow_item_port { + uint32_t index; /**< Physical port index. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_PORT. */ +#ifndef __cplusplus +static const struct rte_flow_item_port rte_flow_item_port_mask = { + .index = 0x00000000, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_RAW + * + * Matches a byte string of a given length at a given offset. + * + * Offset is either absolute (using the start of the packet) or relative to + * the end of the previous matched item in the stack, in which case negative + * values are allowed. + * + * If search is enabled, offset is used as the starting point. The search + * area can be delimited by setting limit to a nonzero value, which is the + * maximum number of bytes after offset where the pattern may start. + * + * Matching a zero-length pattern is allowed, doing so resets the relative + * offset for subsequent items. + * + * This type does not support ranges (struct rte_flow_item.last). + */ +struct rte_flow_item_raw { + uint32_t relative:1; /**< Look for pattern after the previous item. */ + uint32_t search:1; /**< Search pattern from offset (see also limit). */ + uint32_t reserved:30; /**< Reserved, must be set to zero. */ + int32_t offset; /**< Absolute or relative offset for pattern. */ + uint16_t limit; /**< Search area limit for start of pattern. */ + uint16_t length; /**< Pattern length. */ + uint8_t pattern[]; /**< Byte string to look for. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_RAW. */ +#ifndef __cplusplus +static const struct rte_flow_item_raw rte_flow_item_raw_mask = { + .relative = 1, + .search = 1, + .reserved = 0x3fffffff, + .offset = 0xffffffff, + .limit = 0xffff, + .length = 0xffff, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ETH + * + * Matches an Ethernet header. + */ +struct rte_flow_item_eth { + struct ether_addr dst; /**< Destination MAC. */ + struct ether_addr src; /**< Source MAC. */ + rte_be16_t type; /**< EtherType. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ETH. */ +#ifndef __cplusplus +static const struct rte_flow_item_eth rte_flow_item_eth_mask = { + .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff", + .src.addr_bytes = "\xff\xff\xff\xff\xff\xff", + .type = RTE_BE16(0x0000), +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_VLAN + * + * Matches an 802.1Q/ad VLAN tag. + * + * This type normally follows either RTE_FLOW_ITEM_TYPE_ETH or + * RTE_FLOW_ITEM_TYPE_VLAN. + */ +struct rte_flow_item_vlan { + rte_be16_t tpid; /**< Tag protocol identifier. */ + rte_be16_t tci; /**< Tag control information. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_VLAN. */ +#ifndef __cplusplus +static const struct rte_flow_item_vlan rte_flow_item_vlan_mask = { + .tpid = RTE_BE16(0x0000), + .tci = RTE_BE16(0xffff), +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_IPV4 + * + * Matches an IPv4 header. + * + * Note: IPv4 options are handled by dedicated pattern items. + */ +struct rte_flow_item_ipv4 { + struct ipv4_hdr hdr; /**< IPv4 header definition. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_IPV4. */ +#ifndef __cplusplus +static const struct rte_flow_item_ipv4 rte_flow_item_ipv4_mask = { + .hdr = { + .src_addr = RTE_BE32(0xffffffff), + .dst_addr = RTE_BE32(0xffffffff), + }, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_IPV6. + * + * Matches an IPv6 header. + * + * Note: IPv6 options are handled by dedicated pattern items. + */ +struct rte_flow_item_ipv6 { + struct ipv6_hdr hdr; /**< IPv6 header definition. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */ +#ifndef __cplusplus +static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = { + .hdr = { + .src_addr = + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff", + .dst_addr = + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff", + }, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ICMP. + * + * Matches an ICMP header. + */ +struct rte_flow_item_icmp { + struct icmp_hdr hdr; /**< ICMP header definition. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP. */ +#ifndef __cplusplus +static const struct rte_flow_item_icmp rte_flow_item_icmp_mask = { + .hdr = { + .icmp_type = 0xff, + .icmp_code = 0xff, + }, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_UDP. + * + * Matches a UDP header. + */ +struct rte_flow_item_udp { + struct udp_hdr hdr; /**< UDP header definition. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_UDP. */ +#ifndef __cplusplus +static const struct rte_flow_item_udp rte_flow_item_udp_mask = { + .hdr = { + .src_port = RTE_BE16(0xffff), + .dst_port = RTE_BE16(0xffff), + }, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_TCP. + * + * Matches a TCP header. + */ +struct rte_flow_item_tcp { + struct tcp_hdr hdr; /**< TCP header definition. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_TCP. */ +#ifndef __cplusplus +static const struct rte_flow_item_tcp rte_flow_item_tcp_mask = { + .hdr = { + .src_port = RTE_BE16(0xffff), + .dst_port = RTE_BE16(0xffff), + }, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_SCTP. + * + * Matches a SCTP header. + */ +struct rte_flow_item_sctp { + struct sctp_hdr hdr; /**< SCTP header definition. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_SCTP. */ +#ifndef __cplusplus +static const struct rte_flow_item_sctp rte_flow_item_sctp_mask = { + .hdr = { + .src_port = RTE_BE16(0xffff), + .dst_port = RTE_BE16(0xffff), + }, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_VXLAN. + * + * Matches a VXLAN header (RFC 7348). + */ +struct rte_flow_item_vxlan { + uint8_t flags; /**< Normally 0x08 (I flag). */ + uint8_t rsvd0[3]; /**< Reserved, normally 0x000000. */ + uint8_t vni[3]; /**< VXLAN identifier. */ + uint8_t rsvd1; /**< Reserved, normally 0x00. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_VXLAN. */ +#ifndef __cplusplus +static const struct rte_flow_item_vxlan rte_flow_item_vxlan_mask = { + .vni = "\xff\xff\xff", +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_E_TAG. + * + * Matches a E-tag header. + */ +struct rte_flow_item_e_tag { + rte_be16_t tpid; /**< Tag protocol identifier (0x893F). */ + /** + * E-Tag control information (E-TCI). + * E-PCP (3b), E-DEI (1b), ingress E-CID base (12b). + */ + rte_be16_t epcp_edei_in_ecid_b; + /** Reserved (2b), GRP (2b), E-CID base (12b). */ + rte_be16_t rsvd_grp_ecid_b; + uint8_t in_ecid_e; /**< Ingress E-CID ext. */ + uint8_t ecid_e; /**< E-CID ext. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_E_TAG. */ +#ifndef __cplusplus +static const struct rte_flow_item_e_tag rte_flow_item_e_tag_mask = { + .rsvd_grp_ecid_b = RTE_BE16(0x3fff), +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_NVGRE. + * + * Matches a NVGRE header. + */ +struct rte_flow_item_nvgre { + /** + * Checksum (1b), undefined (1b), key bit (1b), sequence number (1b), + * reserved 0 (9b), version (3b). + * + * c_k_s_rsvd0_ver must have value 0x2000 according to RFC 7637. + */ + rte_be16_t c_k_s_rsvd0_ver; + rte_be16_t protocol; /**< Protocol type (0x6558). */ + uint8_t tni[3]; /**< Virtual subnet ID. */ + uint8_t flow_id; /**< Flow ID. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_NVGRE. */ +#ifndef __cplusplus +static const struct rte_flow_item_nvgre rte_flow_item_nvgre_mask = { + .tni = "\xff\xff\xff", +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_MPLS. + * + * Matches a MPLS header. + */ +struct rte_flow_item_mpls { + /** + * Label (20b), TC (3b), Bottom of Stack (1b). + */ + uint8_t label_tc_s[3]; + uint8_t ttl; /** Time-to-Live. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_MPLS. */ +#ifndef __cplusplus +static const struct rte_flow_item_mpls rte_flow_item_mpls_mask = { + .label_tc_s = "\xff\xff\xf0", +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_GRE. + * + * Matches a GRE header. + */ +struct rte_flow_item_gre { + /** + * Checksum (1b), reserved 0 (12b), version (3b). + * Refer to RFC 2784. + */ + rte_be16_t c_rsvd0_ver; + rte_be16_t protocol; /**< Protocol type. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_GRE. */ +#ifndef __cplusplus +static const struct rte_flow_item_gre rte_flow_item_gre_mask = { + .protocol = RTE_BE16(0xffff), +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_FUZZY + * + * Fuzzy pattern match, expect faster than default. + * + * This is for device that support fuzzy match option. + * Usually a fuzzy match is fast but the cost is accuracy. + * i.e. Signature Match only match pattern's hash value, but it is + * possible two different patterns have the same hash value. + * + * Matching accuracy level can be configure by threshold. + * Driver can divide the range of threshold and map to different + * accuracy levels that device support. + * + * Threshold 0 means perfect match (no fuzziness), while threshold + * 0xffffffff means fuzziest match. + */ +struct rte_flow_item_fuzzy { + uint32_t thresh; /**< Accuracy threshold. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_FUZZY. */ +#ifndef __cplusplus +static const struct rte_flow_item_fuzzy rte_flow_item_fuzzy_mask = { + .thresh = 0xffffffff, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_GTP. + * + * Matches a GTPv1 header. + */ +struct rte_flow_item_gtp { + /** + * Version (3b), protocol type (1b), reserved (1b), + * Extension header flag (1b), + * Sequence number flag (1b), + * N-PDU number flag (1b). + */ + uint8_t v_pt_rsv_flags; + uint8_t msg_type; /**< Message type. */ + rte_be16_t msg_len; /**< Message length. */ + rte_be32_t teid; /**< Tunnel endpoint identifier. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_GTP. */ +#ifndef __cplusplus +static const struct rte_flow_item_gtp rte_flow_item_gtp_mask = { + .teid = RTE_BE32(0xffffffff), +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ESP + * + * Matches an ESP header. + */ +struct rte_flow_item_esp { + struct esp_hdr hdr; /**< ESP header definition. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ESP. */ +#ifndef __cplusplus +static const struct rte_flow_item_esp rte_flow_item_esp_mask = { + .hdr = { + .spi = OVS_BE32_MAX, + }, +}; +#endif + +/** + * Matching pattern item definition. + * + * A pattern is formed by stacking items starting from the lowest protocol + * layer to match. This stacking restriction does not apply to meta items + * which can be placed anywhere in the stack without affecting the meaning + * of the resulting pattern. + * + * Patterns are terminated by END items. + * + * The spec field should be a valid pointer to a structure of the related + * item type. It may remain unspecified (NULL) in many cases to request + * broad (nonspecific) matching. In such cases, last and mask must also be + * set to NULL. + * + * Optionally, last can point to a structure of the same type to define an + * inclusive range. This is mostly supported by integer and address fields, + * may cause errors otherwise. Fields that do not support ranges must be set + * to 0 or to the same value as the corresponding fields in spec. + * + * Only the fields defined to nonzero values in the default masks (see + * rte_flow_item_{name}_mask constants) are considered relevant by + * default. This can be overridden by providing a mask structure of the + * same type with applicable bits set to one. It can also be used to + * partially filter out specific fields (e.g. as an alternate mean to match + * ranges of IP addresses). + * + * Mask is a simple bit-mask applied before interpreting the contents of + * spec and last, which may yield unexpected results if not used + * carefully. For example, if for an IPv4 address field, spec provides + * 10.1.2.3, last provides 10.3.4.5 and mask provides 255.255.0.0, the + * effective range becomes 10.1.0.0 to 10.3.255.255. + */ +struct rte_flow_item { + enum rte_flow_item_type type; /**< Item type. */ + const void *spec; /**< Pointer to item specification structure. */ + const void *last; /**< Defines an inclusive range (spec to last). */ + const void *mask; /**< Bit-mask applied to spec and last. */ +}; + +/** + * Action types. + * + * Each possible action is represented by a type. Some have associated + * configuration structures. Several actions combined in a list can be + * affected to a flow rule. That list is not ordered. + * + * They fall in three categories: + * + * - Terminating actions (such as QUEUE, DROP, RSS, PF, VF) that prevent + * processing matched packets by subsequent flow rules, unless overridden + * with PASSTHRU. + * + * - Non terminating actions (PASSTHRU, DUP) that leave matched packets up + * for additional processing by subsequent flow rules. + * + * - Other non terminating meta actions that do not affect the fate of + * packets (END, VOID, MARK, FLAG, COUNT). + * + * When several actions are combined in a flow rule, they should all have + * different types (e.g. dropping a packet twice is not possible). + * + * Only the last action of a given type is taken into account. PMDs still + * perform error checking on the entire list. + * + * Note that PASSTHRU is the only action able to override a terminating + * rule. + */ +enum rte_flow_action_type { + /** + * [META] + * + * End marker for action lists. Prevents further processing of + * actions, thereby ending the list. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_END, + + /** + * [META] + * + * Used as a placeholder for convenience. It is ignored and simply + * discarded by PMDs. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_VOID, + + /** + * Leaves packets up for additional processing by subsequent flow + * rules. This is the default when a rule does not contain a + * terminating action, but can be specified to force a rule to + * become non-terminating. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_PASSTHRU, + + /** + * [META] + * + * Attaches an integer value to packets and sets PKT_RX_FDIR and + * PKT_RX_FDIR_ID mbuf flags. + * + * See struct rte_flow_action_mark. + */ + RTE_FLOW_ACTION_TYPE_MARK, + + /** + * [META] + * + * Flags packets. Similar to MARK without a specific value; only + * sets the PKT_RX_FDIR mbuf flag. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_FLAG, + + /** + * Assigns packets to a given queue index. + * + * See struct rte_flow_action_queue. + */ + RTE_FLOW_ACTION_TYPE_QUEUE, + + /** + * Drops packets. + * + * PASSTHRU overrides this action if both are specified. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_DROP, + + /** + * [META] + * + * Enables counters for this rule. + * + * These counters can be retrieved and reset through rte_flow_query(), + * see struct rte_flow_query_count. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_COUNT, + + /** + * Duplicates packets to a given queue index. + * + * This is normally combined with QUEUE, however when used alone, it + * is actually similar to QUEUE + PASSTHRU. + * + * See struct rte_flow_action_dup. + */ + RTE_FLOW_ACTION_TYPE_DUP, + + /** + * Similar to QUEUE, except RSS is additionally performed on packets + * to spread them among several queues according to the provided + * parameters. + * + * See struct rte_flow_action_rss. + */ + RTE_FLOW_ACTION_TYPE_RSS, + + /** + * Redirects packets to the physical function (PF) of the current + * device. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_PF, + + /** + * Redirects packets to the virtual function (VF) of the current + * device with the specified ID. + * + * See struct rte_flow_action_vf. + */ + RTE_FLOW_ACTION_TYPE_VF, + + /** + * Traffic metering and policing (MTR). + * + * See struct rte_flow_action_meter. + * See file rte_mtr.h for MTR object configuration. + */ + RTE_FLOW_ACTION_TYPE_METER, + + /** + * Redirects packets to security engine of current device for security + * processing as specified by security session. + * + * See struct rte_flow_action_security. + */ + RTE_FLOW_ACTION_TYPE_SECURITY +}; + +/** + * RTE_FLOW_ACTION_TYPE_MARK + * + * Attaches an integer value to packets and sets PKT_RX_FDIR and + * PKT_RX_FDIR_ID mbuf flags. + * + * This value is arbitrary and application-defined. Maximum allowed value + * depends on the underlying implementation. It is returned in the + * hash.fdir.hi mbuf field. + */ +struct rte_flow_action_mark { + uint32_t id; /**< Integer value to return with packets. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_QUEUE + * + * Assign packets to a given queue index. + * + * Terminating by default. + */ +struct rte_flow_action_queue { + uint16_t index; /**< Queue index to use. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_COUNT (query) + * + * Query structure to retrieve and reset flow rule counters. + */ +struct rte_flow_query_count { + uint32_t reset:1; /**< Reset counters after query [in]. */ + uint32_t hits_set:1; /**< hits field is set [out]. */ + uint32_t bytes_set:1; /**< bytes field is set [out]. */ + uint32_t reserved:29; /**< Reserved, must be zero [in, out]. */ + uint64_t hits; /**< Number of hits for this rule [out]. */ + uint64_t bytes; /**< Number of bytes through this rule [out]. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_DUP + * + * Duplicates packets to a given queue index. + * + * This is normally combined with QUEUE, however when used alone, it is + * actually similar to QUEUE + PASSTHRU. + * + * Non-terminating by default. + */ +struct rte_flow_action_dup { + uint16_t index; /**< Queue index to duplicate packets to. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_RSS + * + * Similar to QUEUE, except RSS is additionally performed on packets to + * spread them among several queues according to the provided parameters. + * + * Note: RSS hash result is stored in the hash.rss mbuf field which overlaps + * hash.fdir.lo. Since the MARK action sets the hash.fdir.hi field only, + * both can be requested simultaneously. + * + * Terminating by default. + */ +struct rte_flow_action_rss { + const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */ + uint16_t num; /**< Number of entries in queue[]. */ + uint16_t queue[]; /**< Queues indices to use. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_VF + * + * Redirects packets to a virtual function (VF) of the current device. + * + * Packets matched by a VF pattern item can be redirected to their original + * VF ID instead of the specified one. This parameter may not be available + * and is not guaranteed to work properly if the VF part is matched by a + * prior flow rule or if packets are not addressed to a VF in the first + * place. + * + * Terminating by default. + */ +struct rte_flow_action_vf { + uint32_t original:1; /**< Use original VF ID if possible. */ + uint32_t reserved:31; /**< Reserved, must be zero. */ + uint32_t id; /**< VF ID to redirect packets to. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_METER + * + * Traffic metering and policing (MTR). + * + * Packets matched by items of this type can be either dropped or passed to the + * next item with their color set by the MTR object. + * + * Non-terminating by default. + */ +struct rte_flow_action_meter { + uint32_t mtr_id; /**< MTR object ID created with rte_mtr_create(). */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_SECURITY + * + * Perform the security action on flows matched by the pattern items + * according to the configuration of the security session. + * + * This action modifies the payload of matched flows. For INLINE_CRYPTO, the + * security protocol headers and IV are fully provided by the application as + * specified in the flow pattern. The payload of matching packets is + * encrypted on egress, and decrypted and authenticated on ingress. + * For INLINE_PROTOCOL, the security protocol is fully offloaded to HW, + * providing full encapsulation and decapsulation of packets in security + * protocols. The flow pattern specifies both the outer security header fields + * and the inner packet fields. The security session specified in the action + * must match the pattern parameters. + * + * The security session specified in the action must be created on the same + * port as the flow action that is being specified. + * + * The ingress/egress flow attribute should match that specified in the + * security session if the security session supports the definition of the + * direction. + * + * Multiple flows can be configured to use the same security session. + * + * Non-terminating by default. + */ +struct rte_flow_action_security { + void *security_session; /**< Pointer to security session structure. */ +}; + +/** + * Definition of a single action. + * + * A list of actions is terminated by a END action. + * + * For simple actions without a configuration structure, conf remains NULL. + */ +struct rte_flow_action { + enum rte_flow_action_type type; /**< Action type. */ + const void *conf; /**< Pointer to action configuration structure. */ +}; + +/** + * Opaque type returned after successfully creating a flow. + * + * This handle can be used to manage and query the related flow (e.g. to + * destroy it or retrieve counters). + */ +struct rte_flow; + +/** + * Verbose error types. + * + * Most of them provide the type of the object referenced by struct + * rte_flow_error.cause. + */ +enum rte_flow_error_type { + RTE_FLOW_ERROR_TYPE_NONE, /**< No error. */ + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, /**< Cause unspecified. */ + RTE_FLOW_ERROR_TYPE_HANDLE, /**< Flow rule (handle). */ + RTE_FLOW_ERROR_TYPE_ATTR_GROUP, /**< Group field. */ + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, /**< Priority field. */ + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, /**< Ingress field. */ + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, /**< Egress field. */ + RTE_FLOW_ERROR_TYPE_ATTR, /**< Attributes structure. */ + RTE_FLOW_ERROR_TYPE_ITEM_NUM, /**< Pattern length. */ + RTE_FLOW_ERROR_TYPE_ITEM, /**< Specific pattern item. */ + RTE_FLOW_ERROR_TYPE_ACTION_NUM, /**< Number of actions. */ + RTE_FLOW_ERROR_TYPE_ACTION, /**< Specific action. */ +}; + +/** + * Verbose error structure definition. + * + * This object is normally allocated by applications and set by PMDs, the + * message points to a constant string which does not need to be freed by + * the application, however its pointer can be considered valid only as long + * as its associated DPDK port remains configured. Closing the underlying + * device or unloading the PMD invalidates it. + * + * Both cause and message may be NULL regardless of the error type. + */ +struct rte_flow_error { + enum rte_flow_error_type type; /**< Cause field and error types. */ + const void *cause; /**< Object responsible for the error. */ + const char *message; /**< Human-readable error message. */ +}; + +/** + * Check whether a flow rule can be created on a given port. + * + * The flow rule is validated for correctness and whether it could be accepted + * by the device given sufficient resources. The rule is checked against the + * current device mode and queue configuration. The flow rule may also + * optionally be validated against existing flow rules and device resources. + * This function has no effect on the target device. + * + * The returned value is guaranteed to remain valid only as long as no + * successful calls to rte_flow_create() or rte_flow_destroy() are made in + * the meantime and no device parameter affecting flow rules in any way are + * modified, due to possible collisions or resource limitations (although in + * such cases EINVAL should not be returned). + * + * @param port_id + * Port identifier of Ethernet device. + * @param[in] attr + * Flow rule attributes. + * @param[in] pattern + * Pattern specification (list terminated by the END pattern item). + * @param[in] actions + * Associated actions (list terminated by the END action). + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * 0 if flow rule is valid and can be created. A negative errno value + * otherwise (rte_errno is also set), the following errors are defined: + * + * -ENOSYS: underlying device does not support this functionality. + * + * -EINVAL: unknown or invalid rule specification. + * + * -ENOTSUP: valid but unsupported rule specification (e.g. partial + * bit-masks are unsupported). + * + * -EEXIST: collision with an existing rule. Only returned if device + * supports flow rule collision checking and there was a flow rule + * collision. Not receiving this return code is no guarantee that creating + * the rule will not fail due to a collision. + * + * -ENOMEM: not enough memory to execute the function, or if the device + * supports resource validation, resource limitation on the device. + * + * -EBUSY: action cannot be performed due to busy device resources, may + * succeed if the affected queues or even the entire port are in a stopped + * state (see rte_eth_dev_rx_queue_stop() and rte_eth_dev_stop()). + */ +int +rte_flow_validate(uint16_t port_id, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow_error *error); + +/** + * Create a flow rule on a given port. + * + * @param port_id + * Port identifier of Ethernet device. + * @param[in] attr + * Flow rule attributes. + * @param[in] pattern + * Pattern specification (list terminated by the END pattern item). + * @param[in] actions + * Associated actions (list terminated by the END action). + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * A valid handle in case of success, NULL otherwise and rte_errno is set + * to the positive version of one of the error codes defined for + * rte_flow_validate(). + */ +struct rte_flow * +rte_flow_create(uint16_t port_id, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow_error *error); + +/** + * Destroy a flow rule on a given port. + * + * Failure to destroy a flow rule handle may occur when other flow rules + * depend on it, and destroying it would result in an inconsistent state. + * + * This function is only guaranteed to succeed if handles are destroyed in + * reverse order of their creation. + * + * @param port_id + * Port identifier of Ethernet device. + * @param flow + * Flow rule handle to destroy. + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +rte_flow_destroy(uint16_t port_id, + struct rte_flow *flow, + struct rte_flow_error *error); + +/** + * Destroy all flow rules associated with a port. + * + * In the unlikely event of failure, handles are still considered destroyed + * and no longer valid but the port must be assumed to be in an inconsistent + * state. + * + * @param port_id + * Port identifier of Ethernet device. + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +rte_flow_flush(uint16_t port_id, + struct rte_flow_error *error); + +/** + * Query an existing flow rule. + * + * This function allows retrieving flow-specific data such as counters. + * Data is gathered by special actions which must be present in the flow + * rule definition. + * + * \see RTE_FLOW_ACTION_TYPE_COUNT + * + * @param port_id + * Port identifier of Ethernet device. + * @param flow + * Flow rule handle to query. + * @param action + * Action type to query. + * @param[in, out] data + * Pointer to storage for the associated query data type. + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +rte_flow_query(uint16_t port_id, + struct rte_flow *flow, + enum rte_flow_action_type action, + void *data, + struct rte_flow_error *error); + +/** + * Restrict ingress traffic to the defined flow rules. + * + * Isolated mode guarantees that all ingress traffic comes from defined flow + * rules only (current and future). + * + * Besides making ingress more deterministic, it allows PMDs to safely reuse + * resources otherwise assigned to handle the remaining traffic, such as + * global RSS configuration settings, VLAN filters, MAC address entries, + * legacy filter API rules and so on in order to expand the set of possible + * flow rule types. + * + * Calling this function as soon as possible after device initialization, + * ideally before the first call to rte_eth_dev_configure(), is recommended + * to avoid possible failures due to conflicting settings. + * + * Once effective, leaving isolated mode may not be possible depending on + * PMD implementation. + * + * Additionally, the following functionality has no effect on the underlying + * port and may return errors such as ENOTSUP ("not supported"): + * + * - Toggling promiscuous mode. + * - Toggling allmulticast mode. + * - Configuring MAC addresses. + * - Configuring multicast addresses. + * - Configuring VLAN filters. + * - Configuring Rx filters through the legacy API (e.g. FDIR). + * - Configuring global RSS settings. + * + * @param port_id + * Port identifier of Ethernet device. + * @param set + * Nonzero to enter isolated mode, attempt to leave it otherwise. + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +rte_flow_isolate(uint16_t port_id, int set, struct rte_flow_error *error); + +/** + * Initialize flow error structure. + * + * @param[out] error + * Pointer to flow error structure (may be NULL). + * @param code + * Related error code (rte_errno). + * @param type + * Cause field and error types. + * @param cause + * Object responsible for the error. + * @param message + * Human-readable error message. + * + * @return + * Negative error code (errno value) and rte_errno is set. + */ +int +rte_flow_error_set(struct rte_flow_error *error, + int code, + enum rte_flow_error_type type, + const void *cause, + const char *message); + +/** + * Generic flow representation. + * + * This form is sufficient to describe an rte_flow independently from any + * PMD implementation and allows for replayability and identification. + */ +struct rte_flow_desc { + size_t size; /**< Allocated space including data[]. */ + struct rte_flow_attr attr; /**< Attributes. */ + struct rte_flow_item *items; /**< Items. */ + struct rte_flow_action *actions; /**< Actions. */ + uint8_t data[]; /**< Storage for items/actions. */ +}; + +/** + * Copy an rte_flow rule description. + * + * @param[in] fd + * Flow rule description. + * @param[in] len + * Total size of allocated data for the flow description. + * @param[in] attr + * Flow rule attributes. + * @param[in] items + * Pattern specification (list terminated by the END pattern item). + * @param[in] actions + * Associated actions (list terminated by the END action). + * + * @return + * If len is greater or equal to the size of the flow, the total size of the + * flow description and its data. + * If len is lower than the size of the flow, the number of bytes that would + * have been written to desc had it been sufficient. Nothing is written. + */ +size_t +rte_flow_copy(struct rte_flow_desc *fd, size_t len, + const struct rte_flow_attr *attr, + const struct rte_flow_item *items, + const struct rte_flow_action *actions); + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_FLOW_H_ */ diff --git a/include/sparse/rte_icmp.h b/include/sparse/rte_icmp.h new file mode 100644 index 000000000000..62e8b0400303 --- /dev/null +++ b/include/sparse/rte_icmp.h @@ -0,0 +1,106 @@ +/* BSD LICENSE + * + * Copyright(c) 2013 6WIND. + * + * 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 + * 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 + * distribution. + * * Neither the name of 6WIND S.A. 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 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)in.h 8.3 (Berkeley) 1/3/94 + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ + */ + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +#ifndef _RTE_ICMP_H_ +#define _RTE_ICMP_H_ + +/** + * @file + * + * ICMP-related defines + */ + +#include "openvswitch/types.h" +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * ICMP Header + */ +struct icmp_hdr { + uint8_t icmp_type; /* ICMP packet type. */ + uint8_t icmp_code; /* ICMP packet code. */ + ovs_be16 icmp_cksum; /* ICMP packet checksum. */ + ovs_be16 icmp_ident; /* ICMP packet identifier. */ + ovs_be16 icmp_seq_nb; /* ICMP packet sequence number. */ +} __attribute__((__packed__)); + +/* ICMP packet types */ +#define IP_ICMP_ECHO_REPLY 0 +#define IP_ICMP_ECHO_REQUEST 8 + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_ICMP_H_ */ diff --git a/include/sparse/rte_ip.h b/include/sparse/rte_ip.h new file mode 100644 index 000000000000..b171308c09cd --- /dev/null +++ b/include/sparse/rte_ip.h @@ -0,0 +1,490 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright 2014 6WIND S.A. + * All rights reserved. + * + * 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 + * 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 + * distribution. + * * 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 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)in.h 8.3 (Berkeley) 1/3/94 + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ + */ + +#ifndef _RTE_IP_H_ +#define _RTE_IP_H_ + +/** + * @file + * + * IP-related defines + */ + +#include <stdint.h> +#include <netinet/in.h> + +#include <rte_byteorder.h> +#include <rte_mbuf.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * IPv4 Header + */ +struct ipv4_hdr { + uint8_t version_ihl; /**< version and header length */ + uint8_t type_of_service; /**< type of service */ + ovs_be16 total_length; /**< length of packet */ + ovs_be16 packet_id; /**< packet ID */ + ovs_be16 fragment_offset; /**< fragmentation offset */ + uint8_t time_to_live; /**< time to live */ + uint8_t next_proto_id; /**< protocol ID */ + ovs_be16 hdr_checksum; /**< header checksum */ + ovs_be32 src_addr; /**< source address */ + ovs_be32 dst_addr; /**< destination address */ +} __attribute__((__packed__)); + +/** Create IPv4 address */ +#define IPv4(a,b,c,d) ((uint32_t)(((a) & 0xff) << 24) | \ + (((b) & 0xff) << 16) | \ + (((c) & 0xff) << 8) | \ + ((d) & 0xff)) + +/** Maximal IPv4 packet length (including a header) */ +#define IPV4_MAX_PKT_LEN 65535 + +/** Internet header length mask for version_ihl field */ +#define IPV4_HDR_IHL_MASK (0x0f) +/** + * Internet header length field multiplier (IHL field specifies overall header + * length in number of 4-byte words) + */ +#define IPV4_IHL_MULTIPLIER (4) + +/* Fragment Offset * Flags. */ +#define IPV4_HDR_DF_SHIFT 14 +#define IPV4_HDR_MF_SHIFT 13 +#define IPV4_HDR_FO_SHIFT 3 + +#define IPV4_HDR_DF_FLAG (1 << IPV4_HDR_DF_SHIFT) +#define IPV4_HDR_MF_FLAG (1 << IPV4_HDR_MF_SHIFT) + +#define IPV4_HDR_OFFSET_MASK ((1 << IPV4_HDR_MF_SHIFT) - 1) + +#define IPV4_HDR_OFFSET_UNITS 8 + +/* + * IPv4 address types + */ +#define IPV4_ANY ((uint32_t)0x00000000) /**< 0.0.0.0 */ +#define IPV4_LOOPBACK ((uint32_t)0x7f000001) /**< 127.0.0.1 */ +#define IPV4_BROADCAST ((uint32_t)0xe0000000) /**< 224.0.0.0 */ +#define IPV4_ALLHOSTS_GROUP ((uint32_t)0xe0000001) /**< 224.0.0.1 */ +#define IPV4_ALLRTRS_GROUP ((uint32_t)0xe0000002) /**< 224.0.0.2 */ +#define IPV4_MAX_LOCAL_GROUP ((uint32_t)0xe00000ff) /**< 224.0.0.255 */ + +/* + * IPv4 Multicast-related macros + */ +#define IPV4_MIN_MCAST IPv4(224, 0, 0, 0) /**< Minimal IPv4-multicast address */ +#define IPV4_MAX_MCAST IPv4(239, 255, 255, 255) /**< Maximum IPv4 multicast address */ + +#define IS_IPV4_MCAST(x) \ + ((x) >= IPV4_MIN_MCAST && (x) <= IPV4_MAX_MCAST) /**< check if IPv4 address is multicast */ + +/** + * @internal Calculate a sum of all words in the buffer. + * Helper routine for the rte_raw_cksum(). + * + * @param buf + * Pointer to the buffer. + * @param len + * Length of the buffer. + * @param sum + * Initial value of the sum. + * @return + * sum += Sum of all words in the buffer. + */ +static inline uint32_t +__rte_raw_cksum(const void *buf, size_t len, uint32_t sum) +{ + /* workaround gcc strict-aliasing warning */ + uintptr_t ptr = (uintptr_t)buf; + typedef uint16_t __attribute__((__may_alias__)) u16_p; + const u16_p *u16 = (const u16_p *)ptr; + + while (len >= (sizeof(*u16) * 4)) { + sum += u16[0]; + sum += u16[1]; + sum += u16[2]; + sum += u16[3]; + len -= sizeof(*u16) * 4; + u16 += 4; + } + while (len >= sizeof(*u16)) { + sum += *u16; + len -= sizeof(*u16); + u16 += 1; + } + + /* if length is in odd bytes */ + if (len == 1) + sum += *((const uint8_t *)u16); + + return sum; +} + +/** + * @internal Reduce a sum to the non-complemented checksum. + * Helper routine for the rte_raw_cksum(). + * + * @param sum + * Value of the sum. + * @return + * The non-complemented checksum. + */ +static inline uint16_t +__rte_raw_cksum_reduce(uint32_t sum) +{ + sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff); + sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff); + return (uint16_t)sum; +} + +/** + * Process the non-complemented checksum of a buffer. + * + * @param buf + * Pointer to the buffer. + * @param len + * Length of the buffer. + * @return + * The non-complemented checksum. + */ +static inline uint16_t +rte_raw_cksum(const void *buf, size_t len) +{ + uint32_t sum; + + sum = __rte_raw_cksum(buf, len, 0); + return __rte_raw_cksum_reduce(sum); +} + +/** + * Compute the raw (non complemented) checksum of a packet. + * + * @param m + * The pointer to the mbuf. + * @param off + * The offset in bytes to start the checksum. + * @param len + * The length in bytes of the data to checksum. + * @param cksum + * A pointer to the checksum, filled on success. + * @return + * 0 on success, -1 on error (bad length or offset). + */ +static inline int +rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, + uint16_t *cksum) +{ + const struct rte_mbuf *seg; + const char *buf; + uint32_t sum, tmp; + uint32_t seglen, done; + + /* easy case: all data in the first segment */ + if (off + len <= rte_pktmbuf_data_len(m)) { + *cksum = rte_raw_cksum(rte_pktmbuf_mtod_offset(m, + const char *, off), len); + return 0; + } + + if (unlikely(off + len > rte_pktmbuf_pkt_len(m))) + return -1; /* invalid params, return a dummy value */ + + /* else browse the segment to find offset */ + seglen = 0; + for (seg = m; seg != NULL; seg = seg->next) { + seglen = rte_pktmbuf_data_len(seg); + if (off < seglen) + break; + off -= seglen; + } + seglen -= off; + buf = rte_pktmbuf_mtod_offset(seg, const char *, off); + if (seglen >= len) { + /* all in one segment */ + *cksum = rte_raw_cksum(buf, len); + return 0; + } + + /* hard case: process checksum of several segments */ + sum = 0; + done = 0; + for (;;) { + tmp = __rte_raw_cksum(buf, seglen, 0); + if (done & 1) + tmp = rte_bswap16(tmp); + sum += tmp; + done += seglen; + if (done == len) + break; + seg = seg->next; + buf = rte_pktmbuf_mtod(seg, const char *); + seglen = rte_pktmbuf_data_len(seg); + if (seglen > len - done) + seglen = len - done; + } + + *cksum = __rte_raw_cksum_reduce(sum); + return 0; +} + +/** + * Process the IPv4 checksum of an IPv4 header. + * + * The checksum field must be set to 0 by the caller. + * + * @param ipv4_hdr + * The pointer to the contiguous IPv4 header. + * @return + * The complemented checksum to set in the IP packet. + */ +static inline uint16_t +rte_ipv4_cksum(const struct ipv4_hdr *ipv4_hdr) +{ + uint16_t cksum; + cksum = rte_raw_cksum(ipv4_hdr, sizeof(struct ipv4_hdr)); + return (cksum == 0xffff) ? cksum : ~cksum; +} + +/** + * Process the pseudo-header checksum of an IPv4 header. + * + * The checksum field must be set to 0 by the caller. + * + * Depending on the ol_flags, the pseudo-header checksum expected by the + * drivers is not the same. For instance, when TSO is enabled, the IP + * payload length must not be included in the packet. + * + * When ol_flags is 0, it computes the standard pseudo-header checksum. + * + * @param ipv4_hdr + * The pointer to the contiguous IPv4 header. + * @param ol_flags + * The ol_flags of the associated mbuf. + * @return + * The non-complemented checksum to set in the L4 header. + */ +static inline uint16_t +rte_ipv4_phdr_cksum(const struct ipv4_hdr *ipv4_hdr, uint64_t ol_flags) +{ + struct ipv4_psd_header { + ovs_be32 src_addr; /* IP address of source host. */ + ovs_be32 dst_addr; /* IP address of destination host. */ + uint8_t zero; /* zero. */ + uint8_t proto; /* L4 protocol type. */ + uint16_t len; /* L4 length. */ + } psd_hdr; + + psd_hdr.src_addr = ipv4_hdr->src_addr; + psd_hdr.dst_addr = ipv4_hdr->dst_addr; + psd_hdr.zero = 0; + psd_hdr.proto = ipv4_hdr->next_proto_id; + if (ol_flags & PKT_TX_TCP_SEG) { + psd_hdr.len = 0; + } else { + psd_hdr.len = rte_cpu_to_be_16( + (uint16_t)(rte_be_to_cpu_16(ipv4_hdr->total_length) + - sizeof(struct ipv4_hdr))); + } + return rte_raw_cksum(&psd_hdr, sizeof(psd_hdr)); +} + +/** + * Process the IPv4 UDP or TCP checksum. + * + * The IPv4 header should not contains options. The IP and layer 4 + * checksum must be set to 0 in the packet by the caller. + * + * @param ipv4_hdr + * The pointer to the contiguous IPv4 header. + * @param l4_hdr + * The pointer to the beginning of the L4 header. + * @return + * The complemented checksum to set in the IP packet. + */ +static inline uint16_t +rte_ipv4_udptcp_cksum(const struct ipv4_hdr *ipv4_hdr, const void *l4_hdr) +{ + uint32_t cksum; + uint32_t l4_len; + + l4_len = rte_be_to_cpu_16(ipv4_hdr->total_length) - + sizeof(struct ipv4_hdr); + + cksum = rte_raw_cksum(l4_hdr, l4_len); + cksum += rte_ipv4_phdr_cksum(ipv4_hdr, 0); + + cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff); + cksum = (~cksum) & 0xffff; + if (cksum == 0) + cksum = 0xffff; + + return cksum; +} + +/** + * IPv6 Header + */ +struct ipv6_hdr { + ovs_be32 vtc_flow; /**< IP version, traffic class & flow label. */ + ovs_be16 payload_len; /**< IP packet length - includes sizeof(ip_header). */ + uint8_t proto; /**< Protocol, next header. */ + uint8_t hop_limits; /**< Hop limits. */ + uint8_t src_addr[16]; /**< IP address of source host. */ + uint8_t dst_addr[16]; /**< IP address of destination host(s). */ +} __attribute__((__packed__)); + +/* IPv6 vtc_flow: IPv / TC / flow_label */ +#define IPV6_HDR_FL_SHIFT 0 +#define IPV6_HDR_TC_SHIFT 20 +#define IPV6_HDR_FL_MASK ((1u << IPV6_HDR_TC_SHIFT) - 1) +#define IPV6_HDR_TC_MASK (0xf << IPV6_HDR_TC_SHIFT) + +/** + * Process the pseudo-header checksum of an IPv6 header. + * + * Depending on the ol_flags, the pseudo-header checksum expected by the + * drivers is not the same. For instance, when TSO is enabled, the IPv6 + * payload length must not be included in the packet. + * + * When ol_flags is 0, it computes the standard pseudo-header checksum. + * + * @param ipv6_hdr + * The pointer to the contiguous IPv6 header. + * @param ol_flags + * The ol_flags of the associated mbuf. + * @return + * The non-complemented checksum to set in the L4 header. + */ +static inline uint16_t +rte_ipv6_phdr_cksum(const struct ipv6_hdr *ipv6_hdr, uint64_t ol_flags) +{ + uint32_t sum; + struct { + ovs_be32 len; /* L4 length. */ + ovs_be32 proto; /* L4 protocol - top 3 bytes must be zero */ + } psd_hdr; + + psd_hdr.proto = (ipv6_hdr->proto << 24); + if (ol_flags & PKT_TX_TCP_SEG) { + psd_hdr.len = 0; + } else { + psd_hdr.len = ipv6_hdr->payload_len; + } + + sum = __rte_raw_cksum(ipv6_hdr->src_addr, + sizeof(ipv6_hdr->src_addr) + sizeof(ipv6_hdr->dst_addr), + 0); + sum = __rte_raw_cksum(&psd_hdr, sizeof(psd_hdr), sum); + return __rte_raw_cksum_reduce(sum); +} + +/** + * Process the IPv6 UDP or TCP checksum. + * + * The IPv4 header should not contains options. The layer 4 checksum + * must be set to 0 in the packet by the caller. + * + * @param ipv6_hdr + * The pointer to the contiguous IPv6 header. + * @param l4_hdr + * The pointer to the beginning of the L4 header. + * @return + * The complemented checksum to set in the IP packet. + */ +static inline uint16_t +rte_ipv6_udptcp_cksum(const struct ipv6_hdr *ipv6_hdr, const void *l4_hdr) +{ + uint32_t cksum; + uint32_t l4_len; + + l4_len = rte_be_to_cpu_16(ipv6_hdr->payload_len); + + cksum = rte_raw_cksum(l4_hdr, l4_len); + cksum += rte_ipv6_phdr_cksum(ipv6_hdr, 0); + + cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff); + cksum = (~cksum) & 0xffff; + if (cksum == 0) + cksum = 0xffff; + + return cksum; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_IP_H_ */ diff --git a/include/sparse/rte_sctp.h b/include/sparse/rte_sctp.h new file mode 100644 index 000000000000..74287905dcc9 --- /dev/null +++ b/include/sparse/rte_sctp.h @@ -0,0 +1,103 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 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 + * are met: + * + * * 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 + * distribution. + * * 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 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)in.h 8.3 (Berkeley) 1/3/94 + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ + */ + +/** + * @file + * + * SCTP-related defines + */ + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +#ifndef _RTE_SCTP_H_ +#define _RTE_SCTP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/** + * SCTP Header + */ +struct sctp_hdr { + ovs_be16 src_port; /**< Source port. */ + ovs_be16 dst_port; /**< Destin port. */ + ovs_be32 tag; /**< Validation tag. */ + ovs_be32 cksum; /**< Checksum. */ +} __attribute__((__packed__)); + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_SCTP_H_ */ diff --git a/include/sparse/rte_tcp.h b/include/sparse/rte_tcp.h new file mode 100644 index 000000000000..729529695f34 --- /dev/null +++ b/include/sparse/rte_tcp.h @@ -0,0 +1,108 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 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 + * are met: + * + * * 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 + * distribution. + * * 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 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)in.h 8.3 (Berkeley) 1/3/94 + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ + */ + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +#ifndef _RTE_TCP_H_ +#define _RTE_TCP_H_ + +/** + * @file + * + * TCP-related defines + */ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * TCP Header + */ +struct tcp_hdr { + ovs_be16 src_port; /**< TCP source port. */ + ovs_be16 dst_port; /**< TCP destination port. */ + ovs_be32 sent_seq; /**< TX data sequence number. */ + ovs_be32 recv_ack; /**< RX data acknowledgement sequence number. */ + uint8_t data_off; /**< Data offset. */ + uint8_t tcp_flags; /**< TCP flags */ + ovs_be16 rx_win; /**< RX flow control window. */ + ovs_be16 cksum; /**< TCP checksum. */ + ovs_be16 tcp_urp; /**< TCP urgent pointer, if any. */ +} __attribute__((__packed__)); + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_TCP_H_ */ diff --git a/include/sparse/rte_udp.h b/include/sparse/rte_udp.h new file mode 100644 index 000000000000..8694a1dcfd3c --- /dev/null +++ b/include/sparse/rte_udp.h @@ -0,0 +1,103 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 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 + * are met: + * + * * 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 + * distribution. + * * 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 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)in.h 8.3 (Berkeley) 1/3/94 + * $FreeBSD: src/sys/netinet/in.h,v 1.82 2003/10/25 09:37:10 ume Exp $ + */ + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +#ifndef _RTE_UDP_H_ +#define _RTE_UDP_H_ + +/** + * @file + * + * UDP-related defines + */ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * UDP Header + */ +struct udp_hdr { + ovs_be16 src_port; /**< UDP source port. */ + ovs_be16 dst_port; /**< UDP destination port. */ + ovs_be16 dgram_len; /**< UDP datagram length */ + ovs_be16 dgram_cksum; /**< UDP datagram checksum */ +} __attribute__((__packed__)); + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_UDP_H_ */ diff --git a/include/sparse/xmmintrin.h b/include/sparse/xmmintrin.h new file mode 100644 index 000000000000..5d311b9117bc --- /dev/null +++ b/include/sparse/xmmintrin.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2015 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CHECKER__ +#error "Use this header only with sparse. It is not a correct implementation." +#endif + +/* sparse doesn't know about this builtin function yet. */ +#define __builtin_ia32_pause() (void) 0 + +/* Get actual <xmmintrin.h> definitions for us to annotate and build on. */ +#include_next <xmmintrin.h>
This allows netdev-dpdk.c to compile cleanly with sparse. Signed-off-by: Ben Pfaff <blp@ovn.org> --- Makefile.am | 2 +- build-aux/initial-tab-whitelist | 1 + include/sparse/automake.mk | 9 + include/sparse/rte_byteorder.h | 281 ++++++++ include/sparse/rte_esp.h | 65 ++ include/sparse/rte_flow.h | 1483 +++++++++++++++++++++++++++++++++++++++ include/sparse/rte_icmp.h | 106 +++ include/sparse/rte_ip.h | 490 +++++++++++++ include/sparse/rte_sctp.h | 103 +++ include/sparse/rte_tcp.h | 108 +++ include/sparse/rte_udp.h | 103 +++ include/sparse/xmmintrin.h | 24 + 12 files changed, 2774 insertions(+), 1 deletion(-) create mode 100644 include/sparse/rte_byteorder.h create mode 100644 include/sparse/rte_esp.h create mode 100644 include/sparse/rte_flow.h create mode 100644 include/sparse/rte_icmp.h create mode 100644 include/sparse/rte_ip.h create mode 100644 include/sparse/rte_sctp.h create mode 100644 include/sparse/rte_tcp.h create mode 100644 include/sparse/rte_udp.h create mode 100644 include/sparse/xmmintrin.h