summaryrefslogtreecommitdiff
path: root/include/openvswitch/ofp-table.h
blob: 8e0a1cbe2e3a6cc18361cbb9d8c3973ddca524e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/*
 * Copyright (c) 2008-2017 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_OFP_TABLE_H
#define OPENVSWITCH_OFP_TABLE_H 1

#include <limits.h>
#include "openflow/openflow.h"
#include "openvswitch/meta-flow.h"
#include "openvswitch/ofp-port.h"

#ifdef __cplusplus
extern "C" {
#endif

struct ofputil_table_stats;

/* Abstract version of OFPTC11_TABLE_MISS_*.
 *
 * OpenFlow 1.0 always sends packets that miss to the next flow table, or to
 * the controller if they miss in the last flow table.
 *
 * OpenFlow 1.1 and 1.2 can configure table miss behavior via a "table-mod"
 * that specifies "send to controller", "miss", or "drop".
 *
 * OpenFlow 1.3 and later never sends packets that miss to the controller.
 */
enum ofputil_table_miss {
    /* Protocol-specific default behavior.  On OpenFlow 1.0 through 1.2
     * connections, the packet is sent to the controller, and on OpenFlow 1.3
     * and later connections, the packet is dropped.
     *
     * This is also used as a result of decoding OpenFlow 1.3+ "config" values
     * in table-mods, to indicate that no table-miss was specified. */
    OFPUTIL_TABLE_MISS_DEFAULT,    /* Protocol default behavior. */

    /* These constants have the same meanings as those in OpenFlow with the
     * same names. */
    OFPUTIL_TABLE_MISS_CONTROLLER, /* Send to controller. */
    OFPUTIL_TABLE_MISS_CONTINUE,   /* Go to next table. */
    OFPUTIL_TABLE_MISS_DROP,       /* Drop the packet. */
};

const char *ofputil_table_miss_to_string(enum ofputil_table_miss);

/* Abstract version of OFPTC14_EVICTION.
 *
 * OpenFlow 1.0 through 1.3 don't know anything about eviction, so decoding a
 * message for one of these protocols always yields
 * OFPUTIL_TABLE_EVICTION_DEFAULT. */
enum ofputil_table_eviction {
    OFPUTIL_TABLE_EVICTION_DEFAULT, /* No value. */
    OFPUTIL_TABLE_EVICTION_ON,      /* Enable eviction. */
    OFPUTIL_TABLE_EVICTION_OFF      /* Disable eviction. */
};

const char *ofputil_table_eviction_to_string(enum ofputil_table_eviction);

/* Abstract version of OFPTC14_VACANCY_EVENTS.
 *
 * OpenFlow 1.0 through 1.3 don't know anything about vacancy events, so
 * decoding a message for one of these protocols always yields
 * OFPUTIL_TABLE_VACANCY_DEFAULT. */
enum ofputil_table_vacancy {
    OFPUTIL_TABLE_VACANCY_DEFAULT, /* No value. */
    OFPUTIL_TABLE_VACANCY_ON,      /* Enable vacancy events. */
    OFPUTIL_TABLE_VACANCY_OFF      /* Disable vacancy events. */
};

const char *ofputil_table_vacancy_to_string(enum ofputil_table_vacancy);

/* Abstract version of OFPTMPT_VACANCY.
 *
 * Openflow 1.4+ defines vacancy events.
 * The fields vacancy_down and vacancy_up are the threshold for generating
 * vacancy events that should be configured on the flow table, expressed as
 * a percent.
 * The vacancy field is only used when this property in included in a
 * OFPMP_TABLE_DESC multipart reply or a OFPT_TABLE_STATUS message and
 * represent the current vacancy of the table, expressed as a percent. In
 * OFP_TABLE_MOD requests, this field must be set to 0 */
struct ofputil_table_mod_prop_vacancy {
    uint8_t vacancy_down;    /* Vacancy threshold when space decreases (%). */
    uint8_t vacancy_up;      /* Vacancy threshold when space increases (%). */
    uint8_t vacancy;         /* Current vacancy (%). */
};

/* Mapping between table numbers and names. */
struct ofputil_table_map {
    struct namemap map;
};
#define OFPUTIL_TABLE_MAP_INITIALIZER(MAP) { NAMEMAP_INITIALIZER((MAP).map) }

void ofputil_table_map_init(struct ofputil_table_map *);
const char *ofputil_table_map_get_name(const struct ofputil_table_map *,
                                       uint8_t);
uint8_t ofputil_table_map_get_number(const struct ofputil_table_map *,
                                     const char *name);
void ofputil_table_map_put(struct ofputil_table_map *,
                           uint8_t, const char *name);
void ofputil_table_map_destroy(struct ofputil_table_map *);

/* Table numbers. */
bool ofputil_table_from_string(const char *, const struct ofputil_table_map *,
                               uint8_t *tablep);
