Coverage Report

Created: 2025-10-10 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openvswitch/lib/ofp-flow.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2008-2017, 2019 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
#include <config.h>
18
#include "openvswitch/ofp-flow.h"
19
#include <errno.h>
20
#include "byte-order.h"
21
#include "colors.h"
22
#include "flow.h"
23
#include "nx-match.h"
24
#include "openvswitch/ofp-actions.h"
25
#include "openvswitch/ofp-group.h"
26
#include "openvswitch/ofp-match.h"
27
#include "openvswitch/ofp-msgs.h"
28
#include "openvswitch/ofp-parse.h"
29
#include "openvswitch/ofp-port.h"
30
#include "openvswitch/ofp-print.h"
31
#include "openvswitch/ofp-table.h"
32
#include "openvswitch/ofpbuf.h"
33
#include "openvswitch/vlog.h"
34
#include "util.h"
35
#include "ox-stat.h"
36
37
VLOG_DEFINE_THIS_MODULE(ofp_flow);
38
39
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
40

41
struct ofputil_flow_mod_flag {
42
    uint16_t raw_flag;
43
    enum ofp_version min_version, max_version;
44
    enum ofputil_flow_mod_flags flag;
45
};
46
47
static const struct ofputil_flow_mod_flag ofputil_flow_mod_flags[] = {
48
    { OFPFF_SEND_FLOW_REM,   OFP10_VERSION, 0, OFPUTIL_FF_SEND_FLOW_REM },
49
    { OFPFF_CHECK_OVERLAP,   OFP10_VERSION, 0, OFPUTIL_FF_CHECK_OVERLAP },
50
    { OFPFF10_EMERG,         OFP10_VERSION, OFP10_VERSION,
51
      OFPUTIL_FF_EMERG },
52
    { OFPFF12_RESET_COUNTS,  OFP12_VERSION, 0, OFPUTIL_FF_RESET_COUNTS },
53
    { OFPFF13_NO_PKT_COUNTS, OFP13_VERSION, 0, OFPUTIL_FF_NO_PKT_COUNTS },
54
    { OFPFF13_NO_BYT_COUNTS, OFP13_VERSION, 0, OFPUTIL_FF_NO_BYT_COUNTS },
55
    { 0, 0, 0, 0 },
56
};
57
58
static enum ofperr
59
ofputil_decode_flow_mod_flags(ovs_be16 raw_flags_,
60
                              enum ofp_flow_mod_command command,
61
                              enum ofp_version version,
62
                              enum ofputil_flow_mod_flags *flagsp)
63
88.0k
{
64
88.0k
    uint16_t raw_flags = ntohs(raw_flags_);
65
88.0k
    const struct ofputil_flow_mod_flag *f;
66
67
88.0k
    *flagsp = 0;
68
616k
    for (f = ofputil_flow_mod_flags; f->raw_flag; f++) {
69
528k
        if (raw_flags & f->raw_flag
70
62.2k
            && version >= f->min_version
71
60.9k
            && (!f->max_version || version <= f->max_version)) {
72
54.5k
            raw_flags &= ~f->raw_flag;
73
54.5k
            *flagsp |= f->flag;
74
54.5k
        }
75
528k
    }
76
77
    /* In OF1.0 and OF1.1, "add" always resets counters, and other commands
78
     * never do.
79
     *
80
     * In OF1.2 and later, OFPFF12_RESET_COUNTS controls whether each command
81
     * resets counters. */
82
88.0k
    if ((version == OFP10_VERSION || version == OFP11_VERSION)
83
51.5k
        && command == OFPFC_ADD) {
84
45.3k
        *flagsp |= OFPUTIL_FF_RESET_COUNTS;
85
45.3k
    }
86
87
88.0k
    return raw_flags ? OFPERR_OFPFMFC_BAD_FLAGS : 0;
88
88.0k
}
89
90
static ovs_be16
91
ofputil_encode_flow_mod_flags(enum ofputil_flow_mod_flags flags,
92
                              enum ofp_version version)
93
9.56k
{
94
9.56k
    const struct ofputil_flow_mod_flag *f;
95
9.56k
    uint16_t raw_flags;
96
97
9.56k
    raw_flags = 0;
98
66.9k
    for (f = ofputil_flow_mod_flags; f->raw_flag; f++) {
99
57.3k
        if (f->flag & flags
100
160
            && version >= f->min_version
101
160
            && (!f->max_version || version <= f->max_version)) {
102
160
            raw_flags |= f->raw_flag;
103
160
        }
104
57.3k
    }
105
106
9.56k
    return htons(raw_flags);
107
9.56k
}
108
109
void
110
ofputil_flow_mod_flags_format(struct ds *s, enum ofputil_flow_mod_flags flags)
111
67.7k
{
112
67.7k
    if (flags & OFPUTIL_FF_SEND_FLOW_REM) {
113
10.6k
        ds_put_cstr(s, "send_flow_rem ");
114
10.6k
    }
115
67.7k
    if (flags & OFPUTIL_FF_CHECK_OVERLAP) {
116
14.4k
        ds_put_cstr(s, "check_overlap ");
117
14.4k
    }
118
67.7k
    if (flags & OFPUTIL_FF_RESET_COUNTS) {
119
1.63k
        ds_put_cstr(s, "reset_counts ");
120
1.63k
    }
121
67.7k
    if (flags & OFPUTIL_FF_NO_PKT_COUNTS) {
122
4.40k
        ds_put_cstr(s, "no_packet_counts ");
123
4.40k
    }
124
67.7k
    if (flags & OFPUTIL_FF_NO_BYT_COUNTS) {
125
1.16k
        ds_put_cstr(s, "no_byte_counts ");
126
1.16k
    }
127
67.7k
    if (flags & OFPUTIL_FF_HIDDEN_FIELDS) {
128
0
        ds_put_cstr(s, "allow_hidden_fields ");
129
0
    }
130
67.7k
    if (flags & OFPUTIL_FF_NO_READONLY) {
131
0
        ds_put_cstr(s, "no_readonly_table ");
132
0
    }
133
67.7k
}
134
135
/* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract
136
 * flow_mod in 'fm'.  Returns 0 if successful, otherwise an OpenFlow error
137
 * code.
138
 *
139
 * Uses 'ofpacts' to store the abstract OFPACT_* version of 'oh''s actions.
140
 * The caller must initialize 'ofpacts' and retains ownership of it.
141
 * 'fm->ofpacts' will point into the 'ofpacts' buffer.
142
 *
143
 * On success, the caller must eventually destroy fm->match.
144
 *
145
 * Does not validate the flow_mod actions.  The caller should do that, with
146
 * ofpacts_check(). */
147
enum ofperr
148
ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
149
                        const struct ofp_header *oh,
150
                        enum ofputil_protocol protocol,
151
                        const struct tun_table *tun_table,
152
                        const struct vl_mff_map *vl_mff_map,
153
                        struct ofpbuf *ofpacts,
154
                        ofp_port_t max_port, uint8_t max_table)
155
158k
{
156
158k
    ovs_be16 raw_flags;
157
158k
    enum ofperr error;
158
158k
    struct match match;
159
158k
    struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
160
158k
    enum ofpraw raw = ofpraw_pull_assert(&b);
161
158k
    if (raw == OFPRAW_OFPT11_FLOW_MOD) {
162
        /* Standard OpenFlow 1.1+ flow_mod. */
163
53.9k
        const struct ofp11_flow_mod *ofm;
164
165
53.9k
        ofm = ofpbuf_pull(&b, sizeof *ofm);
166
167
53.9k
        error = ofputil_pull_ofp11_match(&b, tun_table, vl_mff_map, &match,
168
53.9k
                                         NULL);
169
53.9k
        if (error) {
170
13.5k
            return error;
171
13.5k
        }
172
173
        /* Translate the message. */
174
40.3k
        fm->priority = ntohs(ofm->priority);
175
40.3k
        if (ofm->command == OFPFC_ADD
176
12.6k
            || (oh->version == OFP11_VERSION
177
1.46k
                && (ofm->command == OFPFC_MODIFY ||
178
358
                    ofm->command == OFPFC_MODIFY_STRICT)
179
28.1k
                && ofm->cookie_mask == htonll(0))) {
180
            /* In OpenFlow 1.1 only, a "modify" or "modify-strict" that does
181
             * not match on the cookie is treated as an "add" if there is no
182
             * match. */
183
28.1k
            fm->cookie = htonll(0);
184
28.1k
            fm->cookie_mask = htonll(0);
185
28.1k
            fm->new_cookie = ofm->cookie;
186
28.1k
        } else {
187
12.2k
            fm->cookie = ofm->cookie;
188
12.2k
            fm->cookie_mask = ofm->cookie_mask;
189
12.2k
            fm->new_cookie = OVS_BE64_MAX;
190
12.2k
        }
191
40.3k
        fm->modify_cookie = false;
192
40.3k
        fm->command = ofm->command;
193
194
        /* Get table ID.
195
         *
196
         * OF1.1 entirely forbids table_id == OFPTT_ALL.
197
         * OF1.2+ allows table_id == OFPTT_ALL only for deletes. */
198
40.3k
        fm->table_id = ofm->table_id;
199
40.3k
        if (fm->table_id == OFPTT_ALL
200
2.11k
            && (oh->version == OFP11_VERSION
201
2.05k
                || (ofm->command != OFPFC_DELETE &&
202
1.20k
                    ofm->command != OFPFC_DELETE_STRICT))) {
203
1.09k
            return OFPERR_OFPFMFC_BAD_TABLE_ID;
204
1.09k
        }
205
206
39.2k
        fm->idle_timeout = ntohs(ofm->idle_timeout);
207
39.2k
        fm->hard_timeout = ntohs(ofm->hard_timeout);
208
39.2k
        if (oh->version >= OFP14_VERSION && ofm->command == OFPFC_ADD) {
209
27.3k
            fm->importance = ntohs(ofm->importance);
210
27.3k
        } else {
211
11.9k
            fm->importance = 0;
212
11.9k
        }
213
39.2k
        fm->buffer_id = ntohl(ofm->buffer_id);
214
39.2k
        error = ofputil_port_from_ofp11(ofm->out_port, &fm->out_port);
215
39.2k
        if (error) {
216
1.02k
            return error;
217
1.02k
        }
218
219
38.2k
        fm->out_group = (ofm->command == OFPFC_DELETE ||
220
33.4k
                         ofm->command == OFPFC_DELETE_STRICT
221
38.2k
                         ? ntohl(ofm->out_group)
222
38.2k
                         : OFPG_ANY);
223
38.2k
        raw_flags = ofm->flags;
224
104k
    } else {
225
104k
        uint16_t command;
226
227
104k
        if (raw == OFPRAW_OFPT10_FLOW_MOD) {
228
            /* Standard OpenFlow 1.0 flow_mod. */
229
100k
            const struct ofp10_flow_mod *ofm;
230
231
            /* Get the ofp10_flow_mod. */
232
100k
            ofm = ofpbuf_pull(&b, sizeof *ofm);
233
234
            /* Translate the rule. */
235
100k
            ofputil_match_from_ofp10_match(&ofm->match, &match);
236
100k
            ofputil_normalize_match(&match);
237
238
            /* OpenFlow 1.0 says that exact-match rules have to have the
239
             * highest possible priority. */
240
100k
            fm->priority = (ofm->match.wildcards & htonl(OFPFW10_ALL)
241
100k
                            ? ntohs(ofm->priority)
242
100k
                            : UINT16_MAX);
243
244
            /* Translate the message. */
245
100k
            command = ntohs(ofm->command);
246
100k
            fm->cookie = htonll(0);
247
100k
            fm->cookie_mask = htonll(0);
248
100k
            fm->new_cookie = ofm->cookie;
249
100k
            fm->idle_timeout = ntohs(ofm->idle_timeout);
250
100k
            fm->hard_timeout = ntohs(ofm->hard_timeout);
251
100k
            fm->importance = 0;
252
100k
            fm->buffer_id = ntohl(ofm->buffer_id);
253
100k
            fm->out_port = u16_to_ofp(ntohs(ofm->out_port));
254
100k
            fm->out_group = OFPG_ANY;
255
100k
            raw_flags = ofm->flags;
256
100k
        } else if (raw == OFPRAW_NXT_FLOW_MOD) {
257
            /* Nicira extended flow_mod. */
258
4.39k
            const struct nx_flow_mod *nfm;
259
260
            /* Dissect the message. */
261
4.39k
            nfm = ofpbuf_pull(&b, sizeof *nfm);
262
4.39k
            error = nx_pull_match(&b, ntohs(nfm->match_len),
263
4.39k
                                  &match, &fm->cookie, &fm->cookie_mask,
264
4.39k
                                  false, tun_table, vl_mff_map);
265
4.39k
            if (error) {
266
515
                return error;
267
515
            }
268
269
            /* Translate the message. */
270
3.87k
            command = ntohs(nfm->command);
271
3.87k
            if ((command & 0xff) == OFPFC_ADD && fm->cookie_mask) {
272
                /* Flow additions may only set a new cookie, not match an
273
                 * existing cookie. */
274
49
                return OFPERR_NXBRC_NXM_INVALID;
275
49
            }
276
3.82k
            fm->priority = ntohs(nfm->priority);
277
3.82k
            fm->new_cookie = nfm->cookie;
278
3.82k
            fm->idle_timeout = ntohs(nfm->idle_timeout);
279
3.82k
            fm->hard_timeout = ntohs(nfm->hard_timeout);
280
3.82k
            fm->importance = 0;
281
3.82k
            fm->buffer_id = ntohl(nfm->buffer_id);
282
3.82k
            fm->out_port = u16_to_ofp(ntohs(nfm->out_port));
283
3.82k
            fm->out_group = OFPG_ANY;
284
3.82k
            raw_flags = nfm->flags;
285
3.82k
        } else {
286
0
            OVS_NOT_REACHED();
287
0
        }
288
289
104k
        fm->modify_cookie = fm->new_cookie != OVS_BE64_MAX;
290
104k
        if (protocol & OFPUTIL_P_TID) {
291
104k
            fm->command = command & 0xff;
292
104k
            fm->table_id = command >> 8;
293
104k
        } else {
294
0
            if (command > 0xff) {
295
0
                VLOG_WARN_RL(&rl, "flow_mod has explicit table_id "
296
0
                             "but flow_mod_table_id extension is not enabled");
297
0
            }
298
0
            fm->command = command;
299
0
            fm->table_id = 0xff;
300
0
        }
301
104k
    }
302
303
    /* Check for mismatched conntrack original direction tuple address fields
304
     * w.r.t. the IP version of the match. */
305
142k
    if (((match.wc.masks.ct_nw_src || match.wc.masks.ct_nw_dst)
306
0
         && match.flow.dl_type != htons(ETH_TYPE_IP))
307
142k
        || ((ipv6_addr_is_set(&match.wc.masks.ct_ipv6_src)
308
142k
             || ipv6_addr_is_set(&match.wc.masks.ct_ipv6_dst))
309
0
            && match.flow.dl_type != htons(ETH_TYPE_IPV6))) {
310
0
        return OFPERR_OFPBAC_MATCH_INCONSISTENT;
311
0
    }
312
313
142k
    if (fm->command > OFPFC_DELETE_STRICT) {
314
16.0k
        return OFPERR_OFPFMFC_BAD_COMMAND;
315
16.0k
    }
316
317
126k
    fm->ofpacts_tlv_bitmap = 0;
318
126k
    error = ofpacts_pull_openflow_instructions(&b, b.size, oh->version,
319
126k
                                               vl_mff_map,
320
126k
                                               &fm->ofpacts_tlv_bitmap,
321
126k
                                               ofpacts);
322
126k
    if (error) {
323
52.9k
        return error;
324
52.9k
    }
325
73.4k
    fm->ofpacts = ofpacts->data;
326
73.4k
    fm->ofpacts_len = ofpacts->size;
327
328
73.4k
    error = ofputil_decode_flow_mod_flags(raw_flags, fm->command,
329
73.4k
                                          oh->version, &fm->flags);
330
73.4k
    if (error) {
331
3.28k
        return error;
332
3.28k
    }
333
334
70.2k
    if (fm->flags & OFPUTIL_FF_EMERG) {
335
        /* We do not support the OpenFlow 1.0 emergency flow cache, which
336
         * is not required in OpenFlow 1.0.1 and removed from OpenFlow 1.1.
337
         *
338
         * OpenFlow 1.0 specifies the error code to use when idle_timeout
339
         * or hard_timeout is nonzero.  Otherwise, there is no good error
340
         * code, so just state that the flow table is full. */
341
225
        return (fm->hard_timeout || fm->idle_timeout
342
225
                ? OFPERR_OFPFMFC_BAD_EMERG_TIMEOUT
343
225
                : OFPERR_OFPFMFC_TABLE_FULL);
344
225
    }
345
346
69.9k
    struct ofpact_check_params cp = {
347
69.9k
        .match = &match,
348
69.9k
        .max_ports = max_port,
349
69.9k
        .table_id = fm->table_id,
350
69.9k
        .n_tables = max_table
351
69.9k
    };
352
69.9k
    error = ofpacts_check_consistency(fm->ofpacts, fm->ofpacts_len,
353
69.9k
                                      protocol, &cp);
354
69.9k
    if (!error) {
355
61.9k
        minimatch_init(&fm->match, &match);
356
61.9k
    }
357
69.9k
    return error;
358
70.2k
}
359
360
static ovs_be16
361
ofputil_tid_command(const struct ofputil_flow_mod *fm,
362
                    enum ofputil_protocol protocol)
