Coverage Report

Created: 2023-03-26 07:42

/src/openvswitch/lib/ofp-msgs.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2012, 2013, 2014, 2015, 2016 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 "byte-order.h"
19
#include "hash.h"
20
#include "openvswitch/hmap.h"
21
#include "openflow/nicira-ext.h"
22
#include "openflow/openflow.h"
23
#include "openvswitch/dynamic-string.h"
24
#include "openvswitch/ofp-msgs.h"
25
#include "openvswitch/ofpbuf.h"
26
#include "openvswitch/vlog.h"
27
#include "ovs-thread.h"
28
#include "util.h"
29
30
VLOG_DEFINE_THIS_MODULE(ofp_msgs);
31
32
8.61M
#define OFPT_VENDOR 4
33
3.31M
#define OFPT10_STATS_REQUEST 16
34
1.93M
#define OFPT10_STATS_REPLY 17
35
16.7M
#define OFPT11_STATS_REQUEST 18
36
9.55M
#define OFPT11_STATS_REPLY 19
37
625k
#define OFPST_VENDOR 0xffff
38
39
/* Vendor extension message. */
40
struct ofp_vendor_header {
41
    struct ofp_header header;   /* OFPT_VENDOR. */
42
    ovs_be32 vendor;            /* Vendor ID:
43
                                 * - MSB 0: low-order bytes are IEEE OUI.
44
                                 * - MSB != 0: defined by OpenFlow
45
                                 *   consortium. */
46
47
    /* In theory everything after 'vendor' is vendor specific.  In practice,
48
     * the vendors we support put a 32-bit subtype here.  We'll change this
49
     * structure if we start adding support for other vendor formats. */
50
    ovs_be32 subtype;           /* Vendor-specific subtype. */
51
52
    /* Followed by vendor-defined additional data. */
53
};
54
OFP_ASSERT(sizeof(struct ofp_vendor_header) == 16);
55
56
/* Statistics request or reply message. */
57
struct ofp10_stats_msg {
58
    struct ofp_header header;
59
    ovs_be16 type;              /* One of the OFPST_* constants. */
60
    ovs_be16 flags;             /* Requests: always 0.
61
                                 * Replies: 0 or OFPSF_REPLY_MORE. */
62
};
63
OFP_ASSERT(sizeof(struct ofp10_stats_msg) == 12);
64
65
/* Vendor extension stats message. */
66
struct ofp10_vendor_stats_msg {
67
    struct ofp10_stats_msg osm; /* Type OFPST_VENDOR. */
68
    ovs_be32 vendor;            /* Vendor ID:
69
                                 * - MSB 0: low-order bytes are IEEE OUI.
70
                                 * - MSB != 0: defined by OpenFlow
71
                                 *   consortium. */
72
    /* Followed by vendor-defined arbitrary additional data. */
73
};
74
OFP_ASSERT(sizeof(struct ofp10_vendor_stats_msg) == 16);
75
76
struct ofp11_stats_msg {
77
    struct ofp_header header;
78
    ovs_be16 type;              /* One of the OFPST_* constants. */
79
    ovs_be16 flags;             /* OFPSF_REQ_* flags (none yet defined). */
80
    uint8_t pad[4];
81
    /* Followed by the body of the request. */
82
};
83
OFP_ASSERT(sizeof(struct ofp11_stats_msg) == 16);
84
85
/* Vendor extension stats message. */
86
struct ofp11_vendor_stats_msg {
87
    struct ofp11_stats_msg osm; /* Type OFPST_VENDOR. */
88
    ovs_be32 vendor;            /* Vendor ID:
89
                                 * - MSB 0: low-order bytes are IEEE OUI.
90
                                 * - MSB != 0: defined by OpenFlow
91
                                 *   consortium. */
92
93
    /* In theory everything after 'vendor' is vendor specific.  In practice,
94
     * the vendors we support put a 32-bit subtype here.  We'll change this
95
     * structure if we start adding support for other vendor formats. */
96
    ovs_be32 subtype;           /* Vendor-specific subtype. */
97
98
    /* Followed by vendor-defined additional data. */
99
};
100
OFP_ASSERT(sizeof(struct ofp11_vendor_stats_msg) == 24);
101
102
/* Header for Nicira vendor stats request and reply messages in OpenFlow
103
 * 1.0. */
104
struct nicira10_stats_msg {
105
    struct ofp10_vendor_stats_msg vsm; /* Vendor NX_VENDOR_ID. */
106
    ovs_be32 subtype;           /* One of NXST_* below. */
107
    uint8_t pad[4];             /* Align to 64-bits. */
108
};
109
OFP_ASSERT(sizeof(struct nicira10_stats_msg) == 24);
110
111
/* A thin abstraction of OpenFlow headers:
112
 *
113
 *   - 'version' and 'type' come straight from struct ofp_header, so these are
114
 *     always present and meaningful.
115
 *
116
 *   - 'stat' comes from the 'type' member in statistics messages only.  It is
117
 *     meaningful, therefore, only if 'version' and 'type' taken together
118
 *     specify a statistics request or reply.  Otherwise it is 0.
119
 *
120
 *   - 'vendor' is meaningful only for vendor messages, that is, if 'version'
121
 *     and 'type' specify a vendor message or if 'version' and 'type' specify
122
 *     a statistics message and 'stat' specifies a vendor statistic type.
123
 *     Otherwise it is 0.
124
 *
125
 *   - 'subtype' is meaningful only for vendor messages and otherwise 0.  It
126
 *     specifies a vendor-defined subtype.  There is no standard format for
127
 *     these but 32 bits seems like it should be enough. */
128
struct ofphdrs {
129
    uint8_t version;            /* From ofp_header. */
130
    uint8_t type;               /* From ofp_header. */
131
    uint16_t stat;              /* From ofp10_stats_msg or ofp11_stats_msg. */
132
    uint32_t vendor;            /* From ofp_vendor_header,
133
                                 * ofp10_vendor_stats_msg, or
134
                                 * ofp11_vendor_stats_msg. */
135
    uint32_t subtype;           /* From nicira_header, nicira10_stats_msg, or
136
                                 * nicira11_stats_msg. */
137
};
138
BUILD_ASSERT_DECL(sizeof(struct ofphdrs) == 12);
139
140
/* A mapping from OpenFlow headers to OFPRAW_*.  */
141
struct raw_instance {
142
    struct hmap_node hmap_node; /* In 'raw_instance_map'. */
143
    struct ofphdrs hdrs;        /* Key. */
144
    enum ofpraw raw;            /* Value. */
145
    unsigned int hdrs_len;      /* ofphdrs_len(hdrs). */
146
};
147
148
/* Information about a particular 'enum ofpraw'. */
149
struct raw_info {
150
    /* All possible instantiations of this OFPRAW_* into OpenFlow headers. */
151
    struct raw_instance *instances; /* max_version - min_version + 1 elems. */
152
    uint8_t min_version;
153
    uint8_t max_version;
154
155
    unsigned int min_body;
156
    unsigned int extra_multiple;
157
    enum ofptype type;
158
    const char *name;
159
};
160
161
/* All understood OpenFlow message types, indexed by their 'struct ofphdrs'. */
162
static struct hmap raw_instance_map;
163
#include "ofp-msgs.inc"
164
165
static ovs_be32 alloc_xid(void);
166
167
/* ofphdrs functions. */
168
static uint32_t ofphdrs_hash(const struct ofphdrs *);
169
static bool ofphdrs_equal(const struct ofphdrs *a, const struct ofphdrs *b);
170
static enum ofperr ofphdrs_decode(struct ofphdrs *,
171
                                  const struct ofp_header *oh, size_t length);
172
static void ofphdrs_decode_assert(struct ofphdrs *,
173
                                  const struct ofp_header *oh, size_t length);
174
size_t ofphdrs_len(const struct ofphdrs *);
175
176
static const struct raw_info *raw_info_get(enum ofpraw);
177
static struct raw_instance *raw_instance_get(const struct raw_info *,
178
                                             uint8_t version);