void ofputil_format_table(uint8_t table, const struct ofputil_table_map *,
                         struct ds *);
void ofputil_table_to_string(uint8_t, const struct ofputil_table_map *,
                            char *namebuf, size_t bufsize);

/* Abstract ofp_table_mod. */
struct ofputil_table_mod {
    uint8_t table_id;         /* ID of the table, 0xff indicates all tables. */

    /* OpenFlow 1.1 and 1.2 only.  For other versions, ignored on encoding,
     * decoded to OFPUTIL_TABLE_MISS_DEFAULT. */
    enum ofputil_table_miss miss;

    /* OpenFlow 1.4+ only.  For other versions, ignored on encoding, decoded to
     * OFPUTIL_TABLE_EVICTION_DEFAULT. */
    enum ofputil_table_eviction eviction;

    /* OpenFlow 1.4+ only and optional even there; UINT32_MAX indicates
     * absence.  For other versions, ignored on encoding, decoded to
     * UINT32_MAX.*/
    uint32_t eviction_flags;    /* OFPTMPEF14_*. */

    /* OpenFlow 1.4+ only. For other versions, ignored on encoding, decoded to
     * OFPUTIL_TABLE_VACANCY_DEFAULT. */
    enum ofputil_table_vacancy vacancy;

    /* Openflow 1.4+ only. Defines threshold values of vacancy expressed as
     * percent, value of current vacancy is set to zero for table-mod.
     * For other versions, ignored on encoding, all values decoded to
     * zero. */
    struct ofputil_table_mod_prop_vacancy table_vacancy;
};

enum ofperr ofputil_decode_table_mod(const struct ofp_header *,
                                    struct ofputil_table_mod *);
struct ofpbuf *ofputil_encode_table_mod(const struct ofputil_table_mod *,
                                       enum ofputil_protocol);
void ofputil_table_mod_format(struct ds *, const struct ofputil_table_mod *,
                              const struct ofputil_table_map *);
char *parse_ofp_table_mod(struct ofputil_table_mod *, const char **namep,
                          const char *table_id, const char *flow_miss_handling,
                          const struct ofputil_table_map *,
                          uint32_t *usable_versions)
    OVS_WARN_UNUSED_RESULT;

/* Abstract ofp14_table_desc. */
struct ofputil_table_desc {
    uint8_t table_id;         /* ID of the table. */
    enum ofputil_table_eviction eviction;
    uint32_t eviction_flags;    /* UINT32_MAX if not present. */
    enum ofputil_table_vacancy vacancy;
    struct ofputil_table_mod_prop_vacancy table_vacancy;
};

int ofputil_decode_table_desc(struct ofpbuf *,
                              struct ofputil_table_desc *,
                              enum ofp_version);
void ofputil_append_table_desc_reply(const struct ofputil_table_desc *td,
                                     struct ovs_list *replies,
                                     enum ofp_version);
void ofputil_table_desc_format(struct ds *,
                               const struct ofputil_table_desc *,
                               const struct ofputil_table_map *);

/* Abstract ofp_table_features.
 *
 * This is used for all versions of OpenFlow, even though ofp_table_features
 * was only introduced in OpenFlow 1.3, because earlier versions of OpenFlow
 * include support for a subset of ofp_table_features through OFPST_TABLE (aka
 * OFPMP_TABLE). */
struct ofputil_table_features {
    /* Only for OFPT_TABLE_FEATURES requests and only the first table_features
     * in such a request.  */
    enum ofp15_table_features_command command;

    /* The following are always present in table features requests and
     * replies. */
    uint8_t table_id;
    char name[OFP_MAX_TABLE_NAME_LEN];
    ovs_be64 metadata_match;  /* Bits of metadata table can match. */
    ovs_be64 metadata_write;  /* Bits of metadata table can write. */
    uint32_t max_entries;     /* Max number of entries supported. */

    /* True if the message included any properties.  This is important for
     * OFPT_TABLE_FEATURES requests, which change table properties only if any
     * are included. */
    bool any_properties;

    /* Flags.
     *
     * 'miss_config' is relevant for OpenFlow 1.1 and 1.2 only, because those
     * versions include OFPTC_MISS_* flags in OFPST_TABLE.  For other versions,
     * it is decoded to OFPUTIL_TABLE_MISS_DEFAULT and ignored for encoding.
     *
     * 'supports_eviction' and 'supports_vacancy_events' are relevant only for
     * OpenFlow 1.4 and later only.  For OF1.4, they are boolean: 1 if
     * supported, otherwise 0.  For other versions, they are decoded as -1 and
     * ignored for encoding.
     *
     * Search for "OFPTC_* Table Configuration" in the documentation for more
     * details of how OpenFlow has changed in this area.
     */
    enum ofputil_table_miss miss_config; /* OF1.1 and 1.2 only. */
    int supports_eviction;               /* OF1.4+ only. */
    int supports_vacancy_events;         /* OF1.4+ only. */