363
8.87k
{
364
8.87k
    return htons(protocol & OFPUTIL_P_TID
365
8.87k
                 ? (fm->command & 0xff) | (fm->table_id << 8)
366
8.87k
                 : fm->command);
367
8.87k
}
368
369
/* Converts 'fm' into an OFPT_FLOW_MOD or NXT_FLOW_MOD message according to
370
 * 'protocol' and returns the message. */
371
struct ofpbuf *
372
ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
373
                        enum ofputil_protocol protocol)
374
9.56k
{
375
9.56k
    enum ofp_version version = ofputil_protocol_to_ofp_version(protocol);
376
9.56k
    ovs_be16 raw_flags = ofputil_encode_flow_mod_flags(fm->flags, version);
377
9.56k
    struct ofpbuf *msg;
378
379
9.56k
    struct match match;
380
9.56k
    minimatch_expand(&fm->match, &match);
381
382
9.56k
    switch (protocol) {
383
181
    case OFPUTIL_P_OF11_STD:
384
269
    case OFPUTIL_P_OF12_OXM:
385
682
    case OFPUTIL_P_OF13_OXM:
386
682
    case OFPUTIL_P_OF14_OXM:
387
682
    case OFPUTIL_P_OF15_OXM: {
388
682
        struct ofp11_flow_mod *ofm;
389
682
        int tailroom;
390
391
682
        tailroom = ofputil_match_typical_len(protocol) + fm->ofpacts_len;
392
682
        msg = ofpraw_alloc(OFPRAW_OFPT11_FLOW_MOD, version, tailroom);
393
682
        ofm = ofpbuf_put_zeros(msg, sizeof *ofm);
394
682
        if ((protocol == OFPUTIL_P_OF11_STD
395
181
             && (fm->command == OFPFC_MODIFY ||
396
152
                 fm->command == OFPFC_MODIFY_STRICT)
397
105
             && fm->cookie_mask == htonll(0))
398
619
            || fm->command == OFPFC_ADD) {
399
232
            ofm->cookie = fm->new_cookie;
400
450
        } else {
401
450
            ofm->cookie = fm->cookie & fm->cookie_mask;
402
450
        }
403
682
        ofm->cookie_mask = fm->cookie_mask;
404
682
        if (fm->table_id != OFPTT_ALL
405
681
            || (protocol != OFPUTIL_P_OF11_STD
406
501
                && (fm->command == OFPFC_DELETE ||
407
495
                    fm->command == OFPFC_DELETE_STRICT))) {
408
11
            ofm->table_id = fm->table_id;
409
671
        } else {
410
671
            ofm->table_id = 0;
411
671
        }
412
682
        ofm->command = fm->command;
413
682
        ofm->idle_timeout = htons(fm->idle_timeout);
414
682
        ofm->hard_timeout = htons(fm->hard_timeout);
415
682
        ofm->priority = htons(fm->priority);
416
682
        ofm->buffer_id = htonl(fm->buffer_id);
417
682
        ofm->out_port = ofputil_port_to_ofp11(fm->out_port);
418
682
        ofm->out_group = htonl(fm->out_group);
419
682
        ofm->flags = raw_flags;
420
682
        if (version >= OFP14_VERSION && fm->command == OFPFC_ADD) {
421
0
            ofm->importance = htons(fm->importance);
422
682
        } else {
423
682
            ofm->importance = 0;
424
682
        }
425
682
        ofputil_put_ofp11_match(msg, &match, protocol);
426
682
        ofpacts_put_openflow_instructions(fm->ofpacts, fm->ofpacts_len, msg,
427
682
                                          version);
428
682
        break;
429
682
    }
430
431
4.81k
    case OFPUTIL_P_OF10_STD:
432
5.07k
    case OFPUTIL_P_OF10_STD_TID: {
433
5.07k
        struct ofp10_flow_mod *ofm;
434
435
5.07k
        msg = ofpraw_alloc(OFPRAW_OFPT10_FLOW_MOD, OFP10_VERSION,
436
5.07k
                           fm->ofpacts_len);
437
5.07k
        ofm = ofpbuf_put_zeros(msg, sizeof *ofm);
438
5.07k
        ofputil_match_to_ofp10_match(&match, &ofm->match);
439
5.07k
        ofm->cookie = fm->new_cookie;
440
5.07k
        ofm->command = ofputil_tid_command(fm, protocol);
441
5.07k
        ofm->idle_timeout = htons(fm->idle_timeout);
442
5.07k
        ofm->hard_timeout = htons(fm->hard_timeout);
443
5.07k
        ofm->priority = htons(fm->priority);
444
5.07k
        ofm->buffer_id = htonl(fm->buffer_id);
445
5.07k
        ofm->out_port = htons(ofp_to_u16(fm->out_port));
446
5.07k
        ofm->flags = raw_flags;
447
5.07k
        ofpacts_put_openflow_actions(fm->ofpacts, fm->ofpacts_len, msg,
448
5.07k
                                     version);
449
5.07k
        break;
450
4.81k
    }
451
452
3.79k
    case OFPUTIL_P_OF10_NXM:
453
3.80k
    case OFPUTIL_P_OF10_NXM_TID: {
454
3.80k
        struct nx_flow_mod *nfm;
455
3.80k
        int match_len;
456
457
3.80k
        msg = ofpraw_alloc(OFPRAW_NXT_FLOW_MOD, OFP10_VERSION,
458
3.80k
                           NXM_TYPICAL_LEN + fm->ofpacts_len);
459
3.80k
        nfm = ofpbuf_put_zeros(msg, sizeof *nfm);
460
3.80k
        nfm->command = ofputil_tid_command(fm, protocol);
461
3.80k
        nfm->cookie = fm->new_cookie;
462
3.80k
        match_len = nx_put_match(msg, &match, fm->cookie, fm->cookie_mask);
463
3.80k
        nfm = msg->msg;
464
3.80k
        nfm->idle_timeout = htons(fm->idle_timeout);
465
3.80k
        nfm->hard_timeout = htons(fm->hard_timeout);
466
3.80k
        nfm->priority = htons(fm->priority);
467
3.80k
        nfm->buffer_id = htonl(fm->buffer_id);
468
3.80k
        nfm->out_port = htons(ofp_to_u16(fm->out_port));
469
3.80k
        nfm->flags = raw_flags;
470
3.80k
        nfm->match_len = htons(match_len);
471
3.80k
        ofpacts_put_openflow_actions(fm->ofpacts, fm->ofpacts_len, msg,
472
3.80k
                                     version);
473
3.80k
        break;
474
3.79k
    }
475
476
0
    default:
477
0
        OVS_NOT_REACHED();
478
9.56k
    }
479
480
9.56k
    ofpmsg_update_length(msg);
481
9.56k
    return msg;
482
9.56k
}
483
484
enum ofperr
485
ofputil_flow_mod_format(struct ds *s, const struct ofp_header *oh,
486
                        const struct ofputil_port_map *port_map,
487
                        const struct ofputil_table_map *table_map,
488
                        int verbosity)