179
180
static enum ofperr ofpraw_from_ofphdrs(enum ofpraw *, const struct ofphdrs *);
181

182
/* Returns a transaction ID to use for an outgoing OpenFlow message. */
183
static ovs_be32
184
alloc_xid(void)
185
10.1k
{
186
10.1k
    static atomic_count next_xid = ATOMIC_COUNT_INIT(1);
187
188
10.1k
    return htonl(atomic_count_inc(&next_xid));
189
10.1k
}
190

191
static uint32_t
192
ofphdrs_hash(const struct ofphdrs *hdrs)
193
8.46M
{
194
8.46M
    BUILD_ASSERT_DECL(sizeof *hdrs % 4 == 0);
195
8.46M
    return hash_bytes32((const uint32_t *) hdrs, sizeof *hdrs, 0);
196
8.46M
}
197
198
static bool
199
ofphdrs_equal(const struct ofphdrs *a, const struct ofphdrs *b)
200
7.13M
{
201
7.13M
    return !memcmp(a, b, sizeof *a);
202
7.13M
}
203
204
static void
205
log_bad_vendor(uint32_t vendor)
206
27.5k
{
207
27.5k
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
208
209
27.5k
    VLOG_WARN_RL(&rl, "OpenFlow message has unknown vendor %#"PRIx32, vendor);
210
27.5k
}
211
212
static enum ofperr
213
ofphdrs_decode(struct ofphdrs *hdrs,
214
               const struct ofp_header *oh, size_t length)
215
8.58M
{
216
8.58M
    memset(hdrs, 0, sizeof *hdrs);
217
8.58M
    if (length < sizeof *oh) {
218
0
        return OFPERR_OFPBRC_BAD_LEN;
219
0
    }
220
221
    /* Get base message version and type (OFPT_*). */
222
8.58M
    hdrs->version = oh->version;
223
8.58M
    hdrs->type = oh->type;
224
225
8.58M
    if (hdrs->type == OFPT_VENDOR) {
226
        /* Get vendor. */
227
312k
        const struct ofp_vendor_header *ovh;
228
229
312k
        if (length < sizeof *ovh) {
230
52.5k
            return OFPERR_OFPBRC_BAD_LEN;
231
52.5k
        }
232
233
260k
        ovh = (const struct ofp_vendor_header *) oh;
234
260k
        hdrs->vendor = ntohl(ovh->vendor);
235
260k
        if (hdrs->vendor == NX_VENDOR_ID || hdrs->vendor == ONF_VENDOR_ID) {
236
235k
            hdrs->subtype = ntohl(ovh->subtype);
237
235k
        } else {
238
25.3k
            log_bad_vendor(hdrs->vendor);
239
25.3k
            return OFPERR_OFPBRC_BAD_VENDOR;
240
25.3k
        }
241
8.27M
    } else if (hdrs->version == OFP10_VERSION
242
8.27M
               && (hdrs->type == OFPT10_STATS_REQUEST ||
243
1.29M
                   hdrs->type == OFPT10_STATS_REPLY)) {
244
168k
        const struct ofp10_stats_msg *osm;
245
246
        /* Get statistic type (OFPST_*). */
247
168k
        if (length < sizeof *osm) {
248
1.44k
            return OFPERR_OFPBRC_BAD_LEN;
249
1.44k
        }
250
167k
        osm = (const struct ofp10_stats_msg *) oh;
251
167k
        hdrs->stat = ntohs(osm->type);
252
253
167k
        if (hdrs->stat == OFPST_VENDOR) {
254
            /* Get vendor. */
255
94.5k
            const struct ofp10_vendor_stats_msg *ovsm;
256
257
94.5k
            if (length < sizeof *ovsm) {
258
144
                return OFPERR_OFPBRC_BAD_LEN;
259
144
            }
260
261
94.3k
            ovsm = (const struct ofp10_vendor_stats_msg *) oh;
262
94.3k
            hdrs->vendor = ntohl(ovsm->vendor);
263
94.3k
            if (hdrs->vendor == NX_VENDOR_ID) {
264
                /* Get Nicira statistic type (NXST_*). */
265
92.7k
                const struct nicira10_stats_msg *nsm;
266
267
92.7k
                if (length < sizeof *nsm) {
268
67
                    return OFPERR_OFPBRC_BAD_LEN;
269
67
                }
270
92.6k
                nsm = (const struct nicira10_stats_msg *) oh;
271
92.6k
                hdrs->subtype = ntohl(nsm->subtype);
272
92.6k
            } else {
273
1.65k
                log_bad_vendor(hdrs->vendor);
274
1.65k
                return OFPERR_OFPBRC_BAD_VENDOR;
275
1.65k
            }
276
94.3k
        }
277
8.10M
    } else if (hdrs->version != OFP10_VERSION
278
8.10M
               && (hdrs->type == OFPT11_STATS_REQUEST ||
279
6.97M
                   hdrs->type == OFPT11_STATS_REPLY)) {
280
471k
        const struct ofp11_stats_msg *osm;
281
282
        /* Get statistic type (OFPST_*). */
283
471k
        if (length < sizeof *osm) {
284
24.3k
            return OFPERR_OFPBRC_BAD_LEN;
285
24.3k
        }
286
446k
        osm = (const struct ofp11_stats_msg *) oh;
287
446k
        hdrs->stat = ntohs(osm->type);
288
289
446k
        if (hdrs->stat == OFPST_VENDOR) {
290
            /* Get vendor. */
291
5.53k
            const struct ofp11_vendor_stats_msg *ovsm;
292
293
5.53k
            if (length < sizeof *ovsm) {
294
4.39k
                return OFPERR_OFPBRC_BAD_LEN;
295
4.39k
            }
296
297
1.13k
            ovsm = (const struct ofp11_vendor_stats_msg *) oh;
298
1.13k
            hdrs->vendor = ntohl(ovsm->vendor);
299
1.13k
            if (hdrs->vendor == NX_VENDOR_ID ||
300
1.13k
                hdrs->vendor == ONF_VENDOR_ID) {
301
571
                hdrs->subtype = ntohl(ovsm->subtype);
302
571
            } else {
303
564
                log_bad_vendor(hdrs->vendor);
304
564
                return OFPERR_OFPBRC_BAD_VENDOR;
305
564
            }
306
1.13k
        }
307
446k
    }
308
309
8.47M
    return 0;
310
8.58M
}
311
312
static void
313
ofphdrs_decode_assert(struct ofphdrs *hdrs,
314
                      const struct ofp_header *oh, size_t length)
