#include "vconn.h"
#include "vlog.h"
+#include "bundles.h"
+
VLOG_DEFINE_THIS_MODULE(connmgr);
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
* contains an update event of type NXFME_ABBREV and false otherwise.. */
struct list updates OVS_GUARDED_BY(ofproto_mutex);
bool sent_abbrev_update OVS_GUARDED_BY(ofproto_mutex);
+
+ /* Active bundles. Contains "struct ofp_bundle"s. */
+ struct hmap bundles;
};
static struct ofconn *ofconn_create(struct connmgr *, struct rconn *,
{
list_push_back(&ofconn->opgroups, ofconn_node);
}
+
+struct hmap *
+ofconn_get_bundles(struct ofconn *ofconn)
+{
+ return &ofconn->bundles;
+}
+
\f
/* Private ofconn functions. */
hmap_init(&ofconn->monitors);
list_init(&ofconn->updates);
+ hmap_init(&ofconn->bundles);
+
ofconn_flush(ofconn);
return ofconn;
hmap_remove(&ofconn->connmgr->controllers, &ofconn->hmap_node);
}
+ ofp_bundle_remove_all(ofconn);
+
hmap_destroy(&ofconn->monitors);
list_remove(&ofconn->node);
rconn_destroy(ofconn->rconn);
return true;
}
+/* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the
+ * packet rather than to send the packet to the controller.
+ *
+ * This function returns false to indicate the packet should be dropped if
+ * the controller action was the result of the default table-miss behaviour
+ * and the controller is using OpenFlow1.3+.
+ *
+ * Otherwise true is returned to indicate the packet should be forwarded to
+ * the controller */
+static bool
+ofconn_wants_packet_in_on_miss(struct ofconn *ofconn,
+ const struct ofproto_packet_in *pin)
+{
+ if (pin->miss_type == OFPROTO_PACKET_IN_MISS_WITHOUT_FLOW) {
+ enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
+
+ if (protocol != OFPUTIL_P_NONE
+ && ofputil_protocol_to_ofp_version(protocol) >= OFP13_VERSION) {
+ enum ofproto_table_config config;
+
+ config = ofproto_table_get_config(ofconn->connmgr->ofproto,
+ pin->up.table_id);
+ if (config == OFPROTO_TABLE_MISS_DEFAULT) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the
+ * packet rather than to send the packet to the controller.
+ *
+ * This function returns false to indicate that a packet_in message
+ * for a "table-miss" should be sent to at least one controller.
+ * That is there is at least one controller with controller_id 0
+ * which connected using an OpenFlow version earlier than OpenFlow1.3.
+ *
+ * False otherwise.
+ *
+ * This logic assumes that "table-miss" packet_in messages
+ * are always sent to controller_id 0. */
+bool
+connmgr_wants_packet_in_on_miss(struct connmgr *mgr)
+{
+ struct ofconn *ofconn;
+
+ LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
+ enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
+
+ if (ofconn->controller_id == 0 &&
+ (protocol == OFPUTIL_P_NONE ||
+ ofputil_protocol_to_ofp_version(protocol) < OFP13_VERSION)) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* Returns a human-readable name for an OpenFlow connection between 'mgr' and
* 'target', suitable for use in log messages for identifying the connection.
*
static enum ofp_packet_in_reason
wire_reason(struct ofconn *ofconn, const struct ofproto_packet_in *pin)
{
- if (pin->generated_by_table_miss && pin->up.reason == OFPR_ACTION) {
+ if (pin->miss_type == OFPROTO_PACKET_IN_MISS_FLOW
+ && pin->up.reason == OFPR_ACTION) {
enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
if (protocol != OFPUTIL_P_NONE
LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
enum ofp_packet_in_reason reason = wire_reason(ofconn, pin);
- if (ofconn_receives_async_msg(ofconn, OAM_PACKET_IN, reason)
+ if (ofconn_wants_packet_in_on_miss(ofconn, pin)
+ && ofconn_receives_async_msg(ofconn, OAM_PACKET_IN, pin->up.reason)
&& ofconn->controller_id == pin->controller_id) {
schedule_packet_in(ofconn, *pin, reason);
}
ofpact_pad(&ofpacts);
match_init_catchall(&match);
- ofproto_add_flow(mgr->ofproto, &match, 0, ofpacts.data, ofpacts.size);
+ ofproto_add_flow(mgr->ofproto, &match, 0, ofpbuf_data(&ofpacts),
+ ofpbuf_size(&ofpacts));
ofpbuf_uninit(&ofpacts);
}
ovs_mutex_unlock(&rule->mutex);
if (flags & NXFMF_ACTIONS) {
- fu.ofpacts = rule->actions->ofpacts;
- fu.ofpacts_len = rule->actions->ofpacts_len;
+ const struct rule_actions *actions = rule_get_actions(rule);
+ fu.ofpacts = actions->ofpacts;
+ fu.ofpacts_len = actions->ofpacts_len;
} else {
fu.ofpacts = NULL;
fu.ofpacts_len = 0;