2010-10-21 11:31:43 -07:00
|
|
|
|
/*
|
2013-06-19 16:58:44 -07:00
|
|
|
|
* Copyright (c) 2010, 2011, 2013 Nicira, Inc.
|
2010-10-21 11:31:43 -07:00
|
|
|
|
*
|
|
|
|
|
* 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 OPENVSWITCH_TYPES_H
|
|
|
|
|
#define OPENVSWITCH_TYPES_H 1
|
|
|
|
|
|
datapath-protocol: Use Linux kernel types directly.
We want datapath-protocol.h to be acceptable as a Linux kernel header, so
it must use Linux kernel types and must not have references to Open vSwitch
symbols or header files. This commit primarily makes that change to
datapath-protocol.h.
At the same time, at least for now we also want datapath-protocol.h to be
usable on non-Linux platforms, so we need some kind of compatiblity. Thus,
this commit also introduces a <linux/types.h> header file that defines the
necessary Linux kernel types on non-Linux platforms.
In turn, this requires openvswitch/types.h to use the Linux types directly
for ovs_be<N>; otherwise, sparse complains because now __be<N> and
ovs_be<N> are incompatible from its perspective, so this commit makes that
change too.
I don't have a non-Linux kernel platform readily available, so I only
tested the non-Linux part of the linux/types.h substitute by forcing that
case to be triggered with #if 0. It worked, except for errors in actual
Linux kernel headers included explicitly from OVS source files, so I think
it's likely to work in practice.
Bug #7559.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
2011-10-05 10:42:34 -07:00
|
|
|
|
#include <linux/types.h>
|
2011-02-05 13:14:47 -08:00
|
|
|
|
#include <sys/types.h>
|
2010-10-21 11:31:43 -07:00
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
|
|
#ifdef __CHECKER__
|
|
|
|
|
#define OVS_BITWISE __attribute__((bitwise))
|
2010-11-10 14:39:54 -08:00
|
|
|
|
#define OVS_FORCE __attribute__((force))
|
2010-10-21 11:31:43 -07:00
|
|
|
|
#else
|
|
|
|
|
#define OVS_BITWISE
|
2010-11-10 14:39:54 -08:00
|
|
|
|
#define OVS_FORCE
|
2010-10-21 11:31:43 -07:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* The ovs_be<N> types indicate that an object is in big-endian, not
|
|
|
|
|
* native-endian, byte order. They are otherwise equivalent to uint<N>_t.
|
|
|
|
|
*
|
datapath-protocol: Use Linux kernel types directly.
We want datapath-protocol.h to be acceptable as a Linux kernel header, so
it must use Linux kernel types and must not have references to Open vSwitch
symbols or header files. This commit primarily makes that change to
datapath-protocol.h.
At the same time, at least for now we also want datapath-protocol.h to be
usable on non-Linux platforms, so we need some kind of compatiblity. Thus,
this commit also introduces a <linux/types.h> header file that defines the
necessary Linux kernel types on non-Linux platforms.
In turn, this requires openvswitch/types.h to use the Linux types directly
for ovs_be<N>; otherwise, sparse complains because now __be<N> and
ovs_be<N> are incompatible from its perspective, so this commit makes that
change too.
I don't have a non-Linux kernel platform readily available, so I only
tested the non-Linux part of the linux/types.h substitute by forcing that
case to be triggered with #if 0. It worked, except for errors in actual
Linux kernel headers included explicitly from OVS source files, so I think
it's likely to work in practice.
Bug #7559.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
2011-10-05 10:42:34 -07:00
|
|
|
|
* We bootstrap these from the Linux __be<N> types. If we instead define our
|
|
|
|
|
* own independently then __be<N> and ovs_be<N> become mutually
|
|
|
|
|
* incompatible. */
|
|
|
|
|
typedef __be16 ovs_be16;
|
|
|
|
|
typedef __be32 ovs_be32;
|
|
|
|
|
typedef __be64 ovs_be64;
|
2013-06-27 15:27:15 -07:00
|
|
|
|
|
|
|
|
|
#define OVS_BE16_MAX ((OVS_FORCE ovs_be16) 0xffff)
|
|
|
|
|
#define OVS_BE32_MAX ((OVS_FORCE ovs_be32) 0xffffffff)
|
|
|
|
|
#define OVS_BE64_MAX ((OVS_FORCE ovs_be64) 0xffffffffffffffffULL)
|
2011-02-05 13:14:47 -08:00
|
|
|
|
|
packets: Do not assume that IPv4, TCP, or ARP headers are 32-bit aligned.
Ethernet headers are 14 bytes long, so when the beginning of such a header
is 32-bit aligned, the following data is misaligned. The usual trick to
fix that is to start the Ethernet header on an odd-numbered 16-bit
boundary. That trick works OK for Open vSwitch, but there are two
problems:
- OVS doesn't use that trick everywhere. Maybe it should, but it's
difficult to make sure that it does consistently because the CPUs
most commonly used with OVS don't care about misalignment, so we
only find problems when porting.
- Some protocols (GRE, VXLAN) don't use that trick, so in such a case
one can properly align the inner or outer L3/L4/L7 but not both. (OVS
userspace doesn't directly deal with such protocols yet, so this is
just future-proofing.)
- OpenFlow uses the alignment trick in a few places but not all of them.
This commit starts the adoption of what I hope will be a more robust way
to avoid misalignment problems and the resulting bus errors on RISC
architectures. Instead of trying to ensure that 32-bit quantities are
always aligned, we always read them as if they were misaligned. To ensure
that they are read this way, we change their types from 32-bit types to
pairs of 16-bit types. (I don't know of any protocols that offset the
next header by an odd number of bytes, so a 16-bit alignment assumption
seems OK.)
The same would be necessary for 64-bit types in protocol headers, but we
don't yet have any protocol definitions with 64-bit types.
IPv6 protocol headers need the same treatment, but for those we rely on
structs provided by system headers, so I'll leave them for an upcoming
patch.
Signed-off-by: Ben Pfaff <blp@nicira.com>
2013-08-15 10:47:39 -07:00
|
|
|
|
/* These types help with a few funny situations:
|
|
|
|
|
*
|
|
|
|
|
* - The Ethernet header is 14 bytes long, which misaligns everything after
|
|
|
|
|
* that. One can put 2 "shim" bytes before the Ethernet header, but this
|
|
|
|
|
* helps only if there is exactly one Ethernet header. If there are two,
|
|
|
|
|
* as with GRE and VXLAN (and if the inner header doesn't use this
|
|
|
|
|
* trick--GRE and VXLAN don't) then you have the choice of aligning the
|
|
|
|
|
* inner data or the outer data. So it seems better to treat 32-bit fields
|
|
|
|
|
* in protocol headers as aligned only on 16-bit boundaries.
|
|
|
|
|
*
|
|
|
|
|
* - ARP headers contain misaligned 32-bit fields.
|
|
|
|
|
*
|
|
|
|
|
* - Netlink and OpenFlow contain 64-bit values that are only guaranteed to
|
|
|
|
|
* be aligned on 32-bit boundaries.
|
2011-02-05 13:14:47 -08:00
|
|
|
|
*
|
|
|
|
|
* lib/unaligned.h has helper functions for accessing these. */
|
|
|
|
|
|
packets: Do not assume that IPv4, TCP, or ARP headers are 32-bit aligned.
Ethernet headers are 14 bytes long, so when the beginning of such a header
is 32-bit aligned, the following data is misaligned. The usual trick to
fix that is to start the Ethernet header on an odd-numbered 16-bit
boundary. That trick works OK for Open vSwitch, but there are two
problems:
- OVS doesn't use that trick everywhere. Maybe it should, but it's
difficult to make sure that it does consistently because the CPUs
most commonly used with OVS don't care about misalignment, so we
only find problems when porting.
- Some protocols (GRE, VXLAN) don't use that trick, so in such a case
one can properly align the inner or outer L3/L4/L7 but not both. (OVS
userspace doesn't directly deal with such protocols yet, so this is
just future-proofing.)
- OpenFlow uses the alignment trick in a few places but not all of them.
This commit starts the adoption of what I hope will be a more robust way
to avoid misalignment problems and the resulting bus errors on RISC
architectures. Instead of trying to ensure that 32-bit quantities are
always aligned, we always read them as if they were misaligned. To ensure
that they are read this way, we change their types from 32-bit types to
pairs of 16-bit types. (I don't know of any protocols that offset the
next header by an odd number of bytes, so a 16-bit alignment assumption
seems OK.)
The same would be necessary for 64-bit types in protocol headers, but we
don't yet have any protocol definitions with 64-bit types.
IPv6 protocol headers need the same treatment, but for those we rely on
structs provided by system headers, so I'll leave them for an upcoming
patch.
Signed-off-by: Ben Pfaff <blp@nicira.com>
2013-08-15 10:47:39 -07:00
|
|
|
|
/* A 32-bit value, in host byte order, that is only aligned on a 16-bit
|
|
|
|
|
* boundary. */
|
|
|
|
|
typedef struct {
|
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
|
|
|
uint16_t hi, lo;
|
|
|
|
|
#else
|
|
|
|
|
uint16_t lo, hi;
|
|
|
|
|
#endif
|
|
|
|
|
} ovs_16aligned_u32;
|
|
|
|
|
|
|
|
|
|
/* A 32-bit value, in network byte order, that is only aligned on a 16-bit
|
|
|
|
|
* boundary. */
|
|
|
|
|
typedef struct {
|
|
|
|
|
ovs_be16 hi, lo;
|
|
|
|
|
} ovs_16aligned_be32;
|
|
|
|
|
|
2011-02-05 13:14:47 -08:00
|
|
|
|
/* A 64-bit value, in host byte order, that is only aligned on a 32-bit
|
|
|
|
|
* boundary. */
|
|
|
|
|
typedef struct {
|
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
2012-03-23 11:43:54 -07:00
|
|
|
|
uint32_t hi, lo;
|
2011-02-05 13:14:47 -08:00
|
|
|
|
#else
|
2012-03-23 11:43:54 -07:00
|
|
|
|
uint32_t lo, hi;
|
2011-02-05 13:14:47 -08:00
|
|
|
|
#endif
|
|
|
|
|
} ovs_32aligned_u64;
|
|
|
|
|
|
|
|
|
|
/* A 64-bit value, in network byte order, that is only aligned on a 32-bit
|
|
|
|
|
* boundary. */
|
|
|
|
|
typedef struct {
|
2012-03-23 11:43:54 -07:00
|
|
|
|
ovs_be32 hi, lo;
|
2011-02-05 13:14:47 -08:00
|
|
|
|
} ovs_32aligned_be64;
|
2010-10-21 11:31:43 -07:00
|
|
|
|
|
2013-06-19 16:58:44 -07:00
|
|
|
|
/* ofp_port_t represents the port number of a OpenFlow switch.
|
|
|
|
|
* odp_port_t represents the port number on the datapath.
|
|
|
|
|
* ofp11_port_t represents the OpenFlow-1.1 port number. */
|
|
|
|
|
typedef uint16_t OVS_BITWISE ofp_port_t;
|
|
|
|
|
typedef uint32_t OVS_BITWISE odp_port_t;
|
|
|
|
|
typedef uint32_t OVS_BITWISE ofp11_port_t;
|
|
|
|
|
|
|
|
|
|
/* Macro functions that cast int types to ofp/odp/ofp11 types. */
|
|
|
|
|
#define OFP_PORT_C(X) ((OVS_FORCE ofp_port_t) (X))
|
|
|
|
|
#define ODP_PORT_C(X) ((OVS_FORCE odp_port_t) (X))
|
|
|
|
|
#define OFP11_PORT_C(X) ((OVS_FORCE ofp11_port_t) (X))
|
|
|
|
|
|
2010-10-21 11:31:43 -07:00
|
|
|
|
#endif /* openvswitch/types.h */
|