#include "nx-match.h"
#include "ofp-actions.h"
#include "ofp-errors.h"
+#include "ofp-msgs.h"
#include "ofp-print.h"
#include "ofp-util.h"
#include "ofpbuf.h"
ofproto->frag_handling = OFPC_FRAG_NORMAL;
hmap_init(&ofproto->ports);
shash_init(&ofproto->port_by_name);
+ ofproto->max_ports = OFPP_MAX;
ofproto->tables = NULL;
ofproto->n_tables = 0;
ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name);
return 0;
}
+/* Must be called (only) by an ofproto implementation in its constructor
+ * function. See the large comment on 'construct' in struct ofproto_class for
+ * details. */
void
ofproto_init_tables(struct ofproto *ofproto, int n_tables)
{
}
}
+/* To be optionally called (only) by an ofproto implementation in its
+ * constructor function. See the large comment on 'construct' in struct
+ * ofproto_class for details.
+ *
+ * Sets the maximum number of ports to 'max_ports'. The ofproto generic layer
+ * will then ensure that actions passed into the ofproto implementation will
+ * not refer to OpenFlow ports numbered 'max_ports' or higher. If this
+ * function is not called, there will be no such restriction.
+ *
+ * Reserved ports numbered OFPP_MAX and higher are special and not subject to
+ * the 'max_ports' restriction. */
+void
+ofproto_init_max_ports(struct ofproto *ofproto, uint16_t max_ports)
+{
+ assert(max_ports <= OFPP_MAX);
+ ofproto->max_ports = max_ports;
+}
+
uint64_t
ofproto_get_datapath_id(const struct ofproto *ofproto)
{
struct ofpbuf *buf;
/* Send reply. */
- osc = make_openflow_xid(sizeof *osc, OFPT_GET_CONFIG_REPLY, oh->xid, &buf);
+ buf = ofpraw_alloc_reply(OFPRAW_OFPT_GET_CONFIG_REPLY, oh, 0);
+ osc = ofpbuf_put_uninit(buf, sizeof *osc);
flags = ofproto->frag_handling;
if (ofconn_get_invalid_ttl_to_controller(ofconn)) {
flags |= OFPC_INVALID_TTL_TO_CONTROLLER;
}
static enum ofperr
-handle_set_config(struct ofconn *ofconn, const struct ofp_switch_config *osc)
+handle_set_config(struct ofconn *ofconn, const struct ofp_header *oh)
{
+ const struct ofp_switch_config *osc = ofpmsg_body(oh);
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
uint16_t flags = ntohs(osc->flags);
}
static enum ofperr
-handle_packet_out(struct ofconn *ofconn, const struct ofp_packet_out *opo)
+handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
{
struct ofproto *p = ofconn_get_ofproto(ofconn);
struct ofputil_packet_out po;
/* Decode message. */
ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
- error = ofputil_decode_packet_out(&po, opo, &ofpacts);
+ error = ofputil_decode_packet_out(&po, oh, &ofpacts);
if (error) {
goto exit_free_ofpacts;
}
+ if (po.in_port >= p->max_ports && po.in_port < OFPP_MAX) {
+ error = OFPERR_NXBRC_BAD_IN_PORT;
+ goto exit_free_ofpacts;
+ }
/* Get payload. */
if (po.buffer_id != UINT32_MAX) {
ofpbuf_use_const(payload, po.packet, po.packet_len);
}
- /* Send out packet. */
+ /* Verify actions against packet, then send packet if successful. */
flow_extract(payload, 0, 0, po.in_port, &flow);
- error = p->ofproto_class->packet_out(p, payload, &flow,
- po.ofpacts, po.ofpacts_len);
+ error = ofpacts_check(po.ofpacts, po.ofpacts_len, &flow, p->max_ports);
+ if (!error) {
+ error = p->ofproto_class->packet_out(p, payload, &flow,
+ po.ofpacts, po.ofpacts_len);
+ }
ofpbuf_delete(payload);
exit_free_ofpacts:
static enum ofperr
handle_desc_stats_request(struct ofconn *ofconn,
- const struct ofp_stats_msg *request)
+ const struct ofp_header *request)
{
struct ofproto *p = ofconn_get_ofproto(ofconn);
struct ofp_desc_stats *ods;
struct ofpbuf *msg;
- ods = ofputil_make_stats_reply(sizeof *ods, request, &msg);
+ msg = ofpraw_alloc_stats_reply(request, 0);
+ ods = ofpbuf_put_zeros(msg, sizeof *ods);
ovs_strlcpy(ods->mfr_desc, p->mfr_desc, sizeof ods->mfr_desc);
ovs_strlcpy(ods->hw_desc, p->hw_desc, sizeof ods->hw_desc);
ovs_strlcpy(ods->sw_desc, p->sw_desc, sizeof ods->sw_desc);
static enum ofperr
handle_table_stats_request(struct ofconn *ofconn,
- const struct ofp_stats_msg *request)
+ const struct ofp_header *request)
{
struct ofproto *p = ofconn_get_ofproto(ofconn);
- struct ofp_table_stats *ots;
+ struct ofp10_table_stats *ots;
struct ofpbuf *msg;
size_t i;
- ofputil_make_stats_reply(sizeof(struct ofp_stats_msg), request, &msg);
-
+ msg = ofpraw_alloc_stats_reply(request, sizeof *ots * p->n_tables);
ots = ofpbuf_put_zeros(msg, sizeof *ots * p->n_tables);
for (i = 0; i < p->n_tables; i++) {
ots[i].table_id = i;
append_port_stat(struct ofport *port, struct list *replies)
{
struct netdev_stats stats;
- struct ofp_port_stats *ops;
+ struct ofp10_port_stats *ops;
/* Intentionally ignore return value, since errors will set
* 'stats' to all-1s, which is correct for OpenFlow, and
* netdev_get_stats() will log errors. */
ofproto_port_get_stats(port, &stats);
- ops = ofputil_append_stats_reply(sizeof *ops, replies);
+ ops = ofpmp_append(replies, sizeof *ops);
ops->port_no = htons(port->pp.port_no);
memset(ops->pad, 0, sizeof ops->pad);
put_32aligned_be64(&ops->rx_packets, htonll(stats.rx_packets));
static enum ofperr
handle_port_stats_request(struct ofconn *ofconn,
- const struct ofp_port_stats_request *psr)
+ const struct ofp_header *request)
{
struct ofproto *p = ofconn_get_ofproto(ofconn);
+ const struct ofp10_port_stats_request *psr = ofpmsg_body(request);
struct ofport *port;
struct list replies;
- ofputil_start_stats_reply(&psr->osm, &replies);
+ ofpmp_init(&replies, request);
if (psr->port_no != htons(OFPP_NONE)) {
port = ofproto_get_port(p, ntohs(psr->port_no));
if (port) {
static enum ofperr
handle_port_desc_stats_request(struct ofconn *ofconn,
- const struct ofp_stats_msg *osm)
+ const struct ofp_header *request)
{
struct ofproto *p = ofconn_get_ofproto(ofconn);
+ enum ofp_version version;
struct ofport *port;
struct list replies;
- ofputil_start_stats_reply(osm, &replies);
+ ofpmp_init(&replies, request);
+ version = ofputil_protocol_to_ofp_version(ofconn_get_protocol(ofconn));
HMAP_FOR_EACH (port, hmap_node, &p->ports) {
- ofputil_append_port_desc_stats_reply(ofconn_get_protocol(ofconn),
- &port->pp, &replies);
+ ofputil_append_port_desc_stats_reply(version, &port->pp, &replies);
}
ofconn_send_replies(ofconn, &replies);
static enum ofperr
handle_flow_stats_request(struct ofconn *ofconn,
- const struct ofp_stats_msg *osm)
+ const struct ofp_header *request)
{
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
struct ofputil_flow_stats_request fsr;
struct rule *rule;
enum ofperr error;
- error = ofputil_decode_flow_stats_request(&fsr, &osm->header);
+ error = ofputil_decode_flow_stats_request(&fsr, request);
if (error) {
return error;
}
return error;
}
- ofputil_start_stats_reply(osm, &replies);
+ ofpmp_init(&replies, request);
LIST_FOR_EACH (rule, ofproto_node, &rules) {
long long int now = time_msec();
struct ofputil_flow_stats fs;
/* Checks the fault status of CFM for 'ofp_port' within 'ofproto'. Returns a
* bitmask of 'cfm_fault_reason's to indicate a CFM fault (generally
* indicating a connectivity problem). Returns zero if CFM is not faulted,
- * and -1 if CFM is not enabled on 'port'. */
+ * and -1 if CFM is not enabled on 'ofp_port'. */
int
ofproto_port_get_cfm_fault(const struct ofproto *ofproto, uint16_t ofp_port)
{
: -1);
}
+/* Checks the operational status reported by the remote CFM endpoint of
+ * 'ofp_port' Returns 1 if operationally up, 0 if operationally down, and -1
+ * if CFM is not enabled on 'ofp_port' or does not support operational status.
+ */
+int
+ofproto_port_get_cfm_opup(const struct ofproto *ofproto, uint16_t ofp_port)
+{
+ struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
+ return (ofport && ofproto->ofproto_class->get_cfm_opup
+ ? ofproto->ofproto_class->get_cfm_opup(ofport)
+ : -1);
+}
+
/* Gets the MPIDs of the remote maintenance points broadcasting to 'ofp_port'
* within 'ofproto'. Populates 'rmps' with an array of MPIDs owned by
* 'ofproto', and 'n_rmps' with the number of MPIDs in 'rmps'. Returns a
static enum ofperr
handle_aggregate_stats_request(struct ofconn *ofconn,
- const struct ofp_stats_msg *osm)
+ const struct ofp_header *oh)
{
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
struct ofputil_flow_stats_request request;
struct rule *rule;
enum ofperr error;
- error = ofputil_decode_flow_stats_request(&request, &osm->header);
+ error = ofputil_decode_flow_stats_request(&request, oh);
if (error) {
return error;
}
stats.byte_count = UINT64_MAX;
}
- reply = ofputil_encode_aggregate_stats_reply(&stats, osm);
+ reply = ofputil_encode_aggregate_stats_reply(&stats, oh);
ofconn_send_reply(ofconn, reply);
return 0;
put_queue_stats(struct queue_stats_cbdata *cbdata, uint32_t queue_id,
const struct netdev_queue_stats *stats)
{
- struct ofp_queue_stats *reply;
+ struct ofp10_queue_stats *reply;
- reply = ofputil_append_stats_reply(sizeof *reply, &cbdata->replies);
+ reply = ofpmp_append(&cbdata->replies, sizeof *reply);
reply->port_no = htons(cbdata->ofport->pp.port_no);
memset(reply->pad, 0, sizeof reply->pad);
reply->queue_id = htonl(queue_id);
static enum ofperr
handle_queue_stats_request(struct ofconn *ofconn,
- const struct ofp_queue_stats_request *qsr)
+ const struct ofp_header *rq)
{
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
+ const struct ofp10_queue_stats_request *qsr = ofpmsg_body(rq);
struct queue_stats_cbdata cbdata;
unsigned int port_no;
struct ofport *port;
COVERAGE_INC(ofproto_queue_req);
- ofputil_start_stats_reply(&qsr->osm, &cbdata.replies);
+ ofpmp_init(&cbdata.replies, rq);
port_no = ntohs(qsr->port_no);
queue_id = ntohl(qsr->queue_id);
calc_flow_duration__(rule->created, time_msec(),
&fr.duration_sec, &fr.duration_nsec);
fr.idle_timeout = rule->idle_timeout;
+ fr.hard_timeout = rule->hard_timeout;
rule->ofproto->ofproto_class->rule_get_stats(rule, &fr.packet_count,
&fr.byte_count);
goto exit_free_ofpacts;
}
+ if (fm.flags & OFPFF10_EMERG) {
/* We do not support the OpenFlow 1.0 emergency flow cache, which is not
* required in OpenFlow 1.0.1 and removed from OpenFlow 1.1. */
- if (fm.flags & OFPFF_EMERG) {
/* We do not support the emergency flow cache. It will hopefully get
* dropped from OpenFlow in the near future. There is no good error
* code, so just state that the flow table is full. */
error = OFPERR_OFPFMFC_ALL_TABLES_FULL;
- } else {
+ }
+ if (!error) {
+ error = ofpacts_check(fm.ofpacts, fm.ofpacts_len,
+ &fm.cr.flow, ofproto->max_ports);
+ }
+ if (!error) {
error = handle_flow_mod__(ofconn_get_ofproto(ofconn), ofconn, &fm, oh);
}
if (error) {
static enum ofperr
handle_role_request(struct ofconn *ofconn, const struct ofp_header *oh)
{
- struct nx_role_request *nrr = (struct nx_role_request *) oh;
+ const struct nx_role_request *nrr = ofpmsg_body(oh);
struct nx_role_request *reply;
struct ofpbuf *buf;
uint32_t role;
ofconn_set_role(ofconn, role);
- reply = make_nxmsg_xid(sizeof *reply, NXT_ROLE_REPLY, oh->xid, &buf);
+ buf = ofpraw_alloc_reply(OFPRAW_NXT_ROLE_REPLY, oh, 0);
+ reply = ofpbuf_put_zeros(buf, sizeof *reply);
reply->role = htonl(role);
ofconn_send_reply(ofconn, buf);
handle_nxt_flow_mod_table_id(struct ofconn *ofconn,
const struct ofp_header *oh)
{
- const struct nx_flow_mod_table_id *msg
- = (const struct nx_flow_mod_table_id *) oh;
+ const struct nx_flow_mod_table_id *msg = ofpmsg_body(oh);
enum ofputil_protocol cur, next;
cur = ofconn_get_protocol(ofconn);
static enum ofperr
handle_nxt_set_flow_format(struct ofconn *ofconn, const struct ofp_header *oh)
{
- const struct nx_set_flow_format *msg
- = (const struct nx_set_flow_format *) oh;
+ const struct nx_set_flow_format *msg = ofpmsg_body(oh);
enum ofputil_protocol cur, next;
enum ofputil_protocol next_base;
handle_nxt_set_packet_in_format(struct ofconn *ofconn,
const struct ofp_header *oh)
{
- const struct nx_set_packet_in_format *msg;
+ const struct nx_set_packet_in_format *msg = ofpmsg_body(oh);
uint32_t format;
- msg = (const struct nx_set_packet_in_format *) oh;
format = ntohl(msg->format);
if (format != NXPIF_OPENFLOW10 && format != NXPIF_NXM) {
return OFPERR_OFPBRC_EPERM;
static enum ofperr
handle_nxt_set_async_config(struct ofconn *ofconn, const struct ofp_header *oh)
{
- const struct nx_async_config *msg = (const struct nx_async_config *) oh;
+ const struct nx_async_config *msg = ofpmsg_body(oh);
uint32_t master[OAM_N_TYPES];
uint32_t slave[OAM_N_TYPES];
handle_nxt_set_controller_id(struct ofconn *ofconn,
const struct ofp_header *oh)
{
- const struct nx_controller_id *nci;
+ const struct nx_controller_id *nci = ofpmsg_body(oh);
- nci = (const struct nx_controller_id *) oh;
if (!is_all_zeros(nci->zero, sizeof nci->zero)) {
return OFPERR_NXBRC_MUST_BE_ZERO;
}
return OFPROTO_POSTPONE;
}
- make_openflow_xid(sizeof *oh, OFPT10_BARRIER_REPLY, oh->xid, &buf);
+ buf = ofpraw_alloc_reply((oh->version == OFP10_VERSION
+ ? OFPRAW_OFPT10_BARRIER_REPLY
+ : OFPRAW_OFPT11_BARRIER_REPLY), oh, 0);
ofconn_send_reply(ofconn, buf);
return 0;
}
fu.hard_timeout = rule->hard_timeout;
fu.table_id = rule->table_id;
fu.cookie = rule->flow_cookie;
- fu.match = (struct cls_rule *) &rule->cr;
+ fu.match = CONST_CAST(struct cls_rule *, &rule->cr);
if (!(flags & NXFMF_ACTIONS)) {
fu.ofpacts = NULL;
fu.ofpacts_len = 0;
}
static enum ofperr
-handle_flow_monitor_request(struct ofconn *ofconn,
- const struct ofp_stats_msg *osm)
+handle_flow_monitor_request(struct ofconn *ofconn, const struct ofp_header *oh)
{
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
struct ofmonitor **monitors;
size_t i;
error = 0;
- ofpbuf_use_const(&b, osm, ntohs(osm->header.length));
+ ofpbuf_use_const(&b, oh, ntohs(oh->length));
monitors = NULL;
n_monitors = allocated_monitors = 0;
for (;;) {
ofproto_collect_ofmonitor_initial_rules(monitors[i], &rules);
}
- ofputil_start_stats_reply(osm, &replies);
+ ofpmp_init(&replies, oh);
ofmonitor_compose_refresh_updates(&rules, &replies);
ofconn_send_replies(ofconn, &replies);
handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
{
const struct ofp_header *oh = msg->data;
- const struct ofputil_msg_type *type;
+ enum ofptype type;
enum ofperr error;
- error = ofputil_decode_msg_type(oh, &type);
+ error = ofptype_decode(&type, oh);
if (error) {
return error;
}
- switch (ofputil_msg_type_code(type)) {
+ switch (type) {
/* OpenFlow requests. */
- case OFPUTIL_OFPT_ECHO_REQUEST:
+ case OFPTYPE_ECHO_REQUEST:
return handle_echo_request(ofconn, oh);
- case OFPUTIL_OFPT_FEATURES_REQUEST:
+ case OFPTYPE_FEATURES_REQUEST:
return handle_features_request(ofconn, oh);
- case OFPUTIL_OFPT_GET_CONFIG_REQUEST:
+ case OFPTYPE_GET_CONFIG_REQUEST:
return handle_get_config_request(ofconn, oh);
- case OFPUTIL_OFPT_SET_CONFIG:
- return handle_set_config(ofconn, msg->data);
+ case OFPTYPE_SET_CONFIG:
+ return handle_set_config(ofconn, oh);
- case OFPUTIL_OFPT_PACKET_OUT:
- return handle_packet_out(ofconn, msg->data);
+ case OFPTYPE_PACKET_OUT:
+ return handle_packet_out(ofconn, oh);
- case OFPUTIL_OFPT_PORT_MOD:
+ case OFPTYPE_PORT_MOD:
return handle_port_mod(ofconn, oh);
- case OFPUTIL_OFPT_FLOW_MOD:
+ case OFPTYPE_FLOW_MOD:
return handle_flow_mod(ofconn, oh);
- case OFPUTIL_OFPT_BARRIER_REQUEST:
+ case OFPTYPE_BARRIER_REQUEST:
return handle_barrier_request(ofconn, oh);
/* OpenFlow replies. */
- case OFPUTIL_OFPT_ECHO_REPLY:
+ case OFPTYPE_ECHO_REPLY:
return 0;
/* Nicira extension requests. */
- case OFPUTIL_NXT_ROLE_REQUEST:
+ case OFPTYPE_ROLE_REQUEST:
return handle_role_request(ofconn, oh);
- case OFPUTIL_NXT_FLOW_MOD_TABLE_ID:
+ case OFPTYPE_FLOW_MOD_TABLE_ID:
return handle_nxt_flow_mod_table_id(ofconn, oh);
- case OFPUTIL_NXT_SET_FLOW_FORMAT:
+ case OFPTYPE_SET_FLOW_FORMAT:
return handle_nxt_set_flow_format(ofconn, oh);
- case OFPUTIL_NXT_SET_PACKET_IN_FORMAT:
+ case OFPTYPE_SET_PACKET_IN_FORMAT:
return handle_nxt_set_packet_in_format(ofconn, oh);
- case OFPUTIL_NXT_SET_CONTROLLER_ID:
+ case OFPTYPE_SET_CONTROLLER_ID:
return handle_nxt_set_controller_id(ofconn, oh);
- case OFPUTIL_NXT_FLOW_MOD:
- return handle_flow_mod(ofconn, oh);
-
- case OFPUTIL_NXT_FLOW_AGE:
+ case OFPTYPE_FLOW_AGE:
/* Nothing to do. */
return 0;
- case OFPUTIL_NXT_FLOW_MONITOR_CANCEL:
+ case OFPTYPE_FLOW_MONITOR_CANCEL:
return handle_flow_monitor_cancel(ofconn, oh);
- case OFPUTIL_NXT_SET_ASYNC_CONFIG:
+ case OFPTYPE_SET_ASYNC_CONFIG:
return handle_nxt_set_async_config(ofconn, oh);
/* Statistics requests. */
- case OFPUTIL_OFPST_DESC_REQUEST:
- return handle_desc_stats_request(ofconn, msg->data);
-
- case OFPUTIL_OFPST_FLOW_REQUEST:
- case OFPUTIL_NXST_FLOW_REQUEST:
- return handle_flow_stats_request(ofconn, msg->data);
-
- case OFPUTIL_OFPST_AGGREGATE_REQUEST:
- case OFPUTIL_NXST_AGGREGATE_REQUEST:
- return handle_aggregate_stats_request(ofconn, msg->data);
-
- case OFPUTIL_OFPST_TABLE_REQUEST:
- return handle_table_stats_request(ofconn, msg->data);
-
- case OFPUTIL_OFPST_PORT_REQUEST:
- return handle_port_stats_request(ofconn, msg->data);
-
- case OFPUTIL_OFPST_QUEUE_REQUEST:
- return handle_queue_stats_request(ofconn, msg->data);
-
- case OFPUTIL_OFPST_PORT_DESC_REQUEST:
- return handle_port_desc_stats_request(ofconn, msg->data);
-
- case OFPUTIL_NXST_FLOW_MONITOR_REQUEST:
- return handle_flow_monitor_request(ofconn, msg->data);
-
- case OFPUTIL_MSG_INVALID:
- case OFPUTIL_OFPT_HELLO:
- case OFPUTIL_OFPT_ERROR:
- case OFPUTIL_OFPT_FEATURES_REPLY:
- case OFPUTIL_OFPT_GET_CONFIG_REPLY:
- case OFPUTIL_OFPT_PACKET_IN:
- case OFPUTIL_OFPT_FLOW_REMOVED:
- case OFPUTIL_OFPT_PORT_STATUS:
- case OFPUTIL_OFPT_BARRIER_REPLY:
- case OFPUTIL_OFPT_QUEUE_GET_CONFIG_REQUEST:
- case OFPUTIL_OFPT_QUEUE_GET_CONFIG_REPLY:
- case OFPUTIL_OFPST_DESC_REPLY:
- case OFPUTIL_OFPST_FLOW_REPLY:
- case OFPUTIL_OFPST_QUEUE_REPLY:
- case OFPUTIL_OFPST_PORT_REPLY:
- case OFPUTIL_OFPST_TABLE_REPLY:
- case OFPUTIL_OFPST_AGGREGATE_REPLY:
- case OFPUTIL_OFPST_PORT_DESC_REPLY:
- case OFPUTIL_NXT_ROLE_REPLY:
- case OFPUTIL_NXT_FLOW_REMOVED:
- case OFPUTIL_NXT_PACKET_IN:
- case OFPUTIL_NXT_FLOW_MONITOR_PAUSED:
- case OFPUTIL_NXT_FLOW_MONITOR_RESUMED:
- case OFPUTIL_NXST_FLOW_REPLY:
- case OFPUTIL_NXST_AGGREGATE_REPLY:
- case OFPUTIL_NXST_FLOW_MONITOR_REPLY:
+ case OFPTYPE_DESC_STATS_REQUEST:
+ return handle_desc_stats_request(ofconn, oh);
+
+ case OFPTYPE_FLOW_STATS_REQUEST:
+ return handle_flow_stats_request(ofconn, oh);
+
+ case OFPTYPE_AGGREGATE_STATS_REQUEST:
+ return handle_aggregate_stats_request(ofconn, oh);
+
+ case OFPTYPE_TABLE_STATS_REQUEST:
+ return handle_table_stats_request(ofconn, oh);
+
+ case OFPTYPE_PORT_STATS_REQUEST:
+ return handle_port_stats_request(ofconn, oh);
+
+ case OFPTYPE_QUEUE_STATS_REQUEST:
+ return handle_queue_stats_request(ofconn, oh);
+
+ case OFPTYPE_PORT_DESC_STATS_REQUEST:
+ return handle_port_desc_stats_request(ofconn, oh);
+
+ case OFPTYPE_FLOW_MONITOR_STATS_REQUEST:
+ return handle_flow_monitor_request(ofconn, oh);
+
+ case OFPTYPE_HELLO:
+ case OFPTYPE_ERROR:
+ case OFPTYPE_FEATURES_REPLY:
+ case OFPTYPE_GET_CONFIG_REPLY:
+ case OFPTYPE_PACKET_IN:
+ case OFPTYPE_FLOW_REMOVED:
+ case OFPTYPE_PORT_STATUS:
+ case OFPTYPE_BARRIER_REPLY:
+ case OFPTYPE_DESC_STATS_REPLY:
+ case OFPTYPE_FLOW_STATS_REPLY:
+ case OFPTYPE_QUEUE_STATS_REPLY:
+ case OFPTYPE_PORT_STATS_REPLY:
+ case OFPTYPE_TABLE_STATS_REPLY:
+ case OFPTYPE_AGGREGATE_STATS_REPLY:
+ case OFPTYPE_PORT_DESC_STATS_REPLY:
+ case OFPTYPE_ROLE_REPLY:
+ case OFPTYPE_FLOW_MONITOR_PAUSED:
+ case OFPTYPE_FLOW_MONITOR_RESUMED:
+ case OFPTYPE_FLOW_MONITOR_STATS_REPLY:
default:
- return (oh->type == OFPT10_STATS_REQUEST ||
- oh->type == OFPT10_STATS_REPLY
- ? OFPERR_OFPBRC_BAD_STAT
- : OFPERR_OFPBRC_BAD_TYPE);
+ return OFPERR_OFPBRC_BAD_TYPE;
}
}