489
158k
{
490
158k
    struct ofputil_flow_mod fm;
491
158k
    struct ofpbuf ofpacts;
492
158k
    bool need_priority;
493
158k
    enum ofperr error;
494
158k
    enum ofpraw raw;
495
158k
    enum ofputil_protocol protocol;
496
497
158k
    protocol = ofputil_protocol_from_ofp_version(oh->version);
498
158k
    protocol = ofputil_protocol_set_tid(protocol, true);
499
500
158k
    ofpbuf_init(&ofpacts, 64);
501
158k
    error = ofputil_decode_flow_mod(&fm, oh, protocol, NULL, NULL, &ofpacts,
502
158k
                                    OFPP_MAX, 255);
503
158k
    if (error) {
504
96.7k
        ofpbuf_uninit(&ofpacts);
505
96.7k
        return error;
506
96.7k
    }
507
508
61.9k
    ds_put_char(s, ' ');
509
61.9k
    switch (fm.command) {
510
53.2k
    case OFPFC_ADD:
511
53.2k
        ds_put_cstr(s, "ADD");
512
53.2k
        break;
513
2.33k
    case OFPFC_MODIFY:
514
2.33k
        ds_put_cstr(s, "MOD");
515
2.33k
        break;
516
1.18k
    case OFPFC_MODIFY_STRICT:
517
1.18k
        ds_put_cstr(s, "MOD_STRICT");
518
1.18k
        break;
519
2.98k
    case OFPFC_DELETE:
520
2.98k
        ds_put_cstr(s, "DEL");
521
2.98k
        break;
522
2.22k
    case OFPFC_DELETE_STRICT:
523
2.22k
        ds_put_cstr(s, "DEL_STRICT");
524
2.22k
        break;
525
0
    default:
526
0
        ds_put_format(s, "cmd:%d", fm.command);
527
61.9k
    }
528
61.9k
    if (fm.table_id != 0
529
38.5k
        || ofputil_table_map_get_name(table_map, fm.table_id)) {
530
23.4k
        ds_put_format(s, " table:");
531
23.4k
        ofputil_format_table(fm.table_id, table_map, s);
532
23.4k
    }
533
534
61.9k
    ds_put_char(s, ' ');
535
61.9k
    ofpraw_decode(&raw, oh);
536
61.9k
    if (verbosity >= 3 && raw == OFPRAW_OFPT10_FLOW_MOD) {
537
0
        const struct ofp10_flow_mod *ofm = ofpmsg_body(oh);
538
0
        ofp10_match_print(s, &ofm->match, port_map, verbosity);
539
540
        /* ofp_print_match() doesn't print priority. */
541
0
        need_priority = true;
542
61.9k
    } else if (verbosity >= 3 && raw == OFPRAW_NXT_FLOW_MOD) {
543
0
        const struct nx_flow_mod *nfm = ofpmsg_body(oh);
544
0
        const void *nxm = nfm + 1;
545
0
        char *nxm_s;
546
547
0
        nxm_s = nx_match_to_string(nxm, ntohs(nfm->match_len));
548
0
        ds_put_cstr(s, nxm_s);
549
0
        free(nxm_s);
550
551
        /* nx_match_to_string() doesn't print priority. */
552
0
        need_priority = true;
553
61.9k
    } else {
554
61.9k
        struct match match;
555
61.9k
        minimatch_expand(&fm.match, &match);
556
61.9k
        match_format(&match, port_map, s, fm.priority);
557
558
        /* match_format() does print priority. */
559
61.9k
        need_priority = false;
560
61.9k
    }
561
562
61.9k
    if (ds_last(s) != ' ') {
563
61.8k
        ds_put_char(s, ' ');
564
61.8k
    }
565
61.9k
    if (fm.new_cookie != htonll(0) && fm.new_cookie != OVS_BE64_MAX) {
566
55.8k
        ds_put_format(s, "cookie:0x%"PRIx64" ", ntohll(fm.new_cookie));
567
55.8k
    }
568
61.9k
    if (fm.cookie_mask != htonll(0)) {
569
5.24k
        ds_put_format(s, "cookie:0x%"PRIx64"/0x%"PRIx64" ",
570
5.24k
                ntohll(fm.cookie), ntohll(fm.cookie_mask));
571
5.24k
    }
572
61.9k
    if (fm.idle_timeout != OFP_FLOW_PERMANENT) {
573
42.0k
        ds_put_format(s, "idle:%"PRIu16" ", fm.idle_timeout);
574
42.0k
    }
575
61.9k
    if (fm.hard_timeout != OFP_FLOW_PERMANENT) {
576
47.5k
        ds_put_format(s, "hard:%"PRIu16" ", fm.hard_timeout);
577
47.5k
    }
578
61.9k
    if (fm.importance != 0) {
579
10.2k
        ds_put_format(s, "importance:%"PRIu16" ", fm.importance);
580
10.2k
    }
581
61.9k
    if (fm.priority != OFP_DEFAULT_PRIORITY && need_priority) {
582
0
        ds_put_format(s, "pri:%d ", fm.priority);
583
0
    }
584
61.9k
    if (fm.buffer_id != UINT32_MAX) {
585
60.6k
        ds_put_format(s, "buf:0x%"PRIx32" ", fm.buffer_id);
586
60.6k
    }
587
61.9k
    if (fm.out_port != OFPP_ANY) {
588
52.9k
        ds_put_format(s, "out_port:");
589
52.9k
        ofputil_format_port(fm.out_port, port_map, s);
590
52.9k
        ds_put_char(s, ' ');
591
52.9k
    }
592
593
61.9k
    if (oh->version == OFP10_VERSION || oh->version == OFP11_VERSION) {
594
        /* Don't print the reset_counts flag for OF1.0 and OF1.1 because those
595
         * versions don't really have such a flag and printing one is likely to
596
         * confuse people. */
597
45.7k
        fm.flags &= ~OFPUTIL_FF_RESET_COUNTS;
598
45.7k
    }
599
61.9k
    ofputil_flow_mod_flags_format(s, fm.flags);
600
601
61.9k
    ds_put_cstr(s, "actions=");
602
61.9k
    struct ofpact_format_params fp = {
603
61.9k
        .port_map = port_map,
604
61.9k
        .table_map = table_map,
605
61.9k
        .s = s,
606
61.9k
    };
607
61.9k
    ofpacts_format(fm.ofpacts, fm.ofpacts_len, &fp);
608
61.9k
    ofpbuf_uninit(&ofpacts);
609
61.9k
    minimatch_destroy(&fm.match);
610
611
61.9k
    return 0;
612
61.9k
}
613
614
static enum ofperr
615
ofputil_decode_ofpst10_flow_request(struct ofputil_flow_stats_request *fsr,
616
                                    const struct ofp10_flow_stats_request *ofsr,
617
                                    bool aggregate)
618
3.68k
{
619
3.68k
    fsr->aggregate = aggregate;
620
3.68k
    ofputil_match_from_ofp10_match(&ofsr->match, &fsr->match);
621
3.68k
    fsr->out_port = u16_to_ofp(ntohs(ofsr->out_port));
622
3.68k
    fsr->out_group = OFPG_ANY;
623
3.68k
    fsr->table_id = ofsr->table_id;
624
3.68k
    fsr->cookie = fsr->cookie_mask = htonll(0);
625
626
3.68k
    return 0;
627
3.68k
}
628
629
static enum ofperr
630
ofputil_decode_ofpst11_flow_request(struct ofputil_flow_stats_request *fsr,
631
                                    struct ofpbuf *b, bool aggregate,
632
                                    const struct tun_table *tun_table,
633
                                    const struct vl_mff_map *vl_mff_map)
634
1.32k
{
635
1.32k
    const struct ofp11_flow_stats_request *ofsr;
636
1.32k
    enum ofperr error;
637
638
1.32k
    ofsr = ofpbuf_pull(b, sizeof *ofsr);
639
1.32k
    fsr->aggregate = aggregate;
640
1.32k
    fsr->table_id = ofsr->table_id;
641
1.32k
    error = ofputil_port_from_ofp11(ofsr->out_port, &fsr->out_port);
642
1.32k
    if (error) {
643
658
        return error;
644
658
    }
645
666
    fsr->out_group = ntohl(ofsr->out_group);
646
666
    fsr->cookie = ofsr->cookie;
647
666
    fsr->cookie_mask = ofsr->cookie_mask;
648
666
    error = ofputil_pull_ofp11_match(b, tun_table, vl_mff_map, &fsr->match,
649
666
                                     NULL);
650
666
    if (error) {
651
578
        return error;
652
578
    }
653
654
88
    return 0;
655
666
}
656
657
static enum ofperr
658
ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr,
659
                                 struct ofpbuf *b, bool aggregate,
660
                                 const struct tun_table *tun_table,
661
                                 const struct vl_mff_map *vl_mff_map)
662
1.21k
{
663
1.21k
    const struct nx_flow_stats_request *nfsr;
664
1.21k
    enum ofperr error;
665
666
1.21k
    nfsr = ofpbuf_pull(b, sizeof *nfsr);
667
1.21k
    error = nx_pull_match(b, ntohs(nfsr->match_len), &fsr->match,
668
1.21k
                          &fsr->cookie, &fsr->cookie_mask, false, tun_table,
669
1.21k
                          vl_mff_map);
670
1.21k
    if (error) {
671
1.01k
        return error;
672
1.01k
    }
673
204
    if (b->size) {
674
59
        return OFPERR_OFPBRC_BAD_LEN;
675
59
    }
676
677
145
    fsr->aggregate = aggregate;
678
145
    fsr->out_port = u16_to_ofp(ntohs(nfsr->out_port));
679
145
    fsr->out_group = OFPG_ANY;
680
145
    fsr->table_id = nfsr->table_id;
681
682
145
    return 0;
683
204
}
684
685
/* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
686
 * request 'oh', into an abstract flow_stats_request in 'fsr'.  Returns 0 if
687
 * successful, otherwise an OpenFlow error code.
688
 *
689
 * 'vl_mff_map' is an optional parameter that is used to validate the length
690
 * of variable length mf_fields in 'match'. If it is not provided, the
691
 * default mf_fields with maximum length will be used. */
692
enum ofperr
693
ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request *fsr,
694
                                  const struct ofp_header *oh,
695
                                  const struct tun_table *tun_table,
696
                                  const struct vl_mff_map *vl_mff_map)
697
6.22k
{
698
6.22k
    struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
699
6.22k
    enum ofpraw raw = ofpraw_pull_assert(&b);
700
6.22k
    switch ((int) raw) {
701
2.61k
    case OFPRAW_OFPST10_FLOW_REQUEST:
702
2.61k
        return ofputil_decode_ofpst10_flow_request(fsr, b.data, false);
703
704
1.06k
    case OFPRAW_OFPST10_AGGREGATE_REQUEST:
705
1.06k
        return ofputil_decode_ofpst10_flow_request(fsr, b.data, true);
706
707
495
    case OFPRAW_OFPST11_FLOW_REQUEST:
708
495
        return ofputil_decode_ofpst11_flow_request(fsr, &b, false, tun_table,
709
495
                                                   vl_mff_map);
710
711
676
    case OFPRAW_OFPST11_AGGREGATE_REQUEST:
712
676
        return ofputil_decode_ofpst11_flow_request(fsr, &b, true, tun_table,
713
676
                                                   vl_mff_map);
714
715
153
    case OFPRAW_OFPST15_AGGREGATE_REQUEST:
716
153
       return ofputil_decode_ofpst11_flow_request(fsr, &b, true,
717
153
                                                  tun_table, vl_mff_map);
718
719
993
    case OFPRAW_NXST_FLOW_REQUEST:
720
993
        return ofputil_decode_nxst_flow_request(fsr, &b, false, tun_table,
721
993
                                                vl_mff_map);
722
723
221
    case OFPRAW_NXST_AGGREGATE_REQUEST:
724
221
        return ofputil_decode_nxst_flow_request(fsr, &b, true, tun_table,
725
221
                                                vl_mff_map);
726
727
0
    default:
728
        /* Hey, the caller lied. */
729
0
        OVS_NOT_REACHED();
730
6.22k
    }
731
6.22k
}
732
733
/* Converts abstract flow_stats_request 'fsr' into an OFPST_FLOW,
734
 * OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE request 'oh' according to
735
 * 'protocol', and returns the message. */
736
struct ofpbuf *
737
ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
738
                                  enum ofputil_protocol protocol)
739
0
{
740
0
    struct ofpbuf *msg;
741
0
    enum ofpraw raw;
742
743
0
    switch (protocol) {
744
0
    case OFPUTIL_P_OF11_STD:
745
0
    case OFPUTIL_P_OF12_OXM:
746
0
    case OFPUTIL_P_OF13_OXM:
747
0
    case OFPUTIL_P_OF14_OXM:
748
0
    case OFPUTIL_P_OF15_OXM: {
749
0
        struct ofp11_flow_stats_request *ofsr;
750
751
0
        if (protocol > OFPUTIL_P_OF14_OXM) {
752
0
            raw = (fsr->aggregate
753
0
                   ? OFPRAW_OFPST15_AGGREGATE_REQUEST
754
0
                   : OFPRAW_OFPST11_FLOW_REQUEST);
755
0
        } else {
756
0
            raw = (fsr->aggregate
757
0
                   ? OFPRAW_OFPST11_AGGREGATE_REQUEST
758
0
                   : OFPRAW_OFPST11_FLOW_REQUEST);
759
0
        }
760
0
        msg = ofpraw_alloc(raw, ofputil_protocol_to_ofp_version(protocol),
761
0
                           ofputil_match_typical_len(protocol));
762
0
        ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr);
763
0
        ofsr->table_id = fsr->table_id;
764
0
        ofsr->out_port = ofputil_port_to_ofp11(fsr->out_port);
765
0
        ofsr->out_group = htonl(fsr->out_group);
766
0
        ofsr->cookie = fsr->cookie;
767
0
        ofsr->cookie_mask = fsr->cookie_mask;
768
0
        ofputil_put_ofp11_match(msg, &fsr->match, protocol);
769
0
        break;
770
0
    }
771
772
0
    case OFPUTIL_P_OF10_STD:
773
0
    case OFPUTIL_P_OF10_STD_TID: {
774
0
        struct ofp10_flow_stats_request *ofsr;
775
776
0
        raw = (fsr->aggregate
777
0
               ? OFPRAW_OFPST10_AGGREGATE_REQUEST
778
0
               : OFPRAW_OFPST10_FLOW_REQUEST);
779
0
        msg = ofpraw_alloc(raw, OFP10_VERSION, 0);
780
0
        ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr);
781
0
        ofputil_match_to_ofp10_match(&fsr->match, &ofsr->match);
782
0
        ofsr->table_id = fsr->table_id;
783
0
        ofsr->out_port = htons(ofp_to_u16(fsr->out_port));
784
0
        break;
785
0
    }
