~ubuntu-branches/ubuntu/wily/openvswitch/wily

« back to all changes in this revision

Viewing changes to lib/ofp-util.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-08-10 11:35:15 UTC
  • mfrom: (1.1.30)
  • Revision ID: package-import@ubuntu.com-20150810113515-575vj06oq29emxsn
Tags: 2.4.0~git20150810.97bab95-0ubuntu1
* New upstream snapshot from 2.4 branch:
  - d/*: Align any relevant packaging changes with upstream.
* d/*: wrap-and-sort.
* d/openvswitch-{common,vswitch}.install: Correct install location for
  bash completion files.
* d/tests/openflow.py: Explicitly use ovs-testcontroller as provided
  by 2.4.0 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
 
2
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
3
3
 *
4
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
5
 * you may not use this file except in compliance with the License.
32
32
#include "multipath.h"
33
33
#include "netdev.h"
34
34
#include "nx-match.h"
 
35
#include "id-pool.h"
35
36
#include "ofp-actions.h"
36
37
#include "ofp-errors.h"
37
38
#include "ofp-msgs.h"
38
39
#include "ofp-util.h"
39
40
#include "ofpbuf.h"
 
41
#include "openflow/netronome-ext.h"
40
42
#include "packets.h"
41
43
#include "random.h"
42
44
#include "unaligned.h"
43
45
#include "type-props.h"
44
 
#include "vlog.h"
 
46
#include "openvswitch/vlog.h"
45
47
#include "bitmap.h"
46
48
 
47
49
VLOG_DEFINE_THIS_MODULE(ofp_util);
50
52
 * in the peer and so there's not much point in showing a lot of them. */
51
53
static struct vlog_rate_limit bad_ofmsg_rl = VLOG_RATE_LIMIT_INIT(1, 5);
52
54
 
 
55
static enum ofputil_table_miss ofputil_table_miss_from_config(
 
56
    ovs_be32 config_, enum ofp_version);
 
57
 
53
58
struct ofp_prop_header {
54
59
    ovs_be16 type;
55
60
    ovs_be16 len;
56
61
};
57
62
 
 
63
struct ofp_prop_experimenter {
 
64
    ovs_be16 type;          /* OFP*_EXPERIMENTER. */
 
65
    ovs_be16 length;        /* Length in bytes of this property. */
 
66
    ovs_be32 experimenter;  /* Experimenter ID which takes the same form as
 
67
                             * in struct ofp_experimenter_header. */
 
68
    ovs_be32 exp_type;      /* Experimenter defined. */
 
69
};
 
70
 
58
71
/* Pulls a property, beginning with struct ofp_prop_header, from the beginning
59
72
 * of 'msg'.  Stores the type of the property in '*typep' and, if 'property' is
60
73
 * nonnull, the entire property, including the header, in '*property'.  Returns
61
 
 * 0 if successful, otherwise an error code. */
 
74
 * 0 if successful, otherwise an error code.
 
75
 *
 
76
 * This function pulls the property's stated size padded out to a multiple of
 
77
 * 'alignment' bytes.  The common case in OpenFlow is an 'alignment' of 8, so
 
78
 * you can use ofputil_pull_property() for that case. */
62
79
static enum ofperr
63
 
ofputil_pull_property(struct ofpbuf *msg, struct ofpbuf *property,
64
 
                      uint16_t *typep)
 
80
ofputil_pull_property__(struct ofpbuf *msg, struct ofpbuf *property,
 
81
                        unsigned int alignment, uint16_t *typep)
