Coverage Report

Created: 2025-07-01 06:50

/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
0
#define OFPT_VENDOR 4
33
0
#define OFPT10_STATS_REQUEST 16
34
0
#define OFPT10_STATS_REPLY 17
35
0
#define OFPT11_STATS_REQUEST 18
36
0
#define OFPT11_STATS_REPLY 19
37
0
#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
0
{
186
0
    static atomic_count next_xid = ATOMIC_COUNT_INIT(1);
187
188
0
    return htonl(atomic_count_inc(&next_xid));
189
0
}
190

191
static uint32_t
192
ofphdrs_hash(const struct ofphdrs *hdrs)
193
0
{
194
0
    BUILD_ASSERT_DECL(sizeof *hdrs % 4 == 0);
195
0
    return hash_bytes32((const uint32_t *) hdrs, sizeof *hdrs, 0);
196
0
}
197
198
static bool
199
ofphdrs_equal(const struct ofphdrs *a, const struct ofphdrs *b)
200
0
{
201
0
    return !memcmp(a, b, sizeof *a);
202
0
}
203
204
static void
205
log_bad_vendor(uint32_t vendor)
206
0
{
207
0
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
208
209
0
    VLOG_WARN_RL(&rl, "OpenFlow message has unknown vendor %#"PRIx32, vendor);
210
0
}
211
212
static enum ofperr
213
ofphdrs_decode(struct ofphdrs *hdrs,
214
               const struct ofp_header *oh, size_t length)
215
0
{
216
0
    memset(hdrs, 0, sizeof *hdrs);
217
0
    if (length < sizeof *oh) {
218
0
        return OFPERR_OFPBRC_BAD_LEN;
219
0
    }
220
221
    /* Get base message version and type (OFPT_*). */
222
0
    hdrs->version = oh->version;
223
0
    hdrs->type = oh->type;
224
225
0
    if (hdrs->type == OFPT_VENDOR) {
226
        /* Get vendor. */
227
0
        const struct ofp_vendor_header *ovh;
228
229
0
        if (length < sizeof *ovh) {
230
0
            return OFPERR_OFPBRC_BAD_LEN;
231
0
        }
232
233
0
        ovh = (const struct ofp_vendor_header *) oh;
234
0
        hdrs->vendor = ntohl(ovh->vendor);
235
0
        if (hdrs->vendor == NX_VENDOR_ID || hdrs->vendor == ONF_VENDOR_ID) {
236
0
            hdrs->subtype = ntohl(ovh->subtype);
237
0
        } else {
238
0
            log_bad_vendor(hdrs->vendor);
239
0
            return OFPERR_OFPBRC_BAD_VENDOR;
240
0
        }
241
0
    } else if (hdrs->version == OFP10_VERSION
242
0
               && (hdrs->type == OFPT10_STATS_REQUEST ||
243
0
                   hdrs->type == OFPT10_STATS_REPLY)) {
244
0
        const struct ofp10_stats_msg *osm;
245
246
        /* Get statistic type (OFPST_*). */
247
0
        if (length < sizeof *osm) {
248
0
            return OFPERR_OFPBRC_BAD_LEN;
249
0
        }
250
0
        osm = (const struct ofp10_stats_msg *) oh;
251
0
        hdrs->stat = ntohs(osm->type);
252
253
0
        if (hdrs->stat == OFPST_VENDOR) {
254
            /* Get vendor. */
255
0
            const struct ofp10_vendor_stats_msg *ovsm;
256
257
0
            if (length < sizeof *ovsm) {
258
0
                return OFPERR_OFPBRC_BAD_LEN;
259
0
            }
260
261
0
            ovsm = (const struct ofp10_vendor_stats_msg *) oh;
262
0
            hdrs->vendor = ntohl(ovsm->vendor);
263
0
            if (hdrs->vendor == NX_VENDOR_ID) {
264
                /* Get Nicira statistic type (NXST_*). */
265
0
                const struct nicira10_stats_msg *nsm;
266
267
0
                if (length < sizeof *nsm) {
268
0
                    return OFPERR_OFPBRC_BAD_LEN;
269
0
                }
270
0
                nsm = (const struct nicira10_stats_msg *) oh;
271
0
                hdrs->subtype = ntohl(nsm->subtype);
272
0
            } else {
273
0
                log_bad_vendor(hdrs->vendor);
274
0
                return OFPERR_OFPBRC_BAD_VENDOR;
275
0
            }
276
0
        }
277
0
    } else if (hdrs->version != OFP10_VERSION
278
0
               && (hdrs->type == OFPT11_STATS_REQUEST ||
279
0
                   hdrs->type == OFPT11_STATS_REPLY)) {
280
0
        const struct ofp11_stats_msg *osm;
281
282
        /* Get statistic type (OFPST_*). */
283
0
        if (length < sizeof *osm) {
284
0
            return OFPERR_OFPBRC_BAD_LEN;
285
0
        }
286
0
        osm = (const struct ofp11_stats_msg *) oh;
287
0
        hdrs->stat = ntohs(osm->type);
288
289
0
        if (hdrs->stat == OFPST_VENDOR) {
290
            /* Get vendor. */
291
0
            const struct ofp11_vendor_stats_msg *ovsm;
292
293
0
            if (length < sizeof *ovsm) {
294
0
                return OFPERR_OFPBRC_BAD_LEN;
295
0
            }
296
297
0
            ovsm = (const struct ofp11_vendor_stats_msg *) oh;
298
0
            hdrs->vendor = ntohl(ovsm->vendor);
299
0
            if (hdrs->vendor == NX_VENDOR_ID ||
300
0
                hdrs->vendor == ONF_VENDOR_ID) {
301
0
                hdrs->subtype = ntohl(ovsm->subtype);
302
0
            } else {
303
0
                log_bad_vendor(hdrs->vendor);
304
0
                return OFPERR_OFPBRC_BAD_VENDOR;
305
0
            }
306
0
        }
307
0
    }
308
309
0
    return 0;
310
0
}
311
312
static void
313
ofphdrs_decode_assert(struct ofphdrs *hdrs,
314
                      const struct ofp_header *oh, size_t length)
