for (i = 0; i < n_ofproto_classes; i++) {
ofproto_classes[i]->init(&init_ofp_ports);
}
+
+ ofproto_unixctl_init();
}
/* 'type' should be a normalized datapath type, as returned by
*ofprotop = NULL;
- ofproto_unixctl_init();
-
datapath_type = ofproto_normalize_type(datapath_type);
class = ofproto_class_find__(datapath_type);
if (!class) {
}
}
pp->port_no = ofproto_port->ofp_port;
- netdev_get_etheraddr(netdev, pp->hw_addr);
+ netdev_get_etheraddr(netdev, &pp->hw_addr);
ovs_strlcpy(pp->name, ofproto_port->name, sizeof pp->name);
netdev_get_flags(netdev, &flags);
pp->config = flags & NETDEV_UP ? 0 : OFPUTIL_PC_PORT_DOWN;
static void
ofport_modified(struct ofport *port, struct ofputil_phy_port *pp)
{
- memcpy(port->pp.hw_addr, pp->hw_addr, ETH_ADDR_LEN);
+ port->pp.hw_addr = pp->hw_addr;
port->pp.config = ((port->pp.config & ~OFPUTIL_PC_PORT_DOWN)
| (pp->config & OFPUTIL_PC_PORT_DOWN));
port->pp.state = ((port->pp.state & ~OFPUTIL_PS_LINK_DOWN)
* - If they use any groups, then 'ofproto' has that group configured.
*
* Returns 0 if successful, otherwise an OpenFlow error. */
-static enum ofperr
+enum ofperr
ofproto_check_ofpacts(struct ofproto *ofproto,
const struct ofpact ofpacts[], size_t ofpacts_len)
{
/* Verify actions against packet, then send packet if successful. */
flow_extract(payload, &flow);
flow.in_port.ofp_port = po.in_port;
- error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len);
+
+ /* Check actions like for flow mods. We pass a 'table_id' of 0 to
+ * ofproto_check_consistency(), which isn't strictly correct because these
+ * actions aren't in any table. This is OK as 'table_id' is only used to
+ * check instructions (e.g., goto-table), which can't appear on the action
+ * list of a packet-out. */
+ error = ofpacts_check_consistency(po.ofpacts, po.ofpacts_len,
+ &flow, u16_to_ofp(p->max_ports),
+ 0, p->n_tables,
+ ofconn_get_protocol(ofconn));
if (!error) {
- error = p->ofproto_class->packet_out(p, payload, &flow,
- po.ofpacts, po.ofpacts_len);
+ error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len);
+ if (!error) {
+ error = p->ofproto_class->packet_out(p, payload, &flow,
+ po.ofpacts, po.ofpacts_len);
+ }
}
dp_packet_delete(payload);
enum ofperr error;
rule_criteria_init(&criteria, fm->table_id, &fm->match, 0, CLS_MAX_VERSION,
- fm->cookie, fm->cookie_mask, OFPP_ANY, OFPG11_ANY);
+ fm->cookie, fm->cookie_mask, OFPP_ANY, OFPG_ANY);
rule_criteria_require_rw(&criteria,
(fm->flags & OFPUTIL_FF_NO_READONLY) != 0);
error = collect_rules_loose(ofproto, &criteria, old_rules);
rule_criteria_init(&criteria, fm->table_id, &fm->match, fm->priority,
CLS_MAX_VERSION, fm->cookie, fm->cookie_mask, OFPP_ANY,
- OFPG11_ANY);
+ OFPG_ANY);
rule_criteria_require_rw(&criteria,
(fm->flags & OFPUTIL_FF_NO_READONLY) != 0);
error = collect_rules_strict(ofproto, &criteria, old_rules);
}
if (request.role != OFPCR12_ROLE_NOCHANGE) {
- if (request.have_generation_id
+ if (request.role != OFPCR12_ROLE_EQUAL
+ && request.have_generation_id
&& !ofconn_set_master_election_id(ofconn, request.generation_id)) {
return OFPERR_OFPRRFC_STALE;
}
static enum ofperr
handle_nxt_set_async_config(struct ofconn *ofconn, const struct ofp_header *oh)
{
- const struct nx_async_config *msg = ofpmsg_body(oh);
- uint32_t master[OAM_N_TYPES];
- uint32_t slave[OAM_N_TYPES];
+ uint32_t master[OAM_N_TYPES] = {0};
+ uint32_t slave[OAM_N_TYPES] = {0};
- master[OAM_PACKET_IN] = ntohl(msg->packet_in_mask[0]);
- master[OAM_PORT_STATUS] = ntohl(msg->port_status_mask[0]);
- master[OAM_FLOW_REMOVED] = ntohl(msg->flow_removed_mask[0]);
-
- slave[OAM_PACKET_IN] = ntohl(msg->packet_in_mask[1]);
- slave[OAM_PORT_STATUS] = ntohl(msg->port_status_mask[1]);
- slave[OAM_FLOW_REMOVED] = ntohl(msg->flow_removed_mask[1]);
+ ofputil_decode_set_async_config(oh, master, slave, false);
ofconn_set_async_config(ofconn, master, slave);
if (ofconn_get_type(ofconn) == OFCONN_SERVICE &&
struct ofpbuf *buf;
uint32_t master[OAM_N_TYPES];
uint32_t slave[OAM_N_TYPES];
- struct nx_async_config *msg;
ofconn_get_async_config(ofconn, master, slave);
- buf = ofpraw_alloc_reply(OFPRAW_OFPT13_GET_ASYNC_REPLY, oh, 0);
- msg = ofpbuf_put_zeros(buf, sizeof *msg);
-
- msg->packet_in_mask[0] = htonl(master[OAM_PACKET_IN]);
- msg->port_status_mask[0] = htonl(master[OAM_PORT_STATUS]);
- msg->flow_removed_mask[0] = htonl(master[OAM_FLOW_REMOVED]);
-
- msg->packet_in_mask[1] = htonl(slave[OAM_PACKET_IN]);
- msg->port_status_mask[1] = htonl(slave[OAM_PORT_STATUS]);
- msg->flow_removed_mask[1] = htonl(slave[OAM_FLOW_REMOVED]);
+ buf = ofputil_encode_get_async_config(oh, master, slave);
ofconn_send_reply(ofconn, buf);
return 0;
break;
}
+ if (!error) {
+ struct ofputil_requestforward rf;
+ rf.xid = oh->xid;
+ rf.reason = OFPRFR_METER_MOD;
+ rf.meter_mod = &mm;
+ connmgr_send_requestforward(ofproto->connmgr, ofconn, &rf);
+ }
+
exit_free_bands:
ofpbuf_uninit(&bands);
return error;
ofputil_bucket_clone_list(&new_ofgroup->buckets, &ofgroup->buckets, NULL);
- if (ofputil_bucket_check_duplicate_id(&ofgroup->buckets)) {
- VLOG_WARN_RL(&rl, "Duplicate bucket id");
+ if (ofputil_bucket_check_duplicate_id(&new_ofgroup->buckets)) {
+ VLOG_INFO_RL(&rl, "Duplicate bucket id");
return OFPERR_OFPGMFC_BUCKET_EXISTS;
}
switch (gm.command) {
case OFPGC11_ADD:
- return add_group(ofproto, &gm);
+ error = add_group(ofproto, &gm);
+ break;
case OFPGC11_MODIFY:
- return modify_group(ofproto, &gm);
+ error = modify_group(ofproto, &gm);
+ break;
case OFPGC11_DELETE:
delete_group(ofproto, gm.group_id);
- return 0;
+ error = 0;
+ break;
case OFPGC15_INSERT_BUCKET:
- return modify_group(ofproto, &gm);
+ error = modify_group(ofproto, &gm);
+ break;
case OFPGC15_REMOVE_BUCKET:
- return modify_group(ofproto, &gm);
+ error = modify_group(ofproto, &gm);
+ break;
default:
if (gm.command > OFPGC11_DELETE) {
- VLOG_WARN_RL(&rl, "%s: Invalid group_mod command type %d",
+ VLOG_INFO_RL(&rl, "%s: Invalid group_mod command type %d",
ofproto->name, gm.command);
}
return OFPERR_OFPGMFC_BAD_COMMAND;
}
+
+ if (!error) {
+ struct ofputil_requestforward rf;
+ rf.xid = oh->xid;
+ rf.reason = OFPRFR_GROUP_MOD;
+ rf.group_mod = &gm;
+ connmgr_send_requestforward(ofproto->connmgr, ofconn, &rf);
+ }
+ return error;
}
enum ofputil_table_miss
break;
case OFPBCT_CLOSE_REQUEST:
error = ofp_bundle_close(ofconn, bctrl.bundle_id, bctrl.flags);
- reply.type = OFPBCT_CLOSE_REPLY;;
+ reply.type = OFPBCT_CLOSE_REPLY;
break;
case OFPBCT_COMMIT_REQUEST:
error = do_bundle_commit(ofconn, bctrl.bundle_id, bctrl.flags);
case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
case OFPTYPE_TABLE_DESC_REPLY:
case OFPTYPE_ROLE_STATUS:
+ case OFPTYPE_REQUESTFORWARD:
case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
default:
if (ofpmsg_is_stat_request(oh)) {
port = ofproto_get_port(ofproto, OFPP_LOCAL);
if (port) {
- uint8_t ea[ETH_ADDR_LEN];
+ struct eth_addr ea;
int error;
- error = netdev_get_etheraddr(port->netdev, ea);
+ error = netdev_get_etheraddr(port->netdev, &ea);
if (!error) {
return eth_addr_to_uint64(ea);
}
static uint64_t
pick_fallback_dpid(void)
{
- uint8_t ea[ETH_ADDR_LEN];
- eth_addr_nicira_random(ea);
+ struct eth_addr ea;
+ eth_addr_nicira_random(&ea);
return eth_addr_to_uint64(ea);
}
\f