2010-05-27 13:14:05 -07:00
|
|
|
|
/*
|
2013-02-11 23:55:31 -08:00
|
|
|
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
2010-05-27 13:14:05 -07:00
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at:
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef OFP_UTIL_H
|
|
|
|
|
#define OFP_UTIL_H 1
|
|
|
|
|
|
2010-06-17 15:04:12 -07:00
|
|
|
|
#include <stdbool.h>
|
2010-05-27 13:14:05 -07:00
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdint.h>
|
2010-12-06 10:20:20 -08:00
|
|
|
|
#include "classifier.h"
|
2012-07-03 22:17:14 -07:00
|
|
|
|
#include "compiler.h"
|
2010-05-27 13:14:05 -07:00
|
|
|
|
#include "flow.h"
|
2012-08-07 15:28:18 -07:00
|
|
|
|
#include "match.h"
|
2012-02-15 14:23:38 -08:00
|
|
|
|
#include "netdev.h"
|
2010-11-17 10:06:37 -08:00
|
|
|
|
#include "openflow/nicira-ext.h"
|
2010-11-16 11:00:25 -08:00
|
|
|
|
#include "openvswitch/types.h"
|
2013-04-16 15:13:21 -07:00
|
|
|
|
#include "type-props.h"
|
2010-05-27 13:14:05 -07:00
|
|
|
|
|
|
|
|
|
struct ofpbuf;
|
|
|
|
|
|
2011-08-16 15:26:18 -07:00
|
|
|
|
/* Port numbers. */
|
2013-06-19 16:58:44 -07:00
|
|
|
|
enum ofperr ofputil_port_from_ofp11(ovs_be32 ofp11_port,
|
|
|
|
|
ofp_port_t *ofp10_port);
|
|
|
|
|
ovs_be32 ofputil_port_to_ofp11(ofp_port_t ofp10_port);
|
2012-02-14 17:08:03 -08:00
|
|
|
|
|
2013-06-19 16:58:44 -07:00
|
|
|
|
enum ofperr ofputil_check_output_port(ofp_port_t ofp_port,
|
|
|
|
|
ofp_port_t max_ports);
|
|
|
|
|
bool ofputil_port_from_string(const char *, ofp_port_t *portp);
|
|
|
|
|
void ofputil_format_port(ofp_port_t port, struct ds *);
|
2010-12-06 10:20:20 -08:00
|
|
|
|
|
2012-05-21 21:51:03 -07:00
|
|
|
|
/* Converting OFPFW10_NW_SRC_MASK and OFPFW10_NW_DST_MASK wildcard bit counts
|
|
|
|
|
* to and from IP bitmasks. */
|
2010-11-22 10:09:18 -08:00
|
|
|
|
ovs_be32 ofputil_wcbits_to_netmask(int wcbits);
|
|
|
|
|
int ofputil_netmask_to_wcbits(ovs_be32 netmask);
|
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
|
/* Protocols.
|
2012-11-15 21:01:13 -08:00
|
|
|
|
*
|
|
|
|
|
* A "protocol" is an OpenFlow version plus, for some OpenFlow versions,
|
|
|
|
|
* a bit extra about the flow match format in use.
|
2012-02-10 13:30:23 -08:00
|
|
|
|
*
|
|
|
|
|
* These are arranged from most portable to least portable, or alternatively
|
2012-11-15 21:01:13 -08:00
|
|
|
|
* from least powerful to most powerful. Protocols earlier on the list are
|
|
|
|
|
* more likely to be understood for the purpose of making requests, but
|
|
|
|
|
* protocol later on the list are more likely to accurately describe a flow
|
|
|
|
|
* within a switch.
|
2012-02-10 13:30:23 -08:00
|
|
|
|
*
|
|
|
|
|
* On any given OpenFlow connection, a single protocol is in effect at any
|
|
|
|
|
* given time. These values use separate bits only because that makes it easy
|
|
|
|
|
* to test whether a particular protocol is within a given set of protocols and
|
|
|
|
|
* to implement set union and intersection.
|
|
|
|
|
*/
|
|
|
|
|
enum ofputil_protocol {
|
2012-11-15 21:01:13 -08:00
|
|
|
|
/* OpenFlow 1.0 protocols.
|
|
|
|
|
*
|
|
|
|
|
* The "STD" protocols use the standard OpenFlow 1.0 flow format.
|
|
|
|
|
* The "NXM" protocols use the Nicira Extensible Match (NXM) flow format.
|
|
|
|
|
*
|
|
|
|
|
* The protocols with "TID" mean that the nx_flow_mod_table_id Nicira
|
|
|
|
|
* extension has been enabled. The other protocols have it disabled.
|
|
|
|
|
*/
|
2012-11-19 09:49:13 -08:00
|
|
|
|
#define OFPUTIL_P_NONE 0
|
2012-11-15 21:01:13 -08:00
|
|
|
|
OFPUTIL_P_OF10_STD = 1 << 0,
|
|
|
|
|
OFPUTIL_P_OF10_STD_TID = 1 << 1,
|
|
|
|
|
OFPUTIL_P_OF10_NXM = 1 << 2,
|
|
|
|
|
OFPUTIL_P_OF10_NXM_TID = 1 << 3,
|
|
|
|
|
#define OFPUTIL_P_OF10_STD_ANY (OFPUTIL_P_OF10_STD | OFPUTIL_P_OF10_STD_TID)
|
|
|
|
|
#define OFPUTIL_P_OF10_NXM_ANY (OFPUTIL_P_OF10_NXM | OFPUTIL_P_OF10_NXM_TID)
|
2012-02-10 13:30:23 -08:00
|
|
|
|
|
2012-11-27 17:44:22 +02:00
|
|
|
|
/* OpenFlow 1.2+ protocols (only one variant each).
|
2012-11-15 21:01:13 -08:00
|
|
|
|
*
|
2012-11-27 17:44:22 +02:00
|
|
|
|
* These use the standard OpenFlow Extensible Match (OXM) flow format.
|
2012-11-15 21:01:13 -08:00
|
|
|
|
*
|
2012-11-27 17:44:22 +02:00
|
|
|
|
* OpenFlow 1.2+ always operates with an equivalent of the
|
2012-11-15 21:01:13 -08:00
|
|
|
|
* nx_flow_mod_table_id Nicira extension enabled, so there is no "TID"
|
|
|
|
|
* variant. */
|
|
|
|
|
OFPUTIL_P_OF12_OXM = 1 << 4,
|
2012-11-27 17:44:22 +02:00
|
|
|
|
OFPUTIL_P_OF13_OXM = 1 << 5,
|
2012-11-28 20:43:02 -08:00
|
|
|
|
#define OFPUTIL_P_ANY_OXM (OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM)
|
2012-07-22 21:14:41 -07:00
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
|
/* All protocols. */
|
2012-11-27 17:44:22 +02:00
|
|
|
|
#define OFPUTIL_P_ANY ((1 << 6) - 1)
|
2012-02-10 13:30:23 -08:00
|
|
|
|
|
|
|
|
|
/* Protocols in which a specific table may be specified in flow_mods. */
|
2012-11-15 22:36:15 -08:00
|
|
|
|
#define OFPUTIL_P_TID (OFPUTIL_P_OF10_STD_TID | \
|
|
|
|
|
OFPUTIL_P_OF10_NXM_TID | \
|
2012-11-28 21:41:05 -08:00
|
|
|
|
OFPUTIL_P_ANY_OXM)
|
2012-02-10 13:30:23 -08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Protocols to use for flow dumps, from most to least preferred. */
|
|
|
|
|
extern enum ofputil_protocol ofputil_flow_dump_protocols[];
|
|
|
|
|
extern size_t ofputil_n_flow_dump_protocols;
|
|
|
|
|
|
2012-11-28 21:33:04 -08:00
|
|
|
|
enum ofputil_protocol ofputil_protocol_from_ofp_version(enum ofp_version);
|
2012-11-28 21:41:05 -08:00
|
|
|
|
enum ofputil_protocol ofputil_protocols_from_ofp_version(enum ofp_version);
|
|
|
|
|
enum ofp_version ofputil_protocol_to_ofp_version(enum ofputil_protocol);
|
2012-02-15 16:33:04 -08:00
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
|
bool ofputil_protocol_is_valid(enum ofputil_protocol);
|
|
|
|
|
enum ofputil_protocol ofputil_protocol_set_tid(enum ofputil_protocol,
|
|
|
|
|
bool enable);
|
|
|
|
|
enum ofputil_protocol ofputil_protocol_to_base(enum ofputil_protocol);
|
|
|
|
|
enum ofputil_protocol ofputil_protocol_set_base(
|
|
|
|
|
enum ofputil_protocol cur, enum ofputil_protocol new_base);
|
|
|
|
|
|
|
|
|
|
const char *ofputil_protocol_to_string(enum ofputil_protocol);
|
|
|
|
|
char *ofputil_protocols_to_string(enum ofputil_protocol);
|
|
|
|
|
enum ofputil_protocol ofputil_protocols_from_string(const char *);
|
2012-08-07 15:28:18 -07:00
|
|
|
|
enum ofputil_protocol ofputil_usable_protocols(const struct match *);
|
2012-02-10 13:30:23 -08:00
|
|
|
|
|
2012-11-04 21:40:54 -08:00
|
|
|
|
void ofputil_format_version(struct ds *, enum ofp_version);
|
|
|
|
|
void ofputil_format_version_name(struct ds *, enum ofp_version);
|
|
|
|
|
|
|
|
|
|
/* A bitmap of version numbers
|
|
|
|
|
*
|
|
|
|
|
* Bit offsets correspond to ofp_version numbers which in turn correspond to
|
|
|
|
|
* wire-protocol numbers for Open Flow versions.. E.g. (1u << OFP11_VERSION)
|
|
|
|
|
* is the mask for Open Flow 1.1. If the bit for a version is set then it is
|
|
|
|
|
* allowed, otherwise it is disallowed. */
|
|
|
|
|
|
|
|
|
|
void ofputil_format_version_bitmap(struct ds *msg, uint32_t bitmap);
|
|
|
|
|
void ofputil_format_version_bitmap_names(struct ds *msg, uint32_t bitmap);
|
|
|
|
|
|
2012-11-28 21:41:05 -08:00
|
|
|
|
uint32_t ofputil_protocols_to_version_bitmap(enum ofputil_protocol);
|
|
|
|
|
enum ofputil_protocol ofputil_protocols_from_version_bitmap(uint32_t bitmap);
|
|
|
|
|
|
2012-11-04 21:40:54 -08:00
|
|
|
|
/* Bitmap of OpenFlow versions that Open vSwitch supports. */
|
|
|
|
|
#define OFPUTIL_SUPPORTED_VERSIONS \
|
2012-11-27 17:44:22 +02:00
|
|
|
|
((1u << OFP10_VERSION) | (1u << OFP12_VERSION) | (1u << OFP13_VERSION))
|
2012-11-04 21:40:54 -08:00
|
|
|
|
|
|
|
|
|
/* Bitmap of OpenFlow versions to enable by default (a subset of
|
|
|
|
|
* OFPUTIL_SUPPORTED_VERSIONS). */
|
|
|
|
|
#define OFPUTIL_DEFAULT_VERSIONS (1u << OFP10_VERSION)
|
|
|
|
|
|
|
|
|
|
enum ofputil_protocol ofputil_protocols_from_string(const char *s);
|
|
|
|
|
|
|
|
|
|
const char *ofputil_version_to_string(enum ofp_version ofp_version);
|
|
|
|
|
uint32_t ofputil_versions_from_string(const char *s);
|
2012-11-19 14:59:30 +09:00
|
|
|
|
uint32_t ofputil_versions_from_strings(char ** const s, size_t count);
|
2012-11-04 21:40:54 -08:00
|
|
|
|
|
2012-11-04 22:04:55 -08:00
|
|
|
|
bool ofputil_decode_hello(const struct ofp_header *,
|
|
|
|
|
uint32_t *allowed_versions);
|
|
|
|
|
struct ofpbuf *ofputil_encode_hello(uint32_t version_bitmap);
|
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
|
struct ofpbuf *ofputil_encode_set_protocol(enum ofputil_protocol current,
|
|
|
|
|
enum ofputil_protocol want,
|
|
|
|
|
enum ofputil_protocol *next);
|
|
|
|
|
|
|
|
|
|
/* nx_flow_format */
|
|
|
|
|
struct ofpbuf *ofputil_encode_nx_set_flow_format(enum nx_flow_format);
|
|
|
|
|
enum ofputil_protocol ofputil_nx_flow_format_to_protocol(enum nx_flow_format);
|
|
|
|
|
bool ofputil_nx_flow_format_is_valid(enum nx_flow_format);
|
|
|
|
|
const char *ofputil_nx_flow_format_to_string(enum nx_flow_format);
|
|
|
|
|
|
2012-05-21 21:51:03 -07:00
|
|
|
|
/* Work with ofp10_match. */
|
|
|
|
|
void ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *);
|
2012-08-07 15:28:18 -07:00
|
|
|
|
void ofputil_match_from_ofp10_match(const struct ofp10_match *,
|
|
|
|
|
struct match *);
|
|
|
|
|
void ofputil_normalize_match(struct match *);
|
|
|
|
|
void ofputil_normalize_match_quiet(struct match *);
|
|
|
|
|
void ofputil_match_to_ofp10_match(const struct match *, struct ofp10_match *);
|
2010-11-10 14:39:54 -08:00
|
|
|
|
|
2012-06-09 15:49:16 -07:00
|
|
|
|
/* Work with ofp11_match. */
|
2012-08-07 15:28:18 -07:00
|
|
|
|
enum ofperr ofputil_pull_ofp11_match(struct ofpbuf *, struct match *,
|
2012-08-08 06:49:36 +09:00
|
|
|
|
uint16_t *padded_match_len);
|
2012-08-07 15:28:18 -07:00
|
|
|
|
enum ofperr ofputil_match_from_ofp11_match(const struct ofp11_match *,
|
|
|
|
|
struct match *);
|
|
|
|
|
void ofputil_match_to_ofp11_match(const struct match *, struct ofp11_match *);
|
2012-06-09 15:49:16 -07:00
|
|
|
|
|
2011-01-23 18:44:44 -08:00
|
|
|
|
/* dl_type translation between OpenFlow and 'struct flow' format. */
|
|
|
|
|
ovs_be16 ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type);
|
|
|
|
|
ovs_be16 ofputil_dl_type_from_openflow(ovs_be16 ofp_dl_type);
|
|
|
|
|
|
2011-12-09 15:48:26 -08:00
|
|
|
|
/* PACKET_IN. */
|
|
|
|
|
bool ofputil_packet_in_format_is_valid(enum nx_packet_in_format);
|
|
|
|
|
int ofputil_packet_in_format_from_string(const char *);
|
|
|
|
|
const char *ofputil_packet_in_format_to_string(enum nx_packet_in_format);
|
2012-10-04 11:41:16 +09:00
|
|
|
|
struct ofpbuf *ofputil_make_set_packet_in_format(enum ofp_version,
|
|
|
|
|
enum nx_packet_in_format);
|
2011-12-09 15:48:26 -08:00
|
|
|
|
|
2011-05-12 09:58:01 -07:00
|
|
|
|
/* NXT_FLOW_MOD_TABLE_ID extension. */
|
|
|
|
|
struct ofpbuf *ofputil_make_flow_mod_table_id(bool flow_mod_table_id);
|
|
|
|
|
|
2012-03-24 01:02:26 -07:00
|
|
|
|
/* Protocol-independent flow_mod.
|
|
|
|
|
*
|
|
|
|
|
* The handling of cookies across multiple versions of OpenFlow is a bit
|
|
|
|
|
* confusing. A full description of Open vSwitch's cookie handling is
|
|
|
|
|
* in the DESIGN file. The following table shows the expected values of
|
|
|
|
|
* the cookie-related fields for the different flow_mod commands in
|
|
|
|
|
* OpenFlow 1.0 ("OF10") and NXM. "<used>" and "-" indicate a value
|
|
|
|
|
* that may be populated and an ignored field, respectively.
|
|
|
|
|
*
|
|
|
|
|
* cookie cookie_mask new_cookie
|
|
|
|
|
* ====== =========== ==========
|
|
|
|
|
* OF10 Add - 0 <used>
|
|
|
|
|
* OF10 Modify - 0 <used>
|
|
|
|
|
* OF10 Delete - 0 -
|
|
|
|
|
* NXM Add - 0 <used>
|
|
|
|
|
* NXM Modify <used> <used> <used>
|
|
|
|
|
* NXM Delete <used> <used> -
|
|
|
|
|
*/
|
2011-08-08 14:46:38 -07:00
|
|
|
|
struct ofputil_flow_mod {
|
2012-08-07 15:28:18 -07:00
|
|
|
|
struct match match;
|
|
|
|
|
unsigned int priority;
|
2012-03-24 01:02:26 -07:00
|
|
|
|
ovs_be64 cookie; /* Cookie bits to match. */
|
|
|
|
|
ovs_be64 cookie_mask; /* 1-bit in each 'cookie' bit to match. */
|
|
|
|
|
ovs_be64 new_cookie; /* New cookie to install or -1. */
|
2011-05-12 09:58:01 -07:00
|
|
|
|
uint8_t table_id;
|
2010-12-07 12:45:24 -08:00
|
|
|
|
uint16_t command;
|
|
|
|
|
uint16_t idle_timeout;
|
|
|
|
|
uint16_t hard_timeout;
|
|
|
|
|
uint32_t buffer_id;
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t out_port;
|
2010-12-07 12:45:24 -08:00
|
|
|
|
uint16_t flags;
|
2012-07-03 22:17:14 -07:00
|
|
|
|
struct ofpact *ofpacts; /* Series of "struct ofpact"s. */
|
|
|
|
|
size_t ofpacts_len; /* Length of ofpacts, in bytes. */
|
2010-12-07 12:45:24 -08:00
|
|
|
|
};
|
|
|
|
|
|
2012-01-12 15:48:19 -08:00
|
|
|
|
enum ofperr ofputil_decode_flow_mod(struct ofputil_flow_mod *,
|
|
|
|
|
const struct ofp_header *,
|
2012-07-03 22:17:14 -07:00
|
|
|
|
enum ofputil_protocol,
|
|
|
|
|
struct ofpbuf *ofpacts);
|
2011-08-08 14:46:38 -07:00
|
|
|
|
struct ofpbuf *ofputil_encode_flow_mod(const struct ofputil_flow_mod *,
|
2012-02-10 13:30:23 -08:00
|
|
|
|
enum ofputil_protocol);
|
|
|
|
|
|
|
|
|
|
enum ofputil_protocol ofputil_flow_mod_usable_protocols(
|
|
|
|
|
const struct ofputil_flow_mod *fms, size_t n_fms);
|
2010-12-07 12:45:24 -08:00
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
|
/* Flow stats or aggregate stats request, independent of protocol. */
|
2011-08-08 14:48:48 -07:00
|
|
|
|
struct ofputil_flow_stats_request {
|
2010-12-07 12:45:24 -08:00
|
|
|
|
bool aggregate; /* Aggregate results? */
|
2012-08-07 15:28:18 -07:00
|
|
|
|
struct match match;
|
2011-12-23 12:23:24 -08:00
|
|
|
|
ovs_be64 cookie;
|
|
|
|
|
ovs_be64 cookie_mask;
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t out_port;
|
2010-12-07 12:45:24 -08:00
|
|
|
|
uint8_t table_id;
|
|
|
|
|
};
|
|
|
|
|
|
2012-01-12 15:48:19 -08:00
|
|
|
|
enum ofperr ofputil_decode_flow_stats_request(
|
|
|
|
|
struct ofputil_flow_stats_request *, const struct ofp_header *);
|
2010-12-07 12:45:24 -08:00
|
|
|
|
struct ofpbuf *ofputil_encode_flow_stats_request(
|
2012-02-10 13:30:23 -08:00
|
|
|
|
const struct ofputil_flow_stats_request *, enum ofputil_protocol);
|
|
|
|
|
enum ofputil_protocol ofputil_flow_stats_request_usable_protocols(
|
|
|
|
|
const struct ofputil_flow_stats_request *);
|
2010-12-07 12:45:24 -08:00
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
|
/* Flow stats reply, independent of protocol. */
|
2011-03-10 15:02:05 -08:00
|
|
|
|
struct ofputil_flow_stats {
|
2012-08-07 15:28:18 -07:00
|
|
|
|
struct match match;
|
2011-03-10 15:02:05 -08:00
|
|
|
|
ovs_be64 cookie;
|
|
|
|
|
uint8_t table_id;
|
|
|
|
|
uint32_t duration_sec;
|
|
|
|
|
uint32_t duration_nsec;
|
2012-08-07 15:28:18 -07:00
|
|
|
|
uint16_t priority;
|
2011-03-10 15:02:05 -08:00
|
|
|
|
uint16_t idle_timeout;
|
|
|
|
|
uint16_t hard_timeout;
|
2012-02-07 10:13:52 -08:00
|
|
|
|
int idle_age; /* Seconds since last packet, -1 if unknown. */
|
|
|
|
|
int hard_age; /* Seconds since last change, -1 if unknown. */
|
2011-05-27 15:16:08 -07:00
|
|
|
|
uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
|
|
|
|
|
uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */
|
2012-07-03 22:17:14 -07:00
|
|
|
|
struct ofpact *ofpacts;
|
|
|
|
|
size_t ofpacts_len;
|
2012-11-27 17:44:22 +02:00
|
|
|
|
uint16_t flags; /* Added for OF 1.3 */
|
2011-03-10 15:02:05 -08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *,
|
2012-02-07 10:13:52 -08:00
|
|
|
|
struct ofpbuf *msg,
|
2012-07-03 22:17:14 -07:00
|
|
|
|
bool flow_age_extension,
|
|
|
|
|
struct ofpbuf *ofpacts);
|
2011-05-31 16:55:02 -07:00
|
|
|
|
void ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *,
|
|
|
|
|
struct list *replies);
|
2011-03-10 15:02:05 -08:00
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
|
/* Aggregate stats reply, independent of protocol. */
|
2011-05-26 16:02:56 -07:00
|
|
|
|
struct ofputil_aggregate_stats {
|
2011-05-27 15:16:08 -07:00
|
|
|
|
uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
|
|
|
|
|
uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */
|
2011-05-26 16:02:56 -07:00
|
|
|
|
uint32_t flow_count;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ofpbuf *ofputil_encode_aggregate_stats_reply(
|
|
|
|
|
const struct ofputil_aggregate_stats *stats,
|
2012-07-19 23:23:17 -07:00
|
|
|
|
const struct ofp_header *request);
|
|
|
|
|
enum ofperr ofputil_decode_aggregate_stats_reply(
|
|
|
|
|
struct ofputil_aggregate_stats *,
|
|
|
|
|
const struct ofp_header *reply);
|
2011-05-26 16:02:56 -07:00
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
|
/* Flow removed message, independent of protocol. */
|
2010-12-09 10:31:49 -08:00
|
|
|
|
struct ofputil_flow_removed {
|
2012-08-07 15:28:18 -07:00
|
|
|
|
struct match match;
|
|
|
|
|
uint16_t priority;
|
2010-12-09 10:31:49 -08:00
|
|
|
|
ovs_be64 cookie;
|
|
|
|
|
uint8_t reason; /* One of OFPRR_*. */
|
2012-10-01 16:51:49 +09:00
|
|
|
|
uint8_t table_id; /* 255 if message didn't include table ID. */
|
2010-12-09 10:31:49 -08:00
|
|
|
|
uint32_t duration_sec;
|
|
|
|
|
uint32_t duration_nsec;
|
|
|
|
|
uint16_t idle_timeout;
|
2012-08-09 11:01:48 -07:00
|
|
|
|
uint16_t hard_timeout;
|
2011-05-27 15:16:08 -07:00
|
|
|
|
uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
|
|
|
|
|
uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */
|
2010-12-09 10:31:49 -08:00
|
|
|
|
};
|
|
|
|
|
|
2012-01-12 15:48:19 -08:00
|
|
|
|
enum ofperr ofputil_decode_flow_removed(struct ofputil_flow_removed *,
|
|
|
|
|
const struct ofp_header *);
|
2011-03-15 09:49:14 -07:00
|
|
|
|
struct ofpbuf *ofputil_encode_flow_removed(const struct ofputil_flow_removed *,
|
2012-02-10 13:30:23 -08:00
|
|
|
|
enum ofputil_protocol);
|
2010-12-09 10:31:49 -08:00
|
|
|
|
|
2011-03-22 09:13:02 -07:00
|
|
|
|
/* Abstract packet-in message. */
|
|
|
|
|
struct ofputil_packet_in {
|
2011-12-21 19:01:18 -08:00
|
|
|
|
const void *packet;
|
|
|
|
|
size_t packet_len;
|
|
|
|
|
|
2012-03-12 14:21:14 -07:00
|
|
|
|
enum ofp_packet_in_reason reason; /* One of OFPR_*. */
|
2012-02-09 14:17:33 -08:00
|
|
|
|
uint16_t controller_id; /* Controller ID to send to. */
|
2011-12-09 15:48:26 -08:00
|
|
|
|
uint8_t table_id;
|
|
|
|
|
ovs_be64 cookie;
|
2011-03-22 09:13:02 -07:00
|
|
|
|
|
|
|
|
|
uint32_t buffer_id;
|
|
|
|
|
int send_len;
|
2011-12-22 16:35:23 -08:00
|
|
|
|
uint16_t total_len; /* Full length of frame. */
|
2012-01-04 16:40:13 -08:00
|
|
|
|
|
|
|
|
|
struct flow_metadata fmd; /* Metadata at creation time. */
|
2011-03-22 09:13:02 -07:00
|
|
|
|
};
|
|
|
|
|
|
2012-06-06 23:13:49 -04:00
|
|
|
|
enum ofperr ofputil_decode_packet_in(struct ofputil_packet_in *,
|
|
|
|
|
const struct ofp_header *);
|
2011-12-09 15:48:26 -08:00
|
|
|
|
struct ofpbuf *ofputil_encode_packet_in(const struct ofputil_packet_in *,
|
2012-08-08 06:49:38 +09:00
|
|
|
|
enum ofputil_protocol protocol,
|
2011-12-09 15:48:26 -08:00
|
|
|
|
enum nx_packet_in_format);
|
2011-03-22 09:13:02 -07:00
|
|
|
|
|
2013-04-16 15:13:21 -07:00
|
|
|
|
enum { OFPUTIL_PACKET_IN_REASON_BUFSIZE = INT_STRLEN(int) + 1 };
|
|
|
|
|
const char *ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason,
|
|
|
|
|
char *reasonbuf,
|
|
|
|
|
size_t bufsize);
|
2012-02-07 14:46:34 -08:00
|
|
|
|
bool ofputil_packet_in_reason_from_string(const char *,
|
|
|
|
|
enum ofp_packet_in_reason *);
|
|
|
|
|
|
2012-05-07 12:30:54 -07:00
|
|
|
|
/* Abstract packet-out message.
|
|
|
|
|
*
|
|
|
|
|
* ofputil_decode_packet_out() will ensure that 'in_port' is a physical port
|
|
|
|
|
* (OFPP_MAX or less) or one of OFPP_LOCAL, OFPP_NONE, or OFPP_CONTROLLER. */
|
2012-02-06 14:17:49 -08:00
|
|
|
|
struct ofputil_packet_out {
|
|
|
|
|
const void *packet; /* Packet data, if buffer_id == UINT32_MAX. */
|
|
|
|
|
size_t packet_len; /* Length of packet data in bytes. */
|
|
|
|
|
uint32_t buffer_id; /* Buffer id or UINT32_MAX if no buffer. */
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t in_port; /* Packet's input port. */
|
2012-07-03 22:17:14 -07:00
|
|
|
|
struct ofpact *ofpacts; /* Actions. */
|
|
|
|
|
size_t ofpacts_len; /* Size of ofpacts in bytes. */
|
2012-02-06 14:17:49 -08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum ofperr ofputil_decode_packet_out(struct ofputil_packet_out *,
|
2012-07-19 23:23:17 -07:00
|
|
|
|
const struct ofp_header *,
|
2012-07-03 22:17:14 -07:00
|
|
|
|
struct ofpbuf *ofpacts);
|
2012-08-08 12:19:57 +09:00
|
|
|
|
struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *,
|
|
|
|
|
enum ofputil_protocol protocol);
|
2012-02-06 14:17:49 -08:00
|
|
|
|
|
2012-02-15 16:33:04 -08:00
|
|
|
|
enum ofputil_port_config {
|
|
|
|
|
/* OpenFlow 1.0 and 1.1 share these values for these port config bits. */
|
|
|
|
|
OFPUTIL_PC_PORT_DOWN = 1 << 0, /* Port is administratively down. */
|
|
|
|
|
OFPUTIL_PC_NO_RECV = 1 << 2, /* Drop all packets received by port. */
|
|
|
|
|
OFPUTIL_PC_NO_FWD = 1 << 5, /* Drop packets forwarded to port. */
|
|
|
|
|
OFPUTIL_PC_NO_PACKET_IN = 1 << 6, /* No send packet-in msgs for port. */
|
|
|
|
|
/* OpenFlow 1.0 only. */
|
|
|
|
|
OFPUTIL_PC_NO_STP = 1 << 1, /* No 802.1D spanning tree for port. */
|
|
|
|
|
OFPUTIL_PC_NO_RECV_STP = 1 << 3, /* Drop received 802.1D STP packets. */
|
|
|
|
|
OFPUTIL_PC_NO_FLOOD = 1 << 4, /* Do not include port when flooding. */
|
|
|
|
|
/* There are no OpenFlow 1.1-only bits. */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum ofputil_port_state {
|
|
|
|
|
/* OpenFlow 1.0 and 1.1 share this values for these port state bits. */
|
|
|
|
|
OFPUTIL_PS_LINK_DOWN = 1 << 0, /* No physical link present. */
|
|
|
|
|
/* OpenFlow 1.1 only. */
|
|
|
|
|
OFPUTIL_PS_BLOCKED = 1 << 1, /* Port is blocked */
|
|
|
|
|
OFPUTIL_PS_LIVE = 1 << 2, /* Live for Fast Failover Group. */
|
|
|
|
|
/* OpenFlow 1.0 only. */
|
|
|
|
|
OFPUTIL_PS_STP_LISTEN = 0 << 8, /* Not learning or relaying frames. */
|
|
|
|
|
OFPUTIL_PS_STP_LEARN = 1 << 8, /* Learning but not relaying frames. */
|
|
|
|
|
OFPUTIL_PS_STP_FORWARD = 2 << 8, /* Learning and relaying frames. */
|
|
|
|
|
OFPUTIL_PS_STP_BLOCK = 3 << 8, /* Not part of spanning tree. */
|
|
|
|
|
OFPUTIL_PS_STP_MASK = 3 << 8 /* Bit mask for OFPPS10_STP_* values. */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Abstract ofp10_phy_port or ofp11_port. */
|
|
|
|
|
struct ofputil_phy_port {
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t port_no;
|
2012-02-15 16:33:04 -08:00
|
|
|
|
uint8_t hw_addr[OFP_ETH_ALEN];
|
|
|
|
|
char name[OFP_MAX_PORT_NAME_LEN];
|
|
|
|
|
enum ofputil_port_config config;
|
|
|
|
|
enum ofputil_port_state state;
|
|
|
|
|
|
|
|
|
|
/* NETDEV_F_* feature bitmasks. */
|
|
|
|
|
enum netdev_features curr; /* Current features. */
|
|
|
|
|
enum netdev_features advertised; /* Features advertised by the port. */
|
|
|
|
|
enum netdev_features supported; /* Features supported by the port. */
|
|
|
|
|
enum netdev_features peer; /* Features advertised by peer. */
|
|
|
|
|
|
|
|
|
|
/* Speed. */
|
|
|
|
|
uint32_t curr_speed; /* Current speed, in kbps. */
|
|
|
|
|
uint32_t max_speed; /* Maximum supported speed, in kbps. */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum ofputil_capabilities {
|
2012-11-27 17:44:22 +02:00
|
|
|
|
/* OpenFlow 1.0, 1.1, 1.2, and 1.3 share these capability values. */
|
2012-02-15 16:33:04 -08:00
|
|
|
|
OFPUTIL_C_FLOW_STATS = 1 << 0, /* Flow statistics. */
|
|
|
|
|
OFPUTIL_C_TABLE_STATS = 1 << 1, /* Table statistics. */
|
|
|
|
|
OFPUTIL_C_PORT_STATS = 1 << 2, /* Port statistics. */
|
|
|
|
|
OFPUTIL_C_IP_REASM = 1 << 5, /* Can reassemble IP fragments. */
|
|
|
|
|
OFPUTIL_C_QUEUE_STATS = 1 << 6, /* Queue statistics. */
|
2012-07-30 11:03:03 +09:00
|
|
|
|
|
|
|
|
|
/* OpenFlow 1.0 and 1.1 share this capability. */
|
2012-02-15 16:33:04 -08:00
|
|
|
|
OFPUTIL_C_ARP_MATCH_IP = 1 << 7, /* Match IP addresses in ARP pkts. */
|
|
|
|
|
|
|
|
|
|
/* OpenFlow 1.0 only. */
|
|
|
|
|
OFPUTIL_C_STP = 1 << 3, /* 802.1d spanning tree. */
|
|
|
|
|
|
2012-11-27 17:44:22 +02:00
|
|
|
|
/* OpenFlow 1.1, 1.2, and 1.3 share this capability. */
|
2012-02-15 16:33:04 -08:00
|
|
|
|
OFPUTIL_C_GROUP_STATS = 1 << 4, /* Group statistics. */
|
2012-07-30 11:03:03 +09:00
|
|
|
|
|
2012-11-27 17:44:22 +02:00
|
|
|
|
/* OpenFlow 1.2 and 1.3 share this capability */
|
2012-07-30 11:03:03 +09:00
|
|
|
|
OFPUTIL_C_PORT_BLOCKED = 1 << 8, /* Switch will block looping ports */
|
2012-02-15 16:33:04 -08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum ofputil_action_bitmap {
|
|
|
|
|
OFPUTIL_A_OUTPUT = 1 << 0,
|
|
|
|
|
OFPUTIL_A_SET_VLAN_VID = 1 << 1,
|
|
|
|
|
OFPUTIL_A_SET_VLAN_PCP = 1 << 2,
|
|
|
|
|
OFPUTIL_A_STRIP_VLAN = 1 << 3,
|
|
|
|
|
OFPUTIL_A_SET_DL_SRC = 1 << 4,
|
|
|
|
|
OFPUTIL_A_SET_DL_DST = 1 << 5,
|
|
|
|
|
OFPUTIL_A_SET_NW_SRC = 1 << 6,
|
|
|
|
|
OFPUTIL_A_SET_NW_DST = 1 << 7,
|
|
|
|
|
OFPUTIL_A_SET_NW_ECN = 1 << 8,
|
|
|
|
|
OFPUTIL_A_SET_NW_TOS = 1 << 9,
|
|
|
|
|
OFPUTIL_A_SET_TP_SRC = 1 << 10,
|
|
|
|
|
OFPUTIL_A_SET_TP_DST = 1 << 11,
|
|
|
|
|
OFPUTIL_A_ENQUEUE = 1 << 12,
|
|
|
|
|
OFPUTIL_A_COPY_TTL_OUT = 1 << 13,
|
|
|
|
|
OFPUTIL_A_COPY_TTL_IN = 1 << 14,
|
|
|
|
|
OFPUTIL_A_SET_MPLS_LABEL = 1 << 15,
|
|
|
|
|
OFPUTIL_A_SET_MPLS_TC = 1 << 16,
|
|
|
|
|
OFPUTIL_A_SET_MPLS_TTL = 1 << 17,
|
|
|
|
|
OFPUTIL_A_DEC_MPLS_TTL = 1 << 18,
|
|
|
|
|
OFPUTIL_A_PUSH_VLAN = 1 << 19,
|
|
|
|
|
OFPUTIL_A_POP_VLAN = 1 << 20,
|
|
|
|
|
OFPUTIL_A_PUSH_MPLS = 1 << 21,
|
|
|
|
|
OFPUTIL_A_POP_MPLS = 1 << 22,
|
|
|
|
|
OFPUTIL_A_SET_QUEUE = 1 << 23,
|
|
|
|
|
OFPUTIL_A_GROUP = 1 << 24,
|
|
|
|
|
OFPUTIL_A_SET_NW_TTL = 1 << 25,
|
|
|
|
|
OFPUTIL_A_DEC_NW_TTL = 1 << 26,
|
2012-09-04 10:32:48 +09:00
|
|
|
|
OFPUTIL_A_SET_FIELD = 1 << 27,
|
2012-02-15 16:33:04 -08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Abstract ofp_switch_features. */
|
|
|
|
|
struct ofputil_switch_features {
|
|
|
|
|
uint64_t datapath_id; /* Datapath unique ID. */
|
|
|
|
|
uint32_t n_buffers; /* Max packets buffered at once. */
|
|
|
|
|
uint8_t n_tables; /* Number of tables supported by datapath. */
|
2012-11-27 17:44:22 +02:00
|
|
|
|
uint8_t auxiliary_id; /* Identify auxiliary connections */
|
2012-02-15 16:33:04 -08:00
|
|
|
|
enum ofputil_capabilities capabilities;
|
|
|
|
|
enum ofputil_action_bitmap actions;
|
|
|
|
|
};
|
|
|
|
|
|
2012-07-19 23:23:17 -07:00
|
|
|
|
enum ofperr ofputil_decode_switch_features(const struct ofp_header *,
|
2012-02-15 16:33:04 -08:00
|
|
|
|
struct ofputil_switch_features *,
|
|
|
|
|
struct ofpbuf *);
|
|
|
|
|
|
|
|
|
|
struct ofpbuf *ofputil_encode_switch_features(
|
|
|
|
|
const struct ofputil_switch_features *, enum ofputil_protocol,
|
|
|
|
|
ovs_be32 xid);
|
|
|
|
|
void ofputil_put_switch_features_port(const struct ofputil_phy_port *,
|
|
|
|
|
struct ofpbuf *);
|
2012-05-04 17:19:26 -07:00
|
|
|
|
bool ofputil_switch_features_ports_trunc(struct ofpbuf *b);
|
2012-02-15 16:33:04 -08:00
|
|
|
|
|
2012-05-04 14:42:04 -07:00
|
|
|
|
/* phy_port helper functions. */
|
2012-07-30 11:02:59 +09:00
|
|
|
|
int ofputil_pull_phy_port(enum ofp_version ofp_version, struct ofpbuf *,
|
2012-05-04 14:42:04 -07:00
|
|
|
|
struct ofputil_phy_port *);
|
|
|
|
|
size_t ofputil_count_phy_ports(uint8_t ofp_version, struct ofpbuf *);
|
|
|
|
|
|
2012-02-15 16:33:04 -08:00
|
|
|
|
/* Abstract ofp_port_status. */
|
|
|
|
|
struct ofputil_port_status {
|
|
|
|
|
enum ofp_port_reason reason;
|
|
|
|
|
struct ofputil_phy_port desc;
|
|
|
|
|
};
|
|
|
|
|
|
2012-07-19 23:23:17 -07:00
|
|
|
|
enum ofperr ofputil_decode_port_status(const struct ofp_header *,
|
2012-02-15 16:33:04 -08:00
|
|
|
|
struct ofputil_port_status *);
|
|
|
|
|
struct ofpbuf *ofputil_encode_port_status(const struct ofputil_port_status *,
|
|
|
|
|
enum ofputil_protocol);
|
|
|
|
|
|
|
|
|
|
/* Abstract ofp_port_mod. */
|
|
|
|
|
struct ofputil_port_mod {
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t port_no;
|
2012-02-15 16:33:04 -08:00
|
|
|
|
uint8_t hw_addr[OFP_ETH_ALEN];
|
|
|
|
|
enum ofputil_port_config config;
|
|
|
|
|
enum ofputil_port_config mask;
|
|
|
|
|
enum netdev_features advertise;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum ofperr ofputil_decode_port_mod(const struct ofp_header *,
|
|
|
|
|
struct ofputil_port_mod *);
|
|
|
|
|
struct ofpbuf *ofputil_encode_port_mod(const struct ofputil_port_mod *,
|
|
|
|
|
enum ofputil_protocol);
|
2012-02-15 14:23:38 -08:00
|
|
|
|
|
2012-12-28 18:28:49 +02:00
|
|
|
|
/* Abstract ofp_role_request and reply. */
|
|
|
|
|
struct ofputil_role_request {
|
2013-02-11 23:55:31 -08:00
|
|
|
|
enum ofp12_controller_role role;
|
2012-12-28 18:28:49 +02:00
|
|
|
|
bool have_generation_id;
|
|
|
|
|
uint64_t generation_id;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum ofperr ofputil_decode_role_message(const struct ofp_header *,
|
|
|
|
|
struct ofputil_role_request *);
|
|
|
|
|
struct ofpbuf *ofputil_encode_role_reply(const struct ofp_header *,
|
2013-02-11 23:55:31 -08:00
|
|
|
|
const struct ofputil_role_request *);
|
2012-12-28 18:28:49 +02:00
|
|
|
|
|
2012-09-11 21:47:27 -07:00
|
|
|
|
/* Abstract table stats.
|
|
|
|
|
*
|
|
|
|
|
* For now we use ofp12_table_stats as a superset of the other protocol
|
|
|
|
|
* versions' table stats. */
|
|
|
|
|
|
|
|
|
|
struct ofpbuf *ofputil_encode_table_stats_reply(
|
|
|
|
|
const struct ofp12_table_stats[], int n,
|
|
|
|
|
const struct ofp_header *request);
|
|
|
|
|
|
2012-07-12 14:18:05 -07:00
|
|
|
|
/* Abstract nx_flow_monitor_request. */
|
|
|
|
|
struct ofputil_flow_monitor_request {
|
|
|
|
|
uint32_t id;
|
|
|
|
|
enum nx_flow_monitor_flags flags;
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t out_port;
|
2012-07-12 14:18:05 -07:00
|
|
|
|
uint8_t table_id;
|
2012-08-07 15:28:18 -07:00
|
|
|
|
struct match match;
|
2012-07-12 14:18:05 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request *,
|
|
|
|
|
struct ofpbuf *msg);
|
|
|
|
|
void ofputil_append_flow_monitor_request(
|
|
|
|
|
const struct ofputil_flow_monitor_request *, struct ofpbuf *msg);
|
|
|
|
|
|
|
|
|
|
/* Abstract nx_flow_update. */
|
|
|
|
|
struct ofputil_flow_update {
|
|
|
|
|
enum nx_flow_update_event event;
|
|
|
|
|
|
|
|
|
|
/* Used only for NXFME_ADDED, NXFME_DELETED, NXFME_MODIFIED. */
|
|
|
|
|
enum ofp_flow_removed_reason reason;
|
|
|
|
|
uint16_t idle_timeout;
|
|
|
|
|
uint16_t hard_timeout;
|
|
|
|
|
uint8_t table_id;
|
|
|
|
|
ovs_be64 cookie;
|
2012-08-07 15:28:18 -07:00
|
|
|
|
struct match *match;
|
|
|
|
|
uint16_t priority;
|
2012-07-12 14:18:05 -07:00
|
|
|
|
struct ofpact *ofpacts;
|
|
|
|
|
size_t ofpacts_len;
|
|
|
|
|
|
|
|
|
|
/* Used only for NXFME_ABBREV. */
|
|
|
|
|
ovs_be32 xid;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int ofputil_decode_flow_update(struct ofputil_flow_update *,
|
|
|
|
|
struct ofpbuf *msg, struct ofpbuf *ofpacts);
|
|
|
|
|
void ofputil_start_flow_update(struct list *replies);
|
|
|
|
|
void ofputil_append_flow_update(const struct ofputil_flow_update *,
|
|
|
|
|
struct list *replies);
|
|
|
|
|
|
|
|
|
|
/* Abstract nx_flow_monitor_cancel. */
|
|
|
|
|
uint32_t ofputil_decode_flow_monitor_cancel(const struct ofp_header *);
|
|
|
|
|
struct ofpbuf *ofputil_encode_flow_monitor_cancel(uint32_t id);
|
|
|
|
|
|
2012-07-19 23:23:17 -07:00
|
|
|
|
/* Encoding OpenFlow stats messages. */
|
2012-07-30 11:02:59 +09:00
|
|
|
|
void ofputil_append_port_desc_stats_reply(enum ofp_version ofp_version,
|
2012-05-04 14:42:04 -07:00
|
|
|
|
const struct ofputil_phy_port *pp,
|
|
|
|
|
struct list *replies);
|
|
|
|
|
|
2012-07-19 23:23:17 -07:00
|
|
|
|
/* Encoding simple OpenFlow messages. */
|
2012-08-01 16:01:50 +09:00
|
|
|
|
struct ofpbuf *make_echo_request(enum ofp_version);
|
2010-05-27 13:14:05 -07:00
|
|
|
|
struct ofpbuf *make_echo_reply(const struct ofp_header *rq);
|
Implement new fragment handling policy.
Until now, OVS has handled IP fragments more awkwardly than necessary. It
has not been possible to match on L4 headers, even in fragments with offset
0 where they are actually present. This means that there was no way to
implement ACLs that treat, say, different TCP ports differently, on
fragmented traffic; instead, all decisions for fragment forwarding had to
be made on the basis of L2 and L3 headers alone.
This commit improves the situation significantly. It is still not possible
to match on L4 headers in fragments with nonzero offset, because that
information is simply not present in such fragments, but this commit adds
the ability to match on L4 headers for fragments with zero offset. This
means that it becomes possible to implement ACLs that drop such "first
fragments" on the basis of L4 headers. In practice, that effectively
blocks even fragmented traffic on an L4 basis, because the receiving IP
stack cannot reassemble a full packet when the first fragment is missing.
This commit works by adding a new "fragment type" to the kernel flow match
and making it available through OpenFlow as a new NXM field named
NXM_NX_IP_FRAG. Because OpenFlow 1.0 explicitly says that the L4 fields
are always 0 for IP fragments, it adds a new OpenFlow fragment handling
mode that fills in the L4 fields for "first fragments". It also enhances
ovs-ofctl to allow users to configure this new fragment handling mode and
to parse the new field.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Bug #7557.
2011-10-19 21:33:44 -07:00
|
|
|
|
|
2012-08-01 16:01:47 +09:00
|
|
|
|
struct ofpbuf *ofputil_encode_barrier_request(enum ofp_version);
|
2012-01-26 13:17:12 -08:00
|
|
|
|
|
Implement new fragment handling policy.
Until now, OVS has handled IP fragments more awkwardly than necessary. It
has not been possible to match on L4 headers, even in fragments with offset
0 where they are actually present. This means that there was no way to
implement ACLs that treat, say, different TCP ports differently, on
fragmented traffic; instead, all decisions for fragment forwarding had to
be made on the basis of L2 and L3 headers alone.
This commit improves the situation significantly. It is still not possible
to match on L4 headers in fragments with nonzero offset, because that
information is simply not present in such fragments, but this commit adds
the ability to match on L4 headers for fragments with zero offset. This
means that it becomes possible to implement ACLs that drop such "first
fragments" on the basis of L4 headers. In practice, that effectively
blocks even fragmented traffic on an L4 basis, because the receiving IP
stack cannot reassemble a full packet when the first fragment is missing.
This commit works by adding a new "fragment type" to the kernel flow match
and making it available through OpenFlow as a new NXM field named
NXM_NX_IP_FRAG. Because OpenFlow 1.0 explicitly says that the L4 fields
are always 0 for IP fragments, it adds a new OpenFlow fragment handling
mode that fills in the L4 fields for "first fragments". It also enhances
ovs-ofctl to allow users to configure this new fragment handling mode and
to parse the new field.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Bug #7557.
2011-10-19 21:33:44 -07:00
|
|
|
|
const char *ofputil_frag_handling_to_string(enum ofp_config_flags);
|
|
|
|
|
bool ofputil_frag_handling_from_string(const char *, enum ofp_config_flags *);
|
2012-05-04 14:42:04 -07:00
|
|
|
|
|
2010-12-07 16:57:12 -08:00
|
|
|
|
|
|
|
|
|
/* Actions. */
|
|
|
|
|
|
2011-08-17 11:01:17 -07:00
|
|
|
|
/* The type of an action.
|
|
|
|
|
*
|
2012-02-15 16:22:18 -08:00
|
|
|
|
* For each implemented OFPAT10_* and NXAST_* action type, there is a
|
2011-08-17 11:01:17 -07:00
|
|
|
|
* corresponding constant prefixed with OFPUTIL_, e.g.:
|
|
|
|
|
*
|
2012-02-15 16:22:18 -08:00
|
|
|
|
* OFPUTIL_OFPAT10_OUTPUT
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_VLAN_VID
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_VLAN_PCP
|
|
|
|
|
* OFPUTIL_OFPAT10_STRIP_VLAN
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_DL_SRC
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_DL_DST
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_NW_SRC
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_NW_DST
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_NW_TOS
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_TP_SRC
|
|
|
|
|
* OFPUTIL_OFPAT10_SET_TP_DST
|
|
|
|
|
* OFPUTIL_OFPAT10_ENQUEUE
|
2011-08-17 11:01:17 -07:00
|
|
|
|
* OFPUTIL_NXAST_RESUBMIT
|
|
|
|
|
* OFPUTIL_NXAST_SET_TUNNEL
|
2012-10-19 02:37:37 +09:00
|
|
|
|
* OFPUTIL_NXAST_SET_METADATA
|
2011-08-17 11:01:17 -07:00
|
|
|
|
* OFPUTIL_NXAST_SET_QUEUE
|
|
|
|
|
* OFPUTIL_NXAST_POP_QUEUE
|
|
|
|
|
* OFPUTIL_NXAST_REG_MOVE
|
|
|
|
|
* OFPUTIL_NXAST_REG_LOAD
|
|
|
|
|
* OFPUTIL_NXAST_NOTE
|
|
|
|
|
* OFPUTIL_NXAST_SET_TUNNEL64
|
|
|
|
|
* OFPUTIL_NXAST_MULTIPATH
|
|
|
|
|
* OFPUTIL_NXAST_BUNDLE
|
|
|
|
|
* OFPUTIL_NXAST_BUNDLE_LOAD
|
|
|
|
|
* OFPUTIL_NXAST_RESUBMIT_TABLE
|
|
|
|
|
* OFPUTIL_NXAST_OUTPUT_REG
|
2012-02-15 10:37:03 -08:00
|
|
|
|
* OFPUTIL_NXAST_LEARN
|
|
|
|
|
* OFPUTIL_NXAST_DEC_TTL
|
|
|
|
|
* OFPUTIL_NXAST_FIN_TIMEOUT
|
2011-08-17 11:01:17 -07:00
|
|
|
|
*
|
|
|
|
|
* (The above list helps developers who want to "grep" for these definitions.)
|
|
|
|
|
*/
|
2012-07-03 22:17:14 -07:00
|
|
|
|
enum OVS_PACKED_ENUM ofputil_action_code {
|
2012-06-07 20:23:59 -04:00
|
|
|
|
OFPUTIL_ACTION_INVALID,
|
2012-09-24 13:18:38 -07:00
|
|
|
|
#define OFPAT10_ACTION(ENUM, STRUCT, NAME) OFPUTIL_##ENUM,
|
|
|
|
|
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) OFPUTIL_##ENUM,
|
|
|
|
|
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) OFPUTIL_##ENUM,
|
2011-08-17 11:01:17 -07:00
|
|
|
|
#include "ofp-util.def"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* The number of values of "enum ofputil_action_code". */
|
|
|
|
|
enum {
|
2012-09-24 13:18:38 -07:00
|
|
|
|
#define OFPAT10_ACTION(ENUM, STRUCT, NAME) + 1
|
|
|
|
|
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) + 1
|
|
|
|
|
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) + 1
|
2012-06-07 20:23:59 -04:00
|
|
|
|
OFPUTIL_N_ACTIONS = 1
|
2011-08-17 11:01:17 -07:00
|
|
|
|
#include "ofp-util.def"
|
2011-06-30 10:05:52 -07:00
|
|
|
|
};
|
|
|
|
|
|
2011-08-17 11:01:17 -07:00
|
|
|
|
int ofputil_action_code_from_name(const char *);
|
|
|
|
|
|
2011-08-16 16:30:57 -07:00
|
|
|
|
void *ofputil_put_action(enum ofputil_action_code, struct ofpbuf *buf);
|
|
|
|
|
|
|
|
|
|
/* For each OpenFlow action <ENUM> that has a corresponding action structure
|
|
|
|
|
* struct <STRUCT>, this defines two functions:
|
|
|
|
|
*
|
|
|
|
|
* void ofputil_init_<ENUM>(struct <STRUCT> *action);
|
|
|
|
|
*
|
|
|
|
|
* Initializes the parts of 'action' that identify it as having type <ENUM>
|
|
|
|
|
* and length 'sizeof *action' and zeros the rest. For actions that have
|
|
|
|
|
* variable length, the length used and cleared is that of struct <STRUCT>.
|
|
|
|
|
*
|
|
|
|
|
* struct <STRUCT> *ofputil_put_<ENUM>(struct ofpbuf *buf);
|
|
|
|
|
*
|
|
|
|
|
* Appends a new 'action', of length 'sizeof(struct <STRUCT>)', to 'buf',
|
|
|
|
|
* initializes it with ofputil_init_<ENUM>(), and returns it.
|
|
|
|
|
*/
|
2012-02-15 16:22:18 -08:00
|
|
|
|
#define OFPAT10_ACTION(ENUM, STRUCT, NAME) \
|
2011-08-16 16:30:57 -07:00
|
|
|
|
void ofputil_init_##ENUM(struct STRUCT *); \
|
|
|
|
|
struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
|
2012-09-24 13:18:38 -07:00
|
|
|
|
#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
|
2012-07-03 22:14:29 -07:00
|
|
|
|
void ofputil_init_##ENUM(struct STRUCT *); \
|
|
|
|
|
struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
|
2011-08-16 16:30:57 -07:00
|
|
|
|
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
|
|
|
|
|
void ofputil_init_##ENUM(struct STRUCT *); \
|
|
|
|
|
struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
|
|
|
|
|
#include "ofp-util.def"
|
|
|
|
|
|
2010-12-07 16:57:12 -08:00
|
|
|
|
#define OFP_ACTION_ALIGN 8 /* Alignment of ofp_actions. */
|
2010-05-27 13:14:05 -07:00
|
|
|
|
|
2011-03-29 14:42:20 -07:00
|
|
|
|
bool action_outputs_to_port(const union ofp_action *, ovs_be16 port);
|
2010-11-08 10:43:19 -08:00
|
|
|
|
|
2012-01-12 15:48:19 -08:00
|
|
|
|
enum ofperr ofputil_pull_actions(struct ofpbuf *, unsigned int actions_len,
|
|
|
|
|
union ofp_action **, size_t *);
|
2011-05-26 16:49:10 -07:00
|
|
|
|
|
|
|
|
|
bool ofputil_actions_equal(const union ofp_action *a, size_t n_a,
|
|
|
|
|
const union ofp_action *b, size_t n_b);
|
|
|
|
|
union ofp_action *ofputil_actions_clone(const union ofp_action *, size_t n);
|
2010-08-20 10:29:03 -07:00
|
|
|
|
|
2011-08-17 13:39:02 -07:00
|
|
|
|
/* Handy utility for parsing flows and actions. */
|
|
|
|
|
bool ofputil_parse_key_value(char **stringp, char **keyp, char **valuep);
|
|
|
|
|
|
2012-10-06 19:39:49 +09:00
|
|
|
|
struct ofputil_port_stats {
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t port_no;
|
2012-10-06 19:39:49 +09:00
|
|
|
|
struct netdev_stats stats;
|
2013-05-30 12:49:59 -07:00
|
|
|
|
uint32_t duration_sec; /* UINT32_MAX if unknown. */
|
|
|
|
|
uint32_t duration_nsec;
|
2012-10-06 19:39:49 +09:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ofpbuf *ofputil_encode_dump_ports_request(enum ofp_version ofp_version,
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t port);
|
2012-10-06 19:39:49 +09:00
|
|
|
|
void ofputil_append_port_stat(struct list *replies,
|
|
|
|
|
const struct ofputil_port_stats *ops);
|
|
|
|
|
size_t ofputil_count_port_stats(const struct ofp_header *);
|
|
|
|
|
int ofputil_decode_port_stats(struct ofputil_port_stats *, struct ofpbuf *msg);
|
|
|
|
|
enum ofperr ofputil_decode_port_stats_request(const struct ofp_header *request,
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t *ofp10_port);
|
2012-10-12 13:03:04 +09:00
|
|
|
|
|
|
|
|
|
struct ofputil_queue_stats_request {
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t port_no; /* OFPP_ANY means "all ports". */
|
2012-10-12 13:03:04 +09:00
|
|
|
|
uint32_t queue_id;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum ofperr
|
|
|
|
|
ofputil_decode_queue_stats_request(const struct ofp_header *request,
|
|
|
|
|
struct ofputil_queue_stats_request *oqsr);
|
|
|
|
|
struct ofpbuf *
|
|
|
|
|
ofputil_encode_queue_stats_request(enum ofp_version ofp_version,
|
|
|
|
|
const struct ofputil_queue_stats_request *oqsr);
|
|
|
|
|
|
|
|
|
|
struct ofputil_queue_stats {
|
2013-06-19 16:58:44 -07:00
|
|
|
|
ofp_port_t port_no;
|
2012-10-12 13:03:04 +09:00
|
|
|
|
uint32_t queue_id;
|
|
|
|
|
struct netdev_queue_stats stats;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
size_t ofputil_count_queue_stats(const struct ofp_header *);
|
|
|
|
|
int ofputil_decode_queue_stats(struct ofputil_queue_stats *qs, struct ofpbuf *msg);
|
|
|
|
|
void ofputil_append_queue_stat(struct list *replies,
|
|
|
|
|
const struct ofputil_queue_stats *oqs);
|
|
|
|
|
|
2010-05-27 13:14:05 -07:00
|
|
|
|
#endif /* ofp-util.h */
|