X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fconnmgr.c;h=75d616cfca805248b984807165734179f323f145;hb=HEAD;hp=0bcb325a13536bcf9f9f4f988227f599dc5e5972;hpb=1f317cb5c2aa446c4b0252634a4a70dcc3682f93;p=sliver-openvswitch.git diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 0bcb325a1..75d616cfc 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -41,6 +41,8 @@ #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); @@ -129,6 +131,9 @@ struct ofconn { * 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 *, @@ -1136,6 +1141,13 @@ ofconn_add_opgroup(struct ofconn *ofconn, struct list *ofconn_node) { list_push_back(&ofconn->opgroups, ofconn_node); } + +struct hmap * +ofconn_get_bundles(struct ofconn *ofconn) +{ + return &ofconn->bundles; +} + /* Private ofconn functions. */ @@ -1163,6 +1175,8 @@ ofconn_create(struct connmgr *mgr, struct rconn *rconn, enum ofconn_type type, hmap_init(&ofconn->monitors); list_init(&ofconn->updates); + hmap_init(&ofconn->bundles); + ofconn_flush(ofconn); return ofconn; @@ -1263,6 +1277,8 @@ ofconn_destroy(struct ofconn *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); @@ -1410,6 +1426,65 @@ ofconn_receives_async_msg(const struct ofconn *ofconn, 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. * @@ -1559,7 +1634,8 @@ connmgr_send_packet_in(struct connmgr *mgr, 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); } @@ -2045,7 +2121,7 @@ ofmonitor_report(struct connmgr *mgr, struct rule *rule, ovs_mutex_unlock(&rule->mutex); if (flags & NXFMF_ACTIONS) { - struct rule_actions *actions = rule_get_actions(rule); + const struct rule_actions *actions = rule_get_actions(rule); fu.ofpacts = actions->ofpacts; fu.ofpacts_len = actions->ofpacts_len; } else {