When an OpenFlow Bundle Add message is received, a bundle entry is created and the OpenFlow message embedded in the bundle add message is processed. If any error is encountered while processing the embedded message, the bundle entry is freed. The bundle entry free function assumes that the entry has been populated with a properly formatted OpenFlow message and performs some message specific cleanup actions . This assumption does not hold true in the error case and OVS crashes when performing the cleanup.
The fix is in case of errors, simply free the bundle entry without attempting to perform any embedded message cleanup Signed-off-by: Anju Thomas <anju.tho...@ericsson.com> --- ofproto/bundles.c | 2 +- ofproto/bundles.h | 18 ++++++++++-------- ofproto/ofproto.c | 19 ++++++++++++++++--- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/ofproto/bundles.c b/ofproto/bundles.c index 405ec8c..628ba0a 100644 --- a/ofproto/bundles.c +++ b/ofproto/bundles.c @@ -63,7 +63,7 @@ ofp_bundle_remove__(struct ofconn *ofconn, struct ofp_bundle *bundle) struct ofp_bundle_entry *msg; LIST_FOR_EACH_POP (msg, node, &bundle->msg_list) { - ofp_bundle_entry_free(msg); + ofp_bundle_entry_free(msg, true); } ofconn_remove_bundle(ofconn, bundle); diff --git a/ofproto/bundles.h b/ofproto/bundles.h index 806e853..7fc731c 100644 --- a/ofproto/bundles.h +++ b/ofproto/bundles.h @@ -60,7 +60,7 @@ struct ofp_bundle { static inline struct ofp_bundle_entry *ofp_bundle_entry_alloc( enum ofptype type, const struct ofp_header *oh); -static inline void ofp_bundle_entry_free(struct ofp_bundle_entry *); +static inline void ofp_bundle_entry_free(struct ofp_bundle_entry *, bool); enum ofperr ofp_bundle_open(struct ofconn *, uint32_t id, uint16_t flags, const struct ofp_header *); @@ -84,15 +84,17 @@ ofp_bundle_entry_alloc(enum ofptype type, const struct ofp_header *oh) } static inline void -ofp_bundle_entry_free(struct ofp_bundle_entry *entry) +ofp_bundle_entry_free(struct ofp_bundle_entry *entry, bool cleanup) { if (entry) { - if (entry->type == OFPTYPE_FLOW_MOD) { - ofproto_flow_mod_uninit(&entry->ofm); - } else if (entry->type == OFPTYPE_GROUP_MOD) { - ofputil_uninit_group_mod(&entry->ogm.gm); - } else if (entry->type == OFPTYPE_PACKET_OUT) { - ofproto_packet_out_uninit(&entry->opo); + if (cleanup) { + if (entry->type == OFPTYPE_FLOW_MOD) { + ofproto_flow_mod_uninit(&entry->ofm); + } else if (entry->type == OFPTYPE_GROUP_MOD) { + ofputil_uninit_group_mod(&entry->ogm.gm); + } else if (entry->type == OFPTYPE_PACKET_OUT) { + ofproto_packet_out_uninit(&entry->opo); + } } free(entry->msg); free(entry); diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 36f4c0b..bfbc043 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -7901,6 +7901,7 @@ handle_bundle_add(struct ofconn *ofconn, const struct ofp_header *oh) struct ofputil_bundle_add_msg badd; struct ofp_bundle_entry *bmsg; enum ofptype type; + bool cleanup=true; error = reject_slave_controller(ofconn); if (error) { @@ -7929,7 +7930,13 @@ handle_bundle_add(struct ofconn *ofconn, const struct ofp_header *oh) &ofproto->vl_mff_map, &ofpacts, u16_to_ofp(ofproto->max_ports), ofproto->n_tables); - if (!error) { + if (error) { + VLOG_WARN("Unable to parse OFPTYPE_FLOW_MOD message in " + "OFPTYPE_BUNDLE_ADD_MESSAGE(bundle idx = %x)" + "successfully", + badd.bundle_id); + cleanup=false; + } else { error = ofproto_flow_mod_init(ofproto, &bmsg->ofm, &fm, NULL); minimatch_destroy(&fm.match); } @@ -7944,7 +7951,13 @@ handle_bundle_add(struct ofconn *ofconn, const struct ofp_header *oh) error = ofputil_decode_packet_out(&po, badd.msg, ofproto_get_tun_tab(ofproto), &ofpacts); - if (!error) { + if (error) { + VLOG_WARN("Unable to parse OFPTYPE_PACKET_OUT message in " + "OFPTYPE_BUNDLE_ADD_MESSAGE(bundle idx = %x)" + "successfully", + badd.bundle_id); + cleanup=false; + } else { po.ofpacts = ofpbuf_steal_data(&ofpacts); /* Move to heap. */ error = ofproto_packet_out_init(ofproto, ofconn, &bmsg->opo, &po); } @@ -7960,7 +7973,7 @@ handle_bundle_add(struct ofconn *ofconn, const struct ofp_header *oh) } if (error) { - ofp_bundle_entry_free(bmsg); + ofp_bundle_entry_free(bmsg, cleanup); } return error; -- 1.9.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev