X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fconnmgr.c;h=b8cdfa547f0ea0c081d2277b8cf66c7f4c0395c4;hb=e892d5ffb5749c0534fecd903e3e6a76819f1346;hp=77b7b3916bc64d967c2957474be75d336ea080a1;hpb=07c8ec217b5641b74f20b216ad63fef230649f2c;p=sliver-openvswitch.git diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 77b7b3916..b8cdfa547 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,7 @@ struct ofconn { /* State that should be cleared from one connection to the next. */ /* OpenFlow state. */ - enum nx_role role; /* Role. */ + enum ofp12_controller_role role; /* Role. */ enum ofputil_protocol protocol; /* Current protocol variant. */ enum nx_packet_in_format packet_in_format; /* OFPT_PACKET_IN format. */ @@ -154,6 +154,9 @@ struct connmgr { /* OpenFlow connections. */ struct hmap controllers; /* Controller "struct ofconn"s. */ struct list all_conns; /* Contains "struct ofconn"s. */ + uint64_t master_election_id; /* monotonically increasing sequence number + * for master election */ + bool master_election_id_defined; /* OpenFlow listeners. */ struct hmap services; /* Contains "struct ofservice"s. */ @@ -193,6 +196,8 @@ connmgr_create(struct ofproto *ofproto, hmap_init(&mgr->controllers); list_init(&mgr->all_conns); + mgr->master_election_id = 0; + mgr->master_election_id_defined = false; hmap_init(&mgr->services); mgr->snoops = NULL; @@ -748,7 +753,7 @@ set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp, SSET_FOR_EACH (name, sset) { struct pvconn *pvconn; int error; - error = pvconn_open(name, 0, &pvconn, 0); + error = pvconn_open(name, 0, 0, &pvconn); if (!error) { pvconns[n_pvconns++] = pvconn; } else { @@ -772,12 +777,13 @@ static int snoop_preference(const struct ofconn *ofconn) { switch (ofconn->role) { - case NX_ROLE_MASTER: + case OFPCR12_ROLE_MASTER: return 3; - case NX_ROLE_OTHER: + case OFPCR12_ROLE_EQUAL: return 2; - case NX_ROLE_SLAVE: + case OFPCR12_ROLE_SLAVE: return 1; + case OFPCR12_ROLE_NOCHANGE: default: /* Shouldn't happen. */ return 0; @@ -817,26 +823,57 @@ ofconn_get_type(const struct ofconn *ofconn) return ofconn->type; } +/* If a master election id is defined, stores it into '*idp' and returns + * true. Otherwise, stores UINT64_MAX into '*idp' and returns false. */ +bool +ofconn_get_master_election_id(const struct ofconn *ofconn, uint64_t *idp) +{ + *idp = (ofconn->connmgr->master_election_id_defined + ? ofconn->connmgr->master_election_id + : UINT64_MAX); + return ofconn->connmgr->master_election_id_defined; +} + +/* Sets the master election id. + * + * Returns true if successful, false if the id is stale + */ +bool +ofconn_set_master_election_id(struct ofconn *ofconn, uint64_t id) +{ + if (ofconn->connmgr->master_election_id_defined + && + /* Unsigned difference interpreted as a two's complement signed + * value */ + (int64_t)(id - ofconn->connmgr->master_election_id) < 0) { + return false; + } + ofconn->connmgr->master_election_id = id; + ofconn->connmgr->master_election_id_defined = true; + + return true; +} + /* Returns the role configured for 'ofconn'. * - * The default role, if no other role has been set, is NX_ROLE_OTHER. */ -enum nx_role + * The default role, if no other role has been set, is OFPCR12_ROLE_EQUAL. */ +enum ofp12_controller_role ofconn_get_role(const struct ofconn *ofconn) { return ofconn->role; } -/* Changes 'ofconn''s role to 'role'. If 'role' is NX_ROLE_MASTER then any - * existing master is demoted to a slave. */ +/* Changes 'ofconn''s role to 'role'. If 'role' is OFPCR12_ROLE_MASTER then + * any existing master is demoted to a slave. */ void -ofconn_set_role(struct ofconn *ofconn, enum nx_role role) +ofconn_set_role(struct ofconn *ofconn, enum ofp12_controller_role role) { - if (role == NX_ROLE_MASTER) { + if (role == OFPCR12_ROLE_MASTER) { struct ofconn *other; HMAP_FOR_EACH (other, hmap_node, &ofconn->connmgr->controllers) { - if (other->role == NX_ROLE_MASTER) { - other->role = NX_ROLE_SLAVE; + if (other->role == OFPCR12_ROLE_MASTER) { + other->role = OFPCR12_ROLE_SLAVE; } } } @@ -1067,7 +1104,7 @@ ofconn_flush(struct ofconn *ofconn) struct ofmonitor *monitor, *next_monitor; int i; - ofconn->role = NX_ROLE_OTHER; + ofconn->role = OFPCR12_ROLE_EQUAL; ofconn_set_protocol(ofconn, OFPUTIL_P_NONE); ofconn->packet_in_format = NXPIF_OPENFLOW10; @@ -1152,6 +1189,7 @@ ofconn_destroy(struct ofconn *ofconn) hmap_remove(&ofconn->connmgr->controllers, &ofconn->hmap_node); } + hmap_destroy(&ofconn->monitors); list_remove(&ofconn->node); rconn_destroy(ofconn->rconn); rconn_packet_counter_destroy(ofconn->packet_in_counter); @@ -1265,8 +1303,8 @@ ofconn_receives_async_msg(const struct ofconn *ofconn, { const uint32_t *async_config; - assert(reason < 32); - assert((unsigned int) type < OAM_N_TYPES); + ovs_assert(reason < 32); + ovs_assert((unsigned int) type < OAM_N_TYPES); if (ofconn_get_protocol(ofconn) == OFPUTIL_P_NONE || !rconn_is_connected(ofconn->rconn)) { @@ -1282,7 +1320,7 @@ ofconn_receives_async_msg(const struct ofconn *ofconn, return false; } - async_config = (ofconn->role == NX_ROLE_SLAVE + async_config = (ofconn->role == OFPCR12_ROLE_SLAVE ? ofconn->slave_async_config : ofconn->master_async_config); if (!(async_config[type] & (1u << reason))) { @@ -1613,10 +1651,12 @@ connmgr_msg_in_hook(struct connmgr *mgr, const struct flow *flow, bool connmgr_may_set_up_flow(struct connmgr *mgr, const struct flow *flow, + uint32_t local_odp_port, const struct nlattr *odp_actions, size_t actions_len) { - return !mgr->in_band || in_band_rule_check(flow, odp_actions, actions_len); + return !mgr->in_band || in_band_rule_check(flow, local_odp_port, + odp_actions, actions_len); } /* Fail-open and in-band implementation. */ @@ -1665,7 +1705,7 @@ ofservice_create(struct connmgr *mgr, const char *target, struct pvconn *pvconn; int error; - error = pvconn_open(target, allowed_versions, &pvconn, dscp); + error = pvconn_open(target, allowed_versions, dscp, &pvconn); if (error) { return error; } @@ -1782,6 +1822,7 @@ void ofmonitor_destroy(struct ofmonitor *m) { if (m) { + minimatch_destroy(&m->match); hmap_remove(&m->ofconn->monitors, &m->ofconn_node); free(m); }