*/
#include <config.h>
-#include "ofp-print.h"
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
#include <stdlib.h>
+#include "bitmap.h"
#include "bundle.h"
#include "byte-order.h"
#include "classifier.h"
-#include "openvswitch/dynamic-string.h"
#include "learn.h"
-#include "meta-flow.h"
#include "multipath.h"
#include "netdev.h"
#include "nx-match.h"
#include "id-pool.h"
-#include "ofp-actions.h"
-#include "ofp-msgs.h"
-#include "ofp-prop.h"
-#include "ofp-util.h"
-#include "ofpbuf.h"
#include "openflow/netronome-ext.h"
+#include "openvswitch/dynamic-string.h"
+#include "openvswitch/meta-flow.h"
+#include "openvswitch/ofp-actions.h"
+#include "openvswitch/ofp-errors.h"
+#include "openvswitch/ofp-msgs.h"
+#include "openvswitch/ofp-print.h"
+#include "openvswitch/ofp-prop.h"
+#include "openvswitch/ofp-util.h"
+#include "openvswitch/ofpbuf.h"
+#include "openvswitch/type-props.h"
+#include "openvswitch/vlog.h"
+#include "openflow/intel-ext.h"
#include "packets.h"
#include "pktbuf.h"
#include "random.h"
#include "tun-metadata.h"
#include "unaligned.h"
-#include "type-props.h"
-#include "openvswitch/ofp-errors.h"
-#include "openvswitch/vlog.h"
-#include "bitmap.h"
+#include "uuid.h"
VLOG_DEFINE_THIS_MODULE(ofp_util);
case OFPUTIL_P_OF13_OXM:
case OFPUTIL_P_OF14_OXM:
case OFPUTIL_P_OF15_OXM:
+ case OFPUTIL_P_OF16_OXM:
return NXM_TYPICAL_LEN;
default:
case OFPUTIL_P_OF13_OXM:
case OFPUTIL_P_OF14_OXM:
case OFPUTIL_P_OF15_OXM:
+ case OFPUTIL_P_OF16_OXM:
return oxm_put_match(b, match,
ofputil_protocol_to_ofp_version(protocol));
}
#define N_PROTO_ABBREVS ARRAY_SIZE(proto_abbrevs)
enum ofputil_protocol ofputil_flow_dump_protocols[] = {
+ OFPUTIL_P_OF16_OXM,
OFPUTIL_P_OF15_OXM,
OFPUTIL_P_OF14_OXM,
OFPUTIL_P_OF13_OXM,
return OFPUTIL_P_OF14_OXM;
case OFP15_VERSION:
return OFPUTIL_P_OF15_OXM;
+ case OFP16_VERSION:
+ return OFPUTIL_P_OF16_OXM;
default:
return 0;
}
return OFP14_VERSION;
case OFPUTIL_P_OF15_OXM:
return OFP15_VERSION;
+ case OFPUTIL_P_OF16_OXM:
+ return OFP16_VERSION;
}
OVS_NOT_REACHED();
case OFPUTIL_P_OF15_OXM:
return OFPUTIL_P_OF15_OXM;
+ case OFPUTIL_P_OF16_OXM:
+ return OFPUTIL_P_OF16_OXM;
+
default:
OVS_NOT_REACHED();
}
case OFPUTIL_P_OF15_OXM:
return ofputil_protocol_set_tid(OFPUTIL_P_OF15_OXM, tid);
+ case OFPUTIL_P_OF16_OXM:
+ return ofputil_protocol_set_tid(OFPUTIL_P_OF16_OXM, tid);
+
default:
OVS_NOT_REACHED();
}
case OFPUTIL_P_OF15_OXM:
return "OXM-OpenFlow15";
+
+ case OFPUTIL_P_OF16_OXM:
+ return "OXM-OpenFlow16";
}
/* Check abbreviations. */
if (!strcasecmp(s, "OpenFlow15")) {
return OFP15_VERSION;
}
+ if (!strcasecmp(s, "OpenFlow16")) {
+ return OFP16_VERSION;
+ }
return 0;
}
return "OpenFlow14";
case OFP15_VERSION:
return "OpenFlow15";
+ case OFP16_VERSION:
+ return "OpenFlow16";
default:
OVS_NOT_REACHED();
}
case OFPUTIL_P_OF13_OXM:
case OFPUTIL_P_OF14_OXM:
case OFPUTIL_P_OF15_OXM:
+ case OFPUTIL_P_OF16_OXM:
/* There is only one variant of each OpenFlow 1.1+ protocol, and we
* verified above that we're not trying to change versions. */
OVS_NOT_REACHED();
ofputil_append_meter_config(struct ovs_list *replies,
const struct ofputil_meter_config *mc)
{
- struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
+ struct ofpbuf *msg = ofpbuf_from_list(ovs_list_back(replies));
size_t start_ofs = msg->size;
struct ofp13_meter_config *reply;
case OFPUTIL_P_OF12_OXM:
case OFPUTIL_P_OF13_OXM:
case OFPUTIL_P_OF14_OXM:
- case OFPUTIL_P_OF15_OXM: {
+ case OFPUTIL_P_OF15_OXM:
+ case OFPUTIL_P_OF16_OXM: {
struct ofp11_flow_mod *ofm;
int tailroom;
OVS_NOT_REACHED();
}
- list_init(replies);
- list_push_back(replies, &reply->list_node);
+ ovs_list_init(replies);
+ ovs_list_push_back(replies, &reply->list_node);
}
static void
struct ovs_list *replies)
{
enum ofp_version ofp_version = ofpmp_version(replies);
- struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
+ struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
size_t start_ofs = reply->size;
size_t len_ofs;
ovs_be16 *len;
case OFPUTIL_P_OF12_OXM:
case OFPUTIL_P_OF13_OXM:
case OFPUTIL_P_OF14_OXM:
- case OFPUTIL_P_OF15_OXM: {
+ case OFPUTIL_P_OF15_OXM:
+ case OFPUTIL_P_OF16_OXM: {
struct ofp11_flow_stats_request *ofsr;
raw = (fsr->aggregate
ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
struct ovs_list *replies)
{
- struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
+ struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
size_t start_ofs = reply->size;
enum ofp_version version = ofpmp_version(replies);
enum ofpraw raw = ofpmp_decode_raw(replies);
case OFPUTIL_P_OF12_OXM:
case OFPUTIL_P_OF13_OXM:
case OFPUTIL_P_OF14_OXM:
- case OFPUTIL_P_OF15_OXM: {
+ case OFPUTIL_P_OF15_OXM:
+ case OFPUTIL_P_OF16_OXM: {
struct ofp12_flow_removed *ofr;
msg = ofpraw_alloc_xid(OFPRAW_OFPT11_FLOW_REMOVED,
case OFPUTIL_P_OF13_OXM:
case OFPUTIL_P_OF14_OXM:
case OFPUTIL_P_OF15_OXM:
+ case OFPUTIL_P_OF16_OXM:
msg = ofputil_encode_ofp12_packet_in(&pin->public, version, buffer_id);
break;
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
ofputil_put_ofp14_port(pp, b);
break;
request = ofpraw_alloc(OFPRAW_OFPST10_PORT_DESC_REQUEST,
ofp_version, 0);
break;
- case OFP15_VERSION:{
+ case OFP15_VERSION:
+ case OFP16_VERSION:{
struct ofp15_port_desc_request *req;
request = ofpraw_alloc(OFPRAW_OFPST15_PORT_DESC_REQUEST,
ofp_version, 0);
ofputil_append_port_desc_stats_reply(const struct ofputil_phy_port *pp,
struct ovs_list *replies)
{
- struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
+ struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
size_t start_ofs = reply->size;
ofputil_put_phy_port(ofpmp_version(replies), pp, reply);
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
return OFPC_COMMON | OFPC12_PORT_BLOCKED;
default:
/* Caller needs to check osf->header.version itself */
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
raw = OFPRAW_OFPT13_FEATURES_REPLY;
break;
default:
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
osf->auxiliary_id = features->auxiliary_id;
/* fall through */
case OFP11_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
raw = OFPRAW_OFPT14_PORT_STATUS;
break;
break;
}
case OFP14_VERSION:
- case OFP15_VERSION: {
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp14_port_mod *opm;
b = ofpraw_alloc(OFPRAW_OFPT14_PORT_MOD, ofp_version, 0);
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
request = ofpraw_alloc(OFPRAW_OFPST13_TABLE_FEATURES_REQUEST,
ofp_version, 0);
break;
ofputil_append_table_features_reply(const struct ofputil_table_features *tf,
struct ovs_list *replies)
{
- struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
+ struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
enum ofp_version version = ofpmp_version(replies);
size_t start_ofs = reply->size;
struct ofp13_table_features *otf;
struct ovs_list *replies,
enum ofp_version version)
{
- struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
+ struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
size_t start_otd;
struct ofp14_table_desc *otd;
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
/* OpenFlow 1.4 introduced OFPTC14_EVICTION and
* OFPTC14_VACANCY_EVENTS. */
if (eviction == OFPUTIL_TABLE_EVICTION_ON) {
break;
}
case OFP14_VERSION:
- case OFP15_VERSION: {
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp14_table_mod *otm;
b = ofpraw_alloc(OFPRAW_OFPT14_TABLE_MOD, ofp_version, 0);
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
ofputil_put_ofp13_table_stats(stats, reply);
break;
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
return ofputil_decode_ofp13_table_stats(msg, stats, features);
default:
msg = ofpraw_alloc_xid(OFPRAW_NXST_FLOW_MONITOR_REPLY, OFP10_VERSION,
htonl(0), 1024);
- list_init(replies);
- list_push_back(replies, &msg->list_node);
+ ovs_list_init(replies);
+ ovs_list_push_back(replies, &msg->list_node);
}
void
struct ofpbuf *msg;
size_t start_ofs;
- msg = ofpbuf_from_list(list_back(replies));
+ msg = ofpbuf_from_list(ovs_list_back(replies));
start_ofs = msg->size;
if (update->event == NXFME_ABBREV) {
case OFP12_VERSION:
case OFP13_VERSION:
case OFP14_VERSION:
- case OFP15_VERSION: {
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp11_packet_out *opo;
size_t len;
enum ofpraw type;
switch (ofp_version) {
+ case OFP16_VERSION:
case OFP15_VERSION:
case OFP14_VERSION:
case OFP13_VERSION:
}
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
return b->size ? ofputil_pull_ofp14_port(pp, b) : EOF;
default:
OVS_NOT_REACHED();
case OFP12_VERSION:
case OFP13_VERSION:
case OFP14_VERSION:
- case OFP15_VERSION: {
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp11_port_stats_request *req;
request = ofpraw_alloc(OFPRAW_OFPST11_PORT_REQUEST, ofp_version, 0);
req = ofpbuf_put_zeros(request, sizeof *req);
struct ovs_list *replies)
{
struct ofp14_port_stats_prop_ethernet *eth;
+ struct intel_port_stats_rfc2819 *stats_rfc2819;
struct ofp14_port_stats *ps14;
struct ofpbuf *reply;
- reply = ofpmp_reserve(replies, sizeof *ps14 + sizeof *eth);
+ reply = ofpmp_reserve(replies, sizeof *ps14 + sizeof *eth +
+ sizeof *stats_rfc2819);
ps14 = ofpbuf_put_uninit(reply, sizeof *ps14);
- ps14->length = htons(sizeof *ps14 + sizeof *eth);
+ ps14->length = htons(sizeof *ps14 + sizeof *eth +
+ sizeof *stats_rfc2819);
memset(ps14->pad, 0, sizeof ps14->pad);
ps14->port_no = ofputil_port_to_ofp11(ops->port_no);
ps14->duration_sec = htonl(ops->duration_sec);
eth->rx_over_err = htonll(ops->stats.rx_over_errors);
eth->rx_crc_err = htonll(ops->stats.rx_crc_errors);
eth->collisions = htonll(ops->stats.collisions);
+
+ uint64_t prop_type = OFPPROP_EXP(INTEL_VENDOR_ID,
+ INTEL_PORT_STATS_RFC2819);
+
+ stats_rfc2819 = ofpprop_put_zeros(reply, prop_type,
+ sizeof *stats_rfc2819);
+
+ memset(stats_rfc2819->pad, 0, sizeof stats_rfc2819->pad);
+ stats_rfc2819->rx_1_to_64_packets = htonll(ops->stats.rx_1_to_64_packets);
+ stats_rfc2819->rx_65_to_127_packets =
+ htonll(ops->stats.rx_65_to_127_packets);
+ stats_rfc2819->rx_128_to_255_packets =
+ htonll(ops->stats.rx_128_to_255_packets);
+ stats_rfc2819->rx_256_to_511_packets =
+ htonll(ops->stats.rx_256_to_511_packets);
+ stats_rfc2819->rx_512_to_1023_packets =
+ htonll(ops->stats.rx_512_to_1023_packets);
+ stats_rfc2819->rx_1024_to_1522_packets =
+ htonll(ops->stats.rx_1024_to_1522_packets);
+ stats_rfc2819->rx_1523_to_max_packets =
+ htonll(ops->stats.rx_1523_to_max_packets);
+
+ stats_rfc2819->tx_1_to_64_packets = htonll(ops->stats.tx_1_to_64_packets);
+ stats_rfc2819->tx_65_to_127_packets =
+ htonll(ops->stats.tx_65_to_127_packets);
+ stats_rfc2819->tx_128_to_255_packets =
+ htonll(ops->stats.tx_128_to_255_packets);
+ stats_rfc2819->tx_256_to_511_packets =
+ htonll(ops->stats.tx_256_to_511_packets);
+ stats_rfc2819->tx_512_to_1023_packets =
+ htonll(ops->stats.tx_512_to_1023_packets);
+ stats_rfc2819->tx_1024_to_1522_packets =
+ htonll(ops->stats.tx_1024_to_1522_packets);
+ stats_rfc2819->tx_1523_to_max_packets =
+ htonll(ops->stats.tx_1523_to_max_packets);
+
+ stats_rfc2819->tx_multicast_packets =
+ htonll(ops->stats.tx_multicast_packets);
+ stats_rfc2819->rx_broadcast_packets =
+ htonll(ops->stats.rx_broadcast_packets);
+ stats_rfc2819->tx_broadcast_packets =
+ htonll(ops->stats.tx_broadcast_packets);
+ stats_rfc2819->rx_undersized_errors =
+ htonll(ops->stats.rx_undersized_errors);
+ stats_rfc2819->rx_oversize_errors =
+ htonll(ops->stats.rx_oversize_errors);
+ stats_rfc2819->rx_fragmented_errors =
+ htonll(ops->stats.rx_fragmented_errors);
+ stats_rfc2819->rx_jabber_errors =
+ htonll(ops->stats.rx_jabber_errors);
}
/* Encode a ports stat for 'ops' and append it to 'replies'. */
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
ofputil_append_ofp14_port_stats(ops, replies);
break;
ofputil_port_stats_from_ofp10(struct ofputil_port_stats *ops,
const struct ofp10_port_stats *ps10)
{
- memset(ops, 0, sizeof *ops);
ops->port_no = u16_to_ofp(ntohs(ps10->port_no));
ops->stats.rx_packets = ntohll(get_32aligned_be64(&ps10->rx_packets));
{
enum ofperr error;
- memset(ops, 0, sizeof *ops);
error = ofputil_port_from_ofp11(ps11->port_no, &ops->port_no);
if (error) {
return error;
return 0;
}
+static enum ofperr
+parse_intel_port_stats_rfc2819_property(const struct ofpbuf *payload,
+ struct ofputil_port_stats *ops)
+{
+ const struct intel_port_stats_rfc2819 *rfc2819 = payload->data;
+
+ if (payload->size != sizeof *rfc2819) {
+ return OFPERR_OFPBPC_BAD_LEN;
+ }
+ ops->stats.rx_1_to_64_packets = ntohll(rfc2819->rx_1_to_64_packets);
+ ops->stats.rx_65_to_127_packets = ntohll(rfc2819->rx_65_to_127_packets);
+ ops->stats.rx_128_to_255_packets = ntohll(rfc2819->rx_128_to_255_packets);
+ ops->stats.rx_256_to_511_packets = ntohll(rfc2819->rx_256_to_511_packets);
+ ops->stats.rx_512_to_1023_packets =
+ ntohll(rfc2819->rx_512_to_1023_packets);
+ ops->stats.rx_1024_to_1522_packets =
+ ntohll(rfc2819->rx_1024_to_1522_packets);
+ ops->stats.rx_1523_to_max_packets =
+ ntohll(rfc2819->rx_1523_to_max_packets);
+
+ ops->stats.tx_1_to_64_packets = ntohll(rfc2819->tx_1_to_64_packets);
+ ops->stats.tx_65_to_127_packets = ntohll(rfc2819->tx_65_to_127_packets);
+ ops->stats.tx_128_to_255_packets = ntohll(rfc2819->tx_128_to_255_packets);
+ ops->stats.tx_256_to_511_packets = ntohll(rfc2819->tx_256_to_511_packets);
+ ops->stats.tx_512_to_1023_packets =
+ ntohll(rfc2819->tx_512_to_1023_packets);
+ ops->stats.tx_1024_to_1522_packets =
+ ntohll(rfc2819->tx_1024_to_1522_packets);
+ ops->stats.tx_1523_to_max_packets =
+ ntohll(rfc2819->tx_1523_to_max_packets);
+
+ ops->stats.tx_multicast_packets = ntohll(rfc2819->tx_multicast_packets);
+ ops->stats.rx_broadcast_packets = ntohll(rfc2819->rx_broadcast_packets);
+ ops->stats.tx_broadcast_packets = ntohll(rfc2819->tx_broadcast_packets);
+ ops->stats.rx_undersized_errors = ntohll(rfc2819->rx_undersized_errors);
+
+ ops->stats.rx_oversize_errors = ntohll(rfc2819->rx_oversize_errors);
+ ops->stats.rx_fragmented_errors = ntohll(rfc2819->rx_fragmented_errors);
+ ops->stats.rx_jabber_errors = ntohll(rfc2819->rx_jabber_errors);
+
+ return 0;
+}
+
+static enum ofperr
+parse_intel_port_stats_property(const struct ofpbuf *payload,
+ uint32_t exp_type,
+ struct ofputil_port_stats *ops)
+{
+ enum ofperr error;
+
+ switch (exp_type) {
+ case INTEL_PORT_STATS_RFC2819:
+ error = parse_intel_port_stats_rfc2819_property(payload, ops);
+ break;
+ default:
+ error = OFPERR_OFPBPC_BAD_EXP_TYPE;
+ break;
+ }
+
+ return error;
+}
+
static enum ofperr
ofputil_pull_ofp14_port_stats(struct ofputil_port_stats *ops,
struct ofpbuf *msg)
ops->stats.tx_dropped = ntohll(ps14->tx_dropped);
ops->stats.rx_errors = ntohll(ps14->rx_errors);
ops->stats.tx_errors = ntohll(ps14->tx_errors);
- ops->stats.rx_frame_errors = UINT64_MAX;
- ops->stats.rx_over_errors = UINT64_MAX;
- ops->stats.rx_crc_errors = UINT64_MAX;
- ops->stats.collisions = UINT64_MAX;
+
struct ofpbuf properties = ofpbuf_const_initializer(ofpbuf_pull(msg, len),
len);
while (properties.size > 0) {
struct ofpbuf payload;
enum ofperr error;
- uint64_t type;
+ uint64_t type = 0;
error = ofpprop_pull(&properties, &payload, &type);
if (error) {
return error;
}
-
switch (type) {
case OFPPSPT14_ETHERNET:
error = parse_ofp14_port_stats_ethernet_property(&payload, ops);
break;
-
+ case OFPPROP_EXP(INTEL_VENDOR_ID, INTEL_PORT_STATS_RFC2819):
+ error = parse_intel_port_stats_property(&payload,
+ INTEL_PORT_STATS_RFC2819,
+ ops);
+ break;
default:
error = OFPPROP_UNKNOWN(true, "port stats", type);
break;
enum ofperr error;
enum ofpraw raw;
+ memset(&(ps->stats), 0xFF, sizeof (ps->stats));
+
error = (msg->header ? ofpraw_decode(&raw, msg->header)
: ofpraw_pull(&raw, msg));
if (error) {
return ofputil_pull_ofp14_port_stats(ps, msg);
} else if (raw == OFPRAW_OFPST13_PORT_REPLY) {
const struct ofp13_port_stats *ps13;
-
ps13 = ofpbuf_try_pull(msg, sizeof *ps13);
if (!ps13) {
goto bad_len;
ofp_port_t *ofp10_port)
{
switch ((enum ofp_version)request->version) {
+ case OFP16_VERSION:
case OFP15_VERSION:
case OFP14_VERSION:
case OFP13_VERSION:
}
}
+static void
+ofputil_ipfix_stats_to_reply(const struct ofputil_ipfix_stats *ois,
+ struct nx_ipfix_stats_reply *reply)
+{
+ reply->collector_set_id = htonl(ois->collector_set_id);
+ reply->total_flows = htonll(ois->total_flows);
+ reply->current_flows = htonll(ois->current_flows);
+ reply->pkts = htonll(ois->pkts);
+ reply->ipv4_pkts = htonll(ois->ipv4_pkts);
+ reply->ipv6_pkts = htonll(ois->ipv6_pkts);
+ reply->error_pkts = htonll(ois->error_pkts);
+ reply->ipv4_error_pkts = htonll(ois->ipv4_error_pkts);
+ reply->ipv6_error_pkts = htonll(ois->ipv6_error_pkts);
+ reply->tx_pkts = htonll(ois->tx_pkts);
+ reply->tx_errors = htonll(ois->tx_errors);
+}
+
+/* Encode a ipfix stat for 'ois' and append it to 'replies'. */
+void
+ofputil_append_ipfix_stat(struct ovs_list *replies,
+ const struct ofputil_ipfix_stats *ois)
+{
+ struct nx_ipfix_stats_reply *reply = ofpmp_append(replies, sizeof *reply);
+ ofputil_ipfix_stats_to_reply(ois, reply);
+}
+
+static enum ofperr
+ofputil_ipfix_stats_from_nx(struct ofputil_ipfix_stats *is,
+ const struct nx_ipfix_stats_reply *reply)
+{
+ is->collector_set_id = ntohl(reply->collector_set_id);
+ is->total_flows = ntohll(reply->total_flows);
+ is->current_flows = ntohll(reply->current_flows);
+ is->pkts = ntohll(reply->pkts);
+ is->ipv4_pkts = ntohll(reply->ipv4_pkts);
+ is->ipv6_pkts = ntohll(reply->ipv6_pkts);
+ is->error_pkts = ntohll(reply->error_pkts);
+ is->ipv4_error_pkts = ntohll(reply->ipv4_error_pkts);
+ is->ipv6_error_pkts = ntohll(reply->ipv6_error_pkts);
+ is->tx_pkts = ntohll(reply->tx_pkts);
+ is->tx_errors = ntohll(reply->tx_errors);
+
+ return 0;
+}
+
+int
+ofputil_pull_ipfix_stats(struct ofputil_ipfix_stats *is, struct ofpbuf *msg)
+{
+ enum ofperr error;
+ enum ofpraw raw;
+
+ memset(is, 0xFF, sizeof (*is));
+
+ error = (msg->header ? ofpraw_decode(&raw, msg->header)
+ : ofpraw_pull(&raw, msg));
+ if (error) {
+ return error;
+ }
+
+ if (!msg->size) {
+ return EOF;
+ } else if (raw == OFPRAW_NXST_IPFIX_BRIDGE_REPLY ||
+ raw == OFPRAW_NXST_IPFIX_FLOW_REPLY) {
+ struct nx_ipfix_stats_reply *reply;
+
+ reply = ofpbuf_try_pull(msg, sizeof *reply);
+ return ofputil_ipfix_stats_from_nx(is, reply);
+ } else {
+ OVS_NOT_REACHED();
+ }
+}
+
+
+/* Returns the number of ipfix stats elements in
+ * OFPTYPE_IPFIX_BRIDGE_STATS_REPLY or OFPTYPE_IPFIX_FLOW_STATS_REPLY
+ * message 'oh'. */
+size_t
+ofputil_count_ipfix_stats(const struct ofp_header *oh)
+{
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
+ ofpraw_pull_assert(&b);
+
+ return b.size / sizeof(struct ofputil_ipfix_stats);
+}
+
/* Frees all of the "struct ofputil_bucket"s in the 'buckets' list. */
void
ofputil_bucket_list_destroy(struct ovs_list *buckets)
}
new_bucket = ofputil_bucket_clone_data(bucket);
- list_push_back(dest, &new_bucket->list_node);
+ ovs_list_push_back(dest, &new_bucket->list_node);
}
}
{
static struct ofputil_bucket *bucket;
- ASSIGN_CONTAINER(bucket, list_front(buckets), list_node);
+ ASSIGN_CONTAINER(bucket, ovs_list_front(buckets), list_node);
return bucket;
}
{
static struct ofputil_bucket *bucket;
- ASSIGN_CONTAINER(bucket, list_back(buckets), list_node);
+ ASSIGN_CONTAINER(bucket, ovs_list_back(buckets), list_node);
return bucket;
}
case OFP12_VERSION:
case OFP13_VERSION:
case OFP14_VERSION:
- case OFP15_VERSION: {
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp11_group_stats_request *req;
request = ofpraw_alloc(OFPRAW_OFPST11_GROUP_REQUEST, ofp_version, 0);
req = ofpbuf_put_zeros(request, sizeof *req);
request = ofpraw_alloc(OFPRAW_OFPST11_GROUP_DESC_REQUEST,
ofp_version, 0);
break;
- case OFP15_VERSION:{
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp15_group_desc_request *req;
request = ofpraw_alloc(OFPRAW_OFPST15_GROUP_DESC_REQUEST,
ofp_version, 0);
case OFP13_VERSION:
case OFP14_VERSION:
- case OFP15_VERSION: {
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp13_group_stats *gs13;
length = sizeof *gs13 + bucket_counter_size;
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
request = ofpraw_alloc(OFPRAW_OFPST12_GROUP_FEATURES_REQUEST,
ofp_version, 0);
break;
struct ovs_list *replies,
enum ofp_version version)
{
- struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
+ struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
struct ofp11_group_desc_stats *ogds;
struct ofputil_bucket *bucket;
size_t start_ogds;
struct ovs_list *replies,
enum ofp_version version)
{
- struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
+ struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
struct ofp15_group_desc_stats *ogds;
struct ofputil_bucket *bucket;
size_t start_ogds, start_buckets;
break;
case OFP15_VERSION:
+ case OFP16_VERSION:
ofputil_append_ofp15_group_desc_reply(gds, buckets, replies, version);
break;
struct ofp11_bucket *ob;
uint32_t bucket_id = 0;
- list_init(buckets);
+ ovs_list_init(buckets);
while (buckets_length > 0) {
struct ofputil_bucket *bucket;
struct ofpbuf ofpacts;
bucket->ofpacts = ofpbuf_steal_data(&ofpacts);
bucket->ofpacts_len = ofpacts.size;
- list_push_back(buckets, &bucket->list_node);
+ ovs_list_push_back(buckets, &bucket->list_node);
}
return 0;
{
struct ofp15_bucket *ob;
- list_init(buckets);
+ ovs_list_init(buckets);
while (buckets_length > 0) {
struct ofputil_bucket *bucket = NULL;
struct ofpbuf ofpacts;
bucket->ofpacts = ofpbuf_steal_data(&ofpacts);
bucket->ofpacts_len = ofpacts.size;
- list_push_back(buckets, &bucket->list_node);
+ ovs_list_push_back(buckets, &bucket->list_node);
continue;
return ofputil_decode_ofp11_group_desc_reply(gd, msg, version);
case OFP15_VERSION:
+ case OFP16_VERSION:
return ofputil_decode_ofp15_group_desc_reply(gd, msg, version);
case OFP10_VERSION:
return ofputil_encode_ofp11_group_mod(ofp_version, gm);
case OFP15_VERSION:
+ case OFP16_VERSION:
return ofputil_encode_ofp15_group_mod(ofp_version, gm);
default:
if (!error
&& ofp_version >= OFP13_VERSION
&& gm->command == OFPGC11_DELETE
- && !list_is_empty(&gm->buckets)) {
+ && !ovs_list_is_empty(&gm->buckets)) {
error = OFPERR_OFPGMFC_INVALID_GROUP;
}
break;
case OFP15_VERSION:
+ case OFP16_VERSION:
err = ofputil_pull_ofp15_group_mod(&msg, ofp_version, gm);
break;
switch (gm->type) {
case OFPGT11_INDIRECT:
- if (!list_is_singleton(&gm->buckets)) {
+ if (gm->command != OFPGC11_DELETE
+ && !ovs_list_is_singleton(&gm->buckets) ) {
return OFPERR_OFPGMFC_INVALID_GROUP;
}
break;
case OFPGC15_INSERT_BUCKET:
break;
case OFPGC15_REMOVE_BUCKET:
- if (!list_is_empty(&gm->buckets)) {
+ if (!ovs_list_is_empty(&gm->buckets)) {
return OFPERR_OFPGMFC_BAD_BUCKET;
}
break;
struct ofputil_queue_stats_request *oqsr)
{
switch ((enum ofp_version)request->version) {
+ case OFP16_VERSION:
case OFP15_VERSION:
case OFP14_VERSION:
case OFP13_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
case OFP14_VERSION:
- case OFP15_VERSION: {
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp11_queue_stats_request *req;
request = ofpraw_alloc(OFPRAW_OFPST11_QUEUE_REQUEST, ofp_version, 0);
req = ofpbuf_put_zeros(request, sizeof *req);
}
case OFP14_VERSION:
- case OFP15_VERSION: {
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
struct ofp14_queue_stats *reply = ofpmp_append(replies, sizeof *reply);
ofputil_queue_stats_to_ofp14(oqs, reply);
break;
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
+ case OFP16_VERSION:
request = ofpraw_alloc(ofp_version == OFP13_VERSION
? OFPRAW_ONFT13_BUNDLE_CONTROL
: OFPRAW_OFPT14_BUNDLE_CONTROL, ofp_version, 0);
case OFPTYPE_NXT_TLV_TABLE_REQUEST:
case OFPTYPE_NXT_TLV_TABLE_REPLY:
case OFPTYPE_NXT_RESUME:
+ case OFPTYPE_IPFIX_BRIDGE_STATS_REQUEST:
+ case OFPTYPE_IPFIX_BRIDGE_STATS_REPLY:
+ case OFPTYPE_IPFIX_FLOW_STATS_REQUEST:
+ case OFPTYPE_IPFIX_FLOW_STATS_REPLY:
break;
}
msg->msg = b.data;
if (msg->msg->version != oh->version) {
- return OFPERR_NXBFC_BAD_VERSION;
+ return OFPERR_OFPBFC_BAD_VERSION;
}
size_t inner_len = ntohs(msg->msg->length);
if (inner_len < sizeof(struct ofp_header) || inner_len > b.size) {
decode_tlv_table_mappings(struct ofpbuf *msg, unsigned int max_fields,
struct ovs_list *mappings)
{
- list_init(mappings);
+ ovs_list_init(mappings);
while (msg->size) {
struct nx_tlv_map *nx_map;
nx_map = ofpbuf_pull(msg, sizeof *nx_map);
map = xmalloc(sizeof *map);
- list_push_back(mappings, &map->list_node);
+ ovs_list_push_back(mappings, &map->list_node);
map->option_class = ntohs(nx_map->option_class);
map->option_type = nx_map->option_type;