Commit 0d71302e authored by Ben Pfaff's avatar Ben Pfaff

ofp-util, ofp-parse: Break up into many separate modules.

ofp-util had been far too large and monolithic for a long time.  This
commit breaks it up into units that make some logical sense.  It also
moves the pieces of ofp-parse that were specific to each unit into the
relevant unit.

Most of this commit is just moving code around.
Signed-off-by: default avatarBen Pfaff <blp@ovn.org>
Reviewed-by: default avatarYifeng Sun <pkusunyifeng@gmail.com>
parent 31292693
......@@ -44,7 +44,7 @@ The primary approach to compatibility is to abstract most of the details of the
differences from the core code, by adding a protocol layer that translates
between OF1.x and a slightly higher-level abstract representation. The core of
this approach is the many ``struct ofputil_*`` structures in
``include/openvswitch/ofp-util.h``.
``include/openvswitch/ofp-*.h``.
As a consequence of this approach, OVS cannot use OpenFlow protocol definitions
that closely resemble those in the OpenFlow specification, because
......
......@@ -10,14 +10,29 @@ openvswitchinclude_HEADERS = \
include/openvswitch/netdev.h \
include/openvswitch/match.h \
include/openvswitch/meta-flow.h \
include/openvswitch/namemap.h \
include/openvswitch/ofpbuf.h \
include/openvswitch/ofp-actions.h \
include/openvswitch/ofp-bundle.h \
include/openvswitch/ofp-connection.h \
include/openvswitch/ofp-ed-props.h \
include/openvswitch/ofp-errors.h \
include/openvswitch/ofp-flow.h \
include/openvswitch/ofp-group.h \
include/openvswitch/ofp-ipfix.h \
include/openvswitch/ofp-match.h \
include/openvswitch/ofp-meter.h \
include/openvswitch/ofp-monitor.h \
include/openvswitch/ofp-msgs.h \
include/openvswitch/ofp-packet.h \
include/openvswitch/ofp-parse.h \
include/openvswitch/ofp-port.h \
include/openvswitch/ofp-print.h \
include/openvswitch/ofp-prop.h \
include/openvswitch/ofp-protocol.h \
include/openvswitch/ofp-queue.h \
include/openvswitch/ofp-switch.h \
include/openvswitch/ofp-table.h \
include/openvswitch/ofp-util.h \
include/openvswitch/packets.h \
include/openvswitch/poll-loop.h \
......
......@@ -25,6 +25,7 @@
#include <netinet/ip6.h>
#include "openvswitch/flow.h"
#include "openvswitch/ofp-errors.h"
#include "openvswitch/ofp-protocol.h"
#include "openvswitch/packets.h"
#include "openvswitch/util.h"
......@@ -2031,14 +2032,10 @@ struct mf_field {
* the OpenFlow protocol version the field was introduced in.
* Also, some field types are tranparently mapped to each other via the
* struct flow (like vlan and dscp/tos fields), so each variant supports
* all protocols.
*
* These are combinations of OFPUTIL_P_*. (They are not declared as type
* enum ofputil_protocol because that would give meta-flow.h and ofp-util.h
* a circular dependency.) */
uint32_t usable_protocols_exact; /* Matching or setting whole field. */
uint32_t usable_protocols_cidr; /* Matching a CIDR mask in field. */
uint32_t usable_protocols_bitwise; /* Matching arbitrary bits in field. */
* all protocols. */
enum ofputil_protocol usable_protocols_exact; /* Match/set whole field. */
enum ofputil_protocol usable_protocols_cidr; /* Match CIDR mask. */
enum ofputil_protocol usable_protocols_bitwise; /* Match arbitrary bits. */
int flow_be32ofs; /* Field's be32 offset in "struct flow", if prefix tree
* lookup is supported for the field, or -1. */
......
/*
* Copyright (c) 2008-2017 Nicira, Inc.
*
* 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 OPENVSWITCH_NAMEMAP_H
#define OPENVSWITCH_NAMEMAP_H 1
#include "openvswitch/hmap.h"
struct ds;
#ifdef __cplusplus
extern "C" {
#endif
/* Name-number mapping.
*
* This data structure tracks and manages a mapping between names and 32-bit
* unsigned integers, with provision for detecting names that are used more
* than once.
*
* This structure is suitable for tracking mappings between OpenFlow port names
* and numbers. OpenFlow doesn't require either these kinds of names to be
* unique, and in OVS it's possible for two ports to appear to have the same
* name if their names are longer than the maximum length supported by a given
* version of OpenFlow.
*
* OpenFlow does require port numbers to be unique. We check for duplicate
* ports numbers just in case a switch has a bug.
*
* This structure is also suitable for tracking mappings between OpenFlow table
* names and number. OpenFlow doesn't require table names to be unique and
* Open vSwitch doesn't try to make them unique. */
struct namemap_node {
struct hmap_node name_node;
struct hmap_node number_node;
uint32_t number;
char *name;
bool duplicate;
};
struct namemap {
struct hmap by_name;
struct hmap by_number;
};
#define NAMEMAP_INITIALIZER(MAP) \
{ HMAP_INITIALIZER(&(MAP)->by_name), HMAP_INITIALIZER(&(MAP)->by_number) }
void namemap_init(struct namemap *);
struct namemap_node *namemap_find_by_name(const struct namemap *,
const char *);
struct namemap_node *namemap_find_by_number(const struct namemap *, uint32_t);
void namemap_put(struct namemap *, uint32_t, const char *);
void namemap_destroy(struct namemap *);
void namemap_put_name(const char *, struct ds *);
#ifdef __cplusplus
}
#endif
#endif /* namemap.h */
......@@ -22,8 +22,8 @@
#include "openflow/openflow.h"
#include "openflow/nicira-ext.h"
#include "openvswitch/meta-flow.h"
#include "openvswitch/ofp-util.h"
#include "openvswitch/ofp-errors.h"
#include "openvswitch/ofp-protocol.h"
#include "openvswitch/types.h"
#include "openvswitch/ofp-ed-props.h"
......
/*
* Copyright (c) 2008-2017 Nicira, Inc.
*
* 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 OPENVSWITCH_OFP_BUNDLE_H
#define OPENVSWITCH_OFP_BUNDLE_H 1
#include "openflow/openflow.h"
#include "openvswitch/ofp-flow.h"
#include "openvswitch/ofp-group.h"
#include "openvswitch/ofp-packet.h"
#include "openvswitch/ofp-msgs.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ofputil_bundle_ctrl_msg {
uint32_t bundle_id;
uint16_t type;
uint16_t flags;
};
struct ofputil_bundle_add_msg {
uint32_t bundle_id;
uint16_t flags;
const struct ofp_header *msg;
};
enum ofperr ofputil_decode_bundle_ctrl(const struct ofp_header *,
struct ofputil_bundle_ctrl_msg *);
struct ofpbuf *ofputil_encode_bundle_ctrl_request(
enum ofp_version, struct ofputil_bundle_ctrl_msg *);
struct ofpbuf *ofputil_encode_bundle_ctrl_reply(
const struct ofp_header *, struct ofputil_bundle_ctrl_msg *);
struct ofpbuf *ofputil_encode_bundle_add(enum ofp_version,
struct ofputil_bundle_add_msg *);
enum ofperr ofputil_decode_bundle_add(const struct ofp_header *,
struct ofputil_bundle_add_msg *,
enum ofptype *);
/* Bundle message as produced by ofp-parse. */
struct ofputil_bundle_msg {
enum ofptype type;
union {
struct ofputil_flow_mod fm;
struct ofputil_group_mod gm;
struct ofputil_packet_out po;
};
};
void ofputil_encode_bundle_msgs(const struct ofputil_bundle_msg *, size_t n,
struct ovs_list *requests,
enum ofputil_protocol);
void ofputil_free_bundle_msgs(struct ofputil_bundle_msg *, size_t n);
char *parse_ofp_bundle_file(const char *file_name,
const struct ofputil_port_map *,
const struct ofputil_table_map *,
struct ofputil_bundle_msg **, size_t *n_bms,
enum ofputil_protocol *)
OVS_WARN_UNUSED_RESULT;
#ifdef __cplusplus
}
#endif
#endif /* ofp-bundle.h */
/*
* Copyright (c) 2008-2017 Nicira, Inc.
*
* 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 OPENVSWITCH_OFP_CONNECTION_H
#define OPENVSWITCH_OFP_CONNECTION_H 1
#include "openflow/openflow.h"
#include "openvswitch/ofp-protocol.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Abstract ofp_role_request and reply. */
struct ofputil_role_request {
enum ofp12_controller_role role;
bool have_generation_id;
uint64_t generation_id;
};
struct ofputil_role_status {
enum ofp12_controller_role role;
enum ofp14_controller_role_reason reason;
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 *,
const struct ofputil_role_request *);
struct ofpbuf *ofputil_encode_role_status(const struct ofputil_role_status *,
enum ofputil_protocol);
enum ofperr ofputil_decode_role_status(const struct ofp_header *,
struct ofputil_role_status *);
enum ofputil_async_msg_type {
/* Standard asynchronous messages. */
OAM_PACKET_IN, /* OFPT_PACKET_IN or NXT_PACKET_IN. */
OAM_PORT_STATUS, /* OFPT_PORT_STATUS. */
OAM_FLOW_REMOVED, /* OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED. */
OAM_ROLE_STATUS, /* OFPT_ROLE_STATUS. */
OAM_TABLE_STATUS, /* OFPT_TABLE_STATUS. */
OAM_REQUESTFORWARD, /* OFPT_REQUESTFORWARD. */
/* Extension asynchronous messages (none yet--coming soon!). */
#define OAM_EXTENSIONS 0 /* Bitmap of all extensions. */
OAM_N_TYPES
};
const char *ofputil_async_msg_type_to_string(enum ofputil_async_msg_type);
struct ofputil_async_cfg {
uint32_t master[OAM_N_TYPES];
uint32_t slave[OAM_N_TYPES];
};
#define OFPUTIL_ASYNC_CFG_INIT (struct ofputil_async_cfg) { .master[0] = 0 }
enum ofperr ofputil_decode_set_async_config(const struct ofp_header *,
bool loose,
const struct ofputil_async_cfg *,
struct ofputil_async_cfg *);
struct ofpbuf *ofputil_encode_get_async_reply(
const struct ofp_header *, const struct ofputil_async_cfg *);
struct ofpbuf *ofputil_encode_set_async_config(
const struct ofputil_async_cfg *, uint32_t oams, enum ofp_version);
struct ofputil_async_cfg ofputil_async_cfg_default(enum ofp_version);
#ifdef __cplusplus
}
#endif
#endif /* ofp-connection.h */
/*
* Copyright (c) 2008-2017 Nicira, Inc.
*
* 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 OPENVSWITCH_OFP_FLOW_H
#define OPENVSWITCH_OFP_FLOW_H 1
#include "openflow/openflow.h"
#include "openflow/nicira-ext.h"
#include "openvswitch/list.h"
#include "openvswitch/match.h"
#include "openvswitch/ofp-protocol.h"
struct vl_mff_map;
struct ofputil_port_map;
struct ofputil_table_map;
#ifdef __cplusplus
extern "C" {
#endif
/* 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);
/* NXT_FLOW_MOD_TABLE_ID extension. */
struct ofpbuf *ofputil_make_flow_mod_table_id(bool flow_mod_table_id);
/* Protocol-independent flow_mod flags. */
enum ofputil_flow_mod_flags {
/* Flags that are maintained with a flow as part of its state.
*
* (OFPUTIL_FF_EMERG would be here too, if OVS supported it.) */
OFPUTIL_FF_SEND_FLOW_REM = 1 << 0, /* All versions. */
OFPUTIL_FF_NO_PKT_COUNTS = 1 << 1, /* OpenFlow 1.3+. */
OFPUTIL_FF_NO_BYT_COUNTS = 1 << 2, /* OpenFlow 1.3+. */
/* These flags primarily affects flow_mod behavior. They are not
* particularly useful as part of flow state. We include them in flow
* state only because OpenFlow implies that they should be. */
OFPUTIL_FF_CHECK_OVERLAP = 1 << 3, /* All versions. */
OFPUTIL_FF_RESET_COUNTS = 1 << 4, /* OpenFlow 1.2+. */
/* Not supported by OVS. */
OFPUTIL_FF_EMERG = 1 << 5, /* OpenFlow 1.0 only. */
/* The set of flags maintained as part of a flow table entry. */
#define OFPUTIL_FF_STATE (OFPUTIL_FF_SEND_FLOW_REM \
| OFPUTIL_FF_NO_PKT_COUNTS \
| OFPUTIL_FF_NO_BYT_COUNTS \
| OFPUTIL_FF_CHECK_OVERLAP \
| OFPUTIL_FF_RESET_COUNTS)
/* Flags that are only set by OVS for its internal use. Cannot be set via
* OpenFlow. */
OFPUTIL_FF_HIDDEN_FIELDS = 1 << 6, /* Allow hidden match fields to be
set or modified. */
OFPUTIL_FF_NO_READONLY = 1 << 7, /* Allow rules within read only tables
to be modified */
};
/* Protocol-independent flow_mod.
*
* The handling of cookies across multiple versions of OpenFlow is a bit
* confusing. See the topics/design doc for the details. */
struct ofputil_flow_mod {
struct ovs_list list_node; /* For queuing flow_mods. */
struct match match;
int priority;
/* Cookie matching. The flow_mod affects only flows that have cookies that
* bitwise match 'cookie' bits in positions where 'cookie_mask has 1-bits.
*
* 'cookie_mask' should be zero for OFPFC_ADD flow_mods. */
ovs_be64 cookie; /* Cookie bits to match. */
ovs_be64 cookie_mask; /* 1-bit in each 'cookie' bit to match. */
/* Cookie changes.
*
* OFPFC_ADD uses 'new_cookie' as the new flow's cookie. 'new_cookie'
* should not be UINT64_MAX.
*
* OFPFC_MODIFY and OFPFC_MODIFY_STRICT have two cases:
*
* - If one or more matching flows exist and 'modify_cookie' is true,
* then the flow_mod changes the existing flows' cookies to
* 'new_cookie'. 'new_cookie' should not be UINT64_MAX.
*
* - If no matching flow exists, 'new_cookie' is not UINT64_MAX, and
* 'cookie_mask' is 0, then the flow_mod adds a new flow with
* 'new_cookie' as its cookie.
*/
ovs_be64 new_cookie; /* New cookie to install or UINT64_MAX. */
bool modify_cookie; /* Set cookie of existing flow to 'new_cookie'? */
uint8_t table_id;
uint16_t command;
uint16_t idle_timeout;
uint16_t hard_timeout;
uint32_t buffer_id;
ofp_port_t out_port;
uint32_t out_group;
enum ofputil_flow_mod_flags flags;
uint16_t importance; /* Eviction precedence. */
struct ofpact *ofpacts; /* Series of "struct ofpact"s. */
size_t ofpacts_len; /* Length of ofpacts, in bytes. */
uint64_t ofpacts_tlv_bitmap; /* 1-bit for each present TLV in 'ofpacts'. */
};
enum ofperr ofputil_decode_flow_mod(struct ofputil_flow_mod *,
const struct ofp_header *,
enum ofputil_protocol,
const struct tun_table *,
const struct vl_mff_map *,
struct ofpbuf *ofpacts,
ofp_port_t max_port,
uint8_t max_table);
struct ofpbuf *ofputil_encode_flow_mod(const struct ofputil_flow_mod *,
enum ofputil_protocol);
char *parse_ofp_str(struct ofputil_flow_mod *, int command, const char *str_,
const struct ofputil_port_map *,
const struct ofputil_table_map *,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
char *parse_ofp_flow_mod_str(struct ofputil_flow_mod *, const char *string,
const struct ofputil_port_map *,
const struct ofputil_table_map *,
int command,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
char *parse_ofp_flow_mod_file(const char *file_name,
const struct ofputil_port_map *,
const struct ofputil_table_map *,
int command,
struct ofputil_flow_mod **fms, size_t *n_fms,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
char *parse_ofp_exact_flow(struct flow *flow, struct flow_wildcards *wc,
const struct tun_table *tun_table, const char *s,
const struct ofputil_port_map *port_map);
/* Flow stats or aggregate stats request, independent of protocol. */
struct ofputil_flow_stats_request {
bool aggregate; /* Aggregate results? */
struct match match;
ovs_be64 cookie;
ovs_be64 cookie_mask;
ofp_port_t out_port;
uint32_t out_group;
uint8_t table_id;
};
enum ofperr ofputil_decode_flow_stats_request(
struct ofputil_flow_stats_request *, const struct ofp_header *,
const struct tun_table *, const struct vl_mff_map *);
struct ofpbuf *ofputil_encode_flow_stats_request(
const struct ofputil_flow_stats_request *, enum ofputil_protocol);
char *parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *,
bool aggregate, const char *string,
const struct ofputil_port_map *,
const struct ofputil_table_map *,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
/* Flow stats reply, independent of protocol. */
struct ofputil_flow_stats {
struct match match;
ovs_be64 cookie;
uint8_t table_id;
uint16_t priority;
uint16_t idle_timeout;
uint16_t hard_timeout;
uint32_t duration_sec;
uint32_t duration_nsec;
int idle_age; /* Seconds since last packet, -1 if unknown. */
int hard_age; /* Seconds since last change, -1 if unknown. */
uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */
const struct ofpact *ofpacts;
size_t ofpacts_len;
enum ofputil_flow_mod_flags flags;
uint16_t importance; /* Eviction precedence. */
};
int ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *,
struct ofpbuf *msg,
bool flow_age_extension,
struct ofpbuf *ofpacts);
void ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *,
struct ovs_list *replies,
const struct tun_table *);
/* Aggregate stats reply, independent of protocol. */
struct ofputil_aggregate_stats {
uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */
uint32_t flow_count;
};
struct ofpbuf *ofputil_encode_aggregate_stats_reply(
const struct ofputil_aggregate_stats *stats,
const struct ofp_header *request);
enum ofperr ofputil_decode_aggregate_stats_reply(
struct ofputil_aggregate_stats *,
const struct ofp_header *reply);
#ifdef __cplusplus
}
#endif
#endif /* ofp-flow.h */
/*
* Copyright (c) 2008-2017 Nicira, Inc.
*
* 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 OPENVSWITCH_OFP_GROUP_H
#define OPENVSWITCH_OFP_GROUP_H 1
#include "openflow/openflow.h"
#include "openflow/netronome-ext.h"
#include "openvswitch/list.h"
#include "openvswitch/meta-flow.h"
#include "openvswitch/type-props.h"
struct ds;
#ifdef __cplusplus
extern "C" {
#endif
struct ofputil_table_map;
/* Group numbers. */
enum { MAX_GROUP_NAME_LEN = INT_STRLEN(uint32_t) };
bool ofputil_group_from_string(const char *, uint32_t *group_id);
void ofputil_format_group(uint32_t group_id, struct ds *);
void ofputil_group_to_string(uint32_t group_id,
char namebuf[MAX_GROUP_NAME_LEN + 1],
size_t bufsize);
struct bucket_counter {
uint64_t packet_count; /* Number of packets processed by bucket. */
uint64_t byte_count; /* Number of bytes processed by bucket. */
};
/* Bucket for use in groups. */
struct ofputil_bucket {
struct ovs_list list_node;
uint16_t weight; /* Relative weight, for "select" groups. */
ofp_port_t watch_port; /* Port whose state affects whether this bucket
* is live. Only required for fast failover
* groups. */
uint32_t watch_group; /* Group whose state affects whether this
* bucket is live. Only required for fast
* failover groups. */
uint32_t bucket_id; /* Bucket Id used to identify bucket*/
struct ofpact *ofpacts; /* Series of "struct ofpact"s. */
size_t ofpacts_len; /* Length of ofpacts, in bytes. */
struct bucket_counter stats;
};
void ofputil_bucket_list_destroy(struct ovs_list *buckets);
void ofputil_bucket_clone_list(struct ovs_list *dest,
const struct ovs_list *src,
const struct ofputil_bucket *);
struct ofputil_bucket *ofputil_bucket_find(const struct ovs_list *,
uint32_t bucket_id);
bool ofputil_bucket_check_duplicate_id(const struct ovs_list *);
struct ofputil_bucket *ofputil_bucket_list_front(const struct ovs_list *);
struct ofputil_bucket *ofputil_bucket_list_back(const struct ovs_list *);
static inline bool
ofputil_bucket_has_liveness(const struct ofputil_bucket *bucket)
{
return (bucket->watch_port != OFPP_ANY ||
bucket->watch_group != OFPG_ANY);
}
struct ofputil_group_props {
/* NTR selection method */
char selection_method[NTR_MAX_SELECTION_METHOD_LEN];
uint64_t selection_method_param;
struct field_array fields;
};
void ofputil_group_properties_destroy(struct ofputil_group_props *);
void ofputil_group_properties_copy(struct ofputil_group_props *to,
const struct ofputil_group_props *from);
/* Protocol-independent group_mod. */
struct ofputil_group_mod {
uint16_t command; /* One of OFPGC15_*. */
uint8_t type; /* One of OFPGT11_*. */
uint32_t group_id; /* Group identifier. */
uint32_t command_bucket_id; /* Bucket Id used as part of
* OFPGC15_INSERT_BUCKET and
* OFPGC15_REMOVE_BUCKET commands
* execution.*/
struct ovs_list buckets; /* Contains "struct ofputil_bucket"s. */
struct ofputil_group_props props; /* Group properties. */
};
void ofputil_uninit_group_mod(struct ofputil_group_mod *gm);
struct ofpbuf *ofputil_encode_group_mod(enum ofp_version ofp_version,
const struct ofputil_group_mod *gm);
enum ofperr ofputil_decode_group_mod(const struct ofp_header *,
struct ofputil_group_mod *);
char *parse_ofp_group_mod_file(const char *file_name,
const struct ofputil_port_map *,
const struct ofputil_table_map *, int command,
struct ofputil_group_mod **gms, size_t *n_gms,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
char *parse_ofp_group_mod_str(struct ofputil_group_mod *, int command,
const char *string,
const struct ofputil_port_map *,
const struct ofputil_table_map *,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
/* Group stats reply, independent of protocol. */
struct ofputil_group_stats {
uint32_t group_id; /* Group identifier. */
uint32_t ref_count;
uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */
uint32_t duration_sec; /* UINT32_MAX if unknown. */
uint32_t duration_nsec;
uint32_t n_buckets;
struct bucket_counter *bucket_stats;
};
struct ofpbuf *ofputil_encode_group_stats_request(enum ofp_version,
uint32_t group_id);
enum ofperr ofputil_decode_group_stats_request(
const struct ofp_header *request, uint32_t *group_id);
void ofputil_append_group_stats(struct ovs_list *replies,
const struct ofputil_group_stats *);