786
787
0
    case OFPUTIL_P_OF10_NXM:
788
0
    case OFPUTIL_P_OF10_NXM_TID: {
789
0
        struct nx_flow_stats_request *nfsr;
790
0
        int match_len;
791
792
0
        raw = (fsr->aggregate
793
0
               ? OFPRAW_NXST_AGGREGATE_REQUEST
794
0
               : OFPRAW_NXST_FLOW_REQUEST);
795
0
        msg = ofpraw_alloc(raw, OFP10_VERSION, NXM_TYPICAL_LEN);
796
0
        ofpbuf_put_zeros(msg, sizeof *nfsr);
797
0
        match_len = nx_put_match(msg, &fsr->match,
798
0
                                 fsr->cookie, fsr->cookie_mask);
799
800
0
        nfsr = msg->msg;
801
0
        nfsr->out_port = htons(ofp_to_u16(fsr->out_port));
802
0
        nfsr->match_len = htons(match_len);
803
0
        nfsr->table_id = fsr->table_id;
804
0
        break;
805
0
    }
806
807
0
    default:
808
0
        OVS_NOT_REACHED();
809
0
    }
810
811
0
    return msg;
812
0
}
813
814
void
815
ofputil_flow_stats_request_format(struct ds *s,
816
                                  const struct ofputil_flow_stats_request *fsr,
817
                                  const struct ofputil_port_map *port_map,
818
                                  const struct ofputil_table_map *table_map)
819
3.91k
{
820
3.91k
    if (fsr->table_id != 0xff) {
821
1.74k
        ds_put_format(s, " table=");
822
1.74k
        ofputil_format_table(fsr->table_id, table_map, s);
823
1.74k
    }
824
825
3.91k
    if (fsr->out_port != OFPP_ANY) {
826
2.96k
        ds_put_cstr(s, " out_port=");
827
2.96k
        ofputil_format_port(fsr->out_port, port_map, s);
828
2.96k
    }
829
830
3.91k
    ds_put_char(s, ' ');
831
3.91k
    match_format(&fsr->match, port_map, s, OFP_DEFAULT_PRIORITY);
832
3.91k
}
833
834
char * OVS_WARN_UNUSED_RESULT
835
parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr,
836
                                 bool aggregate, const char *string,
837
                                 const struct ofputil_port_map *port_map,
838
                                 const struct ofputil_table_map *table_map,
839
                                 enum ofputil_protocol *usable_protocols)
840
0
{
841
0
    struct ofputil_flow_mod fm;
842
0
    char *error;
843
844
0
    error = parse_ofp_str(&fm, -1, string, port_map, table_map,
845
0
                          usable_protocols);
846
0
    if (error) {
847
0
        return error;
848
0
    }
849
850
    /* Special table ID support not required for stats requests. */
851
0
    if (*usable_protocols & OFPUTIL_P_OF10_STD_TID) {
852
0
        *usable_protocols |= OFPUTIL_P_OF10_STD;
853
0
    }
854
0
    if (*usable_protocols & OFPUTIL_P_OF10_NXM_TID) {
855
0
        *usable_protocols |= OFPUTIL_P_OF10_NXM;
856
0
    }
857
858
0
    fsr->aggregate = aggregate;
859
0
    fsr->cookie = fm.cookie;
860
0
    fsr->cookie_mask = fm.cookie_mask;
861
0
    minimatch_expand(&fm.match, &fsr->match);
862
0
    fsr->out_port = fm.out_port;
863
0
    fsr->out_group = fm.out_group;
864
0
    fsr->table_id = fm.table_id;
865
866
0
    minimatch_destroy(&fm.match);
867
868
0
    return NULL;
869
0
}
870
871
/* Converts an OFPST_FLOW or NXST_FLOW reply in 'msg' into an abstract
872
 * ofputil_flow_stats in 'fs'.
873
 *
874
 * Multiple OFPST_FLOW or NXST_FLOW replies can be packed into a single
875
 * OpenFlow message.  Calling this function multiple times for a single 'msg'
876
 * iterates through the replies.  The caller must initially leave 'msg''s layer
877
 * pointers null and not modify them between calls.
878
 *
879
 * Most switches don't send the values needed to populate fs->idle_age and
880
 * fs->hard_age, so those members will usually be set to 0.  If the switch from
881
 * which 'msg' originated is known to implement NXT_FLOW_AGE, then pass
882
 * 'flow_age_extension' as true so that the contents of 'msg' determine the
883
 * 'idle_age' and 'hard_age' members in 'fs'.
884
 *
885
 * Uses 'ofpacts' to store the abstract OFPACT_* version of the flow stats
886
 * reply's actions.  The caller must initialize 'ofpacts' and retains ownership
887
 * of it.  'fs->ofpacts' will point into the 'ofpacts' buffer.
888
 *
889
 * Returns 0 if successful, EOF if no replies were left in this 'msg',
890
 * otherwise an OFPERR_* value. */
891
int
892
ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
893
                                struct ofpbuf *msg,
894
                                bool flow_age_extension,
895
                                struct ofpbuf *ofpacts)
896
40.0k
{
897
40.0k
    const struct ofp_header *oh;
898
40.0k
    size_t instructions_len;
899
40.0k
    enum ofperr error;
900
40.0k
    enum ofpraw raw;
901
902
40.0k
    error = (msg->header ? ofpraw_decode(&raw, msg->header)
903
40.0k
             : ofpraw_pull(&raw, msg));
904
40.0k
    if (error) {
905
0
        return error;
906
0
    }
907
40.0k
    oh = msg->header;
908
909
40.0k
    if (!msg->size) {
910
2.50k
        return EOF;
911
37.5k
    } else if (raw == OFPRAW_OFPST15_FLOW_REPLY) {
912
27.8k
        const struct ofp15_flow_desc *ofd;
913
27.8k
        size_t length;
914
27.8k
        uint16_t padded_match_len;
915
27.8k
        uint16_t stat_len;
916
27.8k
        uint8_t oxs_field_set;
917
918
27.8k
        ofd = ofpbuf_try_pull(msg, sizeof *ofd);
919
27.8k
        if (!ofd) {
920
7.84k
            VLOG_WARN_RL(&rl, "OFPST_FLOW reply has %" PRIu32
921
7.84k
                         " leftover " "bytes at end", msg->size);
922
7.84k
            return EINVAL;
923
7.84k
        }
924
925
20.0k
        length = ntohs(ofd->length);
926
20.0k
        if (length < sizeof *ofd) {
927
2.04k
            VLOG_WARN_RL(&rl, "OFPST_FLOW reply claims invalid "
928
2.04k
                         "length %" PRIuSIZE, length);
929
2.04k
            return EINVAL;
930
2.04k
        }
931
932
17.9k
        if (ofputil_pull_ofp11_match(msg, NULL, NULL, &fs->match,
933
17.9k
                                     &padded_match_len)) {
934
4.97k
            VLOG_WARN_RL(&rl, "OFPST_FLOW reply bad match");
935
4.97k
            return EINVAL;
936
4.97k
        }
937
938
13.0k
        fs->priority = ntohs(ofd->priority);
939
13.0k
        fs->table_id = ofd->table_id;
940
13.0k
        fs->cookie = ofd->cookie;
941
13.0k
        fs->idle_timeout = ntohs(ofd->idle_timeout);
942
13.0k
        fs->hard_timeout = ntohs(ofd->hard_timeout);
943
13.0k
        fs->importance = ntohs(ofd->importance);
944
945
13.0k
        error = ofputil_decode_flow_mod_flags(ofd->flags, -1, oh->version,
946
13.0k
                                                &fs->flags);
947
13.0k
        if (error) {
948
1.54k
            return error;
949
1.54k
        }
950
951
11.4k
        struct oxs_stats oxs;
952
11.4k
        if (oxs_pull_stat(msg, &oxs, &stat_len, &oxs_field_set)) {
953
1.96k
            VLOG_WARN_RL(&rl, "OXS OFPST_FLOW reply bad stats");
954
1.96k
            return EINVAL;
955
1.96k
        }
956
9.50k
        fs->duration_sec = oxs.duration_sec;
957
9.50k
        fs->duration_nsec = oxs.duration_nsec;
958
9.50k
        fs->packet_count = oxs.packet_count;
959
9.50k
        fs->byte_count = oxs.byte_count;
960
9.50k
        fs->idle_age = oxs.idle_age == UINT32_MAX ? -1 : oxs.idle_age;
961
9.50k
        fs->hard_age = -1;
962
963
9.50k
        instructions_len = length - sizeof *ofd - padded_match_len - stat_len;
964
9.69k
    } else if (raw == OFPRAW_OFPST11_FLOW_REPLY
965
8.20k
               || raw == OFPRAW_OFPST13_FLOW_REPLY) {
966
3.34k
        const struct ofp11_flow_stats *ofs;
967
3.34k
        size_t length;
968
3.34k
        uint16_t padded_match_len;
969
970
3.34k
        ofs = ofpbuf_try_pull(msg, sizeof *ofs);
971
3.34k
        if (!ofs) {
972
590
            VLOG_WARN_RL(&rl, "OFPST_FLOW reply has %"PRIu32" leftover "
973
590
                         "bytes at end", msg->size);
974
590
            return OFPERR_OFPBRC_BAD_LEN;
975
590
        }
976
977
2.75k
        length = ntohs(ofs->length);
978
2.75k
        if (length < sizeof *ofs) {
979
541
            VLOG_WARN_RL(&rl, "OFPST_FLOW reply claims invalid "
980
541
                         "length %"PRIuSIZE, length);
981
541
            return OFPERR_OFPBRC_BAD_LEN;
982
541
        }
983
984
2.21k
        error = ofputil_pull_ofp11_match(msg, NULL, NULL, &fs->match,
985
2.21k
                                         &padded_match_len);
986
2.21k
        if (error) {
987
163
            VLOG_WARN_RL(&rl, "OFPST_FLOW reply bad match");
988
163
            return error;
989
163
        }
990
2.05k
        instructions_len = length - sizeof *ofs - padded_match_len;
991
992
2.05k
        fs->priority = ntohs(ofs->priority);
993
2.05k
        fs->table_id = ofs->table_id;
994
2.05k
        fs->duration_sec = ntohl(ofs->duration_sec);
995
2.05k
        fs->duration_nsec = ntohl(ofs->duration_nsec);
996
2.05k
        fs->idle_timeout = ntohs(ofs->idle_timeout);
997
2.05k
        fs->hard_timeout = ntohs(ofs->hard_timeout);
998
2.05k
        if (oh->version >= OFP14_VERSION) {
999
87
            fs->importance = ntohs(ofs->importance);
1000
1.96k
        } else {
1001
1.96k
            fs->importance = 0;
1002
1.96k
        }
1003
2.05k
        if (raw == OFPRAW_OFPST13_FLOW_REPLY) {
1004
1.51k
            error = ofputil_decode_flow_mod_flags(ofs->flags, -1, oh->version,
1005
1.51k
                                                  &fs->flags);
1006
1.51k
            if (error) {
1007
1.43k
                return error;
1008
1.43k
            }
1009
1.51k
        } else {
1010
536
            fs->flags = 0;
1011
536
        }
1012
617
        fs->idle_age = -1;
1013
617
        fs->hard_age = -1;
1014
617
        fs->cookie = ofs->cookie;
1015
617
        fs->packet_count = ntohll(ofs->packet_count);
1016
617
        fs->byte_count = ntohll(ofs->byte_count);
1017
6.35k
    } else if (raw == OFPRAW_OFPST10_FLOW_REPLY) {
1018
860
        const struct ofp10_flow_stats *ofs;
1019
860
        size_t length;
1020
1021
860
        ofs = ofpbuf_try_pull(msg, sizeof *ofs);
1022
860
        if (!ofs) {
1023
105
            VLOG_WARN_RL(&rl, "OFPST_FLOW reply has %"PRIu32" leftover "
1024
105
                         "bytes at end", msg->size);
1025
105
            return OFPERR_OFPBRC_BAD_LEN;
1026
105
        }
1027
1028
755
        length = ntohs(ofs->length);
1029
755
        if (length < sizeof *ofs) {
1030
562
            VLOG_WARN_RL(&rl, "OFPST_FLOW reply claims invalid "
1031
562
                         "length %"PRIuSIZE, length);
1032
562
            return OFPERR_OFPBRC_BAD_LEN;
1033
562
        }
1034
193
        instructions_len = length - sizeof *ofs;
1035
1036
193
        fs->cookie = get_32aligned_be64(&ofs->cookie);
1037
193
        ofputil_match_from_ofp10_match(&ofs->match, &fs->match);
1038
193
        fs->priority = ntohs(ofs->priority);
1039
193
        fs->table_id = ofs->table_id;
1040
193
        fs->duration_sec = ntohl(ofs->duration_sec);
1041
193
        fs->duration_nsec = ntohl(ofs->duration_nsec);
1042
193
        fs->idle_timeout = ntohs(ofs->idle_timeout);
1043
193
        fs->hard_timeout = ntohs(ofs->hard_timeout);
1044
193
        fs->importance = 0;
1045
193
        fs->idle_age = -1;
1046
193
        fs->hard_age = -1;
1047
193
        fs->packet_count = ntohll(get_32aligned_be64(&ofs->packet_count));
1048
193
        fs->byte_count = ntohll(get_32aligned_be64(&ofs->byte_count));
1049
193
        fs->flags = 0;
1050
5.49k
    } else if (raw == OFPRAW_NXST_FLOW_REPLY) {
1051
5.49k
        const struct nx_flow_stats *nfs;
1052
5.49k
        size_t match_len, length;
1053
1054
5.49k
        nfs = ofpbuf_try_pull(msg, sizeof *nfs);
1055
5.49k
        if (!nfs) {
1056
979
            VLOG_WARN_RL(&rl, "NXST_FLOW reply has %"PRIu32" leftover "
1057
979
                         "bytes at end", msg->size);
1058
979
            return OFPERR_OFPBRC_BAD_LEN;
1059
979
        }
1060
1061
4.51k
        length = ntohs(nfs->length);
1062
4.51k
        match_len = ntohs(nfs->match_len);
1063
4.51k
        if (length < sizeof *nfs + ROUND_UP(match_len, 8)) {
1064
346
            VLOG_WARN_RL(&rl, "NXST_FLOW reply with match_len=%"PRIuSIZE" "
1065
346
                         "claims invalid length %"PRIuSIZE, match_len, length);
1066
346
            return OFPERR_OFPBRC_BAD_LEN;
1067
346
        }
1068
4.16k
        error = nx_pull_match(msg, match_len, &fs->match, NULL, NULL, false,
1069
4.16k
                              NULL, NULL);
1070
4.16k
        if (error) {
1071
256
            return error;
1072
256
        }
1073
3.91k
        instructions_len = length - sizeof *nfs - ROUND_UP(match_len, 8);
1074
1075
3.91k
        fs->cookie = nfs->cookie;
1076
3.91k
        fs->table_id = nfs->table_id;
1077
3.91k
        fs->duration_sec = ntohl(nfs->duration_sec);
1078
3.91k
        fs->duration_nsec = ntohl(nfs->duration_nsec);
1079
3.91k
        fs->priority = ntohs(nfs->priority);
1080
3.91k
        fs->idle_timeout = ntohs(nfs->idle_timeout);
1081
3.91k
        fs->hard_timeout = ntohs(nfs->hard_timeout);
1082
3.91k
        fs->importance = 0;
1083
3.91k
        fs->idle_age = -1;
1084
3.91k
        fs->hard_age = -1;
1085
3.91k
        if (flow_age_extension) {
1086
3.91k
            if (nfs->idle_age) {
1087
328
                fs->idle_age = ntohs(nfs->idle_age) - 1;
1088
328
            }
1089
3.91k
            if (nfs->hard_age) {
1090
2.27k
                fs->hard_age = ntohs(nfs->hard_age) - 1;
1091
2.27k
            }
1092
3.91k
        }
1093
3.91k
        fs->packet_count = ntohll(nfs->packet_count);
1094
3.91k
        fs->byte_count = ntohll(nfs->byte_count);
1095
3.91k
        fs->flags = 0;
1096
3.91k
    } else {
1097
0
        OVS_NOT_REACHED();
1098
0
    }
1099
1100
14.2k
    error = ofpacts_pull_openflow_instructions(msg, instructions_len,
1101
14.2k
                                               oh->version, NULL, NULL,
1102
14.2k
                                               ofpacts);
1103
14.2k
    if (error) {
1104
2.23k
        VLOG_WARN_RL(&rl, "OFPST_FLOW reply bad instructions");
1105
2.23k
        return error;
1106
2.23k
    }
1107
11.9k
    fs->ofpacts = ofpacts->data;
1108
11.9k
    fs->ofpacts_len = ofpacts->size;
1109
1110
11.9k
    return 0;
1111
14.2k
}
1112
1113
/* Returns 'count' unchanged except that UINT64_MAX becomes 0.
1114
 *
1115
 * We use this in situations where OVS internally uses UINT64_MAX to mean
1116
 * "value unknown" but OpenFlow 1.0 does not define any unknown value. */