315
15.4k
{
316
15.4k
    ovs_assert(!ofphdrs_decode(hdrs, oh, length));
317
15.4k
}
318
319
static bool
320
ofp_is_stat_request(enum ofp_version version, uint8_t type)
321
4.88M
{
322
4.88M
    switch (version) {
323
719k
    case OFP10_VERSION:
324
719k
        return type == OFPT10_STATS_REQUEST;
325
317k
    case OFP11_VERSION:
326
905k
    case OFP12_VERSION:
327
1.21M
    case OFP13_VERSION:
328
1.99M
    case OFP14_VERSION:
329
2.76M
    case OFP15_VERSION:
330
2.76M
        return type == OFPT11_STATS_REQUEST;
331
4.88M
    }
332
333
1.40M
    return false;
334
4.88M
}
335
336
static bool
337
ofp_is_stat_reply(enum ofp_version version, uint8_t type)
338
4.68M
{
339
4.68M
    switch (version) {
340
658k
    case OFP10_VERSION:
341
658k
        return type == OFPT10_STATS_REPLY;
342
311k
    case OFP11_VERSION:
343
888k
    case OFP12_VERSION:
344
1.19M
    case OFP13_VERSION:
345
1.94M
    case OFP14_VERSION:
346
2.61M
    case OFP15_VERSION:
347
2.61M
        return type == OFPT11_STATS_REPLY;
348
4.68M
    }
349
350
1.40M
    return false;
351
4.68M
}
352
353
static bool
354
ofp_is_stat(enum ofp_version version, uint8_t type)
355
4.71M
{
356
4.71M
    return (ofp_is_stat_request(version, type) ||
357
4.71M
            ofp_is_stat_reply(version, type));
358
4.71M
}
359
360
static bool
361
ofphdrs_is_stat(const struct ofphdrs *hdrs)
362
1.31M
{
363
1.31M
    return ofp_is_stat(hdrs->version, hdrs->type);
364
1.31M
}
365
366
size_t
367
ofphdrs_len(const struct ofphdrs *hdrs)
368
18.3k
{
369
18.3k
    if (hdrs->type == OFPT_VENDOR) {
370
3.22k
        return sizeof(struct ofp_vendor_header);
371
3.22k
    }
372
373
15.1k
    switch ((enum ofp_version) hdrs->version) {
374
784
    case OFP10_VERSION:
375
784
        if (hdrs->type == OFPT10_STATS_REQUEST ||
376
784
            hdrs->type == OFPT10_STATS_REPLY) {
377
746
            return (hdrs->stat == OFPST_VENDOR
378
746
                    ? sizeof(struct nicira10_stats_msg)
379
746
                    : sizeof(struct ofp10_stats_msg));
380
746
        }
381
38
        break;
382
383
1.64k
    case OFP11_VERSION:
384
3.60k
    case OFP12_VERSION:
385
7.31k
    case OFP13_VERSION:
386
9.44k
    case OFP14_VERSION:
387
12.3k
    case OFP15_VERSION:
388
12.3k
        if (hdrs->type == OFPT11_STATS_REQUEST ||
389
12.3k
            hdrs->type == OFPT11_STATS_REPLY) {
390
10.4k
            return (hdrs->stat == OFPST_VENDOR
391
10.4k
                    ? sizeof(struct ofp11_vendor_stats_msg)
392
10.4k
                    : sizeof(struct ofp11_stats_msg));
393
10.4k
        }
394
1.97k
        break;
395
15.1k
    }
396
397
4.00k
    return sizeof(struct ofp_header);
398
15.1k
}
399

400
/* Determines the OFPRAW_* type of the OpenFlow message at 'oh', which has
401
 * length 'oh->length'.  (The caller must ensure that 'oh->length' bytes of
402
 * data are readable at 'oh'.)  On success, returns 0 and stores the type into
403
 * '*raw'.  On failure, returns an OFPERR_* error code and zeros '*raw'.
404
 *
405
 * This function checks that 'oh' is a valid length for its particular type of
406
 * message, and returns an error if not. */
407
enum ofperr
408
ofpraw_decode(enum ofpraw *raw, const struct ofp_header *oh)
409
5.32M
{
410
5.32M
    struct ofpbuf msg = ofpbuf_const_initializer(oh, ntohs(oh->length));
411
5.32M
    return ofpraw_pull(raw, &msg);
412
5.32M
}
413
414
/* Does the same job as ofpraw_decode(), except that it assert-fails if
415
 * ofpraw_decode() would have reported an error.  Thus, it's able to use the
416
 * return value for the OFPRAW_* message type instead of an error code.
417
 *
418
 * (It only makes sense to use this function if you previously called
419
 * ofpraw_decode() on the message and thus know that it's OK.) */
420
enum ofpraw
421
ofpraw_decode_assert(const struct ofp_header *oh)
422
11.1k
{
423
11.1k
    enum ofpraw raw;
424
11.1k
    ovs_assert(!ofpraw_decode(&raw, oh));
425
11.1k
    return raw;
426
11.1k
}
427
428
/* Checks that 'len' is a valid length for an OpenFlow message that corresponds
429
 * to 'info' and 'instance'.  Returns 0 if so, otherwise an OpenFlow error. */
430
static enum ofperr
431
ofpraw_check_length(const struct raw_info *info,
432
                    const struct raw_instance *instance,
433
                    unsigned int len)
434
7.12M
{
435
7.12M
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
436
437
7.12M
    unsigned int min_len = instance->hdrs_len + info->min_body;
438
7.12M
    switch (info->extra_multiple) {
439
217k
    case 0:
440
217k
        if (len != min_len) {
441
87.1k
            VLOG_WARN_RL(&rl, "received %s with incorrect length %u (expected "
442
87.1k
                         "length %u)", info->name, len, min_len);
443
87.1k
            return OFPERR_OFPBRC_BAD_LEN;
444
87.1k
        }
445
130k
        break;
446
447
5.33M
    case 1:
448
5.33M
        if (len < min_len) {
449
116k
            VLOG_WARN_RL(&rl, "received %s with incorrect length %u (expected "
450
116k
                         "length at least %u bytes)",
451
116k
                         info->name, len, min_len);
452
116k
            return OFPERR_OFPBRC_BAD_LEN;
453
116k
        }
454
5.22M
        break;
455
456
5.22M
    default:
457
1.56M
        if (len < min_len || (len - min_len) % info->extra_multiple) {
458
32.7k
            VLOG_WARN_RL(&rl, "received %s with incorrect length %u (must be "
459
32.7k
                         "exactly %u bytes or longer by an integer multiple "
460
32.7k
                         "of %u bytes)",
461
32.7k
                         info->name, len, min_len, info->extra_multiple);
462
32.7k
            return OFPERR_OFPBRC_BAD_LEN;
463
32.7k
        }
464
1.53M
        break;
465
7.12M
    }
466
467
6.88M
    return 0;
468
7.12M
}
469
470
/* Determines the OFPRAW_* type of the OpenFlow message in 'msg', which starts
471
 * at 'msg->data' and has length 'msg->size' bytes.  On success,
472
 * returns 0 and stores the type into '*rawp'.  On failure, returns an OFPERR_*
473
 * error code and zeros '*rawp'.
474
 *
475
 * This function checks that the message has a valid length for its particular
476
 * type of message, and returns an error if not.
477
 *
478
 * In addition to setting '*rawp', this function pulls off the OpenFlow header
479
 * (including the stats headers, vendor header, and any subtype header) with
480
 * ofpbuf_pull().  It also sets 'msg->header' to the start of the OpenFlow
481
 * header and 'msg->msg' just beyond the headers (that is, to the final value
482
 * of msg->data). */
483
enum ofperr
484
ofpraw_pull(enum ofpraw *rawp, struct ofpbuf *msg)
485
8.55M
{
486
    /* Set default outputs. */
487
8.55M
    msg->header = msg->data;
488
8.55M
    msg->msg = msg->header;
489
8.55M
    *rawp = 0;
490
491
8.55M
    struct ofphdrs hdrs;
492
8.55M
    enum ofperr error = ofphdrs_decode(&hdrs, msg->data, msg->size);
493
8.55M
    if (error) {
494
110k
        return error;
495
110k
    }
496
497
8.44M
    enum ofpraw raw;
498
8.44M
    error = ofpraw_from_ofphdrs(&raw, &hdrs);
499
8.44M
    if (error) {
500
1.31M
        return error;
501
1.31M
    }
502
503
7.12M
    const struct raw_info *info = raw_info_get(raw);
504
7.12M
    const struct raw_instance *instance = raw_instance_get(info, hdrs.version);
505
7.12M
    error = ofpraw_check_length(info, instance, msg->size);
506
7.12M
    if (error) {
507
236k
        return error;
508
236k
    }
509
510
6.88M
    msg->header = ofpbuf_pull(msg, instance->hdrs_len);
511
6.88M
    msg->msg = msg->data;
512
6.88M
    *rawp = raw;
513
6.88M
    return 0;
514
7.12M
}
515
516
/* Does the same job as ofpraw_pull(), except that it assert-fails if
517
 * ofpraw_pull() would have reported an error.  Thus, it's able to use the
518
 * return value for the OFPRAW_* message type instead of an error code.
519
 *
520
 * (It only makes sense to use this function if you previously called
521
 * ofpraw_decode() on the message and thus know that it's OK.) */
