Skip to content

Commit

Permalink
tun-metadata: Break header file into public and private parts.
Browse files Browse the repository at this point in the history
Public (struct definitions and some prototypes) go in
include/openvswitch.

Signed-off-by: Ben Warren <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
Ben Warren authored and blp committed Mar 30, 2016
1 parent 3467a4d commit 841b052
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 79 deletions.
1 change: 1 addition & 0 deletions include/openvswitch/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ openvswitchinclude_HEADERS = \
include/openvswitch/ofp-parse.h \
include/openvswitch/thread.h \
include/openvswitch/token-bucket.h \
include/openvswitch/tun-metadata.h \
include/openvswitch/types.h \
include/openvswitch/util.h \
include/openvswitch/version.h \
Expand Down
101 changes: 101 additions & 0 deletions include/openvswitch/tun-metadata.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* 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 OPENVSWITCH_TUN_METADATA_H
#define OPENVSWITCH_TUN_METADATA_H 1

#include "openvswitch/geneve.h"

#define TUN_METADATA_NUM_OPTS 64
#define TUN_METADATA_TOT_OPT_SIZE 256

/* Tunnel option data, plus metadata to aid in their interpretation.
*
* The option data exists in two forms and is interpreted differently depending
* on whether FLOW_TNL_F_UDPIF is set in struct flow_tnl flags:
*
* When FLOW_TNL_F_UDPIF is set, the tunnel metadata is in "userspace datapath
* format". This is typically used for fast-path packet processing to avoid
* the cost of translating options and in situations where we need to maintain
* tunnel metadata exactly as it came in. In this case 'opts.gnv' is raw
* packet data from the tunnel header and 'present.len' indicates the length
* of the data stored there. In these situations, 'tab' is NULL.
*
* In all other cases, we are doing flow-based processing (such as during
* upcalls). FLOW_TNL_F_UDPIF is not set and options are reordered into
* pre-allocated locations. 'present.map' is indexed by type, that is, by the
* <i> in TUN_METADATA<i>, so that e.g. TUN_METADATA5 is present if
* 'present.map & (1ULL << 5)' is nonzero. The actual data for TUN_METADATA5,
* if present, might be anywhere in 'opts.u8' (not necessarily even contiguous),
* and finding it requires referring to 'tab', if set, or the global metadata
* table. */
struct tun_metadata {
union { /* Valid members of 'opts'. When 'opts' is sorted into known types,
* 'map' is used. When 'opts' is raw packet data, 'len' is used. */
uint64_t map; /* 1-bit for each present TLV. */
uint8_t len; /* Length of data in 'opts'. */
} present;
struct tun_table *tab; /* Types & lengths for 'opts' and 'opt_map'. */

#if UINTPTR_MAX == UINT32_MAX
uint8_t pad[4]; /* Pad to 64-bit boundary. */
#endif

union {
uint8_t u8[TUN_METADATA_TOT_OPT_SIZE]; /* Values from tunnel TLVs. */
struct geneve_opt gnv[TLV_TOT_OPT_SIZE / sizeof(struct geneve_opt)];
} opts;
};
BUILD_ASSERT_DECL(offsetof(struct tun_metadata, opts) % 8 == 0);
BUILD_ASSERT_DECL(sizeof(((struct tun_metadata *)0)->present.map) * 8 >=
TUN_METADATA_NUM_OPTS);

/* The location of an option can be stored either as a single offset/len
* pair (hopefully) or if the address space is fragmented then it is a
* linked list of these blocks. */
struct tun_metadata_loc_chain {
struct tun_metadata_loc_chain *next;
int offset; /* In bytes, from start of 'opts', multiple of 4. */
int len; /* In bytes, multiple of 4. */
};

struct tun_metadata_loc {
int len; /* Sum of 'len' over elements in chain. */
struct tun_metadata_loc_chain c;
};

/* Bookkeeping information to keep track of an option that was allocated
* inside struct match. */
struct tun_metadata_match_entry {
struct tun_metadata_loc loc; /* Allocated position. */
bool masked; /* Source value had a mask. Otherwise we can't tell if the
* entire field was exact matched or only the portion that
* is the same size as the value. */
};

/* Allocation of options inside struct match. This is important if we don't
* have access to a global allocation table - either because there isn't one
* (ovs-ofctl) or if we need to keep the allocation outside of packet
* processing context (Packet-In). These structures never have dynamically
* allocated memory because the address space is never fragmented. */
struct tun_metadata_allocation {
struct tun_metadata_match_entry entry[TUN_METADATA_NUM_OPTS];
int alloc_offset; /* Byte offset into 'opts', multiple of 4. */
bool valid; /* Set to true after any allocation occurs. */
};