1117
static uint64_t
1118
unknown_to_zero(uint64_t count)
1119
0
{
1120
0
    return count != UINT64_MAX ? count : 0;
1121
0
}
1122
1123
/* Appends an OFPST_FLOW or NXST_FLOW reply that contains the data in 'fs' to
1124
 * those already present in the list of ofpbufs in 'replies'.  'replies' should
1125
 * have been initialized with ofpmp_init(). */
1126
void
1127
ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
1128
                                struct ovs_list *replies,
1129
                                const struct tun_table *tun_table)
1130
0
{
1131
0
    struct ofputil_flow_stats *fs_ = CONST_CAST(struct ofputil_flow_stats *,
1132
0
                                                fs);
1133
0
    const struct tun_table *orig_tun_table;
1134
0
    struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
1135
0
    size_t start_ofs = reply->size;
1136
0
    enum ofp_version version = ofpmp_version(replies);
1137
0
    enum ofpraw raw = ofpmp_decode_raw(replies);
1138
1139
0
    orig_tun_table = fs->match.flow.tunnel.metadata.tab;
1140
0
    fs_->match.flow.tunnel.metadata.tab = tun_table;
1141
1142
0
    if (raw == OFPRAW_OFPST15_FLOW_REPLY) {
1143
0
        struct ofp15_flow_desc *ofd;
1144
1145
0
        ofpbuf_put_uninit(reply, sizeof *ofd);
1146
0
        oxm_put_match(reply, &fs->match, version);
1147
1148
0
        struct oxs_stats oxs = {
1149
0
            .duration_sec = fs->duration_sec,
1150
0
            .duration_nsec = fs->duration_nsec,
1151
0
            .idle_age = fs->idle_age >= 0 ? fs->idle_age : UINT32_MAX,
1152
0
            .packet_count = fs->packet_count,
1153
0
            .byte_count = fs->byte_count,
1154
0
            .flow_count = UINT32_MAX,
1155
0
        };
1156
0
        oxs_put_stats(reply, &oxs);
1157
1158
0
        ofpacts_put_openflow_instructions(fs->ofpacts, fs->ofpacts_len, reply,
1159
0
                                      version);
1160
1161
0
        ofd = ofpbuf_at_assert(reply, start_ofs, sizeof *ofd);
1162
0
        ofd->length = htons(reply->size - start_ofs);
1163
0
        ofd->table_id = fs->table_id;
1164
0
        ofd->priority = htons(fs->priority);
1165
0
        ofd->idle_timeout = htons(fs->idle_timeout);
1166
0
        ofd->hard_timeout = htons(fs->hard_timeout);
1167
0
        ofd->cookie = fs->cookie;
1168
0
        memset(ofd->pad2, 0, sizeof ofd->pad2);
1169
0
        ofd->pad = 0;
1170
0
        ofd->importance = htons(fs->importance);
1171
0
        ofd->flags = ofputil_encode_flow_mod_flags(fs->flags, version);
1172
0
    } else if (raw == OFPRAW_OFPST11_FLOW_REPLY ||
1173
0
               raw == OFPRAW_OFPST13_FLOW_REPLY) {
1174
0
        struct ofp11_flow_stats *ofs;
1175
1176
0
        ofpbuf_put_uninit(reply, sizeof *ofs);
1177
0
        oxm_put_match(reply, &fs->match, version);
1178
0
        ofpacts_put_openflow_instructions(fs->ofpacts, fs->ofpacts_len, reply,
1179
0
                                          version);
1180
1181
0
        ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
1182
0
        ofs->length = htons(reply->size - start_ofs);
1183
0
        ofs->table_id = fs->table_id;
1184
0
        ofs->pad = 0;
1185
0
        ofs->duration_sec = htonl(fs->duration_sec);
1186
0
        ofs->duration_nsec = htonl(fs->duration_nsec);
1187
0
        ofs->priority = htons(fs->priority);
1188
0
        ofs->idle_timeout = htons(fs->idle_timeout);
1189
0
        ofs->hard_timeout = htons(fs->hard_timeout);
1190
0
        if (version >= OFP14_VERSION) {
1191
0
            ofs->importance = htons(fs->importance);
1192
0
        } else {
1193
0
            ofs->importance = 0;
1194
0
        }
1195
0
        if (raw == OFPRAW_OFPST13_FLOW_REPLY) {
1196
0
            ofs->flags = ofputil_encode_flow_mod_flags(fs->flags, version);
1197
0
        } else {
1198
0
            ofs->flags = 0;
1199
0
        }
1200
0
        memset(ofs->pad2, 0, sizeof ofs->pad2);
1201
0
        ofs->cookie = fs->cookie;
1202
0
        ofs->packet_count = htonll(unknown_to_zero(fs->packet_count));
1203
0
        ofs->byte_count = htonll(unknown_to_zero(fs->byte_count));
1204
0
    } else if (raw == OFPRAW_OFPST10_FLOW_REPLY) {
1205
0
        struct ofp10_flow_stats *ofs;
1206
1207
0
        ofpbuf_put_uninit(reply, sizeof *ofs);
1208
0
        ofpacts_put_openflow_actions(fs->ofpacts, fs->ofpacts_len, reply,
1209
0
                                     version);
1210
0
        ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
1211
0
        ofs->length = htons(reply->size - start_ofs);
1212
0
        ofs->table_id = fs->table_id;
1213
0
        ofs->pad = 0;
1214
0
        ofputil_match_to_ofp10_match(&fs->match, &ofs->match);
1215
0
        ofs->duration_sec = htonl(fs->duration_sec);
1216
0
        ofs->duration_nsec = htonl(fs->duration_nsec);
1217
0
        ofs->priority = htons(fs->priority);
1218
0
        ofs->idle_timeout = htons(fs->idle_timeout);
1219
0
        ofs->hard_timeout = htons(fs->hard_timeout);
1220
0
        memset(ofs->pad2, 0, sizeof ofs->pad2);
1221
0
        put_32aligned_be64(&ofs->cookie, fs->cookie);
1222
0
        put_32aligned_be64(&ofs->packet_count,
1223
0
                           htonll(unknown_to_zero(fs->packet_count)));
1224
0
        put_32aligned_be64(&ofs->byte_count,
1225
0
                           htonll(unknown_to_zero(fs->byte_count)));
1226
0
    } else if (raw == OFPRAW_NXST_FLOW_REPLY) {
1227
0
        struct nx_flow_stats *nfs;
1228
0
        int match_len;
1229
1230
0
        ofpbuf_put_uninit(reply, sizeof *nfs);
1231
0
        match_len = nx_put_match(reply, &fs->match, 0, 0);
1232
0
        ofpacts_put_openflow_actions(fs->ofpacts, fs->ofpacts_len, reply,
1233
0
                                     version);
1234
0
        nfs = ofpbuf_at_assert(reply, start_ofs, sizeof *nfs);
1235
0
        nfs->length = htons(reply->size - start_ofs);
1236
0
        nfs->table_id = fs->table_id;
1237
0
        nfs->pad = 0;
1238
0
        nfs->duration_sec = htonl(fs->duration_sec);
1239
0
        nfs->duration_nsec = htonl(fs->duration_nsec);
1240
0
        nfs->priority = htons(fs->priority);
1241
0
        nfs->idle_timeout = htons(fs->idle_timeout);
1242
0
        nfs->hard_timeout = htons(fs->hard_timeout);
1243
0
        nfs->idle_age = htons(fs->idle_age < 0 ? 0
1244
0
                              : fs->idle_age < UINT16_MAX ? fs->idle_age + 1
1245
0
                              : UINT16_MAX);
1246
0
        nfs->hard_age = htons(fs->hard_age < 0 ? 0
1247
0
                              : fs->hard_age < UINT16_MAX ? fs->hard_age + 1
1248
0
                              : UINT16_MAX);
1249
0
        nfs->match_len = htons(match_len);
1250
0
        nfs->cookie = fs->cookie;
1251
0
        nfs->packet_count = htonll(fs->packet_count);
1252
0
        nfs->byte_count = htonll(fs->byte_count);
1253
0
    } else {
1254
0
        OVS_NOT_REACHED();
1255
0
    }
1256
1257
0
    if ((reply->size - start_ofs) > (UINT16_MAX - ofpbuf_headersize(reply))) {
1258
        /* When this happens, the reply will not fit in a single OFP message,
1259
         * and we should not append it to the queue. We will log a warning
1260
         * and continue with the next flow stat entry. */
1261
0
        reply->size = start_ofs;
1262
0
        VLOG_WARN_RL(&rl, "Flow exceeded the maximum flow statistics reply "
1263
0
                     "size and was excluded from the response set");
1264
0
    } else {
1265
0
        ofpmp_postappend(replies, start_ofs);
1266
0
    }
1267
0
    fs_->match.flow.tunnel.metadata.tab = orig_tun_table;
1268
0
}
1269
1270
static void
1271
print_flow_stat(struct ds *string, const char *leader, uint64_t stat)
1272
23.9k
{
1273
23.9k
    ds_put_format(string, "%s%s=%s", colors.param, leader, colors.end);
1274
23.9k
    if (stat != UINT64_MAX) {
1275
8.25k
        ds_put_format(string, "%"PRIu64, stat);
1276
15.7k
    } else {
1277
15.7k
        ds_put_char(string, '?');
1278
15.7k
    }
1279
23.9k
    ds_put_cstr(string, ", ");
1280
23.9k
}
1281
1282
/* Appends a textual form of 'fs' to 'string', translating port numbers to
1283
 * names using 'port_map' (if provided).  If 'show_stats' is true, the output
1284
 * includes the flow duration, packet and byte counts, and its idle and hard
1285
 * ages, otherwise they are omitted. */