522
enum ofpraw
523
ofpraw_pull_assert(struct ofpbuf *msg)
524
1.25M
{
525
1.25M
    enum ofpraw raw;
526
1.25M
    ovs_assert(!ofpraw_pull(&raw, msg));
527
1.25M
    return raw;
528
1.25M
}
529
530
/* Determines the OFPRAW_* type of the OpenFlow message that starts at 'oh' and
531
 * has length 'length' bytes.  On success, returns 0 and stores the type into
532
 * '*rawp'.  On failure, returns an OFPERR_* error code and zeros '*rawp'.
533
 *
534
 * Unlike other functions for decoding message types, this one is not picky
535
 * about message length.  For example, it will successfully decode a message
536
 * whose body is shorter than the minimum length for a message of its type.
537
 * Thus, this is the correct function to use for decoding the type of a message
538
 * that might have been truncated, such as the payload of an OpenFlow error
539
 * message (which is allowed to be truncated to 64 bytes). */
540
enum ofperr
541
ofpraw_decode_partial(enum ofpraw *raw,
542
                      const struct ofp_header *oh, size_t length)
543
16.6k
{
544
16.6k
    struct ofphdrs hdrs;
545
16.6k
    enum ofperr error;
546
547
16.6k
    error = ofphdrs_decode(&hdrs, oh, length);
548
16.6k
    if (!error) {
549
16.1k
        error = ofpraw_from_ofphdrs(raw, &hdrs);
550
16.1k
    }
551
552
16.6k
    if (error) {
553
7.91k
        *raw = 0;
554
7.91k
    }
555
16.6k
    return error;
556
16.6k
}
557

558
/* Encoding messages using OFPRAW_* values. */
559
560
static void ofpraw_put__(enum ofpraw, uint8_t version, ovs_be32 xid,
561
                         size_t extra_tailroom, struct ofpbuf *);
562
563
/* Allocates and returns a new ofpbuf that contains an OpenFlow header for
564
 * 'raw' with OpenFlow version 'version' and a fresh OpenFlow transaction ID.
565
 * The ofpbuf has enough tailroom for the minimum body length of 'raw', plus
566
 * 'extra_tailroom' additional bytes.
567
 *
568
 * Each 'raw' value is valid only for certain OpenFlow versions.  The caller
569
 * must specify a valid (raw, version) pair.
570
 *
571
 * In the returned ofpbuf, 'header' points to the beginning of the
572
 * OpenFlow header and 'msg' points just after it, to where the
573
 * message's body will start.  The caller must actually allocate the
574
 * body into the space reserved for it, e.g. with ofpbuf_put_uninit().
575
 *
576
 * The caller owns the returned ofpbuf and must free it when it is no longer
577
 * needed, e.g. with ofpbuf_delete(). */
578
struct ofpbuf *
579
ofpraw_alloc(enum ofpraw raw, uint8_t version, size_t extra_tailroom)
580
10.1k
{
581
10.1k
    return ofpraw_alloc_xid(raw, version, alloc_xid(), extra_tailroom);
582
10.1k
}
583
584
/* Same as ofpraw_alloc() but the caller provides the transaction ID. */
585
struct ofpbuf *
586
ofpraw_alloc_xid(enum ofpraw raw, uint8_t version, ovs_be32 xid,
587
                 size_t extra_tailroom)
588
10.1k
{
589
10.1k
    struct ofpbuf *buf = ofpbuf_new(0);
590
10.1k
    ofpraw_put__(raw, version, xid, extra_tailroom, buf);
591
10.1k
    return buf;
592
10.1k
}
593
594
/* Same as ofpraw_alloc(), but obtains the OpenFlow version and transaction ID
595
 * from 'request->version' and 'request->xid', respectively.
596
 *
597
 * Even though the version comes from 'request->version', the caller must still
598
 * know what it is doing, by specifying a valid pairing of 'raw' and
599
 * 'request->version', just like ofpraw_alloc(). */
600
struct ofpbuf *
601
ofpraw_alloc_reply(enum ofpraw raw, const struct ofp_header *request,
602
                   size_t extra_tailroom)
603
0
{
604
0
    return ofpraw_alloc_xid(raw, request->version, request->xid,
605
0
                            extra_tailroom);
606
0
}
607
608
/* Allocates and returns a new ofpbuf that contains an OpenFlow header that is
609
 * a stats reply to the stats request in 'request', using the same OpenFlow
610
 * version and transaction ID as 'request'.  The ofpbuf has enough tailroom for
611
 * the stats reply's minimum body length, plus 'extra_tailroom' additional
612
 * bytes.
613
 *
614
 * 'request' must be a stats request, that is, an OFPRAW_OFPST* or OFPRAW_NXST*
615
 * value.  Every stats request has a corresponding reply, so the (raw, version)
616
 * pairing pitfalls of the other ofpraw_alloc_*() functions don't apply here.
617
 *
618
 * In the returned ofpbuf, 'header' points to the beginning of the
619
 * OpenFlow header and 'msg' points just after it, to where the
620
 * message's body will start.  The caller must actually allocate the
621
 * body into the space reserved for it, e.g. with ofpbuf_put_uninit().
622
 *
623
 * The caller owns the returned ofpbuf and must free it when it is no longer
624
 * needed, e.g. with ofpbuf_delete(). */
625
struct ofpbuf *
626
ofpraw_alloc_stats_reply(const struct ofp_header *request,
627
                         size_t extra_tailroom)
628
0
{
629
0
    enum ofpraw request_raw;
630
0
    enum ofpraw reply_raw;
631
632
0
    ovs_assert(!ofpraw_decode_partial(&request_raw, request,
633
0
                                      ntohs(request->length)));
634
635
0
    reply_raw = ofpraw_stats_request_to_reply(request_raw, request->version);
636
0
    ovs_assert(reply_raw);
637
638
0
    return ofpraw_alloc_reply(reply_raw, request, extra_tailroom);
639
0
}
640
641
/* Appends to 'buf' an OpenFlow header for 'raw' with OpenFlow version
642
 * 'version' and a fresh OpenFlow transaction ID.  Preallocates enough tailroom
643
 * in 'buf' for the minimum body length of 'raw', plus 'extra_tailroom'
644
 * additional bytes.
645
 *
646
 * Each 'raw' value is valid only for certain OpenFlow versions.  The caller
647
 * must specify a valid (raw, version) pair.
648
 *
649
 * Upon return, 'buf->header' points to the beginning of the OpenFlow header
650
 * and 'buf->msg' points just after it, to where the message's body will start.
651
 * The caller must actually allocating the body into the space reserved for it,
652
 * e.g. with ofpbuf_put_uninit(). */
653
void
654
ofpraw_put(enum ofpraw raw, uint8_t version, struct ofpbuf *buf)
655
0
{
656
0
    ofpraw_put__(raw, version, alloc_xid(), 0, buf);
657
0
}
658
659
/* Same as ofpraw_put() but the caller provides the transaction ID. */
660
void
661
ofpraw_put_xid(enum ofpraw raw, uint8_t version, ovs_be32 xid,
662
               struct ofpbuf *buf)
663
0
{
664
0
    ofpraw_put__(raw, version, xid, 0, buf);
665
0
}
666
667
/* Same as ofpraw_put(), but obtains the OpenFlow version and transaction ID
668
 * from 'request->version' and 'request->xid', respectively.
669
 *
670
 * Even though the version comes from 'request->version', the caller must still
671
 * know what it is doing, by specifying a valid pairing of 'raw' and
672
 * 'request->version', just like ofpraw_put(). */
673
void
674
ofpraw_put_reply(enum ofpraw raw, const struct ofp_header *request,
675
                 struct ofpbuf *buf)
