netdev-dpdk: fix mbuf leaks
[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 "geneve.h"
24 #include "netlink.h"
25 #include "ofpbuf.h"
26 #include "openflow/openflow.h"
27
28 struct flow_tnl;
29 struct match;
30 struct mf_field;
31 union mf_value;
32 struct ofputil_tlv_table_mod;
33 struct ofputil_tlv_table_reply;
34 struct tun_table;
35
36 #define TUN_METADATA_NUM_OPTS 64
37 #define TUN_METADATA_TOT_OPT_SIZE 256
38
39 /* Tunnel option data, plus metadata to aid in their interpretation.
40  *
41  * The option data exists in two forms and is interpreted differently depending
42  * on whether FLOW_TNL_F_UDPIF is set in struct flow_tnl flags:
43  *
44  * When FLOW_TNL_F_UDPIF is set, the tunnel metadata is in "userspace datapath
45  * format". This is typically used for fast-path packet processing to avoid
46  * the cost of translating options and in situations where we need to maintain
47  * tunnel metadata exactly as it came in. In this case 'opts.gnv' is raw
48  * packet data from the tunnel header and 'present.len' indicates the length
49  * of the data stored there. In these situations, 'tab' is NULL.
50  *
51  * In all other cases, we are doing flow-based processing (such as during
52  * upcalls). FLOW_TNL_F_UDPIF is not set and options are reordered into
53  * pre-allocated locations. 'present.map' is indexed by type, that is, by the
54  * <i> in TUN_METADATA<i>, so that e.g. TUN_METADATA5 is present if
55  * 'present.map & (1ULL << 5)' is nonzero. The actual data for TUN_METADATA5,
56  * if present, might be anywhere in 'opts.u8' (not necessarily even contiguous),
57  * and finding it requires referring to 'tab', if set, or the global metadata
58  * table. */
59 struct tun_metadata {
60     union { /* Valid members of 'opts'. When 'opts' is sorted into known types,
61              * 'map' is used. When 'opts' is raw packet data, 'len' is used. */
62         uint64_t map;                      /* 1-bit for each present TLV. */
63         uint8_t len;                       /* Length of data in 'opts'. */
64     } present;
65     struct tun_table *tab;      /* Types & lengths for 'opts' and 'opt_map'. */
66
67 #if UINTPTR_MAX == UINT32_MAX
68     uint8_t pad[4];             /* Pad to 64-bit boundary. */
69 #endif
70
71     union {
72         uint8_t u8[TUN_METADATA_TOT_OPT_SIZE]; /* Values from tunnel TLVs. */
73         struct geneve_opt gnv[TLV_TOT_OPT_SIZE / sizeof(struct geneve_opt)];
74     } opts;
75 };
76 BUILD_ASSERT_DECL(offsetof(struct tun_metadata, opts) % 8 == 0);
77 BUILD_ASSERT_DECL(sizeof(((struct tun_metadata *)0)->present.map) * 8 >=
78                   TUN_METADATA_NUM_OPTS);
79
80 /* The location of an option can be stored either as a single offset/len
81  * pair (hopefully) or if the address space is fragmented then it is a
82  * linked list of these blocks. */
83 struct tun_metadata_loc_chain {
84     struct tun_metadata_loc_chain *next;
85     int offset;       /* In bytes, from start of 'opts', multiple of 4.  */
86     int len;          /* In bytes, multiple of 4. */
87 };
88
89 struct tun_metadata_loc {
90     int len;                    /* Sum of 'len' over elements in chain. */
91     struct tun_metadata_loc_chain c;
92 };
93
94 /* Bookkeeping information to keep track of an option that was allocated
95  * inside struct match. */
96 struct tun_metadata_match_entry {
97     struct tun_metadata_loc loc; /* Allocated position. */
98     bool masked; /* Source value had a mask. Otherwise we can't tell if the
99                   * entire field was exact matched or only the portion that
100                   * is the same size as the value. */
101 };
102
103 /* Allocation of options inside struct match.  This is important if we don't
104  * have access to a global allocation table - either because there isn't one
105  * (ovs-ofctl) or if we need to keep the allocation outside of packet
106  * processing context (Packet-In). These structures never have dynamically
107  * allocated memory because the address space is never fragmented. */
108 struct tun_metadata_allocation {
109     struct tun_metadata_match_entry entry[TUN_METADATA_NUM_OPTS];
110     int alloc_offset;           /* Byte offset into 'opts', multiple of 4.  */
111     bool valid;                 /* Set to true after any allocation occurs. */
112 };
113
114 void tun_metadata_init(void);
115
116 enum ofperr tun_metadata_table_mod(struct ofputil_tlv_table_mod *);
117 void tun_metadata_table_request(struct ofputil_tlv_table_reply *);
118
119 void tun_metadata_read(const struct flow_tnl *,
120                        const struct mf_field *, union mf_value *);
121 void tun_metadata_write(struct flow_tnl *,
122                         const struct mf_field *, const union mf_value *);
123 void tun_metadata_set_match(const struct mf_field *,
124                             const union mf_value *value,
125                             const union mf_value *mask, struct match *,
126                             char **err_str);
127 void tun_metadata_get_fmd(const struct flow_tnl *, struct match *flow_metadata);
128
129 int tun_metadata_from_geneve_nlattr(const struct nlattr *attr,
130                                     const struct nlattr *flow_attrs,
131                                     size_t flow_attr_len,
132                                     const struct flow_tnl *flow_tun,
133                                     bool udpif, struct flow_tnl *tun);
134 void tun_metadata_to_geneve_nlattr(const struct flow_tnl *tun,
135                                    const struct flow_tnl *flow,
136                                    const struct ofpbuf *key,
137                                    struct ofpbuf *);
138
139 int tun_metadata_from_geneve_udpif(const struct flow_tnl *flow,
140                                    const struct flow_tnl *src,
141                                    struct flow_tnl *dst);
142 void tun_metadata_to_geneve_udpif_mask(const struct flow_tnl *flow_src,
143                                        const struct flow_tnl *mask_src,
144                                        const struct geneve_opt *flow_src_opt,
145                                        int opts_len, struct geneve_opt *dst);
146
147 int tun_metadata_to_geneve_header(const struct flow_tnl *flow,
148                                   struct geneve_opt *, bool *crit_opt);
149
150 void tun_metadata_to_nx_match(struct ofpbuf *b, enum ofp_version oxm,
151                               const struct match *);
152 void tun_metadata_match_format(struct ds *, const struct match *);
153
154 #endif /* tun-metadata.h */