]> git.proxmox.com Git - mirror_ovs.git/blame - lib/ofp-util.c
Support matching and modifying IP ECN bits.
[mirror_ovs.git] / lib / ofp-util.c
CommitLineData
fa37b408 1/*
dc4762ed 2 * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
fa37b408
BP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <config.h>
18#include "ofp-print.h"
dc4762ed 19#include <errno.h>
fa37b408 20#include <inttypes.h>
6ca00f6f
ETN
21#include <sys/types.h>
22#include <netinet/in.h>
b459a924 23#include <netinet/icmp6.h>
fa37b408 24#include <stdlib.h>
3b6a2571 25#include "autopath.h"
daff3353 26#include "bundle.h"
10a24935 27#include "byte-order.h"
d8ae4d67 28#include "classifier.h"
dc4762ed 29#include "dynamic-string.h"
75a75043 30#include "learn.h"
53ddd40a 31#include "multipath.h"
b6c9e612 32#include "nx-match.h"
dc4762ed 33#include "ofp-errors.h"
fa37b408
BP
34#include "ofp-util.h"
35#include "ofpbuf.h"
36#include "packets.h"
37#include "random.h"
4ffd1b43 38#include "unaligned.h"
e41a9130 39#include "type-props.h"
5136ce49 40#include "vlog.h"
fa37b408 41
d98e6007 42VLOG_DEFINE_THIS_MODULE(ofp_util);
fa37b408
BP
43
44/* Rate limit for OpenFlow message parse errors. These always indicate a bug
45 * in the peer and so there's not much point in showing a lot of them. */
46static struct vlog_rate_limit bad_ofmsg_rl = VLOG_RATE_LIMIT_INIT(1, 5);
47
0596e897
BP
48/* Given the wildcard bit count in the least-significant 6 of 'wcbits', returns
49 * an IP netmask with a 1 in each bit that must match and a 0 in each bit that
50 * is wildcarded.
51 *
52 * The bits in 'wcbits' are in the format used in enum ofp_flow_wildcards: 0
53 * is exact match, 1 ignores the LSB, 2 ignores the 2 least-significant bits,
54 * ..., 32 and higher wildcard the entire field. This is the *opposite* of the
55 * usual convention where e.g. /24 indicates that 8 bits (not 24 bits) are
56 * wildcarded. */
57ovs_be32
58ofputil_wcbits_to_netmask(int wcbits)
59{
60 wcbits &= 0x3f;
61 return wcbits < 32 ? htonl(~((1u << wcbits) - 1)) : 0;
62}
63
64/* Given the IP netmask 'netmask', returns the number of bits of the IP address
aad29cd1
BP
65 * that it wildcards, that is, the number of 0-bits in 'netmask'. 'netmask'
66 * must be a CIDR netmask (see ip_is_cidr()). */
0596e897
BP
67int
68ofputil_netmask_to_wcbits(ovs_be32 netmask)
69{
aad29cd1 70 return 32 - ip_count_cidr_bits(netmask);
0596e897
BP
71}
72
d8ae4d67
BP
73/* A list of the FWW_* and OFPFW_ bits that have the same value, meaning, and
74 * name. */
75#define WC_INVARIANT_LIST \
76 WC_INVARIANT_BIT(IN_PORT) \
d8ae4d67
BP
77 WC_INVARIANT_BIT(DL_SRC) \
78 WC_INVARIANT_BIT(DL_DST) \
79 WC_INVARIANT_BIT(DL_TYPE) \
80 WC_INVARIANT_BIT(NW_PROTO) \
81 WC_INVARIANT_BIT(TP_SRC) \
82 WC_INVARIANT_BIT(TP_DST)
83
84/* Verify that all of the invariant bits (as defined on WC_INVARIANT_LIST)
85 * actually have the same names and values. */
86#define WC_INVARIANT_BIT(NAME) BUILD_ASSERT_DECL(FWW_##NAME == OFPFW_##NAME);
87 WC_INVARIANT_LIST
88#undef WC_INVARIANT_BIT
89
90/* WC_INVARIANTS is the invariant bits (as defined on WC_INVARIANT_LIST) all
91 * OR'd together. */
eeba8e4f 92static const flow_wildcards_t WC_INVARIANTS = 0
d8ae4d67
BP
93#define WC_INVARIANT_BIT(NAME) | FWW_##NAME
94 WC_INVARIANT_LIST
95#undef WC_INVARIANT_BIT
eeba8e4f 96;
d8ae4d67 97
eb6f28db
BP
98/* Converts the wildcard in 'ofpfw' into a flow_wildcards in 'wc' for use in
99 * struct cls_rule. It is the caller's responsibility to handle the special
100 * case where the flow match's dl_vlan is set to OFP_VLAN_NONE. */
7286b1e1 101void
eb6f28db 102ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
d8ae4d67 103{
9e44d715 104 BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
a877206f 105
d8ae4d67 106 /* Initialize most of rule->wc. */
f9ba8dad 107 flow_wildcards_init_catchall(wc);
eeba8e4f 108 wc->wildcards = (OVS_FORCE flow_wildcards_t) ofpfw & WC_INVARIANTS;
bad68a99
JP
109
110 /* Wildcard fields that aren't defined by ofp_match or tun_id. */
fa8223b7
JP
111 wc->wildcards |= (FWW_ARP_SHA | FWW_ARP_THA | FWW_ND_TARGET
112 | FWW_IPV6_LABEL);
bad68a99 113
7257b535 114 if (!(ofpfw & OFPFW_NW_TOS)) {
9e44d715 115 wc->tos_mask |= IP_DSCP_MASK;
d8ae4d67 116 }
7257b535 117
d8ae4d67
BP
118 wc->nw_src_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_SRC_SHIFT);
119 wc->nw_dst_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_DST_SHIFT);
120
d8ae4d67
BP
121 if (ofpfw & OFPFW_DL_DST) {
122 /* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet destination, but
123 * Open vSwitch breaks the Ethernet destination into bits as FWW_DL_DST
124 * and FWW_ETH_MCAST. */
125 wc->wildcards |= FWW_ETH_MCAST;
126 }
127
eb6f28db
BP
128 /* VLAN TCI mask. */
129 if (!(ofpfw & OFPFW_DL_VLAN_PCP)) {
130 wc->vlan_tci_mask |= htons(VLAN_PCP_MASK | VLAN_CFI);
131 }
132 if (!(ofpfw & OFPFW_DL_VLAN)) {
133 wc->vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI);
134 }
135}
136
137/* Converts the ofp_match in 'match' into a cls_rule in 'rule', with the given
138 * 'priority'. */
139void
140ofputil_cls_rule_from_match(const struct ofp_match *match,
141 unsigned int priority, struct cls_rule *rule)
142{
143 uint32_t ofpfw = ntohl(match->wildcards) & OFPFW_ALL;
144
145 /* Initialize rule->priority, rule->wc. */
146 rule->priority = !ofpfw ? UINT16_MAX : priority;
147 ofputil_wildcard_from_openflow(ofpfw, &rule->wc);
148
66642cb4 149 /* Initialize most of rule->flow. */
d8ae4d67
BP
150 rule->flow.nw_src = match->nw_src;
151 rule->flow.nw_dst = match->nw_dst;
abe529af 152 rule->flow.in_port = ntohs(match->in_port);
36956a7d 153 rule->flow.dl_type = ofputil_dl_type_from_openflow(match->dl_type);
d8ae4d67
BP
154 rule->flow.tp_src = match->tp_src;
155 rule->flow.tp_dst = match->tp_dst;
156 memcpy(rule->flow.dl_src, match->dl_src, ETH_ADDR_LEN);
157 memcpy(rule->flow.dl_dst, match->dl_dst, ETH_ADDR_LEN);
9e44d715 158 rule->flow.tos = match->nw_tos & IP_DSCP_MASK;
d8ae4d67
BP
159 rule->flow.nw_proto = match->nw_proto;
160
66642cb4 161 /* Translate VLANs. */
47271d0d
BP
162 if (!(ofpfw & OFPFW_DL_VLAN) && match->dl_vlan == htons(OFP_VLAN_NONE)) {
163 /* Match only packets without 802.1Q header.
164 *
165 * When OFPFW_DL_VLAN_PCP is wildcarded, this is obviously correct.
166 *
167 * If OFPFW_DL_VLAN_PCP is matched, the flow match is contradictory,
168 * because we can't have a specific PCP without an 802.1Q header.
169 * However, older versions of OVS treated this as matching packets
170 * withut an 802.1Q header, so we do here too. */
66642cb4 171 rule->flow.vlan_tci = htons(0);
eb6f28db 172 rule->wc.vlan_tci_mask = htons(0xffff);
47271d0d
BP
173 } else {
174 ovs_be16 vid, pcp, tci;
175
47271d0d
BP
176 vid = match->dl_vlan & htons(VLAN_VID_MASK);
177 pcp = htons((match->dl_vlan_pcp << VLAN_PCP_SHIFT) & VLAN_PCP_MASK);
178 tci = vid | pcp | htons(VLAN_CFI);
eb6f28db 179 rule->flow.vlan_tci = tci & rule->wc.vlan_tci_mask;
66642cb4
BP
180 }
181
d8ae4d67
BP
182 /* Clean up. */
183 cls_rule_zero_wildcarded_fields(rule);
184}
185
b78f6b77 186/* Convert 'rule' into the OpenFlow match structure 'match'. */
d8ae4d67 187void
b78f6b77 188ofputil_cls_rule_to_match(const struct cls_rule *rule, struct ofp_match *match)
d8ae4d67
BP
189{
190 const struct flow_wildcards *wc = &rule->wc;
eeba8e4f 191 uint32_t ofpfw;
d8ae4d67 192
66642cb4 193 /* Figure out most OpenFlow wildcards. */
eeba8e4f 194 ofpfw = (OVS_FORCE uint32_t) (wc->wildcards & WC_INVARIANTS);
d8ae4d67
BP
195 ofpfw |= ofputil_netmask_to_wcbits(wc->nw_src_mask) << OFPFW_NW_SRC_SHIFT;
196 ofpfw |= ofputil_netmask_to_wcbits(wc->nw_dst_mask) << OFPFW_NW_DST_SHIFT;
9e44d715 197 if (!(wc->tos_mask & IP_DSCP_MASK)) {
d8ae4d67
BP
198 ofpfw |= OFPFW_NW_TOS;
199 }
ff9d3826 200
66642cb4
BP
201 /* Translate VLANs. */
202 match->dl_vlan = htons(0);
203 match->dl_vlan_pcp = 0;
204 if (rule->wc.vlan_tci_mask == htons(0)) {
205 ofpfw |= OFPFW_DL_VLAN | OFPFW_DL_VLAN_PCP;
206 } else if (rule->wc.vlan_tci_mask & htons(VLAN_CFI)
207 && !(rule->flow.vlan_tci & htons(VLAN_CFI))) {
208 match->dl_vlan = htons(OFP_VLAN_NONE);
209 } else {
210 if (!(rule->wc.vlan_tci_mask & htons(VLAN_VID_MASK))) {
211 ofpfw |= OFPFW_DL_VLAN;
212 } else {
213 match->dl_vlan = htons(vlan_tci_to_vid(rule->flow.vlan_tci));
214 }
215
216 if (!(rule->wc.vlan_tci_mask & htons(VLAN_PCP_MASK))) {
217 ofpfw |= OFPFW_DL_VLAN_PCP;
218 } else {
219 match->dl_vlan_pcp = vlan_tci_to_pcp(rule->flow.vlan_tci);
220 }
221 }
222
223 /* Compose most of the match structure. */
d8ae4d67 224 match->wildcards = htonl(ofpfw);
abe529af 225 match->in_port = htons(rule->flow.in_port);
d8ae4d67
BP
226 memcpy(match->dl_src, rule->flow.dl_src, ETH_ADDR_LEN);
227 memcpy(match->dl_dst, rule->flow.dl_dst, ETH_ADDR_LEN);
36956a7d 228 match->dl_type = ofputil_dl_type_to_openflow(rule->flow.dl_type);
d8ae4d67
BP
229 match->nw_src = rule->flow.nw_src;
230 match->nw_dst = rule->flow.nw_dst;
9e44d715 231 match->nw_tos = rule->flow.tos & IP_DSCP_MASK;
d8ae4d67
BP
232 match->nw_proto = rule->flow.nw_proto;
233 match->tp_src = rule->flow.tp_src;
234 match->tp_dst = rule->flow.tp_dst;
235 memset(match->pad1, '\0', sizeof match->pad1);
236 memset(match->pad2, '\0', sizeof match->pad2);
237}
238
36956a7d
BP
239/* Given a 'dl_type' value in the format used in struct flow, returns the
240 * corresponding 'dl_type' value for use in an OpenFlow ofp_match structure. */
241ovs_be16
242ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type)
243{
244 return (flow_dl_type == htons(FLOW_DL_TYPE_NONE)
245 ? htons(OFP_DL_TYPE_NOT_ETH_TYPE)
246 : flow_dl_type);
247}
248
249/* Given a 'dl_type' value in the format used in an OpenFlow ofp_match
250 * structure, returns the corresponding 'dl_type' value for use in struct
251 * flow. */
252ovs_be16
253ofputil_dl_type_from_openflow(ovs_be16 ofp_dl_type)
254{
255 return (ofp_dl_type == htons(OFP_DL_TYPE_NOT_ETH_TYPE)
256 ? htons(FLOW_DL_TYPE_NONE)
257 : ofp_dl_type);
258}
259
72fae175 260/* Returns a transaction ID to use for an outgoing OpenFlow message. */
44381c1b 261static ovs_be32
fa37b408
BP
262alloc_xid(void)
263{
72fae175 264 static uint32_t next_xid = 1;
44381c1b 265 return htonl(next_xid++);
fa37b408 266}
d1e2cf21
BP
267\f
268/* Basic parsing of OpenFlow messages. */
fa37b408 269
d1e2cf21
BP
270struct ofputil_msg_type {
271 enum ofputil_msg_code code; /* OFPUTIL_*. */
272 uint32_t value; /* OFPT_*, OFPST_*, NXT_*, or NXST_*. */
273 const char *name; /* e.g. "OFPT_FLOW_REMOVED". */
274 unsigned int min_size; /* Minimum total message size in bytes. */
275 /* 0 if 'min_size' is the exact size that the message must be. Otherwise,
276 * the message may exceed 'min_size' by an even multiple of this value. */
277 unsigned int extra_multiple;
278};
279
5a020ef3
BP
280/* Represents a malformed OpenFlow message. */
281static const struct ofputil_msg_type ofputil_invalid_type = {
282 OFPUTIL_MSG_INVALID, 0, "OFPUTIL_MSG_INVALID", 0, 0
283};
284
d1e2cf21
BP
285struct ofputil_msg_category {
286 const char *name; /* e.g. "OpenFlow message" */
287 const struct ofputil_msg_type *types;
288 size_t n_types;
289 int missing_error; /* ofp_mkerr() value for missing type. */
290};
291
5a020ef3
BP
292static int
293ofputil_check_length(const struct ofputil_msg_type *type, unsigned int size)
d1e2cf21
BP
294{
295 switch (type->extra_multiple) {
296 case 0:
297 if (size != type->min_size) {
5a020ef3 298 VLOG_WARN_RL(&bad_ofmsg_rl, "received %s with incorrect "
d1e2cf21 299 "length %u (expected length %u)",
5a020ef3
BP
300 type->name, size, type->min_size);
301 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
d1e2cf21 302 }
5a020ef3 303 return 0;
d1e2cf21
BP
304
305 case 1:
306 if (size < type->min_size) {
5a020ef3 307 VLOG_WARN_RL(&bad_ofmsg_rl, "received %s with incorrect "
d1e2cf21 308 "length %u (expected length at least %u bytes)",
5a020ef3
BP
309 type->name, size, type->min_size);
310 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
d1e2cf21 311 }
5a020ef3 312 return 0;
d1e2cf21
BP
313
314 default:
315 if (size < type->min_size
316 || (size - type->min_size) % type->extra_multiple) {
5a020ef3 317 VLOG_WARN_RL(&bad_ofmsg_rl, "received %s with incorrect "
d1e2cf21
BP
318 "length %u (must be exactly %u bytes or longer "
319 "by an integer multiple of %u bytes)",
5a020ef3 320 type->name, size,
d1e2cf21 321 type->min_size, type->extra_multiple);
5a020ef3 322 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
d1e2cf21 323 }
5a020ef3 324 return 0;
d1e2cf21
BP
325 }
326}
327
328static int
329ofputil_lookup_openflow_message(const struct ofputil_msg_category *cat,
5a020ef3 330 uint32_t value,
d1e2cf21
BP
331 const struct ofputil_msg_type **typep)
332{
333 const struct ofputil_msg_type *type;
334
335 for (type = cat->types; type < &cat->types[cat->n_types]; type++) {
336 if (type->value == value) {
d1e2cf21
BP
337 *typep = type;
338 return 0;
339 }
340 }
341
5c47debb 342 VLOG_WARN_RL(&bad_ofmsg_rl, "received %s of unknown type %"PRIu32,
d1e2cf21
BP
343 cat->name, value);
344 return cat->missing_error;
345}
346
347static int
5a020ef3 348ofputil_decode_vendor(const struct ofp_header *oh, size_t length,
d1e2cf21
BP
349 const struct ofputil_msg_type **typep)
350{
351 static const struct ofputil_msg_type nxt_messages[] = {
d1e2cf21
BP
352 { OFPUTIL_NXT_ROLE_REQUEST,
353 NXT_ROLE_REQUEST, "NXT_ROLE_REQUEST",
354 sizeof(struct nx_role_request), 0 },
355
356 { OFPUTIL_NXT_ROLE_REPLY,
357 NXT_ROLE_REPLY, "NXT_ROLE_REPLY",
358 sizeof(struct nx_role_request), 0 },
359
360 { OFPUTIL_NXT_SET_FLOW_FORMAT,
361 NXT_SET_FLOW_FORMAT, "NXT_SET_FLOW_FORMAT",
362 sizeof(struct nxt_set_flow_format), 0 },
363
364 { OFPUTIL_NXT_FLOW_MOD,
365 NXT_FLOW_MOD, "NXT_FLOW_MOD",
366 sizeof(struct nx_flow_mod), 8 },
367
368 { OFPUTIL_NXT_FLOW_REMOVED,
369 NXT_FLOW_REMOVED, "NXT_FLOW_REMOVED",
370 sizeof(struct nx_flow_removed), 8 },
d1e9b9bf
BP
371
372 { OFPUTIL_NXT_FLOW_MOD_TABLE_ID,
373 NXT_FLOW_MOD_TABLE_ID, "NXT_FLOW_MOD_TABLE_ID",
374 sizeof(struct nxt_flow_mod_table_id), 0 },
d1e2cf21
BP
375 };
376
377 static const struct ofputil_msg_category nxt_category = {
378 "Nicira extension message",
379 nxt_messages, ARRAY_SIZE(nxt_messages),
380 OFP_MKERR(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE)
381 };
382
383 const struct ofp_vendor_header *ovh;
384 const struct nicira_header *nh;
385
5a020ef3
BP
386 if (length < sizeof(struct ofp_vendor_header)) {
387 if (length == ntohs(oh->length)) {
388 VLOG_WARN_RL(&bad_ofmsg_rl, "truncated vendor message");
389 }
390 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
391 }
392
d1e2cf21
BP
393 ovh = (const struct ofp_vendor_header *) oh;
394 if (ovh->vendor != htonl(NX_VENDOR_ID)) {
395 VLOG_WARN_RL(&bad_ofmsg_rl, "received vendor message for unknown "
396 "vendor %"PRIx32, ntohl(ovh->vendor));
397 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_VENDOR);
398 }
399
5a020ef3
BP
400 if (length < sizeof(struct nicira_header)) {
401 if (length == ntohs(oh->length)) {
402 VLOG_WARN_RL(&bad_ofmsg_rl, "received Nicira vendor message of "
403 "length %u (expected at least %zu)",
404 ntohs(ovh->header.length),
405 sizeof(struct nicira_header));
406 }
d1e2cf21
BP
407 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
408 }
409
410 nh = (const struct nicira_header *) oh;
411 return ofputil_lookup_openflow_message(&nxt_category, ntohl(nh->subtype),
5a020ef3 412 typep);
d1e2cf21
BP
413}
414
415static int
5a020ef3 416check_nxstats_msg(const struct ofp_header *oh, size_t length)
d1e2cf21 417{
28c8bad1 418 const struct ofp_stats_msg *osm = (const struct ofp_stats_msg *) oh;
d1e2cf21
BP
419 ovs_be32 vendor;
420
5a020ef3
BP
421 if (length < sizeof(struct ofp_vendor_stats_msg)) {
422 if (length == ntohs(oh->length)) {
423 VLOG_WARN_RL(&bad_ofmsg_rl, "truncated vendor stats message");
424 }
425 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
426 }
427
03cd3493 428 memcpy(&vendor, osm + 1, sizeof vendor);
d1e2cf21
BP
429 if (vendor != htonl(NX_VENDOR_ID)) {
430 VLOG_WARN_RL(&bad_ofmsg_rl, "received vendor stats message for "
431 "unknown vendor %"PRIx32, ntohl(vendor));
432 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_VENDOR);
433 }
434
5a020ef3
BP
435 if (length < sizeof(struct nicira_stats_msg)) {
436 if (length == ntohs(osm->header.length)) {
437 VLOG_WARN_RL(&bad_ofmsg_rl, "truncated Nicira stats message");
438 }
d1e2cf21
BP
439 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
440 }
441
442 return 0;
443}
444
445static int
5a020ef3 446ofputil_decode_nxst_request(const struct ofp_header *oh, size_t length,
d1e2cf21
BP
447 const struct ofputil_msg_type **typep)
448{
449 static const struct ofputil_msg_type nxst_requests[] = {
450 { OFPUTIL_NXST_FLOW_REQUEST,
451 NXST_FLOW, "NXST_FLOW request",
452 sizeof(struct nx_flow_stats_request), 8 },
453
454 { OFPUTIL_NXST_AGGREGATE_REQUEST,
455 NXST_AGGREGATE, "NXST_AGGREGATE request",
456 sizeof(struct nx_aggregate_stats_request), 8 },
457 };
458
459 static const struct ofputil_msg_category nxst_request_category = {
08717852 460 "Nicira extension statistics request",
d1e2cf21
BP
461 nxst_requests, ARRAY_SIZE(nxst_requests),
462 OFP_MKERR(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE)
463 };
464
465 const struct nicira_stats_msg *nsm;
466 int error;
467
5a020ef3 468 error = check_nxstats_msg(oh, length);
d1e2cf21
BP
469 if (error) {
470 return error;
471 }
472
473 nsm = (struct nicira_stats_msg *) oh;
474 return ofputil_lookup_openflow_message(&nxst_request_category,
5a020ef3 475 ntohl(nsm->subtype), typep);
d1e2cf21
BP
476}
477
478static int
5a020ef3 479ofputil_decode_nxst_reply(const struct ofp_header *oh, size_t length,
d1e2cf21
BP
480 const struct ofputil_msg_type **typep)
481{
482 static const struct ofputil_msg_type nxst_replies[] = {
483 { OFPUTIL_NXST_FLOW_REPLY,
484 NXST_FLOW, "NXST_FLOW reply",
485 sizeof(struct nicira_stats_msg), 8 },
486
487 { OFPUTIL_NXST_AGGREGATE_REPLY,
488 NXST_AGGREGATE, "NXST_AGGREGATE reply",
489 sizeof(struct nx_aggregate_stats_reply), 0 },
490 };
491
492 static const struct ofputil_msg_category nxst_reply_category = {
08717852 493 "Nicira extension statistics reply",
d1e2cf21
BP
494 nxst_replies, ARRAY_SIZE(nxst_replies),
495 OFP_MKERR(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE)
496 };
497
498 const struct nicira_stats_msg *nsm;
499 int error;
500
5a020ef3 501 error = check_nxstats_msg(oh, length);
d1e2cf21
BP
502 if (error) {
503 return error;
504 }
505
506 nsm = (struct nicira_stats_msg *) oh;
507 return ofputil_lookup_openflow_message(&nxst_reply_category,
5a020ef3
BP
508 ntohl(nsm->subtype), typep);
509}
510
511static int
512check_stats_msg(const struct ofp_header *oh, size_t length)
513{
514 if (length < sizeof(struct ofp_stats_msg)) {
515 if (length == ntohs(oh->length)) {
516 VLOG_WARN_RL(&bad_ofmsg_rl, "truncated stats message");
517 }
518 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
519 }
520
521 return 0;
d1e2cf21
BP
522}
523
524static int
5a020ef3 525ofputil_decode_ofpst_request(const struct ofp_header *oh, size_t length,
d1e2cf21
BP
526 const struct ofputil_msg_type **typep)
527{
d1e2cf21
BP
528 static const struct ofputil_msg_type ofpst_requests[] = {
529 { OFPUTIL_OFPST_DESC_REQUEST,
530 OFPST_DESC, "OFPST_DESC request",
63f2140a 531 sizeof(struct ofp_stats_msg), 0 },
d1e2cf21
BP
532
533 { OFPUTIL_OFPST_FLOW_REQUEST,
534 OFPST_FLOW, "OFPST_FLOW request",
63f2140a 535 sizeof(struct ofp_flow_stats_request), 0 },
d1e2cf21
BP
536
537 { OFPUTIL_OFPST_AGGREGATE_REQUEST,
538 OFPST_AGGREGATE, "OFPST_AGGREGATE request",
63f2140a 539 sizeof(struct ofp_flow_stats_request), 0 },
d1e2cf21
BP
540
541 { OFPUTIL_OFPST_TABLE_REQUEST,
542 OFPST_TABLE, "OFPST_TABLE request",
63f2140a 543 sizeof(struct ofp_stats_msg), 0 },
d1e2cf21
BP
544
545 { OFPUTIL_OFPST_PORT_REQUEST,
546 OFPST_PORT, "OFPST_PORT request",
63f2140a 547 sizeof(struct ofp_port_stats_request), 0 },
d1e2cf21
BP
548
549 { OFPUTIL_OFPST_QUEUE_REQUEST,
550 OFPST_QUEUE, "OFPST_QUEUE request",
63f2140a 551 sizeof(struct ofp_queue_stats_request), 0 },
d1e2cf21
BP
552
553 { 0,
554 OFPST_VENDOR, "OFPST_VENDOR request",
63f2140a 555 sizeof(struct ofp_vendor_stats_msg), 1 },
d1e2cf21
BP
556 };
557
558 static const struct ofputil_msg_category ofpst_request_category = {
559 "OpenFlow statistics",
560 ofpst_requests, ARRAY_SIZE(ofpst_requests),
561 OFP_MKERR(OFPET_BAD_REQUEST, OFPBRC_BAD_STAT)
562 };
563
28c8bad1 564 const struct ofp_stats_msg *request = (const struct ofp_stats_msg *) oh;
d1e2cf21
BP
565 int error;
566
5a020ef3
BP
567 error = check_stats_msg(oh, length);
568 if (error) {
569 return error;
570 }
571
d1e2cf21 572 error = ofputil_lookup_openflow_message(&ofpst_request_category,
5a020ef3 573 ntohs(request->type), typep);
28c8bad1 574 if (!error && request->type == htons(OFPST_VENDOR)) {
5a020ef3 575 error = ofputil_decode_nxst_request(oh, length, typep);
d1e2cf21
BP
576 }
577 return error;
578}
579
580static int
5a020ef3 581ofputil_decode_ofpst_reply(const struct ofp_header *oh, size_t length,
d1e2cf21
BP
582 const struct ofputil_msg_type **typep)
583{
d1e2cf21
BP
584 static const struct ofputil_msg_type ofpst_replies[] = {
585 { OFPUTIL_OFPST_DESC_REPLY,
586 OFPST_DESC, "OFPST_DESC reply",
63f2140a 587 sizeof(struct ofp_desc_stats), 0 },
d1e2cf21
BP
588
589 { OFPUTIL_OFPST_FLOW_REPLY,
590 OFPST_FLOW, "OFPST_FLOW reply",
63f2140a 591 sizeof(struct ofp_stats_msg), 1 },
d1e2cf21
BP
592
593 { OFPUTIL_OFPST_AGGREGATE_REPLY,
594 OFPST_AGGREGATE, "OFPST_AGGREGATE reply",
63f2140a 595 sizeof(struct ofp_aggregate_stats_reply), 0 },
d1e2cf21
BP
596
597 { OFPUTIL_OFPST_TABLE_REPLY,
598 OFPST_TABLE, "OFPST_TABLE reply",
63f2140a 599 sizeof(struct ofp_stats_msg), sizeof(struct ofp_table_stats) },
d1e2cf21
BP
600
601 { OFPUTIL_OFPST_PORT_REPLY,
602 OFPST_PORT, "OFPST_PORT reply",
63f2140a 603 sizeof(struct ofp_stats_msg), sizeof(struct ofp_port_stats) },
d1e2cf21
BP
604
605 { OFPUTIL_OFPST_QUEUE_REPLY,
606 OFPST_QUEUE, "OFPST_QUEUE reply",
63f2140a 607 sizeof(struct ofp_stats_msg), sizeof(struct ofp_queue_stats) },
d1e2cf21
BP
608
609 { 0,
610 OFPST_VENDOR, "OFPST_VENDOR reply",
63f2140a 611 sizeof(struct ofp_vendor_stats_msg), 1 },
d1e2cf21
BP
612 };
613
614 static const struct ofputil_msg_category ofpst_reply_category = {
615 "OpenFlow statistics",
616 ofpst_replies, ARRAY_SIZE(ofpst_replies),
617 OFP_MKERR(OFPET_BAD_REQUEST, OFPBRC_BAD_STAT)
618 };
619
28c8bad1 620 const struct ofp_stats_msg *reply = (const struct ofp_stats_msg *) oh;
d1e2cf21
BP
621 int error;
622
5a020ef3
BP
623 error = check_stats_msg(oh, length);
624 if (error) {
625 return error;
626 }
627
d1e2cf21 628 error = ofputil_lookup_openflow_message(&ofpst_reply_category,
5a020ef3 629 ntohs(reply->type), typep);
28c8bad1 630 if (!error && reply->type == htons(OFPST_VENDOR)) {
5a020ef3 631 error = ofputil_decode_nxst_reply(oh, length, typep);
d1e2cf21
BP
632 }
633 return error;
634}
635
5a020ef3
BP
636static int
637ofputil_decode_msg_type__(const struct ofp_header *oh, size_t length,
638 const struct ofputil_msg_type **typep)
d1e2cf21
BP
639{
640 static const struct ofputil_msg_type ofpt_messages[] = {
641 { OFPUTIL_OFPT_HELLO,
642 OFPT_HELLO, "OFPT_HELLO",
643 sizeof(struct ofp_hello), 1 },
644
645 { OFPUTIL_OFPT_ERROR,
646 OFPT_ERROR, "OFPT_ERROR",
647 sizeof(struct ofp_error_msg), 1 },
648
649 { OFPUTIL_OFPT_ECHO_REQUEST,
650 OFPT_ECHO_REQUEST, "OFPT_ECHO_REQUEST",
651 sizeof(struct ofp_header), 1 },
652
653 { OFPUTIL_OFPT_ECHO_REPLY,
654 OFPT_ECHO_REPLY, "OFPT_ECHO_REPLY",
655 sizeof(struct ofp_header), 1 },
656
657 { OFPUTIL_OFPT_FEATURES_REQUEST,
658 OFPT_FEATURES_REQUEST, "OFPT_FEATURES_REQUEST",
659 sizeof(struct ofp_header), 0 },
660
661 { OFPUTIL_OFPT_FEATURES_REPLY,
662 OFPT_FEATURES_REPLY, "OFPT_FEATURES_REPLY",
663 sizeof(struct ofp_switch_features), sizeof(struct ofp_phy_port) },
664
665 { OFPUTIL_OFPT_GET_CONFIG_REQUEST,
666 OFPT_GET_CONFIG_REQUEST, "OFPT_GET_CONFIG_REQUEST",
667 sizeof(struct ofp_header), 0 },
668
669 { OFPUTIL_OFPT_GET_CONFIG_REPLY,
670 OFPT_GET_CONFIG_REPLY, "OFPT_GET_CONFIG_REPLY",
671 sizeof(struct ofp_switch_config), 0 },
672
673 { OFPUTIL_OFPT_SET_CONFIG,
674 OFPT_SET_CONFIG, "OFPT_SET_CONFIG",
675 sizeof(struct ofp_switch_config), 0 },
676
677 { OFPUTIL_OFPT_PACKET_IN,
678 OFPT_PACKET_IN, "OFPT_PACKET_IN",
679 offsetof(struct ofp_packet_in, data), 1 },
680
681 { OFPUTIL_OFPT_FLOW_REMOVED,
682 OFPT_FLOW_REMOVED, "OFPT_FLOW_REMOVED",
683 sizeof(struct ofp_flow_removed), 0 },
684
685 { OFPUTIL_OFPT_PORT_STATUS,
686 OFPT_PORT_STATUS, "OFPT_PORT_STATUS",
687 sizeof(struct ofp_port_status), 0 },
688
689 { OFPUTIL_OFPT_PACKET_OUT,
690 OFPT_PACKET_OUT, "OFPT_PACKET_OUT",
691 sizeof(struct ofp_packet_out), 1 },
692
693 { OFPUTIL_OFPT_FLOW_MOD,
694 OFPT_FLOW_MOD, "OFPT_FLOW_MOD",
695 sizeof(struct ofp_flow_mod), 1 },
696
697 { OFPUTIL_OFPT_PORT_MOD,
698 OFPT_PORT_MOD, "OFPT_PORT_MOD",
699 sizeof(struct ofp_port_mod), 0 },
700
701 { 0,
702 OFPT_STATS_REQUEST, "OFPT_STATS_REQUEST",
28c8bad1 703 sizeof(struct ofp_stats_msg), 1 },
d1e2cf21
BP
704
705 { 0,
706 OFPT_STATS_REPLY, "OFPT_STATS_REPLY",
28c8bad1 707 sizeof(struct ofp_stats_msg), 1 },
d1e2cf21
BP
708
709 { OFPUTIL_OFPT_BARRIER_REQUEST,
710 OFPT_BARRIER_REQUEST, "OFPT_BARRIER_REQUEST",
711 sizeof(struct ofp_header), 0 },
712
713 { OFPUTIL_OFPT_BARRIER_REPLY,
714 OFPT_BARRIER_REPLY, "OFPT_BARRIER_REPLY",
715 sizeof(struct ofp_header), 0 },
716
717 { 0,
718 OFPT_VENDOR, "OFPT_VENDOR",
719 sizeof(struct ofp_vendor_header), 1 },
720 };
721
722 static const struct ofputil_msg_category ofpt_category = {
723 "OpenFlow message",
724 ofpt_messages, ARRAY_SIZE(ofpt_messages),
725 OFP_MKERR(OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE)
726 };
727
728 int error;
729
5a020ef3 730 error = ofputil_lookup_openflow_message(&ofpt_category, oh->type, typep);
d1e2cf21
BP
731 if (!error) {
732 switch (oh->type) {
733 case OFPT_VENDOR:
5a020ef3 734 error = ofputil_decode_vendor(oh, length, typep);
d1e2cf21
BP
735 break;
736
737 case OFPT_STATS_REQUEST:
5a020ef3 738 error = ofputil_decode_ofpst_request(oh, length, typep);
d1e2cf21
BP
739 break;
740
741 case OFPT_STATS_REPLY:
5a020ef3 742 error = ofputil_decode_ofpst_reply(oh, length, typep);
d1e2cf21
BP
743
744 default:
745 break;
746 }
747 }
5a020ef3
BP
748 return error;
749}
750
751/* Decodes the message type represented by 'oh'. Returns 0 if successful or
752 * an OpenFlow error code constructed with ofp_mkerr() on failure. Either
753 * way, stores in '*typep' a type structure that can be inspected with the
754 * ofputil_msg_type_*() functions.
755 *
756 * oh->length must indicate the correct length of the message (and must be at
757 * least sizeof(struct ofp_header)).
758 *
759 * Success indicates that 'oh' is at least as long as the minimum-length
760 * message of its type. */
761int
762ofputil_decode_msg_type(const struct ofp_header *oh,
763 const struct ofputil_msg_type **typep)
764{
765 size_t length = ntohs(oh->length);
766 int error;
767
768 error = ofputil_decode_msg_type__(oh, length, typep);
769 if (!error) {
770 error = ofputil_check_length(*typep, length);
771 }
d1e2cf21 772 if (error) {
5a020ef3
BP
773 *typep = &ofputil_invalid_type;
774 }
775 return error;
776}
d1e2cf21 777
5a020ef3
BP
778/* Decodes the message type represented by 'oh', of which only the first
779 * 'length' bytes are available. Returns 0 if successful or an OpenFlow error
780 * code constructed with ofp_mkerr() on failure. Either way, stores in
781 * '*typep' a type structure that can be inspected with the
782 * ofputil_msg_type_*() functions. */
783int
784ofputil_decode_msg_type_partial(const struct ofp_header *oh, size_t length,
785 const struct ofputil_msg_type **typep)
786{
787 int error;
788
789 error = (length >= sizeof *oh
790 ? ofputil_decode_msg_type__(oh, length, typep)
791 : ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN));
792 if (error) {
d1e2cf21
BP
793 *typep = &ofputil_invalid_type;
794 }
795 return error;
796}
797
798/* Returns an OFPUTIL_* message type code for 'type'. */
799enum ofputil_msg_code
800ofputil_msg_type_code(const struct ofputil_msg_type *type)
801{
802 return type->code;
803}
2e4f5fcf 804\f
7fa91113
BP
805/* Flow formats. */
806
807bool
808ofputil_flow_format_is_valid(enum nx_flow_format flow_format)
809{
810 switch (flow_format) {
811 case NXFF_OPENFLOW10:
7fa91113
BP
812 case NXFF_NXM:
813 return true;
814 }
815
816 return false;
817}
818
819const char *
820ofputil_flow_format_to_string(enum nx_flow_format flow_format)
821{
822 switch (flow_format) {
823 case NXFF_OPENFLOW10:
824 return "openflow10";
7fa91113
BP
825 case NXFF_NXM:
826 return "nxm";
827 default:
828 NOT_REACHED();
829 }
830}
831
88ca35ee
BP
832int
833ofputil_flow_format_from_string(const char *s)
834{
835 return (!strcmp(s, "openflow10") ? NXFF_OPENFLOW10
88ca35ee
BP
836 : !strcmp(s, "nxm") ? NXFF_NXM
837 : -1);
838}
839
840static bool
841regs_fully_wildcarded(const struct flow_wildcards *wc)
842{
843 int i;
844
845 for (i = 0; i < FLOW_N_REGS; i++) {
846 if (wc->reg_masks[i] != 0) {
847 return false;
848 }
849 }
850 return true;
851}
852
b78f6b77
BP
853/* Returns the minimum nx_flow_format to use for sending 'rule' to a switch
854 * (e.g. to add or remove a flow). Only NXM can handle tunnel IDs, registers,
855 * or fixing the Ethernet multicast bit. Otherwise, it's better to use
856 * NXFF_OPENFLOW10 for backward compatibility. */
857enum nx_flow_format
858ofputil_min_flow_format(const struct cls_rule *rule)
8368c090
BP
859{
860 const struct flow_wildcards *wc = &rule->wc;
8368c090 861
9e44d715 862 BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
a877206f 863
8368c090
BP
864 /* Only NXM supports separately wildcards the Ethernet multicast bit. */
865 if (!(wc->wildcards & FWW_DL_DST) != !(wc->wildcards & FWW_ETH_MCAST)) {
b78f6b77 866 return NXFF_NXM;
8368c090
BP
867 }
868
bad68a99
JP
869 /* Only NXM supports matching ARP hardware addresses. */
870 if (!(wc->wildcards & FWW_ARP_SHA) || !(wc->wildcards & FWW_ARP_THA)) {
b78f6b77 871 return NXFF_NXM;
bad68a99
JP
872 }
873
d31f1109
JP
874 /* Only NXM supports matching IPv6 traffic. */
875 if (!(wc->wildcards & FWW_DL_TYPE)
876 && (rule->flow.dl_type == htons(ETH_TYPE_IPV6))) {
b78f6b77 877 return NXFF_NXM;
d31f1109
JP
878 }
879
8368c090
BP
880 /* Only NXM supports matching registers. */
881 if (!regs_fully_wildcarded(wc)) {
b78f6b77 882 return NXFF_NXM;
8368c090
BP
883 }
884
b78f6b77
BP
885 /* Only NXM supports matching tun_id. */
886 if (wc->tun_id_mask != htonll(0)) {
887 return NXFF_NXM;
8368c090
BP
888 }
889
7257b535 890 /* Only NXM supports matching fragments. */
9e44d715 891 if (wc->frag_mask) {
7257b535
BP
892 return NXFF_NXM;
893 }
894
fa8223b7
JP
895 /* Only NXM supports matching IPv6 flow label. */
896 if (!(wc->wildcards & FWW_IPV6_LABEL)) {
897 return NXFF_NXM;
898 }
899
530180fd
JP
900 /* Only NXM supports matching IP ECN bits. */
901 if (wc->tos_mask & IP_ECN_MASK) {
902 return NXFF_NXM;
903 }
904
8368c090 905 /* Other formats can express this rule. */
b78f6b77 906 return NXFF_OPENFLOW10;
88ca35ee
BP
907}
908
909/* Returns an OpenFlow message that can be used to set the flow format to
910 * 'flow_format'. */
911struct ofpbuf *
912ofputil_make_set_flow_format(enum nx_flow_format flow_format)
913{
b78f6b77 914 struct nxt_set_flow_format *sff;
88ca35ee
BP
915 struct ofpbuf *msg;
916
b78f6b77
BP
917 sff = make_nxmsg(sizeof *sff, NXT_SET_FLOW_FORMAT, &msg);
918 sff->format = htonl(flow_format);
88ca35ee
BP
919
920 return msg;
921}
922
6c1491fb
BP
923/* Returns an OpenFlow message that can be used to turn the flow_mod_table_id
924 * extension on or off (according to 'flow_mod_table_id'). */
925struct ofpbuf *
926ofputil_make_flow_mod_table_id(bool flow_mod_table_id)
927{
928 struct nxt_flow_mod_table_id *nfmti;
929 struct ofpbuf *msg;
930
931 nfmti = make_nxmsg(sizeof *nfmti, NXT_FLOW_MOD_TABLE_ID, &msg);
932 nfmti->set = flow_mod_table_id;
933 return msg;
934}
935
7fa91113
BP
936/* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract
937 * flow_mod in 'fm'. Returns 0 if successful, otherwise an OpenFlow error
938 * code.
939 *
6c1491fb
BP
940 * 'flow_mod_table_id' should be true if the NXT_FLOW_MOD_TABLE_ID extension is
941 * enabled, false otherwise.
942 *
2e4f5fcf
BP
943 * Does not validate the flow_mod actions. */
944int
a9a2da38
BP
945ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
946 const struct ofp_header *oh, bool flow_mod_table_id)
2e4f5fcf
BP
947{
948 const struct ofputil_msg_type *type;
6c1491fb 949 uint16_t command;
2e4f5fcf
BP
950 struct ofpbuf b;
951
2013493b 952 ofpbuf_use_const(&b, oh, ntohs(oh->length));
2e4f5fcf
BP
953
954 ofputil_decode_msg_type(oh, &type);
955 if (ofputil_msg_type_code(type) == OFPUTIL_OFPT_FLOW_MOD) {
956 /* Standard OpenFlow flow_mod. */
2e4f5fcf 957 const struct ofp_flow_mod *ofm;
1c0b7503 958 uint16_t priority;
2e4f5fcf
BP
959 int error;
960
961 /* Dissect the message. */
bbc32a88 962 ofm = ofpbuf_pull(&b, sizeof *ofm);
2e4f5fcf
BP
963 error = ofputil_pull_actions(&b, b.size, &fm->actions, &fm->n_actions);
964 if (error) {
965 return error;
966 }
967
1c0b7503
BP
968 /* Set priority based on original wildcards. Normally we'd allow
969 * ofputil_cls_rule_from_match() to do this for us, but
b459a924 970 * ofputil_normalize_rule() can put wildcards where the original flow
1c0b7503
BP
971 * didn't have them. */
972 priority = ntohs(ofm->priority);
973 if (!(ofm->match.wildcards & htonl(OFPFW_ALL))) {
974 priority = UINT16_MAX;
975 }
976
b459a924
BP
977 /* Translate the rule. */
978 ofputil_cls_rule_from_match(&ofm->match, priority, &fm->cr);
979 ofputil_normalize_rule(&fm->cr, NXFF_OPENFLOW10);
2e4f5fcf
BP
980
981 /* Translate the message. */
2e4f5fcf 982 fm->cookie = ofm->cookie;
6c1491fb 983 command = ntohs(ofm->command);
2e4f5fcf
BP
984 fm->idle_timeout = ntohs(ofm->idle_timeout);
985 fm->hard_timeout = ntohs(ofm->hard_timeout);
986 fm->buffer_id = ntohl(ofm->buffer_id);
987 fm->out_port = ntohs(ofm->out_port);
988 fm->flags = ntohs(ofm->flags);
989 } else if (ofputil_msg_type_code(type) == OFPUTIL_NXT_FLOW_MOD) {
990 /* Nicira extended flow_mod. */
991 const struct nx_flow_mod *nfm;
992 int error;
993
994 /* Dissect the message. */
bbc32a88 995 nfm = ofpbuf_pull(&b, sizeof *nfm);
2e4f5fcf
BP
996 error = nx_pull_match(&b, ntohs(nfm->match_len), ntohs(nfm->priority),
997 &fm->cr);
998 if (error) {
999 return error;
1000 }
1001 error = ofputil_pull_actions(&b, b.size, &fm->actions, &fm->n_actions);
1002 if (error) {
1003 return error;
1004 }
1005
1006 /* Translate the message. */
1007 fm->cookie = nfm->cookie;
6c1491fb 1008 command = ntohs(nfm->command);
2e4f5fcf
BP
1009 fm->idle_timeout = ntohs(nfm->idle_timeout);
1010 fm->hard_timeout = ntohs(nfm->hard_timeout);
1011 fm->buffer_id = ntohl(nfm->buffer_id);
1012 fm->out_port = ntohs(nfm->out_port);
1013 fm->flags = ntohs(nfm->flags);
1014 } else {
1015 NOT_REACHED();
1016 }
1017
6c1491fb
BP
1018 if (flow_mod_table_id) {
1019 fm->command = command & 0xff;
1020 fm->table_id = command >> 8;
1021 } else {
1022 fm->command = command;
1023 fm->table_id = 0xff;
1024 }
1025
2e4f5fcf
BP
1026 return 0;
1027}
1028
1029/* Converts 'fm' into an OFPT_FLOW_MOD or NXT_FLOW_MOD message according to
6c1491fb
BP
1030 * 'flow_format' and returns the message.
1031 *
1032 * 'flow_mod_table_id' should be true if the NXT_FLOW_MOD_TABLE_ID extension is
1033 * enabled, false otherwise. */
2e4f5fcf 1034struct ofpbuf *
a9a2da38 1035ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
6c1491fb
BP
1036 enum nx_flow_format flow_format,
1037 bool flow_mod_table_id)
2e4f5fcf
BP
1038{
1039 size_t actions_len = fm->n_actions * sizeof *fm->actions;
1040 struct ofpbuf *msg;
6c1491fb
BP
1041 uint16_t command;
1042
1043 command = (flow_mod_table_id
1044 ? (fm->command & 0xff) | (fm->table_id << 8)
1045 : fm->command);
2e4f5fcf 1046
b78f6b77 1047 if (flow_format == NXFF_OPENFLOW10) {
2e4f5fcf
BP
1048 struct ofp_flow_mod *ofm;
1049
1050 msg = ofpbuf_new(sizeof *ofm + actions_len);
1051 ofm = put_openflow(sizeof *ofm, OFPT_FLOW_MOD, msg);
b78f6b77
BP
1052 ofputil_cls_rule_to_match(&fm->cr, &ofm->match);
1053 ofm->cookie = fm->cookie;
05411977 1054 ofm->command = htons(command);
2e4f5fcf
BP
1055 ofm->idle_timeout = htons(fm->idle_timeout);
1056 ofm->hard_timeout = htons(fm->hard_timeout);
1057 ofm->priority = htons(fm->cr.priority);
1058 ofm->buffer_id = htonl(fm->buffer_id);
1059 ofm->out_port = htons(fm->out_port);
1060 ofm->flags = htons(fm->flags);
1061 } else if (flow_format == NXFF_NXM) {
1062 struct nx_flow_mod *nfm;
1063 int match_len;
1064
1065 msg = ofpbuf_new(sizeof *nfm + NXM_TYPICAL_LEN + actions_len);
1066 put_nxmsg(sizeof *nfm, NXT_FLOW_MOD, msg);
1067 match_len = nx_put_match(msg, &fm->cr);
1068
1069 nfm = msg->data;
1070 nfm->cookie = fm->cookie;
6c1491fb 1071 nfm->command = htons(command);
2e4f5fcf
BP
1072 nfm->idle_timeout = htons(fm->idle_timeout);
1073 nfm->hard_timeout = htons(fm->hard_timeout);
1074 nfm->priority = htons(fm->cr.priority);
1075 nfm->buffer_id = htonl(fm->buffer_id);
1076 nfm->out_port = htons(fm->out_port);
1077 nfm->flags = htons(fm->flags);
1078 nfm->match_len = htons(match_len);
1079 } else {
1080 NOT_REACHED();
1081 }
1082
1083 ofpbuf_put(msg, fm->actions, actions_len);
1084 update_openflow_length(msg);
1085 return msg;
1086}
1087
1088static int
81d1ea94 1089ofputil_decode_ofpst_flow_request(struct ofputil_flow_stats_request *fsr,
2e4f5fcf 1090 const struct ofp_header *oh,
2e4f5fcf
BP
1091 bool aggregate)
1092{
63f2140a
BP
1093 const struct ofp_flow_stats_request *ofsr =
1094 (const struct ofp_flow_stats_request *) oh;
2e4f5fcf
BP
1095
1096 fsr->aggregate = aggregate;
b78f6b77 1097 ofputil_cls_rule_from_match(&ofsr->match, 0, &fsr->match);
2e4f5fcf
BP
1098 fsr->out_port = ntohs(ofsr->out_port);
1099 fsr->table_id = ofsr->table_id;
1100
1101 return 0;
1102}
1103
1104static int
81d1ea94 1105ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr,
2e4f5fcf
BP
1106 const struct ofp_header *oh,
1107 bool aggregate)
1108{
1109 const struct nx_flow_stats_request *nfsr;
1110 struct ofpbuf b;
1111 int error;
1112
2013493b 1113 ofpbuf_use_const(&b, oh, ntohs(oh->length));
2e4f5fcf 1114
bbc32a88 1115 nfsr = ofpbuf_pull(&b, sizeof *nfsr);
2e4f5fcf
BP
1116 error = nx_pull_match(&b, ntohs(nfsr->match_len), 0, &fsr->match);
1117 if (error) {
1118 return error;
1119 }
1120 if (b.size) {
1121 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
1122 }
1123
1124 fsr->aggregate = aggregate;
1125 fsr->out_port = ntohs(nfsr->out_port);
1126 fsr->table_id = nfsr->table_id;
1127
1128 return 0;
1129}
1130
1131/* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
b78f6b77
BP
1132 * request 'oh', into an abstract flow_stats_request in 'fsr'. Returns 0 if
1133 * successful, otherwise an OpenFlow error code. */
2e4f5fcf 1134int
81d1ea94 1135ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request *fsr,
b78f6b77 1136 const struct ofp_header *oh)
2e4f5fcf
BP
1137{
1138 const struct ofputil_msg_type *type;
1139 struct ofpbuf b;
1140 int code;
1141
2013493b 1142 ofpbuf_use_const(&b, oh, ntohs(oh->length));
2e4f5fcf
BP
1143
1144 ofputil_decode_msg_type(oh, &type);
1145 code = ofputil_msg_type_code(type);
1146 switch (code) {
1147 case OFPUTIL_OFPST_FLOW_REQUEST:
b78f6b77 1148 return ofputil_decode_ofpst_flow_request(fsr, oh, false);
2e4f5fcf
BP
1149
1150 case OFPUTIL_OFPST_AGGREGATE_REQUEST:
b78f6b77 1151 return ofputil_decode_ofpst_flow_request(fsr, oh, true);
2e4f5fcf
BP
1152
1153 case OFPUTIL_NXST_FLOW_REQUEST:
1154 return ofputil_decode_nxst_flow_request(fsr, oh, false);
1155
1156 case OFPUTIL_NXST_AGGREGATE_REQUEST:
1157 return ofputil_decode_nxst_flow_request(fsr, oh, true);
1158
1159 default:
1160 /* Hey, the caller lied. */
1161 NOT_REACHED();
1162 }
1163}
1164
1165/* Converts abstract flow_stats_request 'fsr' into an OFPST_FLOW,
4ffd1b43 1166 * OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE request 'oh' according to
2e4f5fcf
BP
1167 * 'flow_format', and returns the message. */
1168struct ofpbuf *
81d1ea94 1169ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
2e4f5fcf
BP
1170 enum nx_flow_format flow_format)
1171{
1172 struct ofpbuf *msg;
1173
b78f6b77 1174 if (flow_format == NXFF_OPENFLOW10) {
2e4f5fcf
BP
1175 struct ofp_flow_stats_request *ofsr;
1176 int type;
1177
2e4f5fcf 1178 type = fsr->aggregate ? OFPST_AGGREGATE : OFPST_FLOW;
63f2140a 1179 ofsr = ofputil_make_stats_request(sizeof *ofsr, type, 0, &msg);
b78f6b77 1180 ofputil_cls_rule_to_match(&fsr->match, &ofsr->match);
2e4f5fcf
BP
1181 ofsr->table_id = fsr->table_id;
1182 ofsr->out_port = htons(fsr->out_port);
1183 } else if (flow_format == NXFF_NXM) {
1184 struct nx_flow_stats_request *nfsr;
1185 int match_len;
9fb7fa87 1186 int subtype;
2e4f5fcf 1187
9fb7fa87 1188 subtype = fsr->aggregate ? NXST_AGGREGATE : NXST_FLOW;
63f2140a 1189 ofputil_make_stats_request(sizeof *nfsr, OFPST_VENDOR, subtype, &msg);
2e4f5fcf
BP
1190 match_len = nx_put_match(msg, &fsr->match);
1191
1192 nfsr = msg->data;
1193 nfsr->out_port = htons(fsr->out_port);
1194 nfsr->match_len = htons(match_len);
1195 nfsr->table_id = fsr->table_id;
1196 } else {
1197 NOT_REACHED();
1198 }
1199
1200 return msg;
1201}
d1e2cf21 1202
4ffd1b43 1203/* Converts an OFPST_FLOW or NXST_FLOW reply in 'msg' into an abstract
b78f6b77 1204 * ofputil_flow_stats in 'fs'.
4ffd1b43
BP
1205 *
1206 * Multiple OFPST_FLOW or NXST_FLOW replies can be packed into a single
1207 * OpenFlow message. Calling this function multiple times for a single 'msg'
1208 * iterates through the replies. The caller must initially leave 'msg''s layer
1209 * pointers null and not modify them between calls.
1210 *
1211 * Returns 0 if successful, EOF if no replies were left in this 'msg',
1212 * otherwise a positive errno value. */
1213int
1214ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
b78f6b77 1215 struct ofpbuf *msg)
4ffd1b43
BP
1216{
1217 const struct ofputil_msg_type *type;
1218 int code;
1219
1220 ofputil_decode_msg_type(msg->l2 ? msg->l2 : msg->data, &type);
1221 code = ofputil_msg_type_code(type);
1222 if (!msg->l2) {
1223 msg->l2 = msg->data;
1224 if (code == OFPUTIL_OFPST_FLOW_REPLY) {
28c8bad1 1225 ofpbuf_pull(msg, sizeof(struct ofp_stats_msg));
4ffd1b43
BP
1226 } else if (code == OFPUTIL_NXST_FLOW_REPLY) {
1227 ofpbuf_pull(msg, sizeof(struct nicira_stats_msg));
1228 } else {
1229 NOT_REACHED();
1230 }
1231 }
1232
1233 if (!msg->size) {
1234 return EOF;
1235 } else if (code == OFPUTIL_OFPST_FLOW_REPLY) {
1236 const struct ofp_flow_stats *ofs;
1237 size_t length;
1238
1239 ofs = ofpbuf_try_pull(msg, sizeof *ofs);
1240 if (!ofs) {
1241 VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply has %zu leftover "
1242 "bytes at end", msg->size);
1243 return EINVAL;
1244 }
1245
1246 length = ntohs(ofs->length);
1247 if (length < sizeof *ofs) {
1248 VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply claims invalid "
1249 "length %zu", length);
1250 return EINVAL;
1251 }
1252
1253 if (ofputil_pull_actions(msg, length - sizeof *ofs,
1254 &fs->actions, &fs->n_actions)) {
1255 return EINVAL;
1256 }
1257
1258 fs->cookie = get_32aligned_be64(&ofs->cookie);
1259 ofputil_cls_rule_from_match(&ofs->match, ntohs(ofs->priority),
b78f6b77 1260 &fs->rule);
4ffd1b43
BP
1261 fs->table_id = ofs->table_id;
1262 fs->duration_sec = ntohl(ofs->duration_sec);
1263 fs->duration_nsec = ntohl(ofs->duration_nsec);
1264 fs->idle_timeout = ntohs(ofs->idle_timeout);
1265 fs->hard_timeout = ntohs(ofs->hard_timeout);
1266 fs->packet_count = ntohll(get_32aligned_be64(&ofs->packet_count));
1267 fs->byte_count = ntohll(get_32aligned_be64(&ofs->byte_count));
1268 } else if (code == OFPUTIL_NXST_FLOW_REPLY) {
1269 const struct nx_flow_stats *nfs;
1270 size_t match_len, length;
1271
1272 nfs = ofpbuf_try_pull(msg, sizeof *nfs);
1273 if (!nfs) {
1274 VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW reply has %zu leftover "
1275 "bytes at end", msg->size);
1276 return EINVAL;
1277 }
1278
1279 length = ntohs(nfs->length);
1280 match_len = ntohs(nfs->match_len);
1281 if (length < sizeof *nfs + ROUND_UP(match_len, 8)) {
1282 VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW reply with match_len=%zu "
1283 "claims invalid length %zu", match_len, length);
1284 return EINVAL;
1285 }
1286 if (nx_pull_match(msg, match_len, ntohs(nfs->priority), &fs->rule)) {
1287 return EINVAL;
1288 }
1289
1290 if (ofputil_pull_actions(msg,
1291 length - sizeof *nfs - ROUND_UP(match_len, 8),
1292 &fs->actions, &fs->n_actions)) {
1293 return EINVAL;
1294 }
1295
1296 fs->cookie = nfs->cookie;
1297 fs->table_id = nfs->table_id;
1298 fs->duration_sec = ntohl(nfs->duration_sec);
1299 fs->duration_nsec = ntohl(nfs->duration_nsec);
1300 fs->idle_timeout = ntohs(nfs->idle_timeout);
1301 fs->hard_timeout = ntohs(nfs->hard_timeout);
1302 fs->packet_count = ntohll(nfs->packet_count);
1303 fs->byte_count = ntohll(nfs->byte_count);
1304 } else {
1305 NOT_REACHED();
1306 }
1307
1308 return 0;
1309}
1310
5e9d0469
BP
1311/* Returns 'count' unchanged except that UINT64_MAX becomes 0.
1312 *
1313 * We use this in situations where OVS internally uses UINT64_MAX to mean
1314 * "value unknown" but OpenFlow 1.0 does not define any unknown value. */
1315static uint64_t
1316unknown_to_zero(uint64_t count)
1317{
1318 return count != UINT64_MAX ? count : 0;
1319}
1320
349adfb2
BP
1321/* Appends an OFPST_FLOW or NXST_FLOW reply that contains the data in 'fs' to
1322 * those already present in the list of ofpbufs in 'replies'. 'replies' should
1323 * have been initialized with ofputil_start_stats_reply(). */
1324void
1325ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
1326 struct list *replies)
1327{
1328 size_t act_len = fs->n_actions * sizeof *fs->actions;
1329 const struct ofp_stats_msg *osm;
1330
1331 osm = ofpbuf_from_list(list_back(replies))->data;
1332 if (osm->type == htons(OFPST_FLOW)) {
1333 size_t len = offsetof(struct ofp_flow_stats, actions) + act_len;
1334 struct ofp_flow_stats *ofs;
1335
1336 ofs = ofputil_append_stats_reply(len, replies);
1337 ofs->length = htons(len);
1338 ofs->table_id = fs->table_id;
1339 ofs->pad = 0;
1340 ofputil_cls_rule_to_match(&fs->rule, &ofs->match);
1341 ofs->duration_sec = htonl(fs->duration_sec);
1342 ofs->duration_nsec = htonl(fs->duration_nsec);
1343 ofs->priority = htons(fs->rule.priority);
1344 ofs->idle_timeout = htons(fs->idle_timeout);
1345 ofs->hard_timeout = htons(fs->hard_timeout);
1346 memset(ofs->pad2, 0, sizeof ofs->pad2);
1347 put_32aligned_be64(&ofs->cookie, fs->cookie);
5e9d0469
BP
1348 put_32aligned_be64(&ofs->packet_count,
1349 htonll(unknown_to_zero(fs->packet_count)));
1350 put_32aligned_be64(&ofs->byte_count,
1351 htonll(unknown_to_zero(fs->byte_count)));
349adfb2
BP
1352 memcpy(ofs->actions, fs->actions, act_len);
1353 } else if (osm->type == htons(OFPST_VENDOR)) {
1354 struct nx_flow_stats *nfs;
1355 struct ofpbuf *msg;
1356 size_t start_len;
1357
1358 msg = ofputil_reserve_stats_reply(
1359 sizeof *nfs + NXM_MAX_LEN + act_len, replies);
1360 start_len = msg->size;
1361
1362 nfs = ofpbuf_put_uninit(msg, sizeof *nfs);
1363 nfs->table_id = fs->table_id;
1364 nfs->pad = 0;
1365 nfs->duration_sec = htonl(fs->duration_sec);
1366 nfs->duration_nsec = htonl(fs->duration_nsec);
1367 nfs->priority = htons(fs->rule.priority);
1368 nfs->idle_timeout = htons(fs->idle_timeout);
1369 nfs->hard_timeout = htons(fs->hard_timeout);
1370 nfs->match_len = htons(nx_put_match(msg, &fs->rule));
1371 memset(nfs->pad2, 0, sizeof nfs->pad2);
1372 nfs->cookie = fs->cookie;
1373 nfs->packet_count = htonll(fs->packet_count);
1374 nfs->byte_count = htonll(fs->byte_count);
1375 ofpbuf_put(msg, fs->actions, act_len);
1376 nfs->length = htons(msg->size - start_len);
1377 } else {
1378 NOT_REACHED();
1379 }
1380}
1381
76c93b22
BP
1382/* Converts abstract ofputil_aggregate_stats 'stats' into an OFPST_AGGREGATE or
1383 * NXST_AGGREGATE reply according to 'flow_format', and returns the message. */
1384struct ofpbuf *
1385ofputil_encode_aggregate_stats_reply(
1386 const struct ofputil_aggregate_stats *stats,
1387 const struct ofp_stats_msg *request)
1388{
1389 struct ofpbuf *msg;
1390
1391 if (request->type == htons(OFPST_AGGREGATE)) {
1392 struct ofp_aggregate_stats_reply *asr;
1393
1394 asr = ofputil_make_stats_reply(sizeof *asr, request, &msg);
5e9d0469
BP
1395 put_32aligned_be64(&asr->packet_count,
1396 htonll(unknown_to_zero(stats->packet_count)));
1397 put_32aligned_be64(&asr->byte_count,
1398 htonll(unknown_to_zero(stats->byte_count)));
76c93b22
BP
1399 asr->flow_count = htonl(stats->flow_count);
1400 } else if (request->type == htons(OFPST_VENDOR)) {
1401 struct nx_aggregate_stats_reply *nasr;
1402
1403 nasr = ofputil_make_stats_reply(sizeof *nasr, request, &msg);
1404 assert(nasr->nsm.subtype == htonl(NXST_AGGREGATE));
1405 nasr->packet_count = htonll(stats->packet_count);
1406 nasr->byte_count = htonll(stats->byte_count);
1407 nasr->flow_count = htonl(stats->flow_count);
1408 } else {
1409 NOT_REACHED();
1410 }
1411
1412 return msg;
1413}
1414
b78f6b77
BP
1415/* Converts an OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED message 'oh' into an
1416 * abstract ofputil_flow_removed in 'fr'. Returns 0 if successful, otherwise
1417 * an OpenFlow error code. */
9b045a0c
BP
1418int
1419ofputil_decode_flow_removed(struct ofputil_flow_removed *fr,
b78f6b77 1420 const struct ofp_header *oh)
9b045a0c
BP
1421{
1422 const struct ofputil_msg_type *type;
1423 enum ofputil_msg_code code;
1424
1425 ofputil_decode_msg_type(oh, &type);
1426 code = ofputil_msg_type_code(type);
1427 if (code == OFPUTIL_OFPT_FLOW_REMOVED) {
1428 const struct ofp_flow_removed *ofr;
1429
1430 ofr = (const struct ofp_flow_removed *) oh;
1431 ofputil_cls_rule_from_match(&ofr->match, ntohs(ofr->priority),
b78f6b77 1432 &fr->rule);
9b045a0c
BP
1433 fr->cookie = ofr->cookie;
1434 fr->reason = ofr->reason;
1435 fr->duration_sec = ntohl(ofr->duration_sec);
1436 fr->duration_nsec = ntohl(ofr->duration_nsec);
1437 fr->idle_timeout = ntohs(ofr->idle_timeout);
1438 fr->packet_count = ntohll(ofr->packet_count);
1439 fr->byte_count = ntohll(ofr->byte_count);
1440 } else if (code == OFPUTIL_NXT_FLOW_REMOVED) {
1441 struct nx_flow_removed *nfr;
1442 struct ofpbuf b;
1443 int error;
1444
1445 ofpbuf_use_const(&b, oh, ntohs(oh->length));
1446
1447 nfr = ofpbuf_pull(&b, sizeof *nfr);
1448 error = nx_pull_match(&b, ntohs(nfr->match_len), ntohs(nfr->priority),
1449 &fr->rule);
1450 if (error) {
1451 return error;
1452 }
1453 if (b.size) {
1454 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
1455 }
1456
1457 fr->cookie = nfr->cookie;
1458 fr->reason = nfr->reason;
1459 fr->duration_sec = ntohl(nfr->duration_sec);
1460 fr->duration_nsec = ntohl(nfr->duration_nsec);
1461 fr->idle_timeout = ntohs(nfr->idle_timeout);
1462 fr->packet_count = ntohll(nfr->packet_count);
1463 fr->byte_count = ntohll(nfr->byte_count);
1464 } else {
1465 NOT_REACHED();
1466 }
1467
1468 return 0;
1469}
1470
588cd7b5
BP
1471/* Converts abstract ofputil_flow_removed 'fr' into an OFPT_FLOW_REMOVED or
1472 * NXT_FLOW_REMOVED message 'oh' according to 'flow_format', and returns the
1473 * message. */
1474struct ofpbuf *
1475ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
1476 enum nx_flow_format flow_format)
1477{
1478 struct ofpbuf *msg;
1479
b78f6b77 1480 if (flow_format == NXFF_OPENFLOW10) {
588cd7b5
BP
1481 struct ofp_flow_removed *ofr;
1482
1483 ofr = make_openflow_xid(sizeof *ofr, OFPT_FLOW_REMOVED, htonl(0),
1484 &msg);
b78f6b77 1485 ofputil_cls_rule_to_match(&fr->rule, &ofr->match);
7fb563b9 1486 ofr->cookie = fr->cookie;
588cd7b5
BP
1487 ofr->priority = htons(fr->rule.priority);
1488 ofr->reason = fr->reason;
1489 ofr->duration_sec = htonl(fr->duration_sec);
1490 ofr->duration_nsec = htonl(fr->duration_nsec);
1491 ofr->idle_timeout = htons(fr->idle_timeout);
5e9d0469
BP
1492 ofr->packet_count = htonll(unknown_to_zero(fr->packet_count));
1493 ofr->byte_count = htonll(unknown_to_zero(fr->byte_count));
588cd7b5
BP
1494 } else if (flow_format == NXFF_NXM) {
1495 struct nx_flow_removed *nfr;
1496 int match_len;
1497
1498 make_nxmsg_xid(sizeof *nfr, NXT_FLOW_REMOVED, htonl(0), &msg);
1499 match_len = nx_put_match(msg, &fr->rule);
1500
1501 nfr = msg->data;
1502 nfr->cookie = fr->cookie;
1503 nfr->priority = htons(fr->rule.priority);
1504 nfr->reason = fr->reason;
1505 nfr->duration_sec = htonl(fr->duration_sec);
1506 nfr->duration_nsec = htonl(fr->duration_nsec);
1507 nfr->idle_timeout = htons(fr->idle_timeout);
1508 nfr->match_len = htons(match_len);
1509 nfr->packet_count = htonll(fr->packet_count);
1510 nfr->byte_count = htonll(fr->byte_count);
1511 } else {
1512 NOT_REACHED();
1513 }
1514
1515 return msg;
1516}
1517
ebb57021
BP
1518/* Converts abstract ofputil_packet_in 'pin' into an OFPT_PACKET_IN message
1519 * and returns the message.
1520 *
1521 * If 'rw_packet' is NULL, the caller takes ownership of the newly allocated
1522 * returned ofpbuf.
1523 *
1524 * If 'rw_packet' is nonnull, then it must contain the same data as
1525 * pin->packet. 'rw_packet' is allowed to be the same ofpbuf as pin->packet.
1526 * It is modified in-place into an OFPT_PACKET_IN message according to 'pin',
1527 * and then ofputil_encode_packet_in() returns 'rw_packet'. If 'rw_packet' has
1528 * enough headroom to insert a "struct ofp_packet_in", this is more efficient
1529 * than ofputil_encode_packet_in() because it does not copy the packet
1530 * payload. */
1531struct ofpbuf *
1532ofputil_encode_packet_in(const struct ofputil_packet_in *pin,
1533 struct ofpbuf *rw_packet)
1534{
1535 int total_len = pin->packet->size;
62698c77 1536 struct ofp_packet_in opi;
ebb57021
BP
1537
1538 if (rw_packet) {
1539 if (pin->send_len < rw_packet->size) {
1540 rw_packet->size = pin->send_len;
1541 }
1542 } else {
1543 rw_packet = ofpbuf_clone_data_with_headroom(
1544 pin->packet->data, MIN(pin->send_len, pin->packet->size),
1545 offsetof(struct ofp_packet_in, data));
1546 }
1547
1548 /* Add OFPT_PACKET_IN. */
62698c77
BP
1549 memset(&opi, 0, sizeof opi);
1550 opi.header.version = OFP_VERSION;
1551 opi.header.type = OFPT_PACKET_IN;
1552 opi.total_len = htons(total_len);
1553 opi.in_port = htons(pin->in_port);
1554 opi.reason = pin->reason;
1555 opi.buffer_id = htonl(pin->buffer_id);
1556 ofpbuf_push(rw_packet, &opi, offsetof(struct ofp_packet_in, data));
ebb57021
BP
1557 update_openflow_length(rw_packet);
1558
1559 return rw_packet;
1560}
1561
d1e2cf21
BP
1562/* Returns a string representing the message type of 'type'. The string is the
1563 * enumeration constant for the type, e.g. "OFPT_HELLO". For statistics
1564 * messages, the constant is followed by "request" or "reply",
1565 * e.g. "OFPST_AGGREGATE reply". */
1566const char *
1567ofputil_msg_type_name(const struct ofputil_msg_type *type)
1568{
1569 return type->name;
1570}
1571\f
fa37b408
BP
1572/* Allocates and stores in '*bufferp' a new ofpbuf with a size of
1573 * 'openflow_len', starting with an OpenFlow header with the given 'type' and
1574 * an arbitrary transaction id. Allocated bytes beyond the header, if any, are
1575 * zeroed.
1576 *
1577 * The caller is responsible for freeing '*bufferp' when it is no longer
1578 * needed.
1579 *
1580 * The OpenFlow header length is initially set to 'openflow_len'; if the
1581 * message is later extended, the length should be updated with
1582 * update_openflow_length() before sending.
1583 *
1584 * Returns the header. */
1585void *
1586make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **bufferp)
1587{
1588 *bufferp = ofpbuf_new(openflow_len);
1589 return put_openflow_xid(openflow_len, type, alloc_xid(), *bufferp);
1590}
1591
0bd0c660
BP
1592/* Similar to make_openflow() but creates a Nicira vendor extension message
1593 * with the specific 'subtype'. 'subtype' should be in host byte order. */
1594void *
1595make_nxmsg(size_t openflow_len, uint32_t subtype, struct ofpbuf **bufferp)
1596{
1597 return make_nxmsg_xid(openflow_len, subtype, alloc_xid(), bufferp);
1598}
1599
fa37b408
BP
1600/* Allocates and stores in '*bufferp' a new ofpbuf with a size of
1601 * 'openflow_len', starting with an OpenFlow header with the given 'type' and
1602 * transaction id 'xid'. Allocated bytes beyond the header, if any, are
1603 * zeroed.
1604 *
1605 * The caller is responsible for freeing '*bufferp' when it is no longer
1606 * needed.
1607 *
1608 * The OpenFlow header length is initially set to 'openflow_len'; if the
1609 * message is later extended, the length should be updated with
1610 * update_openflow_length() before sending.
1611 *
1612 * Returns the header. */
1613void *
44381c1b 1614make_openflow_xid(size_t openflow_len, uint8_t type, ovs_be32 xid,
fa37b408
BP
1615 struct ofpbuf **bufferp)
1616{
1617 *bufferp = ofpbuf_new(openflow_len);
1618 return put_openflow_xid(openflow_len, type, xid, *bufferp);
1619}
1620
0bd0c660
BP
1621/* Similar to make_openflow_xid() but creates a Nicira vendor extension message
1622 * with the specific 'subtype'. 'subtype' should be in host byte order. */
1623void *
44381c1b 1624make_nxmsg_xid(size_t openflow_len, uint32_t subtype, ovs_be32 xid,
0bd0c660
BP
1625 struct ofpbuf **bufferp)
1626{
dfdfc8d4
BP
1627 *bufferp = ofpbuf_new(openflow_len);
1628 return put_nxmsg_xid(openflow_len, subtype, xid, *bufferp);
0bd0c660
BP
1629}
1630
fa37b408
BP
1631/* Appends 'openflow_len' bytes to 'buffer', starting with an OpenFlow header
1632 * with the given 'type' and an arbitrary transaction id. Allocated bytes
1633 * beyond the header, if any, are zeroed.
1634 *
1635 * The OpenFlow header length is initially set to 'openflow_len'; if the
1636 * message is later extended, the length should be updated with
1637 * update_openflow_length() before sending.
1638 *
1639 * Returns the header. */
1640void *
1641put_openflow(size_t openflow_len, uint8_t type, struct ofpbuf *buffer)
1642{
1643 return put_openflow_xid(openflow_len, type, alloc_xid(), buffer);
1644}
1645
1646/* Appends 'openflow_len' bytes to 'buffer', starting with an OpenFlow header
1647 * with the given 'type' and an transaction id 'xid'. Allocated bytes beyond
1648 * the header, if any, are zeroed.
1649 *
1650 * The OpenFlow header length is initially set to 'openflow_len'; if the
1651 * message is later extended, the length should be updated with
1652 * update_openflow_length() before sending.
1653 *
1654 * Returns the header. */
1655void *
44381c1b 1656put_openflow_xid(size_t openflow_len, uint8_t type, ovs_be32 xid,
fa37b408
BP
1657 struct ofpbuf *buffer)
1658{
1659 struct ofp_header *oh;
1660
1661 assert(openflow_len >= sizeof *oh);
1662 assert(openflow_len <= UINT16_MAX);
1663
1664 oh = ofpbuf_put_uninit(buffer, openflow_len);
1665 oh->version = OFP_VERSION;
1666 oh->type = type;
1667 oh->length = htons(openflow_len);
1668 oh->xid = xid;
1669 memset(oh + 1, 0, openflow_len - sizeof *oh);
1670 return oh;
1671}
1672
dfdfc8d4
BP
1673/* Similar to put_openflow() but append a Nicira vendor extension message with
1674 * the specific 'subtype'. 'subtype' should be in host byte order. */
1675void *
1676put_nxmsg(size_t openflow_len, uint32_t subtype, struct ofpbuf *buffer)
1677{
1678 return put_nxmsg_xid(openflow_len, subtype, alloc_xid(), buffer);
1679}
1680
1681/* Similar to put_openflow_xid() but append a Nicira vendor extension message
1682 * with the specific 'subtype'. 'subtype' should be in host byte order. */
1683void *
1684put_nxmsg_xid(size_t openflow_len, uint32_t subtype, ovs_be32 xid,
1685 struct ofpbuf *buffer)
1686{
1687 struct nicira_header *nxh;
1688
1689 nxh = put_openflow_xid(openflow_len, OFPT_VENDOR, xid, buffer);
1690 nxh->vendor = htonl(NX_VENDOR_ID);
1691 nxh->subtype = htonl(subtype);
1692 return nxh;
1693}
1694
fa37b408
BP
1695/* Updates the 'length' field of the OpenFlow message in 'buffer' to
1696 * 'buffer->size'. */
1697void
d295e8e9 1698update_openflow_length(struct ofpbuf *buffer)
fa37b408
BP
1699{
1700 struct ofp_header *oh = ofpbuf_at_assert(buffer, 0, sizeof *oh);
d295e8e9 1701 oh->length = htons(buffer->size);
fa37b408
BP
1702}
1703
63f2140a
BP
1704static void
1705put_stats__(ovs_be32 xid, uint8_t ofp_type,
1706 ovs_be16 ofpst_type, ovs_be32 nxst_subtype,
1707 struct ofpbuf *msg)
1708{
1709 if (ofpst_type == htons(OFPST_VENDOR)) {
1710 struct nicira_stats_msg *nsm;
1711
1712 nsm = put_openflow_xid(sizeof *nsm, ofp_type, xid, msg);
1713 nsm->vsm.osm.type = ofpst_type;
1714 nsm->vsm.vendor = htonl(NX_VENDOR_ID);
1715 nsm->subtype = nxst_subtype;
1716 } else {
1717 struct ofp_stats_msg *osm;
1718
1719 osm = put_openflow_xid(sizeof *osm, ofp_type, xid, msg);
1720 osm->type = ofpst_type;
1721 }
1722}
1723
1724/* Creates a statistics request message with total length 'openflow_len'
1725 * (including all headers) and the given 'ofpst_type', and stores the buffer
1726 * containing the new message in '*bufferp'. If 'ofpst_type' is OFPST_VENDOR
1727 * then 'nxst_subtype' is used as the Nicira vendor extension statistics
1728 * subtype (otherwise 'nxst_subtype' is ignored).
1729 *
1730 * Initializes bytes following the headers to all-bits-zero.
1731 *
1732 * Returns the first byte of the new message. */
dfdfc8d4 1733void *
63f2140a
BP
1734ofputil_make_stats_request(size_t openflow_len, uint16_t ofpst_type,
1735 uint32_t nxst_subtype, struct ofpbuf **bufferp)
dfdfc8d4 1736{
63f2140a
BP
1737 struct ofpbuf *msg;
1738
1739 msg = *bufferp = ofpbuf_new(openflow_len);
1740 put_stats__(alloc_xid(), OFPT_STATS_REQUEST,
1741 htons(ofpst_type), htonl(nxst_subtype), msg);
1742 ofpbuf_padto(msg, openflow_len);
1743
1744 return msg->data;
1745}
1746
1747static void
1748put_stats_reply__(const struct ofp_stats_msg *request, struct ofpbuf *msg)
1749{
1750 assert(request->header.type == OFPT_STATS_REQUEST ||
1751 request->header.type == OFPT_STATS_REPLY);
1752 put_stats__(request->header.xid, OFPT_STATS_REPLY, request->type,
1753 (request->type != htons(OFPST_VENDOR)
1754 ? htonl(0)
1755 : ((const struct nicira_stats_msg *) request)->subtype),
1756 msg);
1757}
1758
1759/* Creates a statistics reply message with total length 'openflow_len'
1760 * (including all headers) and the same type (either a standard OpenFlow
1761 * statistics type or a Nicira extension type and subtype) as 'request', and
1762 * stores the buffer containing the new message in '*bufferp'.
1763 *
1764 * Initializes bytes following the headers to all-bits-zero.
1765 *
1766 * Returns the first byte of the new message. */
1767void *
1768ofputil_make_stats_reply(size_t openflow_len,
1769 const struct ofp_stats_msg *request,
1770 struct ofpbuf **bufferp)
1771{
1772 struct ofpbuf *msg;
1773
1774 msg = *bufferp = ofpbuf_new(openflow_len);
1775 put_stats_reply__(request, msg);
1776 ofpbuf_padto(msg, openflow_len);
1777
1778 return msg->data;
1779}
1780
1781/* Initializes 'replies' as a list of ofpbufs that will contain a series of
1782 * replies to 'request', which should be an OpenFlow or Nicira extension
1783 * statistics request. Initially 'replies' will have a single reply message
1784 * that has only a header. The functions ofputil_reserve_stats_reply() and
1785 * ofputil_append_stats_reply() may be used to add to the reply. */
1786void
1787ofputil_start_stats_reply(const struct ofp_stats_msg *request,
1788 struct list *replies)
1789{
1790 struct ofpbuf *msg;
1791
1792 msg = ofpbuf_new(1024);
1793 put_stats_reply__(request, msg);
1794
1795 list_init(replies);
1796 list_push_back(replies, &msg->list_node);
1797}
1798
1799/* Prepares to append up to 'len' bytes to the series of statistics replies in
1800 * 'replies', which should have been initialized with
1801 * ofputil_start_stats_reply(). Returns an ofpbuf with at least 'len' bytes of
1802 * tailroom. (The 'len' bytes have not actually be allocated; the caller must
1803 * do so with e.g. ofpbuf_put_uninit().) */
1804struct ofpbuf *
1805ofputil_reserve_stats_reply(size_t len, struct list *replies)
1806{
1807 struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
1808 struct ofp_stats_msg *osm = msg->data;
1809
1810 if (msg->size + len <= UINT16_MAX) {
1811 ofpbuf_prealloc_tailroom(msg, len);
1812 } else {
1813 osm->flags |= htons(OFPSF_REPLY_MORE);
1814
1815 msg = ofpbuf_new(MAX(1024, sizeof(struct nicira_stats_msg) + len));
1816 put_stats_reply__(osm, msg);
1817 list_push_back(replies, &msg->list_node);
1818 }
1819 return msg;
dfdfc8d4
BP
1820}
1821
63f2140a
BP
1822/* Appends 'len' bytes to the series of statistics replies in 'replies', and
1823 * returns the first byte. */
dfdfc8d4 1824void *
63f2140a 1825ofputil_append_stats_reply(size_t len, struct list *replies)
dfdfc8d4 1826{
63f2140a 1827 return ofpbuf_put_uninit(ofputil_reserve_stats_reply(len, replies), len);
dfdfc8d4
BP
1828}
1829
03cd3493 1830/* Returns the first byte past the ofp_stats_msg header in 'oh'. */
d1e2cf21
BP
1831const void *
1832ofputil_stats_body(const struct ofp_header *oh)
1833{
1834 assert(oh->type == OFPT_STATS_REQUEST || oh->type == OFPT_STATS_REPLY);
28c8bad1 1835 return (const struct ofp_stats_msg *) oh + 1;
d1e2cf21
BP
1836}
1837
03cd3493 1838/* Returns the number of bytes past the ofp_stats_msg header in 'oh'. */
d1e2cf21
BP
1839size_t
1840ofputil_stats_body_len(const struct ofp_header *oh)
1841{
1842 assert(oh->type == OFPT_STATS_REQUEST || oh->type == OFPT_STATS_REPLY);
28c8bad1 1843 return ntohs(oh->length) - sizeof(struct ofp_stats_msg);
d1e2cf21
BP
1844}
1845
03cd3493 1846/* Returns the first byte past the nicira_stats_msg header in 'oh'. */
c6430da5
BP
1847const void *
1848ofputil_nxstats_body(const struct ofp_header *oh)
1849{
1850 assert(oh->type == OFPT_STATS_REQUEST || oh->type == OFPT_STATS_REPLY);
1851 return ((const struct nicira_stats_msg *) oh) + 1;
1852}
1853
03cd3493 1854/* Returns the number of bytes past the nicira_stats_msg header in 'oh'. */
c6430da5
BP
1855size_t
1856ofputil_nxstats_body_len(const struct ofp_header *oh)
1857{
1858 assert(oh->type == OFPT_STATS_REQUEST || oh->type == OFPT_STATS_REPLY);
1859 return ntohs(oh->length) - sizeof(struct nicira_stats_msg);
1860}
1861
fa37b408 1862struct ofpbuf *
daa68e9f
BP
1863make_flow_mod(uint16_t command, const struct cls_rule *rule,
1864 size_t actions_len)
fa37b408
BP
1865{
1866 struct ofp_flow_mod *ofm;
1867 size_t size = sizeof *ofm + actions_len;
1868 struct ofpbuf *out = ofpbuf_new(size);
1869 ofm = ofpbuf_put_zeros(out, sizeof *ofm);
1870 ofm->header.version = OFP_VERSION;
1871 ofm->header.type = OFPT_FLOW_MOD;
1872 ofm->header.length = htons(size);
1873 ofm->cookie = 0;
daa68e9f 1874 ofm->priority = htons(MIN(rule->priority, UINT16_MAX));
b78f6b77 1875 ofputil_cls_rule_to_match(rule, &ofm->match);
fa37b408
BP
1876 ofm->command = htons(command);
1877 return out;
1878}
1879
1880struct ofpbuf *
daa68e9f 1881make_add_flow(const struct cls_rule *rule, uint32_t buffer_id,
fa37b408
BP
1882 uint16_t idle_timeout, size_t actions_len)
1883{
daa68e9f 1884 struct ofpbuf *out = make_flow_mod(OFPFC_ADD, rule, actions_len);
fa37b408
BP
1885 struct ofp_flow_mod *ofm = out->data;
1886 ofm->idle_timeout = htons(idle_timeout);
1887 ofm->hard_timeout = htons(OFP_FLOW_PERMANENT);
1888 ofm->buffer_id = htonl(buffer_id);
1889 return out;
1890}
1891
1892struct ofpbuf *
daa68e9f 1893make_del_flow(const struct cls_rule *rule)
fa37b408 1894{
daa68e9f 1895 struct ofpbuf *out = make_flow_mod(OFPFC_DELETE_STRICT, rule, 0);
fa37b408
BP
1896 struct ofp_flow_mod *ofm = out->data;
1897 ofm->out_port = htons(OFPP_NONE);
1898 return out;
1899}
1900
1901struct ofpbuf *
daa68e9f 1902make_add_simple_flow(const struct cls_rule *rule,
fa37b408
BP
1903 uint32_t buffer_id, uint16_t out_port,
1904 uint16_t idle_timeout)
1905{
81f3cad4
BP
1906 if (out_port != OFPP_NONE) {
1907 struct ofp_action_output *oao;
1908 struct ofpbuf *buffer;
1909
daa68e9f 1910 buffer = make_add_flow(rule, buffer_id, idle_timeout, sizeof *oao);
93996add 1911 ofputil_put_OFPAT_OUTPUT(buffer)->port = htons(out_port);
81f3cad4
BP
1912 return buffer;
1913 } else {
daa68e9f 1914 return make_add_flow(rule, buffer_id, idle_timeout, 0);
81f3cad4 1915 }
fa37b408
BP
1916}
1917
1918struct ofpbuf *
1919make_packet_in(uint32_t buffer_id, uint16_t in_port, uint8_t reason,
1920 const struct ofpbuf *payload, int max_send_len)
1921{
1922 struct ofp_packet_in *opi;
1923 struct ofpbuf *buf;
1924 int send_len;
1925
1926 send_len = MIN(max_send_len, payload->size);
1927 buf = ofpbuf_new(sizeof *opi + send_len);
1928 opi = put_openflow_xid(offsetof(struct ofp_packet_in, data),
1929 OFPT_PACKET_IN, 0, buf);
1930 opi->buffer_id = htonl(buffer_id);
1931 opi->total_len = htons(payload->size);
1932 opi->in_port = htons(in_port);
1933 opi->reason = reason;
1934 ofpbuf_put(buf, payload->data, send_len);
1935 update_openflow_length(buf);
1936
1937 return buf;
1938}
1939
1940struct ofpbuf *
1941make_packet_out(const struct ofpbuf *packet, uint32_t buffer_id,
1942 uint16_t in_port,
1943 const struct ofp_action_header *actions, size_t n_actions)
1944{
1945 size_t actions_len = n_actions * sizeof *actions;
1946 struct ofp_packet_out *opo;
1947 size_t size = sizeof *opo + actions_len + (packet ? packet->size : 0);
1948 struct ofpbuf *out = ofpbuf_new(size);
1949
1950 opo = ofpbuf_put_uninit(out, sizeof *opo);
1951 opo->header.version = OFP_VERSION;
1952 opo->header.type = OFPT_PACKET_OUT;
1953 opo->header.length = htons(size);
1954 opo->header.xid = htonl(0);
1955 opo->buffer_id = htonl(buffer_id);
6c24d402 1956 opo->in_port = htons(in_port);
fa37b408
BP
1957 opo->actions_len = htons(actions_len);
1958 ofpbuf_put(out, actions, actions_len);
1959 if (packet) {
1960 ofpbuf_put(out, packet->data, packet->size);
1961 }
1962 return out;
1963}
1964
1965struct ofpbuf *
1966make_unbuffered_packet_out(const struct ofpbuf *packet,
1967 uint16_t in_port, uint16_t out_port)
1968{
1969 struct ofp_action_output action;
1970 action.type = htons(OFPAT_OUTPUT);
1971 action.len = htons(sizeof action);
1972 action.port = htons(out_port);
1973 return make_packet_out(packet, UINT32_MAX, in_port,
1974 (struct ofp_action_header *) &action, 1);
1975}
1976
1977struct ofpbuf *
1978make_buffered_packet_out(uint32_t buffer_id,
1979 uint16_t in_port, uint16_t out_port)
1980{
81f3cad4
BP
1981 if (out_port != OFPP_NONE) {
1982 struct ofp_action_output action;
1983 action.type = htons(OFPAT_OUTPUT);
1984 action.len = htons(sizeof action);
1985 action.port = htons(out_port);
1986 return make_packet_out(NULL, buffer_id, in_port,
1987 (struct ofp_action_header *) &action, 1);
1988 } else {
1989 return make_packet_out(NULL, buffer_id, in_port, NULL, 0);
1990 }
fa37b408
BP
1991}
1992
1993/* Creates and returns an OFPT_ECHO_REQUEST message with an empty payload. */
1994struct ofpbuf *
1995make_echo_request(void)
1996{
1997 struct ofp_header *rq;
1998 struct ofpbuf *out = ofpbuf_new(sizeof *rq);
1999 rq = ofpbuf_put_uninit(out, sizeof *rq);
2000 rq->version = OFP_VERSION;
2001 rq->type = OFPT_ECHO_REQUEST;
2002 rq->length = htons(sizeof *rq);
44381c1b 2003 rq->xid = htonl(0);
fa37b408
BP
2004 return out;
2005}
2006
2007/* Creates and returns an OFPT_ECHO_REPLY message matching the
2008 * OFPT_ECHO_REQUEST message in 'rq'. */
2009struct ofpbuf *
2010make_echo_reply(const struct ofp_header *rq)
2011{
2012 size_t size = ntohs(rq->length);
2013 struct ofpbuf *out = ofpbuf_new(size);
2014 struct ofp_header *reply = ofpbuf_put(out, rq, size);
2015 reply->type = OFPT_ECHO_REPLY;
2016 return out;
2017}
2018
7257b535
BP
2019const char *
2020ofputil_frag_handling_to_string(enum ofp_config_flags flags)
2021{
2022 switch (flags & OFPC_FRAG_MASK) {
2023 case OFPC_FRAG_NORMAL: return "normal";
2024 case OFPC_FRAG_DROP: return "drop";
2025 case OFPC_FRAG_REASM: return "reassemble";
2026 case OFPC_FRAG_NX_MATCH: return "nx-match";
2027 }
2028
2029 NOT_REACHED();
2030}
2031
2032bool
2033ofputil_frag_handling_from_string(const char *s, enum ofp_config_flags *flags)
2034{
2035 if (!strcasecmp(s, "normal")) {
2036 *flags = OFPC_FRAG_NORMAL;
2037 } else if (!strcasecmp(s, "drop")) {
2038 *flags = OFPC_FRAG_DROP;
2039 } else if (!strcasecmp(s, "reassemble")) {
2040 *flags = OFPC_FRAG_REASM;
2041 } else if (!strcasecmp(s, "nx-match")) {
2042 *flags = OFPC_FRAG_NX_MATCH;
2043 } else {
2044 return false;
2045 }
2046 return true;
2047}
2048
c1c9c9c4
BP
2049/* Checks that 'port' is a valid output port for the OFPAT_OUTPUT action, given
2050 * that the switch will never have more than 'max_ports' ports. Returns 0 if
2051 * 'port' is valid, otherwise an ofp_mkerr() return code. */
77410139
EJ
2052int
2053ofputil_check_output_port(uint16_t port, int max_ports)
fa37b408
BP
2054{
2055 switch (port) {
2056 case OFPP_IN_PORT:
2057 case OFPP_TABLE:
2058 case OFPP_NORMAL:
2059 case OFPP_FLOOD:
2060 case OFPP_ALL:
2061 case OFPP_CONTROLLER:
2062 case OFPP_LOCAL:
2063 return 0;
2064
2065 default:
c1c9c9c4 2066 if (port < max_ports) {
fa37b408
BP
2067 return 0;
2068 }
fa37b408
BP
2069 return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT);
2070 }
2071}
2072
39dc9082
BP
2073#define OFPUTIL_NAMED_PORTS \
2074 OFPUTIL_NAMED_PORT(IN_PORT) \
2075 OFPUTIL_NAMED_PORT(TABLE) \
2076 OFPUTIL_NAMED_PORT(NORMAL) \
2077 OFPUTIL_NAMED_PORT(FLOOD) \
2078 OFPUTIL_NAMED_PORT(ALL) \
2079 OFPUTIL_NAMED_PORT(CONTROLLER) \
2080 OFPUTIL_NAMED_PORT(LOCAL) \
2081 OFPUTIL_NAMED_PORT(NONE)
2082
2083/* Checks whether 's' is the string representation of an OpenFlow port number,
2084 * either as an integer or a string name (e.g. "LOCAL"). If it is, stores the
2085 * number in '*port' and returns true. Otherwise, returns false. */
2086bool
2087ofputil_port_from_string(const char *name, uint16_t *port)
2088{
2089 struct pair {
2090 const char *name;
2091 uint16_t value;
2092 };
2093 static const struct pair pairs[] = {
2094#define OFPUTIL_NAMED_PORT(NAME) {#NAME, OFPP_##NAME},
2095 OFPUTIL_NAMED_PORTS
2096#undef OFPUTIL_NAMED_PORT
2097 };
2098 static const int n_pairs = ARRAY_SIZE(pairs);
2099 int i;
2100
2101 if (str_to_int(name, 0, &i) && i >= 0 && i < UINT16_MAX) {
2102 *port = i;
2103 return true;
2104 }
2105
2106 for (i = 0; i < n_pairs; i++) {
2107 if (!strcasecmp(name, pairs[i].name)) {
2108 *port = pairs[i].value;
2109 return true;
2110 }
2111 }
2112 return false;
2113}
2114
2115/* Appends to 's' a string representation of the OpenFlow port number 'port'.
2116 * Most ports' string representation is just the port number, but for special
2117 * ports, e.g. OFPP_LOCAL, it is the name, e.g. "LOCAL". */
2118void
2119ofputil_format_port(uint16_t port, struct ds *s)
2120{
2121 const char *name;
2122
2123 switch (port) {
2124#define OFPUTIL_NAMED_PORT(NAME) case OFPP_##NAME: name = #NAME; break;
2125 OFPUTIL_NAMED_PORTS
2126#undef OFPUTIL_NAMED_PORT
2127
2128 default:
2129 ds_put_format(s, "%"PRIu16, port);
2130 return;
2131 }
2132 ds_put_cstr(s, name);
2133}
2134
29901626
BP
2135static int
2136check_resubmit_table(const struct nx_action_resubmit *nar)
2137{
2138 if (nar->pad[0] || nar->pad[1] || nar->pad[2]) {
2139 return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
2140 }
2141 return 0;
2142}
2143
f694937d
EJ
2144static int
2145check_output_reg(const struct nx_action_output_reg *naor,
2146 const struct flow *flow)
2147{
2148 size_t i;
2149
2150 for (i = 0; i < sizeof naor->zero; i++) {
2151 if (naor->zero[i]) {
2152 return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
2153 }
2154 }
2155
2156 return nxm_src_check(naor->src, nxm_decode_ofs(naor->ofs_nbits),
2157 nxm_decode_n_bits(naor->ofs_nbits), flow);
2158}
2159
38f2e360
BP
2160int
2161validate_actions(const union ofp_action *actions, size_t n_actions,
2162 const struct flow *flow, int max_ports)
c1c9c9c4 2163{
38f2e360
BP
2164 const union ofp_action *a;
2165 size_t left;
c1c9c9c4 2166
38f2e360
BP
2167 OFPUTIL_ACTION_FOR_EACH (a, left, actions, n_actions) {
2168 uint16_t port;
2169 int error;
2170 int code;
c1c9c9c4 2171
38f2e360
BP
2172 code = ofputil_decode_action(a);
2173 if (code < 0) {
2174 char *msg;
c1c9c9c4 2175
38f2e360
BP
2176 error = -code;
2177 msg = ofputil_error_to_string(error);
2178 VLOG_WARN_RL(&bad_ofmsg_rl,
2179 "action decoding error at offset %td (%s)",
2180 (a - actions) * sizeof *a, msg);
2181 free(msg);
fa37b408 2182
38f2e360
BP
2183 return error;
2184 }
fa37b408 2185
38f2e360
BP
2186 error = 0;
2187 switch ((enum ofputil_action_code) code) {
2188 case OFPUTIL_OFPAT_OUTPUT:
77410139
EJ
2189 error = ofputil_check_output_port(ntohs(a->output.port),
2190 max_ports);
38f2e360 2191 break;
e41a9130 2192
38f2e360
BP
2193 case OFPUTIL_OFPAT_SET_VLAN_VID:
2194 if (a->vlan_vid.vlan_vid & ~htons(0xfff)) {
2195 error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
2196 }
2197 break;
96fc46e8 2198
38f2e360
BP
2199 case OFPUTIL_OFPAT_SET_VLAN_PCP:
2200 if (a->vlan_pcp.vlan_pcp & ~7) {
2201 error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
2202 }
2203 break;
96fc46e8 2204
38f2e360
BP
2205 case OFPUTIL_OFPAT_ENQUEUE:
2206 port = ntohs(((const struct ofp_action_enqueue *) a)->port);
2207 if (port >= max_ports && port != OFPP_IN_PORT) {
2208 error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT);
2209 }
2210 break;
96fc46e8 2211
38f2e360
BP
2212 case OFPUTIL_NXAST_REG_MOVE:
2213 error = nxm_check_reg_move((const struct nx_action_reg_move *) a,
2214 flow);
2215 break;
96fc46e8 2216
38f2e360
BP
2217 case OFPUTIL_NXAST_REG_LOAD:
2218 error = nxm_check_reg_load((const struct nx_action_reg_load *) a,
2219 flow);
2220 break;
b9298d3f 2221
38f2e360 2222 case OFPUTIL_NXAST_MULTIPATH:
43edca57
EJ
2223 error = multipath_check((const struct nx_action_multipath *) a,
2224 flow);
38f2e360
BP
2225 break;
2226
2227 case OFPUTIL_NXAST_AUTOPATH:
43edca57
EJ
2228 error = autopath_check((const struct nx_action_autopath *) a,
2229 flow);
38f2e360
BP
2230 break;
2231
daff3353 2232 case OFPUTIL_NXAST_BUNDLE:
a368bb53 2233 case OFPUTIL_NXAST_BUNDLE_LOAD:
daff3353 2234 error = bundle_check((const struct nx_action_bundle *) a,
a368bb53 2235 max_ports, flow);
daff3353
EJ
2236 break;
2237
f694937d
EJ
2238 case OFPUTIL_NXAST_OUTPUT_REG:
2239 error = check_output_reg((const struct nx_action_output_reg *) a,
2240 flow);
2241 break;
2242
29901626
BP
2243 case OFPUTIL_NXAST_RESUBMIT_TABLE:
2244 error = check_resubmit_table(
2245 (const struct nx_action_resubmit *) a);
2246 break;
2247
75a75043
BP
2248 case OFPUTIL_NXAST_LEARN:
2249 error = learn_check((const struct nx_action_learn *) a, flow);
2250 break;
2251
38f2e360
BP
2252 case OFPUTIL_OFPAT_STRIP_VLAN:
2253 case OFPUTIL_OFPAT_SET_NW_SRC:
2254 case OFPUTIL_OFPAT_SET_NW_DST:
2255 case OFPUTIL_OFPAT_SET_NW_TOS:
2256 case OFPUTIL_OFPAT_SET_TP_SRC:
2257 case OFPUTIL_OFPAT_SET_TP_DST:
2258 case OFPUTIL_OFPAT_SET_DL_SRC:
2259 case OFPUTIL_OFPAT_SET_DL_DST:
2260 case OFPUTIL_NXAST_RESUBMIT:
2261 case OFPUTIL_NXAST_SET_TUNNEL:
2262 case OFPUTIL_NXAST_SET_QUEUE:
2263 case OFPUTIL_NXAST_POP_QUEUE:
2264 case OFPUTIL_NXAST_NOTE:
2265 case OFPUTIL_NXAST_SET_TUNNEL64:
848e8809 2266 case OFPUTIL_NXAST_EXIT:
38f2e360 2267 break;
53ddd40a 2268 }
53ddd40a 2269
3b6a2571 2270 if (error) {
38f2e360
BP
2271 char *msg = ofputil_error_to_string(error);
2272 VLOG_WARN_RL(&bad_ofmsg_rl, "bad action at offset %td (%s)",
2273 (a - actions) * sizeof *a, msg);
2274 free(msg);
3b6a2571
EJ
2275 return error;
2276 }
fa37b408 2277 }
38f2e360
BP
2278 if (left) {
2279 VLOG_WARN_RL(&bad_ofmsg_rl, "bad action format at offset %zu",
2280 (n_actions - left) * sizeof *a);
2281 return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_LEN);
2282 }
2283 return 0;
fa37b408
BP
2284}
2285
51cb6e0c
BP
2286struct ofputil_action {
2287 int code;
38f2e360
BP
2288 unsigned int min_len;
2289 unsigned int max_len;
2290};
27bcf966 2291
51cb6e0c
BP
2292static const struct ofputil_action action_bad_type
2293 = { -OFP_MKERR(OFPET_BAD_ACTION, OFPBAC_BAD_TYPE), 0, UINT_MAX };
2294static const struct ofputil_action action_bad_len
2295 = { -OFP_MKERR(OFPET_BAD_ACTION, OFPBAC_BAD_LEN), 0, UINT_MAX };
2296static const struct ofputil_action action_bad_vendor
2297 = { -OFP_MKERR(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR), 0, UINT_MAX };
27bcf966 2298
51cb6e0c 2299static const struct ofputil_action *
38f2e360
BP
2300ofputil_decode_ofpat_action(const union ofp_action *a)
2301{
51cb6e0c 2302 enum ofp_action_type type = ntohs(a->type);
fa37b408 2303
51cb6e0c 2304 switch (type) {
e23ae585 2305#define OFPAT_ACTION(ENUM, STRUCT, NAME) \
51cb6e0c
BP
2306 case ENUM: { \
2307 static const struct ofputil_action action = { \
e23ae585
BP
2308 OFPUTIL_##ENUM, \
2309 sizeof(struct STRUCT), \
2310 sizeof(struct STRUCT) \
51cb6e0c
BP
2311 }; \
2312 return &action; \
2313 }
e23ae585 2314#include "ofp-util.def"
51cb6e0c
BP
2315
2316 case OFPAT_VENDOR:
2317 default:
2318 return &action_bad_type;
38f2e360
BP
2319 }
2320}
fa37b408 2321
51cb6e0c 2322static const struct ofputil_action *
38f2e360
BP
2323ofputil_decode_nxast_action(const union ofp_action *a)
2324{
51cb6e0c
BP
2325 const struct nx_action_header *nah = (const struct nx_action_header *) a;
2326 enum nx_action_subtype subtype = ntohs(nah->subtype);
2327
2328 switch (subtype) {
e23ae585
BP
2329#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
2330 case ENUM: { \
2331 static const struct ofputil_action action = { \
2332 OFPUTIL_##ENUM, \
2333 sizeof(struct STRUCT), \
2334 EXTENSIBLE ? UINT_MAX : sizeof(struct STRUCT) \
2335 }; \
2336 return &action; \
38f2e360 2337 }
e23ae585 2338#include "ofp-util.def"
51cb6e0c
BP
2339
2340 case NXAST_SNAT__OBSOLETE:
2341 case NXAST_DROP_SPOOFED_ARP__OBSOLETE:
2342 default:
2343 return &action_bad_type;
fa37b408
BP
2344 }
2345}
2346
38f2e360
BP
2347/* Parses 'a' to determine its type. Returns a nonnegative OFPUTIL_OFPAT_* or
2348 * OFPUTIL_NXAST_* constant if successful, otherwise a negative OpenFlow error
2349 * code (as returned by ofp_mkerr()).
2350 *
2351 * The caller must have already verified that 'a''s length is correct (that is,
2352 * a->header.len is nonzero and a multiple of sizeof(union ofp_action) and no
2353 * longer than the amount of space allocated to 'a').
2354 *
2355 * This function verifies that 'a''s length is correct for the type of action
2356 * that it represents. */
fa37b408 2357int
38f2e360 2358ofputil_decode_action(const union ofp_action *a)
fa37b408 2359{
51cb6e0c
BP
2360 const struct ofputil_action *action;
2361 uint16_t len = ntohs(a->header.len);
2362
38f2e360 2363 if (a->type != htons(OFPAT_VENDOR)) {
51cb6e0c 2364 action = ofputil_decode_ofpat_action(a);
38f2e360 2365 } else {
51cb6e0c
BP
2366 switch (ntohl(a->vendor.vendor)) {
2367 case NX_VENDOR_ID:
2368 if (len < sizeof(struct nx_action_header)) {
2369 return -ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_LEN);
2370 }
2371 action = ofputil_decode_nxast_action(a);
2372 break;
2373 default:
2374 action = &action_bad_vendor;
2375 break;
2376 }
38f2e360 2377 }
51cb6e0c
BP
2378
2379 return (len >= action->min_len && len <= action->max_len
2380 ? action->code
2381 : -ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_LEN));
38f2e360 2382}
fa37b408 2383
38f2e360
BP
2384/* Parses 'a' and returns its type as an OFPUTIL_OFPAT_* or OFPUTIL_NXAST_*
2385 * constant. The caller must have already validated that 'a' is a valid action
2386 * understood by Open vSwitch (e.g. by a previous successful call to
2387 * ofputil_decode_action()). */
2388enum ofputil_action_code
2389ofputil_decode_action_unsafe(const union ofp_action *a)
2390{
51cb6e0c
BP
2391 const struct ofputil_action *action;
2392
38f2e360 2393 if (a->type != htons(OFPAT_VENDOR)) {
51cb6e0c 2394 action = ofputil_decode_ofpat_action(a);
38f2e360 2395 } else {
51cb6e0c 2396 action = ofputil_decode_nxast_action(a);
fa37b408 2397 }
51cb6e0c
BP
2398
2399 return action->code;
fa37b408
BP
2400}
2401
e23ae585
BP
2402/* Returns the 'enum ofputil_action_code' corresponding to 'name' (e.g. if
2403 * 'name' is "output" then the return value is OFPUTIL_OFPAT_OUTPUT), or -1 if
2404 * 'name' is not the name of any action.
2405 *
2406 * ofp-util.def lists the mapping from names to action. */
2407int
2408ofputil_action_code_from_name(const char *name)
2409{
2410 static const char *names[OFPUTIL_N_ACTIONS] = {
2411#define OFPAT_ACTION(ENUM, STRUCT, NAME) NAME,
2412#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) NAME,
2413#include "ofp-util.def"
2414 };
2415
2416 const char **p;
2417
2418 for (p = names; p < &names[ARRAY_SIZE(names)]; p++) {
2419 if (*p && !strcasecmp(name, *p)) {
2420 return p - names;
2421 }
2422 }
2423 return -1;
2424}
2425
93996add
BP
2426/* Appends an action of the type specified by 'code' to 'buf' and returns the
2427 * action. Initializes the parts of 'action' that identify it as having type
2428 * <ENUM> and length 'sizeof *action' and zeros the rest. For actions that
2429 * have variable length, the length used and cleared is that of struct
2430 * <STRUCT>. */
2431void *
2432ofputil_put_action(enum ofputil_action_code code, struct ofpbuf *buf)
2433{
2434 switch (code) {
2435#define OFPAT_ACTION(ENUM, STRUCT, NAME) \
2436 case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
2437#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
2438 case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
2439#include "ofp-util.def"
2440 }
2441 NOT_REACHED();
2442}
2443
2444#define OFPAT_ACTION(ENUM, STRUCT, NAME) \
2445 void \
2446 ofputil_init_##ENUM(struct STRUCT *s) \
2447 { \
2448 memset(s, 0, sizeof *s); \
2449 s->type = htons(ENUM); \
2450 s->len = htons(sizeof *s); \
2451 } \
2452 \
2453 struct STRUCT * \
2454 ofputil_put_##ENUM(struct ofpbuf *buf) \
2455 { \
2456 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
2457 ofputil_init_##ENUM(s); \
2458 return s; \
2459 }
2460#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
2461 void \
2462 ofputil_init_##ENUM(struct STRUCT *s) \
2463 { \
2464 memset(s, 0, sizeof *s); \
2465 s->type = htons(OFPAT_VENDOR); \
2466 s->len = htons(sizeof *s); \
2467 s->vendor = htonl(NX_VENDOR_ID); \
2468 s->subtype = htons(ENUM); \
2469 } \
2470 \
2471 struct STRUCT * \
2472 ofputil_put_##ENUM(struct ofpbuf *buf) \
2473 { \
2474 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
2475 ofputil_init_##ENUM(s); \
2476 return s; \
2477 }
2478#include "ofp-util.def"
2479
dbba996b 2480/* Returns true if 'action' outputs to 'port', false otherwise. */
c1c9c9c4 2481bool
dbba996b 2482action_outputs_to_port(const union ofp_action *action, ovs_be16 port)
c1c9c9c4
BP
2483{
2484 switch (ntohs(action->type)) {
2485 case OFPAT_OUTPUT:
2486 return action->output.port == port;
2487 case OFPAT_ENQUEUE:
2488 return ((const struct ofp_action_enqueue *) action)->port == port;
2489 default:
2490 return false;
2491 }
2492}
2493
b459a924
BP
2494/* "Normalizes" the wildcards in 'rule'. That means:
2495 *
2496 * 1. If the type of level N is known, then only the valid fields for that
2497 * level may be specified. For example, ARP does not have a TOS field,
2498 * so nw_tos must be wildcarded if 'rule' specifies an ARP flow.
2499 * Similarly, IPv4 does not have any IPv6 addresses, so ipv6_src and
2500 * ipv6_dst (and other fields) must be wildcarded if 'rule' specifies an
2501 * IPv4 flow.
2502 *
2503 * 2. If the type of level N is not known (or not understood by Open
2504 * vSwitch), then no fields at all for that level may be specified. For
2505 * example, Open vSwitch does not understand SCTP, an L4 protocol, so the
2506 * L4 fields tp_src and tp_dst must be wildcarded if 'rule' specifies an
2507 * SCTP flow.
2508 *
2509 * 'flow_format' specifies the format of the flow as received or as intended to
2510 * be sent. This is important for IPv6 and ARP, for which NXM supports more
2511 * detailed matching. */
2512void
2513ofputil_normalize_rule(struct cls_rule *rule, enum nx_flow_format flow_format)
2514{
2515 enum {
2516 MAY_NW_ADDR = 1 << 0, /* nw_src, nw_dst */
2517 MAY_TP_ADDR = 1 << 1, /* tp_src, tp_dst */
2518 MAY_NW_PROTO = 1 << 2, /* nw_proto */
9e44d715 2519 MAY_IPVx = 1 << 3, /* tos, frag */
b459a924
BP
2520 MAY_ARP_SHA = 1 << 4, /* arp_sha */
2521 MAY_ARP_THA = 1 << 5, /* arp_tha */
2522 MAY_IPV6_ADDR = 1 << 6, /* ipv6_src, ipv6_dst */
2523 MAY_ND_TARGET = 1 << 7 /* nd_target */
2524 } may_match;
2525
2526 struct flow_wildcards wc;
2527
2528 /* Figure out what fields may be matched. */
2529 if (rule->flow.dl_type == htons(ETH_TYPE_IP)) {
9e44d715 2530 may_match = MAY_NW_PROTO | MAY_IPVx | MAY_NW_ADDR;
b459a924
BP
2531 if (rule->flow.nw_proto == IPPROTO_TCP ||
2532 rule->flow.nw_proto == IPPROTO_UDP ||
2533 rule->flow.nw_proto == IPPROTO_ICMP) {
2534 may_match |= MAY_TP_ADDR;
2535 }
2536 } else if (rule->flow.dl_type == htons(ETH_TYPE_IPV6)
2537 && flow_format == NXFF_NXM) {
9e44d715 2538 may_match = MAY_NW_PROTO | MAY_IPVx | MAY_IPV6_ADDR;
b459a924
BP
2539 if (rule->flow.nw_proto == IPPROTO_TCP ||
2540 rule->flow.nw_proto == IPPROTO_UDP) {
2541 may_match |= MAY_TP_ADDR;
2542 } else if (rule->flow.nw_proto == IPPROTO_ICMPV6) {
2543 may_match |= MAY_TP_ADDR;
2544 if (rule->flow.tp_src == htons(ND_NEIGHBOR_SOLICIT)) {
2545 may_match |= MAY_ND_TARGET | MAY_ARP_SHA;
2546 } else if (rule->flow.tp_src == htons(ND_NEIGHBOR_ADVERT)) {
2547 may_match |= MAY_ND_TARGET | MAY_ARP_THA;
2548 }
2549 }
2550 } else if (rule->flow.dl_type == htons(ETH_TYPE_ARP)) {
2551 may_match = MAY_NW_PROTO | MAY_NW_ADDR;
2552 if (flow_format == NXFF_NXM) {
2553 may_match |= MAY_ARP_SHA | MAY_ARP_THA;
fa37b408 2554 }
1c0b7503 2555 } else {
b459a924
BP
2556 may_match = 0;
2557 }
2558
2559 /* Clear the fields that may not be matched. */
2560 wc = rule->wc;
2561 if (!(may_match & MAY_NW_ADDR)) {
2562 wc.nw_src_mask = wc.nw_dst_mask = htonl(0);
2563 }
2564 if (!(may_match & MAY_TP_ADDR)) {
2565 wc.wildcards |= FWW_TP_SRC | FWW_TP_DST;
2566 }
2567 if (!(may_match & MAY_NW_PROTO)) {
2568 wc.wildcards |= FWW_NW_PROTO;
2569 }
9e44d715
JP
2570 if (!(may_match & MAY_IPVx)) {
2571 wc.tos_mask = 0;
2572 wc.frag_mask = 0;
b459a924
BP
2573 }
2574 if (!(may_match & MAY_ARP_SHA)) {
2575 wc.wildcards |= FWW_ARP_SHA;
2576 }
2577 if (!(may_match & MAY_ARP_THA)) {
2578 wc.wildcards |= FWW_ARP_THA;
2579 }
2580 if (!(may_match & MAY_IPV6_ADDR)) {
2581 wc.ipv6_src_mask = wc.ipv6_dst_mask = in6addr_any;
fa8223b7 2582 wc.wildcards |= FWW_IPV6_LABEL;
b459a924
BP
2583 }
2584 if (!(may_match & MAY_ND_TARGET)) {
2585 wc.wildcards |= FWW_ND_TARGET;
2586 }
2587
2588 /* Log any changes. */
2589 if (!flow_wildcards_equal(&wc, &rule->wc)) {
2590 bool log = !VLOG_DROP_INFO(&bad_ofmsg_rl);
2591 char *pre = log ? cls_rule_to_string(rule) : NULL;
2592
2593 rule->wc = wc;
2594 cls_rule_zero_wildcarded_fields(rule);
2595
2596 if (log) {
2597 char *post = cls_rule_to_string(rule);
2598 VLOG_INFO("normalization changed ofp_match, details:");
2599 VLOG_INFO(" pre: %s", pre);
2600 VLOG_INFO("post: %s", post);
2601 free(pre);
2602 free(post);
2603 }
fa37b408 2604 }
3f09c339 2605}
26c112c2
BP
2606
2607static uint32_t
2608vendor_code_to_id(uint8_t code)
2609{
2610 switch (code) {
2611#define OFPUTIL_VENDOR(NAME, VENDOR_ID) case NAME: return VENDOR_ID;
3a75cda9
BP
2612 OFPUTIL_VENDORS
2613#undef OFPUTIL_VENDOR
26c112c2
BP
2614 default:
2615 return UINT32_MAX;
2616 }
2617}
2618
dc4762ed
BP
2619static int
2620vendor_id_to_code(uint32_t id)
2621{
2622 switch (id) {
2623#define OFPUTIL_VENDOR(NAME, VENDOR_ID) case VENDOR_ID: return NAME;
2624 OFPUTIL_VENDORS
2625#undef OFPUTIL_VENDOR
2626 default:
2627 return -1;
2628 }
2629}
2630
26c112c2
BP
2631/* Creates and returns an OpenFlow message of type OFPT_ERROR with the error
2632 * information taken from 'error', whose encoding must be as described in the
2633 * large comment in ofp-util.h. If 'oh' is nonnull, then the error will use
2634 * oh->xid as its transaction ID, and it will include up to the first 64 bytes
2635 * of 'oh'.
2636 *
2637 * Returns NULL if 'error' is not an OpenFlow error code. */
2638struct ofpbuf *
dc4762ed 2639ofputil_encode_error_msg(int error, const struct ofp_header *oh)
26c112c2
BP
2640{
2641 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
2642
2643 struct ofpbuf *buf;
2644 const void *data;
2645 size_t len;
2646 uint8_t vendor;
2647 uint16_t type;
2648 uint16_t code;
44381c1b 2649 ovs_be32 xid;
26c112c2
BP
2650
2651 if (!is_ofp_error(error)) {
2652 /* We format 'error' with strerror() here since it seems likely to be
2653 * a system errno value. */
2654 VLOG_WARN_RL(&rl, "invalid OpenFlow error code %d (%s)",
2655 error, strerror(error));
2656 return NULL;
2657 }
2658
2659 if (oh) {
2660 xid = oh->xid;
2661 data = oh;
2662 len = ntohs(oh->length);
2663 if (len > 64) {
2664 len = 64;
2665 }
2666 } else {
2667 xid = 0;
2668 data = NULL;
2669 len = 0;
2670 }
2671
2672 vendor = get_ofp_err_vendor(error);
2673 type = get_ofp_err_type(error);
2674 code = get_ofp_err_code(error);
2675 if (vendor == OFPUTIL_VENDOR_OPENFLOW) {
2676 struct ofp_error_msg *oem;
2677
2678 oem = make_openflow_xid(len + sizeof *oem, OFPT_ERROR, xid, &buf);
2679 oem->type = htons(type);
2680 oem->code = htons(code);
2681 } else {
2682 struct ofp_error_msg *oem;
217f48c6 2683 struct nx_vendor_error *nve;
26c112c2
BP
2684 uint32_t vendor_id;
2685
2686 vendor_id = vendor_code_to_id(vendor);
2687 if (vendor_id == UINT32_MAX) {
2688 VLOG_WARN_RL(&rl, "error %x contains invalid vendor code %d",
2689 error, vendor);
2690 return NULL;
2691 }
2692
217f48c6 2693 oem = make_openflow_xid(len + sizeof *oem + sizeof *nve,
26c112c2
BP
2694 OFPT_ERROR, xid, &buf);
2695 oem->type = htons(NXET_VENDOR);
2696 oem->code = htons(NXVC_VENDOR_ERROR);
2697
17764fb2 2698 nve = (struct nx_vendor_error *)oem->data;
217f48c6
BP
2699 nve->vendor = htonl(vendor_id);
2700 nve->type = htons(type);
2701 nve->code = htons(code);
26c112c2
BP
2702 }
2703
2704 if (len) {
59edb09c 2705 buf->size -= len;
26c112c2
BP
2706 ofpbuf_put(buf, data, len);
2707 }
2708
2709 return buf;
2710}
3052b0c5 2711
dc4762ed
BP
2712/* Decodes 'oh', which should be an OpenFlow OFPT_ERROR message, and returns an
2713 * Open vSwitch internal error code in the format described in the large
2714 * comment in ofp-util.h.
2715 *
2716 * If 'payload_ofs' is nonnull, on success '*payload_ofs' is set to the offset
2717 * to the payload starting from 'oh' and on failure it is set to 0. */
2718int
2719ofputil_decode_error_msg(const struct ofp_header *oh, size_t *payload_ofs)
2720{
2721 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
2722
2723 const struct ofp_error_msg *oem;
2724 uint16_t type, code;
2725 struct ofpbuf b;
2726 int vendor;
2727
2728 if (payload_ofs) {
2729 *payload_ofs = 0;
2730 }
2731 if (oh->type != OFPT_ERROR) {
2732 return EPROTO;
2733 }
2734
2735 ofpbuf_use_const(&b, oh, ntohs(oh->length));
2736 oem = ofpbuf_try_pull(&b, sizeof *oem);
2737 if (!oem) {
2738 return EPROTO;
2739 }
2740
2741 type = ntohs(oem->type);
2742 code = ntohs(oem->code);
2743 if (type == NXET_VENDOR && code == NXVC_VENDOR_ERROR) {
2744 const struct nx_vendor_error *nve = ofpbuf_try_pull(&b, sizeof *nve);
2745 if (!nve) {
2746 return EPROTO;
2747 }
2748
2749 vendor = vendor_id_to_code(ntohl(nve->vendor));
2750 if (vendor < 0) {
2751 VLOG_WARN_RL(&rl, "error contains unknown vendor ID %#"PRIx32,
2752 ntohl(nve->vendor));
2753 return EPROTO;
2754 }
2755 type = ntohs(nve->type);
2756 code = ntohs(nve->code);
2757 } else {
2758 vendor = OFPUTIL_VENDOR_OPENFLOW;
2759 }
2760
2761 if (type >= 1024) {
2762 VLOG_WARN_RL(&rl, "error contains type %"PRIu16" greater than "
2763 "supported maximum value 1023", type);
2764 return EPROTO;
2765 }
2766
2767 if (payload_ofs) {
2768 *payload_ofs = (uint8_t *) b.data - (uint8_t *) oh;
2769 }
2770 return ofp_mkerr_vendor(vendor, type, code);
2771}
2772
2773void
2774ofputil_format_error(struct ds *s, int error)
2775{
2776 if (is_errno(error)) {
2777 ds_put_cstr(s, strerror(error));
2778 } else {
2779 uint16_t type = get_ofp_err_type(error);
2780 uint16_t code = get_ofp_err_code(error);
2781 const char *type_s = ofp_error_type_to_string(type);
2782 const char *code_s = ofp_error_code_to_string(type, code);
2783
2784 ds_put_format(s, "type ");
2785 if (type_s) {
2786 ds_put_cstr(s, type_s);
2787 } else {
2788 ds_put_format(s, "%"PRIu16, type);
2789 }
2790
2791 ds_put_cstr(s, ", code ");
2792 if (code_s) {
2793 ds_put_cstr(s, code_s);
2794 } else {
2795 ds_put_format(s, "%"PRIu16, code);
2796 }
2797 }
2798}
2799
2800char *
2801ofputil_error_to_string(int error)
2802{
2803 struct ds s = DS_EMPTY_INITIALIZER;
2804 ofputil_format_error(&s, error);
2805 return ds_steal_cstr(&s);
2806}
2807
3052b0c5
BP
2808/* Attempts to pull 'actions_len' bytes from the front of 'b'. Returns 0 if
2809 * successful, otherwise an OpenFlow error.
2810 *
2811 * If successful, the first action is stored in '*actionsp' and the number of
2812 * "union ofp_action" size elements into '*n_actionsp'. Otherwise NULL and 0
2813 * are stored, respectively.
2814 *
2815 * This function does not check that the actions are valid (the caller should
2816 * do so, with validate_actions()). The caller is also responsible for making
2817 * sure that 'b->data' is initially aligned appropriately for "union
2818 * ofp_action". */
2819int
2820ofputil_pull_actions(struct ofpbuf *b, unsigned int actions_len,
2821 union ofp_action **actionsp, size_t *n_actionsp)
2822{
69b6be19 2823 if (actions_len % OFP_ACTION_ALIGN != 0) {
f4350529
BP
2824 VLOG_WARN_RL(&bad_ofmsg_rl, "OpenFlow message actions length %u "
2825 "is not a multiple of %d", actions_len, OFP_ACTION_ALIGN);
3052b0c5
BP
2826 goto error;
2827 }
2828
2829 *actionsp = ofpbuf_try_pull(b, actions_len);
2830 if (*actionsp == NULL) {
f4350529
BP
2831 VLOG_WARN_RL(&bad_ofmsg_rl, "OpenFlow message actions length %u "
2832 "exceeds remaining message length (%zu)",
2833 actions_len, b->size);
3052b0c5
BP
2834 goto error;
2835 }
2836
69b6be19 2837 *n_actionsp = actions_len / OFP_ACTION_ALIGN;
3052b0c5
BP
2838 return 0;
2839
2840error:
2841 *actionsp = NULL;
2842 *n_actionsp = 0;
2843 return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
2844}
18ddadc2
BP
2845
2846bool
2847ofputil_actions_equal(const union ofp_action *a, size_t n_a,
2848 const union ofp_action *b, size_t n_b)
2849{
2850 return n_a == n_b && (!n_a || !memcmp(a, b, n_a * sizeof *a));
2851}
2852
2853union ofp_action *
2854ofputil_actions_clone(const union ofp_action *actions, size_t n)
2855{
2856 return n ? xmemdup(actions, n * sizeof *actions) : NULL;
2857}
0ff22822
BP
2858
2859/* Parses a key or a key-value pair from '*stringp'.
2860 *
2861 * On success: Stores the key into '*keyp'. Stores the value, if present, into
2862 * '*valuep', otherwise an empty string. Advances '*stringp' past the end of
2863 * the key-value pair, preparing it for another call. '*keyp' and '*valuep'
2864 * are substrings of '*stringp' created by replacing some of its bytes by null
2865 * terminators. Returns true.
2866 *
2867 * If '*stringp' is just white space or commas, sets '*keyp' and '*valuep' to
2868 * NULL and returns false. */
2869bool
2870ofputil_parse_key_value(char **stringp, char **keyp, char **valuep)
2871{
2872 char *pos, *key, *value;
2873 size_t key_len;
2874
2875 pos = *stringp;
2876 pos += strspn(pos, ", \t\r\n");
2877 if (*pos == '\0') {
2878 *keyp = *valuep = NULL;
2879 return false;
2880 }
2881
2882 key = pos;
2883 key_len = strcspn(pos, ":=(, \t\r\n");
2884 if (key[key_len] == ':' || key[key_len] == '=') {
2885 /* The value can be separated by a colon. */
2886 size_t value_len;
2887
2888 value = key + key_len + 1;
2889 value_len = strcspn(value, ", \t\r\n");
2890 pos = value + value_len + (value[value_len] != '\0');
2891 value[value_len] = '\0';
2892 } else if (key[key_len] == '(') {
2893 /* The value can be surrounded by balanced parentheses. The outermost
2894 * set of parentheses is removed. */
2895 int level = 1;
2896 size_t value_len;
2897
2898 value = key + key_len + 1;
2899 for (value_len = 0; level > 0; value_len++) {
2900 switch (value[value_len]) {
2901 case '\0':
2902 ovs_fatal(0, "unbalanced parentheses in argument to %s", key);
2903
2904 case '(':
2905 level++;
2906 break;
2907
2908 case ')':
2909 level--;
2910 break;
2911 }
2912 }
2913 value[value_len - 1] = '\0';
2914 pos = value + value_len;
2915 } else {
2916 /* There might be no value at all. */
2917 value = key + key_len; /* Will become the empty string below. */
2918 pos = key + key_len + (key[key_len] != '\0');
2919 }
2920 key[key_len] = '\0';
2921
2922 *stringp = pos;
2923 *keyp = key;
2924 *valuep = value;
2925 return true;
2926}