676
0
{
677
0
    ofpraw_put__(raw, request->version, request->xid, 0, buf);
678
0
}
679
680
/* Appends to 'buf' an OpenFlow header that is a stats reply to the stats
681
 * request in 'request', using the same OpenFlow version and transaction ID as
682
 * 'request'.  Preallocate enough tailroom in 'buf for the stats reply's
683
 * minimum body length, plus 'extra_tailroom' additional bytes.
684
 *
685
 * 'request' must be a stats request, that is, an OFPRAW_OFPST* or OFPRAW_NXST*
686
 * value.  Every stats request has a corresponding reply, so the (raw, version)
687
 * pairing pitfalls of the other ofpraw_alloc_*() functions don't apply here.
688
 *
689
 * In the returned ofpbuf, 'header' points to the beginning of the
690
 * OpenFlow header and 'msg' points just after it, to where the
691
 * message's body will start.  The caller must actually allocate the
692
 * body into the space reserved for it, e.g. with ofpbuf_put_uninit().
693
 *
694
 * The caller owns the returned ofpbuf and must free it when it is no longer
695
 * needed, e.g. with ofpbuf_delete(). */
696
void
697
ofpraw_put_stats_reply(const struct ofp_header *request, struct ofpbuf *buf)
698
0
{
699
0
    enum ofpraw raw;
700
701
0
    ovs_assert(!ofpraw_decode_partial(&raw, request, ntohs(request->length)));
702
703
0
    raw = ofpraw_stats_request_to_reply(raw, request->version);
704
0
    ovs_assert(raw);
705
706
0
    ofpraw_put__(raw, request->version, request->xid, 0, buf);
707
0
}
708
709
static void
710
ofpraw_put__(enum ofpraw raw, uint8_t version, ovs_be32 xid,
711
             size_t extra_tailroom, struct ofpbuf *buf)
712
10.1k
{
713
10.1k
    const struct raw_info *info = raw_info_get(raw);
714
10.1k
    const struct raw_instance *instance = raw_instance_get(info, version);
715
10.1k
    const struct ofphdrs *hdrs = &instance->hdrs;
716
10.1k
    struct ofp_header *oh;
717
718
10.1k
    ofpbuf_prealloc_tailroom(buf, (instance->hdrs_len + info->min_body
719
10.1k
                                   + extra_tailroom));
720
10.1k
    buf->header = ofpbuf_put_uninit(buf, instance->hdrs_len);
721
10.1k
    buf->msg = ofpbuf_tail(buf);
722
723
10.1k
    oh = buf->header;
724
10.1k
    oh->version = version;
725
10.1k
    oh->type = hdrs->type;
726
10.1k
    oh->length = htons(buf->size);
727
10.1k
    oh->xid = xid;
728
729
10.1k
    if (hdrs->type == OFPT_VENDOR) {
730
4.11k
        struct ofp_vendor_header *ovh = buf->header;
731
732
4.11k
        ovh->vendor = htonl(hdrs->vendor);
733
4.11k
        ovh->subtype = htonl(hdrs->subtype);
734
6.01k
    } else if (version == OFP10_VERSION
735
6.01k
               && (hdrs->type == OFPT10_STATS_REQUEST ||
736
5.28k
                   hdrs->type == OFPT10_STATS_REPLY)) {
737
0
        struct ofp10_stats_msg *osm = buf->header;
738
739
0
        osm->type = htons(hdrs->stat);
740
0
        osm->flags = htons(0);
741
742
0
        if (hdrs->stat == OFPST_VENDOR) {
743
0
            struct ofp10_vendor_stats_msg *ovsm = buf->header;
744
745
0
            ovsm->vendor = htonl(hdrs->vendor);
746
0
            if (hdrs->vendor == NX_VENDOR_ID) {
747
0
                struct nicira10_stats_msg *nsm = buf->header;
748
749
0
                nsm->subtype = htonl(hdrs->subtype);
750
0
                memset(nsm->pad, 0, sizeof nsm->pad);
751
0
            } else {
752
0
                OVS_NOT_REACHED();
753
0
            }
754
0
        }
755
6.01k
    } else if (version != OFP10_VERSION
756
6.01k
               && (hdrs->type == OFPT11_STATS_REQUEST ||
757
734
                   hdrs->type == OFPT11_STATS_REPLY)) {
758
0
        struct ofp11_stats_msg *osm = buf->header;
759
760
0
        osm->type = htons(hdrs->stat);
761
0
        osm->flags = htons(0);
762
0
        memset(osm->pad, 0, sizeof osm->pad);
763
764
0
        if (hdrs->stat == OFPST_VENDOR) {
765
0
            struct ofp11_vendor_stats_msg *ovsm = buf->header;
766
767
0
            ovsm->vendor = htonl(hdrs->vendor);
768
0
            ovsm->subtype = htonl(hdrs->subtype);
769
0
        }
770
0
    }
771
10.1k
}
772

773
/* Returns 'raw''s name.
774
 *
775
 * The name is the name used for 'raw' in the OpenFlow specification.  For
776
 * example, ofpraw_get_name(OFPRAW_OFPT10_FEATURES_REPLY) is
777
 * "OFPT_FEATURES_REPLY".
778
 *
779
 * The caller must not modify or free the returned string. */
780
const char *
781
ofpraw_get_name(enum ofpraw raw)
782
3.40M
{
783
3.40M
    return raw_info_get(raw)->name;
784
3.40M
}
785
786
/* Returns the stats reply that corresponds to 'raw' in the given OpenFlow
787
 * 'version'. */
788
enum ofpraw
789
ofpraw_stats_request_to_reply(enum ofpraw raw, uint8_t version)
790
0
{
791
0
    const struct raw_info *info = raw_info_get(raw);
792
0
    const struct raw_instance *instance = raw_instance_get(info, version);
793
0
    enum ofpraw reply_raw;
794
0
    struct ofphdrs hdrs;
795
796
0
    hdrs = instance->hdrs;
797
0
    switch ((enum ofp_version)hdrs.version) {
798
0
    case OFP10_VERSION:
799
0
        ovs_assert(hdrs.type == OFPT10_STATS_REQUEST);
800
0
        hdrs.type = OFPT10_STATS_REPLY;
801
0
        break;
802
0
    case OFP11_VERSION:
803
0
    case OFP12_VERSION:
804
0
    case OFP13_VERSION:
805
0
    case OFP14_VERSION:
806
0
    case OFP15_VERSION:
807
0
        ovs_assert(hdrs.type == OFPT11_STATS_REQUEST);
808
0
        hdrs.type = OFPT11_STATS_REPLY;
809
0
        break;
810
0
    default:
811
0
        OVS_NOT_REACHED();
812
0
    }
813
814
0
    ovs_assert(!ofpraw_from_ofphdrs(&reply_raw, &hdrs));
815
816
0
    return reply_raw;
817
0
}
818

819
/* Determines the OFPTYPE_* type of the OpenFlow message at 'oh', which has
820
 * length 'oh->length'.  (The caller must ensure that 'oh->length' bytes of
821
 * data are readable at 'oh'.)  On success, returns 0 and stores the type into
822
 * '*typep'.  On failure, returns an OFPERR_* error code and zeros '*typep'.
823
 *
824
 * This function checks that 'oh' is a valid length for its particular type of
825
 * message, and returns an error if not. */
826
enum ofperr
827
ofptype_decode(enum ofptype *typep, const struct ofp_header *oh)
828
21.4k
{
829
21.4k
    enum ofperr error;
830
21.4k
    enum ofpraw raw;
831
832
21.4k
    error = ofpraw_decode(&raw, oh);
833
21.4k
    *typep = error ? 0 : ofptype_from_ofpraw(raw);
834
21.4k
    return error;
835
21.4k
}
836
837
/* Determines the OFPTYPE_* type of the OpenFlow message in 'msg', which starts
838
 * at 'msg->data' and has length 'msg->size' bytes.  On success,
839
 * returns 0 and stores the type into '*typep'.  On failure, returns an
840
 * OFPERR_* error code and zeros '*typep'.
841
 *
842
 * This function checks that the message has a valid length for its particular
843
 * type of message, and returns an error if not.
844
 *
845
 * In addition to setting '*typep', this function pulls off the OpenFlow header
846
 * (including the stats headers, vendor header, and any subtype header) with
847
 * ofpbuf_pull().  It also sets 'msg->header' to the start of the OpenFlow
848
 * header and 'msg->msg' just beyond the headers (that is, to the final value
849
 * of msg->data). */