315
0
{
316
0
    ovs_assert(!ofphdrs_decode(hdrs, oh, length));
317
0
}
318
319
static bool
320
ofp_is_stat_request(enum ofp_version version, uint8_t type)
321
0
{
322
0
    switch (version) {
323
0
    case OFP10_VERSION:
324
0
        return type == OFPT10_STATS_REQUEST;
325
0
    case OFP11_VERSION:
326
0
    case OFP12_VERSION:
327
0
    case OFP13_VERSION:
328
0
    case OFP14_VERSION:
329
0
    case OFP15_VERSION:
330
0
        return type == OFPT11_STATS_REQUEST;
331
0
    }
332
333
0
    return false;
334
0
}
335
336
static bool
337
ofp_is_stat_reply(enum ofp_version version, uint8_t type)
338
0
{
339
0
    switch (version) {
340
0
    case OFP10_VERSION:
341
0
        return type == OFPT10_STATS_REPLY;
342
0
    case OFP11_VERSION:
343
0
    case OFP12_VERSION:
344
0
    case OFP13_VERSION:
345
0
    case OFP14_VERSION:
346
0
    case OFP15_VERSION:
347
0
        return type == OFPT11_STATS_REPLY;
348
0
    }
349
350
0
    return false;
351
0
}
352
353
static bool
354
ofp_is_stat(enum ofp_version version, uint8_t type)
355
0
{
356
0
    return (ofp_is_stat_request(version, type) ||
357
0
            ofp_is_stat_reply(version, type));
358
0
}
359
360
static bool
361
ofphdrs_is_stat(const struct ofphdrs *hdrs)
362
0
{
363
0
    return ofp_is_stat(hdrs->version, hdrs->type);
364
0
}
365
366
size_t
367
ofphdrs_len(const struct ofphdrs *hdrs)
368
0
{
369
0
    if (hdrs->type == OFPT_VENDOR) {
370
0
        return sizeof(struct ofp_vendor_header);
371
0
    }
372
373
0
    switch ((enum ofp_version) hdrs->version) {
374
0
    case OFP10_VERSION:
375
0
        if (hdrs->type == OFPT10_STATS_REQUEST ||
376
0
            hdrs->type == OFPT10_STATS_REPLY) {
377
0
            return (hdrs->stat == OFPST_VENDOR
378
0
                    ? sizeof(struct nicira10_stats_msg)
379
0
                    : sizeof(struct ofp10_stats_msg));
380
0
        }
381
0
        break;
382
383
0
    case OFP11_VERSION:
384
0
    case OFP12_VERSION:
385
0
    case OFP13_VERSION:
386
0
    case OFP14_VERSION:
387
0
    case OFP15_VERSION:
388
0
        if (hdrs->type == OFPT11_STATS_REQUEST ||
389
0
            hdrs->type == OFPT11_STATS_REPLY) {
390
0
            return (hdrs->stat == OFPST_VENDOR
391
0
                    ? sizeof(struct ofp11_vendor_stats_msg)
392
0
                    : sizeof(struct ofp11_stats_msg));
393
0
        }
394
0
        break;
395
0
    }
396
397
0
    return sizeof(struct ofp_header);
398
0
}
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
0
{
410
0
    struct ofpbuf msg = ofpbuf_const_initializer(oh, ntohs(oh->length));
411
0
    return ofpraw_pull(raw, &msg);
412
0
}
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
0
{
423
0
    enum ofpraw raw;
424
0
    ovs_assert(!ofpraw_decode(&raw, oh));
425
0
    return raw;
426
0
}
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
0
{
435
0
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
436
437
0
    unsigned int min_len = instance->hdrs_len + info->min_body;
438
0
    switch (info->extra_multiple) {
439
0
    case 0:
440
0
        if (len != min_len) {
441
0
            VLOG_WARN_RL(&rl, "received %s with incorrect length %u (expected "
442
0
                         "length %u)", info->name, len, min_len);
443
0
            return OFPERR_OFPBRC_BAD_LEN;
444
0
        }
445
0
        break;
446
447
0
    case 1:
448
0
        if (len < min_len) {
449
0
            VLOG_WARN_RL(&rl, "received %s with incorrect length %u (expected "
450
0
                         "length at least %u bytes)",
451
0
                         info->name, len, min_len);
452
0
            return OFPERR_OFPBRC_BAD_LEN;
453
0
        }
454
0
        break;
455
456
0
    default:
457
0
        if (len < min_len || (len - min_len) % info->extra_multiple) {
458
0
            VLOG_WARN_RL(&rl, "received %s with incorrect length %u (must be "
459
0
                         "exactly %u bytes or longer by an integer multiple "
460
0
                         "of %u bytes)",
461
0
                         info->name, len, min_len, info->extra_multiple);
462
0
            return OFPERR_OFPBRC_BAD_LEN;
463
0
        }
464
0
        break;
465
0
    }
466
467
0
    return 0;
468
0
}
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
0
{
486
    /* Set default outputs. */
487
0
    msg->header = msg->data;
488
0
    msg->msg = msg->header;
489
0
    *rawp = 0;
490
491
0
    struct ofphdrs hdrs;
492
0
    enum ofperr error = ofphdrs_decode(&hdrs, msg->data, msg->size);
493
0
    if (error) {
494
0
        return error;
495
0
    }
496
497
0
    enum ofpraw raw;
498
0
    error = ofpraw_from_ofphdrs(&raw, &hdrs);
499
0
    if (error) {
500
0
        return error;
501
0
    }
502
503
0
    const struct raw_info *info = raw_info_get(raw);
504
0
    const struct raw_instance *instance = raw_instance_get(info, hdrs.version);
505
0
    error = ofpraw_check_length(info, instance, msg->size);
506
0
    if (error) {
507
0
        return error;
508
0
    }
509
510
0
    msg->header = ofpbuf_pull(msg, instance->hdrs_len);
511
0
    msg->msg = msg->data;
512
0
    *rawp = raw;
513
0
    return 0;
514
0
}
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
0
{
525
0
    enum ofpraw raw;
526
0
    ovs_assert(!ofpraw_pull(&raw, msg));
527
0
    return raw;
528
0
}
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
0
{
544
0
    struct ofphdrs hdrs;
545
0
    enum ofperr error;
546
547
0
    error = ofphdrs_decode(&hdrs, oh, length);
548
0
    if (!error) {
549
0
        error = ofpraw_from_ofphdrs(raw, &hdrs);
550
0
    }
551
552
0
    if (error) {
553
0
        *raw = 0;
554
0
    }
555
0
    return error;
556
0
}
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
0
{
581
0
    return ofpraw_alloc_xid(raw, version, alloc_xid(), extra_tailroom);
582
0
}
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
0
{
589
0
    struct ofpbuf *buf = ofpbuf_new(0);
590
0
    ofpraw_put__(raw, version, xid, extra_tailroom, buf);
591
0
    return buf;
592
0
}
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
0
{
713
0
    const struct raw_info *info = raw_info_get(raw);
714
0
    const struct raw_instance *instance = raw_instance_get(info, version);
715
0
    const struct ofphdrs *hdrs = &instance->hdrs;
716
0
    struct ofp_header *oh;
717
718
0
    ofpbuf_prealloc_tailroom(buf, (instance->hdrs_len + info->min_body
719
0
                                   + extra_tailroom));
720
0
    buf->header = ofpbuf_put_uninit(buf, instance->hdrs_len);
721
0
    buf->msg = ofpbuf_tail(buf);
722
723
0
    oh = buf->header;
724
0
    oh->version = version;
725
0
    oh->type = hdrs->type;
726
0
    oh->length = htons(buf->size);
727
0
    oh->xid = xid;
728
729
0
    if (hdrs->type == OFPT_VENDOR) {
730
0
        struct ofp_vendor_header *ovh = buf->header;
731
732
0
        ovh->vendor = htonl(hdrs->vendor);
733
0
        ovh->subtype = htonl(hdrs->subtype);
734
0
    } else if (version == OFP10_VERSION
735
0
               && (hdrs->type == OFPT10_STATS_REQUEST ||
736
0
                   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
0
    } else if (version != OFP10_VERSION
756
0
               && (hdrs->type == OFPT11_STATS_REQUEST ||
757
0
                   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
0
}
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
0
{
783
0
    return raw_info_get(raw)->name;
784
0
}
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
0
{
829
0
    enum ofperr error;
830
0
    enum ofpraw raw;
831
832
0
    error = ofpraw_decode(&raw, oh);
833
0
    *typep = error ? 0 : ofptype_from_ofpraw(raw);
834
0
    return error;
835
0
}
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
0
{
868
0
    return raw_info_get(raw)->type;
869
0
}
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
0
{
883
0
    struct ofp_header *oh = ofpbuf_at_assert(buf, 0, sizeof *oh);
884
0
    oh->length = htons(buf->size);
885
0
}
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
0
{
892
0
    struct ofphdrs hdrs;
893
894
0
    ofphdrs_decode_assert(&hdrs, oh, ntohs(oh->length));
895
0
    return (const uint8_t *) oh + ofphdrs_len(&hdrs);
896
0
}
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
0
{
902
0
    return ofp_is_stat_request(oh->version, oh->type);
903
0
}
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
0
{
916
0
    return ofp_is_stat(oh->version, oh->type);
917
0
}
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
0
{
1029
0
    switch ((enum ofp_version)oh->version) {
1030
0
    case OFP10_VERSION:
1031
0
        return &((struct ofp10_stats_msg *) oh)->flags;
1032
0
    case OFP11_VERSION:
1033
0
    case OFP12_VERSION:
1034
0
    case OFP13_VERSION:
1035
0
    case OFP14_VERSION:
1036
0
    case OFP15_VERSION:
1037
0
        return &((struct ofp11_stats_msg *) oh)->flags;
1038
0
    default:
1039
0
        OVS_NOT_REACHED();
1040
0
    }
1041
0
}
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
0
{
1050
0
    return ntohs(*ofpmp_flags__(oh));
1051
0
}
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
0
{
1308
0
    ofpmsgs_init();
1309
1310
0
    ovs_assert(raw < ARRAY_SIZE(raw_infos));
1311
0
    return &raw_infos[raw];
1312
0
}
1313
1314
static struct raw_instance *
1315
raw_instance_get(const struct raw_info *info, uint8_t version)
1316
0
{
1317
0
    ovs_assert(version >= info->min_version && version <= info->max_version);
1318
0
    return &info->instances[version - info->min_version];
1319
0
}
1320
1321
static enum ofperr
1322
ofpraw_from_ofphdrs(enum ofpraw *raw, const struct ofphdrs *hdrs)
1323
0
{
1324
0
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
1325
1326
0
    struct raw_instance *raw_hdrs;
1327
0
    uint32_t hash;
1328
1329
0
    ofpmsgs_init();
1330
1331
0
    hash = ofphdrs_hash(hdrs);
1332
0
    HMAP_FOR_EACH_WITH_HASH (raw_hdrs, hmap_node, hash, &raw_instance_map) {
1333
0
        if (ofphdrs_equal(hdrs, &raw_hdrs->hdrs)) {
1334
0
            *raw = raw_hdrs->raw;
1335
0
            return 0;
1336
0
        }
1337
0
    }
1338
1339
0
    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
0
    return (hdrs->vendor ? OFPERR_OFPBRC_BAD_SUBTYPE
1357
0
            : ofphdrs_is_stat(hdrs) ? OFPERR_OFPBRC_BAD_STAT
1358
0
            : OFPERR_OFPBRC_BAD_TYPE);
1359
0
}
1360
1361
static void
1362
ofpmsgs_init(void)
1363
0
{
1364
0
    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
1365
0
    const struct raw_info *info;
1366
1367
0
    if (!ovsthread_once_start(&once)) {
1368
0
        return;
1369
0
    }
1370
1371
0
    hmap_init(&raw_instance_map);
1372
0
    for (info = raw_infos; info < &raw_infos[ARRAY_SIZE(raw_infos)]; info++)
1373
0
    {
1374
0
        int n_instances = info->max_version - info->min_version + 1;
1375
0
        struct raw_instance *inst;
1376
1377
0
        for (inst = info->instances;
1378
0
             inst < &info->instances[n_instances];
1379
0
             inst++) {
1380
0
            inst->hdrs_len = ofphdrs_len(&inst->hdrs);
1381
0
            hmap_insert(&raw_instance_map, &inst->hmap_node,
1382
0
                        ofphdrs_hash(&inst->hdrs));
1383
0
        }
1384
0
    }
1385
1386
0
    ovsthread_once_done(&once);
1387
0
}