1286
void
1287
ofputil_flow_stats_format(struct ds *string,
1288
                          const struct ofputil_flow_stats *fs,
1289
                          const struct ofputil_port_map *port_map,
1290
                          const struct ofputil_table_map *table_map,
1291
                          bool show_stats)
1292
11.9k
{
1293
11.9k
    if (show_stats || fs->cookie) {
1294
11.9k
        ds_put_format(string, "%scookie=%s0x%"PRIx64", ",
1295
11.9k
                      colors.param, colors.end, ntohll(fs->cookie));
1296
11.9k
    }
1297
11.9k
    if (show_stats) {
1298
11.9k
        ds_put_format(string, "%sduration=%s", colors.param, colors.end);
1299
11.9k
        ofp_print_duration(string, fs->duration_sec, fs->duration_nsec);
1300
11.9k
        ds_put_cstr(string, ", ");
1301
11.9k
    }
1302
1303
11.9k
    if (show_stats || fs->table_id
1304
11.9k
        || ofputil_table_map_get_name(table_map, fs->table_id) != NULL) {
1305
11.9k
        ds_put_format(string, "%stable=%s", colors.special, colors.end);
1306
11.9k
        ofputil_format_table(fs->table_id, table_map, string);
1307
11.9k
        ds_put_cstr(string, ", ");
1308
11.9k
    }
1309
11.9k
    if (show_stats) {
1310
11.9k
        print_flow_stat(string, "n_packets", fs->packet_count);
1311
11.9k
        print_flow_stat(string, "n_bytes", fs->byte_count);
1312
11.9k
    }
1313
11.9k
    if (fs->idle_timeout != OFP_FLOW_PERMANENT) {
1314
8.48k
        ds_put_format(string, "%sidle_timeout=%s%"PRIu16", ",
1315
8.48k
                      colors.param, colors.end, fs->idle_timeout);
1316
8.48k
    }
1317
11.9k
    if (fs->hard_timeout != OFP_FLOW_PERMANENT) {
1318
5.44k
        ds_put_format(string, "%shard_timeout=%s%"PRIu16", ",
1319
5.44k
                      colors.param, colors.end, fs->hard_timeout);
1320
5.44k
    }
1321
11.9k
    if (fs->flags) {
1322
5.79k
        ofputil_flow_mod_flags_format(string, fs->flags);
1323
5.79k
    }
1324
11.9k
    if (fs->importance != 0) {
1325
7.80k
        ds_put_format(string, "%simportance=%s%"PRIu16", ",
1326
7.80k
                      colors.param, colors.end, fs->importance);
1327
7.80k
    }
1328
11.9k
    if (show_stats && fs->idle_age >= 0) {
1329
291
        ds_put_format(string, "%sidle_age=%s%d, ",
1330
291
                      colors.param, colors.end, fs->idle_age);
1331
291
    }
1332
11.9k
    if (show_stats && fs->hard_age >= 0 && fs->hard_age != fs->duration_sec) {
1333
2.22k
        ds_put_format(string, "%shard_age=%s%d, ",
1334
2.22k
                      colors.param, colors.end, fs->hard_age);
1335
2.22k
    }
1336
1337
    /* Print the match, followed by a space (but omit the space if the match
1338
     * was an empty string). */
1339
11.9k
    size_t length = string->length;
1340
11.9k
    match_format(&fs->match, port_map, string, fs->priority);
1341
11.9k
    if (string->length != length) {
1342
11.9k
        ds_put_char(string, ' ');
1343
11.9k
    }
1344
1345
11.9k
    ds_put_format(string, "%sactions=%s", colors.actions, colors.end);
1346
11.9k
    struct ofpact_format_params fp = {
1347
11.9k
        .port_map = port_map,
1348
11.9k
        .table_map = table_map,
1349
11.9k
        .s = string,
1350
11.9k
    };
1351
11.9k
    ofpacts_format(fs->ofpacts, fs->ofpacts_len, &fp);
1352
11.9k
}
1353
1354
/* Converts abstract ofputil_aggregate_stats 'stats' into an OFPST_AGGREGATE or
1355
 * NXST_AGGREGATE reply matching 'request', and returns the message. */
1356
struct ofpbuf *
1357
ofputil_encode_aggregate_stats_reply(
1358
    const struct ofputil_aggregate_stats *stats,
1359
    const struct ofp_header *request)
1360
0
{
1361
0
    struct ofp_aggregate_stats_reply *asr;
1362
0
    uint64_t packet_count;
1363
0
    uint64_t byte_count;
1364
0
    struct ofpbuf *msg;
1365
0
    enum ofpraw raw;
1366
1367
0
    ofpraw_decode(&raw, request);
1368
0
    if (raw == OFPRAW_OFPST15_AGGREGATE_REQUEST) {
1369
0
        msg = ofpraw_alloc_stats_reply(request, 0);
1370
1371
0
        struct oxs_stats oxs = {
1372
0
            .duration_sec = UINT32_MAX,
1373
0
            .duration_nsec = UINT32_MAX,
1374
0
            .idle_age = UINT32_MAX,
1375
0
            .packet_count = stats->packet_count,
1376
0
            .byte_count = stats->byte_count,
1377
0
            .flow_count = stats->flow_count,
1378
0
        };
1379
0
        oxs_put_stats(msg, &oxs);
1380
0
    } else {
1381
0
        if (raw == OFPRAW_OFPST10_AGGREGATE_REQUEST) {
1382
0
            packet_count = unknown_to_zero(stats->packet_count);
1383
0
            byte_count = unknown_to_zero(stats->byte_count);
1384
0
        } else {
1385
0
            packet_count = stats->packet_count;
1386
0
            byte_count = stats->byte_count;
1387
0
        }
1388
1389
0
        msg = ofpraw_alloc_stats_reply(request, 0);
1390
0
        asr = ofpbuf_put_zeros(msg, sizeof *asr);
1391
0
        put_32aligned_be64(&asr->packet_count, htonll(packet_count));
1392
0
        put_32aligned_be64(&asr->byte_count, htonll(byte_count));
1393
0
        asr->flow_count = htonl(stats->flow_count);
1394
0
    }
1395
0
    return msg;
1396
0
}
1397
1398
enum ofperr
1399
ofputil_decode_aggregate_stats_reply(struct ofputil_aggregate_stats *stats,
1400
                                     const struct ofp_header *reply)
1401
3.04k
{
1402
3.04k
    struct ofpbuf msg = ofpbuf_const_initializer(reply, ntohs(reply->length));
1403
3.04k
    enum ofpraw raw;
1404
1405
3.04k
    raw = ofpraw_pull_assert(&msg);
1406
3.04k
    if (raw == OFPRAW_OFPST15_AGGREGATE_REPLY) {
1407
2.98k
        struct oxs_stats oxs;
1408
2.98k
        uint16_t statlen;
1409
2.98k
        uint8_t oxs_field_set;
1410
2.98k
        enum ofperr error = oxs_pull_stat(&msg, &oxs, &statlen,
1411
2.98k
                                          &oxs_field_set);
1412
2.98k
        if (error) {
1413
2.84k
            return error;
1414
2.84k
        }
1415
132
        stats->packet_count = oxs.packet_count;
1416
132
        stats->byte_count = oxs.byte_count;
1417
132
        stats->flow_count = oxs.flow_count;
1418
132
    } else {
1419
69
        struct ofp_aggregate_stats_reply *asr = msg.msg;
1420
69
        stats->packet_count = ntohll(get_32aligned_be64(&asr->packet_count));
1421
69
        stats->byte_count = ntohll(get_32aligned_be64(&asr->byte_count));
1422
69
        stats->flow_count = ntohl(asr->flow_count);
1423
69
    }
1424
1425
201
    return 0;
1426
3.04k
}
1427
1428
void
1429
ofputil_aggregate_stats_format(struct ds *s,
1430
                               const struct ofputil_aggregate_stats *as)
1431
201
{
1432
201
    ds_put_format(s, " packet_count=%"PRIu64, as->packet_count);
1433
201
    ds_put_format(s, " byte_count=%"PRIu64, as->byte_count);
1434
201
    ds_put_format(s, " flow_count=%"PRIu32, as->flow_count);
1435
201
}
1436

1437
/* Parses 'str_value' as the value of subfield 'name', and updates
1438
 * 'match' appropriately.  Restricts the set of usable protocols to ones
1439
 * supporting the parsed field.
1440
 *
1441
 * Returns NULL if successful, otherwise a malloc()'d string describing the
1442
 * error.  The caller is responsible for freeing the returned string. */
1443
static char * OVS_WARN_UNUSED_RESULT
1444
parse_subfield(const char *name, const char *str_value, struct match *match,
1445
               enum ofputil_protocol *usable_protocols)
1446
44.7k
{
1447
44.7k
    struct mf_subfield sf;
1448
44.7k
    char *error;
1449
1450
44.7k
    error = mf_parse_subfield(&sf, name);
1451
44.7k
    if (!error) {
1452
44.2k
        union mf_value val;
1453
44.2k
        char *tail;
1454
44.2k
        if (parse_int_string(str_value, (uint8_t *)&val, sf.field->n_bytes,
1455
44.2k
                             &tail) || *tail != 0) {
1456
38
            return xasprintf("%s: cannot parse integer value: %s", name,
1457
38
                             str_value);
1458
38
        }
1459
44.2k
        if (!bitwise_is_all_zeros(&val, sf.field->n_bytes, sf.n_bits,
1460
44.2k
                                  sf.field->n_bytes * 8 - sf.n_bits)) {
1461
124
            struct ds ds;
1462
1463
124
            ds_init(&ds);
1464
124
            mf_format(sf.field, &val, NULL, NULL, &ds);
1465
124
            error = xasprintf("%s: value %s does not fit into %d bits",
1466
124
                              name, ds_cstr(&ds), sf.n_bits);
1467
124
            ds_destroy(&ds);
1468
124
            return error;
1469
124
        }
1470
1471
44.1k
        const struct mf_field *field = sf.field;
1472
44.1k
        union mf_value value, mask;
1473
44.1k
        unsigned int size = field->n_bytes;
1474
1475
44.1k
        mf_get(field, match, &value, &mask);
1476
44.1k
        bitwise_copy(&val, size, 0, &value, size, sf.ofs, sf.n_bits);
1477
44.1k
        bitwise_one (               &mask,  size, sf.ofs, sf.n_bits);
1478
44.1k
        *usable_protocols &= mf_set(field, &value, &mask, match, &error);
1479
1480
44.1k
        match_add_ethernet_prereq(match, sf.field);
1481
44.1k
    }
1482
44.6k
    return error;
1483
44.7k
}
1484
1485
static char * OVS_WARN_UNUSED_RESULT
1486
parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string,
1487
                const struct ofputil_port_map *port_map,