850
enum ofperr
851
ofptype_pull(enum ofptype *typep, struct ofpbuf *buf)
852
0
{
853
0
    enum ofperr error;
854
0
    enum ofpraw raw;
855
856
0
    error = ofpraw_pull(&raw, buf);
857
0
    *typep = error ? 0 : ofptype_from_ofpraw(raw);
858
0
    return error;
859
0
}
860
861
/* Returns the OFPTYPE_* type that corresponds to 'raw'.
862
 *
863
 * (This is a one-way trip, because the mapping from ofpraw to ofptype is
864
 * many-to-one.)  */
865
enum ofptype
866
ofptype_from_ofpraw(enum ofpraw raw)
867
3.41M
{
868
3.41M
    return raw_info_get(raw)->type;
869
3.41M
}
870
871
const char *
872
ofptype_get_name(enum ofptype type)
873
0
{
874
0
    ovs_assert(type < ARRAY_SIZE(type_names));
875
0
    return type_names[type];
876
0
}
877

878
/* Updates the 'length' field of the OpenFlow message in 'buf' to
879
 * 'buf->size'. */
880
void
881
ofpmsg_update_length(struct ofpbuf *buf)
882
10.1k
{
883
10.1k
    struct ofp_header *oh = ofpbuf_at_assert(buf, 0, sizeof *oh);
884
10.1k
    oh->length = htons(buf->size);
885
10.1k
}
886
887
/* Returns just past the OpenFlow header (including the stats headers, vendor
888
 * header, and any subtype header) in 'oh'. */
889
const void *
890
ofpmsg_body(const struct ofp_header *oh)
891
15.4k
{
892
15.4k
    struct ofphdrs hdrs;
893
894
15.4k
    ofphdrs_decode_assert(&hdrs, oh, ntohs(oh->length));
895
15.4k
    return (const uint8_t *) oh + ofphdrs_len(&hdrs);
896
15.4k
}
897
898
/* Return if 'oh' is a stat/multipart (OFPST) request message. */
899
bool
900
ofpmsg_is_stat_request(const struct ofp_header *oh)
901
171k
{
902
171k
    return ofp_is_stat_request(oh->version, oh->type);
903
171k
}
904
905
/* Return if 'oh' is a stat/multipart (OFPST) reply message. */
906
bool
907
ofpmsg_is_stat_reply(const struct ofp_header *oh)
908
0
{
909
0
    return ofp_is_stat_reply(oh->version, oh->type);
910
0
}
911
912
/* Return if 'oh' is a stat/multipart (OFPST) request or reply message. */
913
bool
914
ofpmsg_is_stat(const struct ofp_header *oh)
915
3.39M
{
916
3.39M
    return ofp_is_stat(oh->version, oh->type);
917
3.39M
}
918

919
static ovs_be16 *ofpmp_flags__(const struct ofp_header *);
920
921
/* Initializes 'replies' as a new list of stats messages that reply to
922
 * 'request', which must be a stats request message.  Initially the list will
923
 * consist of only a single reply part without any body.  The caller should
924
 * use calls to the other ofpmp_*() functions to add to the body and split the
925
 * message into multiple parts, if necessary. */
926
void
927
ofpmp_init(struct ovs_list *replies, const struct ofp_header *request)
928
0
{
929
0
    struct ofpbuf *msg;
930
931
0
    ovs_list_init(replies);
932
933
0
    msg = ofpraw_alloc_stats_reply(request, 1000);
934
0
    ovs_list_push_back(replies, &msg->list_node);
935
0
}
936
937
/* Prepares to append up to 'len' bytes to the series of statistics replies in
938
 * 'replies', which should have been initialized with ofpmp_init(), if
939
 * necessary adding a new reply to the list.
940
 *
941
 * Returns an ofpbuf with at least 'len' bytes of tailroom.  The 'len' bytes
942
 * have not actually been allocated, so the caller must do so with
943
 * e.g. ofpbuf_put_uninit(). */
944
struct ofpbuf *
945
ofpmp_reserve(struct ovs_list *replies, size_t len)
946
0
{
947
0
    struct ofpbuf *msg = ofpbuf_from_list(ovs_list_back(replies));
948
949
0
    if (msg->size + len <= UINT16_MAX) {
950
0
        ofpbuf_prealloc_tailroom(msg, len);
951
0
        return msg;
952
0
    } else {
953
0
        unsigned int hdrs_len;
954
0
        struct ofpbuf *next;
955
0
        struct ofphdrs hdrs;
956
957
0
        ofphdrs_decode_assert(&hdrs, msg->data, msg->size);
958
0
        hdrs_len = ofphdrs_len(&hdrs);
959
960
0
        next = ofpbuf_new(MAX(1024, hdrs_len + len));
961
0
        ofpbuf_put(next, msg->data, hdrs_len);
962
0
        next->header = next->data;
963
0
        next->msg = ofpbuf_tail(next);
964
0
        ovs_list_push_back(replies, &next->list_node);
965
966
0
        *ofpmp_flags__(msg->data) |= htons(OFPSF_REPLY_MORE);
967
968
0
        return next;
969
0
    }
970
0
}
971
972
/* Appends 'len' bytes to the series of statistics replies in 'replies', and
973
 * returns the first byte. */
974
void *
975
ofpmp_append(struct ovs_list *replies, size_t len)
976
0
{
977
0
    return ofpbuf_put_uninit(ofpmp_reserve(replies, len), len);
978
0
}
979
980
/* Sometimes, when composing stats replies, it's difficult to predict how long
981
 * an individual reply chunk will be before actually encoding it into the reply
982
 * buffer.  This function allows easy handling of this case: just encode the
983
 * reply, then use this function to break the message into two pieces if it
984
 * exceeds the OpenFlow message limit.
985
 *
986
 * In detail, if the final stats message in 'replies' is too long for OpenFlow,
987
 * this function breaks it into two separate stats replies, the first one with
988
 * the first 'start_ofs' bytes, the second one containing the bytes from that
989
 * offset onward. */
990
void
991
ofpmp_postappend(struct ovs_list *replies, size_t start_ofs)
992
0
{
993
0
    struct ofpbuf *msg = ofpbuf_from_list(ovs_list_back(replies));
994
995
0
    ovs_assert(start_ofs <= UINT16_MAX);
996
0
    if (msg->size > UINT16_MAX) {
997
0
        size_t len = msg->size - start_ofs;
998
0
        memcpy(ofpmp_append(replies, len),
999
0
               (const uint8_t *) msg->data + start_ofs, len);
1000
0
        msg->size = start_ofs;
1001
0
    }
1002
0
}
1003
1004
/* Returns the OpenFlow version of the replies being constructed in 'replies',
1005
 * which should have been initialized by ofpmp_init(). */
1006
enum ofp_version
1007
ofpmp_version(struct ovs_list *replies)
1008
0
{
1009
0
    struct ofpbuf *msg = ofpbuf_from_list(ovs_list_back(replies));
1010
0
    const struct ofp_header *oh = msg->data;
1011
1012
0
    return oh->version;
1013
0
}
1014
1015
/* Determines the OFPRAW_* type of the OpenFlow messages in 'replies', which
1016
 * should have been initialized by ofpmp_init(). */