#endif /* tun-metadata.h */
80 changes: 1 addition & 79 deletions lib/tun-metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "netlink.h"
#include "openvswitch/ofpbuf.h"
#include "openflow/openflow.h"
#include "openvswitch/geneve.h"
#include "openvswitch/tun-metadata.h"

struct flow_tnl;
struct match;
Expand All @@ -33,84 +33,6 @@ struct ofputil_tlv_table_mod;
struct ofputil_tlv_table_reply;
struct tun_table;

#define TUN_METADATA_NUM_OPTS 64
#define TUN_METADATA_TOT_OPT_SIZE 256

/* Tunnel option data, plus metadata to aid in their interpretation.
*
* The option data exists in two forms and is interpreted differently depending
* on whether FLOW_TNL_F_UDPIF is set in struct flow_tnl flags:
*
* When FLOW_TNL_F_UDPIF is set, the tunnel metadata is in "userspace datapath
* format". This is typically used for fast-path packet processing to avoid
* the cost of translating options and in situations where we need to maintain
* tunnel metadata exactly as it came in. In this case 'opts.gnv' is raw
* packet data from the tunnel header and 'present.len' indicates the length
* of the data stored there. In these situations, 'tab' is NULL.
*
* In all other cases, we are doing flow-based processing (such as during
* upcalls). FLOW_TNL_F_UDPIF is not set and options are reordered into
* pre-allocated locations. 'present.map' is indexed by type, that is, by the
* <i> in TUN_METADATA<i>, so that e.g. TUN_METADATA5 is present if
* 'present.map & (1ULL << 5)' is nonzero. The actual data for TUN_METADATA5,
* if present, might be anywhere in 'opts.u8' (not necessarily even contiguous),
* and finding it requires referring to 'tab', if set, or the global metadata
* table. */
struct tun_metadata {
union { /* Valid members of 'opts'. When 'opts' is sorted into known types,
* 'map' is used. When 'opts' is raw packet data, 'len' is used. */
uint64_t map; /* 1-bit for each present TLV. */
uint8_t len; /* Length of data in 'opts'. */
} present;
struct tun_table *tab; /* Types & lengths for 'opts' and 'opt_map'. */

#if UINTPTR_MAX == UINT32_MAX
uint8_t pad[4]; /* Pad to 64-bit boundary. */
#endif

union {
uint8_t u8[TUN_METADATA_TOT_OPT_SIZE]; /* Values from tunnel TLVs. */
struct geneve_opt gnv[TLV_TOT_OPT_SIZE / sizeof(struct geneve_opt)];
} opts;
};
BUILD_ASSERT_DECL(offsetof(struct tun_metadata, opts) % 8 == 0);
BUILD_ASSERT_DECL(sizeof(((struct tun_metadata *)0)->present.map) * 8 >=
TUN_METADATA_NUM_OPTS);

/* The location of an option can be stored either as a single offset/len
* pair (hopefully) or if the address space is fragmented then it is a
* linked list of these blocks. */
struct tun_metadata_loc_chain {
struct tun_metadata_loc_chain *next;
int offset; /* In bytes, from start of 'opts', multiple of 4. */
int len; /* In bytes, multiple of 4. */
};

struct tun_metadata_loc {
int len; /* Sum of 'len' over elements in chain. */
struct tun_metadata_loc_chain c;
};

/* Bookkeeping information to keep track of an option that was allocated
* inside struct match. */
struct tun_metadata_match_entry {
struct tun_metadata_loc loc; /* Allocated position. */
bool masked; /* Source value had a mask. Otherwise we can't tell if the
* entire field was exact matched or only the portion that
* is the same size as the value. */
};

/* Allocation of options inside struct match. This is important if we don't
* have access to a global allocation table - either because there isn't one
* (ovs-ofctl) or if we need to keep the allocation outside of packet
* processing context (Packet-In). These structures never have dynamically
* allocated memory because the address space is never fragmented. */
struct tun_metadata_allocation {
struct tun_metadata_match_entry entry[TUN_METADATA_NUM_OPTS];
int alloc_offset; /* Byte offset into 'opts', multiple of 4. */
bool valid; /* Set to true after any allocation occurs. */
};

void tun_metadata_init(void);

enum ofperr tun_metadata_table_mod(struct ofputil_tlv_table_mod *);
Expand Down

0 comments on commit 841b052

Please sign in to comment.