1488
                const struct ofputil_table_map *table_map,
1489
                enum ofputil_protocol *usable_protocols)
1490
22.5k
{
1491
22.5k
    enum {
1492
22.5k
        F_OUT_PORT = 1 << 0,
1493
22.5k
        F_ACTIONS = 1 << 1,
1494
22.5k
        F_IMPORTANCE = 1 << 2,
1495
22.5k
        F_TIMEOUT = 1 << 3,
1496
22.5k
        F_PRIORITY = 1 << 4,
1497
22.5k
        F_FLAGS = 1 << 5,
1498
22.5k
    } fields;
1499
22.5k
    char *act_str = NULL;
1500
22.5k
    char *name, *value;
1501
1502
22.5k
    *usable_protocols = OFPUTIL_P_ANY;
1503
1504
22.5k
    if (command == -2) {
1505
2.37k
        size_t len;
1506
1507
2.37k
        string += strspn(string, " \t\r\n");   /* Skip white space. */
1508
2.37k
        len = strcspn(string, ", \t\r\n"); /* Get length of the first token. */
1509
1510
2.37k
        if (!strncmp(string, "add", len)) {
1511
8
            command = OFPFC_ADD;
1512
2.36k
        } else if (!strncmp(string, "delete", len)) {
1513
7
            command = OFPFC_DELETE;
1514
2.35k
        } else if (!strncmp(string, "delete_strict", len)) {
1515
1
            command = OFPFC_DELETE_STRICT;
1516
2.35k
        } else if (!strncmp(string, "modify", len)) {
1517
1
            command = OFPFC_MODIFY;
1518
2.35k
        } else if (!strncmp(string, "modify_strict", len)) {
1519
1
            command = OFPFC_MODIFY_STRICT;
1520
2.35k
        } else {
1521
2.35k
            len = 0;
1522
2.35k
            command = OFPFC_ADD;
1523
2.35k
        }
1524
2.37k
        string += len;
1525
2.37k
    }
1526
1527
22.5k
    switch (command) {
1528
799
    case -1:
1529
799
        fields = F_OUT_PORT;
1530
799
        break;
1531
1532
4.03k
    case OFPFC_ADD:
1533
4.03k
        fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS | F_IMPORTANCE;
1534
4.03k
        break;
1535
1536
3.43k
    case OFPFC_DELETE:
1537
3.43k
        fields = F_OUT_PORT;
1538
3.43k
        break;
1539
1540
3.30k
    case OFPFC_DELETE_STRICT:
1541
3.30k
        fields = F_OUT_PORT | F_PRIORITY;
1542
3.30k
        break;
1543
1544
6.81k
    case OFPFC_MODIFY:
1545
6.81k
        fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS;
1546
6.81k
        break;
1547
1548
4.16k
    case OFPFC_MODIFY_STRICT:
1549
4.16k
        fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS;
1550
4.16k
        break;
1551
1552
0
    default:
1553
0
        OVS_NOT_REACHED();
1554
22.5k
    }
1555
1556
22.5k
    *fm = (struct ofputil_flow_mod) {
1557
22.5k
        .priority = OFP_DEFAULT_PRIORITY,
1558
22.5k
        .table_id = 0xff,
1559
22.5k
        .command = command,
1560
22.5k
        .buffer_id = UINT32_MAX,
1561
22.5k
        .out_port = OFPP_ANY,
1562
22.5k
        .out_group = OFPG_ANY,
1563
22.5k
    };
1564
    /* For modify, by default, don't update the cookie. */
1565
22.5k
    if (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT) {
1566
10.9k
        fm->new_cookie = OVS_BE64_MAX;
1567
10.9k
    }
1568
1569
22.5k
    if (fields & F_ACTIONS) {
1570
15.0k
        act_str = ofp_extract_actions(string);
1571
15.0k
        if (!act_str) {
1572
221
            return xstrdup("must specify an action");
1573
221
        }
1574
15.0k
    }
1575
1576
22.3k
    struct match match = MATCH_CATCHALL_INITIALIZER;
1577
158k
    while (ofputil_parse_key_value(&string, &name, &value)) {
1578
140k
        const struct ofp_protocol *p;
1579
140k
        const struct mf_field *mf;
1580
140k
        char *error = NULL;
1581
1582
140k
        if (ofp_parse_protocol(name, &p)) {
1583
15.7k
            match_set_dl_type(&match, htons(p->dl_type));
1584
15.7k
            if (p->nw_proto) {
1585
8.87k
                match_set_nw_proto(&match, p->nw_proto);
1586
8.87k
            }
1587
15.7k
            match_set_default_packet_type(&match);
1588
125k
        } else if (!strcmp(name, "eth")) {
1589
1.19k
            match_set_packet_type(&match, htonl(PT_ETH));
1590
123k
        } else if (fields & F_FLAGS && !strcmp(name, "send_flow_rem")) {
1591
304
            fm->flags |= OFPUTIL_FF_SEND_FLOW_REM;
1592
123k
        } else if (fields & F_FLAGS && !strcmp(name, "check_overlap")) {
1593
512
            fm->flags |= OFPUTIL_FF_CHECK_OVERLAP;
1594
123k
        } else if (fields & F_FLAGS && !strcmp(name, "reset_counts")) {
1595
512
            fm->flags |= OFPUTIL_FF_RESET_COUNTS;
1596
512
            *usable_protocols &= OFPUTIL_P_OF12_UP;
1597
122k
        } else if (fields & F_FLAGS && !strcmp(name, "no_packet_counts")) {
1598
244
            fm->flags |= OFPUTIL_FF_NO_PKT_COUNTS;
1599
244
            *usable_protocols &= OFPUTIL_P_OF13_UP;
1600
122k
        } else if (fields & F_FLAGS && !strcmp(name, "no_byte_counts")) {
1601
269
            fm->flags |= OFPUTIL_FF_NO_BYT_COUNTS;
1602
269
            *usable_protocols &= OFPUTIL_P_OF13_UP;
1603
121k
        } else if (!strcmp(name, "no_readonly_table")
1604
121k
                   || !strcmp(name, "allow_hidden_fields")) {
1605
             /* ignore these fields. */
1606
121k
        } else if ((mf = mf_from_name(name)) != NULL) {
1607
61.0k
            error = ofp_parse_field(mf, value, port_map,
1608
61.0k
                                    &match, usable_protocols);
1609
61.0k
        } else if (strchr(name, '[')) {
1610
44.7k
            error = parse_subfield(name, value, &match, usable_protocols);
1611
44.7k
        } else {
1612
15.7k
            if (!*value) {
1613
1.35k
                return xasprintf("field %s missing value", name);
1614
1.35k
            }
1615
1616
14.3k
            if (!strcmp(name, "table")) {
1617
6.49k
                if (!ofputil_table_from_string(value, table_map,
1618
6.49k
                                               &fm->table_id)) {
1619
351
                    return xasprintf("unknown table \"%s\"", value);
1620
351
                }
1621
6.14k
                if (fm->table_id != 0xff) {
1622
6.05k
                    *usable_protocols &= OFPUTIL_P_TID;
1623
6.05k
                }
1624
7.88k
            } else if (fields & F_OUT_PORT && !strcmp(name, "out_port")) {
1625
197
                if (!ofputil_port_from_string(value, port_map,
1626
197
                                              &fm->out_port)) {
1627
1
                    error = xasprintf("%s is not a valid OpenFlow port",
1628
1
                                      value);
1629
1
                }
1630
7.68k
            } else if (fields & F_OUT_PORT && !strcmp(name, "out_group")) {
1631
544
                *usable_protocols &= OFPUTIL_P_OF11_UP;
1632
544
                if (!ofputil_group_from_string(value, &fm->out_group)) {
1633
41
                    error = xasprintf("%s is not a valid OpenFlow group",
1634
41
                                      value);
1635
41
                }
1636
7.14k
            } else if (fields & F_PRIORITY && !strcmp(name, "priority")) {
1637
358
                uint16_t priority = 0;
1638
1639
358
                error = str_to_u16(value, name, &priority);
1640
358
                fm->priority = priority;
1641
6.78k
            } else if (fields & F_TIMEOUT && !strcmp(name, "idle_timeout")) {
1642
197
                error = str_to_u16(value, name, &fm->idle_timeout);
1643
6.59k
            } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) {
1644
239
                error = str_to_u16(value, name, &fm->hard_timeout);
1645
6.35k
            } else if (fields & F_IMPORTANCE && !strcmp(name, "importance")) {
1646
197
                error = str_to_u16(value, name, &fm->importance);
1647
6.15k
            } else if (!strcmp(name, "cookie")) {
1648
1.99k
                char *mask = strchr(value, '/');
1649
1650
1.99k
                if (mask) {
1651
                    /* A mask means we're searching for a cookie. */
1652
1.05k
                    if (command == OFPFC_ADD) {
1653
1
                        return xstrdup("flow additions cannot use "
1654
1
                                       "a cookie mask");
1655
1
                    }
1656
1.05k
                    *mask = '\0';
1657
1.05k
                    error = str_to_be64(value, &fm->cookie);
1658
1.05k
                    if (error) {
1659
11
                        return error;
1660
11
                    }
1661
1.04k
                    error = str_to_be64(mask + 1, &fm->cookie_mask);
1662
1663
                    /* Matching of the cookie is only supported through NXM or
1664
                     * OF1.1+. */
1665
1.04k
                    if (fm->cookie_mask != htonll(0)) {
1666
639
                        *usable_protocols &= OFPUTIL_P_NXM_OF11_UP;
1667
639
                    }
1668
1.04k
                } else {
1669
                    /* No mask means that the cookie is being set. */
1670
937
                    if (command != OFPFC_ADD && command != OFPFC_MODIFY
1671
116
                        && command != OFPFC_MODIFY_STRICT) {
1672
1
                        return xasprintf("cannot set cookie (to match on a "
1673
1
                                         "cookie, specify a mask, e.g. "
1674
1
                                         "cookie=%s/-1)", value);
1675
1
                    }
1676
936
                    error = str_to_be64(value, &fm->new_cookie);
1677
936
                    fm->modify_cookie = true;
1678
936
                }
1679
4.16k
            } else if (!strcmp(name, "duration")
1680
3.96k
                       || !strcmp(name, "n_packets")
1681
3.32k
                       || !strcmp(name, "n_bytes")
1682
2.85k
                       || !strcmp(name, "idle_age")
1683
3.20k
                       || !strcmp(name, "hard_age")) {
1684
                /* Ignore these, so that users can feed the output of
1685
                 * "ovs-ofctl dump-flows" back into commands that parse
1686
                 * flows. */
1687
3.20k
            } else {
1688
958
                error = xasprintf("unknown keyword %s", name);
1689
958
            }
1690
14.3k
        }
1691
1692
139k
        if (error) {
1693
2.61k
            return error;
1694
2.61k
        }
1695
139k
    }
1696
    /* Copy ethertype to flow->dl_type for matches on packet_type
1697
     * (OFPHTN_ETHERTYPE, ethertype). */
1698
17.9k
    if (match.wc.masks.packet_type == OVS_BE32_MAX &&
1699
4.64k
            pt_ns(match.flow.packet_type) == OFPHTN_ETHERTYPE) {
1700
117
        match.flow.dl_type = pt_ns_type_be(match.flow.packet_type);
1701
117
    }
1702
    /* Check for usable protocol interdependencies between match fields. */
1703
17.9k
    if (match.flow.dl_type == htons(ETH_TYPE_IPV6)) {
1704
860
        const struct flow_wildcards *wc = &match.wc;
1705
        /* Only NXM and OXM support matching L3 and L4 fields within IPv6.
1706
         *
1707
         * (IPv6 specific fields as well as arp_sha, arp_tha, nw_frag, and
1708
         *  nw_ttl are covered elsewhere so they don't need to be included in
1709
         *  this test too.)
1710
         */
1711
860
        if (wc->masks.nw_proto || wc->masks.nw_tos
1712
460
            || wc->masks.tp_src || wc->masks.tp_dst) {
1713
414
            *usable_protocols &= OFPUTIL_P_NXM_OXM_ANY;
1714
414
        }
1715
860
    }
1716
17.9k
    if (!fm->cookie_mask && fm->new_cookie == OVS_BE64_MAX
1717
10.3k
        && (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT)) {
1718
        /* On modifies without a mask, we are supposed to add a flow if
1719
         * one does not exist.  If a cookie wasn't been specified, use a
1720
         * default of zero. */
1721
10.3k
        fm->new_cookie = htonll(0);
1722
10.3k
    }
