]> git.proxmox.com Git - mirror_ovs.git/blob - include/openvswitch/tun-metadata.h
Misc cleanup with "util.h" header files
[mirror_ovs.git] / include / openvswitch / tun-metadata.h
1 /*
2 * Copyright (c) 2015 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef OPENVSWITCH_TUN_METADATA_H
18 #define OPENVSWITCH_TUN_METADATA_H 1
19
20 #include "openvswitch/geneve.h"
21
22 #define TUN_METADATA_NUM_OPTS 64
23 #define TUN_METADATA_TOT_OPT_SIZE 256
24
25 /* Tunnel option data, plus metadata to aid in their interpretation.
26 *
27 * The option data exists in two forms and is interpreted differently depending
28 * on whether FLOW_TNL_F_UDPIF is set in struct flow_tnl flags:
29 *
30 * When FLOW_TNL_F_UDPIF is set, the tunnel metadata is in "userspace datapath
31 * format". This is typically used for fast-path packet processing to avoid
32 * the cost of translating options and in situations where we need to maintain
33 * tunnel metadata exactly as it came in. In this case 'opts.gnv' is raw
34 * packet data from the tunnel header and 'present.len' indicates the length
35 * of the data stored there. In these situations, 'tab' is NULL.
36 *
37 * In all other cases, we are doing flow-based processing (such as during
38 * upcalls). FLOW_TNL_F_UDPIF is not set and options are reordered into
39 * pre-allocated locations. 'present.map' is indexed by type, that is, by the
40 * <i> in TUN_METADATA<i>, so that e.g. TUN_METADATA5 is present if
41 * 'present.map & (1ULL << 5)' is nonzero. The actual data for TUN_METADATA5,
42 * if present, might be anywhere in 'opts.u8' (not necessarily even contiguous),
43 * and finding it requires referring to 'tab', if set, or the global metadata
44 * table. */
45 struct tun_metadata {
46 union { /* Valid members of 'opts'. When 'opts' is sorted into known types,
47 * 'map' is used. When 'opts' is raw packet data, 'len' is used. */
48 uint64_t map; /* 1-bit for each present TLV. */
49 uint8_t len; /* Length of data in 'opts'. */
50 } present;
51 struct tun_table *tab; /* Types & lengths for 'opts' and 'opt_map'. */
52
53 #if UINTPTR_MAX == UINT32_MAX
54 uint8_t pad[4]; /* Pad to 64-bit boundary. */
55 #endif
56
57 union {
58 uint8_t u8[TUN_METADATA_TOT_OPT_SIZE]; /* Values from tunnel TLVs. */
59 struct geneve_opt gnv[TLV_TOT_OPT_SIZE / sizeof(struct geneve_opt)];
60 } opts;
61 };
62 BUILD_ASSERT_DECL(offsetof(struct tun_metadata, opts) % 8 == 0);
63 BUILD_ASSERT_DECL(sizeof(((struct tun_metadata *)0)->present.map) * 8 >=
64 TUN_METADATA_NUM_OPTS);
65
66 /* The location of an option can be stored either as a single offset/len
67 * pair (hopefully) or if the address space is fragmented then it is a
68 * linked list of these blocks. */
69 struct tun_metadata_loc_chain {
70 struct tun_metadata_loc_chain *next;
71 int offset; /* In bytes, from start of 'opts', multiple of 4. */
72 int len; /* In bytes, multiple of 4. */
73 };
74
75 struct tun_metadata_loc {
76 int len; /* Sum of 'len' over elements in chain. */
77 struct tun_metadata_loc_chain c;
78 };
79
80 /* Bookkeeping information to keep track of an option that was allocated
81 * inside struct match. */
82 struct tun_metadata_match_entry {
83 struct tun_metadata_loc loc; /* Allocated position. */
84 bool masked; /* Source value had a mask. Otherwise we can't tell if the
85 * entire field was exact matched or only the portion that
86 * is the same size as the value. */
87 };
88
89 /* Allocation of options inside struct match. This is important if we don't
90 * have access to a global allocation table - either because there isn't one
91 * (ovs-ofctl) or if we need to keep the allocation outside of packet
92 * processing context (Packet-In). These structures never have dynamically
93 * allocated memory because the address space is never fragmented. */
94 struct tun_metadata_allocation {
95 struct tun_metadata_match_entry entry[TUN_METADATA_NUM_OPTS];
96 int alloc_offset; /* Byte offset into 'opts', multiple of 4. */
97 bool valid; /* Set to true after any allocation occurs. */
98 };
99
100
101 #endif /* tun-metadata.h */