summaryrefslogtreecommitdiff
path: root/include/openvswitch/ofp-flow.h
blob: f2223d90b4988b6f5ec42032283cee360f5b1690 (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
/*
 * 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_FLOW_H
#define OPENVSWITCH_OFP_FLOW_H 1

#include "openflow/openflow.h"
#include "openflow/nicira-ext.h"
#include "openvswitch/list.h"
#include "openvswitch/match.h"
#include "openvswitch/ofp-protocol.h"

struct vl_mff_map;
struct ofputil_port_map;
struct ofputil_table_map;

#ifdef __cplusplus
extern "C" {
#endif

/* Protocol-independent flow_mod flags. */
enum ofputil_flow_mod_flags {
    /* Flags that are maintained with a flow as part of its state.
     *
     * (OFPUTIL_FF_EMERG would be here too, if OVS supported it.) */
    OFPUTIL_FF_SEND_FLOW_REM = 1 << 0, /* All versions. */
    OFPUTIL_FF_NO_PKT_COUNTS = 1 << 1, /* OpenFlow 1.3+. */
    OFPUTIL_FF_NO_BYT_COUNTS = 1 << 2, /* OpenFlow 1.3+. */

    /* These flags primarily affects flow_mod behavior.  They are not
     * particularly useful as part of flow state.  We include them in flow
     * state only because OpenFlow implies that they should be. */
    OFPUTIL_FF_CHECK_OVERLAP = 1 << 3, /* All versions. */
    OFPUTIL_FF_RESET_COUNTS  = 1 << 4, /* OpenFlow 1.2+. */

    /* Not supported by OVS. */
    OFPUTIL_FF_EMERG         = 1 << 5, /* OpenFlow 1.0 only. */

    /* The set of flags maintained as part of a flow table entry. */
#define OFPUTIL_FF_STATE (OFPUTIL_FF_SEND_FLOW_REM      \
                          | OFPUTIL_FF_NO_PKT_COUNTS    \
                          | OFPUTIL_FF_NO_BYT_COUNTS    \
                          | OFPUTIL_FF_CHECK_OVERLAP    \
                          | OFPUTIL_FF_RESET_COUNTS)

    /* Flags that are only set by OVS for its internal use.  Cannot be set via
     * OpenFlow. */
    OFPUTIL_FF_HIDDEN_FIELDS = 1 << 6, /* Allow hidden match fields to be
                                          set or modified. */
    OFPUTIL_FF_NO_READONLY   = 1 << 7, /* Allow rules within read only tables
                                          to be modified */
};

void ofputil_flow_mod_flags_format(struct ds *, enum ofputil_flow_mod_flags);

/* Protocol-independent flow_mod.
 *
 * The handling of cookies across multiple versions of OpenFlow is a bit
 * confusing.  See the topics/design doc for the details. */
struct ofputil_flow_mod {
    struct ovs_list list_node; /* For queuing flow_mods. */

    struct minimatch match;
    int priority;

    /* Cookie matching.  The flow_mod affects only flows that have cookies that
     * bitwise match 'cookie' bits in positions where 'cookie_mask has 1-bits.
     *
     * 'cookie_mask' should be zero for OFPFC_ADD flow_mods. */
    ovs_be64 cookie;         /* Cookie bits to match. */
    ovs_be64 cookie_mask;    /* 1-bit in each 'cookie' bit to match. */

    /* Cookie changes.
     *
     * OFPFC_ADD uses 'new_cookie' as the new flow's cookie.  'new_cookie'
     * should not be UINT64_MAX.
     *
     * OFPFC_MODIFY and OFPFC_MODIFY_STRICT have two cases:
     *
     *   - If one or more matching flows exist and 'modify_cookie' is true,
     *     then the flow_mod changes the existing flows' cookies to
     *     'new_cookie'.  'new_cookie' should not be UINT64_MAX.
     *
     *   - If no matching flow exists, 'new_cookie' is not UINT64_MAX, and
     *     'cookie_mask' is 0, then the flow_mod adds a new flow with
     *     'new_cookie' as its cookie.
     */
    ovs_be64 new_cookie;     /* New cookie to install or UINT64_MAX. */
    bool modify_cookie;      /* Set cookie of existing flow to 'new_cookie'? */

    uint8_t table_id;
    uint16_t command;
    uint16_t idle_timeout;
    uint16_t hard_timeout;
    uint32_t buffer_id;
    ofp_port_t out_port;
    uint32_t out_group;
    enum ofputil_flow_mod_flags flags;
    uint16_t importance;     /* Eviction precedence. */
    struct ofpact *ofpacts;  /* Series of "struct ofpact"s. */
    size_t ofpacts_len;      /* Length of ofpacts, in bytes. */
    uint64_t ofpacts_tlv_bitmap; /* 1-bit for each present TLV in 'ofpacts'. */
};

