034c75b75d
OFPFMFC_BAD_EMERG_TIMEOUT
260 lines
7.2 KiB
C
260 lines
7.2 KiB
C
/*-
|
|
* Copyright (c) 2008, 2009
|
|
* The Board of Trustees of The Leland Stanford Junior University
|
|
*
|
|
* We are making the OpenFlow specification and associated documentation
|
|
* (Software) available for public use and benefit with the expectation that
|
|
* others will use, modify and enhance the Software and contribute those
|
|
* enhancements back to the community. However, since we would like to make the
|
|
* Software available for broadest use, with as few restrictions as possible
|
|
* permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this Software to deal in the Software under the copyrights without
|
|
* restriction, including without limitation the rights to use, copy, modify,
|
|
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
|
* and to permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*
|
|
* The name and trademarks of copyright holder(s) may NOT be used in
|
|
* advertising or publicity pertaining to the Software or any derivatives
|
|
* without specific, written prior permission.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include "openflow/openflow.h"
|
|
#include "ofpstat.h"
|
|
|
|
#define INC_IFP_STAT(ifps, tag) do {++(ifps)->tag;} while (0)
|
|
|
|
static void inc_protocol_message(struct ofpstat *, struct ofp_header *);
|
|
static void inc_error_notification(struct ofpstat *, struct ofp_header *);
|
|
static void inc_flow_manipulation(struct ofpstat *, struct ofp_header *);
|
|
|
|
static void
|
|
inc_protocol_message(struct ofpstat *ifps, struct ofp_header *hdr)
|
|
{
|
|
switch (hdr->type) {
|
|
case OFPT_HELLO:
|
|
INC_IFP_STAT(ifps, ofps_hello);
|
|
break;
|
|
case OFPT_ERROR:
|
|
INC_IFP_STAT(ifps, ofps_error);
|
|
break;
|
|
case OFPT_ECHO_REQUEST:
|
|
INC_IFP_STAT(ifps, ofps_echo_request);
|
|
break;
|
|
case OFPT_ECHO_REPLY:
|
|
INC_IFP_STAT(ifps, ofps_echo_reply);
|
|
break;
|
|
case OFPT_VENDOR:
|
|
INC_IFP_STAT(ifps, ofps_vendor);
|
|
break;
|
|
case OFPT_FEATURES_REQUEST:
|
|
INC_IFP_STAT(ifps, ofps_feats_request);
|
|
break;
|
|
case OFPT_FEATURES_REPLY:
|
|
INC_IFP_STAT(ifps, ofps_feats_reply);
|
|
break;
|
|
case OFPT_GET_CONFIG_REQUEST:
|
|
INC_IFP_STAT(ifps, ofps_get_config_request);
|
|
break;
|
|
case OFPT_GET_CONFIG_REPLY:
|
|
INC_IFP_STAT(ifps, ofps_get_config_reply);
|
|
break;
|
|
case OFPT_SET_CONFIG:
|
|
INC_IFP_STAT(ifps, ofps_set_config);
|
|
break;
|
|
case OFPT_PACKET_IN:
|
|
INC_IFP_STAT(ifps, ofps_packet_in);
|
|
break;
|
|
case OFPT_FLOW_REMOVED:
|
|
INC_IFP_STAT(ifps, ofps_flow_removed);
|
|
break;
|
|
case OFPT_PORT_STATUS:
|
|
INC_IFP_STAT(ifps, ofps_port_status);
|
|
break;
|
|
case OFPT_PACKET_OUT:
|
|
INC_IFP_STAT(ifps, ofps_packet_out);
|
|
break;
|
|
case OFPT_FLOW_MOD:
|
|
INC_IFP_STAT(ifps, ofps_flow_mod);
|
|
break;
|
|
case OFPT_PORT_MOD:
|
|
INC_IFP_STAT(ifps, ofps_port_mod);
|
|
break;
|
|
case OFPT_STATS_REQUEST:
|
|
INC_IFP_STAT(ifps, ofps_stats_request);
|
|
break;
|
|
case OFPT_STATS_REPLY:
|
|
INC_IFP_STAT(ifps, ofps_stats_reply);
|
|
break;
|
|
case OFPT_BARRIER_REQUEST:
|
|
INC_IFP_STAT(ifps, ofps_barrier_request);
|
|
break;
|
|
case OFPT_BARRIER_REPLY:
|
|
INC_IFP_STAT(ifps, ofps_barrier_reply);
|
|
break;
|
|
default:
|
|
INC_IFP_STAT(ifps, ofps_unknown);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
inc_error_notification(struct ofpstat *ifps, struct ofp_header *hdr)
|
|
{
|
|
struct ofp_error_msg *errmsg = (struct ofp_error_msg *)hdr;
|
|
uint16_t errtype = ntohs(errmsg->type);
|
|
uint16_t errcode = ntohs(errmsg->code);
|
|
|
|
switch (errtype) {
|
|
case OFPET_HELLO_FAILED:
|
|
INC_IFP_STAT(ifps, ofps_error_type.hello_fail);
|
|
switch (errcode) {
|
|
case OFPHFC_INCOMPATIBLE:
|
|
INC_IFP_STAT(ifps, ofps_error_code.hf_incompat);
|
|
break;
|
|
case OFPHFC_EPERM:
|
|
INC_IFP_STAT(ifps, ofps_error_code.hf_eperm);
|
|
break;
|
|
default:
|
|
INC_IFP_STAT(ifps, ofps_error_code.unknown);
|
|
break;
|
|
}
|
|
break;
|
|
case OFPET_BAD_REQUEST:
|
|
INC_IFP_STAT(ifps, ofps_error_type.bad_request);
|
|
switch (errcode) {
|
|
case OFPBRC_BAD_VERSION:
|
|
INC_IFP_STAT(ifps, ofps_error_code.br_bad_version);
|
|
break;
|
|
case OFPBRC_BAD_TYPE:
|
|
INC_IFP_STAT(ifps, ofps_error_code.br_bad_type);
|
|
break;
|
|
case OFPBRC_BAD_STAT:
|
|
INC_IFP_STAT(ifps, ofps_error_code.br_bad_stat);
|
|
break;
|
|
case OFPBRC_BAD_VENDOR:
|
|
INC_IFP_STAT(ifps, ofps_error_code.br_bad_vendor);
|
|
break;
|
|
case OFPBRC_EPERM:
|
|
INC_IFP_STAT(ifps, ofps_error_code.br_eperm);
|
|
break;
|
|
default:
|
|
INC_IFP_STAT(ifps, ofps_error_code.unknown);
|
|
break;
|
|
}
|
|
break;
|
|
case OFPET_BAD_ACTION:
|
|
INC_IFP_STAT(ifps, ofps_error_type.bad_action);
|
|
switch (errcode) {
|
|
case OFPBAC_BAD_TYPE:
|
|
INC_IFP_STAT(ifps, ofps_error_code.ba_bad_type);
|
|
break;
|
|
case OFPBAC_BAD_LEN:
|
|
INC_IFP_STAT(ifps, ofps_error_code.ba_bad_len);
|
|
break;
|
|
case OFPBAC_BAD_VENDOR:
|
|
INC_IFP_STAT(ifps, ofps_error_code.ba_bad_vendor);
|
|
break;
|
|
case OFPBAC_BAD_VENDOR_TYPE:
|
|
INC_IFP_STAT(ifps, ofps_error_code.ba_bad_vendor_type);
|
|
break;
|
|
case OFPBAC_BAD_OUT_PORT:
|
|
INC_IFP_STAT(ifps, ofps_error_code.ba_bad_out_port);
|
|
break;
|
|
case OFPBAC_BAD_ARGUMENT:
|
|
INC_IFP_STAT(ifps, ofps_error_code.ba_bad_argument);
|
|
break;
|
|
case OFPBAC_EPERM:
|
|
INC_IFP_STAT(ifps, ofps_error_code.ba_eperm);
|
|
break;
|
|
default:
|
|
INC_IFP_STAT(ifps, ofps_error_code.unknown);
|
|
break;
|
|
}
|
|
break;
|
|
case OFPET_FLOW_MOD_FAILED:
|
|
INC_IFP_STAT(ifps, ofps_error_type.flow_mod_fail);
|
|
switch (errcode) {
|
|
case OFPFMFC_ALL_TABLES_FULL:
|
|
INC_IFP_STAT(ifps, ofps_error_code.fmf_all_tables_full);
|
|
break;
|
|
case OFPFMFC_OVERLAP:
|
|
INC_IFP_STAT(ifps, ofps_error_code.fmf_overlap);
|
|
break;
|
|
case OFPFMFC_EPERM:
|
|
INC_IFP_STAT(ifps, ofps_error_code.fmf_eperm);
|
|
break;
|
|
case OFPFMFC_BAD_EMERG_TIMEOUT:
|
|
INC_IFP_STAT(ifps, ofps_error_code.fmf_emerg);
|
|
break;
|
|
default:
|
|
INC_IFP_STAT(ifps, ofps_error_code.unknown);
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
INC_IFP_STAT(ifps, ofps_error_type.unknown);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
inc_flow_manipulation(struct ofpstat *ifps, struct ofp_header *hdr)
|
|
{
|
|
struct ofp_flow_mod *flowmodmsg = (struct ofp_flow_mod *)hdr;
|
|
uint16_t flowmodops = ntohs(flowmodmsg->command);
|
|
|
|
switch (flowmodops) {
|
|
case OFPFC_ADD:
|
|
INC_IFP_STAT(ifps, ofps_flow_mod_ops.add);
|
|
break;
|
|
case OFPFC_MODIFY:
|
|
INC_IFP_STAT(ifps, ofps_flow_mod_ops.modify);
|
|
break;
|
|
case OFPFC_MODIFY_STRICT:
|
|
INC_IFP_STAT(ifps, ofps_flow_mod_ops.modify_strict);
|
|
break;
|
|
case OFPFC_DELETE:
|
|
INC_IFP_STAT(ifps, ofps_flow_mod_ops.delete);
|
|
break;
|
|
case OFPFC_DELETE_STRICT:
|
|
INC_IFP_STAT(ifps, ofps_flow_mod_ops.delete_strict);
|
|
break;
|
|
default:
|
|
INC_IFP_STAT(ifps, ofps_flow_mod_ops.unknown);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
ofpstat_inc_protocol_stat(struct ofpstat *ifps, struct ofp_header *hdr)
|
|
{
|
|
++ifps->ofps_total;
|
|
inc_protocol_message(ifps, hdr);
|
|
|
|
switch (hdr->type) {
|
|
case OFPT_ERROR:
|
|
inc_error_notification(ifps, hdr);
|
|
break;
|
|
case OFPT_FLOW_MOD:
|
|
inc_flow_manipulation(ifps, hdr);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|