COVERAGE_DEFINE(packet_in_overflow);
COVERAGE_DEFINE(flow_mod_overflow);
-#define N_THREADS 16
-
/* Number of implemented OpenFlow tables. */
enum { N_TABLES = 255 };
enum { TBL_INTERNAL = N_TABLES - 1 }; /* Used for internal hidden rules. */
/* Number of subfacets added or deleted from 'created' to 'last_minute.' */
unsigned long long int total_subfacet_add_count;
unsigned long long int total_subfacet_del_count;
+
+ /* Number of upcall handling threads. */
+ unsigned int n_handler_threads;
};
/* All existing ofproto_backer instances, indexed by ofproto->up.type. */
ovs_mutex_unlock(&ofproto->flow_mod_mutex);
}
+/* Appends 'pin' to the queue of "packet ins" to be sent to the controller.
+ * Takes ownership of 'pin' and pin->packet. */
void
ofproto_dpif_send_packet_in(struct ofproto_dpif *ofproto,
struct ofputil_packet_in *pin)
VLOG_ERR("Failed to enable receiving packets in dpif.");
return error;
}
- udpif_recv_set(backer->udpif, N_THREADS, backer->recv_set_enable);
+ udpif_recv_set(backer->udpif, n_handler_threads,
+ backer->recv_set_enable);
dpif_flow_flush(backer->dpif);
backer->need_revalidate = REV_RECONFIGURE;
}
+ /* If the n_handler_threads is reconfigured, call udpif_recv_set()
+ * to reset the handler threads. */
+ if (backer->n_handler_threads != n_handler_threads) {
+ udpif_recv_set(backer->udpif, n_handler_threads,
+ backer->recv_set_enable);
+ backer->n_handler_threads = n_handler_threads;
+ }
+
if (backer->need_revalidate) {
struct ofproto_dpif *ofproto;
struct simap_node *node;
}
timer_wait(&backer->next_expiration);
+ dpif_wait(backer->dpif);
+ udpif_wait(backer->udpif);
}
\f
/* Basic life-cycle. */
close_dpif_backer(backer);
return error;
}
- udpif_recv_set(backer->udpif, N_THREADS, backer->recv_set_enable);
+ udpif_recv_set(backer->udpif, n_handler_threads,
+ backer->recv_set_enable);
+ backer->n_handler_threads = n_handler_threads;
backer->max_n_subfacet = 0;
backer->created = time_msec();
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
struct rule_dpif *rule, *next_rule;
- struct ofputil_flow_mod *pin, *next_pin;
+ struct ofputil_packet_in *pin, *next_pin;
struct ofputil_flow_mod *fm, *next_fm;
struct oftable *table;
LIST_FOR_EACH_SAFE (pin, next_pin, list_node, &ofproto->pins) {
list_remove(&pin->list_node);
ofproto->n_pins--;
- free(pin->ofpacts);
+ free(CONST_CAST(void *, pin->packet));
free(pin);
}
ovs_mutex_unlock(&ofproto->pin_mutex);
return;
}
- dpif_wait(ofproto->backer->dpif);
- udpif_wait(ofproto->backer->udpif);
if (ofproto->sflow) {
dpif_sflow_wait(ofproto->sflow);
}
if (port->bundle != bundle) {
bundle->ofproto->backer->need_revalidate = REV_RECONFIGURE;
if (port->bundle) {
- bundle_del_port(port);
+ bundle_remove(&port->up);
}
port->bundle = bundle;
rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto,
const struct flow *flow, struct flow_wildcards *wc,
uint8_t table_id, struct rule_dpif **rule)
+ OVS_ACQ_RDLOCK((*rule)->up.evict)
{
struct cls_rule *cls_rule;
struct classifier *cls;
/* Use the metadata from the flow and the packet argument
* to reconstruct the flow. */
- flow_extract(packet, flow.skb_priority, flow.skb_mark, NULL,
+ flow_extract(packet, flow.skb_priority, flow.pkt_mark, NULL,
&in_port_, &flow);
}
}
const struct ofpbuf *packet, struct ds *ds)
{
struct rule_dpif *rule;
+ struct flow_wildcards wc;
ds_put_cstr(ds, "Flow: ");
flow_format(ds, flow);
ds_put_char(ds, '\n');
- rule_dpif_lookup(ofproto, flow, NULL, &rule);
+ flow_wildcards_init_catchall(&wc);
+ rule_dpif_lookup(ofproto, flow, &wc, &rule);
trace_format_rule(ds, 0, rule);
if (rule == ofproto->miss_rule) {
trace.xin.report_hook = trace_report;
xlate_actions(&trace.xin, &trace.xout);
+ flow_wildcards_or(&trace.xout.wc, &trace.xout.wc, &wc);
ds_put_char(ds, '\n');
trace_format_flow(ds, 0, "Final flow", &trace);