1723
17.9k
    if (fields & F_ACTIONS) {
1724
14.0k
        enum ofputil_protocol action_usable_protocols;
1725
14.0k
        struct ofpbuf ofpacts;
1726
14.0k
        char *error;
1727
1728
14.0k
        ofpbuf_init(&ofpacts, 32);
1729
14.0k
        struct ofpact_parse_params pp = {
1730
14.0k
            .port_map = port_map,
1731
14.0k
            .table_map = table_map,
1732
14.0k
            .ofpacts = &ofpacts,
1733
14.0k
            .usable_protocols = &action_usable_protocols
1734
14.0k
        };
1735
14.0k
        error = ofpacts_parse_instructions(act_str, &pp);
1736
14.0k
        *usable_protocols &= action_usable_protocols;
1737
14.0k
        if (!error) {
1738
6.69k
            enum ofperr err;
1739
1740
6.69k
            struct ofpact_check_params cp = {
1741
6.69k
                .match = &match,
1742
6.69k
                .max_ports = OFPP_MAX,
1743
6.69k
                .table_id = fm->table_id,
1744
6.69k
                .n_tables = 255,
1745
6.69k
            };
1746
6.69k
            err = ofpacts_check(ofpacts.data, ofpacts.size, &cp);
1747
6.69k
            *usable_protocols &= cp.usable_protocols;
1748
6.69k
            if (!err && !*usable_protocols) {
1749
16
                err = OFPERR_OFPBAC_MATCH_INCONSISTENT;
1750
16
            }
1751
6.69k
            if (err) {
1752
838
                error = xasprintf("actions are invalid with specified match "
1753
838
                                  "(%s)", ofperr_to_string(err));
1754
838
            }
1755
1756
6.69k
        }
1757
14.0k
        if (error) {
1758
8.18k
            ofpbuf_uninit(&ofpacts);
1759
8.18k
            return error;
1760
8.18k
        }
1761
1762
5.85k
        fm->ofpacts_len = ofpacts.size;
1763
5.85k
        fm->ofpacts = ofpbuf_steal_data(&ofpacts);
1764
5.85k
    } else {
1765
3.95k
        fm->ofpacts_len = 0;
1766
3.95k
        fm->ofpacts = NULL;
1767
3.95k
    }
1768
9.80k
    minimatch_init(&fm->match, &match);
1769
1770
9.80k
    return NULL;
1771
17.9k
}
1772
1773
/* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man
1774
 * page) into 'fm' for sending the specified flow_mod 'command' to a switch.
1775
 * Returns the set of usable protocols in '*usable_protocols'.
1776
 *
1777
 * To parse syntax for an OFPT_FLOW_MOD (or NXT_FLOW_MOD), use an OFPFC_*
1778
 * constant for 'command'.  To parse syntax for an OFPST_FLOW or
1779
 * OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'.
1780
 *
1781
 * If 'command' is given as -2, 'str_' may begin with a command name ("add",
1782
 * "modify", "delete", "modify_strict", or "delete_strict").  A missing command
1783
 * name is treated as "add".
1784
 *
1785
 * Returns NULL if successful, otherwise a malloc()'d string describing the
1786
 * error.  The caller is responsible for freeing the returned string.
1787
 *
1788
 * On success, the caller is responsible for freeing fm->ofpacts and
1789
 * fm->match. */
1790
char * OVS_WARN_UNUSED_RESULT
1791
parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_,
1792
              const struct ofputil_port_map *port_map,
1793
              const struct ofputil_table_map *table_map,
1794
              enum ofputil_protocol *usable_protocols)
1795
22.5k
{
1796
22.5k
    char *string = xstrdup(str_);
1797
22.5k
    char *error;
1798
1799
22.5k
    error = parse_ofp_str__(fm, command, string, port_map, table_map,
1800
22.5k
                            usable_protocols);
1801
22.5k
    if (error) {
1802
12.7k
        fm->ofpacts = NULL;
1803
12.7k
        fm->ofpacts_len = 0;
1804
12.7k
    }
1805
1806
22.5k
    free(string);
1807
22.5k
    return error;
1808
22.5k
}
1809
1810
/* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
1811
 * (one of OFPFC_*) into 'fm'.
1812
 *
1813
 * If 'command' is given as -2, 'string' may begin with a command name ("add",
1814
 * "modify", "delete", "modify_strict", or "delete_strict").  A missing command
1815
 * name is treated as "add".
1816
 *
1817
 * Returns NULL if successful, otherwise a malloc()'d string describing the
1818
 * error.  The caller is responsible for freeing the returned string. */
1819
char * OVS_WARN_UNUSED_RESULT
1820
parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string,
1821
                       const struct ofputil_port_map *port_map,
1822
                       const struct ofputil_table_map *table_map,
1823
                       int command,
1824
                       enum ofputil_protocol *usable_protocols)
1825
22.5k
{
1826
22.5k
    char *error = parse_ofp_str(fm, command, string, port_map, table_map,
1827
22.5k
                                usable_protocols);
1828
1829
22.5k
    if (!error) {
1830
        /* Normalize a copy of the match.  This ensures that non-normalized
1831
         * flows get logged but doesn't affect what gets sent to the switch, so
1832
         * that the switch can do whatever it likes with the flow. */
1833
9.80k
        struct match match;
1834
9.80k
        minimatch_expand(&fm->match, &match);
1835
9.80k
        ofputil_normalize_match(&match);
1836
9.80k
    }
1837
1838
22.5k
    return error;
1839
22.5k
}
1840
1841
/* Opens file 'file_name' and reads each line as a flow_mod of the specified
1842
 * type (one of OFPFC_*).  Stores each flow_mod in '*fm', an array allocated
1843
 * on the caller's behalf, and the number of flow_mods in '*n_fms'.
1844
 *
1845
 * If 'command' is given as -2, each line may start with a command name
1846
 * ("add", "modify", "delete", "modify_strict", or "delete_strict").  A missing
1847
 * command name is treated as "add".
1848
 *
1849
 * Returns NULL if successful, otherwise a malloc()'d string describing the
1850
 * error.  The caller is responsible for freeing the returned string. */
1851
char * OVS_WARN_UNUSED_RESULT
1852
parse_ofp_flow_mod_file(const char *file_name,
1853
                        const struct ofputil_port_map *port_map,
1854
                        const struct ofputil_table_map *table_map,
1855
                        int command,
1856
                        struct ofputil_flow_mod **fms, size_t *n_fms,
1857
                        enum ofputil_protocol *usable_protocols)
1858
0
{
1859
0
    size_t allocated_fms;
1860
0
    int line_number;
1861
0
    FILE *stream;
1862
0
    struct ds s;
1863
1864
0
    *usable_protocols = OFPUTIL_P_ANY;
1865
1866
0
    *fms = NULL;
1867
0
    *n_fms = 0;
1868
1869
0
    stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
1870
0
    if (stream == NULL) {
1871
0
        return xasprintf("%s: open failed (%s)",
1872
0
                         file_name, ovs_strerror(errno));
1873
0
    }
1874
1875
0
    allocated_fms = *n_fms;
1876
0
    ds_init(&s);
1877
0
    line_number = 0;
1878
0
    while (!ds_get_preprocessed_line(&s, stream, &line_number)) {
1879
0
        char *error;
1880
0
        enum ofputil_protocol usable;
1881
1882
0
        if (*n_fms >= allocated_fms) {
1883
0
            *fms = x2nrealloc(*fms, &allocated_fms, sizeof **fms);
1884
0
        }
1885
0
        error = parse_ofp_flow_mod_str(&(*fms)[*n_fms], ds_cstr(&s), port_map,
1886
0
                                       table_map, command, &usable);
1887
0
        if (error) {
1888
0
            char *err_msg;
1889
0
            size_t i;
1890
1891
0
            for (i = 0; i < *n_fms; i++) {
1892
0
                free(CONST_CAST(struct ofpact *, (*fms)[i].ofpacts));
1893
0
                minimatch_destroy(&(*fms)[i].match);
1894
0
            }
1895
0
            free(*fms);
1896
0
            *fms = NULL;
1897
0
            *n_fms = 0;
1898
1899
0
            ds_destroy(&s);
1900
0
            if (stream != stdin) {
1901
0
                fclose(stream);
1902
0
            }
1903
1904
0
            err_msg = xasprintf("%s:%d: %s", file_name, line_number, error);
1905
0
            free(error);
1906
0
            return err_msg;
1907
0
        }
1908
0
        *usable_protocols &= usable; /* Each line can narrow the set. */
1909
0
        *n_fms += 1;
1910
0
    }
1911
1912
0
    ds_destroy(&s);
1913
0
    if (stream != stdin) {
1914
0
        fclose(stream);
1915
0
    }
1916
0
    return NULL;
1917
0
}
1918
1919
/* Parses a specification of a flow from 's' into 'flow'.  's' must take the
1920
 * form FIELD=VALUE[,FIELD=VALUE]... where each FIELD is the name of a
1921
 * mf_field.  Fields must be specified in a natural order for satisfying
1922
 * prerequisites. If 'wc' is specified, masks the field in 'wc' for each of the
1923
 * field specified in flow. If the map, 'names_portno' is specfied, converts
1924
 * the in_port name into port no while setting the 'flow'.
1925
 *
1926
 * Returns NULL on success, otherwise a malloc()'d string that explains the
1927
 * problem. */
1928
char *
1929
parse_ofp_exact_flow(struct flow *flow, struct flow_wildcards *wc,
1930
                     const struct tun_table *tun_table, const char *s,
1931
                     const struct ofputil_port_map *port_map)
1932
0
{
1933
0
    char *pos, *key, *value_s;
1934
0
    char *error = NULL;
1935
0
    char *copy;
1936
1937
0
    memset(flow, 0, sizeof *flow);
1938
0
    if (wc) {
1939
0
        memset(wc, 0, sizeof *wc);
1940
0
    }
1941
0
    flow->tunnel.metadata.tab = tun_table;
1942
1943
0
    pos = copy = xstrdup(s);
1944
0
    while (ofputil_parse_key_value(&pos, &key, &value_s)) {
1945
0
        const struct ofp_protocol *p;
1946
0
        if (ofp_parse_protocol(key, &p)) {
1947
0
            if (flow->dl_type) {
1948
0
                error = xasprintf("%s: Ethernet type set multiple times", s);
1949
0
                goto exit;
1950
0
            }
1951
0
            flow->dl_type = htons(p->dl_type);
1952
0
            if (wc) {
1953
0
                wc->masks.dl_type = OVS_BE16_MAX;
1954
0
            }
1955
1956
0
            if (p->nw_proto) {
1957
0
                if (flow->nw_proto) {
1958
0
                    error = xasprintf("%s: network protocol set "
1959
0
                                      "multiple times", s);
1960
0
                    goto exit;
1961
0
                }
1962
0
                flow->nw_proto = p->nw_proto;
1963
0
                if (wc) {
1964
0
                    wc->masks.nw_proto = UINT8_MAX;
1965
0
                }
1966
0
            }
1967
0
        } else {
1968
0
            const struct mf_field *mf;
1969
0
            union mf_value value;
1970
0
            char *field_error;
1971
1972
0
            mf = mf_from_name(key);
1973
0
            if (!mf) {
1974
0
                error = xasprintf("%s: unknown field %s", s, key);
1975
0
                goto exit;
1976
0
            }
1977
1978
0
            if (!mf_are_prereqs_ok(mf, flow, NULL)) {
1979
0
                error = xasprintf("%s: prerequisites not met for setting %s",
1980
0
                                  s, key);
1981
0
                goto exit;
1982
0
            }
1983
1984
0
            if (mf_is_set(mf, flow)) {
1985
0
                error = xasprintf("%s: field %s set multiple times", s, key);
1986
0
                goto exit;
1987
0
            }
1988
1989
0
            field_error = mf_parse_value(mf, value_s, port_map, &value);
1990
0
            if (field_error) {
1991
0
                error = xasprintf("%s: bad value for %s (%s)",
1992
0
                                  s, key, field_error);
1993
0
                free(field_error);
1994
0
                goto exit;
1995
0
            }
1996
1997
0
            mf_set_flow_value(mf, &value, flow);
1998
0
            if (wc) {
1999
0
                mf_mask_field(mf, wc);
2000
0
            }
2001
0
        }
2002
0
    }
2003
2004
0
    if (!flow->in_port.ofp_port) {
2005
0
        flow->in_port.ofp_port = OFPP_NONE;
2006
0
    }
2007
2008
0
exit:
2009
0
    free(copy);
2010
2011
0
    if (error) {
2012
0
        memset(flow, 0, sizeof *flow);
2013
0
        if (wc) {
2014
0
            memset(wc, 0, sizeof *wc);
2015
0
        }
2016
0
    }
2017
0
    return error;
2018
0
}