return CONTAINER_OF(ofproto, struct ofproto_dpif, up);
}
-size_t
-ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *ofproto)
-{
- return ofproto->backer->support.max_mpls_depth;
-}
-
bool
-ofproto_dpif_get_enable_recirc(const struct ofproto_dpif *ofproto)
+ofproto_dpif_get_enable_ufid(const struct dpif_backer *backer)
{
- return ofproto->backer->support.recirc;
+ return backer->support.ufid;
}
-bool
-ofproto_dpif_get_enable_ufid(struct dpif_backer *backer)
+struct dpif_backer_support *
+ofproto_dpif_get_support(const struct ofproto_dpif *ofproto)
{
- return backer->support.ufid;
+ return &ofproto->backer->support;
}
static void ofproto_trace(struct ofproto_dpif *, struct flow *,
* it. */
void
ofproto_dpif_flow_mod(struct ofproto_dpif *ofproto,
- struct ofputil_flow_mod *fm)
+ const struct ofputil_flow_mod *fm)
{
- ofproto_flow_mod(&ofproto->up, fm);
+ struct ofproto_flow_mod ofm;
+
+ /* Multiple threads may do this for the same 'fm' at the same time.
+ * Allocate ofproto_flow_mod with execution context from stack.
+ *
+ * Note: This copy could be avoided by making ofproto_flow_mod more
+ * complex, but that may not be desireable, and a learn action is not that
+ * fast to begin with. */
+ ofm.fm = *fm;
+ ofproto_flow_mod(&ofproto->up, &ofm);
}
/* Appends 'pin' to the queue of "packet ins" to be sent to the controller.
shash_add(&init_ofp_ports, node->name, new_hint);
}
+
+ ofproto_unixctl_init();
+ udpif_init();
}
static void
bool enable_recirc;
struct odp_flow_key_parms odp_parms = {
.flow = &flow,
- .recirc = true,
+ .support = {
+ .recirc = true,
+ },
};
memset(&flow, 0, sizeof flow);
/* This feature needs to be tested after udpif threads are set. */
backer->support.variable_length_userdata = false;
- backer->support.recirc = check_recirc(backer);
- backer->support.max_mpls_depth = check_max_mpls_depth(backer);
+ backer->support.odp.recirc = check_recirc(backer);
+ backer->support.odp.max_mpls_depth = check_max_mpls_depth(backer);
backer->support.masked_set_action = check_masked_set_action(backer);
backer->support.ufid = check_ufid(backer);
backer->support.tnl_push_pop = dpif_supports_tnl_push_pop(backer->dpif);
guarded_list_init(&ofproto->pins);
- ofproto_unixctl_init();
-
hmap_init(&ofproto->vlandev_map);
hmap_init(&ofproto->realdev_vid_map);
ofproto_rule_delete(&ofproto->up, &rule->up);
}
}
+ ofproto_group_delete_all(&ofproto->up);
guarded_list_pop_all(&ofproto->pins, &pins);
LIST_FOR_EACH_POP (pin, list_node, &pins) {
group_construct(struct ofgroup *group_)
{
struct group_dpif *group = group_dpif_cast(group_);
- const struct ofputil_bucket *bucket;
-
- /* Prevent group chaining because our locking structure makes it hard to
- * implement deadlock-free. (See xlate_group_resource_check().) */
- LIST_FOR_EACH (bucket, list_node, &group->up.buckets) {
- const struct ofpact *a;
-
- OFPACT_FOR_EACH (a, bucket->ofpacts, bucket->ofpacts_len) {
- if (a->type == OFPACT_GROUP) {
- return OFPERR_OFPGMFC_CHAINING_UNSUPPORTED;
- }
- }
- }
ovs_mutex_init_adaptive(&group->stats_mutex);
ovs_mutex_lock(&group->stats_mutex);
bundle = b->port;
ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
name, sizeof name);
- ds_put_format(&ds, "%5s %4d "IP_FMT" %3d\n",
- name, grp->vlan, IP_ARGS(grp->ip4),
+ ds_put_format(&ds, "%5s %4d ", name, grp->vlan);
+ print_ipv6_mapped(&ds, &grp->addr);
+ ds_put_format(&ds, " %3d\n",
mcast_bundle_age(ofproto->ms, b));
}
}
bundle = mrouter->port;
ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
name, sizeof name);
- ds_put_format(&ds, "%5s %4d querier %3d\n",
+ ds_put_format(&ds, "%5s %4d querier %3d\n",
name, mrouter->vlan,
mcast_mrouter_age(ofproto->ms, mrouter));
}
const struct ofpbuf *ofpacts,
struct rule **rulep)
{
- struct ofputil_flow_mod fm;
+ struct ofproto_flow_mod ofm;
struct rule_dpif *rule;
int error;
- fm.match = *match;
- fm.priority = priority;
- fm.new_cookie = htonll(0);
- fm.cookie = htonll(0);
- fm.cookie_mask = htonll(0);
- fm.modify_cookie = false;
- fm.table_id = TBL_INTERNAL;
- fm.command = OFPFC_ADD;
- fm.idle_timeout = idle_timeout;
- fm.hard_timeout = 0;
- fm.importance = 0;
- fm.buffer_id = 0;
- fm.out_port = 0;
- fm.flags = OFPUTIL_FF_HIDDEN_FIELDS | OFPUTIL_FF_NO_READONLY;
- fm.ofpacts = ofpacts->data;
- fm.ofpacts_len = ofpacts->size;
-
- error = ofproto_flow_mod(&ofproto->up, &fm);
+ ofm.fm.match = *match;
+ ofm.fm.priority = priority;
+ ofm.fm.new_cookie = htonll(0);
+ ofm.fm.cookie = htonll(0);
+ ofm.fm.cookie_mask = htonll(0);
+ ofm.fm.modify_cookie = false;
+ ofm.fm.table_id = TBL_INTERNAL;
+ ofm.fm.command = OFPFC_ADD;
+ ofm.fm.idle_timeout = idle_timeout;
+ ofm.fm.hard_timeout = 0;
+ ofm.fm.importance = 0;
+ ofm.fm.buffer_id = 0;
+ ofm.fm.out_port = 0;
+ ofm.fm.flags = OFPUTIL_FF_HIDDEN_FIELDS | OFPUTIL_FF_NO_READONLY;
+ ofm.fm.ofpacts = ofpacts->data;
+ ofm.fm.ofpacts_len = ofpacts->size;
+
+ error = ofproto_flow_mod(&ofproto->up, &ofm);
if (error) {
VLOG_ERR_RL(&rl, "failed to add internal flow (%s)",
ofperr_to_string(error));
rule = rule_dpif_lookup_in_table(ofproto,
ofproto_dpif_get_tables_version(ofproto),
- TBL_INTERNAL, &fm.match.flow,
- &fm.match.wc, false);
+ TBL_INTERNAL, &ofm.fm.match.flow,
+ &ofm.fm.match.wc, false);
if (rule) {
*rulep = &rule->up;
} else {
ofproto_dpif_delete_internal_flow(struct ofproto_dpif *ofproto,
struct match *match, int priority)
{
- struct ofputil_flow_mod fm;
+ struct ofproto_flow_mod ofm;
int error;
- fm.match = *match;
- fm.priority = priority;
- fm.new_cookie = htonll(0);
- fm.cookie = htonll(0);
- fm.cookie_mask = htonll(0);
- fm.modify_cookie = false;
- fm.table_id = TBL_INTERNAL;
- fm.flags = OFPUTIL_FF_HIDDEN_FIELDS | OFPUTIL_FF_NO_READONLY;
- fm.command = OFPFC_DELETE_STRICT;
-
- error = ofproto_flow_mod(&ofproto->up, &fm);
+ ofm.fm.match = *match;
+ ofm.fm.priority = priority;
+ ofm.fm.new_cookie = htonll(0);
+ ofm.fm.cookie = htonll(0);
+ ofm.fm.cookie_mask = htonll(0);
+ ofm.fm.modify_cookie = false;
+ ofm.fm.table_id = TBL_INTERNAL;
+ ofm.fm.flags = OFPUTIL_FF_HIDDEN_FIELDS | OFPUTIL_FF_NO_READONLY;
+ ofm.fm.command = OFPFC_DELETE_STRICT;
+
+ error = ofproto_flow_mod(&ofproto->up, &ofm);
if (error) {
VLOG_ERR_RL(&rl, "failed to delete internal flow (%s)",
ofperr_to_string(error));