1017
enum ofpraw
1018
ofpmp_decode_raw(struct ovs_list *replies)
1019
0
{
1020
0
    struct ofpbuf *msg = ofpbuf_from_list(ovs_list_back(replies));
1021
0
    enum ofpraw raw;
1022
0
    ovs_assert(!ofpraw_decode_partial(&raw, msg->data, msg->size));
1023
0
    return raw;
1024
0
}
1025
1026
static ovs_be16 *
1027
ofpmp_flags__(const struct ofp_header *oh)
1028
202k
{
1029
202k
    switch ((enum ofp_version)oh->version) {
1030
51.2k
    case OFP10_VERSION:
1031
51.2k
        return &((struct ofp10_stats_msg *) oh)->flags;
1032
2.65k
    case OFP11_VERSION:
1033
11.7k
    case OFP12_VERSION:
1034
14.6k
    case OFP13_VERSION:
1035
40.6k
    case OFP14_VERSION:
1036
151k
    case OFP15_VERSION:
1037
151k
        return &((struct ofp11_stats_msg *) oh)->flags;
1038
0
    default:
1039
0
        OVS_NOT_REACHED();
1040
202k
    }
1041
202k
}
1042
1043
/* Returns the OFPSF_* flags found in the OpenFlow stats header of 'oh', which
1044
 * must be an OpenFlow stats request or reply.
1045
 *
1046
 * (OFPSF_REPLY_MORE is the only defined flag.) */
1047
uint16_t
1048
ofpmp_flags(const struct ofp_header *oh)
1049
202k
{
1050
202k
    return ntohs(*ofpmp_flags__(oh));
1051
202k
}
1052
1053
/* Returns true if the OFPSF_REPLY_MORE flag is set in the OpenFlow stats
1054
 * header of 'oh', which must be an OpenFlow stats request or reply, false if
1055
 * it is not set. */
1056
bool
1057
ofpmp_more(const struct ofp_header *oh)
1058
0
{
1059
0
    return (ofpmp_flags(oh) & OFPSF_REPLY_MORE) != 0;
1060
0
}
1061

1062
/* Multipart request assembler. */
1063
1064
struct ofpmp_partial {
1065
    struct hmap_node hmap_node; /* In struct ofpmp_assembler's 'msgs'. */
1066
    ovs_be32 xid;
1067
    enum ofpraw raw;
1068
    long long int timeout;
1069
    struct ovs_list msgs;
1070
    size_t size;
1071
    bool has_body;
1072
};
1073
1074
static uint32_t
1075
hash_xid(ovs_be32 xid)
1076
0
{
1077
0
    return hash_int((OVS_FORCE uint32_t) xid, 0);
1078
0
}
1079
1080
static struct ofpmp_partial *
1081
ofpmp_assembler_find(struct hmap *assembler, ovs_be32 xid)
1082
0
{
1083
0
    if (hmap_is_empty(assembler)) {
1084
        /* Common case. */
1085
0
        return NULL;
1086
0
    }
1087
1088
0
    struct ofpmp_partial *p;
1089
0
    HMAP_FOR_EACH_IN_BUCKET (p, hmap_node, hash_xid(xid), assembler) {
1090
0
        if (p->xid == xid) {
1091
0
            return p;
1092
0
        }
1093
0
    }
1094
0
    return NULL;
1095
0
}
1096
1097
static void
1098
ofpmp_partial_destroy(struct hmap *assembler, struct ofpmp_partial *p)
1099
0
{
1100
0
    if (p) {
1101
0
        hmap_remove(assembler, &p->hmap_node);
1102
0
        ofpbuf_list_delete(&p->msgs);
1103
0
        free(p);
1104
0
    }
1105
0
}
1106
1107
static struct ofpbuf *
1108
ofpmp_partial_error(struct hmap *assembler, struct ofpmp_partial *p,
1109
                    enum ofperr error)
1110
0
{
1111
0
    const struct ofpbuf *head = ofpbuf_from_list(ovs_list_back(&p->msgs));
1112
0
    const struct ofp_header *oh = head->data;
1113
0
    struct ofpbuf *reply = ofperr_encode_reply(error, oh);
1114
1115
0
    ofpmp_partial_destroy(assembler, p);
1116
1117
0
    return reply;
1118
0
}
1119
1120
/* Clears out and frees any messages currently being reassembled.  Afterward,
1121
 * the caller may destroy the hmap, with hmap_destroy(), without risk of
1122
 * leaks. */
1123
void
1124
ofpmp_assembler_clear(struct hmap *assembler)
1125
0
{
1126
0
    struct ofpmp_partial *p;
1127
0
    HMAP_FOR_EACH_SAFE (p, hmap_node, assembler) {
1128
0
        ofpmp_partial_destroy(assembler, p);
1129
0
    }
1130
0
}
1131
1132
/* Does periodic maintenance on 'assembler'.  If any partially assembled
1133
 * requests have timed out, returns an appropriate error message for the caller
1134
 * to send to the controller.
1135
 *
1136
 * 'now' should be the current time as returned by time_msec(). */
1137
struct ofpbuf * OVS_WARN_UNUSED_RESULT
1138
ofpmp_assembler_run(struct hmap *assembler, long long int now)
1139
0
{
1140
0
    struct ofpmp_partial *p;
1141
0
    HMAP_FOR_EACH (p, hmap_node, assembler) {
1142
0
        if (now >= p->timeout) {
1143
0
            return ofpmp_partial_error(
1144
0
                assembler, p, OFPERR_OFPBRC_MULTIPART_REQUEST_TIMEOUT);
1145
0
        }
1146
0
    }
1147
0
    return NULL;
1148
0
}
1149
1150
/* Returns the time at which the next partially assembled request times out.
1151
 * The caller should pass this time to poll_timer_wait_until(). */
1152
long long int
1153
ofpmp_assembler_wait(struct hmap *assembler)
1154
0
{
1155
0
    long long int timeout = LLONG_MAX;
1156
1157
0
    struct ofpmp_partial *p;
1158
0
    HMAP_FOR_EACH (p, hmap_node, assembler) {
1159
0
        timeout = MIN(timeout, p->timeout);
1160
0
    }
1161
1162
0
    return timeout;
1163
0
}
1164
1165
/* Submits 'msg' to 'assembler' for reassembly.
1166
 *
1167
 * If 'msg' was accepted, returns 0 and initializes 'out' either to an empty
1168
 * list (if 'msg' is being held for reassembly) or to a list of one or more
1169
 * reassembled messages.  The reassembler takes ownership of 'msg'; the caller
1170
 * takes ownership of the messages in 'out'.
1171
 *
1172
 * If 'msg' was rejected, returns an OpenFlow error that the caller should
1173
 * reply to the caller and initializes 'out' as empty.  The caller retains
1174
 * ownership of 'msg'.
1175
 *
1176
 * 'now' should be the current time as returned by time_msec(). */
1177
enum ofperr
1178
ofpmp_assembler_execute(struct hmap *assembler, struct ofpbuf *msg,
1179
                        struct ovs_list *out, long long int now)
