2 * Copyright (c) 2015 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef TUN_METADATA_H
18 #define TUN_METADATA_H 1
22 #include "dynamic-string.h"
25 #include "openflow/openflow.h"
30 struct ofputil_geneve_table_mod
;
31 struct ofputil_geneve_table_reply
;
34 #define TUN_METADATA_NUM_OPTS 64
35 #define TUN_METADATA_TOT_OPT_SIZE 256
37 /* Tunnel option data, plus metadata to aid in their interpretation.
39 * 'opt_map' is indexed by type, that is, by the <i> in TUN_METADATA<i>, so
40 * that e.g. TUN_METADATA5 is present if 'opt_map & (1ULL << 5)' is nonzero.
41 * The actual data for TUN_METADATA5, if present, might be anywhere in 'opts'
42 * (not necessarily even contiguous), and finding it requires referring to
45 uint8_t opts
[TUN_METADATA_TOT_OPT_SIZE
]; /* Values from tunnel TLVs. */
46 uint64_t opt_map
; /* 1-bit for each present TLV. */
47 struct tun_table
*tab
; /* Types & lengths for 'opts' and 'opt_map'. */
48 uint8_t pad
[sizeof(uint64_t) - sizeof(struct tun_table
*)]; /* Make 8 bytes */
50 BUILD_ASSERT_DECL(sizeof(((struct tun_metadata
*)0)->opt_map
) * 8 >=
51 TUN_METADATA_NUM_OPTS
);
53 /* The location of an option can be stored either as a single offset/len
54 * pair (hopefully) or if the address space is fragmented then it is a
55 * linked list of these blocks. */
56 struct tun_metadata_loc_chain
{
57 struct tun_metadata_loc_chain
*next
;
58 uint8_t offset
; /* In bytes, from start of 'opts', multiple of 4. */
59 uint8_t len
; /* In bytes, multiple of 4. */
62 struct tun_metadata_loc
{
63 int len
; /* Sum of 'len' over elements in chain. */
64 struct tun_metadata_loc_chain c
;
67 /* Allocation of options inside struct match. This is important if we don't
68 * have access to a global allocation table - either because there isn't one
69 * (ovs-ofctl) or if we need to keep the allocation outside of packet
70 * processing context (Packet-In). These structures never have dynamically
71 * allocated memory because the address space is never fragmented. */
72 struct tun_metadata_allocation
{
73 struct tun_metadata_loc loc
[TUN_METADATA_NUM_OPTS
];
74 uint8_t alloc_offset
; /* Byte offset into 'opts', multiple of 4. */
75 bool valid
; /* Set to true after any allocation occurs. */
78 void tun_metadata_init(void);
80 enum ofperr
tun_metadata_table_mod(struct ofputil_geneve_table_mod
*);
81 void tun_metadata_table_request(struct ofputil_geneve_table_reply
*);
83 void tun_metadata_read(const struct tun_metadata
*,
84 const struct mf_field
*, union mf_value
*);
85 void tun_metadata_write(struct tun_metadata
*,
86 const struct mf_field
*, const union mf_value
*);
87 void tun_metadata_set_match(const struct mf_field
*,
88 const union mf_value
*value
,
89 const union mf_value
*mask
, struct match
*);
90 void tun_metadata_get_fmd(const struct tun_metadata
*,
91 struct match
*flow_metadata
);
93 int tun_metadata_from_geneve_nlattr(const struct nlattr
*attr
,
94 const struct nlattr
*flow_attrs
,
96 const struct tun_metadata
*flow_metadata
,
97 struct tun_metadata
*metadata
);
98 void tun_metadata_to_geneve_nlattr_flow(const struct tun_metadata
*flow
,
100 void tun_metadata_to_geneve_nlattr_mask(const struct ofpbuf
*key
,
101 const struct tun_metadata
*mask
,
102 const struct tun_metadata
*flow
,
104 void tun_metadata_to_nx_match(struct ofpbuf
*b
, enum ofp_version oxm
,
105 const struct match
*);
106 void tun_metadata_match_format(struct ds
*, const struct match
*);
108 #endif /* tun-metadata.h */