[ovs-dev] New custom Message - unknown OpenFlow message
Adam Paul Rzyska
adam.rzyska at smail.inf.h-brs.de
Mon Mar 27 19:08:32 UTC 2017
Hello,
in the last weeks I tried to exchange custom openflow messages (type
experimenter) between a controller (ONOS) and a switch (Open vSwitch).
The controller sends a really simple of-msg:
struct my_custom_struct : of_nicira_header {
uint8_t version;
uint8_t type == 4;
uint16_t length;
uint32_t xid;
uint32_t experimenter == 0x00002320;
uint32_t subtype == 0x0080;
};
In wireshark and OVS it is possible to see, that the switch receives
my custom messages. I've added ofpraw and oftype in ofp-msgs.h. My
request_method have been added to ofproto.c and also into the switch
case. It works fine with a simple VLOG_INFO() output. Every time the
switch receive my custom message a VLOG_INFO-message pops up into the
logging file of OVS. But as soon as I'm trying to implement a
reply/replies a error occurs, which crash's the vswichd (demon). This
results in disconnecting the switch from the controller.
Error message: 2017-02-05T12:09:02Z|00225|ofp_msgs|WARN|unknown
OpenFlow message (version 4, type 19, stat 0, vendor 0x2320, subtype 80)
I know exactly where it happens, but I don't know why... It starts
with ofpmp_init() in my method.
My method:
static enum ofperr
my_custom_method(struct ofconn *ofconn, const struct ofp_header *request)
{
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
struct ovs_list replies;
VLOG_INFO("Stat Request type: %i", request->type);
ofpmp_init(&replies, request);
VLOG_INFO("After OFPMP INIT");
return 0;
}
From there on to the file ofp-msgs.c:
void
ofpmp_init(struct ovs_list *replies, const struct ofp_header *request)
{
struct ofpbuf *msg;
list_init(replies);
msg = ofpraw_alloc_stats_reply(request, 1000);
list_push_back(replies, &msg->list_node);
}
Next one would be ofpraw_alloc_stats_reply:
struct ofpbuf *
ofpraw_alloc_stats_reply(const struct ofp_header *request,
size_t extra_tailroom)
{
enum ofpraw request_raw;
enum ofpraw reply_raw;
enum ofperr error;
error = ofpraw_decode_partial(&request_raw, request,
ntohs(request->length));
ovs_assert(!error);
reply_raw = ofpraw_stats_request_to_reply(request_raw, request->version);
ovs_assert(reply_raw);
return ofpraw_alloc_reply(reply_raw, request, extra_tailroom);
}
Just two more ofpraw_stats_request_to_reply:
enum ofpraw
ofpraw_stats_request_to_reply(enum ofpraw raw, uint8_t version)
{
const struct raw_info *info = raw_info_get(raw);
const struct raw_instance *instance = raw_instance_get(info, version);
enum ofpraw reply_raw;
struct ofphdrs hdrs;
enum ofperr error;
hdrs = instance->hdrs;
switch ((enum ofp_version)hdrs.version) {
case OFP10_VERSION:
ovs_assert(hdrs.type == OFPT10_STATS_REQUEST);
hdrs.type = OFPT10_STATS_REPLY;
break;
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
case OFP14_VERSION:
case OFP15_VERSION:
ovs_assert(hdrs.type == OFPT11_STATS_REQUEST);
hdrs.type = OFPT11_STATS_REPLY;
break;
default:
OVS_NOT_REACHED();
}
error = ofpraw_from_ofphdrs(&reply_raw, &hdrs);
ovs_assert(!error);
return reply_raw;
}
The last one would be ofpraw_from_ofphdrs:
static enum ofperr
ofpraw_from_ofphdrs(enum ofpraw *raw, const struct ofphdrs *hdrs)
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
struct raw_instance *raw_hdrs;
uint32_t hash;
ofpmsgs_init();
hash = ofphdrs_hash(hdrs);
HMAP_FOR_EACH_WITH_HASH (raw_hdrs, hmap_node, hash, &raw_instance_map) {
if (ofphdrs_equal(hdrs, &raw_hdrs->hdrs)) {
*raw = raw_hdrs->raw;
return 0;
}
}
if (!VLOG_DROP_WARN(&rl)) {
struct ds s;
ds_init(&s);
ds_put_format(&s, "version %"PRIu8", type %"PRIu8,
hdrs->version, hdrs->type);
if (ofphdrs_is_stat(hdrs)) {
ds_put_format(&s, ", stat %"PRIu16, hdrs->stat);
}
if (hdrs->vendor) {
ds_put_format(&s, ", vendor 0x%"PRIx32", subtype %"PRIu32,
hdrs->vendor, hdrs->subtype);
}
VLOG_WARN("unknown OpenFlow message (%s)", ds_cstr(&s));
ds_destroy(&s);
}
return (hdrs->vendor ? OFPERR_OFPBRC_BAD_SUBTYPE
: ofphdrs_is_stat(hdrs) ? OFPERR_OFPBRC_BAD_STAT
: OFPERR_OFPBRC_BAD_TYPE);
}
I couldn't understand why my custom message would fail, but every
other messages which use ofpmp_init would work smoothly. Did I forget
any file, where I should add my subtype/custom message? Do you need
any more information?
Any hint would be appreciated.
Best regards,
--
Adam Paul Rzyska
More information about the dev
mailing list