enum ofperr ofputil_decode_flow_mod(struct ofputil_flow_mod *,
                                    const struct ofp_header *,
                                    enum ofputil_protocol,
                                    const struct tun_table *,
                                    const struct vl_mff_map *,
                                    struct ofpbuf *ofpacts,
                                    ofp_port_t max_port,
                                    uint8_t max_table);
struct ofpbuf *ofputil_encode_flow_mod(const struct ofputil_flow_mod *,
                                       enum ofputil_protocol);
enum ofperr ofputil_flow_mod_format(struct ds *, const struct ofp_header *,
                                    const struct ofputil_port_map *,
                                    const struct ofputil_table_map *,
                                    int verbosity);

char *parse_ofp_str(struct ofputil_flow_mod *, int command, const char *str_,
                    const struct ofputil_port_map *,
                    const struct ofputil_table_map *,
                    enum ofputil_protocol *usable_protocols)
    OVS_WARN_UNUSED_RESULT;

char *parse_ofp_flow_mod_str(struct ofputil_flow_mod *, const char *string,
                             const struct ofputil_port_map *,
                             const struct ofputil_table_map *,
                             int command,
                             enum ofputil_protocol *usable_protocols)
    OVS_WARN_UNUSED_RESULT;

char *parse_ofp_flow_mod_file(const char *file_name,
                              const struct ofputil_port_map *,
                              const struct ofputil_table_map *,
                              int command,
                              struct ofputil_flow_mod **fms, size_t *n_fms,
                              enum ofputil_protocol *usable_protocols)
    OVS_WARN_UNUSED_RESULT;

char *parse_ofp_exact_flow(struct flow *flow, struct flow_wildcards *wc,
                           const struct tun_table *tun_table, const char *s,
                           const struct ofputil_port_map *port_map);

/* Flow stats or aggregate stats request, independent of protocol. */
struct ofputil_flow_stats_request {
    bool aggregate;             /* Aggregate results? */
    struct match match;
    ovs_be64 cookie;
    ovs_be64 cookie_mask;
    ofp_port_t out_port;
    uint32_t out_group;
    uint8_t table_id;
};

enum ofperr ofputil_decode_flow_stats_request(
    struct ofputil_flow_stats_request *, const struct ofp_header *,
    const struct tun_table *, const struct vl_mff_map *);
struct ofpbuf *ofputil_encode_flow_stats_request(
    const struct ofputil_flow_stats_request *, enum ofputil_protocol);
char *parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *,
                                       bool aggregate, const char *string,
                                       const struct ofputil_port_map *,
                                       const struct ofputil_table_map *,
                                       enum ofputil_protocol *usable_protocols)
    OVS_WARN_UNUSED_RESULT;

void ofputil_flow_stats_request_format(
    struct ds *, const struct ofputil_flow_stats_request *,
    const struct ofputil_port_map *, const struct ofputil_table_map *);

/* Flow stats reply, independent of protocol. */
struct ofputil_flow_stats {
    struct match match;
    ovs_be64 cookie;
    uint8_t table_id;
    uint16_t priority;
    uint16_t idle_timeout;
    uint16_t hard_timeout;
    uint32_t duration_sec;
    uint32_t duration_nsec;
    int idle_age;               /* Seconds since last packet, -1 if unknown. */
    int hard_age;               /* Seconds since last change, -1 if unknown. */
    uint64_t packet_count;      /* Packet count, UINT64_MAX if unknown. */
    uint64_t byte_count;        /* Byte count, UINT64_MAX if unknown. */
    const struct ofpact *ofpacts;
    size_t ofpacts_len;
    enum ofputil_flow_mod_flags flags;
    uint16_t importance;        /* Eviction precedence. */
};

int ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *,
                                    struct ofpbuf *msg,
                                    bool flow_age_extension,
                                    struct ofpbuf *ofpacts);
void ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *,
                                     struct ovs_list *replies,
                                     const struct tun_table *);

void ofputil_flow_stats_format(struct ds *, const struct ofputil_flow_stats *,
                               const struct ofputil_port_map *,
                               const struct ofputil_table_map *,
                               bool show_stats);

/* Aggregate stats reply, independent of protocol. */
struct ofputil_aggregate_stats {
    uint64_t packet_count;      /* Packet count, UINT64_MAX if unknown. */
    uint64_t byte_count;        /* Byte count, UINT64_MAX if unknown. */
    uint32_t flow_count;        /* Number of flows, UINT32_MAX if unknown. */
};

struct ofpbuf *ofputil_encode_aggregate_stats_reply(
    const struct ofputil_aggregate_stats *stats,
    const struct ofp_header *request);
enum ofperr ofputil_decode_aggregate_stats_reply(
    struct ofputil_aggregate_stats *,
    const struct ofp_header *reply);
void ofputil_aggregate_stats_format(struct ds *,
                                    const struct ofputil_aggregate_stats *);

#ifdef __cplusplus
}
#endif

#endif  /* ofp-flow.h */