    /* Table features related to instructions.  There are two instances:
     *
     *   - 'miss' reports features available in the table miss flow.
     *
     *   - 'nonmiss' reports features available in other flows. */
    struct ofputil_table_instruction_features {
        /* Tables that "goto-table" may jump to. */
        unsigned long int next[BITMAP_N_LONGS(255)];

        /* Bitmap of OVSINST_* for supported instructions. */
        uint32_t instructions;

        /* Table features related to actions.  There are two instances:
         *
         *    - 'write' reports features available in a "write_actions"
         *      instruction.
         *
         *    - 'apply' reports features available in an "apply_actions"
         *      instruction. */
        struct ofputil_table_action_features {
            uint64_t ofpacts;     /* Bitmap of supported OFPACT_*. */
            struct mf_bitmap set_fields; /* Fields for "set-field". */
        } write, apply;
    } nonmiss, miss;

    /* MFF_* bitmaps.
     *
     * For any given field the following combinations are valid:
     *
     *    - match=0, wildcard=0, mask=0: Flows in this table cannot match on
     *      this field.
     *
     *    - match=1, wildcard=0, mask=0: Flows in this table must match on all
     *      the bits in this field.
     *
     *    - match=1, wildcard=1, mask=0: Flows in this table must either match
     *      on all the bits in the field or wildcard the field entirely.
     *
     *    - match=1, wildcard=1, mask=1: Flows in this table may arbitrarily
     *      mask this field (as special cases, they may match on all the bits
     *      or wildcard it entirely).
     *
     * Other combinations do not make sense.
     */
    struct mf_bitmap match;     /* Fields that may be matched. */
    struct mf_bitmap mask;      /* Subset of 'match' that may have masks. */
    struct mf_bitmap wildcard;  /* Subset of 'match' that may be wildcarded. */
};

int ofputil_decode_table_features(
    struct ofpbuf *, struct ofputil_table_features *,
    struct ofpbuf *raw_properties);

struct ofpbuf *ofputil_encode_table_features_request(enum ofp_version);

struct ofpbuf *ofputil_encode_table_desc_request(enum ofp_version);

void ofputil_append_table_features(
    const struct ofputil_table_features *tf,
    const struct ofpbuf *raw_properties,
    struct ovs_list *msgs);

void ofputil_table_features_format(
    struct ds *, const struct ofputil_table_features *features,
    const struct ofputil_table_features *prev_features,
    const struct ofputil_table_stats *stats,
    const struct ofputil_table_stats *prev_stats,
    int *first_ditto, int *last_ditto);
void ofputil_table_features_format_finish(struct ds *,
                                          int first_ditto, int last_ditto);

bool ofputil_table_features_are_superset(
    const struct ofputil_table_features *super,
    const struct ofputil_table_features *sub);

/* Abstract table stats.
 *
 * This corresponds to the OpenFlow 1.3 table statistics structure, which only
 * includes actual statistics.  In earlier versions of OpenFlow, several
 * members describe table features, so this structure has to be paired with
 * struct ofputil_table_features to get all information. */
struct ofputil_table_stats {
    uint8_t table_id;           /* Identifier of table. */
    uint32_t active_count;      /* Number of active entries. */
    uint64_t lookup_count;      /* Number of packets looked up in table. */
    uint64_t matched_count;     /* Number of packets that hit table. */
};

struct ofpbuf *ofputil_encode_table_stats_reply(const struct ofp_header *rq);

struct ofpbuf *ofputil_encode_table_desc_reply(const struct ofp_header *rq);

void ofputil_append_table_stats_reply(struct ofpbuf *reply,
                                      const struct ofputil_table_stats *,
                                      const struct ofputil_table_features *);

int ofputil_decode_table_stats_reply(struct ofpbuf *reply,
                                     struct ofputil_table_stats *,
                                     struct ofputil_table_features *);

/* Abstract ofp14_table_status. */
struct ofputil_table_status {
    enum ofp14_table_reason reason;     /* One of OFPTR_*. */
    struct ofputil_table_desc desc;   /* New table config. */
};

const char *ofp_table_reason_to_string(enum ofp14_table_reason,
                                       char *reasonbuf, size_t bufsize);

enum ofperr ofputil_decode_table_status(const struct ofp_header *,
                                        struct ofputil_table_status *);
struct ofpbuf *ofputil_encode_table_status(const struct ofputil_table_status *,
                                           enum ofputil_protocol);
void ofputil_format_table_status(struct ds *,
                                 const struct ofputil_table_status *,
                                 const struct ofputil_table_map *);

#ifdef __cplusplus
}
#endif

#endif  /* ofp-table.h */