This will make implementing commit in ofproto.c easier. Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- ofproto/bundles.c | 116 ++++++++++++++--------------------------------------- ofproto/bundles.h | 19 ++++++++- ofproto/connmgr.c | 51 +++++++++++++++++++++-- ofproto/connmgr.h | 6 ++- 4 files changed, 98 insertions(+), 94 deletions(-)
diff --git a/ofproto/bundles.c b/ofproto/bundles.c index f6ad608..ebf8f7f 100644 --- a/ofproto/bundles.c +++ b/ofproto/bundles.c @@ -42,41 +42,6 @@ VLOG_DEFINE_THIS_MODULE(bundles); -enum bundle_state { - BS_OPEN, - BS_CLOSED -}; - -struct ofp_bundle { - struct hmap_node node; /* In struct ofconn's "bundles" hmap. */ - uint32_t id; - uint16_t flags; - enum bundle_state state; - - /* List of 'struct bundle_message's */ - struct ovs_list msg_list; -}; - -static uint32_t -bundle_hash(uint32_t id) -{ - return hash_int(id, 0); -} - -static struct ofp_bundle * -ofp_bundle_find(struct hmap *bundles, uint32_t id) -{ - struct ofp_bundle *bundle; - - HMAP_FOR_EACH_IN_BUCKET(bundle, node, bundle_hash(id), bundles) { - if (bundle->id == id) { - return bundle; - } - } - - return NULL; -} - static struct ofp_bundle * ofp_bundle_create(uint32_t id, uint16_t flags) { @@ -86,88 +51,68 @@ ofp_bundle_create(uint32_t id, uint16_t flags) bundle->id = id; bundle->flags = flags; + bundle->state = BS_OPEN; list_init(&bundle->msg_list); return bundle; } -static void -ofp_bundle_remove(struct ofconn *ofconn, struct ofp_bundle *bundle) +void +ofp_bundle_remove__(struct ofconn *ofconn, struct ofp_bundle *bundle) { struct ofp_bundle_entry *msg; - struct hmap *bundles; LIST_FOR_EACH_POP (msg, node, &bundle->msg_list) { ofp_bundle_entry_free(msg); } - bundles = ofconn_get_bundles(ofconn); - hmap_remove(bundles, &bundle->node); - + ofconn_remove_bundle(ofconn, bundle); free(bundle); } -void -ofp_bundle_remove_all(struct ofconn *ofconn) -{ - struct ofp_bundle *b, *next; - struct hmap *bundles; - - bundles = ofconn_get_bundles(ofconn); - - HMAP_FOR_EACH_SAFE (b, next, node, bundles) { - ofp_bundle_remove(ofconn, b); - } -} - enum ofperr ofp_bundle_open(struct ofconn *ofconn, uint32_t id, uint16_t flags) { - struct hmap *bundles; struct ofp_bundle *bundle; + enum ofperr error; - bundles = ofconn_get_bundles(ofconn); - bundle = ofp_bundle_find(bundles, id); + bundle = ofconn_get_bundle(ofconn, id); if (bundle) { VLOG_INFO("Bundle %x already exists.", id); - ofp_bundle_remove(ofconn, bundle); + ofp_bundle_remove__(ofconn, bundle); return OFPERR_OFPBFC_BAD_ID; } - /* XXX: Check the limit of open bundles */ - bundle = ofp_bundle_create(id, flags); - bundle->state = BS_OPEN; - - bundles = ofconn_get_bundles(ofconn); - hmap_insert(bundles, &bundle->node, bundle_hash(id)); + error = ofconn_insert_bundle(ofconn, bundle); + if (error) { + free(bundle); + } - return 0; + return error; } enum ofperr ofp_bundle_close(struct ofconn *ofconn, uint32_t id, uint16_t flags) { - struct hmap *bundles; struct ofp_bundle *bundle; - bundles = ofconn_get_bundles(ofconn); - bundle = ofp_bundle_find(bundles, id); + bundle = ofconn_get_bundle(ofconn, id); if (!bundle) { return OFPERR_OFPBFC_BAD_ID; } if (bundle->state == BS_CLOSED) { - ofp_bundle_remove(ofconn, bundle); + ofp_bundle_remove__(ofconn, bundle); return OFPERR_OFPBFC_BUNDLE_CLOSED; } if (bundle->flags != flags) { - ofp_bundle_remove(ofconn, bundle); + ofp_bundle_remove__(ofconn, bundle); return OFPERR_OFPBFC_BAD_FLAGS; } @@ -178,13 +123,11 @@ ofp_bundle_close(struct ofconn *ofconn, uint32_t id, uint16_t flags) enum ofperr ofp_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) { - struct hmap *bundles; struct ofp_bundle *bundle; enum ofperr error = 0; struct ofp_bundle_entry *msg; - bundles = ofconn_get_bundles(ofconn); - bundle = ofp_bundle_find(bundles, id); + bundle = ofconn_get_bundle(ofconn, id); if (!bundle) { return OFPERR_OFPBFC_BAD_ID; @@ -198,24 +141,22 @@ ofp_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) } } - ofp_bundle_remove(ofconn, bundle); + ofp_bundle_remove__(ofconn, bundle); return error; } enum ofperr ofp_bundle_discard(struct ofconn *ofconn, uint32_t id) { - struct hmap *bundles; struct ofp_bundle *bundle; - bundles = ofconn_get_bundles(ofconn); - bundle = ofp_bundle_find(bundles, id); + bundle = ofconn_get_bundle(ofconn, id); if (!bundle) { return OFPERR_OFPBFC_BAD_ID; } - ofp_bundle_remove(ofconn, bundle); + ofp_bundle_remove__(ofconn, bundle); return 0; } @@ -224,23 +165,24 @@ enum ofperr ofp_bundle_add_message(struct ofconn *ofconn, uint32_t id, uint16_t flags, struct ofp_bundle_entry *bmsg) { - struct hmap *bundles; struct ofp_bundle *bundle; - bundles = ofconn_get_bundles(ofconn); - bundle = ofp_bundle_find(bundles, id); + bundle = ofconn_get_bundle(ofconn, id); if (!bundle) { - bundle = ofp_bundle_create(id, flags); - bundle->state = BS_OPEN; + enum ofperr error; - bundles = ofconn_get_bundles(ofconn); - hmap_insert(bundles, &bundle->node, bundle_hash(id)); + bundle = ofp_bundle_create(id, flags); + error = ofconn_insert_bundle(ofconn, bundle); + if (error) { + free(bundle); + return error; + } } else if (bundle->state == BS_CLOSED) { - ofp_bundle_remove(ofconn, bundle); + ofp_bundle_remove__(ofconn, bundle); return OFPERR_OFPBFC_BUNDLE_CLOSED; } else if (flags != bundle->flags) { - ofp_bundle_remove(ofconn, bundle); + ofp_bundle_remove__(ofconn, bundle); return OFPERR_OFPBFC_BAD_FLAGS; } diff --git a/ofproto/bundles.h b/ofproto/bundles.h index a769cc9..353a893 100644 --- a/ofproto/bundles.h +++ b/ofproto/bundles.h @@ -22,7 +22,6 @@ #include <sys/types.h> #include "connmgr.h" -#include "list.h" #include "ofp-msgs.h" #include "ofp-util.h" @@ -42,6 +41,21 @@ struct ofp_bundle_entry { uint64_t ofpacts_stub[1024 / 8]; }; +enum bundle_state { + BS_OPEN, + BS_CLOSED +}; + +struct ofp_bundle { + struct hmap_node node; /* In struct ofconn's "bundles" hmap. */ + uint32_t id; + uint16_t flags; + enum bundle_state state; + + /* List of 'struct bundle_message's */ + struct ovs_list msg_list; +}; + static inline struct ofp_bundle_entry *ofp_bundle_entry_alloc( enum ofptype type, ovs_be32 xid); static inline void ofp_bundle_entry_free(struct ofp_bundle_entry *); @@ -52,7 +66,8 @@ enum ofperr ofp_bundle_commit(struct ofconn *, uint32_t id, uint16_t flags); enum ofperr ofp_bundle_discard(struct ofconn *, uint32_t id); enum ofperr ofp_bundle_add_message(struct ofconn *, uint32_t id, uint16_t flags, struct ofp_bundle_entry *); -void ofp_bundle_remove_all(struct ofconn *); + +void ofp_bundle_remove__(struct ofconn *ofconn, struct ofp_bundle *bundle); static inline struct ofp_bundle_entry * ofp_bundle_entry_alloc(enum ofptype type, ovs_be32 xid) diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 707385f..9851997 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -1168,13 +1168,56 @@ ofconn_report_flow_mod(struct ofconn *ofconn, } ofconn->last_op = now; } + +/* OpenFlow 1.4 bundles. */ + +static inline uint32_t +bundle_hash(uint32_t id) +{ + return hash_int(id, 0); +} -struct hmap * -ofconn_get_bundles(struct ofconn *ofconn) +struct ofp_bundle * +ofconn_get_bundle(struct ofconn *ofconn, uint32_t id) { - return &ofconn->bundles; + struct ofp_bundle *bundle; + + HMAP_FOR_EACH_IN_BUCKET(bundle, node, bundle_hash(id), &ofconn->bundles) { + if (bundle->id == id) { + return bundle; + } + } + + return NULL; } +enum ofperr +ofconn_insert_bundle(struct ofconn *ofconn, struct ofp_bundle *bundle) +{ + /* XXX: Check the limit of open bundles */ + + hmap_insert(&ofconn->bundles, &bundle->node, bundle_hash(bundle->id)); + + return 0; +} + +enum ofperr +ofconn_remove_bundle(struct ofconn *ofconn, struct ofp_bundle *bundle) +{ + hmap_remove(&ofconn->bundles, &bundle->node); + + return 0; +} + +static void +bundle_remove_all(struct ofconn *ofconn) +{ + struct ofp_bundle *b, *next; + + HMAP_FOR_EACH_SAFE (b, next, node, &ofconn->bundles) { + ofp_bundle_remove__(ofconn, b); + } +} /* Private ofconn functions. */ @@ -1300,7 +1343,7 @@ ofconn_destroy(struct ofconn *ofconn) hmap_remove(&ofconn->connmgr->controllers, &ofconn->hmap_node); } - ofp_bundle_remove_all(ofconn); + bundle_remove_all(ofconn); hmap_destroy(&ofconn->bundles); hmap_destroy(&ofconn->monitors); diff --git a/ofproto/connmgr.h b/ofproto/connmgr.h index 193afa8..0e1a5b1 100644 --- a/ofproto/connmgr.h +++ b/ofproto/connmgr.h @@ -156,7 +156,11 @@ void ofconn_send_error(const struct ofconn *, const struct ofp_header *request, enum ofperr ofconn_pktbuf_retrieve(struct ofconn *, uint32_t id, struct dp_packet **bufferp, ofp_port_t *in_port); -struct hmap *ofconn_get_bundles(struct ofconn *ofconn); +struct ofp_bundle; + +struct ofp_bundle *ofconn_get_bundle(struct ofconn *, uint32_t id); +enum ofperr ofconn_insert_bundle(struct ofconn *, struct ofp_bundle *); +enum ofperr ofconn_remove_bundle(struct ofconn *, struct ofp_bundle *); /* Logging flow_mod summaries. */ void ofconn_report_flow_mod(struct ofconn *, enum ofp_flow_mod_command); -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev