tunnel: Geneve TLV handling support for OpenFlow.
[cascardo/ovs.git] / lib / 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 TUN_METADATA_H
18 #define TUN_METADATA_H 1
19
20 #include <stdint.h>
21
22 #include "dynamic-string.h"
23 #include "netlink.h"
24 #include "ofpbuf.h"
25 #include "openflow/openflow.h"
26
27 struct match;
28 struct mf_field;
29 union mf_value;
30 struct ofputil_geneve_table_mod;
31 struct ofputil_geneve_table_reply;
32 struct tun_table;
33
34 #define TUN_METADATA_NUM_OPTS 64
35 #define TUN_METADATA_TOT_OPT_SIZE 256
36
37 /* Tunnel option data, plus metadata to aid in their interpretation.
38  *
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
43  * 'tab'. */
44 struct tun_metadata {
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 */
49 };
50 BUILD_ASSERT_DECL(sizeof(((struct tun_metadata *)0)->opt_map) * 8 >=
51                   TUN_METADATA_NUM_OPTS);
52
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. */
60 };
61
62 struct tun_metadata_loc {
63     int len;                    /* Sum of 'len' over elements in chain. */
64     struct tun_metadata_loc_chain c;
65 };
66
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. */
76 };
77
78 void tun_metadata_init(void);
79
80 enum ofperr tun_metadata_table_mod(struct ofputil_geneve_table_mod *);
81 void tun_metadata_table_request(struct ofputil_geneve_table_reply *);
82
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);
92
93 int tun_metadata_from_geneve_nlattr(const struct nlattr *attr,
94                                     const struct nlattr *flow_attrs,
95                                     size_t flow_attr_len,
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,
99                                         struct ofpbuf *);
100 void tun_metadata_to_geneve_nlattr_mask(const struct ofpbuf *key,
101                                         const struct tun_metadata *mask,
102                                         const struct tun_metadata *flow,
103                                         struct ofpbuf *);
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 *);
107
108 #endif /* tun-metadata.h */