1180
0
{
1181
0
    ovs_list_init(out);
1182
1183
    /* If the message is not a multipart request, pass it along without further
1184
     * inspection.
1185
     *
1186
     * We could also do this kind of early-out for multipart requests that have
1187
     * only a single piece, or for pre-OF1.3 multipart requests (since only
1188
     * OF1.3 introduced multipart requests with more than one piece), but we
1189
     * don't because this allows us to assure code that runs after us that
1190
     * invariants checked below on correct message lengths are always
1191
     * satisfied, even if there's only a single piece. */
1192
0
    struct ofp_header *oh = msg->data;
1193
0
    if (!ofpmsg_is_stat_request(oh)) {
1194
0
        ovs_list_push_back(out, &msg->list_node);
1195
0
        return 0;
1196
0
    }
1197
1198
    /* Decode the multipart request. */
1199
0
    struct ofphdrs hdrs;
1200
0
    enum ofperr error = ofphdrs_decode(&hdrs, msg->data, msg->size);
1201
0
    if (error) {
1202
0
        return error;
1203
0
    }
1204
1205
0
    enum ofpraw raw;
1206
0
    error = ofpraw_from_ofphdrs(&raw, &hdrs);
1207
0
    if (error) {
1208
0
        return error;
1209
0
    }
1210
1211
    /* If the message has a nonempty body, check that it is a valid length.
1212
     *
1213
     * The OpenFlow spec says that pieces with empty bodies are allowed
1214
     * anywhere in a multipart sequence, so for now we allow such messages even
1215
     * if the overall multipart request requires a body. */
1216
0
    const struct raw_info *info = raw_info_get(raw);
1217
0
    const struct raw_instance *instance = raw_instance_get(info, hdrs.version);
1218
0
    unsigned int min_len = ofphdrs_len(&hdrs);
1219
0
    bool has_body = msg->size > min_len;
1220
0
    if (has_body) {
1221
0
        error = ofpraw_check_length(info, instance, msg->size);
1222
0
        if (error) {
1223
0
            return error;
1224
0
        }
1225
0
    }
1226
1227
    /* Find or create an ofpmp_partial record. */
1228
0
    struct ofpmp_partial *p = ofpmp_assembler_find(assembler, oh->xid);
1229
0
    if (!p) {
1230
0
        p = xzalloc(sizeof *p);
1231
0
        hmap_insert(assembler, &p->hmap_node, hash_xid(oh->xid));
1232
0
        p->xid = oh->xid;
1233
0
        ovs_list_init(&p->msgs);
1234
0
        p->raw = raw;
1235
0
    }
1236
0
    p->timeout = now + 1000;
1237
1238
    /* Check that the type is the same as any previous messages in this
1239
     * sequence. */
1240
0
    if (p->raw != raw) {
1241
0
        ofpmp_partial_destroy(assembler, p);
1242
0
        return OFPERR_OFPBRC_BAD_STAT;
1243
0
    }
1244
1245
    /* Limit the size of a multipart sequence.
1246
     *
1247
     * (Table features requests can actually be over 1 MB.) */
1248
0
    p->size += msg->size;
1249
0
    if (p->size > 4 * 1024 * 1024) {
1250
0
        ofpmp_partial_destroy(assembler, p);
1251
0
        return OFPERR_OFPBRC_MULTIPART_BUFFER_OVERFLOW;
1252
0
    }
1253
1254
    /* If a multipart request type requires a body, ensure that at least one of
1255
     * the pieces in a multipart request has one. */
1256
0
    bool more = oh->version >= OFP13_VERSION && ofpmp_more(oh);
1257
0
    if (has_body) {
1258
0
        p->has_body = true;
1259
0
    }
1260
0
    if (!more && !p->has_body && info->min_body) {
1261
0
        ofpmp_partial_destroy(assembler, p);
1262
0
        return OFPERR_OFPBRC_BAD_LEN;
1263
0
    }
1264
1265
    /* Append the part to the list.
1266
     *
1267
     * If there are more pieces to come, we're done for now. */
1268
0
    ovs_list_push_back(&p->msgs, &msg->list_node);
1269
0
    if (more) {
1270
0
        return 0;
1271
0
    }
1272
1273
    /* This multipart request is complete.  Move the messages from 'p' to 'out'
1274
     * and discard 'p'. */
1275
0
    ovs_list_move(out, &p->msgs);
1276
0
    ovs_list_init(&p->msgs);
1277
0
    ofpmp_partial_destroy(assembler, p);
1278
1279
    /* Delete pieces with empty bodies from 'out' (but leave at least one
1280
     * piece).
1281
     *
1282
     * Most types of multipart requests have fixed-size bodies.  For example,
1283
     * OFPMP_PORT_DESCRIPTION has an 8-byte body.  Thus, it doesn't really make
1284
     * sense for a controller to use multiple pieces for these messages, and
1285
     * it's simpler to implement OVS as if they weren't really multipart.
1286
     *
1287
     * However, the OpenFlow spec says that messages with empty bodies are
1288
     * allowed anywhere in a multipart sequence, so in theory a controller
1289
     * could send an OFPMP_PORT_DESCRIPTION with an 8-byte body bracketed
1290
     * on either side by parts with 0-byte bodies.  We remove the 0-byte
1291
     * ones here to simplify processing later.
1292
     */
1293
0
    struct ofpbuf *b;
1294
0
    LIST_FOR_EACH_SAFE (b, list_node, out) {
1295
0
        if (b->size <= min_len && !ovs_list_is_short(out)) {
1296
0
            ovs_list_remove(&b->list_node);
1297
0
            ofpbuf_delete(b);
1298
0
        }
1299
0
    }
1300
0
    return 0;
1301
0
}
1302

1303
static void ofpmsgs_init(void);
1304
1305
static const struct raw_info *
1306
raw_info_get(enum ofpraw raw)
1307
13.9M
{
1308
13.9M
    ofpmsgs_init();
1309
1310
13.9M
    ovs_assert(raw < ARRAY_SIZE(raw_infos));
1311
13.9M
    return &raw_infos[raw];
1312
13.9M
}
1313
1314
static struct raw_instance *
1315
raw_instance_get(const struct raw_info *info, uint8_t version)
1316
7.13M
{
1317
7.13M
    ovs_assert(version >= info->min_version && version <= info->max_version);
1318
7.13M
    return &info->instances[version - info->min_version];
1319
7.13M
}
1320
1321
static enum ofperr
1322
ofpraw_from_ofphdrs(enum ofpraw *raw, const struct ofphdrs *hdrs)
1323
8.45M
{
1324
8.45M
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
1325
1326
8.45M
    struct raw_instance *raw_hdrs;
1327
8.45M
    uint32_t hash;
1328
1329
8.45M
    ofpmsgs_init();
1330
1331
8.45M
    hash = ofphdrs_hash(hdrs);
1332
8.45M
    HMAP_FOR_EACH_WITH_HASH (raw_hdrs, hmap_node, hash, &raw_instance_map) {
1333
7.13M
        if (ofphdrs_equal(hdrs, &raw_hdrs->hdrs)) {
1334
7.13M
            *raw = raw_hdrs->raw;
1335
7.13M
            return 0;
1336
7.13M
        }
1337
7.13M
    }
1338
1339
1.32M
    if (!VLOG_DROP_WARN(&rl)) {
1340
0
        struct ds s;
1341
1342
0
        ds_init(&s);
1343
0
        ds_put_format(&s, "version %"PRIu8", type %"PRIu8,
1344
0
                      hdrs->version, hdrs->type);
1345
0
        if (ofphdrs_is_stat(hdrs)) {
1346
0
            ds_put_format(&s, ", stat %"PRIu16, hdrs->stat);
1347
0
        }
1348
0
        if (hdrs->vendor) {
1349
0
            ds_put_format(&s, ", vendor 0x%"PRIx32", subtype %"PRIu32,
1350
0
                          hdrs->vendor, hdrs->subtype);
1351
0
        }
1352
0
        VLOG_WARN("unknown OpenFlow message (%s)", ds_cstr(&s));
1353
0
        ds_destroy(&s);
1354
0
    }
1355
1356
1.32M
    return (hdrs->vendor ? OFPERR_OFPBRC_BAD_SUBTYPE
1357
1.32M
            : ofphdrs_is_stat(hdrs) ? OFPERR_OFPBRC_BAD_STAT
1358
1.31M
            : OFPERR_OFPBRC_BAD_TYPE);
1359
8.45M
}
1360
1361
static void
1362
ofpmsgs_init(void)
1363
22.4M
{
1364
22.4M
    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
1365
22.4M
    const struct raw_info *info;
1366
1367
22.4M
    if (!ovsthread_once_start(&once)) {
1368
22.4M
        return;
1369
22.4M
    }
1370
1371
2
    hmap_init(&raw_instance_map);
1372
324
    for (info = raw_infos; info < &raw_infos[ARRAY_SIZE(raw_infos)]; info++)
1373
322
    {
1374
322
        int n_instances = info->max_version - info->min_version + 1;
1375
322
        struct raw_instance *inst;
1376
1377
322
        for (inst = info->instances;
1378
3.25k
             inst < &info->instances[n_instances];
1379
2.93k
             inst++) {
1380
2.93k
            inst->hdrs_len = ofphdrs_len(&inst->hdrs);
1381
2.93k
            hmap_insert(&raw_instance_map, &inst->hmap_node,
1382
2.93k
                        ofphdrs_hash(&inst->hdrs));
1383
2.93k
        }
1384
322
    }
1385
1386
2
    ovsthread_once_done(&once);
1387
2
}