desc->features = 0;
desc->speed = 0;
- if (p->port_no < 255) {
- /* FIXME: this is a layering violation and should really be
- * done in the secchan, as with OFPC_STP in
- * OFP_SUPPORTED_CAPABILITIES. */
- desc->features |= OFPPF_STP;
- }
-
spin_lock_irqsave(&p->lock, flags);
desc->flags = htonl(p->flags | p->status);
spin_unlock_irqrestore(&p->lock, flags);
return send_openflow_skb(skb, sender);
}
+int
+dp_send_hello(struct datapath *dp, const struct sender *sender,
+ const struct ofp_header *request)
+{
+ if (request->version < OFP_VERSION) {
+ char err[64];
+ sprintf(err, "Only version 0x%02x supported", OFP_VERSION);
+ dp_send_error_msg(dp, sender, OFPET_HELLO_FAILED,
+ OFPHFC_INCOMPATIBLE, err, strlen(err));
+ return -EINVAL;
+ } else {
+ struct sk_buff *skb;
+ struct ofp_header *reply;
+
+ reply = alloc_openflow_skb(dp, sizeof *reply,
+ OFPT_HELLO, sender, &skb);
+ if (!reply)
+ return -ENOMEM;
+
+ return send_openflow_skb(skb, sender);
+ }
+}
+
/* Callback function for a workqueue to disable an interface */
static void
down_port_cb(struct work_struct *work)
struct ofp_error_msg *oem;
- oem = alloc_openflow_skb(dp, sizeof(*oem)+len, OFPT_ERROR_MSG,
+ oem = alloc_openflow_skb(dp, sizeof(*oem)+len, OFPT_ERROR,
sender, &skb);
if (!oem)
return -ENOMEM;
static int flow_stats_dump_callback(struct sw_flow *flow, void *private)
{
+ struct sw_flow_actions *sf_acts = rcu_dereference(flow->sf_acts);
struct flow_stats_state *s = private;
struct ofp_flow_stats *ofs;
int actions_length;
int length;
- actions_length = sizeof *ofs->actions * flow->n_actions;
- length = sizeof *ofs + sizeof *ofs->actions * flow->n_actions;
+ actions_length = sizeof *ofs->actions * sf_acts->n_actions;
+ length = sizeof *ofs + actions_length;
if (length + s->bytes_used > s->bytes_allocated)
return 1;
memset(ofs->pad2, 0, sizeof ofs->pad2);
ofs->packet_count = cpu_to_be64(flow->packet_count);
ofs->byte_count = cpu_to_be64(flow->byte_count);
- memcpy(ofs->actions, flow->actions, actions_length);
+ memcpy(ofs->actions, sf_acts->actions, actions_length);
s->bytes_used += length;
return 0;
return -EINVAL;
rq = nla_data(va);
- sender.xid = type = ntohs(rq->type);
+ sender.xid = rq->header.xid;
+ type = ntohs(rq->type);
if (rq->header.version != OFP_VERSION) {
dp_send_error_msg(dp, &sender, OFPET_BAD_REQUEST,
OFPBRC_BAD_VERSION, rq, len);