summaryrefslogtreecommitdiff
path: root/ofproto/ofproto.c
diff options
context:
space:
mode:
Diffstat (limited to 'ofproto/ofproto.c')
-rw-r--r--ofproto/ofproto.c142
1 files changed, 15 insertions, 127 deletions
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index aec483732..8c95aa0f5 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -50,7 +50,6 @@
#include "ovs-rcu.h"
#include "packets.h"
#include "pinsched.h"
-#include "pktbuf.h"
#include "poll-loop.h"
#include "random.h"
#include "seq.h"
@@ -142,20 +141,6 @@ static enum ofperr collect_rules_loose(struct ofproto *,
const struct rule_criteria *,
struct rule_collection *);
-/* A packet that needs to be passed to rule_execute().
- *
- * (We can't do this immediately from ofopgroup_complete() because that holds
- * ofproto_mutex, which rule_execute() needs released.) */
-struct rule_execute {
- struct ovs_list list_node; /* In struct ofproto's "rule_executes" list. */
- struct rule *rule; /* Owns a reference to the rule. */
- ofp_port_t in_port;
- struct dp_packet *packet; /* Owns the packet. */
-};
-
-static void run_rule_executes(struct ofproto *) OVS_EXCLUDED(ofproto_mutex);
-static void destroy_rule_executes(struct ofproto *);
-
struct learned_cookie {
union {
/* In struct ofproto's 'learned_cookies' hmap. */
@@ -264,10 +249,6 @@ static void delete_flows__(struct rule_collection *,
const struct openflow_mod_requester *)
OVS_REQUIRES(ofproto_mutex);
-static void send_buffered_packet(const struct openflow_mod_requester *,
- uint32_t buffer_id, struct rule *)
- OVS_REQUIRES(ofproto_mutex);
-
static bool ofproto_group_exists(const struct ofproto *, uint32_t group_id);
static void handle_openflow(struct ofconn *, const struct ofpbuf *);
static enum ofperr ofproto_flow_mod_init(struct ofproto *,
@@ -533,7 +514,6 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
hmap_init(&ofproto->learned_cookies);
ovs_list_init(&ofproto->expirable);
ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name);
- guarded_list_init(&ofproto->rule_executes);
ofproto->min_mtu = INT_MAX;
cmap_init(&ofproto->groups);
ovs_mutex_unlock(&ofproto_mutex);
@@ -1556,9 +1536,6 @@ ofproto_destroy__(struct ofproto *ofproto)
{
struct oftable *table;
- destroy_rule_executes(ofproto);
-
- guarded_list_destroy(&ofproto->rule_executes);
cmap_destroy(&ofproto->groups);
hmap_remove(&all_ofprotos, &ofproto->hmap_node);
@@ -1703,8 +1680,6 @@ ofproto_run(struct ofproto *p)
VLOG_ERR_RL(&rl, "%s: run failed (%s)", p->name, ovs_strerror(error));
}
- run_rule_executes(p);
-
/* Restore the eviction group heap invariant occasionally. */
if (p->eviction_group_timer < time_msec()) {
size_t i;
@@ -3069,50 +3044,6 @@ ofproto_rule_has_out_group(const struct rule *rule, uint32_t group_id)
}
}
-static void
-rule_execute_destroy(struct rule_execute *e)
-{
- ofproto_rule_unref(e->rule);
- ovs_list_remove(&e->list_node);
- free(e);
-}
-
-/* Executes all "rule_execute" operations queued up in ofproto->rule_executes,
- * by passing them to the ofproto provider. */
-static void
-run_rule_executes(struct ofproto *ofproto)
- OVS_EXCLUDED(ofproto_mutex)
-{
- struct rule_execute *e, *next;
- struct ovs_list executes;
-
- guarded_list_pop_all(&ofproto->rule_executes, &executes);
- LIST_FOR_EACH_SAFE (e, next, list_node, &executes) {
- struct flow flow;
-
- flow_extract(e->packet, &flow);
- flow.in_port.ofp_port = e->in_port;
- ofproto->ofproto_class->rule_execute(e->rule, &flow, e->packet);
-
- rule_execute_destroy(e);
- }
-}
-
-/* Destroys and discards all "rule_execute" operations queued up in
- * ofproto->rule_executes. */
-static void
-destroy_rule_executes(struct ofproto *ofproto)
-{
- struct rule_execute *e, *next;
- struct ovs_list executes;
-
- guarded_list_pop_all(&ofproto->rule_executes, &executes);
- LIST_FOR_EACH_SAFE (e, next, list_node, &executes) {
- dp_packet_delete(e->packet);
- rule_execute_destroy(e);
- }
-}
-
static bool
rule_is_readonly(const struct rule *rule)
{
@@ -3353,7 +3284,7 @@ handle_features_request(struct ofconn *ofconn, const struct ofp_header *oh)
query_switch_features(ofproto, &arp_match_ip, &features.ofpacts);
features.datapath_id = ofproto->datapath_id;
- features.n_buffers = pktbuf_capacity();
+ features.n_buffers = 0;
features.n_tables = ofproto_get_n_visible_tables(ofproto);
features.capabilities = (OFPUTIL_C_FLOW_STATS | OFPUTIL_C_TABLE_STATS |
OFPUTIL_C_PORT_STATS | OFPUTIL_C_QUEUE_STATS |
@@ -3502,14 +3433,11 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
/* Get payload. */
if (po.buffer_id != UINT32_MAX) {
- error = ofconn_pktbuf_retrieve(ofconn, po.buffer_id, &payload, NULL);
- if (error) {
- goto exit_free_ofpacts;
- }
- } else {
- /* Ensure that the L3 header is 32-bit aligned. */
- payload = dp_packet_clone_data_with_headroom(po.packet, po.packet_len, 2);
+ error = OFPERR_OFPBRC_BUFFER_UNKNOWN;
+ goto exit_free_ofpacts;
}
+ /* Ensure that the L3 header is 32-bit aligned. */
+ payload = dp_packet_clone_data_with_headroom(po.packet, po.packet_len, 2);
/* Verify actions against packet, then send packet if successful. */
flow_extract(payload, &flow);
@@ -4807,8 +4735,6 @@ add_flow_finish(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
/* Send Vacancy Events for OF1.4+. */
send_table_status(ofproto, new_rule->table_id);
}
-
- send_buffered_packet(req, ofm->buffer_id, new_rule);
}
/* OFPFC_MODIFY and OFPFC_MODIFY_STRICT. */
@@ -5107,10 +5033,7 @@ modify_flows_init_loose(struct ofproto *ofproto,
}
/* Implements OFPFC_MODIFY. Returns 0 on success or an OpenFlow error code on
- * failure.
- *
- * 'ofconn' is used to retrieve the packet buffer specified in ofm->buffer_id,
- * if any. */
+ * failure. */
static enum ofperr
modify_flows_start_loose(struct ofproto *ofproto, struct ofproto_flow_mod *ofm)
OVS_REQUIRES(ofproto_mutex)
@@ -5173,9 +5096,6 @@ modify_flows_finish(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
}
learned_cookies_flush(ofproto, &dead_cookies);
remove_rules_postponed(old_rules);
-
- send_buffered_packet(req, ofm->buffer_id,
- rule_collection_rules(new_rules)[0]);
rule_collection_destroy(new_rules);
}
}
@@ -5520,7 +5440,6 @@ handle_flow_mod__(struct ofproto *ofproto, const struct ofputil_flow_mod *fm,
ofmonitor_flush(ofproto->connmgr);
ovs_mutex_unlock(&ofproto_mutex);
- run_rule_executes(ofproto);
return error;
}
@@ -7110,7 +7029,6 @@ ofproto_flow_mod_init(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
/* Forward flow mod fields we need later. */
ofm->command = fm->command;
- ofm->buffer_id = fm->buffer_id;
ofm->modify_cookie = fm->modify_cookie;
ofm->modify_may_add_flow = (fm->new_cookie != OVS_BE64_MAX
@@ -7122,14 +7040,19 @@ ofproto_flow_mod_init(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
ofm->conjs = NULL;
ofm->n_conjs = 0;
+ bool check_buffer_id = false;
+
switch (ofm->command) {
case OFPFC_ADD:
+ check_buffer_id = true;
error = add_flow_init(ofproto, ofm, fm);
break;
case OFPFC_MODIFY:
+ check_buffer_id = true;
error = modify_flows_init_loose(ofproto, ofm, fm);
break;
case OFPFC_MODIFY_STRICT:
+ check_buffer_id = true;
error = modify_flow_init_strict(ofproto, ofm, fm);
break;
case OFPFC_DELETE:
@@ -7142,6 +7065,10 @@ ofproto_flow_mod_init(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
error = OFPERR_OFPFMFC_BAD_COMMAND;
break;
}
+ if (!error && check_buffer_id && fm->buffer_id != UINT32_MAX) {
+ error = OFPERR_OFPBRC_BUFFER_UNKNOWN;
+ }
+
if (error) {
ofproto_flow_mod_uninit(ofm);
}
@@ -7381,8 +7308,6 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags)
ofmonitor_flush(ofproto->connmgr);
ovs_mutex_unlock(&ofproto_mutex);
-
- run_rule_executes(ofproto);
}
/* The bundle is discarded regardless the outcome. */
@@ -7751,43 +7676,6 @@ handle_openflow(struct ofconn *ofconn, const struct ofpbuf *ofp_msg)
COVERAGE_INC(ofproto_recv_openflow);
}
-/* Asynchronous operations. */
-
-static void
-send_buffered_packet(const struct openflow_mod_requester *req,
- uint32_t buffer_id, struct rule *rule)
- OVS_REQUIRES(ofproto_mutex)
-{
- if (req && req->ofconn && buffer_id != UINT32_MAX) {
- struct ofproto *ofproto = ofconn_get_ofproto(req->ofconn);
- struct dp_packet *packet;
- ofp_port_t in_port;
- enum ofperr error;
-
- error = ofconn_pktbuf_retrieve(req->ofconn, buffer_id, &packet,
- &in_port);
- if (packet) {
- struct rule_execute *re;
-
- ofproto_rule_ref(rule);
-
- re = xmalloc(sizeof *re);
- re->rule = rule;
- re->in_port = in_port;
- re->packet = packet;
-
- if (!guarded_list_push_back(&ofproto->rule_executes,
- &re->list_node, 1024)) {
- ofproto_rule_unref(rule);
- dp_packet_delete(re->packet);
- free(re);
- }
- } else {
- ofconn_send_error(req->ofconn, req->request, error);
- }
- }
-}
-
static uint64_t
pick_datapath_id(const struct ofproto *ofproto)
{