65
82
{
66
83
    struct ofp_prop_header *oph;
 
84
    unsigned int padded_len;
67
85
    unsigned int len;
68
86
 
69
 
    if (ofpbuf_size(msg) < sizeof *oph) {
 
87
    if (msg->size < sizeof *oph) {
70
88
        return OFPERR_OFPBPC_BAD_LEN;
71
89
    }
72
90
 
73
 
    oph = ofpbuf_data(msg);
 
91
    oph = msg->data;
74
92
    len = ntohs(oph->len);
75
 
    if (len < sizeof *oph || ROUND_UP(len, 8) > ofpbuf_size(msg)) {
 
93
    padded_len = ROUND_UP(len, alignment);
 
94
    if (len < sizeof *oph || padded_len > msg->size) {
76
95
        return OFPERR_OFPBPC_BAD_LEN;
77
96
    }
78
97
 
79
98
    *typep = ntohs(oph->type);
80
99
    if (property) {
81
 
        ofpbuf_use_const(property, ofpbuf_data(msg), len);
 
100
        ofpbuf_use_const(property, msg->data, len);
82
101
    }
83
 
    ofpbuf_pull(msg, ROUND_UP(len, 8));
 
102
    ofpbuf_pull(msg, padded_len);
84
103
    return 0;
85
104
}
86
105
 
87
 
static void PRINTF_FORMAT(2, 3)
 
106
/* Pulls a property, beginning with struct ofp_prop_header, from the beginning
 
107
 * of 'msg'.  Stores the type of the property in '*typep' and, if 'property' is
 
108
 * nonnull, the entire property, including the header, in '*property'.  Returns
 
109
 * 0 if successful, otherwise an error code.
 
110
 *
 
111
 * This function pulls the property's stated size padded out to a multiple of
 
112
 * 8 bytes, which is the common case for OpenFlow properties. */
 
113
static enum ofperr
 
114
ofputil_pull_property(struct ofpbuf *msg, struct ofpbuf *property,
 
115
                      uint16_t *typep)
 
116
{
 
117
    return ofputil_pull_property__(msg, property, 8, typep);
 
118
}
 
119
 
 
120
static void OVS_PRINTF_FORMAT(2, 3)
88
121
log_property(bool loose, const char *message, ...)
89
122
{
90
123
    enum vlog_level level = loose ? VLL_DBG : VLL_WARN;
97
130
    }
98
131
}
99
132
 
 
133
static size_t
 
134
start_property(struct ofpbuf *msg, uint16_t type)
 
135
{
 
136
    size_t start_ofs = msg->size;
 
137
    struct ofp_prop_header *oph;
 
138
 
 
139
    oph = ofpbuf_put_uninit(msg, sizeof *oph);
 
140
    oph->type = htons(type);
 
141
    oph->len = htons(4);        /* May be updated later by end_property(). */
 
142
    return start_ofs;
 
143
}
 
144
 
 
145
static void
 
146
end_property(struct ofpbuf *msg, size_t start_ofs)
 
147
{
 
148
    struct ofp_prop_header *oph;
 
149
 
 
150
    oph = ofpbuf_at_assert(msg, start_ofs, sizeof *oph);
 
151
    oph->len = htons(msg->size - start_ofs);
 
152
    ofpbuf_padto(msg, ROUND_UP(msg->size, 8));
 
153
}
 
154
 
 
155
static void
 
156
put_bitmap_properties(struct ofpbuf *msg, uint64_t bitmap)
 
157
{
 
158
    for (; bitmap; bitmap = zero_rightmost_1bit(bitmap)) {
 
159
        start_property(msg, rightmost_1bit_idx(bitmap));
 
160
    }
 
161
}
 
162
 
100
163
/* Given the wildcard bit count in the least-significant 6 of 'wcbits', returns
101
164
 * an IP netmask with a 1 in each bit that must match and a 0 in each bit that
102
165
 * is wildcarded.
132
195
void
133
196
ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
134
197
{
135
 
    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 26);
 
198
    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 31);
136
199
 
137
200
    /* Initialize most of wc. */
138
201
    flow_wildcards_init_catchall(wc);
312
375
ofputil_pull_ofp11_match(struct ofpbuf *buf, struct match *match,
313
376
                         uint16_t *padded_match_len)
314
377
{
315
 
    struct ofp11_match_header *omh = ofpbuf_data(buf);
 
378
    struct ofp11_match_header *omh = buf->data;
316
379
    uint16_t match_len;
317
380
 
318
 
    if (ofpbuf_size(buf) < sizeof *omh) {
 
381
    if (buf->size < sizeof *omh) {
319
382
        return OFPERR_OFPBMC_BAD_LEN;
320
383
    }
321
384
 
325
388
    case OFPMT_STANDARD: {
326
389
        struct ofp11_match *om;
327
390
 
328
 
        if (match_len != sizeof *om || ofpbuf_size(buf) < sizeof *om) {
 
391
        if (match_len != sizeof *om || buf->size < sizeof *om) {
329
392
            return OFPERR_OFPBMC_BAD_LEN;
330
393
        }
331
394
        om = ofpbuf_pull(buf, sizeof *om);
1299
1362
    ofpbuf_pull(&msg, sizeof *oh);
1300
1363
 
1301
1364
    *allowed_versions = version_bitmap_from_version(oh->version);
1302
 
    while (ofpbuf_size(&msg)) {
 
1365
    while (msg.size) {
1303
1366
        const struct ofp_hello_elem_header *oheh;
1304
1367
        unsigned int len;
1305
1368
 
1306
 
        if (ofpbuf_size(&msg) < sizeof *oheh) {
 
1369
        if (msg.size < sizeof *oheh) {
1307
1370
            return false;
1308
1371
        }
1309
1372
 
1310
 
        oheh = ofpbuf_data(&msg);
 
1373
        oheh = msg.data;
1311
1374
        len = ntohs(oheh->length);
1312
1375
        if (len < sizeof *oheh || !ofpbuf_try_pull(&msg, ROUND_UP(len, 8))) {
1313
1376
            return false;
1596
1659
    struct ofpbuf b;
1597
1660
    enum ofpraw raw;
1598
1661
 
 
1662
    /* Ignored for non-delete actions */
 
1663
    fm->delete_reason = OFPRR_DELETE;
 
1664
 
1599
1665
    ofpbuf_use_const(&b, oh, ntohs(oh->length));
1600
1666
    raw = ofpraw_pull_assert(&b);
1601
1667
    if (raw == OFPRAW_OFPT11_FLOW_MOD) {
1609
1675
            return error;
1610
1676
        }
1611
1677
 
1612
 
        error = ofpacts_pull_openflow_instructions(&b, ofpbuf_size(&b), oh->version,
1613
 
                                                   ofpacts);
1614
 
        if (error) {
1615
 
            return error;
1616
 
        }
1617
 
 
1618
1678
        /* Translate the message. */
1619
1679
        fm->priority = ntohs(ofm->priority);
1620
1680
        if (ofm->command == OFPFC_ADD
1650
1710
 
1651
1711
        fm->idle_timeout = ntohs(ofm->idle_timeout);
1652
1712
        fm->hard_timeout = ntohs(ofm->hard_timeout);
 
1713
        if (oh->version >= OFP14_VERSION && ofm->command == OFPFC_ADD) {
 
1714
            fm->importance = ntohs(ofm->importance);
 
1715
        } else {
 
1716
            fm->importance = 0;
 
1717
        }
1653
1718
        fm->buffer_id = ntohl(ofm->buffer_id);
1654
1719
        error = ofputil_port_from_ofp11(ofm->out_port, &fm->out_port);
1655
1720
        if (error) {
1675
1740
            ofputil_match_from_ofp10_match(&ofm->match, &fm->match);
1676
1741
            ofputil_normalize_match(&fm->match);
1677
1742
 
1678
 
            /* Now get the actions. */
1679
 
            error = ofpacts_pull_openflow_actions(&b, ofpbuf_size(&b), oh->version,
1680
 
                                                  ofpacts);
1681
 
            if (error) {
1682
 
                return error;
1683
 
            }
1684
 
 
1685
1743
            /* OpenFlow 1.0 says that exact-match rules have to have the
1686
1744
             * highest possible priority. */
1687
1745
            fm->priority = (ofm->match.wildcards & htonl(OFPFW10_ALL)
1695
1753
            fm->new_cookie = ofm->cookie;
1696
1754
            fm->idle_timeout = ntohs(ofm->idle_timeout);
1697
1755
            fm->hard_timeout = ntohs(ofm->hard_timeout);
 
1756
            fm->importance = 0;
1698
1757
            fm->buffer_id = ntohl(ofm->buffer_id);
1699
1758
            fm->out_port = u16_to_ofp(ntohs(ofm->out_port));
1700
1759
            fm->out_group = OFPG11_ANY;
1710
1769
            if (error) {
1711
1770
                return error;
1712
1771
            }
1713
 
            error = ofpacts_pull_openflow_actions(&b, ofpbuf_size(&b), oh->version,
1714
 
                                                  ofpacts);
1715
 
            if (error) {
1716
 
                return error;
1717
 
            }
1718
1772
 
1719
1773
            /* Translate the message. */
1720
1774
            command = ntohs(nfm->command);
1727
1781
            fm->new_cookie = nfm->cookie;
1728
1782
            fm->idle_timeout = ntohs(nfm->idle_timeout);
1729
1783
            fm->hard_timeout = ntohs(nfm->hard_timeout);
 
1784
            fm->importance = 0;
1730
1785
            fm->buffer_id = ntohl(nfm->buffer_id);
1731
1786
            fm->out_port = u16_to_ofp(ntohs(nfm->out_port));
1732
1787
            fm->out_group = OFPG11_ANY;
1740
1795
            fm->command = command & 0xff;
1741
1796
            fm->table_id = command >> 8;
1742
1797
        } else {
 
1798
            if (command > 0xff) {
 
1799
                VLOG_WARN_RL(&bad_ofmsg_rl, "flow_mod has explicit table_id "
 
1800
                             "but flow_mod_table_id extension is not enabled");
 
1801
            }
1743
1802
            fm->command = command;
1744
1803
            fm->table_id = 0xff;
1745
1804
        }
1746
1805
    }
1747
1806
 
1748
 
    fm->ofpacts = ofpbuf_data(ofpacts);
1749
 
    fm->ofpacts_len = ofpbuf_size(ofpacts);
 
1807
    if (fm->command > OFPFC_DELETE_STRICT) {
 
1808
        return OFPERR_OFPFMFC_BAD_COMMAND;
 
1809
    }
 
1810
 
 
1811
    error = ofpacts_pull_openflow_instructions(&b, b.size,
 
1812
                                               oh->version, ofpacts);
 
1813
    if (error) {
 
1814
        return error;
 
1815
    }
 
1816
    fm->ofpacts = ofpacts->data;
 
1817
    fm->ofpacts_len = ofpacts->size;
1750
1818
 
1751
1819
    error = ofputil_decode_flow_mod_flags(raw_flags, fm->command,
1752
1820
                                          oh->version, &fm->flags);
1844
1912
            mm->meter.flags & OFPMF13_PKTPS) {
1845
1913
            return OFPERR_OFPMMFC_BAD_FLAGS;
1846
1914
        }
1847
 
        mm->meter.bands = ofpbuf_data(bands);
 
1915
        mm->meter.bands = bands->data;
1848
1916
 
1849
 
        error = ofputil_pull_bands(&b, ofpbuf_size(&b), &mm->meter.n_bands, bands);
 
1917
        error = ofputil_pull_bands(&b, b.size, &mm->meter.n_bands, bands);
1850
1918
        if (error) {
1851
1919
            return error;
1852
1920
        }
1918
1986
 
1919
1987
/* Encode a meter stat for 'mc' and append it to 'replies'. */
1920
1988
void
1921
 
ofputil_append_meter_config(struct list *replies,
 
1989
ofputil_append_meter_config(struct ovs_list *replies,
1922
1990
                            const struct ofputil_meter_config *mc)
1923
1991
{
1924
1992
    struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
1925
 
    size_t start_ofs = ofpbuf_size(msg);
 
1993
    size_t start_ofs = msg->size;
1926
1994
    struct ofp13_meter_config *reply = ofpbuf_put_uninit(msg, sizeof *reply);
1927
1995
    reply->flags = htons(mc->flags);
1928
1996
    reply->meter_id = htonl(mc->meter_id);
1929
1997
 
1930
1998
    ofputil_put_bands(mc->n_bands, mc->bands, msg);
1931
1999
 
1932
 
    reply->length = htons(ofpbuf_size(msg) - start_ofs);
 
2000
    reply->length = htons(msg->size - start_ofs);
1933
2001
 
1934
2002
    ofpmp_postappend(replies, start_ofs);
1935
2003
}
1936
2004
 
1937
2005
/* Encode a meter stat for 'ms' and append it to 'replies'. */
1938
2006
void
1939
 
ofputil_append_meter_stats(struct list *replies,
 
2007
ofputil_append_meter_stats(struct ovs_list *replies,
1940
2008
                           const struct ofputil_meter_stats *ms)
1941
2009
{
1942
2010
    struct ofp13_meter_stats *reply;
1984
2052
    enum ofperr err;
1985
2053
 
1986
2054
    /* Pull OpenFlow headers for the first call. */
1987
 
    if (!msg->frame) {
 
2055
    if (!msg->header) {
1988
2056
        ofpraw_pull_assert(msg);
1989
2057
    }
1990
2058
 
1991
 
    if (!ofpbuf_size(msg)) {
 
2059
    if (!msg->size) {
1992
2060
        return EOF;
1993
2061
    }
1994
2062
 
1996
2064
    if (!omc) {
1997
2065
        VLOG_WARN_RL(&bad_ofmsg_rl,
1998
2066
                     "OFPMP_METER_CONFIG reply has %"PRIu32" leftover bytes at end",
1999
 
                     ofpbuf_size(msg));
 
2067
                     msg->size);
2000
2068
        return OFPERR_OFPBRC_BAD_LEN;
2001
2069
    }
2002
2070
 
2008
2076
    }
2009
2077
    mc->meter_id = ntohl(omc->meter_id);
2010
2078
    mc->flags = ntohs(omc->flags);
2011
 
    mc->bands = ofpbuf_data(bands);
 
2079
    mc->bands = bands->data;
2012
2080
 
2013
2081
    return 0;
2014
2082
}
2060
2128
    enum ofperr err;
2061
2129
 
2062
2130
    /* Pull OpenFlow headers for the first call. */
2063
 
    if (!msg->frame) {
 
2131
    if (!msg->header) {
2064
2132
        ofpraw_pull_assert(msg);
2065
2133
    }
2066
2134
 
2067
 
    if (!ofpbuf_size(msg)) {
 
2135
    if (!msg->size) {
2068
2136
        return EOF;
2069
2137
    }
2070
2138
 
2072
2140
    if (!oms) {
2073
2141
        VLOG_WARN_RL(&bad_ofmsg_rl,
2074
2142
                     "OFPMP_METER reply has %"PRIu32" leftover bytes at end",
2075
 
                     ofpbuf_size(msg));
 
2143
                     msg->size);
2076
2144
        return OFPERR_OFPBRC_BAD_LEN;
2077
2145
    }
2078
2146
 
2088
2156
    ms->byte_in_count = ntohll(oms->byte_in_count);
2089
2157
    ms->duration_sec = ntohl(oms->duration_sec);
2090
2158
    ms->duration_nsec = ntohl(oms->duration_nsec);
2091
 
    ms->bands = ofpbuf_data(bands);
 
2159
    ms->bands = bands->data;
2092
2160
 
2093
2161
    return 0;
2094
2162
}
2186
2254
            || fm->command == OFPFC_ADD) {
2187
2255
            ofm->cookie = fm->new_cookie;
2188
2256
        } else {
2189
 
            ofm->cookie = fm->cookie;
 
2257
            ofm->cookie = fm->cookie & fm->cookie_mask;
2190
2258
        }
2191
2259
        ofm->cookie_mask = fm->cookie_mask;
2192
2260
        if (fm->table_id != OFPTT_ALL
2205
2273
        ofm->out_port = ofputil_port_to_ofp11(fm->out_port);
2206
2274
        ofm->out_group = htonl(fm->out_group);
2207
2275
        ofm->flags = raw_flags;
 
2276
        if (version >= OFP14_VERSION && fm->command == OFPFC_ADD) {
 
2277
            ofm->importance = htons(fm->importance);
 
2278
        } else {
 
2279
            ofm->importance = 0;
 
2280
        }
2208
2281
        ofputil_put_ofp11_match(msg, &fm->match, protocol);
2209
2282
        ofpacts_put_openflow_instructions(fm->ofpacts, fm->ofpacts_len, msg,
2210
2283
                                          version);
2243
2316
        nfm->command = ofputil_tid_command(fm, protocol);
2244
2317
        nfm->cookie = fm->new_cookie;
2245
2318
        match_len = nx_put_match(msg, &fm->match, fm->cookie, fm->cookie_mask);
2246
 
        nfm = ofpbuf_l3(msg);
 
2319
        nfm = msg->msg;
2247
2320
        nfm->idle_timeout = htons(fm->idle_timeout);
2248
2321
        nfm->hard_timeout = htons(fm->hard_timeout);
2249
2322
        nfm->priority = htons(fm->priority);
2317
2390
    if (error) {
2318
2391
        return error;
2319
2392
    }
2320
 
    if (ofpbuf_size(b)) {
 
2393
    if (b->size) {
2321
2394
        return OFPERR_OFPBRC_BAD_LEN;
2322
2395
    }
2323
2396
 
2373
2446
 
2374
2447
    switch ((int) raw) {
2375
2448
    case OFPRAW_OFPT10_QUEUE_GET_CONFIG_REQUEST:
2376
 
        qgcr10 = ofpbuf_data(&b);
 
2449
        qgcr10 = b.data;
2377
2450
        *port = u16_to_ofp(ntohs(qgcr10->port));
2378
2451
        return 0;
2379
2452
 
2380
2453
    case OFPRAW_OFPT11_QUEUE_GET_CONFIG_REQUEST:
2381
 
        qgcr11 = ofpbuf_data(&b);
 
2454
        qgcr11 = b.data;
2382
2455
        return ofputil_port_from_ofp11(qgcr11->port, port);
2383
2456
    }
2384
2457
 
2447
2520
ofputil_append_queue_get_config_reply(struct ofpbuf *reply,
2448
2521
                                      const struct ofputil_queue_config *oqc)
2449
2522
{
2450
 
    const struct ofp_header *oh = ofpbuf_data(reply);
 
2523
    const struct ofp_header *oh = reply->data;
2451
2524
    size_t start_ofs, len_ofs;
2452
2525
    ovs_be16 *len;
2453
2526
 
2454
 
    start_ofs = ofpbuf_size(reply);
 
2527
    start_ofs = reply->size;
2455
2528
    if (oh->version < OFP12_VERSION) {
2456
2529
        struct ofp10_packet_queue *opq10;
2457
2530
 
2458
2531
        opq10 = ofpbuf_put_zeros(reply, sizeof *opq10);
2459
2532
        opq10->queue_id = htonl(oqc->queue_id);
2460
 
        len_ofs = (char *) &opq10->len - (char *) ofpbuf_data(reply);
 
2533
        len_ofs = (char *) &opq10->len - (char *) reply->data;
2461
2534
    } else {
2462
2535
        struct ofp11_queue_get_config_reply *qgcr11;
2463
2536
        struct ofp12_packet_queue *opq12;
2464
2537
        ovs_be32 port;
2465
2538
 
2466
 
        qgcr11 = ofpbuf_l3(reply);
 
2539
        qgcr11 = reply->msg;
2467
2540
        port = qgcr11->port;
2468
2541
 
2469
2542
        opq12 = ofpbuf_put_zeros(reply, sizeof *opq12);
2470
2543
        opq12->port = port;
2471
2544
        opq12->queue_id = htonl(oqc->queue_id);
2472
 
        len_ofs = (char *) &opq12->len - (char *) ofpbuf_data(reply);
 
2545
        len_ofs = (char *) &opq12->len - (char *) reply->data;
2473
2546
    }
2474
2547
 
2475
2548
    put_queue_rate(reply, OFPQT_MIN_RATE, oqc->min_rate);
2476
2549
    put_queue_rate(reply, OFPQT_MAX_RATE, oqc->max_rate);
2477
2550
 
2478
2551
    len = ofpbuf_at(reply, len_ofs, sizeof *len);
2479
 
    *len = htons(ofpbuf_size(reply) - start_ofs);
 
2552
    *len = htons(reply->size - start_ofs);
2480
2553
}
2481
2554
 
2482
2555
/* Decodes the initial part of an OFPT_QUEUE_GET_CONFIG_REPLY from 'reply' and
2535
2608
    unsigned int opq_len;
2536
2609
    unsigned int len;
2537
2610
 
2538
 
    if (!ofpbuf_size(reply)) {
 
2611
    if (!reply->size) {
2539
2612
        return EOF;
2540
2613
    }
2541
2614
 
2542
2615
    queue->min_rate = UINT16_MAX;
2543
2616
    queue->max_rate = UINT16_MAX;
2544
2617
 
2545
 
    oh = reply->frame;
 
2618
    oh = reply->header;
2546
2619
    if (oh->version < OFP12_VERSION) {
2547
2620
        const struct ofp10_packet_queue *opq10;
2548
2621
 
2565
2638
        opq_len = sizeof *opq12;
2566
2639
    }
2567
2640
 
2568
 
    if (len < opq_len || len > ofpbuf_size(reply) + opq_len || len % 8) {
 
2641
    if (len < opq_len || len > reply->size + opq_len || len % 8) {
2569
2642
        return OFPERR_OFPBRC_BAD_LEN;
2570
2643
    }
2571
2644
    len -= opq_len;
2578
2651
 
2579
2652
        hdr = ofpbuf_at_assert(reply, 0, sizeof *hdr);
2580
2653
        prop_len = ntohs(hdr->len);
2581
 
        if (prop_len < sizeof *hdr || prop_len > ofpbuf_size(reply) || prop_len % 8) {
 
2654
        if (prop_len < sizeof *hdr || prop_len > reply->size || prop_len % 8) {
2582
2655
            return OFPERR_OFPBRC_BAD_LEN;
2583
2656
        }
2584
2657
 
2620
2693
    raw = ofpraw_pull_assert(&b);
2621
2694
    switch ((int) raw) {
2622
2695
    case OFPRAW_OFPST10_FLOW_REQUEST:
2623
 
        return ofputil_decode_ofpst10_flow_request(fsr, ofpbuf_data(&b), false);
 
2696
        return ofputil_decode_ofpst10_flow_request(fsr, b.data, false);
2624
2697
 
2625
2698
    case OFPRAW_OFPST10_AGGREGATE_REQUEST:
2626
 
        return ofputil_decode_ofpst10_flow_request(fsr, ofpbuf_data(&b), true);
 
2699
        return ofputil_decode_ofpst10_flow_request(fsr, b.data, true);
2627
2700
 
2628
2701
    case OFPRAW_OFPST11_FLOW_REQUEST:
2629
2702
        return ofputil_decode_ofpst11_flow_request(fsr, &b, false);
2704
2777
        match_len = nx_put_match(msg, &fsr->match,
2705
2778
                                 fsr->cookie, fsr->cookie_mask);
2706
2779
 
2707
 
        nfsr = ofpbuf_l3(msg);
 
2780
        nfsr = msg->msg;
2708
2781
        nfsr->out_port = htons(ofp_to_u16(fsr->out_port));
2709
2782
        nfsr->match_len = htons(match_len);
2710
2783
        nfsr->table_id = fsr->table_id;
2745
2818
                                struct ofpbuf *ofpacts)
2746
2819
{
2747
2820
    const struct ofp_header *oh;
 
2821
    size_t instructions_len;
2748
2822
    enum ofperr error;
2749
2823
    enum ofpraw raw;
2750
2824
 
2751
 
    error = (msg->frame
2752
 
             ? ofpraw_decode(&raw, msg->frame)
 
2825
    error = (msg->header ? ofpraw_decode(&raw, msg->header)
2753
2826
             : ofpraw_pull(&raw, msg));
2754
2827
    if (error) {
2755
2828
        return error;
2756
2829
    }
2757
 
    oh = msg->frame;
 
2830
    oh = msg->header;
2758
2831
 
2759
 
    if (!ofpbuf_size(msg)) {
 
2832
    if (!msg->size) {
2760
2833
        return EOF;
2761
2834
    } else if (raw == OFPRAW_OFPST11_FLOW_REPLY
2762
2835
               || raw == OFPRAW_OFPST13_FLOW_REPLY) {
2767
2840
        ofs = ofpbuf_try_pull(msg, sizeof *ofs);
2768
2841
        if (!ofs) {
2769
2842
            VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply has %"PRIu32" leftover "
2770
 
                         "bytes at end", ofpbuf_size(msg));
 
2843
                         "bytes at end", msg->size);
2771
2844
            return EINVAL;
2772
2845
        }
2773
2846
 
2782
2855
            VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad match");
2783
2856
            return EINVAL;
2784
2857
        }
2785
 
 
2786
 
        if (ofpacts_pull_openflow_instructions(msg, length - sizeof *ofs -
2787
 
                                               padded_match_len, oh->version,
2788
 
                                               ofpacts)) {
2789
 
            VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad instructions");
2790
 
            return EINVAL;
2791
 
        }
 
2858
        instructions_len = length - sizeof *ofs - padded_match_len;
2792
2859
 
2793
2860
        fs->priority = ntohs(ofs->priority);
2794
2861
        fs->table_id = ofs->table_id;
2796
2863
        fs->duration_nsec = ntohl(ofs->duration_nsec);
2797
2864
        fs->idle_timeout = ntohs(ofs->idle_timeout);
2798
2865
        fs->hard_timeout = ntohs(ofs->hard_timeout);
 
2866
        if (oh->version >= OFP14_VERSION) {
 
2867
            fs->importance = ntohs(ofs->importance);
 
2868
        } else {
 
2869
            fs->importance = 0;
 
2870
        }
2799
2871
        if (raw == OFPRAW_OFPST13_FLOW_REPLY) {
2800
2872
            error = ofputil_decode_flow_mod_flags(ofs->flags, -1, oh->version,
2801
2873
                                                  &fs->flags);
2817
2889
        ofs = ofpbuf_try_pull(msg, sizeof *ofs);
2818
2890
        if (!ofs) {
2819
2891
            VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply has %"PRIu32" leftover "
2820
 
                         "bytes at end", ofpbuf_size(msg));
 
2892
                         "bytes at end", msg->size);
2821
2893
            return EINVAL;
2822
2894
        }
2823
2895
 
2827
2899
                         "length %"PRIuSIZE, length);
2828
2900
            return EINVAL;
2829
2901
        }
2830
 
 
2831
 
        if (ofpacts_pull_openflow_actions(msg, length - sizeof *ofs,
2832
 
                                          oh->version, ofpacts)) {
2833
 
            return EINVAL;
2834
 
        }
 
2902
        instructions_len = length - sizeof *ofs;
2835
2903
 
2836
2904
        fs->cookie = get_32aligned_be64(&ofs->cookie);
2837
2905
        ofputil_match_from_ofp10_match(&ofs->match, &fs->match);
2841
2909
        fs->duration_nsec = ntohl(ofs->duration_nsec);
2842
2910
        fs->idle_timeout = ntohs(ofs->idle_timeout);
2843
2911
        fs->hard_timeout = ntohs(ofs->hard_timeout);
 
2912
        fs->importance = 0;
2844
2913
        fs->idle_age = -1;
2845
2914
        fs->hard_age = -1;
2846
2915
        fs->packet_count = ntohll(get_32aligned_be64(&ofs->packet_count));
2848
2917
        fs->flags = 0;
2849
2918
    } else if (raw == OFPRAW_NXST_FLOW_REPLY) {
2850
2919
        const struct nx_flow_stats *nfs;
2851
 
        size_t match_len, actions_len, length;
 
2920
        size_t match_len, length;
2852
2921
 
2853
2922
        nfs = ofpbuf_try_pull(msg, sizeof *nfs);
2854
2923
        if (!nfs) {
2855
2924
            VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW reply has %"PRIu32" leftover "
2856
 
                         "bytes at end", ofpbuf_size(msg));
 
2925
                         "bytes at end", msg->size);
2857
2926
            return EINVAL;
2858
2927
        }
2859
2928
 
2867
2936
        if (nx_pull_match(msg, match_len, &fs->match, NULL, NULL)) {
2868
2937
            return EINVAL;
2869
2938
        }
2870
 
 
2871
 
        actions_len = length - sizeof *nfs - ROUND_UP(match_len, 8);
2872
 
        if (ofpacts_pull_openflow_actions(msg, actions_len, oh->version,
2873
 
                                          ofpacts)) {
2874
 
            return EINVAL;
2875
 
        }
 
2939
        instructions_len = length - sizeof *nfs - ROUND_UP(match_len, 8);
2876
2940
 
2877
2941
        fs->cookie = nfs->cookie;
2878
2942
        fs->table_id = nfs->table_id;
2881
2945
        fs->priority = ntohs(nfs->priority);
2882
2946
        fs->idle_timeout = ntohs(nfs->idle_timeout);
2883
2947
        fs->hard_timeout = ntohs(nfs->hard_timeout);
 
2948
        fs->importance = 0;
2884
2949
        fs->idle_age = -1;
2885
2950
        fs->hard_age = -1;
2886
2951
        if (flow_age_extension) {
2898
2963
        OVS_NOT_REACHED();
2899
2964
    }
2900
2965
 
2901
 
    fs->ofpacts = ofpbuf_data(ofpacts);
2902
 
    fs->ofpacts_len = ofpbuf_size(ofpacts);
 
2966
    if (ofpacts_pull_openflow_instructions(msg, instructions_len, oh->version,
 
2967
                                           ofpacts)) {
 
2968
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad instructions");
 
2969
        return EINVAL;
 
2970
    }
 
2971
    fs->ofpacts = ofpacts->data;
 
2972
    fs->ofpacts_len = ofpacts->size;
2903
2973
 
2904
2974
    return 0;
2905
2975
}
2919
2989
 * have been initialized with ofpmp_init(). */
2920
2990
void
2921
2991
ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
2922
 
                                struct list *replies)
 
2992
                                struct ovs_list *replies)
2923
2993
{
2924
2994
    struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
2925
 
    size_t start_ofs = ofpbuf_size(reply);
 
2995
    size_t start_ofs = reply->size;
2926
2996
    enum ofp_version version = ofpmp_version(replies);
2927
2997
    enum ofpraw raw = ofpmp_decode_raw(replies);
2928
2998
 
2935
3005
                                          version);
2936
3006
 
2937
3007
        ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
2938
 
        ofs->length = htons(ofpbuf_size(reply) - start_ofs);
 
3008
        ofs->length = htons(reply->size - start_ofs);
2939
3009
        ofs->table_id = fs->table_id;
2940
3010
        ofs->pad = 0;
2941
3011
        ofs->duration_sec = htonl(fs->duration_sec);
2943
3013
        ofs->priority = htons(fs->priority);
2944
3014
        ofs->idle_timeout = htons(fs->idle_timeout);
2945
3015
        ofs->hard_timeout = htons(fs->hard_timeout);
 
3016
        if (version >= OFP14_VERSION) {
 
3017
            ofs->importance = htons(fs->importance);
 
3018
        } else {
 
3019
            ofs->importance = 0;
 
3020
        }
2946
3021
        if (raw == OFPRAW_OFPST13_FLOW_REPLY) {
2947
3022
            ofs->flags = ofputil_encode_flow_mod_flags(fs->flags, version);
2948
3023
        } else {
2959
3034
        ofpacts_put_openflow_actions(fs->ofpacts, fs->ofpacts_len, reply,
2960
3035
                                     version);
2961
3036
        ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
2962
 
        ofs->length = htons(ofpbuf_size(reply) - start_ofs);
 
3037
        ofs->length = htons(reply->size - start_ofs);
2963
3038
        ofs->table_id = fs->table_id;
2964
3039
        ofs->pad = 0;
2965
3040
        ofputil_match_to_ofp10_match(&fs->match, &ofs->match);
2983
3058
        ofpacts_put_openflow_actions(fs->ofpacts, fs->ofpacts_len, reply,
2984
3059
                                     version);
2985
3060
        nfs = ofpbuf_at_assert(reply, start_ofs, sizeof *nfs);
2986
 
        nfs->length = htons(ofpbuf_size(reply) - start_ofs);
 
3061
        nfs->length = htons(reply->size - start_ofs);
2987
3062
        nfs->table_id = fs->table_id;
2988
3063
        nfs->pad = 0;
2989
3064
        nfs->duration_sec = htonl(fs->duration_sec);
3049
3124
    ofpbuf_use_const(&msg, reply, ntohs(reply->length));
3050
3125
    ofpraw_pull_assert(&msg);
3051
3126
 
3052
 
    asr = ofpbuf_l3(&msg);
 
3127
    asr = msg.msg;
3053
3128
    stats->packet_count = ntohll(get_32aligned_be64(&asr->packet_count));
3054
3129
    stats->byte_count = ntohll(get_32aligned_be64(&asr->byte_count));
3055
3130
    stats->flow_count = ntohl(asr->flow_count);
3116
3191
        if (error) {
3117
3192
            return error;
3118
3193
        }
3119
 
        if (ofpbuf_size(&b)) {
 
3194
        if (b.size) {
3120
3195
            return OFPERR_OFPBRC_BAD_LEN;
3121
3196
        }
3122
3197
 
3145
3220
                            enum ofputil_protocol protocol)
3146
3221
{
3147
3222
    struct ofpbuf *msg;
 
3223
    enum ofp_flow_removed_reason reason = fr->reason;
 
3224
 
 
3225
    if (reason == OFPRR_METER_DELETE && !(protocol & OFPUTIL_P_OF14_UP)) {
 
3226
        reason = OFPRR_DELETE;
 
3227
    }
3148
3228
 
3149
3229
    switch (protocol) {
3150
3230
    case OFPUTIL_P_OF11_STD:
3161
3241
        ofr = ofpbuf_put_zeros(msg, sizeof *ofr);
3162
3242
        ofr->cookie = fr->cookie;
3163
3243
        ofr->priority = htons(fr->priority);
3164
 
        ofr->reason = fr->reason;
 
3244
        ofr->reason = reason;
3165
3245
        ofr->table_id = fr->table_id;
3166
3246
        ofr->duration_sec = htonl(fr->duration_sec);
3167
3247
        ofr->duration_nsec = htonl(fr->duration_nsec);
3183
3263
        ofputil_match_to_ofp10_match(&fr->match, &ofr->match);
3184
3264
        ofr->cookie = fr->cookie;
3185
3265
        ofr->priority = htons(fr->priority);
3186
 
        ofr->reason = fr->reason;
 
3266
        ofr->reason = reason;
3187
3267
        ofr->duration_sec = htonl(fr->duration_sec);
3188
3268
        ofr->duration_nsec = htonl(fr->duration_nsec);
3189
3269
        ofr->idle_timeout = htons(fr->idle_timeout);
3199
3279
 
3200
3280
        msg = ofpraw_alloc_xid(OFPRAW_NXT_FLOW_REMOVED, OFP10_VERSION,
3201
3281
                               htonl(0), NXM_TYPICAL_LEN);
3202
 
        nfr = ofpbuf_put_zeros(msg, sizeof *nfr);
 
3282
        ofpbuf_put_zeros(msg, sizeof *nfr);
3203
3283
        match_len = nx_put_match(msg, &fr->match, 0, 0);
3204
3284
 
3205
 
        nfr = ofpbuf_l3(msg);
 
3285
        nfr = msg->msg;
3206
3286
        nfr->cookie = fr->cookie;
3207
3287
        nfr->priority = htons(fr->priority);
3208
 
        nfr->reason = fr->reason;
 
3288
        nfr->reason = reason;
3209
3289
        nfr->table_id = fr->table_id + 1;
3210
3290
        nfr->duration_sec = htonl(fr->duration_sec);
3211
3291
        nfr->duration_nsec = htonl(fr->duration_nsec);
3223
3303
    return msg;
3224
3304
}
3225
3305
 
3226
 
static void
3227
 
ofputil_decode_packet_in_finish(struct ofputil_packet_in *pin,
3228
 
                                struct match *match, struct ofpbuf *b)
3229
 
{
3230
 
    pin->packet = ofpbuf_data(b);
3231
 
    pin->packet_len = ofpbuf_size(b);
3232
 
 
3233
 
    pin->fmd.in_port = match->flow.in_port.ofp_port;
3234
 
    pin->fmd.tun_id = match->flow.tunnel.tun_id;
3235
 
    pin->fmd.tun_src = match->flow.tunnel.ip_src;
3236
 
    pin->fmd.tun_dst = match->flow.tunnel.ip_dst;
3237
 
    pin->fmd.metadata = match->flow.metadata;
3238
 
    memcpy(pin->fmd.regs, match->flow.regs, sizeof pin->fmd.regs);
3239
 
    pin->fmd.pkt_mark = match->flow.pkt_mark;
3240
 
}
3241
 
 
3242
3306
enum ofperr
3243
3307
ofputil_decode_packet_in(struct ofputil_packet_in *pin,
3244
3308
                         const struct ofp_header *oh)
3253
3317
    raw = ofpraw_pull_assert(&b);
3254
3318
    if (raw == OFPRAW_OFPT13_PACKET_IN || raw == OFPRAW_OFPT12_PACKET_IN) {
3255
3319
        const struct ofp13_packet_in *opi;
3256
 
        struct match match;
3257
3320
        int error;
3258
3321
        size_t packet_in_size;
3259
3322
 
3264
3327
        }
3265
3328
 
3266
3329
        opi = ofpbuf_pull(&b, packet_in_size);
3267
 
        error = oxm_pull_match_loose(&b, &match);
 
3330
        error = oxm_pull_match_loose(&b, &pin->flow_metadata);
3268
3331
        if (error) {
3269
3332
            return error;
3270
3333
        }
3282
3345
            pin->cookie = opi->cookie;
3283
3346
        }
3284
3347
 
3285
 
        ofputil_decode_packet_in_finish(pin, &match, &b);
 
3348
        pin->packet = b.data;
 
3349
        pin->packet_len = b.size;
3286
3350
    } else if (raw == OFPRAW_OFPT10_PACKET_IN) {
3287
3351
        const struct ofp10_packet_in *opi;
3288
3352
 
3289
3353
        opi = ofpbuf_pull(&b, offsetof(struct ofp10_packet_in, data));
3290
3354
 
3291
3355
        pin->packet = opi->data;
3292
 
        pin->packet_len = ofpbuf_size(&b);
 
3356
        pin->packet_len = b.size;
3293
3357
 
3294
 
        pin->fmd.in_port = u16_to_ofp(ntohs(opi->in_port));
 
3358
        match_init_catchall(&pin->flow_metadata);
 
3359
        match_set_in_port(&pin->flow_metadata, u16_to_ofp(ntohs(opi->in_port)));
3295
3360
        pin->reason = opi->reason;
3296
3361
        pin->buffer_id = ntohl(opi->buffer_id);
3297
3362
        pin->total_len = ntohs(opi->total_len);
3298
3363
    } else if (raw == OFPRAW_OFPT11_PACKET_IN) {
3299
3364
        const struct ofp11_packet_in *opi;
 
3365
        ofp_port_t in_port;
3300
3366
        enum ofperr error;
3301
3367
 
3302
3368
        opi = ofpbuf_pull(&b, sizeof *opi);
3303
3369
 
3304
 
        pin->packet = ofpbuf_data(&b);
3305
 
        pin->packet_len = ofpbuf_size(&b);
 
3370
        pin->packet = b.data;
 
3371
        pin->packet_len = b.size;
3306
3372
 
3307
3373
        pin->buffer_id = ntohl(opi->buffer_id);
3308
 
        error = ofputil_port_from_ofp11(opi->in_port, &pin->fmd.in_port);
 
3374
        error = ofputil_port_from_ofp11(opi->in_port, &in_port);
3309
3375
        if (error) {
3310
3376
            return error;
3311
3377
        }
 
3378
        match_init_catchall(&pin->flow_metadata);
 
3379
        match_set_in_port(&pin->flow_metadata, in_port);
3312
3380
        pin->total_len = ntohs(opi->total_len);
3313
3381
        pin->reason = opi->reason;
3314
3382
        pin->table_id = opi->table_id;
3315
3383
    } else if (raw == OFPRAW_NXT_PACKET_IN) {
3316
3384
        const struct nx_packet_in *npi;
3317
 
        struct match match;
3318
3385
        int error;
3319
3386
 
3320
3387
        npi = ofpbuf_pull(&b, sizeof *npi);
3321
 
        error = nx_pull_match_loose(&b, ntohs(npi->match_len), &match, NULL,
3322
 
                                    NULL);
 
3388
        error = nx_pull_match_loose(&b, ntohs(npi->match_len),
 
3389
                                    &pin->flow_metadata, NULL, NULL);
3323
3390
        if (error) {
3324
3391
            return error;
3325
3392
        }
3335
3402
        pin->buffer_id = ntohl(npi->buffer_id);
3336
3403
        pin->total_len = ntohs(npi->total_len);
3337
3404
 
3338
 
        ofputil_decode_packet_in_finish(pin, &match, &b);
 
3405
        pin->packet = b.data;
 
3406
        pin->packet_len = b.size;
3339
3407
    } else {
3340
3408
        OVS_NOT_REACHED();
3341
3409
    }
3343
3411
    return 0;
3344
3412
}
3345
3413
 
3346
 
static void
3347
 
ofputil_packet_in_to_match(const struct ofputil_packet_in *pin,
3348
 
                           struct match *match)
3349
 
{
3350
 
    int i;
3351
 
 
3352
 
    match_init_catchall(match);
3353
 
    if (pin->fmd.tun_id != htonll(0)) {
3354
 
        match_set_tun_id(match, pin->fmd.tun_id);
3355
 
    }
3356
 
    if (pin->fmd.tun_src != htonl(0)) {
3357
 
        match_set_tun_src(match, pin->fmd.tun_src);
3358
 
    }
3359
 
    if (pin->fmd.tun_dst != htonl(0)) {
3360
 
        match_set_tun_dst(match, pin->fmd.tun_dst);
3361
 
    }
3362
 
    if (pin->fmd.metadata != htonll(0)) {
3363
 
        match_set_metadata(match, pin->fmd.metadata);
3364
 
    }
3365
 
 
3366
 
    for (i = 0; i < FLOW_N_REGS; i++) {
3367
 
        if (pin->fmd.regs[i]) {
3368
 
            match_set_reg(match, i, pin->fmd.regs[i]);
3369
 
        }
3370
 
    }
3371
 
 
3372
 
    if (pin->fmd.pkt_mark != 0) {
3373
 
        match_set_pkt_mark(match, pin->fmd.pkt_mark);
3374
 
    }
3375
 
 
3376
 
    match_set_in_port(match, pin->fmd.in_port);
3377
 
}
3378
 
 
3379
3414
static struct ofpbuf *
3380
3415
ofputil_encode_ofp10_packet_in(const struct ofputil_packet_in *pin)
3381
3416
{
3386
3421
                              htonl(0), pin->packet_len);
3387
3422
    opi = ofpbuf_put_zeros(packet, offsetof(struct ofp10_packet_in, data));
3388
3423
    opi->total_len = htons(pin->total_len);
3389
 
    opi->in_port = htons(ofp_to_u16(pin->fmd.in_port));
 
3424
    opi->in_port = htons(ofp_to_u16(pin->flow_metadata.flow.in_port.ofp_port));
3390
3425
    opi->reason = pin->reason;
3391
3426
    opi->buffer_id = htonl(pin->buffer_id);
3392
3427
 
3400
3435
{
3401
3436
    struct nx_packet_in *npi;
3402
3437
    struct ofpbuf *packet;
3403
 
    struct match match;
3404
3438
    size_t match_len;
3405
3439
 
3406
 
    ofputil_packet_in_to_match(pin, &match);
3407
 
 
3408
3440
    /* The final argument is just an estimate of the space required. */
3409
3441
    packet = ofpraw_alloc_xid(OFPRAW_NXT_PACKET_IN, OFP10_VERSION,
3410
 
                              htonl(0), (sizeof(struct flow_metadata) * 2
3411
 
                                         + 2 + pin->packet_len));
 
3442
                              htonl(0), NXM_TYPICAL_LEN + 2 + pin->packet_len);
3412
3443
    ofpbuf_put_zeros(packet, sizeof *npi);
3413
 
    match_len = nx_put_match(packet, &match, 0, 0);
 
3444
    match_len = nx_put_match(packet, &pin->flow_metadata, 0, 0);
3414
3445
    ofpbuf_put_zeros(packet, 2);
3415
3446
    ofpbuf_put(packet, pin->packet, pin->packet_len);
3416
3447
 
3417
 
    npi = ofpbuf_l3(packet);
 
3448
    npi = packet->msg;
3418
3449
    npi->buffer_id = htonl(pin->buffer_id);
3419
3450
    npi->total_len = htons(pin->total_len);
3420
3451
    npi->reason = pin->reason;
3435
3466
                              htonl(0), pin->packet_len);
3436
3467
    opi = ofpbuf_put_zeros(packet, sizeof *opi);
3437
3468
    opi->buffer_id = htonl(pin->buffer_id);
3438
 
    opi->in_port = ofputil_port_to_ofp11(pin->fmd.in_port);
 
3469
    opi->in_port = ofputil_port_to_ofp11(pin->flow_metadata.flow.in_port.ofp_port);
3439
3470
    opi->in_phy_port = opi->in_port;
3440
3471
    opi->total_len = htons(pin->total_len);
3441
3472
    opi->reason = pin->reason;
3451
3482
                               enum ofputil_protocol protocol)
3452
3483
{
3453
3484
    struct ofp13_packet_in *opi;
3454
 
    struct match match;
3455
3485
    enum ofpraw packet_in_raw;
3456
3486
    enum ofp_version packet_in_version;
3457
3487
    size_t packet_in_size;
3463
3493
        packet_in_size = sizeof (struct ofp12_packet_in);
3464
3494
    } else {
3465
3495
        packet_in_raw = OFPRAW_OFPT13_PACKET_IN;
3466
 
        packet_in_version = OFP13_VERSION;
 
3496
        packet_in_version = ofputil_protocol_to_ofp_version(protocol);
3467
3497
        packet_in_size = sizeof (struct ofp13_packet_in);
3468
3498
    }
3469
3499
 
3470
 
    ofputil_packet_in_to_match(pin, &match);
3471
 
 
3472
3500
    /* The final argument is just an estimate of the space required. */
3473
3501
    packet = ofpraw_alloc_xid(packet_in_raw, packet_in_version,
3474
 
                              htonl(0), (sizeof(struct flow_metadata) * 2
3475
 
                                         + 2 + pin->packet_len));
 
3502
                              htonl(0), NXM_TYPICAL_LEN + 2 + pin->packet_len);
3476
3503
    ofpbuf_put_zeros(packet, packet_in_size);
3477
 
    oxm_put_match(packet, &match, ofputil_protocol_to_ofp_version(protocol));
 
3504
    oxm_put_match(packet, &pin->flow_metadata,
 
3505
                  ofputil_protocol_to_ofp_version(protocol));
3478
3506
    ofpbuf_put_zeros(packet, 2);
3479
3507
    ofpbuf_put(packet, pin->packet, pin->packet_len);
3480
3508
 
3481
 
    opi = ofpbuf_l3(packet);
 
3509
    opi = packet->msg;
3482
3510
    opi->pi.buffer_id = htonl(pin->buffer_id);
3483
3511
    opi->pi.total_len = htons(pin->total_len);
3484
3512
    opi->pi.reason = pin->reason;
3485
3513
    opi->pi.table_id = pin->table_id;
3486
 
    if (protocol == OFPUTIL_P_OF13_OXM) {
 
3514
    if (protocol != OFPUTIL_P_OF12_OXM) {
3487
3515
        opi->cookie = pin->cookie;
3488
3516
    }
3489
3517
 
3542
3570
        return "action";
3543
3571
    case OFPR_INVALID_TTL:
3544
3572
        return "invalid_ttl";
 
3573
    case OFPR_ACTION_SET:
 
3574
        return "action_set";
 
3575
    case OFPR_GROUP:
 
3576
        return "group";
 
3577
    case OFPR_PACKET_OUT:
 
3578
        return "packet_out";
3545
3579
 
3546
3580
    case OFPR_N_REASONS:
3547
3581
    default:
3628
3662
        return OFPERR_OFPBRC_BAD_PORT;
3629
3663
    }
3630
3664
 
3631
 
    po->ofpacts = ofpbuf_data(ofpacts);
3632
 
    po->ofpacts_len = ofpbuf_size(ofpacts);
 
3665
    po->ofpacts = ofpacts->data;
 
3666
    po->ofpacts_len = ofpacts->size;
3633
3667
 
3634
3668
    if (po->buffer_id == UINT32_MAX) {
3635
 
        po->packet = ofpbuf_data(&b);
3636
 
        po->packet_len = ofpbuf_size(&b);
 
3669
        po->packet = b.data;
 
3670
        po->packet_len = b.size;
3637
3671
    } else {
3638
3672
        po->packet = NULL;
3639
3673
        po->packet_len = 0;
3755
3789
parse_ofp14_port_ethernet_property(const struct ofpbuf *payload,
3756
3790
                                   struct ofputil_phy_port *pp)
3757
3791
{
3758
 
    struct ofp14_port_desc_prop_ethernet *eth = ofpbuf_data(payload);
 
3792
    struct ofp14_port_desc_prop_ethernet *eth = payload->data;
3759
3793
 
3760
 
    if (ofpbuf_size(payload) != sizeof *eth) {
 
3794
    if (payload->size != sizeof *eth) {
3761
3795
        return OFPERR_OFPBPC_BAD_LEN;
3762
3796
    }
3763
3797
 
3786
3820
    }
3787
3821
 
3788
3822
    len = ntohs(op->length);
3789
 
    if (len < sizeof *op || len - sizeof *op > ofpbuf_size(msg)) {
 
3823
    if (len < sizeof *op || len - sizeof *op > msg->size) {
3790
3824
        return OFPERR_OFPBRC_BAD_LEN;
3791
3825
    }
3792
3826
    len -= sizeof *op;
3802
3836
    pp->config = ntohl(op->config) & OFPPC11_ALL;
3803
3837
    pp->state = ntohl(op->state) & OFPPS11_ALL;
3804
3838
 
3805
 
    while (ofpbuf_size(&properties) > 0) {
 
3839
    while (properties.size > 0) {
3806
3840
        struct ofpbuf payload;
3807
3841
        enum ofperr error;
3808
3842
        uint16_t type;
3984
4018
 
3985
4019
void
3986
4020
ofputil_append_port_desc_stats_reply(const struct ofputil_phy_port *pp,
3987
 
                                     struct list *replies)
 
4021
                                     struct ovs_list *replies)
3988
4022
{
3989
4023
    struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
3990
 
    size_t start_ofs = ofpbuf_size(reply);
 
4024
    size_t start_ofs = reply->size;
3991
4025
 
3992
4026
    ofputil_put_phy_port(ofpmp_version(replies), pp, reply);
3993
4027
    ofpmp_postappend(replies, start_ofs);
4004
4038
BUILD_ASSERT_DECL((int) OFPUTIL_C_QUEUE_STATS == OFPC_QUEUE_STATS);
4005
4039
BUILD_ASSERT_DECL((int) OFPUTIL_C_ARP_MATCH_IP == OFPC_ARP_MATCH_IP);
4006
4040
 
4007
 
struct ofputil_action_bit_translation {
4008
 
    enum ofputil_action_bitmap ofputil_bit;
4009
 
    int of_bit;
4010
 
};
4011
 
 
4012
 
static const struct ofputil_action_bit_translation of10_action_bits[] = {
4013
 
    { OFPUTIL_A_OUTPUT,       OFPAT10_OUTPUT },
4014
 
    { OFPUTIL_A_SET_VLAN_VID, OFPAT10_SET_VLAN_VID },
4015
 
    { OFPUTIL_A_SET_VLAN_PCP, OFPAT10_SET_VLAN_PCP },
4016
 
    { OFPUTIL_A_STRIP_VLAN,   OFPAT10_STRIP_VLAN },
4017
 
    { OFPUTIL_A_SET_DL_SRC,   OFPAT10_SET_DL_SRC },
4018
 
    { OFPUTIL_A_SET_DL_DST,   OFPAT10_SET_DL_DST },
4019
 
    { OFPUTIL_A_SET_NW_SRC,   OFPAT10_SET_NW_SRC },
4020
 
    { OFPUTIL_A_SET_NW_DST,   OFPAT10_SET_NW_DST },
4021
 
    { OFPUTIL_A_SET_NW_TOS,   OFPAT10_SET_NW_TOS },
4022
 
    { OFPUTIL_A_SET_TP_SRC,   OFPAT10_SET_TP_SRC },
4023
 
    { OFPUTIL_A_SET_TP_DST,   OFPAT10_SET_TP_DST },
4024
 
    { OFPUTIL_A_ENQUEUE,      OFPAT10_ENQUEUE },
4025
 
    { 0, 0 },
4026
 
};
4027
 
 
4028
 
static enum ofputil_action_bitmap
4029
 
decode_action_bits(ovs_be32 of_actions,
4030
 
                   const struct ofputil_action_bit_translation *x)
4031
 
{
4032
 
    enum ofputil_action_bitmap ofputil_actions;
4033
 
 
4034
 
    ofputil_actions = 0;
4035
 
    for (; x->ofputil_bit; x++) {
4036
 
        if (of_actions & htonl(1u << x->of_bit)) {
4037
 
            ofputil_actions |= x->ofputil_bit;
4038
 
        }
4039
 
    }
4040
 
    return ofputil_actions;
4041
 
}
4042
 
 
4043
4041
static uint32_t
4044
4042
ofputil_capabilities_mask(enum ofp_version ofp_version)
4045
4043
{
4046
 
    /* Handle capabilities whose bit is unique for all Open Flow versions */
 
4044
    /* Handle capabilities whose bit is unique for all OpenFlow versions */
4047
4045
    switch (ofp_version) {
4048
4046
    case OFP10_VERSION:
4049
4047
    case OFP11_VERSION:
4088
4086
        if (osf->capabilities & htonl(OFPC10_STP)) {
4089
4087
            features->capabilities |= OFPUTIL_C_STP;
4090
4088
        }
4091
 
        features->actions = decode_action_bits(osf->actions, of10_action_bits);
 
4089
        features->ofpacts = ofpact_bitmap_from_openflow(osf->actions,
 
4090
                                                        OFP10_VERSION);
4092
4091
    } else if (raw == OFPRAW_OFPT11_FEATURES_REPLY
4093
4092
               || raw == OFPRAW_OFPT13_FEATURES_REPLY) {
4094
4093
        if (osf->capabilities & htonl(OFPC11_GROUP_STATS)) {
4095
4094
            features->capabilities |= OFPUTIL_C_GROUP_STATS;
4096
4095
        }
4097
 
        features->actions = 0;
 
4096
        features->ofpacts = 0;
4098
4097
        if (raw == OFPRAW_OFPT13_FEATURES_REPLY) {
4099
4098
            features->auxiliary_id = osf->auxiliary_id;
4100
4099
        }
4120
4119
bool
4121
4120
ofputil_switch_features_has_ports(struct ofpbuf *b)
4122
4121
{
4123
 
    struct ofp_header *oh = ofpbuf_data(b);
 
4122
    struct ofp_header *oh = b->data;
4124
4123
    size_t phy_port_size;
4125
4124
 
4126
4125
    if (oh->version >= OFP13_VERSION) {
4140
4139
    /* The feature reply has no room for more ports.  Probably the list is
4141
4140
     * truncated.  Drop the ports and tell the caller to retrieve them with
4142
4141
     * OFPST_PORT_DESC. */
4143
 
    ofpbuf_set_size(b, sizeof *oh + sizeof(struct ofp_switch_features));
 
4142
    b->size = sizeof *oh + sizeof(struct ofp_switch_features);
4144
4143
    ofpmsg_update_length(b);
4145
4144
    return false;
4146
4145
}
4147
4146
 
4148
 
static ovs_be32
4149
 
encode_action_bits(enum ofputil_action_bitmap ofputil_actions,
4150
 
                   const struct ofputil_action_bit_translation *x)
4151
 
{
4152
 
    uint32_t of_actions;
4153
 
 
4154
 
    of_actions = 0;
4155
 
    for (; x->ofputil_bit; x++) {
4156
 
        if (ofputil_actions & x->ofputil_bit) {
4157
 
            of_actions |= 1 << x->of_bit;
4158
 
        }
4159
 
    }
4160
 
    return htonl(of_actions);
4161
 
}
4162
 
 
4163
4147
/* Returns a buffer owned by the caller that encodes 'features' in the format
4164
4148
 * required by 'protocol' with the given 'xid'.  The caller should append port
4165
4149
 * information to the buffer with subsequent calls to
4204
4188
        if (features->capabilities & OFPUTIL_C_STP) {
4205
4189
            osf->capabilities |= htonl(OFPC10_STP);
4206
4190
        }
4207
 
        osf->actions = encode_action_bits(features->actions, of10_action_bits);
 
4191
        osf->actions = ofpact_bitmap_to_openflow(features->ofpacts,
 
4192
                                                 OFP10_VERSION);
4208
4193
        break;
4209
4194
    case OFP13_VERSION:
4210
4195
    case OFP14_VERSION:
4231
4216
ofputil_put_switch_features_port(const struct ofputil_phy_port *pp,
4232
4217
                                 struct ofpbuf *b)
4233
4218
{
4234
 
    const struct ofp_header *oh = ofpbuf_data(b);
 
4219
    const struct ofp_header *oh = b->data;
4235
4220
 
4236
4221
    if (oh->version < OFP13_VERSION) {
4237
4222
        /* Try adding a port description to the message, but drop it again if
4238
4223
         * the buffer overflows.  (This possibility for overflow is why
4239
4224
         * OpenFlow 1.3+ moved port descriptions into a multipart message.)  */
4240
 
        size_t start_ofs = ofpbuf_size(b);
 
4225
        size_t start_ofs = b->size;
4241
4226
        ofputil_put_phy_port(oh->version, pp, b);
4242
 
        if (ofpbuf_size(b) > UINT16_MAX) {
4243
 
            ofpbuf_set_size(b, start_ofs);
 
4227
        if (b->size > UINT16_MAX) {
 
4228
            b->size = start_ofs;
4244
4229
        }
4245
4230
    }
4246
4231
}
4320
4305
parse_port_mod_ethernet_property(struct ofpbuf *property,
4321
4306
                                 struct ofputil_port_mod *pm)
4322
4307
{
4323
 
    struct ofp14_port_mod_prop_ethernet *eth = ofpbuf_data(property);
 
4308
    struct ofp14_port_mod_prop_ethernet *eth = property->data;
4324
4309
 
4325
 
    if (ofpbuf_size(property) != sizeof *eth) {
 
4310
    if (property->size != sizeof *eth) {
4326
4311
        return OFPERR_OFPBRC_BAD_LEN;
4327
4312
    }
4328
4313
 
4343
4328
    raw = ofpraw_pull_assert(&b);
4344
4329
 
4345
4330
    if (raw == OFPRAW_OFPT10_PORT_MOD) {
4346
 
        const struct ofp10_port_mod *opm = ofpbuf_data(&b);
 
4331
        const struct ofp10_port_mod *opm = b.data;
4347
4332
 
4348
4333
        pm->port_no = u16_to_ofp(ntohs(opm->port_no));
4349
4334
        memcpy(pm->hw_addr, opm->hw_addr, ETH_ADDR_LEN);
4351
4336
        pm->mask = ntohl(opm->mask) & OFPPC10_ALL;
4352
4337
        pm->advertise = netdev_port_features_from_ofp10(opm->advertise);
4353
4338
    } else if (raw == OFPRAW_OFPT11_PORT_MOD) {
4354
 
        const struct ofp11_port_mod *opm = ofpbuf_data(&b);
 
4339
        const struct ofp11_port_mod *opm = b.data;
4355
4340
        enum ofperr error;
4356
4341
 
4357
4342
        error = ofputil_port_from_ofp11(opm->port_no, &pm->port_no);
4378
4363
        pm->config = ntohl(opm->config) & OFPPC11_ALL;
4379
4364
        pm->mask = ntohl(opm->mask) & OFPPC11_ALL;
4380
4365
 
4381
 
        while (ofpbuf_size(&b) > 0) {
 
4366
        while (b.size > 0) {
4382
4367
            struct ofpbuf property;
4383
4368
            enum ofperr error;
4384
4369
            uint16_t type;
4481
4466
 
4482
4467
    return b;
4483
4468
}
 
4469
 
 
4470
/* Table features. */
4484
4471
 
4485
4472
static enum ofperr
4486
4473
pull_table_feature_property(struct ofpbuf *msg, struct ofpbuf *payload,
4487
 
                        uint16_t *typep)
 
4474
                            uint16_t *typep)
4488
4475
{
4489
4476
    enum ofperr error;
4490
4477
 
4496
4483
}
4497
4484
 
4498
4485
static enum ofperr
4499
 
parse_table_ids(struct ofpbuf *payload, uint32_t *ids)
 
4486
parse_action_bitmap(struct ofpbuf *payload, enum ofp_version ofp_version,
 
4487
                    uint64_t *ofpacts)
4500
4488
{
4501
 
    uint16_t type;
4502
 
 
4503
 
    *ids = 0;
4504
 
    while (ofpbuf_size(payload) > 0) {
4505
 
        enum ofperr error = pull_table_feature_property(payload, NULL, &type);
 
4489
    uint32_t types = 0;
 
4490
 
 
4491
    while (payload->size > 0) {
 
4492
        uint16_t type;
 
4493
        enum ofperr error;
 
4494
 
 
4495
        error = ofputil_pull_property__(payload, NULL, 1, &type);
4506
4496
        if (error) {
4507
4497
            return error;
4508
4498
        }
4509
 
        if (type < CHAR_BIT * sizeof *ids) {
4510
 
            *ids |= 1u << type;
 
4499
        if (type < CHAR_BIT * sizeof types) {
 
4500
            types |= 1u << type;
4511
4501
        }
4512
4502
    }
 
4503
 
 
4504
    *ofpacts = ofpact_bitmap_from_openflow(htonl(types), ofp_version);
4513
4505
    return 0;
4514
4506
}
4515
4507
 
4517
4509
parse_instruction_ids(struct ofpbuf *payload, bool loose, uint32_t *insts)
4518
4510
{
4519
4511
    *insts = 0;
4520
 
    while (ofpbuf_size(payload) > 0) {
 
4512
    while (payload->size > 0) {
4521
4513
        enum ovs_instruction_type inst;
4522
4514
        enum ofperr error;
4523
4515
        uint16_t ofpit;
4524
4516
 
4525
 
        error = pull_table_feature_property(payload, NULL, &ofpit);
 
4517
        /* OF1.3 and OF1.4 aren't clear about padding in the instruction IDs.
 
4518
         * It seems clear that they aren't padded to 8 bytes, though, because
 
4519
         * both standards say that "non-experimenter instructions are 4 bytes"
 
4520
         * and do not mention any padding before the first instruction ID.
 
4521
         * (There wouldn't be any point in padding to 8 bytes if the IDs were
 
4522
         * aligned on an odd 4-byte boundary.)
 
4523
         *
 
4524
         * Anyway, we just assume they're all glommed together on byte
 
4525
         * boundaries. */
 
4526
        error = ofputil_pull_property__(payload, NULL, 1, &ofpit);
4526
4527
        if (error) {
4527
4528
            return error;
4528
4529
        }
4544
4545
    size_t i;
4545
4546
 
4546
4547
    memset(next_tables, 0, bitmap_n_bytes(255));
4547
 
    for (i = 0; i < ofpbuf_size(payload); i++) {
4548
 
        uint8_t id = ((const uint8_t *) ofpbuf_data(payload))[i];
 
4548
    for (i = 0; i < payload->size; i++) {
 
4549
        uint8_t id = ((const uint8_t *) payload->data)[i];
4549
4550
        if (id >= 255) {
4550
4551
            return OFPERR_OFPBPC_BAD_VALUE;
4551
4552
        }
4555
4556
}
4556
4557
 
4557
4558
static enum ofperr
4558
 
parse_oxm(struct ofpbuf *b, bool loose,
4559
 
          const struct mf_field **fieldp, bool *hasmask)
4560
 
{
4561
 
    ovs_be32 *oxmp;
4562
 
    uint32_t oxm;
4563
 
 
4564
 
    oxmp = ofpbuf_try_pull(b, sizeof *oxmp);
4565
 
    if (!oxmp) {
4566
 
        return OFPERR_OFPBPC_BAD_LEN;
4567
 
    }
4568
 
    oxm = ntohl(*oxmp);
4569
 
 
4570
 
    /* Determine '*hasmask'.  If 'oxm' is masked, convert it to the equivalent
4571
 
     * unmasked version, because the table of OXM fields we support only has
4572
 
     * masked versions of fields that we support with masks, but we should be
4573
 
     * able to parse the masked versions of those here. */
4574
 
    *hasmask = NXM_HASMASK(oxm);
4575
 
    if (*hasmask) {
4576
 
        if (NXM_LENGTH(oxm) & 1) {
4577
 
            return OFPERR_OFPBPC_BAD_VALUE;
4578
 
        }
4579
 
        oxm = NXM_HEADER(NXM_VENDOR(oxm), NXM_FIELD(oxm), NXM_LENGTH(oxm) / 2);
4580
 
    }
4581
 
 
4582
 
    *fieldp = mf_from_nxm_header(oxm);
4583
 
    if (!*fieldp) {
4584
 
        log_property(loose, "unknown OXM field %#"PRIx32, ntohl(*oxmp));
4585
 
    }
4586
 
    return *fieldp ? 0 : OFPERR_OFPBMC_BAD_FIELD;
4587
 
}
4588
 
 
4589
 
static enum ofperr
4590
4559
parse_oxms(struct ofpbuf *payload, bool loose,
4591
 
           uint64_t *exactp, uint64_t *maskedp)
 
4560
           struct mf_bitmap *exactp, struct mf_bitmap *maskedp)
4592
4561
{
4593
 
    uint64_t exact, masked;
 
4562
    struct mf_bitmap exact = MF_BITMAP_INITIALIZER;
 
4563
    struct mf_bitmap masked = MF_BITMAP_INITIALIZER;
4594
4564
 
4595
 
    exact = masked = 0;
4596
 
    while (ofpbuf_size(payload) > 0) {
 
4565
    while (payload->size > 0) {
4597
4566
        const struct mf_field *field;
4598
4567
        enum ofperr error;
4599
4568
        bool hasmask;
4600
4569
 
4601
 
        error = parse_oxm(payload, loose, &field, &hasmask);
 
4570
        error = nx_pull_header(payload, &field, &hasmask);
4602
4571
        if (!error) {
4603
 
            if (hasmask) {
4604
 
                masked |= UINT64_C(1) << field->id;
4605
 
            } else {
4606
 
                exact |= UINT64_C(1) << field->id;
4607
 
            }
 
4572
            bitmap_set1(hasmask ? masked.bm : exact.bm, field->id);
4608
4573
        } else if (error != OFPERR_OFPBMC_BAD_FIELD || !loose) {
4609
4574
            return error;
4610
4575
        }
4611
4576
    }
4612
4577
    if (exactp) {
4613
4578
        *exactp = exact;
4614
 
    } else if (exact) {
 
4579
    } else if (!bitmap_is_all_zeros(exact.bm, MFF_N_IDS)) {
4615
4580
        return OFPERR_OFPBMC_BAD_MASK;
4616
4581
    }
4617
4582
    if (maskedp) {
4618
4583
        *maskedp = masked;
4619
 
    } else if (masked) {
 
4584
    } else if (!bitmap_is_all_zeros(masked.bm, MFF_N_IDS)) {
4620
4585
        return OFPERR_OFPBMC_BAD_MASK;
4621
4586
    }
4622
4587
    return 0;
4642
4607
ofputil_decode_table_features(struct ofpbuf *msg,
4643
4608
                              struct ofputil_table_features *tf, bool loose)
4644
4609
{
 
4610
    const struct ofp_header *oh;
4645
4611
    struct ofp13_table_features *otf;
 
4612
    struct ofpbuf properties;
4646
4613
    unsigned int len;
4647
4614
 
4648
 
    if (!msg->frame) {
 
4615
    memset(tf, 0, sizeof *tf);
 
4616
 
 
4617
    if (!msg->header) {
4649
4618
        ofpraw_pull_assert(msg);
4650
4619
    }
 
4620
    oh = msg->header;
4651
4621
 
4652
 
    if (!ofpbuf_size(msg)) {
 
4622
    if (!msg->size) {
4653
4623
        return EOF;
4654
4624
    }
4655
4625
 
4656
 
    if (ofpbuf_size(msg) < sizeof *otf) {
 
4626
    if (msg->size < sizeof *otf) {
4657
4627
        return OFPERR_OFPBPC_BAD_LEN;
4658
4628
    }
4659
4629
 
4660
 
    otf = ofpbuf_data(msg);
 
4630
    otf = msg->data;
4661
4631
    len = ntohs(otf->length);
4662
 
    if (len < sizeof *otf || len % 8 || len > ofpbuf_size(msg)) {
 
4632
    if (len < sizeof *otf || len % 8 || len > msg->size) {
4663
4633
        return OFPERR_OFPBPC_BAD_LEN;
4664
4634
    }
4665
 
    ofpbuf_pull(msg, sizeof *otf);
 
4635
    ofpbuf_use_const(&properties, ofpbuf_pull(msg, len), len);
 
4636
    ofpbuf_pull(&properties, sizeof *otf);
4666
4637
 
4667
4638
    tf->table_id = otf->table_id;
4668
4639
    if (tf->table_id == OFPTT_ALL) {
4672
4643
    ovs_strlcpy(tf->name, otf->name, OFP_MAX_TABLE_NAME_LEN);
4673
4644
    tf->metadata_match = otf->metadata_match;
4674
4645
    tf->metadata_write = otf->metadata_write;
4675
 
    tf->config = ntohl(otf->config);
 
4646
    tf->miss_config = ofputil_table_miss_from_config(otf->config, oh->version);
4676
4647
    tf->max_entries = ntohl(otf->max_entries);
4677
4648
 
4678
 
    while (ofpbuf_size(msg) > 0) {
 
4649
    while (properties.size > 0) {
4679
4650
        struct ofpbuf payload;
4680
4651
        enum ofperr error;
4681
4652
        uint16_t type;
4682
4653
 
4683
 
        error = pull_table_feature_property(msg, &payload, &type);
 
4654
        error = pull_table_feature_property(&properties, &payload, &type);
4684
4655
        if (error) {
4685
4656
            return error;
4686
4657
        }
4704
4675
            break;
4705
4676
 
4706
4677
        case OFPTFPT13_WRITE_ACTIONS:
4707
 
            error = parse_table_ids(&payload, &tf->nonmiss.write.actions);
 
4678
            error = parse_action_bitmap(&payload, oh->version,
 
4679
                                        &tf->nonmiss.write.ofpacts);
4708
4680
            break;
4709
4681
        case OFPTFPT13_WRITE_ACTIONS_MISS:
4710
 
            error = parse_table_ids(&payload, &tf->miss.write.actions);
 
4682
            error = parse_action_bitmap(&payload, oh->version,
 
4683
                                        &tf->miss.write.ofpacts);
4711
4684
            break;
4712
4685
 
4713
4686
        case OFPTFPT13_APPLY_ACTIONS:
4714
 
            error = parse_table_ids(&payload, &tf->nonmiss.apply.actions);
 
4687
            error = parse_action_bitmap(&payload, oh->version,
 
4688
                                        &tf->nonmiss.apply.ofpacts);
4715
4689
            break;
4716
4690
        case OFPTFPT13_APPLY_ACTIONS_MISS:
4717
 
            error = parse_table_ids(&payload, &tf->miss.apply.actions);
 
4691
            error = parse_action_bitmap(&payload, oh->version,
 
4692
                                        &tf->miss.apply.ofpacts);
4718
4693
            break;
4719
4694
 
4720
4695
        case OFPTFPT13_MATCH:
4756
4731
 
4757
4732
    /* Fix inconsistencies:
4758
4733
     *
4759
 
     *     - Turn off 'mask' and 'wildcard' bits that are not in 'match',
4760
 
     *       because a field must be matchable to be masked or wildcarded.
 
4734
     *     - Turn on 'match' bits that are set in 'mask', because maskable
 
4735
     *       fields are matchable.
4761
4736
     *
4762
4737
     *     - Turn on 'wildcard' bits that are set in 'mask', because a field
4763
 
     *       that is arbitrarily maskable can be wildcarded entirely. */
4764
 
    tf->mask &= tf->match;
4765
 
    tf->wildcard &= tf->match;
4766
 
 
4767
 
    tf->wildcard |= tf->mask;
 
4738
     *       that is arbitrarily maskable can be wildcarded entirely.
 
4739
     *
 
4740
     *     - Turn off 'wildcard' bits that are not in 'match', because a field
 
4741
     *       must be matchable for it to be meaningfully wildcarded. */
 
4742
    bitmap_or(tf->match.bm, tf->mask.bm, MFF_N_IDS);
 
4743
    bitmap_or(tf->wildcard.bm, tf->mask.bm, MFF_N_IDS);
 
4744
    bitmap_and(tf->wildcard.bm, tf->match.bm, MFF_N_IDS);
4768
4745
 
4769
4746
    return 0;
4770
4747
}
4795
4772
    return request;
4796
4773
}
4797
4774
 
 
4775
static void
 
4776
put_fields_property(struct ofpbuf *reply,
 
4777
                    const struct mf_bitmap *fields,
 
4778
                    const struct mf_bitmap *masks,
 
4779
                    enum ofp13_table_feature_prop_type property,
 
4780
                    enum ofp_version version)
 
4781
{
 
4782
    size_t start_ofs;
 
4783
    int field;
 
4784
 
 
4785
    start_ofs = start_property(reply, property);
 
4786
    BITMAP_FOR_EACH_1 (field, MFF_N_IDS, fields->bm) {
 
4787
        nx_put_header(reply, field, version,
 
4788
                      masks && bitmap_is_set(masks->bm, field));
 
4789
    }
 
4790
    end_property(reply, start_ofs);
 
4791
}
 
4792
 
 
4793
static void
 
4794
put_table_action_features(struct ofpbuf *reply,
 
4795
                          const struct ofputil_table_action_features *taf,
 
4796
                          enum ofp13_table_feature_prop_type actions_type,
 
4797
                          enum ofp13_table_feature_prop_type set_fields_type,
 
4798
                          int miss_offset, enum ofp_version version)
 
4799
{
 
4800
    size_t start_ofs;
 
4801
 
 
4802
    start_ofs = start_property(reply, actions_type + miss_offset);
 
4803
    put_bitmap_properties(reply,
 
4804
                          ntohl(ofpact_bitmap_to_openflow(taf->ofpacts,
 
4805
                                                          version)));
 
4806
    end_property(reply, start_ofs);
 
4807
 
 
4808
    put_fields_property(reply, &taf->set_fields, NULL,
 
4809
                        set_fields_type + miss_offset, version);
 
4810
}
 
4811
 
 
4812
static void
 
4813
put_table_instruction_features(
 
4814
    struct ofpbuf *reply, const struct ofputil_table_instruction_features *tif,
 
4815
    int miss_offset, enum ofp_version version)
 
4816
{
 
4817
    size_t start_ofs;
 
4818
    uint8_t table_id;
 
4819
 
 
4820
    start_ofs = start_property(reply, OFPTFPT13_INSTRUCTIONS + miss_offset);
 
4821
    put_bitmap_properties(reply,
 
4822
                          ntohl(ovsinst_bitmap_to_openflow(tif->instructions,
 
4823
                                                           version)));
 
4824
    end_property(reply, start_ofs);
 
4825
 
 
4826
    start_ofs = start_property(reply, OFPTFPT13_NEXT_TABLES + miss_offset);
 
4827
    BITMAP_FOR_EACH_1 (table_id, 255, tif->next) {
 
4828
        ofpbuf_put(reply, &table_id, 1);
 
4829
    }
 
4830
    end_property(reply, start_ofs);
 
4831
 
 
4832
    put_table_action_features(reply, &tif->write,
 
4833
                              OFPTFPT13_WRITE_ACTIONS,
 
4834
                              OFPTFPT13_WRITE_SETFIELD, miss_offset, version);
 
4835
    put_table_action_features(reply, &tif->apply,
 
4836
                              OFPTFPT13_APPLY_ACTIONS,
 
4837
                              OFPTFPT13_APPLY_SETFIELD, miss_offset, version);
 
4838
}
 
4839
 
 
4840
void
 
4841
ofputil_append_table_features_reply(const struct ofputil_table_features *tf,
 
4842
                                    struct ovs_list *replies)
 
4843
{
 
4844
    struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
 
4845
    enum ofp_version version = ofpmp_version(replies);
 
4846
    size_t start_ofs = reply->size;
 
4847
    struct ofp13_table_features *otf;
 
4848
 
 
4849
    otf = ofpbuf_put_zeros(reply, sizeof *otf);
 
4850
    otf->table_id = tf->table_id;
 
4851
    ovs_strlcpy(otf->name, tf->name, sizeof otf->name);
 
4852
    otf->metadata_match = tf->metadata_match;
 
4853
    otf->metadata_write = tf->metadata_write;
 
4854
    otf->config = ofputil_table_miss_to_config(tf->miss_config, version);
 
4855
    otf->max_entries = htonl(tf->max_entries);
 
4856
 
 
4857
    put_table_instruction_features(reply, &tf->nonmiss, 0, version);
 
4858
    put_table_instruction_features(reply, &tf->miss, 1, version);
 
4859
 
 
4860
    put_fields_property(reply, &tf->match, &tf->mask,
 
4861
                        OFPTFPT13_MATCH, version);
 
4862
    put_fields_property(reply, &tf->wildcard, NULL,
 
4863
                        OFPTFPT13_WILDCARDS, version);
 
4864
 
 
4865
    otf = ofpbuf_at_assert(reply, start_ofs, sizeof *otf);
 
4866
    otf->length = htons(reply->size - start_ofs);
 
4867
    ofpmp_postappend(replies, start_ofs);
 
4868
}
 
4869
 
4798
4870
/* ofputil_table_mod */
4799
4871
 
 
4872
/* Given 'config', taken from an OpenFlow 'version' message that specifies
 
4873
 * table configuration (a table mod, table stats, or table features message),
 
4874
 * returns the table miss configuration that it specifies.  */
 
4875
static enum ofputil_table_miss
 
4876
ofputil_table_miss_from_config(ovs_be32 config_, enum ofp_version version)
 
4877
{
 
4878
    uint32_t config = ntohl(config_);
 
4879
 
 
4880
    if (version < OFP13_VERSION) {
 
4881
        switch (config & OFPTC11_TABLE_MISS_MASK) {
 
4882
        case OFPTC11_TABLE_MISS_CONTROLLER:
 
4883
            return OFPUTIL_TABLE_MISS_CONTROLLER;
 
4884
 
 
4885
        case OFPTC11_TABLE_MISS_CONTINUE:
 
4886
            return OFPUTIL_TABLE_MISS_CONTINUE;
 
4887
 
 
4888
        case OFPTC11_TABLE_MISS_DROP:
 
4889
            return OFPUTIL_TABLE_MISS_DROP;
 
4890
 
 
4891
        default:
 
4892
            VLOG_WARN_RL(&bad_ofmsg_rl, "bad table miss config %d", config);
 
4893
            return OFPUTIL_TABLE_MISS_CONTROLLER;
 
4894
        }
 
4895
    } else {
 
4896
        return OFPUTIL_TABLE_MISS_DEFAULT;
 
4897
    }
 
4898
}
 
4899
 
 
4900
/* Given a table miss configuration, returns the corresponding OpenFlow table
 
4901
 * configuration for use in an OpenFlow message of the given 'version'. */
 
4902
ovs_be32
 
4903
ofputil_table_miss_to_config(enum ofputil_table_miss miss,
 
4904
                             enum ofp_version version)
 
4905
{
 
4906
    if (version < OFP13_VERSION) {
 
4907
        switch (miss) {
 
4908
        case OFPUTIL_TABLE_MISS_CONTROLLER:
 
4909
        case OFPUTIL_TABLE_MISS_DEFAULT:
 
4910
            return htonl(OFPTC11_TABLE_MISS_CONTROLLER);
 
4911
 
 
4912
        case OFPUTIL_TABLE_MISS_CONTINUE:
 
4913
            return htonl(OFPTC11_TABLE_MISS_CONTINUE);
 
4914
 
 
4915
        case OFPUTIL_TABLE_MISS_DROP:
 
4916
            return htonl(OFPTC11_TABLE_MISS_DROP);
 
4917
 
 
4918
        default:
 
4919
            OVS_NOT_REACHED();
 
4920
        }
 
4921
    } else {
 
4922
        return htonl(0);
 
4923
    }
 
4924
}
 
4925
 
4800
4926
/* Decodes the OpenFlow "table mod" message in '*oh' into an abstract form in
4801
4927
 * '*pm'.  Returns 0 if successful, otherwise an OFPERR_* value. */
4802
4928
enum ofperr
4810
4936
    raw = ofpraw_pull_assert(&b);
4811
4937
 
4812
4938
    if (raw == OFPRAW_OFPT11_TABLE_MOD) {
4813
 
        const struct ofp11_table_mod *otm = ofpbuf_data(&b);
 
4939
        const struct ofp11_table_mod *otm = b.data;
4814
4940
 
4815
4941
        pm->table_id = otm->table_id;
4816
 
        pm->config = ntohl(otm->config);
 
4942
        pm->miss_config = ofputil_table_miss_from_config(otm->config,
 
4943
                                                         oh->version);
4817
4944
    } else if (raw == OFPRAW_OFPT14_TABLE_MOD) {
4818
4945
        const struct ofp14_table_mod *otm = ofpbuf_pull(&b, sizeof *otm);
4819
4946
 
4820
4947
        pm->table_id = otm->table_id;
4821
 
        pm->config = ntohl(otm->config);
 
4948
        pm->miss_config = ofputil_table_miss_from_config(otm->config,
 
4949
                                                         oh->version);
4822
4950
        /* We do not understand any properties yet, so we do not bother
4823
4951
         * parsing them. */
4824
4952
    } else {
4852
4980
        b = ofpraw_alloc(OFPRAW_OFPT11_TABLE_MOD, ofp_version, 0);
4853
4981
        otm = ofpbuf_put_zeros(b, sizeof *otm);
4854
4982
        otm->table_id = pm->table_id;
4855
 
        otm->config = htonl(pm->config);
 
4983
        otm->config = ofputil_table_miss_to_config(pm->miss_config,
 
4984
                                                   ofp_version);
4856
4985
        break;
4857
4986
    }
4858
4987
    case OFP14_VERSION:
4862
4991
        b = ofpraw_alloc(OFPRAW_OFPT14_TABLE_MOD, ofp_version, 0);
4863
4992
        otm = ofpbuf_put_zeros(b, sizeof *otm);
4864
4993
        otm->table_id = pm->table_id;
4865
 
        otm->config = htonl(pm->config);
 
4994
        otm->config = ofputil_table_miss_to_config(pm->miss_config,
 
4995
                                                   ofp_version);
4866
4996
        break;
4867
4997
    }
4868
4998
    default:
4889
5019
 
4890
5020
    if (raw == OFPRAW_OFPT12_ROLE_REQUEST ||
4891
5021
        raw == OFPRAW_OFPT12_ROLE_REPLY) {
4892
 
        const struct ofp12_role_request *orr = ofpbuf_l3(&b);
 
5022
        const struct ofp12_role_request *orr = b.msg;
4893
5023
 
4894
5024
        if (orr->role != htonl(OFPCR12_ROLE_NOCHANGE) &&
4895
5025
            orr->role != htonl(OFPCR12_ROLE_EQUAL) &&
4910
5040
        }
4911
5041
    } else if (raw == OFPRAW_NXT_ROLE_REQUEST ||
4912
5042
               raw == OFPRAW_NXT_ROLE_REPLY) {
4913
 
        const struct nx_role_request *nrr = ofpbuf_l3(&b);
 
5043
        const struct nx_role_request *nrr = b.msg;
4914
5044
 
4915
5045
        BUILD_ASSERT(NX_ROLE_OTHER + 1 == OFPCR12_ROLE_EQUAL);
4916
5046
        BUILD_ASSERT(NX_ROLE_MASTER + 1 == OFPCR12_ROLE_MASTER);
5008
5138
    raw = ofpraw_pull_assert(&b);
5009
5139
    ovs_assert(raw == OFPRAW_OFPT14_ROLE_STATUS);
5010
5140
 
5011
 
    r = ofpbuf_l3(&b);
 
5141
    r = b.msg;
5012
5142
    if (r->role != htonl(OFPCR12_ROLE_NOCHANGE) &&
5013
5143
        r->role != htonl(OFPCR12_ROLE_EQUAL) &&
5014
5144
        r->role != htonl(OFPCR12_ROLE_MASTER) &&
5025
5155
 
5026
5156
/* Table stats. */
5027
5157
 
 
5158
/* OpenFlow 1.0 and 1.1 don't distinguish between a field that cannot be
 
5159
 * matched and a field that must be wildcarded.  This function returns a bitmap
 
5160
 * that contains both kinds of fields. */
 
5161
static struct mf_bitmap
 
5162
wild_or_nonmatchable_fields(const struct ofputil_table_features *features)
 
5163
{
 
5164
    struct mf_bitmap wc = features->match;
 
5165
    bitmap_not(wc.bm, MFF_N_IDS);
 
5166
    bitmap_or(wc.bm, features->wildcard.bm, MFF_N_IDS);
 
5167
    return wc;
 
5168
}
 
5169
 
 
5170
struct ofp10_wc_map {
 
5171
    enum ofp10_flow_wildcards wc10;
 
5172
    enum mf_field_id mf;
 
5173
};
 
5174
 
 
5175
static const struct ofp10_wc_map ofp10_wc_map[] = {
 
5176
    { OFPFW10_IN_PORT,     MFF_IN_PORT },
 
5177
    { OFPFW10_DL_VLAN,     MFF_VLAN_VID },
 
5178
    { OFPFW10_DL_SRC,      MFF_ETH_SRC },
 
5179
    { OFPFW10_DL_DST,      MFF_ETH_DST},
 
5180
    { OFPFW10_DL_TYPE,     MFF_ETH_TYPE },
 
5181
    { OFPFW10_NW_PROTO,    MFF_IP_PROTO },
 
5182
    { OFPFW10_TP_SRC,      MFF_TCP_SRC },
 
5183
    { OFPFW10_TP_DST,      MFF_TCP_DST },
 
5184
    { OFPFW10_NW_SRC_MASK, MFF_IPV4_SRC },
 
5185
    { OFPFW10_NW_DST_MASK, MFF_IPV4_DST },
 
5186
    { OFPFW10_DL_VLAN_PCP, MFF_VLAN_PCP },
 
5187
    { OFPFW10_NW_TOS,      MFF_IP_DSCP },
 
5188
};
 
5189
 
 
5190
static ovs_be32
 
5191
mf_bitmap_to_of10(const struct mf_bitmap *fields)
 
5192
{
 
5193
    const struct ofp10_wc_map *p;
 
5194
    uint32_t wc10 = 0;
 
5195
 
 
5196
    for (p = ofp10_wc_map; p < &ofp10_wc_map[ARRAY_SIZE(ofp10_wc_map)]; p++) {
 
5197
        if (bitmap_is_set(fields->bm, p->mf)) {
 
5198
            wc10 |= p->wc10;
 
5199
        }
 
5200
    }
 
5201
    return htonl(wc10);
 
5202
}
 
5203
 
 
5204
static struct mf_bitmap
 
5205
mf_bitmap_from_of10(ovs_be32 wc10_)
 
5206
{
 
5207
    struct mf_bitmap fields = MF_BITMAP_INITIALIZER;
 
5208
    const struct ofp10_wc_map *p;
 
5209
    uint32_t wc10 = ntohl(wc10_);
 
5210
 
 
5211
    for (p = ofp10_wc_map; p < &ofp10_wc_map[ARRAY_SIZE(ofp10_wc_map)]; p++) {
 
5212
        if (wc10 & p->wc10) {
 
5213
            bitmap_set1(fields.bm, p->mf);
 
5214
        }
 
5215
    }
 
5216
    return fields;
 
5217
}
 
5218
 
5028
5219
static void
5029
 
ofputil_put_ofp10_table_stats(const struct ofp12_table_stats *in,
 
5220
ofputil_put_ofp10_table_stats(const struct ofputil_table_stats *stats,
 
5221
                              const struct ofputil_table_features *features,
5030
5222
                              struct ofpbuf *buf)
5031
5223
{
5032
 
    struct wc_map {
5033
 
        enum ofp10_flow_wildcards wc10;
5034
 
        enum oxm12_ofb_match_fields mf12;
5035
 
    };
5036
 
 
5037
 
    static const struct wc_map wc_map[] = {
5038
 
        { OFPFW10_IN_PORT,     OFPXMT12_OFB_IN_PORT },
5039
 
        { OFPFW10_DL_VLAN,     OFPXMT12_OFB_VLAN_VID },
5040
 
        { OFPFW10_DL_SRC,      OFPXMT12_OFB_ETH_SRC },
5041
 
        { OFPFW10_DL_DST,      OFPXMT12_OFB_ETH_DST},
5042
 
        { OFPFW10_DL_TYPE,     OFPXMT12_OFB_ETH_TYPE },
5043
 
        { OFPFW10_NW_PROTO,    OFPXMT12_OFB_IP_PROTO },
5044
 
        { OFPFW10_TP_SRC,      OFPXMT12_OFB_TCP_SRC },
5045
 
        { OFPFW10_TP_DST,      OFPXMT12_OFB_TCP_DST },
5046
 
        { OFPFW10_NW_SRC_MASK, OFPXMT12_OFB_IPV4_SRC },
5047
 
        { OFPFW10_NW_DST_MASK, OFPXMT12_OFB_IPV4_DST },
5048
 
        { OFPFW10_DL_VLAN_PCP, OFPXMT12_OFB_VLAN_PCP },
5049
 
        { OFPFW10_NW_TOS,      OFPXMT12_OFB_IP_DSCP },
5050
 
    };
5051
 
 
 
5224
    struct mf_bitmap wc = wild_or_nonmatchable_fields(features);
5052
5225
    struct ofp10_table_stats *out;
5053
 
    const struct wc_map *p;
5054
5226
 
5055
5227
    out = ofpbuf_put_zeros(buf, sizeof *out);
5056
 
    out->table_id = in->table_id;
5057
 
    ovs_strlcpy(out->name, in->name, sizeof out->name);
5058
 
    out->wildcards = 0;
5059
 
    for (p = wc_map; p < &wc_map[ARRAY_SIZE(wc_map)]; p++) {
5060
 
        if (in->wildcards & htonll(1ULL << p->mf12)) {
5061
 
            out->wildcards |= htonl(p->wc10);
5062
 
        }
5063
 
    }
5064
 
    out->max_entries = in->max_entries;
5065
 
    out->active_count = in->active_count;
5066
 
    put_32aligned_be64(&out->lookup_count, in->lookup_count);
5067
 
    put_32aligned_be64(&out->matched_count, in->matched_count);
 
5228
    out->table_id = features->table_id;
 
5229
    ovs_strlcpy(out->name, features->name, sizeof out->name);
 
5230
    out->wildcards = mf_bitmap_to_of10(&wc);
 
5231
    out->max_entries = htonl(features->max_entries);
 
5232
    out->active_count = htonl(stats->active_count);
 
5233
    put_32aligned_be64(&out->lookup_count, htonll(stats->lookup_count));
 
5234
    put_32aligned_be64(&out->matched_count, htonll(stats->matched_count));
5068
5235
}
5069
5236
 
 
5237
struct ofp11_wc_map {
 
5238
    enum ofp11_flow_match_fields wc11;
 
5239
    enum mf_field_id mf;
 
5240
};
 
5241
 
 
5242
static const struct ofp11_wc_map ofp11_wc_map[] = {
 
5243
    { OFPFMF11_IN_PORT,     MFF_IN_PORT },
 
5244
    { OFPFMF11_DL_VLAN,     MFF_VLAN_VID },
 
5245
    { OFPFMF11_DL_VLAN_PCP, MFF_VLAN_PCP },
 
5246
    { OFPFMF11_DL_TYPE,     MFF_ETH_TYPE },
 
5247
    { OFPFMF11_NW_TOS,      MFF_IP_DSCP },
 
5248
    { OFPFMF11_NW_PROTO,    MFF_IP_PROTO },
 
5249
    { OFPFMF11_TP_SRC,      MFF_TCP_SRC },
 
5250
    { OFPFMF11_TP_DST,      MFF_TCP_DST },
 
5251
    { OFPFMF11_MPLS_LABEL,  MFF_MPLS_LABEL },
 
5252
    { OFPFMF11_MPLS_TC,     MFF_MPLS_TC },
 
5253
    /* I don't know what OFPFMF11_TYPE means. */
 
5254
    { OFPFMF11_DL_SRC,      MFF_ETH_SRC },
 
5255
    { OFPFMF11_DL_DST,      MFF_ETH_DST },
 
5256
    { OFPFMF11_NW_SRC,      MFF_IPV4_SRC },
 
5257
    { OFPFMF11_NW_DST,      MFF_IPV4_DST },
 
5258
    { OFPFMF11_METADATA,    MFF_METADATA },
 
5259
};
 
5260
 
5070
5261
static ovs_be32
5071
 
oxm12_to_ofp11_flow_match_fields(ovs_be64 oxm12)
5072
 
{
5073
 
    struct map {
5074
 
        enum ofp11_flow_match_fields fmf11;
5075
 
        enum oxm12_ofb_match_fields mf12;
5076
 
    };
5077
 
 
5078
 
    static const struct map map[] = {
5079
 
        { OFPFMF11_IN_PORT,     OFPXMT12_OFB_IN_PORT },
5080
 
        { OFPFMF11_DL_VLAN,     OFPXMT12_OFB_VLAN_VID },
5081
 
        { OFPFMF11_DL_VLAN_PCP, OFPXMT12_OFB_VLAN_PCP },
5082
 
        { OFPFMF11_DL_TYPE,     OFPXMT12_OFB_ETH_TYPE },
5083
 
        { OFPFMF11_NW_TOS,      OFPXMT12_OFB_IP_DSCP },
5084
 
        { OFPFMF11_NW_PROTO,    OFPXMT12_OFB_IP_PROTO },
5085
 
        { OFPFMF11_TP_SRC,      OFPXMT12_OFB_TCP_SRC },
5086
 
        { OFPFMF11_TP_DST,      OFPXMT12_OFB_TCP_DST },
5087
 
        { OFPFMF11_MPLS_LABEL,  OFPXMT12_OFB_MPLS_LABEL },
5088
 
        { OFPFMF11_MPLS_TC,     OFPXMT12_OFB_MPLS_TC },
5089
 
        /* I don't know what OFPFMF11_TYPE means. */
5090
 
        { OFPFMF11_DL_SRC,      OFPXMT12_OFB_ETH_SRC },
5091
 
        { OFPFMF11_DL_DST,      OFPXMT12_OFB_ETH_DST },
5092
 
        { OFPFMF11_NW_SRC,      OFPXMT12_OFB_IPV4_SRC },
5093
 
        { OFPFMF11_NW_DST,      OFPXMT12_OFB_IPV4_DST },
5094
 
        { OFPFMF11_METADATA,    OFPXMT12_OFB_METADATA },
5095
 
    };
5096
 
 
5097
 
    const struct map *p;
5098
 
    uint32_t fmf11;
5099
 
 
5100
 
    fmf11 = 0;
5101
 
    for (p = map; p < &map[ARRAY_SIZE(map)]; p++) {
5102
 
        if (oxm12 & htonll(1ULL << p->mf12)) {
5103
 
            fmf11 |= p->fmf11;
5104
 
        }
5105
 
    }
5106
 
    return htonl(fmf11);
 
5262
mf_bitmap_to_of11(const struct mf_bitmap *fields)
 
5263
{
 
5264
    const struct ofp11_wc_map *p;
 
5265
    uint32_t wc11 = 0;
 
5266
 
 
5267
    for (p = ofp11_wc_map; p < &ofp11_wc_map[ARRAY_SIZE(ofp11_wc_map)]; p++) {
 
5268
        if (bitmap_is_set(fields->bm, p->mf)) {
 
5269
            wc11 |= p->wc11;
 
5270
        }
 
5271
    }
 
5272
    return htonl(wc11);
 
5273
}
 
5274
 
 
5275
static struct mf_bitmap
 
5276
mf_bitmap_from_of11(ovs_be32 wc11_)
 
5277
{
 
5278
    struct mf_bitmap fields = MF_BITMAP_INITIALIZER;
 
5279
    const struct ofp11_wc_map *p;
 
5280
    uint32_t wc11 = ntohl(wc11_);
 
5281
 
 
5282
    for (p = ofp11_wc_map; p < &ofp11_wc_map[ARRAY_SIZE(ofp11_wc_map)]; p++) {
 
5283
        if (wc11 & p->wc11) {
 
5284
            bitmap_set1(fields.bm, p->mf);
 
5285
        }
 
5286
    }
 
5287
    return fields;
5107
5288
}
5108
5289
 
5109
5290
static void
5110
 
ofputil_put_ofp11_table_stats(const struct ofp12_table_stats *in,
 
5291
ofputil_put_ofp11_table_stats(const struct ofputil_table_stats *stats,
 
5292
                              const struct ofputil_table_features *features,
5111
5293
                              struct ofpbuf *buf)
5112
5294
{
 
5295
    struct mf_bitmap wc = wild_or_nonmatchable_fields(features);
5113
5296
    struct ofp11_table_stats *out;
5114
5297
 
5115
5298
    out = ofpbuf_put_zeros(buf, sizeof *out);
5116
 
    out->table_id = in->table_id;
5117
 
    ovs_strlcpy(out->name, in->name, sizeof out->name);
5118
 
    out->wildcards = oxm12_to_ofp11_flow_match_fields(in->wildcards);
5119
 
    out->match = oxm12_to_ofp11_flow_match_fields(in->match);
5120
 
    out->instructions = in->instructions;
5121
 
    out->write_actions = in->write_actions;
5122
 
    out->apply_actions = in->apply_actions;
5123
 
    out->config = in->config;
5124
 
    out->max_entries = in->max_entries;
5125
 
    out->active_count = in->active_count;
5126
 
    out->lookup_count = in->lookup_count;
5127
 
    out->matched_count = in->matched_count;
 
5299
    out->table_id = features->table_id;
 
5300
    ovs_strlcpy(out->name, features->name, sizeof out->name);
 
5301
    out->wildcards = mf_bitmap_to_of11(&wc);
 
5302
    out->match = mf_bitmap_to_of11(&features->match);
 
5303
    out->instructions = ovsinst_bitmap_to_openflow(
 
5304
        features->nonmiss.instructions, OFP11_VERSION);
 
5305
    out->write_actions = ofpact_bitmap_to_openflow(
 
5306
        features->nonmiss.write.ofpacts, OFP11_VERSION);
 
5307
    out->apply_actions = ofpact_bitmap_to_openflow(
 
5308
        features->nonmiss.apply.ofpacts, OFP11_VERSION);
 
5309
    out->config = htonl(features->miss_config);
 
5310
    out->max_entries = htonl(features->max_entries);
 
5311
    out->active_count = htonl(stats->active_count);
 
5312
    out->lookup_count = htonll(stats->lookup_count);
 
5313
    out->matched_count = htonll(stats->matched_count);
5128
5314
}
5129
5315
 
5130
5316
static void
5131
 
ofputil_put_ofp12_table_stats(const struct ofp12_table_stats *in,
 
5317
ofputil_put_ofp12_table_stats(const struct ofputil_table_stats *stats,
 
5318
                              const struct ofputil_table_features *features,
5132
5319
                              struct ofpbuf *buf)
5133
5320
{
5134
 
    struct ofp12_table_stats *out = ofpbuf_put(buf, in, sizeof *in);
 
5321
    struct ofp12_table_stats *out;
5135
5322
 
5136
 
    /* Trim off OF1.3-only capabilities. */
5137
 
    out->match &= htonll(OFPXMT12_MASK);
5138
 
    out->wildcards &= htonll(OFPXMT12_MASK);
5139
 
    out->write_setfields &= htonll(OFPXMT12_MASK);
5140
 
    out->apply_setfields &= htonll(OFPXMT12_MASK);
 
5323
    out = ofpbuf_put_zeros(buf, sizeof *out);
 
5324
    out->table_id = features->table_id;
 
5325
    ovs_strlcpy(out->name, features->name, sizeof out->name);
 
5326
    out->match = oxm_bitmap_from_mf_bitmap(&features->match, OFP12_VERSION);
 
5327
    out->wildcards = oxm_bitmap_from_mf_bitmap(&features->wildcard,
 
5328
                                             OFP12_VERSION);
 
5329
    out->write_actions = ofpact_bitmap_to_openflow(
 
5330
        features->nonmiss.write.ofpacts, OFP12_VERSION);
 
5331
    out->apply_actions = ofpact_bitmap_to_openflow(
 
5332
        features->nonmiss.apply.ofpacts, OFP12_VERSION);
 
5333
    out->write_setfields = oxm_bitmap_from_mf_bitmap(
 
5334
        &features->nonmiss.write.set_fields, OFP12_VERSION);
 
5335
    out->apply_setfields = oxm_bitmap_from_mf_bitmap(
 
5336
        &features->nonmiss.apply.set_fields, OFP12_VERSION);
 
5337
    out->metadata_match = features->metadata_match;
 
5338
    out->metadata_write = features->metadata_write;
 
5339
    out->instructions = ovsinst_bitmap_to_openflow(
 
5340
        features->nonmiss.instructions, OFP12_VERSION);
 
5341
    out->config = ofputil_table_miss_to_config(features->miss_config,
 
5342
                                               OFP12_VERSION);
 
5343
    out->max_entries = htonl(features->max_entries);
 
5344
    out->active_count = htonl(stats->active_count);
 
5345
    out->lookup_count = htonll(stats->lookup_count);
 
5346
    out->matched_count = htonll(stats->matched_count);
5141
5347
}
5142
5348
 
5143
5349
static void
5144
 
ofputil_put_ofp13_table_stats(const struct ofp12_table_stats *in,
 
5350
ofputil_put_ofp13_table_stats(const struct ofputil_table_stats *stats,
5145
5351
                              struct ofpbuf *buf)
5146
5352
{
5147
5353
    struct ofp13_table_stats *out;
5148
5354
 
5149
 
    /* OF 1.3 splits table features off the ofp_table_stats,
5150
 
     * so there is not much here. */
5151
 
 
5152
 
    out = ofpbuf_put_uninit(buf, sizeof *out);
5153
 
    out->table_id = in->table_id;
5154
 
    out->active_count = in->active_count;
5155
 
    out->lookup_count = in->lookup_count;
5156
 
    out->matched_count = in->matched_count;
 
5355
    out = ofpbuf_put_zeros(buf, sizeof *out);
 
5356
    out->table_id = stats->table_id;
 
5357
    out->active_count = htonl(stats->active_count);
 
5358
    out->lookup_count = htonll(stats->lookup_count);
 
5359
    out->matched_count = htonll(stats->matched_count);
5157
5360
}
5158
5361
 
5159
5362
struct ofpbuf *
5160
 
ofputil_encode_table_stats_reply(const struct ofp12_table_stats stats[], int n,
5161
 
                                 const struct ofp_header *request)
5162
 
{
5163
 
    struct ofpbuf *reply;
5164
 
    int i;
5165
 
 
5166
 
    reply = ofpraw_alloc_stats_reply(request, n * sizeof *stats);
5167
 
 
5168
 
    for (i = 0; i < n; i++) {
5169
 
        switch ((enum ofp_version) request->version) {
5170
 
        case OFP10_VERSION:
5171
 
            ofputil_put_ofp10_table_stats(&stats[i], reply);
5172
 
            break;
5173
 
 
5174
 
        case OFP11_VERSION:
5175
 
            ofputil_put_ofp11_table_stats(&stats[i], reply);
5176
 
            break;
5177
 
 
5178
 
        case OFP12_VERSION:
5179
 
            ofputil_put_ofp12_table_stats(&stats[i], reply);
5180
 
            break;
5181
 
 
5182
 
        case OFP13_VERSION:
5183
 
        case OFP14_VERSION:
5184
 
        case OFP15_VERSION:
5185
 
            ofputil_put_ofp13_table_stats(&stats[i], reply);
5186
 
            break;
5187
 
 
5188
 
        default:
5189
 
            OVS_NOT_REACHED();
5190
 
        }
5191
 
    }
5192
 
 
5193
 
    return reply;
 
5363
ofputil_encode_table_stats_reply(const struct ofp_header *request)
 
5364
{
 
5365
    return ofpraw_alloc_stats_reply(request, 0);
 
5366
}
 
5367
 
 
5368
void
 
5369
ofputil_append_table_stats_reply(struct ofpbuf *reply,
 
5370
                                 const struct ofputil_table_stats *stats,
 
5371
                                 const struct ofputil_table_features *features)
 
5372
{
 
5373
    struct ofp_header *oh = reply->header;
 
5374
 
 
5375
    ovs_assert(stats->table_id == features->table_id);
 
5376
 
 
5377
    switch ((enum ofp_version) oh->version) {
 
5378
    case OFP10_VERSION:
 
5379
        ofputil_put_ofp10_table_stats(stats, features, reply);
 
5380
        break;
 
5381
 
 
5382
    case OFP11_VERSION:
 
5383
        ofputil_put_ofp11_table_stats(stats, features, reply);
 
5384
        break;
 
5385
 
 
5386
    case OFP12_VERSION:
 
5387
        ofputil_put_ofp12_table_stats(stats, features, reply);
 
5388
        break;
 
5389
 
 
5390
    case OFP13_VERSION:
 
5391
    case OFP14_VERSION:
 
5392
    case OFP15_VERSION:
 
5393
        ofputil_put_ofp13_table_stats(stats, reply);
 
5394
        break;
 
5395
 
 
5396
    default:
 
5397
        OVS_NOT_REACHED();
 
5398
    }
 
5399
}
 
5400
 
 
5401
static int
 
5402
ofputil_decode_ofp10_table_stats(struct ofpbuf *msg,
 
5403
                                 struct ofputil_table_stats *stats,
 
5404
                                 struct ofputil_table_features *features)
 
5405
{
 
5406
    struct ofp10_table_stats *ots;
 
5407
 
 
5408
    ots = ofpbuf_try_pull(msg, sizeof *ots);
 
5409
    if (!ots) {
 
5410
        return OFPERR_OFPBRC_BAD_LEN;
 
5411
    }
 
5412
 
 
5413
    features->table_id = ots->table_id;
 
5414
    ovs_strlcpy(features->name, ots->name, sizeof features->name);
 
5415
    features->max_entries = ntohl(ots->max_entries);
 
5416
    features->match = features->wildcard = mf_bitmap_from_of10(ots->wildcards);
 
5417
 
 
5418
    stats->table_id = ots->table_id;
 
5419
    stats->active_count = ntohl(ots->active_count);
 
5420
    stats->lookup_count = ntohll(get_32aligned_be64(&ots->lookup_count));
 
5421
    stats->matched_count = ntohll(get_32aligned_be64(&ots->matched_count));
 
5422
 
 
5423
    return 0;
 
5424
}
 
5425
 
 
5426
static int
 
5427
ofputil_decode_ofp11_table_stats(struct ofpbuf *msg,
 
5428
                                 struct ofputil_table_stats *stats,
 
5429
                                 struct ofputil_table_features *features)
 
5430
{
 
5431
    struct ofp11_table_stats *ots;
 
5432
 
 
5433
    ots = ofpbuf_try_pull(msg, sizeof *ots);
 
5434
    if (!ots) {
 
5435
        return OFPERR_OFPBRC_BAD_LEN;
 
5436
    }
 
5437
 
 
5438
    features->table_id = ots->table_id;
 
5439
    ovs_strlcpy(features->name, ots->name, sizeof features->name);
 
5440
    features->max_entries = ntohl(ots->max_entries);
 
5441
    features->nonmiss.instructions = ovsinst_bitmap_from_openflow(
 
5442
        ots->instructions, OFP11_VERSION);
 
5443
    features->nonmiss.write.ofpacts = ofpact_bitmap_from_openflow(
 
5444
        ots->write_actions, OFP11_VERSION);
 
5445
    features->nonmiss.apply.ofpacts = ofpact_bitmap_from_openflow(
 
5446
        ots->write_actions, OFP11_VERSION);
 
5447
    features->miss = features->nonmiss;
 
5448
    features->miss_config = ofputil_table_miss_from_config(ots->config,
 
5449
                                                           OFP11_VERSION);
 
5450
    features->match = mf_bitmap_from_of11(ots->match);
 
5451
    features->wildcard = mf_bitmap_from_of11(ots->wildcards);
 
5452
    bitmap_or(features->match.bm, features->wildcard.bm, MFF_N_IDS);
 
5453
 
 
5454
    stats->table_id = ots->table_id;
 
5455
    stats->active_count = ntohl(ots->active_count);
 
5456
    stats->lookup_count = ntohll(ots->lookup_count);
 
5457
    stats->matched_count = ntohll(ots->matched_count);
 
5458
 
 
5459
    return 0;
 
5460
}
 
5461
 
 
5462
static int
 
5463
ofputil_decode_ofp12_table_stats(struct ofpbuf *msg,
 
5464
                                 struct ofputil_table_stats *stats,
 
5465
                                 struct ofputil_table_features *features)
 
5466
{
 
5467
    struct ofp12_table_stats *ots;
 
5468
 
 
5469
    ots = ofpbuf_try_pull(msg, sizeof *ots);
 
5470
    if (!ots) {
 
5471
        return OFPERR_OFPBRC_BAD_LEN;
 
5472
    }
 
5473
 
 
5474
    features->table_id = ots->table_id;
 
5475
    ovs_strlcpy(features->name, ots->name, sizeof features->name);
 
5476
    features->metadata_match = ots->metadata_match;
 
5477
    features->metadata_write = ots->metadata_write;
 
5478
    features->miss_config = ofputil_table_miss_from_config(ots->config,
 
5479
                                                           OFP12_VERSION);
 
5480
    features->max_entries = ntohl(ots->max_entries);
 
5481
 
 
5482
    features->nonmiss.instructions = ovsinst_bitmap_from_openflow(
 
5483
        ots->instructions, OFP12_VERSION);
 
5484
    features->nonmiss.write.ofpacts = ofpact_bitmap_from_openflow(
 
5485
        ots->write_actions, OFP12_VERSION);
 
5486
    features->nonmiss.apply.ofpacts = ofpact_bitmap_from_openflow(
 
5487
        ots->apply_actions, OFP12_VERSION);
 
5488
    features->nonmiss.write.set_fields = oxm_bitmap_to_mf_bitmap(
 
5489
        ots->write_setfields, OFP12_VERSION);
 
5490
    features->nonmiss.apply.set_fields = oxm_bitmap_to_mf_bitmap(
 
5491
        ots->apply_setfields, OFP12_VERSION);
 
5492
    features->miss = features->nonmiss;
 
5493
 
 
5494
    features->match = oxm_bitmap_to_mf_bitmap(ots->match, OFP12_VERSION);
 
5495
    features->wildcard = oxm_bitmap_to_mf_bitmap(ots->wildcards,
 
5496
                                                 OFP12_VERSION);
 
5497
    bitmap_or(features->match.bm, features->wildcard.bm, MFF_N_IDS);
 
5498
 
 
5499
    stats->table_id = ots->table_id;
 
5500
    stats->active_count = ntohl(ots->active_count);
 
5501
    stats->lookup_count = ntohll(ots->lookup_count);
 
5502
    stats->matched_count = ntohll(ots->matched_count);
 
5503
 
 
5504
    return 0;
 
5505
}
 
5506
 
 
5507
static int
 
5508
ofputil_decode_ofp13_table_stats(struct ofpbuf *msg,
 
5509
                                 struct ofputil_table_stats *stats,
 
5510
                                 struct ofputil_table_features *features)
 
5511
{
 
5512
    struct ofp13_table_stats *ots;
 
5513
 
 
5514
    ots = ofpbuf_try_pull(msg, sizeof *ots);
 
5515
    if (!ots) {
 
5516
        return OFPERR_OFPBRC_BAD_LEN;
 
5517
    }
 
5518
 
 
5519
    features->table_id = ots->table_id;
 
5520
 
 
5521
    stats->table_id = ots->table_id;
 
5522
    stats->active_count = ntohl(ots->active_count);
 
5523
    stats->lookup_count = ntohll(ots->lookup_count);
 
5524
    stats->matched_count = ntohll(ots->matched_count);
 
5525
 
 
5526
    return 0;
 
5527
}
 
5528
 
 
5529
int
 
5530
ofputil_decode_table_stats_reply(struct ofpbuf *msg,
 
5531
                                 struct ofputil_table_stats *stats,
 
5532
                                 struct ofputil_table_features *features)
 
5533
{
 
5534
    const struct ofp_header *oh;
 
5535
 
 
5536
    if (!msg->header) {
 
5537
        ofpraw_pull_assert(msg);
 
5538
    }
 
5539
    oh = msg->header;
 
5540
 
 
5541
    if (!msg->size) {
 
5542
        return EOF;
 
5543
    }
 
5544
 
 
5545
    memset(stats, 0, sizeof *stats);
 
5546
    memset(features, 0, sizeof *features);
 
5547
 
 
5548
    switch ((enum ofp_version) oh->version) {
 
5549
    case OFP10_VERSION:
 
5550
        return ofputil_decode_ofp10_table_stats(msg, stats, features);
 
5551
 
 
5552
    case OFP11_VERSION:
 
5553
        return ofputil_decode_ofp11_table_stats(msg, stats, features);
 
5554
 
 
5555
    case OFP12_VERSION:
 
5556
        return ofputil_decode_ofp12_table_stats(msg, stats, features);
 
5557
 
 
5558
    case OFP13_VERSION:
 
5559
    case OFP14_VERSION:
 
5560
    case OFP15_VERSION:
 
5561
        return ofputil_decode_ofp13_table_stats(msg, stats, features);
 
5562
 
 
5563
    default:
 
5564
        OVS_NOT_REACHED();
 
5565
    }
5194
5566
}
5195
5567
 
5196
5568
/* ofputil_flow_monitor_request */
5212
5584
    struct nx_flow_monitor_request *nfmr;
5213
5585
    uint16_t flags;
5214
5586
 
5215
 
    if (!msg->frame) {
 
5587
    if (!msg->header) {
5216
5588
        ofpraw_pull_assert(msg);
5217
5589
    }
5218
5590
 
5219
 
    if (!ofpbuf_size(msg)) {
 
5591
    if (!msg->size) {
5220
5592
        return EOF;
5221
5593
    }
5222
5594
 
5223
5595
    nfmr = ofpbuf_try_pull(msg, sizeof *nfmr);
5224
5596
    if (!nfmr) {
5225
5597
        VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW_MONITOR request has %"PRIu32" "
5226
 
                     "leftover bytes at end", ofpbuf_size(msg));
 
5598
                     "leftover bytes at end", msg->size);
5227
5599
        return OFPERR_OFPBRC_BAD_LEN;
5228
5600
    }
5229
5601
 
5233
5605
                     | NXFMF_MODIFY | NXFMF_ACTIONS | NXFMF_OWN)) {
5234
5606
        VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW_MONITOR has bad flags %#"PRIx16,
5235
5607
                     flags);
5236
 
        return OFPERR_NXBRC_FM_BAD_FLAGS;
 
5608
        return OFPERR_OFPMOFC_BAD_FLAGS;
5237
5609
    }
5238
5610
 
5239
5611
    if (!is_all_zeros(nfmr->zeros, sizeof nfmr->zeros)) {
5256
5628
    size_t start_ofs;
5257
5629
    int match_len;
5258
5630
 
5259
 
    if (!ofpbuf_size(msg)) {
 
5631
    if (!msg->size) {
5260
5632
        ofpraw_put(OFPRAW_NXST_FLOW_MONITOR_REQUEST, OFP10_VERSION, msg);
5261
5633
    }
5262
5634
 
5263
 
    start_ofs = ofpbuf_size(msg);
 
5635
    start_ofs = msg->size;
5264
5636
    ofpbuf_put_zeros(msg, sizeof *nfmr);
5265
5637
    match_len = nx_put_match(msg, &rq->match, htonll(0), htonll(0));
5266
5638
 
5296
5668
    unsigned int length;
5297
5669
    struct ofp_header *oh;
5298
5670
 
5299
 
    if (!msg->frame) {
 
5671
    if (!msg->header) {
5300
5672
        ofpraw_pull_assert(msg);
5301
5673
    }
5302
5674
 
5303
 
    if (!ofpbuf_size(msg)) {
 
5675
    if (!msg->size) {
5304
5676
        return EOF;
5305
5677
    }
5306
5678
 
5307
 
    if (ofpbuf_size(msg) < sizeof(struct nx_flow_update_header)) {
 
5679
    if (msg->size < sizeof(struct nx_flow_update_header)) {
5308
5680
        goto bad_len;
5309
5681
    }
5310
5682
 
5311
 
    oh = msg->frame;
 
5683
    oh = msg->header;
5312
5684
 
5313
 
    nfuh = ofpbuf_data(msg);
 
5685
    nfuh = msg->data;
5314
5686
    update->event = ntohs(nfuh->event);
5315
5687
    length = ntohs(nfuh->length);
5316
 
    if (length > ofpbuf_size(msg) || length % 8) {
 
5688
    if (length > msg->size || length % 8) {
5317
5689
        goto bad_len;
5318
5690
    }
5319
5691
 
5364
5736
            return error;
5365
5737
        }
5366
5738
 
5367
 
        update->ofpacts = ofpbuf_data(ofpacts);
5368
 
        update->ofpacts_len = ofpbuf_size(ofpacts);
 
5739
        update->ofpacts = ofpacts->data;
 
5740
        update->ofpacts_len = ofpacts->size;
5369
5741
        return 0;
5370
5742
    } else {
5371
5743
        VLOG_WARN_RL(&bad_ofmsg_rl,
5376
5748
 
5377
5749
bad_len:
5378
5750
    VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW_MONITOR reply has %"PRIu32" "
5379
 
                 "leftover bytes at end", ofpbuf_size(msg));
 
5751
                 "leftover bytes at end", msg->size);
5380
5752
    return OFPERR_OFPBRC_BAD_LEN;
5381
5753
}
5382
5754
 
5401
5773
}
5402
5774
 
5403
5775
void
5404
 
ofputil_start_flow_update(struct list *replies)
 
5776
ofputil_start_flow_update(struct ovs_list *replies)
5405
5777
{
5406
5778
    struct ofpbuf *msg;
5407
5779
 
5414
5786
 
5415
5787
void
5416
5788
ofputil_append_flow_update(const struct ofputil_flow_update *update,
5417
 
                           struct list *replies)
 
5789
                           struct ovs_list *replies)
5418
5790
{
5419
5791
    enum ofp_version version = ofpmp_version(replies);
5420
5792
    struct nx_flow_update_header *nfuh;
5422
5794
    size_t start_ofs;
5423
5795
 
5424
5796
    msg = ofpbuf_from_list(list_back(replies));
5425
 
    start_ofs = ofpbuf_size(msg);
 
5797
    start_ofs = msg->size;
5426
5798
 
5427
5799
    if (update->event == NXFME_ABBREV) {
5428
5800
        struct nx_flow_update_abbrev *nfua;
5448
5820
    }
5449
5821
 
5450
5822
    nfuh = ofpbuf_at_assert(msg, start_ofs, sizeof *nfuh);
5451
 
    nfuh->length = htons(ofpbuf_size(msg) - start_ofs);
 
5823
    nfuh->length = htons(msg->size - start_ofs);
5452
5824
    nfuh->event = htons(update->event);
5453
5825
 
5454
5826
    ofpmp_postappend(replies, start_ofs);
5474
5846
 
5475
5847
        msg = ofpraw_alloc(OFPRAW_OFPT10_PACKET_OUT, OFP10_VERSION, size);
5476
5848
        ofpbuf_put_zeros(msg, sizeof *opo);
5477
 
        actions_ofs = ofpbuf_size(msg);
 
5849
        actions_ofs = msg->size;
5478
5850
        ofpacts_put_openflow_actions(po->ofpacts, po->ofpacts_len, msg,
5479
5851
                                     ofp_version);
5480
5852
 
5481
 
        opo = ofpbuf_l3(msg);
 
5853
        opo = msg->msg;
5482
5854
        opo->buffer_id = htonl(po->buffer_id);
5483
5855
        opo->in_port = htons(ofp_to_u16(po->in_port));
5484
 
        opo->actions_len = htons(ofpbuf_size(msg) - actions_ofs);
 
5856
        opo->actions_len = htons(msg->size - actions_ofs);
5485
5857
        break;
5486
5858
    }
5487
5859
 
5497
5869
        ofpbuf_put_zeros(msg, sizeof *opo);
5498
5870
        len = ofpacts_put_openflow_actions(po->ofpacts, po->ofpacts_len, msg,
5499
5871
                                           ofp_version);
5500
 
        opo = ofpbuf_l3(msg);
 
5872
        opo = msg->msg;
5501
5873
        opo->buffer_id = htonl(po->buffer_id);
5502
5874
        opo->in_port = ofputil_port_to_ofp11(po->in_port);
5503
5875
        opo->actions_len = htons(len);
5536
5908
    ofpbuf_use_const(&rq_buf, rq, ntohs(rq->length));
5537
5909
    ofpraw_pull_assert(&rq_buf);
5538
5910
 
5539
 
    reply = ofpraw_alloc_reply(OFPRAW_OFPT_ECHO_REPLY, rq, ofpbuf_size(&rq_buf));
5540
 
    ofpbuf_put(reply, ofpbuf_data(&rq_buf), ofpbuf_size(&rq_buf));
 
5911
    reply = ofpraw_alloc_reply(OFPRAW_OFPT_ECHO_REPLY, rq, rq_buf.size);
 
5912
    ofpbuf_put(reply, rq_buf.data, rq_buf.size);
5541
5913
    return reply;
5542
5914
}
5543
5915
 
5643
6015
        OFPUTIL_NAMED_PORT(ALL)                 \
5644
6016
        OFPUTIL_NAMED_PORT(CONTROLLER)          \
5645
6017
        OFPUTIL_NAMED_PORT(LOCAL)               \
5646
 
        OFPUTIL_NAMED_PORT(ANY)
 
6018
        OFPUTIL_NAMED_PORT(ANY)                 \
 
6019
        OFPUTIL_NAMED_PORT(UNSET)
5647
6020
 
5648
6021
/* For backwards compatibility, so that "none" is recognized as OFPP_ANY */
5649
6022
#define OFPUTIL_NAMED_PORTS_WITH_NONE           \
5837
6210
    }
5838
6211
    case OFP14_VERSION:
5839
6212
    case OFP15_VERSION:
5840
 
        return ofpbuf_size(b) ? ofputil_pull_ofp14_port(pp, b) : EOF;
5841
 
    default:
5842
 
        OVS_NOT_REACHED();
5843
 
    }
5844
 
}
5845
 
 
5846
 
/* ofp-util.def lists the mapping from names to action. */
5847
 
static const char *const names[OFPUTIL_N_ACTIONS] = {
5848
 
    NULL,
5849
 
#define OFPAT10_ACTION(ENUM, STRUCT, NAME)             NAME,
5850
 
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) NAME,
5851
 
#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) NAME,
5852
 
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)   NAME,
5853
 
#include "ofp-util.def"
5854
 
};
5855
 
 
5856
 
/* Returns the 'enum ofputil_action_code' corresponding to 'name' (e.g. if
5857
 
 * 'name' is "output" then the return value is OFPUTIL_OFPAT10_OUTPUT), or -1
5858
 
 * if 'name' is not the name of any action. */
5859
 
int
5860
 
ofputil_action_code_from_name(const char *name)
5861
 
{
5862
 
    const char *const *p;
5863
 
 
5864
 
    for (p = names; p < &names[ARRAY_SIZE(names)]; p++) {
5865
 
        if (*p && !strcasecmp(name, *p)) {
5866
 
            return p - names;
5867
 
        }
5868
 
    }
5869
 
    return -1;
5870
 
}
5871
 
 
5872
 
/* Returns name corresponding to the 'enum ofputil_action_code',
5873
 
 * or "Unkonwn action", if the name is not available. */
5874
 
const char *
5875
 
ofputil_action_name_from_code(enum ofputil_action_code code)
5876
 
{
5877
 
    return code < (int)OFPUTIL_N_ACTIONS && names[code] ? names[code]
5878
 
        : "Unknown action";
5879
 
}
5880
 
 
5881
 
enum ofputil_action_code
5882
 
ofputil_action_code_from_ofp13_action(enum ofp13_action_type type)
5883
 
{
5884
 
    switch (type) {
5885
 
 
5886
 
#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)  \
5887
 
    case ENUM:                                          \
5888
 
        return OFPUTIL_##ENUM;
5889
 
#include "ofp-util.def"
5890
 
 
5891
 
    default:
5892
 
        return OFPUTIL_ACTION_INVALID;
5893
 
    }
5894
 
}
5895
 
 
5896
 
/* Appends an action of the type specified by 'code' to 'buf' and returns the
5897
 
 * action.  Initializes the parts of 'action' that identify it as having type
5898
 
 * <ENUM> and length 'sizeof *action' and zeros the rest.  For actions that
5899
 
 * have variable length, the length used and cleared is that of struct
5900
 
 * <STRUCT>.  */
5901
 
void *
5902
 
ofputil_put_action(enum ofputil_action_code code, struct ofpbuf *buf)
5903
 
{
5904
 
    switch (code) {
5905
 
    case OFPUTIL_ACTION_INVALID:
5906
 
#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
5907
 
#include "ofp-util.def"
5908
 
        OVS_NOT_REACHED();
5909
 
 
5910
 
#define OFPAT10_ACTION(ENUM, STRUCT, NAME)                  \
5911
 
    case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
5912
 
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)      \
5913
 
    case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
5914
 
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)        \
5915
 
    case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
5916
 
#include "ofp-util.def"
5917
 
    }
5918
 
    OVS_NOT_REACHED();
5919
 
}
5920
 
 
5921
 
#define OFPAT10_ACTION(ENUM, STRUCT, NAME)                        \
5922
 
    void                                                        \
5923
 
    ofputil_init_##ENUM(struct STRUCT *s)                       \
5924
 
    {                                                           \
5925
 
        memset(s, 0, sizeof *s);                                \
5926
 
        s->type = htons(ENUM);                                  \
5927
 
        s->len = htons(sizeof *s);                              \
5928
 
    }                                                           \
5929
 
                                                                \
5930
 
    struct STRUCT *                                             \
5931
 
    ofputil_put_##ENUM(struct ofpbuf *buf)                      \
5932
 
    {                                                           \
5933
 
        struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s);   \
5934
 
        ofputil_init_##ENUM(s);                                 \
5935
 
        return s;                                               \
5936
 
    }
5937
 
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
5938
 
    OFPAT10_ACTION(ENUM, STRUCT, NAME)
5939
 
#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
5940
 
    OFPAT10_ACTION(ENUM, STRUCT, NAME)
5941
 
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)            \
5942
 
    void                                                        \
5943
 
    ofputil_init_##ENUM(struct STRUCT *s)                       \
5944
 
    {                                                           \
5945
 
        memset(s, 0, sizeof *s);                                \
5946
 
        s->type = htons(OFPAT10_VENDOR);                        \
5947
 
        s->len = htons(sizeof *s);                              \
5948
 
        s->vendor = htonl(NX_VENDOR_ID);                        \
5949
 
        s->subtype = htons(ENUM);                               \
5950
 
    }                                                           \
5951
 
                                                                \
5952
 
    struct STRUCT *                                             \
5953
 
    ofputil_put_##ENUM(struct ofpbuf *buf)                      \
5954
 
    {                                                           \
5955
 
        struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s);   \
5956
 
        ofputil_init_##ENUM(s);                                 \
5957
 
        return s;                                               \
5958
 
    }
5959
 
#include "ofp-util.def"
 
6213
        return b->size ? ofputil_pull_ofp14_port(pp, b) : EOF;
 
6214
    default:
 
6215
        OVS_NOT_REACHED();
 
6216
    }
 
6217
}
5960
6218
 
5961
6219
static void
5962
6220
ofputil_normalize_match__(struct match *match, bool may_log)
6162
6420
}
6163
6421
 
6164
6422
/* Encode a dump ports request for 'port', the encoded message
6165
 
 * will be for Open Flow version 'ofp_version'. Returns message
 
6423
 * will be for OpenFlow version 'ofp_version'. Returns message
6166
6424
 * as a struct ofpbuf. Returns encoded message on success, NULL on error */
6167
6425
struct ofpbuf *
6168
6426
ofputil_encode_dump_ports_request(enum ofp_version ofp_version, ofp_port_t port)
6246
6504
 
6247
6505
static void
6248
6506
ofputil_append_ofp14_port_stats(const struct ofputil_port_stats *ops,
6249
 
                                struct list *replies)
 
6507
                                struct ovs_list *replies)
6250
6508
{
6251
6509
    struct ofp14_port_stats_prop_ethernet *eth;
6252
6510
    struct ofp14_port_stats *ps14;
6281
6539
 
6282
6540
/* Encode a ports stat for 'ops' and append it to 'replies'. */
6283
6541
void
6284
 
ofputil_append_port_stat(struct list *replies,
 
6542
ofputil_append_port_stat(struct ovs_list *replies,
6285
6543
                         const struct ofputil_port_stats *ops)
6286
6544
{
6287
6545
    switch (ofpmp_version(replies)) {
6383
6641
parse_ofp14_port_stats_ethernet_property(const struct ofpbuf *payload,
6384
6642
                                         struct ofputil_port_stats *ops)
6385
6643
{
6386
 
    const struct ofp14_port_stats_prop_ethernet *eth = ofpbuf_data(payload);
 
6644
    const struct ofp14_port_stats_prop_ethernet *eth = payload->data;
6387
6645
 
6388
 
    if (ofpbuf_size(payload) != sizeof *eth) {
 
6646
    if (payload->size != sizeof *eth) {
6389
6647
        return OFPERR_OFPBPC_BAD_LEN;
6390
6648
    }
6391
6649
 
6412
6670
    }
6413
6671
 
6414
6672
    len = ntohs(ps14->length);
6415
 
    if (len < sizeof *ps14 || len - sizeof *ps14 > ofpbuf_size(msg)) {
 
6673
    if (len < sizeof *ps14 || len - sizeof *ps14 > msg->size) {
6416
6674
        return OFPERR_OFPBRC_BAD_LEN;
6417
6675
    }
6418
6676
    len -= sizeof *ps14;
6438
6696
    ops->stats.rx_crc_errors = UINT64_MAX;
6439
6697
    ops->stats.collisions = UINT64_MAX;
6440
6698
 
6441
 
    while (ofpbuf_size(&properties) > 0) {
 
6699
    while (properties.size > 0) {
6442
6700
        struct ofpbuf payload;
6443
6701
        enum ofperr error;
6444
6702
        uint16_t type;
6500
6758
    enum ofperr error;
6501
6759
    enum ofpraw raw;
6502
6760
 
6503
 
    error = (msg->frame
6504
 
             ? ofpraw_decode(&raw, msg->frame)
 
6761
    error = (msg->header ? ofpraw_decode(&raw, msg->header)
6505
6762
             : ofpraw_pull(&raw, msg));
6506
6763
    if (error) {
6507
6764
        return error;
6508
6765
    }
6509
6766
 
6510
 
    if (!ofpbuf_size(msg)) {
 
6767
    if (!msg->size) {
6511
6768
        return EOF;
6512
6769
    } else if (raw == OFPRAW_OFPST14_PORT_REPLY) {
6513
6770
        return ofputil_pull_ofp14_port_stats(ps, msg);
6541
6798
 
6542
6799
 bad_len:
6543
6800
    VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_PORT reply has %"PRIu32" leftover "
6544
 
                 "bytes at end", ofpbuf_size(msg));
 
6801
                 "bytes at end", msg->size);
6545
6802
    return OFPERR_OFPBRC_BAD_LEN;
6546
6803
}
6547
6804
 
6575
6832
 
6576
6833
/* Frees all of the "struct ofputil_bucket"s in the 'buckets' list. */
6577
6834
void
6578
 
ofputil_bucket_list_destroy(struct list *buckets)
 
6835
ofputil_bucket_list_destroy(struct ovs_list *buckets)
6579
6836
{
6580
 
    struct ofputil_bucket *bucket, *next_bucket;
 
6837
    struct ofputil_bucket *bucket;
6581
6838
 
6582
 
    LIST_FOR_EACH_SAFE (bucket, next_bucket, list_node, buckets) {
6583
 
        list_remove(&bucket->list_node);
 
6839
    LIST_FOR_EACH_POP (bucket, list_node, buckets) {
6584
6840
        free(bucket->ofpacts);
6585
6841
        free(bucket);
6586
6842
    }
6587
6843
}
6588
6844
 
 
6845
/* Clones 'bucket' and its ofpacts data */
 
6846
static struct ofputil_bucket *
 
6847
ofputil_bucket_clone_data(const struct ofputil_bucket *bucket)
 
6848
{
 
6849
    struct ofputil_bucket *new;
 
6850
 
 
6851
    new = xmemdup(bucket, sizeof *bucket);
 
6852
    new->ofpacts = xmemdup(bucket->ofpacts, bucket->ofpacts_len);
 
6853
 
 
6854
    return new;
 
6855
}
 
6856
 
 
6857
/* Clones each of the buckets in the list 'src' appending them
 
6858
 * in turn to 'dest' which should be an initialised list.
 
6859
 * An exception is that if the pointer value of a bucket in 'src'
 
6860
 * matches 'skip' then it is not cloned or appended to 'dest'.
 
6861
 * This allows all of 'src' or 'all of 'src' except 'skip' to
 
6862
 * be cloned and appended to 'dest'. */
 
6863
void
 
6864
ofputil_bucket_clone_list(struct ovs_list *dest, const struct ovs_list *src,
 
6865
                          const struct ofputil_bucket *skip)
 
6866
{
 
6867
    struct ofputil_bucket *bucket;
 
6868
 
 
6869
    LIST_FOR_EACH (bucket, list_node, src) {
 
6870
        struct ofputil_bucket *new_bucket;
 
6871
 
 
6872
        if (bucket == skip) {
 
6873
            continue;
 
6874
        }
 
6875
 
 
6876
        new_bucket = ofputil_bucket_clone_data(bucket);
 
6877
        list_push_back(dest, &new_bucket->list_node);
 
6878
    }
 
6879
}
 
6880
 
 
6881
/* Find a bucket in the list 'buckets' whose bucket id is 'bucket_id'
 
6882
 * Returns the first bucket found or NULL if no buckets are found. */
 
6883
struct ofputil_bucket *
 
6884
ofputil_bucket_find(const struct ovs_list *buckets, uint32_t bucket_id)
 
6885
{
 
6886
    struct ofputil_bucket *bucket;
 
6887
 
 
6888
    if (bucket_id > OFPG15_BUCKET_MAX) {
 
6889
        return NULL;
 
6890
    }
 
6891
 
 
6892
    LIST_FOR_EACH (bucket, list_node, buckets) {
 
6893
        if (bucket->bucket_id == bucket_id) {
 
6894
            return bucket;
 
6895
        }
 
6896
    }
 
6897
 
 
6898
    return NULL;
 
6899
}
 
6900
 
 
6901
/* Returns true if more than one bucket in the list 'buckets'
 
6902
 * have the same bucket id. Returns false otherwise. */
 
6903
bool
 
6904
ofputil_bucket_check_duplicate_id(const struct ovs_list *buckets)
 
6905
{
 
6906
    struct ofputil_bucket *i, *j;
 
6907
 
 
6908
    LIST_FOR_EACH (i, list_node, buckets) {
 
6909
        LIST_FOR_EACH_REVERSE (j, list_node, buckets) {
 
6910
            if (i == j) {
 
6911
                break;
 
6912
            }
 
6913
            if (i->bucket_id == j->bucket_id) {
 
6914
                return true;
 
6915
            }
 
6916
        }
 
6917
    }
 
6918
 
 
6919
    return false;
 
6920
}
 
6921
 
 
6922
/* Returns the bucket at the front of the list 'buckets'.
 
6923
 * Undefined if 'buckets is empty. */
 
6924
struct ofputil_bucket *
 
6925
ofputil_bucket_list_front(const struct ovs_list *buckets)
 
6926
{
 
6927
    static struct ofputil_bucket *bucket;
 
6928
 
 
6929
    ASSIGN_CONTAINER(bucket, list_front(buckets), list_node);
 
6930
 
 
6931
    return bucket;
 
6932
}
 
6933
 
 
6934
/* Returns the bucket at the back of the list 'buckets'.
 
6935
 * Undefined if 'buckets is empty. */
 
6936
struct ofputil_bucket *
 
6937
ofputil_bucket_list_back(const struct ovs_list *buckets)
 
6938
{
 
6939
    static struct ofputil_bucket *bucket;
 
6940
 
 
6941
    ASSIGN_CONTAINER(bucket, list_back(buckets), list_node);
 
6942
 
 
6943
    return bucket;
 
6944
}
 
6945
 
6589
6946
/* Returns an OpenFlow group stats request for OpenFlow version 'ofp_version',
6590
6947
 * that requests stats for group 'group_id'.  (Use OFPG_ALL to request stats
6591
6948
 * for all groups.)
6619
6976
    return request;
6620
6977
}
6621
6978
 
 
6979
void
 
6980
ofputil_uninit_group_desc(struct ofputil_group_desc *gd)
 
6981
{
 
6982
    ofputil_bucket_list_destroy(&gd->buckets);
 
6983
    free(&gd->props.fields);
 
6984
}
 
6985
 
6622
6986
/* Decodes the OpenFlow group description request in 'oh', returning the group
6623
6987
 * whose description is requested, or OFPG_ALL if stats for all groups was
6624
6988
 * requested. */
6719
7083
 * replies already begun in 'replies' and appends it to the list.  'replies'
6720
7084
 * must have originally been initialized with ofpmp_init(). */
6721
7085
void
6722
 
ofputil_append_group_stats(struct list *replies,
 
7086
ofputil_append_group_stats(struct ovs_list *replies,
6723
7087
                           const struct ofputil_group_stats *gs)
6724
7088
{
6725
7089
    size_t bucket_counter_size;
6792
7156
{
6793
7157
    struct ofp12_group_features_stats *ogf;
6794
7158
    struct ofpbuf *reply;
 
7159
    int i;
6795
7160
 
6796
7161
    reply = ofpraw_alloc_xid(OFPRAW_OFPST12_GROUP_FEATURES_REPLY,
6797
7162
                             request->version, request->xid, 0);
6798
7163
    ogf = ofpbuf_put_zeros(reply, sizeof *ogf);
6799
7164
    ogf->types = htonl(features->types);
6800
7165
    ogf->capabilities = htonl(features->capabilities);
6801
 
    ogf->max_groups[0] = htonl(features->max_groups[0]);
6802
 
    ogf->max_groups[1] = htonl(features->max_groups[1]);
6803
 
    ogf->max_groups[2] = htonl(features->max_groups[2]);
6804
 
    ogf->max_groups[3] = htonl(features->max_groups[3]);
6805
 
    ogf->actions[0] = htonl(features->actions[0]);
6806
 
    ogf->actions[1] = htonl(features->actions[1]);
6807
 
    ogf->actions[2] = htonl(features->actions[2]);
6808
 
    ogf->actions[3] = htonl(features->actions[3]);
 
7166
    for (i = 0; i < OFPGT12_N_TYPES; i++) {
 
7167
        ogf->max_groups[i] = htonl(features->max_groups[i]);
 
7168
        ogf->actions[i] = ofpact_bitmap_to_openflow(features->ofpacts[i],
 
7169
                                                    request->version);
 
7170
    }
6809
7171
 
6810
7172
    return reply;
6811
7173
}
6816
7178
                                    struct ofputil_group_features *features)
6817
7179
{
6818
7180
    const struct ofp12_group_features_stats *ogf = ofpmsg_body(oh);
 
7181
    int i;
6819
7182
 
6820
7183
    features->types = ntohl(ogf->types);
6821
7184
    features->capabilities = ntohl(ogf->capabilities);
6822
 
    features->max_groups[0] = ntohl(ogf->max_groups[0]);
6823
 
    features->max_groups[1] = ntohl(ogf->max_groups[1]);
6824
 
    features->max_groups[2] = ntohl(ogf->max_groups[2]);
6825
 
    features->max_groups[3] = ntohl(ogf->max_groups[3]);
6826
 
    features->actions[0] = ntohl(ogf->actions[0]);
6827
 
    features->actions[1] = ntohl(ogf->actions[1]);
6828
 
    features->actions[2] = ntohl(ogf->actions[2]);
6829
 
    features->actions[3] = ntohl(ogf->actions[3]);
 
7185
    for (i = 0; i < OFPGT12_N_TYPES; i++) {
 
7186
        features->max_groups[i] = ntohl(ogf->max_groups[i]);
 
7187
        features->ofpacts[i] = ofpact_bitmap_from_openflow(
 
7188
            ogf->actions[i], oh->version);
 
7189
    }
6830
7190
}
6831
7191
 
6832
7192
/* Parse a group status request message into a 32 bit OpenFlow 1.1
6865
7225
    size_t i;
6866
7226
 
6867
7227
    gs->bucket_stats = NULL;
6868
 
    error = (msg->frame
6869
 
             ? ofpraw_decode(&raw, msg->frame)
 
7228
    error = (msg->header ? ofpraw_decode(&raw, msg->header)
6870
7229
             : ofpraw_pull(&raw, msg));
6871
7230
    if (error) {
6872
7231
        return error;
6873
7232
    }
6874
7233
 
6875
 
    if (!ofpbuf_size(msg)) {
 
7234
    if (!msg->size) {
6876
7235
        return EOF;
6877
7236
    }
6878
7237
 
6898
7257
 
6899
7258
    if (!ogs11) {
6900
7259
        VLOG_WARN_RL(&bad_ofmsg_rl, "%s reply has %"PRIu32" leftover bytes at end",
6901
 
                     ofpraw_get_name(raw), ofpbuf_size(msg));
 
7260
                     ofpraw_get_name(raw), msg->size);
6902
7261
        return OFPERR_OFPBRC_BAD_LEN;
6903
7262
    }
6904
7263
    length = ntohs(ogs11->length);
6917
7276
    obc = ofpbuf_try_pull(msg, gs->n_buckets * sizeof *obc);
6918
7277
    if (!obc) {
6919
7278
        VLOG_WARN_RL(&bad_ofmsg_rl, "%s reply has %"PRIu32" leftover bytes at end",
6920
 
                     ofpraw_get_name(raw), ofpbuf_size(msg));
 
7279
                     ofpraw_get_name(raw), msg->size);
6921
7280
        return OFPERR_OFPBRC_BAD_LEN;
6922
7281
    }
6923
7282
 
6930
7289
    return 0;
6931
7290
}
6932
7291
 
 
7292
static void
 
7293
ofputil_put_ofp11_bucket(const struct ofputil_bucket *bucket,
 
7294
                         struct ofpbuf *openflow, enum ofp_version ofp_version)
 
7295
{
 
7296
    struct ofp11_bucket *ob;
 
7297
    size_t start;
 
7298
 
 
7299
    start = openflow->size;
 
7300
    ofpbuf_put_zeros(openflow, sizeof *ob);
 
7301
    ofpacts_put_openflow_actions(bucket->ofpacts, bucket->ofpacts_len,
 
7302
                                openflow, ofp_version);
 
7303
    ob = ofpbuf_at_assert(openflow, start, sizeof *ob);
 
7304
    ob->len = htons(openflow->size - start);
 
7305
    ob->weight = htons(bucket->weight);
 
7306
    ob->watch_port = ofputil_port_to_ofp11(bucket->watch_port);
 
7307
    ob->watch_group = htonl(bucket->watch_group);
 
7308
}
 
7309
 
 
7310
static void
 
7311
ofputil_put_ofp15_group_bucket_prop_weight(ovs_be16 weight,
 
7312
                                           struct ofpbuf *openflow)
 
7313
{
 
7314
    size_t start_ofs;
 
7315
    struct ofp15_group_bucket_prop_weight *prop;
 
7316
 
 
7317
    start_ofs = start_property(openflow, OFPGBPT15_WEIGHT);
 
7318
    ofpbuf_put_zeros(openflow, sizeof *prop - sizeof(struct ofp_prop_header));
 
7319
    prop = ofpbuf_at_assert(openflow, start_ofs, sizeof *prop);
 
7320
    prop->weight = weight;
 
7321
    end_property(openflow, start_ofs);
 
7322
}
 
7323
 
 
7324
static void
 
7325
ofputil_put_ofp15_group_bucket_prop_watch(ovs_be32 watch, uint16_t type,
 
7326
                                          struct ofpbuf *openflow)
 
7327
{
 
7328
    size_t start_ofs;
 
7329
    struct ofp15_group_bucket_prop_watch *prop;
 
7330
 
 
7331
    start_ofs = start_property(openflow, type);
 
7332
    ofpbuf_put_zeros(openflow, sizeof *prop - sizeof(struct ofp_prop_header));
 
7333
    prop = ofpbuf_at_assert(openflow, start_ofs, sizeof *prop);
 
7334
    prop->watch = watch;
 
7335
    end_property(openflow, start_ofs);
 
7336
}
 
7337
 
 
7338
static void
 
7339
ofputil_put_ofp15_bucket(const struct ofputil_bucket *bucket,
 
7340
                         uint32_t bucket_id, enum ofp11_group_type group_type,
 
7341
                         struct ofpbuf *openflow, enum ofp_version ofp_version)
 
7342
{
 
7343
    struct ofp15_bucket *ob;
 
7344
    size_t start, actions_start, actions_len;
 
7345
 
 
7346
    start = openflow->size;
 
7347
    ofpbuf_put_zeros(openflow, sizeof *ob);
 
7348
 
 
7349
    actions_start = openflow->size;
 
7350
    ofpacts_put_openflow_actions(bucket->ofpacts, bucket->ofpacts_len,
 
7351
                                 openflow, ofp_version);
 
7352
    actions_len = openflow->size - actions_start;
 
7353
 
 
7354
    if (group_type == OFPGT11_SELECT) {
 
7355
        ofputil_put_ofp15_group_bucket_prop_weight(htons(bucket->weight),
 
7356
                                                   openflow);
 
7357
    }
 
7358
    if (bucket->watch_port != OFPP_ANY) {
 
7359
        ovs_be32 port = ofputil_port_to_ofp11(bucket->watch_port);
 
7360
        ofputil_put_ofp15_group_bucket_prop_watch(port,
 
7361
                                                  OFPGBPT15_WATCH_PORT,
 
7362
                                                  openflow);
 
7363
    }
 
7364
    if (bucket->watch_group != OFPG_ANY) {
 
7365
        ovs_be32 group = htonl(bucket->watch_group);
 
7366
        ofputil_put_ofp15_group_bucket_prop_watch(group,
 
7367
                                                  OFPGBPT15_WATCH_GROUP,
 
7368
                                                  openflow);
 
7369
    }
 
7370
 
 
7371
    ob = ofpbuf_at_assert(openflow, start, sizeof *ob);
 
7372
    ob->len = htons(openflow->size - start);
 
7373
    ob->action_array_len = htons(actions_len);
 
7374
    ob->bucket_id = htonl(bucket_id);
 
7375
}
 
7376
 
 
7377
static void
 
7378
ofputil_put_group_prop_ntr_selection_method(enum ofp_version ofp_version,
 
7379
                                            const struct ofputil_group_props *gp,
 
7380
                                            struct ofpbuf *openflow)
 
7381
{
 
7382
    struct ntr_group_prop_selection_method *prop;
 
7383
    size_t start;
 
7384
 
 
7385
    start = openflow->size;
 
7386
    ofpbuf_put_zeros(openflow, sizeof *prop);
 
7387
    oxm_put_field_array(openflow, &gp->fields, ofp_version);
 
7388
    prop = ofpbuf_at_assert(openflow, start, sizeof *prop);
 
7389
    prop->type = htons(OFPGPT15_EXPERIMENTER);
 
7390
    prop->experimenter = htonl(NTR_VENDOR_ID);
 
7391
    prop->exp_type = htonl(NTRT_SELECTION_METHOD);
 
7392
    strcpy(prop->selection_method, gp->selection_method);
 
7393
    prop->selection_method_param = htonll(gp->selection_method_param);
 
7394
    end_property(openflow, start);
 
7395
}
 
7396
 
 
7397
static void
 
7398
ofputil_append_ofp11_group_desc_reply(const struct ofputil_group_desc *gds,
 
7399
                                      const struct ovs_list *buckets,
 
7400
                                      struct ovs_list *replies,
 
7401
                                      enum ofp_version version)
 
7402
{
 
7403
    struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
 
7404
    struct ofp11_group_desc_stats *ogds;
 
7405
    struct ofputil_bucket *bucket;
 
7406
    size_t start_ogds;
 
7407
 
 
7408
    start_ogds = reply->size;
 
7409
    ofpbuf_put_zeros(reply, sizeof *ogds);
 
7410
    LIST_FOR_EACH (bucket, list_node, buckets) {
 
7411
        ofputil_put_ofp11_bucket(bucket, reply, version);
 
7412
    }
 
7413
    ogds = ofpbuf_at_assert(reply, start_ogds, sizeof *ogds);
 
7414
    ogds->length = htons(reply->size - start_ogds);
 
7415
    ogds->type = gds->type;
 
7416
    ogds->group_id = htonl(gds->group_id);
 
7417
 
 
7418
    ofpmp_postappend(replies, start_ogds);
 
7419
}
 
7420
 
 
7421
static void
 
7422
ofputil_append_ofp15_group_desc_reply(const struct ofputil_group_desc *gds,
 
7423
                                      const struct ovs_list *buckets,
 
7424
                                      struct ovs_list *replies,
 
7425
                                      enum ofp_version version)
 
7426
{
 
7427
    struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
 
7428
    struct ofp15_group_desc_stats *ogds;
 
7429
    struct ofputil_bucket *bucket;
 
7430
    size_t start_ogds, start_buckets;
 
7431
 
 
7432
    start_ogds = reply->size;
 
7433
    ofpbuf_put_zeros(reply, sizeof *ogds);
 
7434
    start_buckets = reply->size;
 
7435
    LIST_FOR_EACH (bucket, list_node, buckets) {
 
7436
        ofputil_put_ofp15_bucket(bucket, bucket->bucket_id,
 
7437
                                 gds->type, reply, version);
 
7438
    }
 
7439
    ogds = ofpbuf_at_assert(reply, start_ogds, sizeof *ogds);
 
7440
    ogds->length = htons(reply->size - start_ogds);
 
7441
    ogds->type = gds->type;
 
7442
    ogds->group_id = htonl(gds->group_id);
 
7443
    ogds->bucket_list_len =  htons(reply->size - start_buckets);
 
7444
 
 
7445
    /* Add group properties */
 
7446
    if (gds->props.selection_method[0]) {
 
7447
        ofputil_put_group_prop_ntr_selection_method(version, &gds->props,
 
7448
                                                    reply);
 
7449
    }
 
7450
 
 
7451
    ofpmp_postappend(replies, start_ogds);
 
7452
}
 
7453
 
6933
7454
/* Appends a group stats reply that contains the data in 'gds' to those already
6934
7455
 * present in the list of ofpbufs in 'replies'.  'replies' should have been
6935
7456
 * initialized with ofpmp_init(). */
6936
7457
void
6937
7458
ofputil_append_group_desc_reply(const struct ofputil_group_desc *gds,
6938
 
                                struct list *buckets,
6939
 
                                struct list *replies)
 
7459
                                const struct ovs_list *buckets,
 
7460
                                struct ovs_list *replies)
6940
7461
{
6941
 
    struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
6942
7462
    enum ofp_version version = ofpmp_version(replies);
6943
 
    struct ofp11_group_desc_stats *ogds;
6944
 
    struct ofputil_bucket *bucket;
6945
 
    size_t start_ogds;
6946
 
 
6947
 
    start_ogds = ofpbuf_size(reply);
6948
 
    ofpbuf_put_zeros(reply, sizeof *ogds);
6949
 
    LIST_FOR_EACH (bucket, list_node, buckets) {
6950
 
        struct ofp11_bucket *ob;
6951
 
        size_t start_ob;
6952
 
 
6953
 
        start_ob = ofpbuf_size(reply);
6954
 
        ofpbuf_put_zeros(reply, sizeof *ob);
6955
 
        ofpacts_put_openflow_actions(bucket->ofpacts, bucket->ofpacts_len,
6956
 
                                     reply, version);
6957
 
        ob = ofpbuf_at_assert(reply, start_ob, sizeof *ob);
6958
 
        ob->len = htons(ofpbuf_size(reply) - start_ob);
6959
 
        ob->weight = htons(bucket->weight);
6960
 
        ob->watch_port = ofputil_port_to_ofp11(bucket->watch_port);
6961
 
        ob->watch_group = htonl(bucket->watch_group);
 
7463
 
 
7464
    switch (version)
 
7465
    {
 
7466
    case OFP11_VERSION:
 
7467
    case OFP12_VERSION:
 
7468
    case OFP13_VERSION:
 
7469
    case OFP14_VERSION:
 
7470
        ofputil_append_ofp11_group_desc_reply(gds, buckets, replies, version);
 
7471
        break;
 
7472
 
 
7473
    case OFP15_VERSION:
 
7474
        ofputil_append_ofp15_group_desc_reply(gds, buckets, replies, version);
 
7475
        break;
 
7476
 
 
7477
    case OFP10_VERSION:
 
7478
    default:
 
7479
        OVS_NOT_REACHED();
6962
7480
    }
6963
 
    ogds = ofpbuf_at_assert(reply, start_ogds, sizeof *ogds);
6964
 
    ogds->length = htons(ofpbuf_size(reply) - start_ogds);
6965
 
    ogds->type = gds->type;
6966
 
    ogds->group_id = htonl(gds->group_id);
6967
 
 
6968
 
    ofpmp_postappend(replies, start_ogds);
6969
7481
}
6970
7482
 
6971
7483
static enum ofperr
6972
 
ofputil_pull_buckets(struct ofpbuf *msg, size_t buckets_length,
6973
 
                     enum ofp_version version, struct list *buckets)
 
7484
ofputil_pull_ofp11_buckets(struct ofpbuf *msg, size_t buckets_length,
 
7485
                           enum ofp_version version, struct ovs_list *buckets)
6974
7486
{
6975
7487
    struct ofp11_bucket *ob;
 
7488
    uint32_t bucket_id = 0;
6976
7489
 
6977
7490
    list_init(buckets);
6978
7491
    while (buckets_length > 0) {
7021
7534
            return OFPERR_OFPGMFC_BAD_WATCH;
7022
7535
        }
7023
7536
        bucket->watch_group = ntohl(ob->watch_group);
7024
 
        bucket->ofpacts = ofpbuf_steal_data(&ofpacts);
7025
 
        bucket->ofpacts_len = ofpbuf_size(&ofpacts);
7026
 
        list_push_back(buckets, &bucket->list_node);
7027
 
    }
7028
 
 
7029
 
    return 0;
 
7537
        bucket->bucket_id = bucket_id++;
 
7538
 
 
7539
        bucket->ofpacts = ofpbuf_steal_data(&ofpacts);
 
7540
        bucket->ofpacts_len = ofpacts.size;
 
7541
        list_push_back(buckets, &bucket->list_node);
 
7542
    }
 
7543
 
 
7544
    return 0;
 
7545
}
 
7546
 
 
7547
static enum ofperr
 
7548
parse_ofp15_group_bucket_prop_weight(const struct ofpbuf *payload,
 
7549
                                     ovs_be16 *weight)
 
7550
{
 
7551
    struct ofp15_group_bucket_prop_weight *prop = payload->data;
 
7552
 
 
7553
    if (payload->size != sizeof *prop) {
 
7554
        log_property(false, "OpenFlow bucket weight property length "
 
7555
                     "%u is not valid", payload->size);
 
7556
        return OFPERR_OFPBPC_BAD_LEN;
 
7557
    }
 
7558
 
 
7559
    *weight = prop->weight;
 
7560
 
 
7561
    return 0;
 
7562
}
 
7563
 
 
7564
static enum ofperr
 
7565
parse_ofp15_group_bucket_prop_watch(const struct ofpbuf *payload,
 
7566
                                    ovs_be32 *watch)
 
7567
{
 
7568
    struct ofp15_group_bucket_prop_watch *prop = payload->data;
 
7569
 
 
7570
    if (payload->size != sizeof *prop) {
 
7571
        log_property(false, "OpenFlow bucket watch port or group "
 
7572
                     "property length %u is not valid", payload->size);
 
7573
        return OFPERR_OFPBPC_BAD_LEN;
 
7574
    }
 
7575
 
 
7576
    *watch = prop->watch;
 
7577
 
 
7578
    return 0;
 
7579
}
 
7580
 
 
7581
static enum ofperr
 
7582
ofputil_pull_ofp15_buckets(struct ofpbuf *msg, size_t buckets_length,
 
7583
                           enum ofp_version version, uint8_t group_type,
 
7584
                           struct ovs_list *buckets)
 
7585
{
 
7586
    struct ofp15_bucket *ob;
 
7587
 
 
7588
    list_init(buckets);
 
7589
    while (buckets_length > 0) {
 
7590
        struct ofputil_bucket *bucket = NULL;
 
7591
        struct ofpbuf ofpacts;
 
7592
        enum ofperr err = OFPERR_OFPGMFC_BAD_BUCKET;
 
7593
        struct ofpbuf properties;
 
7594
        size_t ob_len, actions_len, properties_len;
 
7595
        ovs_be32 watch_port = ofputil_port_to_ofp11(OFPP_ANY);
 
7596
        ovs_be32 watch_group = htonl(OFPG_ANY);
 
7597
        ovs_be16 weight = htons(group_type == OFPGT11_SELECT ? 1 : 0);
 
7598
 
 
7599
        ofpbuf_init(&ofpacts, 0);
 
7600
 
 
7601
        ob = ofpbuf_try_pull(msg, sizeof *ob);
 
7602
        if (!ob) {
 
7603
            VLOG_WARN_RL(&bad_ofmsg_rl, "buckets end with %"PRIuSIZE
 
7604
                         " leftover bytes", buckets_length);
 
7605
            goto err;
 
7606
        }
 
7607
 
 
7608
        ob_len = ntohs(ob->len);
 
7609
        actions_len = ntohs(ob->action_array_len);
 
7610
 
 
7611
        if (ob_len < sizeof *ob) {
 
7612
            VLOG_WARN_RL(&bad_ofmsg_rl, "OpenFlow message bucket length "
 
7613
                         "%"PRIuSIZE" is not valid", ob_len);
 
7614
            goto err;
 
7615
        } else if (ob_len > buckets_length) {
 
7616
            VLOG_WARN_RL(&bad_ofmsg_rl, "OpenFlow message bucket length "
 
7617
                         "%"PRIuSIZE" exceeds remaining buckets data size %"
 
7618
                         PRIuSIZE, ob_len, buckets_length);
 
7619
            goto err;
 
7620
        } else if (actions_len > ob_len - sizeof *ob) {
 
7621
            VLOG_WARN_RL(&bad_ofmsg_rl, "OpenFlow message bucket actions "
 
7622
                         "length %"PRIuSIZE" exceeds remaining bucket "
 
7623
                         "data size %"PRIuSIZE, actions_len,
 
7624
                         ob_len - sizeof *ob);
 
7625
            goto err;
 
7626
        }
 
7627
        buckets_length -= ob_len;
 
7628
 
 
7629
        err = ofpacts_pull_openflow_actions(msg, actions_len, version,
 
7630
                                            &ofpacts);
 
7631
        if (err) {
 
7632
            goto err;
 
7633
        }
 
7634
 
 
7635
        properties_len = ob_len - sizeof *ob - actions_len;
 
7636
        ofpbuf_use_const(&properties, ofpbuf_pull(msg, properties_len),
 
7637
                         properties_len);
 
7638
 
 
7639
        while (properties.size > 0) {
 
7640
            struct ofpbuf payload;
 
7641
            uint16_t type;
 
7642
 
 
7643
            err = ofputil_pull_property(&properties, &payload, &type);
 
7644
            if (err) {
 
7645
                goto err;
 
7646
            }
 
7647
 
 
7648
            switch (type) {
 
7649
            case OFPGBPT15_WEIGHT:
 
7650
                err = parse_ofp15_group_bucket_prop_weight(&payload, &weight);
 
7651
                break;
 
7652
 
 
7653
            case OFPGBPT15_WATCH_PORT:
 
7654
                err = parse_ofp15_group_bucket_prop_watch(&payload,
 
7655
                                                          &watch_port);
 
7656
                break;
 
7657
 
 
7658
            case OFPGBPT15_WATCH_GROUP:
 
7659
                err = parse_ofp15_group_bucket_prop_watch(&payload,
 
7660
                                                          &watch_group);
 
7661
                break;
 
7662
 
 
7663
            default:
 
7664
                log_property(false, "unknown group bucket property %"PRIu16,
 
7665
                             type);
 
7666
                err = OFPERR_OFPBPC_BAD_TYPE;
 
7667
                break;
 
7668
            }
 
7669
 
 
7670
            if (err) {
 
7671
                goto err;
 
7672
            }
 
7673
        }
 
7674
 
 
7675
        bucket = xzalloc(sizeof *bucket);
 
7676
 
 
7677
        bucket->weight = ntohs(weight);
 
7678
        err = ofputil_port_from_ofp11(watch_port, &bucket->watch_port);
 
7679
        if (err) {
 
7680
            err = OFPERR_OFPGMFC_BAD_WATCH;
 
7681
            goto err;
 
7682
        }
 
7683
        bucket->watch_group = ntohl(watch_group);
 
7684
        bucket->bucket_id = ntohl(ob->bucket_id);
 
7685
        if (bucket->bucket_id > OFPG15_BUCKET_MAX) {
 
7686
            VLOG_WARN_RL(&bad_ofmsg_rl, "bucket id (%u) is out of range",
 
7687
                         bucket->bucket_id);
 
7688
            err = OFPERR_OFPGMFC_BAD_BUCKET;
 
7689
            goto err;
 
7690
        }
 
7691
 
 
7692
        bucket->ofpacts = ofpbuf_steal_data(&ofpacts);
 
7693
        bucket->ofpacts_len = ofpacts.size;
 
7694
        list_push_back(buckets, &bucket->list_node);
 
7695
 
 
7696
        continue;
 
7697
 
 
7698
    err:
 
7699
        free(bucket);
 
7700
        ofpbuf_uninit(&ofpacts);
 
7701
        ofputil_bucket_list_destroy(buckets);
 
7702
        return err;
 
7703
    }
 
7704
 
 
7705
    if (ofputil_bucket_check_duplicate_id(buckets)) {
 
7706
        VLOG_WARN_RL(&bad_ofmsg_rl, "Duplicate bucket id");
 
7707
        ofputil_bucket_list_destroy(buckets);
 
7708
        return OFPERR_OFPGMFC_BAD_BUCKET;
 
7709
    }
 
7710
 
 
7711
    return 0;
 
7712
}
 
7713
 
 
7714
static void
 
7715
ofputil_init_group_properties(struct ofputil_group_props *gp)
 
7716
{
 
7717
    memset(gp, 0, sizeof *gp);
 
7718
}
 
7719
 
 
7720
static enum ofperr
 
7721
parse_group_prop_ntr_selection_method(struct ofpbuf *payload,
 
7722
                                      enum ofp11_group_type group_type,
 
7723
                                      enum ofp15_group_mod_command group_cmd,
 
7724
                                      struct ofputil_group_props *gp)
 
7725
{
 
7726
    struct ntr_group_prop_selection_method *prop = payload->data;
 
7727
    size_t fields_len, method_len;
 
7728
    enum ofperr error;
 
7729
 
 
7730
    switch (group_type) {
 
7731
    case OFPGT11_SELECT:
 
7732
        break;
 
7733
    case OFPGT11_ALL:
 
7734
    case OFPGT11_INDIRECT:
 
7735
    case OFPGT11_FF:
 
7736
        log_property(false, "ntr selection method property is only allowed "
 
7737
                     "for select groups");
 
7738
        return OFPERR_OFPBPC_BAD_VALUE;
 
7739
    default:
 
7740
        OVS_NOT_REACHED();
 
7741
    }
 
7742
 
 
7743
    switch (group_cmd) {
 
7744
    case OFPGC15_ADD:
 
7745
    case OFPGC15_MODIFY:
 
7746
        break;
 
7747
    case OFPGC15_DELETE:
 
7748
    case OFPGC15_INSERT_BUCKET:
 
7749
    case OFPGC15_REMOVE_BUCKET:
 
7750
        log_property(false, "ntr selection method property is only allowed "
 
7751
                     "for add and delete group modifications");
 
7752
        return OFPERR_OFPBPC_BAD_VALUE;
 
7753
    default:
 
7754
        OVS_NOT_REACHED();
 
7755
    }
 
7756
 
 
7757
    if (payload->size < sizeof *prop) {
 
7758
        log_property(false, "ntr selection method property length "
 
7759
                     "%u is not valid", payload->size);
 
7760
        return OFPERR_OFPBPC_BAD_LEN;
 
7761
    }
 
7762
 
 
7763
    method_len = strnlen(prop->selection_method, NTR_MAX_SELECTION_METHOD_LEN);
 
7764
 
 
7765
    if (method_len == NTR_MAX_SELECTION_METHOD_LEN) {
 
7766
        log_property(false, "ntr selection method is not null terminated");
 
7767
        return OFPERR_OFPBPC_BAD_VALUE;
 
7768
    }
 
7769
 
 
7770
    if (strcmp("hash", prop->selection_method)) {
 
7771
        log_property(false, "ntr selection method '%s' is not supported",
 
7772
                     prop->selection_method);
 
7773
        return OFPERR_OFPBPC_BAD_VALUE;
 
7774
    }
 
7775
 
 
7776
    strcpy(gp->selection_method, prop->selection_method);
 
7777
    gp->selection_method_param = ntohll(prop->selection_method_param);
 
7778
 
 
7779
    if (!method_len && gp->selection_method_param) {
 
7780
        log_property(false, "ntr selection method parameter is non-zero but "
 
7781
                     "selection method is empty");
 
7782
        return OFPERR_OFPBPC_BAD_VALUE;
 
7783
    }
 
7784
 
 
7785
    ofpbuf_pull(payload, sizeof *prop);
 
7786
 
 
7787
    fields_len = ntohs(prop->length) - sizeof *prop;
 
7788
    if (!method_len && fields_len) {
 
7789
        log_property(false, "ntr selection method parameter is zero "
 
7790
                     "but fields are provided");
 
7791
        return OFPERR_OFPBPC_BAD_VALUE;
 
7792
    }
 
7793
 
 
7794
    error = oxm_pull_field_array(payload->data, fields_len,
 
7795
                                 &gp->fields);
 
7796
    if (error) {
 
7797
        log_property(false, "ntr selection method fields are invalid");
 
7798
        return error;
 
7799
    }
 
7800
 
 
7801
    return 0;
 
7802
}
 
7803
 
 
7804
static enum ofperr
 
7805
parse_group_prop_ntr(struct ofpbuf *payload, uint32_t exp_type,
 
7806
                     enum ofp11_group_type group_type,
 
7807
                     enum ofp15_group_mod_command group_cmd,
 
7808
                     struct ofputil_group_props *gp)
 
7809
{
 
7810
    enum ofperr error;
 
7811
 
 
7812
    switch (exp_type) {
 
7813
    case NTRT_SELECTION_METHOD:
 
7814
        error = parse_group_prop_ntr_selection_method(payload, group_type,
 
7815
                                                      group_cmd, gp);
 
7816
        break;
 
7817
 
 
7818
    default:
 
7819
        log_property(false, "unknown group property ntr experimenter type "
 
7820
                     "%"PRIu32, exp_type);
 
7821
        error = OFPERR_OFPBPC_BAD_TYPE;
 
7822
        break;
 
7823
    }
 
7824
 
 
7825
    return error;
 
7826
}
 
7827
 
 
7828
static enum ofperr
 
7829
parse_ofp15_group_prop_exp(struct ofpbuf *payload,
 
7830
                           enum ofp11_group_type group_type,
 
7831
                           enum ofp15_group_mod_command group_cmd,
 
7832
                           struct ofputil_group_props *gp)
 
7833
{
 
7834
    struct ofp_prop_experimenter *prop = payload->data;
 
7835
    uint16_t experimenter;
 
7836
    uint32_t exp_type;
 
7837
    enum ofperr error;
 
7838
 
 
7839
    if (payload->size < sizeof *prop) {
 
7840
        return OFPERR_OFPBPC_BAD_LEN;
 
7841
    }
 
7842
 
 
7843
    experimenter = ntohl(prop->experimenter);
 
7844
    exp_type = ntohl(prop->exp_type);
 
7845
 
 
7846
    switch (experimenter) {
 
7847
    case NTR_VENDOR_ID:
 
7848
        error = parse_group_prop_ntr(payload, exp_type, group_type,
 
7849
                                     group_cmd, gp);
 
7850
        break;
 
7851
 
 
7852
    default:
 
7853
        log_property(false, "unknown group property experimenter %"PRIu16,
 
7854
                     experimenter);
 
7855
        error = OFPERR_OFPBPC_BAD_EXPERIMENTER;
 
7856
        break;
 
7857
    }
 
7858
 
 
7859
    return error;
 
7860
}
 
7861
 
 
7862
static enum ofperr
 
7863
parse_ofp15_group_properties(struct ofpbuf *msg,
 
7864
                             enum ofp11_group_type group_type,
 
7865
                             enum ofp15_group_mod_command group_cmd,
 
7866
                             struct ofputil_group_props *gp,
 
7867
                             size_t properties_len)
 
7868
{
 
7869
    struct ofpbuf properties;
 
7870
 
 
7871
    ofpbuf_use_const(&properties, ofpbuf_pull(msg, properties_len),
 
7872
                     properties_len);
 
7873
 
 
7874
    while (properties.size > 0) {
 
7875
        struct ofpbuf payload;
 
7876
        enum ofperr error;
 
7877
        uint16_t type;
 
7878
 
 
7879
        error = ofputil_pull_property(&properties, &payload, &type);
 
7880
        if (error) {
 
7881
            return error;
 
7882
        }
 
7883
 
 
7884
        switch (type) {
 
7885
        case OFPGPT15_EXPERIMENTER:
 
7886
            error = parse_ofp15_group_prop_exp(&payload, group_type,
 
7887
                                               group_cmd, gp);
 
7888
            break;
 
7889
 
 
7890
        default:
 
7891
            log_property(false, "unknown group property %"PRIu16, type);
 
7892
            error = OFPERR_OFPBPC_BAD_TYPE;
 
7893
            break;
 
7894
        }
 
7895
 
 
7896
        if (error) {
 
7897
            return error;
 
7898
        }
 
7899
    }
 
7900
 
 
7901
    return 0;
 
7902
}
 
7903
 
 
7904
static int
 
7905
ofputil_decode_ofp11_group_desc_reply(struct ofputil_group_desc *gd,
 
7906
                                      struct ofpbuf *msg,
 
7907
                                      enum ofp_version version)
 
7908
{
 
7909
    struct ofp11_group_desc_stats *ogds;
 
7910
    size_t length;
 
7911
 
 
7912
    if (!msg->header) {
 
7913
        ofpraw_pull_assert(msg);
 
7914
    }
 
7915
 
 
7916
    if (!msg->size) {
 
7917
        return EOF;
 
7918
    }
 
7919
 
 
7920
    ogds = ofpbuf_try_pull(msg, sizeof *ogds);
 
7921
    if (!ogds) {
 
7922
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply has %"PRIu32" "
 
7923
                     "leftover bytes at end", msg->size);
 
7924
        return OFPERR_OFPBRC_BAD_LEN;
 
7925
    }
 
7926
    gd->type = ogds->type;
 
7927
    gd->group_id = ntohl(ogds->group_id);
 
7928
 
 
7929
    length = ntohs(ogds->length);
 
7930
    if (length < sizeof *ogds || length - sizeof *ogds > msg->size) {
 
7931
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply claims invalid "
 
7932
                     "length %"PRIuSIZE, length);
 
7933
        return OFPERR_OFPBRC_BAD_LEN;
 
7934
    }
 
7935
 
 
7936
    return ofputil_pull_ofp11_buckets(msg, length - sizeof *ogds, version,
 
7937
                                      &gd->buckets);
 
7938
}
 
7939
 
 
7940
static int
 
7941
ofputil_decode_ofp15_group_desc_reply(struct ofputil_group_desc *gd,
 
7942
                                      struct ofpbuf *msg,
 
7943
                                      enum ofp_version version)
 
7944
{
 
7945
    struct ofp15_group_desc_stats *ogds;
 
7946
    uint16_t length, bucket_list_len;
 
7947
    int error;
 
7948
 
 
7949
    if (!msg->header) {
 
7950
        ofpraw_pull_assert(msg);
 
7951
    }
 
7952
 
 
7953
    if (!msg->size) {
 
7954
        return EOF;
 
7955
    }
 
7956
 
 
7957
    ogds = ofpbuf_try_pull(msg, sizeof *ogds);
 
7958
    if (!ogds) {
 
7959
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply has %"PRIu32" "
 
7960
                     "leftover bytes at end", msg->size);
 
7961
        return OFPERR_OFPBRC_BAD_LEN;
 
7962
    }
 
7963
    gd->type = ogds->type;
 
7964
    gd->group_id = ntohl(ogds->group_id);
 
7965
 
 
7966
    length = ntohs(ogds->length);
 
7967
    if (length < sizeof *ogds || length - sizeof *ogds > msg->size) {
 
7968
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply claims invalid "
 
7969
                     "length %u", length);
 
7970
        return OFPERR_OFPBRC_BAD_LEN;
 
7971
    }
 
7972
 
 
7973
    bucket_list_len = ntohs(ogds->bucket_list_len);
 
7974
    if (length < bucket_list_len + sizeof *ogds) {
 
7975
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply claims invalid "
 
7976
                     "bucket list length %u", bucket_list_len);
 
7977
        return OFPERR_OFPBRC_BAD_LEN;
 
7978
    }
 
7979
    error = ofputil_pull_ofp15_buckets(msg, bucket_list_len, version, gd->type,
 
7980
                                       &gd->buckets);
 
7981
    if (error) {
 
7982
        return error;
 
7983
    }
 
7984
 
 
7985
    /* By definition group desc messages don't have a group mod command.
 
7986
     * However, parse_group_prop_ntr_selection_method() checks to make sure
 
7987
     * that the command is OFPGC15_ADD or OFPGC15_DELETE to guard
 
7988
     * against group mod messages with other commands supplying
 
7989
     * a NTR selection method group experimenter property.
 
7990
     * Such properties are valid for group desc replies so
 
7991
     * claim that the group mod command is OFPGC15_ADD to
 
7992
     * satisfy the check in parse_group_prop_ntr_selection_method() */
 
7993
    return parse_ofp15_group_properties(msg, gd->type, OFPGC15_ADD, &gd->props,
 
7994
                                        msg->size);
7030
7995
}
7031
7996
 
7032
7997
/* Converts a group description reply in 'msg' into an abstract
7043
8008
ofputil_decode_group_desc_reply(struct ofputil_group_desc *gd,
7044
8009
                                struct ofpbuf *msg, enum ofp_version version)
7045
8010
{
7046
 
    struct ofp11_group_desc_stats *ogds;
7047
 
    size_t length;
7048
 
 
7049
 
    if (!msg->frame) {
7050
 
        ofpraw_pull_assert(msg);
7051
 
    }
7052
 
 
7053
 
    if (!ofpbuf_size(msg)) {
7054
 
        return EOF;
7055
 
    }
7056
 
 
7057
 
    ogds = ofpbuf_try_pull(msg, sizeof *ogds);
7058
 
    if (!ogds) {
7059
 
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply has %"PRIu32" "
7060
 
                     "leftover bytes at end", ofpbuf_size(msg));
7061
 
        return OFPERR_OFPBRC_BAD_LEN;
7062
 
    }
7063
 
    gd->type = ogds->type;
7064
 
    gd->group_id = ntohl(ogds->group_id);
7065
 
 
7066
 
    length = ntohs(ogds->length);
7067
 
    if (length < sizeof *ogds || length - sizeof *ogds > ofpbuf_size(msg)) {
7068
 
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply claims invalid "
7069
 
                     "length %"PRIuSIZE, length);
7070
 
        return OFPERR_OFPBRC_BAD_LEN;
7071
 
    }
7072
 
 
7073
 
    return ofputil_pull_buckets(msg, length - sizeof *ogds, version,
7074
 
                                &gd->buckets);
 
8011
    ofputil_init_group_properties(&gd->props);
 
8012
 
 
8013
    switch (version)
 
8014
    {
 
8015
    case OFP11_VERSION:
 
8016
    case OFP12_VERSION:
 
8017
    case OFP13_VERSION:
 
8018
    case OFP14_VERSION:
 
8019
        return ofputil_decode_ofp11_group_desc_reply(gd, msg, version);
 
8020
 
 
8021
    case OFP15_VERSION:
 
8022
        return ofputil_decode_ofp15_group_desc_reply(gd, msg, version);
 
8023
 
 
8024
    case OFP10_VERSION:
 
8025
    default:
 
8026
        OVS_NOT_REACHED();
 
8027
    }
 
8028
}
 
8029
 
 
8030
void
 
8031
ofputil_uninit_group_mod(struct ofputil_group_mod *gm)
 
8032
{
 
8033
    ofputil_bucket_list_destroy(&gm->buckets);
 
8034
}
 
8035
 
 
8036
static struct ofpbuf *
 
8037
ofputil_encode_ofp11_group_mod(enum ofp_version ofp_version,
 
8038
                               const struct ofputil_group_mod *gm)
 
8039
{
 
8040
    struct ofpbuf *b;
 
8041
    struct ofp11_group_mod *ogm;
 
8042
    size_t start_ogm;
 
8043
    struct ofputil_bucket *bucket;
 
8044
 
 
8045
    b = ofpraw_alloc(OFPRAW_OFPT11_GROUP_MOD, ofp_version, 0);
 
8046
    start_ogm = b->size;
 
8047
    ofpbuf_put_zeros(b, sizeof *ogm);
 
8048
 
 
8049
    LIST_FOR_EACH (bucket, list_node, &gm->buckets) {
 
8050
        ofputil_put_ofp11_bucket(bucket, b, ofp_version);
 
8051
    }
 
8052
    ogm = ofpbuf_at_assert(b, start_ogm, sizeof *ogm);
 
8053
    ogm->command = htons(gm->command);
 
8054
    ogm->type = gm->type;
 
8055
    ogm->group_id = htonl(gm->group_id);
 
8056
 
 
8057
    return b;
 
8058
}
 
8059
 
 
8060
static struct ofpbuf *
 
8061
ofputil_encode_ofp15_group_mod(enum ofp_version ofp_version,
 
8062
                               const struct ofputil_group_mod *gm)
 
8063
{
 
8064
    struct ofpbuf *b;
 
8065
    struct ofp15_group_mod *ogm;
 
8066
    size_t start_ogm;
 
8067
    struct ofputil_bucket *bucket;
 
8068
    struct id_pool *bucket_ids = NULL;
 
8069
 
 
8070
    b = ofpraw_alloc(OFPRAW_OFPT15_GROUP_MOD, ofp_version, 0);
 
8071
    start_ogm = b->size;
 
8072
    ofpbuf_put_zeros(b, sizeof *ogm);
 
8073
 
 
8074
    LIST_FOR_EACH (bucket, list_node, &gm->buckets) {
 
8075
        uint32_t bucket_id;
 
8076
 
 
8077
        /* Generate a bucket id if none was supplied */
 
8078
        if (bucket->bucket_id > OFPG15_BUCKET_MAX) {
 
8079
            if (!bucket_ids) {
 
8080
                const struct ofputil_bucket *bkt;
 
8081
 
 
8082
                bucket_ids = id_pool_create(0, OFPG15_BUCKET_MAX + 1);
 
8083
 
 
8084
                /* Mark all bucket_ids that are present in gm
 
8085
                 * as used in the pool. */
 
8086
                LIST_FOR_EACH_REVERSE (bkt, list_node, &gm->buckets) {
 
8087
                    if (bkt == bucket) {
 
8088
                        break;
 
8089
                    }
 
8090
                    if (bkt->bucket_id <= OFPG15_BUCKET_MAX) {
 
8091
                        id_pool_add(bucket_ids, bkt->bucket_id);
 
8092
                    }
 
8093
                }
 
8094
            }
 
8095
 
 
8096
            if (!id_pool_alloc_id(bucket_ids, &bucket_id)) {
 
8097
                OVS_NOT_REACHED();
 
8098
            }
 
8099
        } else {
 
8100
            bucket_id = bucket->bucket_id;
 
8101
        }
 
8102
 
 
8103
        ofputil_put_ofp15_bucket(bucket, bucket_id, gm->type, b, ofp_version);
 
8104
    }
 
8105
    ogm = ofpbuf_at_assert(b, start_ogm, sizeof *ogm);
 
8106
    ogm->command = htons(gm->command);
 
8107
    ogm->type = gm->type;
 
8108
    ogm->group_id = htonl(gm->group_id);
 
8109
    ogm->command_bucket_id = htonl(gm->command_bucket_id);
 
8110
    ogm->bucket_array_len = htons(b->size - start_ogm - sizeof *ogm);
 
8111
 
 
8112
    /* Add group properties */
 
8113
    if (gm->props.selection_method[0]) {
 
8114
        ofputil_put_group_prop_ntr_selection_method(ofp_version, &gm->props, b);
 
8115
    }
 
8116
 
 
8117
    id_pool_destroy(bucket_ids);
 
8118
    return b;
 
8119
}
 
8120
 
 
8121
static void
 
8122
bad_group_cmd(enum ofp15_group_mod_command cmd)
 
8123
{
 
8124
    const char *opt_version;
 
8125
    const char *version;
 
8126
    const char *cmd_str;
 
8127
 
 
8128
    switch (cmd) {
 
8129
    case OFPGC15_ADD:
 
8130
    case OFPGC15_MODIFY:
 
8131
    case OFPGC15_DELETE:
 
8132
        version = "1.1";
 
8133
        opt_version = "11";
 
8134
        break;
 
8135
 
 
8136
    case OFPGC15_INSERT_BUCKET:
 
8137
    case OFPGC15_REMOVE_BUCKET:
 
8138
        version = "1.5";
 
8139
        opt_version = "15";
 
8140
        break;
 
8141
 
 
8142
    default:
 
8143
        OVS_NOT_REACHED();
 
8144
    }
 
8145
 
 
8146
    switch (cmd) {
 
8147
    case OFPGC15_ADD:
 
8148
        cmd_str = "add-group";
 
8149
        break;
 
8150
 
 
8151
    case OFPGC15_MODIFY:
 
8152
        cmd_str = "mod-group";
 
8153
        break;
 
8154
 
 
8155
    case OFPGC15_DELETE:
 
8156
        cmd_str = "del-group";
 
8157
        break;
 
8158
 
 
8159
    case OFPGC15_INSERT_BUCKET:
 
8160
        cmd_str = "insert-bucket";
 
8161
        break;
 
8162
 
 
8163
    case OFPGC15_REMOVE_BUCKET:
 
8164
        cmd_str = "remove-bucket";
 
8165
        break;
 
8166
 
 
8167
    default:
 
8168
        OVS_NOT_REACHED();
 
8169
    }
 
8170
 
 
8171
    ovs_fatal(0, "%s needs OpenFlow %s or later (\'-O OpenFlow%s\')",
 
8172
              cmd_str, version, opt_version);
 
8173
 
7075
8174
}
7076
8175
 
7077
8176
/* Converts abstract group mod 'gm' into a message for OpenFlow version
7080
8179
ofputil_encode_group_mod(enum ofp_version ofp_version,
7081
8180
                         const struct ofputil_group_mod *gm)
7082
8181
{
7083
 
    struct ofpbuf *b;
7084
 
    struct ofp11_group_mod *ogm;
7085
 
    size_t start_ogm;
7086
 
    size_t start_bucket;
7087
 
    struct ofputil_bucket *bucket;
7088
 
    struct ofp11_bucket *ob;
7089
8182
 
7090
8183
    switch (ofp_version) {
7091
 
    case OFP10_VERSION: {
7092
 
        if (gm->command == OFPGC11_ADD) {
7093
 
            ovs_fatal(0, "add-group needs OpenFlow 1.1 or later "
7094
 
                         "(\'-O OpenFlow11\')");
7095
 
        } else if (gm->command == OFPGC11_MODIFY) {
7096
 
            ovs_fatal(0, "mod-group needs OpenFlow 1.1 or later "
7097
 
                         "(\'-O OpenFlow11\')");
7098
 
        } else {
7099
 
            ovs_fatal(0, "del-groups needs OpenFlow 1.1 or later "
7100
 
                         "(\'-O OpenFlow11\')");
7101
 
        }
7102
 
    }
 
8184
    case OFP10_VERSION:
 
8185
        bad_group_cmd(gm->command);
7103
8186
 
7104
8187
    case OFP11_VERSION:
7105
8188
    case OFP12_VERSION:
7106
8189
    case OFP13_VERSION:
7107
8190
    case OFP14_VERSION:
 
8191
        if (gm->command > OFPGC11_DELETE) {
 
8192
            bad_group_cmd(gm->command);
 
8193
        }
 
8194
        return ofputil_encode_ofp11_group_mod(ofp_version, gm);
 
8195
 
7108
8196
    case OFP15_VERSION:
7109
 
        b = ofpraw_alloc(OFPRAW_OFPT11_GROUP_MOD, ofp_version, 0);
7110
 
        start_ogm = ofpbuf_size(b);
7111
 
        ofpbuf_put_zeros(b, sizeof *ogm);
7112
 
 
7113
 
        LIST_FOR_EACH (bucket, list_node, &gm->buckets) {
7114
 
            start_bucket = ofpbuf_size(b);
7115
 
            ofpbuf_put_zeros(b, sizeof *ob);
7116
 
            if (bucket->ofpacts && bucket->ofpacts_len) {
7117
 
                ofpacts_put_openflow_actions(bucket->ofpacts,
7118
 
                                             bucket->ofpacts_len, b,
7119
 
                                             ofp_version);
7120
 
            }
7121
 
            ob = ofpbuf_at_assert(b, start_bucket, sizeof *ob);
7122
 
            ob->len = htons(ofpbuf_size(b) - start_bucket);;
7123
 
            ob->weight = htons(bucket->weight);
7124
 
            ob->watch_port = ofputil_port_to_ofp11(bucket->watch_port);
7125
 
            ob->watch_group = htonl(bucket->watch_group);
7126
 
        }
7127
 
        ogm = ofpbuf_at_assert(b, start_ogm, sizeof *ogm);
7128
 
        ogm->command = htons(gm->command);
7129
 
        ogm->type = gm->type;
7130
 
        ogm->group_id = htonl(gm->group_id);
7131
 
 
7132
 
        break;
 
8197
        return ofputil_encode_ofp15_group_mod(ofp_version, gm);
7133
8198
 
7134
8199
    default:
7135
8200
        OVS_NOT_REACHED();
7136
8201
    }
7137
 
 
7138
 
    return b;
 
8202
}
 
8203
 
 
8204
static enum ofperr
 
8205
ofputil_pull_ofp11_group_mod(struct ofpbuf *msg, enum ofp_version ofp_version,
 
8206
                             struct ofputil_group_mod *gm)
 
8207
{
 
8208
    const struct ofp11_group_mod *ogm;
 
8209
    enum ofperr error;
 
8210
 
 
8211
    ogm = ofpbuf_pull(msg, sizeof *ogm);
 
8212
    gm->command = ntohs(ogm->command);
 
8213
    gm->type = ogm->type;
 
8214
    gm->group_id = ntohl(ogm->group_id);
 
8215
    gm->command_bucket_id = OFPG15_BUCKET_ALL;
 
8216
 
 
8217
    error = ofputil_pull_ofp11_buckets(msg, msg->size, ofp_version,
 
8218
                                       &gm->buckets);
 
8219
 
 
8220
    /* OF1.3.5+ prescribes an error when an OFPGC_DELETE includes buckets. */
 
8221
    if (!error
 
8222
        && ofp_version >= OFP13_VERSION
 
8223
        && gm->command == OFPGC11_DELETE
 
8224
        && !list_is_empty(&gm->buckets)) {
 
8225
        error = OFPERR_OFPGMFC_INVALID_GROUP;
 
8226
    }
 
8227
 
 
8228
    return error;
 
8229
}
 
8230
 
 
8231
static enum ofperr
 
8232
ofputil_pull_ofp15_group_mod(struct ofpbuf *msg, enum ofp_version ofp_version,
 
8233
                             struct ofputil_group_mod *gm)
 
8234
{
 
8235
    const struct ofp15_group_mod *ogm;
 
8236
    uint16_t bucket_list_len;
 
8237
    enum ofperr error = OFPERR_OFPGMFC_BAD_BUCKET;
 
8238
 
 
8239
    ogm = ofpbuf_pull(msg, sizeof *ogm);
 
8240
    gm->command = ntohs(ogm->command);
 
8241
    gm->type = ogm->type;
 
8242
    gm->group_id = ntohl(ogm->group_id);
 
8243
 
 
8244
    gm->command_bucket_id = ntohl(ogm->command_bucket_id);
 
8245
    switch (gm->command) {
 
8246
    case OFPGC15_REMOVE_BUCKET:
 
8247
        if (gm->command_bucket_id == OFPG15_BUCKET_ALL) {
 
8248
            error = 0;
 
8249
        }
 
8250
        /* Fall through */
 
8251
    case OFPGC15_INSERT_BUCKET:
 
8252
        if (gm->command_bucket_id <= OFPG15_BUCKET_MAX ||
 
8253
            gm->command_bucket_id == OFPG15_BUCKET_FIRST
 
8254
            || gm->command_bucket_id == OFPG15_BUCKET_LAST) {
 
8255
            error = 0;
 
8256
        }
 
8257
        break;
 
8258
 
 
8259
    case OFPGC11_ADD:
 
8260
    case OFPGC11_MODIFY:
 
8261
    case OFPGC11_DELETE:
 
8262
    default:
 
8263
        if (gm->command_bucket_id == OFPG15_BUCKET_ALL) {
 
8264
            error = 0;
 
8265
        }
 
8266
        break;
 
8267
    }
 
8268
    if (error) {
 
8269
        VLOG_WARN_RL(&bad_ofmsg_rl,
 
8270
                     "group command bucket id (%u) is out of range",
 
8271
                     gm->command_bucket_id);
 
8272
        return OFPERR_OFPGMFC_BAD_BUCKET;
 
8273
    }
 
8274
 
 
8275
    bucket_list_len = ntohs(ogm->bucket_array_len);
 
8276
    error = ofputil_pull_ofp15_buckets(msg, bucket_list_len, ofp_version,
 
8277
                                       gm->type, &gm->buckets);
 
8278
    if (error) {
 
8279
        return error;
 
8280
    }
 
8281
 
 
8282
    return parse_ofp15_group_properties(msg, gm->type, gm->command, &gm->props,
 
8283
                                        msg->size);
7139
8284
}
7140
8285
 
7141
8286
/* Converts OpenFlow group mod message 'oh' into an abstract group mod in
7144
8289
ofputil_decode_group_mod(const struct ofp_header *oh,
7145
8290
                         struct ofputil_group_mod *gm)
7146
8291
{
7147
 
    const struct ofp11_group_mod *ogm;
 
8292
    enum ofp_version ofp_version = oh->version;
7148
8293
    struct ofpbuf msg;
7149
8294
    struct ofputil_bucket *bucket;
7150
8295
    enum ofperr err;
7152
8297
    ofpbuf_use_const(&msg, oh, ntohs(oh->length));
7153
8298
    ofpraw_pull_assert(&msg);
7154
8299
 
7155
 
    ogm = ofpbuf_pull(&msg, sizeof *ogm);
7156
 
    gm->command = ntohs(ogm->command);
7157
 
    gm->type = ogm->type;
7158
 
    gm->group_id = ntohl(ogm->group_id);
7159
 
 
7160
 
    err = ofputil_pull_buckets(&msg, ofpbuf_size(&msg), oh->version, &gm->buckets);
 
8300
    ofputil_init_group_properties(&gm->props);
 
8301
 
 
8302
    switch (ofp_version)
 
8303
    {
 
8304
    case OFP11_VERSION:
 
8305
    case OFP12_VERSION:
 
8306
    case OFP13_VERSION:
 
8307
    case OFP14_VERSION:
 
8308
        err = ofputil_pull_ofp11_group_mod(&msg, ofp_version, gm);
 
8309
        break;
 
8310
 
 
8311
    case OFP15_VERSION:
 
8312
        err = ofputil_pull_ofp15_group_mod(&msg, ofp_version, gm);
 
8313
        break;
 
8314
 
 
8315
    case OFP10_VERSION:
 
8316
    default:
 
8317
        OVS_NOT_REACHED();
 
8318
    }
 
8319
 
7161
8320
    if (err) {
7162
8321
        return err;
7163
8322
    }
7164
8323
 
 
8324
    switch (gm->type) {
 
8325
    case OFPGT11_INDIRECT:
 
8326
        if (!list_is_singleton(&gm->buckets)) {
 
8327
            return OFPERR_OFPGMFC_OUT_OF_BUCKETS;
 
8328
        }
 
8329
        break;
 
8330
    case OFPGT11_ALL:
 
8331
    case OFPGT11_SELECT:
 
8332
    case OFPGT11_FF:
 
8333
        break;
 
8334
    default:
 
8335
        OVS_NOT_REACHED();
 
8336
    }
 
8337
 
 
8338
    switch (gm->command) {
 
8339
    case OFPGC11_ADD:
 
8340
    case OFPGC11_MODIFY:
 
8341
    case OFPGC11_DELETE:
 
8342
    case OFPGC15_INSERT_BUCKET:
 
8343
        break;
 
8344
    case OFPGC15_REMOVE_BUCKET:
 
8345
        if (!list_is_empty(&gm->buckets)) {
 
8346
            return OFPERR_OFPGMFC_BAD_BUCKET;
 
8347
        }
 
8348
        break;
 
8349
    default:
 
8350
        OVS_NOT_REACHED();
 
8351
    }
 
8352
 
7165
8353
    LIST_FOR_EACH (bucket, list_node, &gm->buckets) {
 
8354
        if (bucket->weight && gm->type != OFPGT11_SELECT) {
 
8355
            return OFPERR_OFPGMFC_INVALID_GROUP;
 
8356
        }
 
8357
 
7166
8358
        switch (gm->type) {
7167
8359
        case OFPGT11_ALL:
7168
8360
        case OFPGT11_INDIRECT:
7218
8410
    }
7219
8411
}
7220
8412
 
7221
 
/* Encode a queue statsrequest for 'oqsr', the encoded message
7222
 
 * will be fore Open Flow version 'ofp_version'. Returns message
7223
 
 * as a struct ofpbuf. Returns encoded message on success, NULL on error */
 
8413
/* Encode a queue stats request for 'oqsr', the encoded message
 
8414
 * will be for OpenFlow version 'ofp_version'. Returns message
 
8415
 * as a struct ofpbuf. Returns encoded message on success, NULL on error. */
7224
8416
struct ofpbuf *
7225
8417
ofputil_encode_queue_stats_request(enum ofp_version ofp_version,
7226
8418
                                   const struct ofputil_queue_stats_request *oqsr)
7334
8526
    }
7335
8527
 
7336
8528
    len = ntohs(qs14->length);
7337
 
    if (len < sizeof *qs14 || len - sizeof *qs14 > ofpbuf_size(msg)) {
 
8529
    if (len < sizeof *qs14 || len - sizeof *qs14 > msg->size) {
7338
8530
        return OFPERR_OFPBRC_BAD_LEN;
7339
8531
    }
7340
8532
    ofpbuf_pull(msg, len - sizeof *qs14);
7360
8552
    enum ofperr error;
7361
8553
    enum ofpraw raw;
7362
8554
 
7363
 
    error = (msg->frame
7364
 
             ? ofpraw_decode(&raw, msg->frame)
 
8555
    error = (msg->header ? ofpraw_decode(&raw, msg->header)
7365
8556
             : ofpraw_pull(&raw, msg));
7366
8557
    if (error) {
7367
8558
        return error;
7368
8559
    }
7369
8560
 
7370
 
    if (!ofpbuf_size(msg)) {
 
8561
    if (!msg->size) {
7371
8562
        return EOF;
7372
8563
    } else if (raw == OFPRAW_OFPST14_QUEUE_REPLY) {
7373
8564
        return ofputil_pull_ofp14_queue_stats(qs, msg);
7401
8592
 
7402
8593
 bad_len:
7403
8594
    VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_QUEUE reply has %"PRIu32" leftover "
7404
 
                 "bytes at end", ofpbuf_size(msg));
 
8595
                 "bytes at end", msg->size);
7405
8596
    return OFPERR_OFPBRC_BAD_LEN;
7406
8597
}
7407
8598
 
7454
8645
 
7455
8646
/* Encode a queue stat for 'oqs' and append it to 'replies'. */
7456
8647
void
7457
 
ofputil_append_queue_stat(struct list *replies,
 
8648
ofputil_append_queue_stat(struct ovs_list *replies,
7458
8649
                          const struct ofputil_queue_stats *oqs)
7459
8650
{
7460
8651
    switch (ofpmp_version(replies)) {
7501
8692
    raw = ofpraw_pull_assert(&b);
7502
8693
    ovs_assert(raw == OFPRAW_OFPT14_BUNDLE_CONTROL);
7503
8694
 
7504
 
    m = ofpbuf_l3(&b);
 
8695
    m = b.msg;
7505
8696
    msg->bundle_id = ntohl(m->bundle_id);
7506
8697
    msg->type = ntohs(m->type);
7507
8698
    msg->flags = ntohs(m->flags);
7510
8701
}
7511
8702
 
7512
8703
struct ofpbuf *
 
8704
ofputil_encode_bundle_ctrl_request(enum ofp_version ofp_version,
 
8705
                                   struct ofputil_bundle_ctrl_msg *bc)
 
8706
{
 
8707
    struct ofpbuf *request;
 
8708
    struct ofp14_bundle_ctrl_msg *m;
 
8709
 
 
8710
    switch (ofp_version) {
 
8711
    case OFP10_VERSION:
 
8712
    case OFP11_VERSION:
 
8713
    case OFP12_VERSION:
 
8714
    case OFP13_VERSION:
 
8715
        ovs_fatal(0, "bundles need OpenFlow 1.4 or later "
 
8716
                     "(\'-O OpenFlow14\')");
 
8717
    case OFP14_VERSION:
 
8718
    case OFP15_VERSION:
 
8719
        request = ofpraw_alloc(OFPRAW_OFPT14_BUNDLE_CONTROL, ofp_version, 0);
 
8720
        m = ofpbuf_put_zeros(request, sizeof *m);
 
8721
 
 
8722
        m->bundle_id = htonl(bc->bundle_id);
 
8723
        m->type = htons(bc->type);
 
8724
        m->flags = htons(bc->flags);
 
8725
        break;
 
8726
    default:
 
8727
        OVS_NOT_REACHED();
 
8728
    }
 
8729
 
 
8730
    return request;
 
8731
}
 
8732
 
 
8733
struct ofpbuf *
7513
8734
ofputil_encode_bundle_ctrl_reply(const struct ofp_header *oh,
7514
8735
                                 struct ofputil_bundle_ctrl_msg *msg)
7515
8736
{
7526
8747
    return buf;
7527
8748
}
7528
8749
 
 
8750
/* Return true for bundlable state change requests, false for other messages.
 
8751
 */
 
8752
static bool
 
8753
ofputil_is_bundlable(enum ofptype type)
 
8754
{
 
8755
    switch (type) {
 
8756
        /* Minimum required by OpenFlow 1.4. */
 
8757
    case OFPTYPE_PORT_MOD:
 
8758
    case OFPTYPE_FLOW_MOD:
 
8759
        return true;
 
8760
 
 
8761
        /* Nice to have later. */
 
8762
    case OFPTYPE_FLOW_MOD_TABLE_ID:
 
8763
    case OFPTYPE_GROUP_MOD:
 
8764
    case OFPTYPE_TABLE_MOD:
 
8765
    case OFPTYPE_METER_MOD:
 
8766
    case OFPTYPE_PACKET_OUT:
 
8767
 
 
8768
        /* Not to be bundlable. */
 
8769
    case OFPTYPE_ECHO_REQUEST:
 
8770
    case OFPTYPE_FEATURES_REQUEST:
 
8771
    case OFPTYPE_GET_CONFIG_REQUEST:
 
8772
    case OFPTYPE_SET_CONFIG:
 
8773
    case OFPTYPE_BARRIER_REQUEST:
 
8774
    case OFPTYPE_ROLE_REQUEST:
 
8775
    case OFPTYPE_ECHO_REPLY:
 
8776
    case OFPTYPE_SET_FLOW_FORMAT:
 
8777
    case OFPTYPE_SET_PACKET_IN_FORMAT:
 
8778
    case OFPTYPE_SET_CONTROLLER_ID:
 
8779
    case OFPTYPE_FLOW_AGE:
 
8780
    case OFPTYPE_FLOW_MONITOR_CANCEL:
 
8781
    case OFPTYPE_SET_ASYNC_CONFIG:
 
8782
    case OFPTYPE_GET_ASYNC_REQUEST:
 
8783
    case OFPTYPE_DESC_STATS_REQUEST:
 
8784
    case OFPTYPE_FLOW_STATS_REQUEST:
 
8785
    case OFPTYPE_AGGREGATE_STATS_REQUEST:
 
8786
    case OFPTYPE_TABLE_STATS_REQUEST:
 
8787
    case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
 
8788
    case OFPTYPE_PORT_STATS_REQUEST:
 
8789
    case OFPTYPE_QUEUE_STATS_REQUEST:
 
8790
    case OFPTYPE_PORT_DESC_STATS_REQUEST:
 
8791
    case OFPTYPE_FLOW_MONITOR_STATS_REQUEST:
 
8792
    case OFPTYPE_METER_STATS_REQUEST:
 
8793
    case OFPTYPE_METER_CONFIG_STATS_REQUEST:
 
8794
    case OFPTYPE_METER_FEATURES_STATS_REQUEST:
 
8795
    case OFPTYPE_GROUP_STATS_REQUEST:
 
8796
    case OFPTYPE_GROUP_DESC_STATS_REQUEST:
 
8797
    case OFPTYPE_GROUP_FEATURES_STATS_REQUEST:
 
8798
    case OFPTYPE_QUEUE_GET_CONFIG_REQUEST:
 
8799
    case OFPTYPE_BUNDLE_CONTROL:
 
8800
    case OFPTYPE_BUNDLE_ADD_MESSAGE:
 
8801
    case OFPTYPE_HELLO:
 
8802
    case OFPTYPE_ERROR:
 
8803
    case OFPTYPE_FEATURES_REPLY:
 
8804
    case OFPTYPE_GET_CONFIG_REPLY:
 
8805
    case OFPTYPE_PACKET_IN:
 
8806
    case OFPTYPE_FLOW_REMOVED:
 
8807
    case OFPTYPE_PORT_STATUS:
 
8808
    case OFPTYPE_BARRIER_REPLY:
 
8809
    case OFPTYPE_QUEUE_GET_CONFIG_REPLY:
 
8810
    case OFPTYPE_DESC_STATS_REPLY:
 
8811
    case OFPTYPE_FLOW_STATS_REPLY:
 
8812
    case OFPTYPE_QUEUE_STATS_REPLY:
 
8813
    case OFPTYPE_PORT_STATS_REPLY:
 
8814
    case OFPTYPE_TABLE_STATS_REPLY:
 
8815
    case OFPTYPE_AGGREGATE_STATS_REPLY:
 
8816
    case OFPTYPE_PORT_DESC_STATS_REPLY:
 
8817
    case OFPTYPE_ROLE_REPLY:
 
8818
    case OFPTYPE_FLOW_MONITOR_PAUSED:
 
8819
    case OFPTYPE_FLOW_MONITOR_RESUMED:
 
8820
    case OFPTYPE_FLOW_MONITOR_STATS_REPLY:
 
8821
    case OFPTYPE_GET_ASYNC_REPLY:
 
8822
    case OFPTYPE_GROUP_STATS_REPLY:
 
8823
    case OFPTYPE_GROUP_DESC_STATS_REPLY:
 
8824
    case OFPTYPE_GROUP_FEATURES_STATS_REPLY:
 
8825
    case OFPTYPE_METER_STATS_REPLY:
 
8826
    case OFPTYPE_METER_CONFIG_STATS_REPLY:
 
8827
    case OFPTYPE_METER_FEATURES_STATS_REPLY:
 
8828
    case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
 
8829
    case OFPTYPE_ROLE_STATUS:
 
8830
        break;
 
8831
    }
 
8832
 
 
8833
    return false;
 
8834
}
 
8835
 
7529
8836
enum ofperr
7530
8837
ofputil_decode_bundle_add(const struct ofp_header *oh,
7531
 
                          struct ofputil_bundle_add_msg *msg)
 
8838
                          struct ofputil_bundle_add_msg *msg,
 
8839
                          enum ofptype *type_ptr)
7532
8840
{
7533
8841
    const struct ofp14_bundle_ctrl_msg *m;
7534
8842
    struct ofpbuf b;
7535
8843
    enum ofpraw raw;
7536
8844
    size_t inner_len;
 
8845
    enum ofperr error;
 
8846
    enum ofptype type;
7537
8847
 
7538
8848
    ofpbuf_use_const(&b, oh, ntohs(oh->length));
7539
8849
    raw = ofpraw_pull_assert(&b);
7543
8853
    msg->bundle_id = ntohl(m->bundle_id);
7544
8854
    msg->flags = ntohs(m->flags);
7545
8855
 
7546
 
    msg->msg = ofpbuf_data(&b);
 
8856
    msg->msg = b.data;
 
8857
    if (msg->msg->version != oh->version) {
 
8858
        return OFPERR_NXBFC_BAD_VERSION;
 
8859
    }
7547
8860
    inner_len = ntohs(msg->msg->length);
7548
 
    if (inner_len < sizeof(struct ofp_header) || inner_len > ofpbuf_size(&b)) {
 
8861
    if (inner_len < sizeof(struct ofp_header) || inner_len > b.size) {
7549
8862
        return OFPERR_OFPBFC_MSG_BAD_LEN;
7550
8863
    }
 
8864
    if (msg->msg->xid != oh->xid) {
 
8865
        return OFPERR_OFPBFC_MSG_BAD_XID;
 
8866
    }
 
8867
 
 
8868
    /* Reject unbundlable messages. */
 
8869
    if (!type_ptr) {
 
8870
        type_ptr = &type;
 
8871
    }
 
8872
    error = ofptype_decode(type_ptr, msg->msg);
 
8873
    if (error) {
 
8874
        VLOG_WARN_RL(&bad_ofmsg_rl, "OFPT14_BUNDLE_ADD_MESSAGE contained "
 
8875
                     "message is unparsable (%s)", ofperr_get_name(error));
 
8876
        return OFPERR_OFPBFC_MSG_UNSUP; /* 'error' would be confusing. */
 
8877
    }
 
8878
 
 
8879
    if (!ofputil_is_bundlable(*type_ptr)) {
 
8880
        return OFPERR_OFPBFC_MSG_UNSUP;
 
8881
    }
7551
8882
 
7552
8883
    return 0;
7553
8884
}
7559
8890
    struct ofpbuf *request;
7560
8891
    struct ofp14_bundle_ctrl_msg *m;
7561
8892
 
7562
 
    request = ofpraw_alloc(OFPRAW_OFPT14_BUNDLE_ADD_MESSAGE, ofp_version, 0);
 
8893
    /* Must use the same xid as the embedded message. */
 
8894
    request = ofpraw_alloc_xid(OFPRAW_OFPT14_BUNDLE_ADD_MESSAGE, ofp_version,
 
8895
                               msg->msg->xid, 0);
7563
8896
    m = ofpbuf_put_zeros(request, sizeof *m);
7564
8897
 
7565
8898
    m->bundle_id = htonl(msg->bundle_id);