Acked-by: Jarno Rajahalme <ja...@ovn.org> > On Jan 18, 2016, at 11:27 PM, Ben Pfaff <b...@ovn.org> wrote: > > An upcoming commit will add another kind of asynchronous message that > should be handled in the same way as packet-ins. > > Signed-off-by: Ben Pfaff <b...@ovn.org> > --- > ofproto/connmgr.c | 29 ++++++++++++-------- > ofproto/connmgr.h | 20 +++++++++----- > ofproto/fail-open.c | 28 +++++++++++--------- > ofproto/ofproto-dpif-xlate.c | 32 +++++++++++----------- > ofproto/ofproto-dpif.c | 63 +++++++++++++++++++++----------------------- > ofproto/ofproto-dpif.h | 6 ++--- > 6 files changed, 98 insertions(+), 80 deletions(-) > > diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c > index fb8f251..5161a15 100644 > --- a/ofproto/connmgr.c > +++ b/ofproto/connmgr.c > @@ -1653,31 +1653,31 @@ connmgr_send_flow_removed(struct connmgr *mgr, > * > * The caller doesn't need to fill in pin->buffer_id or pin->total_len. */ > void > -connmgr_send_packet_in(struct connmgr *mgr, > - const struct ofproto_packet_in *pin) > +connmgr_send_async_msg(struct connmgr *mgr, > + const struct ofproto_async_msg *am) > { > struct ofconn *ofconn; > > LIST_FOR_EACH (ofconn, node, &mgr->all_conns) { > enum ofputil_protocol protocol = ofconn_get_protocol(ofconn); > if (protocol == OFPUTIL_P_NONE || !rconn_is_connected(ofconn->rconn) > - || ofconn->controller_id != pin->controller_id > - || !ofconn_receives_async_msg(ofconn, OAM_PACKET_IN, > - pin->up.reason)) { > + || ofconn->controller_id != am->controller_id > + || !ofconn_receives_async_msg(ofconn, am->oam, > + am->pin.up.reason)) { > continue; > } > > struct ofpbuf *msg = ofputil_encode_packet_in( > - &pin->up, protocol, ofconn->packet_in_format, > - pin->max_len >= 0 ? pin->max_len : ofconn->miss_send_len, > + &am->pin.up, protocol, ofconn->packet_in_format, > + am->pin.max_len >= 0 ? am->pin.max_len : ofconn->miss_send_len, > ofconn->pktbuf); > > struct ovs_list txq; > - bool is_miss = (pin->up.reason == OFPR_NO_MATCH || > - pin->up.reason == OFPR_EXPLICIT_MISS || > - pin->up.reason == OFPR_IMPLICIT_MISS); > + bool is_miss = (am->pin.up.reason == OFPR_NO_MATCH || > + am->pin.up.reason == OFPR_EXPLICIT_MISS || > + am->pin.up.reason == OFPR_IMPLICIT_MISS); > pinsched_send(ofconn->schedulers[is_miss], > - pin->up.flow_metadata.flow.in_port.ofp_port /* XXX */, > + am->pin.up.flow_metadata.flow.in_port.ofp_port /* XXX > */, > msg, &txq); > do_send_packet_ins(ofconn, &txq); > } > @@ -2243,3 +2243,10 @@ ofmonitor_wait(struct connmgr *mgr) > } > ovs_mutex_unlock(&ofproto_mutex); > } > + > +void > +ofproto_async_msg_free(struct ofproto_async_msg *am) > +{ > + free(CONST_CAST(void *, am->pin.up.packet)); > + free(am); > +} > diff --git a/ofproto/connmgr.h b/ofproto/connmgr.h > index ced6a68..fb7573e 100644 > --- a/ofproto/connmgr.h > +++ b/ofproto/connmgr.h > @@ -54,13 +54,21 @@ enum ofconn_type { > OFCONN_SERVICE /* A service connection, e.g. "ovs-ofctl". */ > }; > > -/* A packet_in, with extra members to assist in queuing and routing it. */ > -struct ofproto_packet_in { > - struct ofputil_packet_in up; > +/* An asynchronous message that might need to be queued between threads. */ > +struct ofproto_async_msg { > struct ovs_list list_node; /* For queuing. */ > uint16_t controller_id; /* Controller ID to send to. */ > - int max_len; /* From action, or -1 if none. */ > + > + enum ofputil_async_msg_type oam; > + union { > + /* OAM_PACKET_IN. */ > + struct { > + struct ofputil_packet_in up; > + int max_len; /* From action, or -1 if none. */ > + } pin; > + }; > }; > +void ofproto_async_msg_free(struct ofproto_async_msg *); > > /* Basics. */ > struct connmgr *connmgr_create(struct ofproto *ofproto, > @@ -140,8 +148,8 @@ void connmgr_send_port_status(struct connmgr *, struct > ofconn *source, > const struct ofputil_phy_port *, uint8_t > reason); > void connmgr_send_flow_removed(struct connmgr *, > const struct ofputil_flow_removed *); > -void connmgr_send_packet_in(struct connmgr *, > - const struct ofproto_packet_in *); > +void connmgr_send_async_msg(struct connmgr *, > + const struct ofproto_async_msg *); > void ofconn_send_role_status(struct ofconn *ofconn, uint32_t role, > uint8_t reason); > > diff --git a/ofproto/fail-open.c b/ofproto/fail-open.c > index 5a692bf..a28acef 100644 > --- a/ofproto/fail-open.c > +++ b/ofproto/fail-open.c > @@ -125,19 +125,23 @@ send_bogus_packet_ins(struct fail_open *fo) > eth_addr_nicira_random(&mac); > compose_rarp(&b, mac); > > - struct ofproto_packet_in pin = { > - .up = { > - .packet = dp_packet_data(&b), > - .len = dp_packet_size(&b), > - .flow_metadata = MATCH_CATCHALL_INITIALIZER, > - .flow_metadata.flow.in_port.ofp_port = OFPP_LOCAL, > - .flow_metadata.wc.masks.in_port.ofp_port = > u16_to_ofp(UINT16_MAX), > - .reason = OFPR_NO_MATCH, > - .cookie = OVS_BE64_MAX, > - }, > - .max_len = UINT16_MAX, > + struct ofproto_async_msg am = { > + .oam = OAM_PACKET_IN, > + .pin = { > + .up = { > + .packet = dp_packet_data(&b), > + .len = dp_packet_size(&b), > + .flow_metadata = MATCH_CATCHALL_INITIALIZER, > + .flow_metadata.flow.in_port.ofp_port = OFPP_LOCAL, > + .flow_metadata.wc.masks.in_port.ofp_port > + = u16_to_ofp(UINT16_MAX), > + .reason = OFPR_NO_MATCH, > + .cookie = OVS_BE64_MAX, > + }, > + .max_len = UINT16_MAX, > + } > }; > - connmgr_send_packet_in(fo->connmgr, &pin); > + connmgr_send_async_msg(fo->connmgr, &am); > > dp_packet_uninit(&b); > } > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c > index c377963..2ee647b 100644 > --- a/ofproto/ofproto-dpif-xlate.c > +++ b/ofproto/ofproto-dpif-xlate.c > @@ -3568,7 +3568,6 @@ execute_controller_action(struct xlate_ctx *ctx, int > len, > enum ofp_packet_in_reason reason, > uint16_t controller_id) > { > - struct ofproto_packet_in *pin; > struct dp_packet *packet; > > ctx->xout->slow |= SLOW_CONTROLLER; > @@ -3592,21 +3591,24 @@ execute_controller_action(struct xlate_ctx *ctx, int > len, > > size_t packet_len = dp_packet_size(packet); > > - pin = xmalloc(sizeof *pin); > - *pin = (struct ofproto_packet_in) { > + struct ofproto_async_msg *am = xmalloc(sizeof *am); > + *am = (struct ofproto_async_msg) { > .controller_id = controller_id, > - .up = { > - .packet = dp_packet_steal_data(packet), > - .len = packet_len, > - .reason = reason, > - .table_id = ctx->table_id, > - .cookie = ctx->rule_cookie, > + .oam = OAM_PACKET_IN, > + .pin = { > + .up = { > + .packet = dp_packet_steal_data(packet), > + .len = packet_len, > + .reason = reason, > + .table_id = ctx->table_id, > + .cookie = ctx->rule_cookie, > + }, > + .max_len = len, > }, > - .max_len = len, > }; > - flow_get_metadata(&ctx->xin->flow, &pin->up.flow_metadata); > + flow_get_metadata(&ctx->xin->flow, &am->pin.up.flow_metadata); > > - ofproto_dpif_send_packet_in(ctx->xbridge->ofproto, pin); > + ofproto_dpif_send_async_msg(ctx->xbridge->ofproto, am); > dp_packet_delete(packet); > } > > @@ -4141,8 +4143,8 @@ recirc_put_unroll_xlate(struct xlate_ctx *ctx) > > /* Copy remaining actions to the action_set to be executed after > recirculation. > * UNROLL_XLATE action is inserted, if not already done so, before actions > that > - * may generate PACKET_INs from the current table and without matching > another > - * rule. */ > + * may generate asynchronous messages from the current table and without > + * matching another rule. */ > static void > recirc_unroll_actions(const struct ofpact *ofpacts, size_t ofpacts_len, > struct xlate_ctx *ctx) > @@ -4151,7 +4153,7 @@ recirc_unroll_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { > switch (a->type) { > - /* May generate PACKET INs. */ > + /* May generate asynchronous messages. */ > case OFPACT_OUTPUT_REG: > case OFPACT_GROUP: > case OFPACT_OUTPUT: > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c > index fbb392f..3281eaa 100644 > --- a/ofproto/ofproto-dpif.c > +++ b/ofproto/ofproto-dpif.c > @@ -341,9 +341,9 @@ struct ofproto_dpif { > uint64_t change_seq; /* Connectivity status changes. */ > > /* Work queues. */ > - struct guarded_list pins; /* Contains "struct ofputil_packet_in"s. > */ > - struct seq *pins_seq; /* For notifying 'pins' reception. */ > - uint64_t pins_seqno; > + struct guarded_list ams; /* Contains "struct ofproto_async_msgs"s. > */ > + struct seq *ams_seq; /* For notifying 'ams' reception. */ > + uint64_t ams_seqno; > }; > > /* All existing ofproto_dpif instances, indexed by ->up.name. */ > @@ -400,20 +400,19 @@ ofproto_dpif_flow_mod(struct ofproto_dpif *ofproto, > ofproto_flow_mod(&ofproto->up, &ofm); > } > > -/* Appends 'pin' to the queue of "packet ins" to be sent to the controller. > - * Takes ownership of 'pin' and pin->packet. */ > +/* Appends 'am' to the queue of asynchronous messages to be sent to the > + * controller. Takes ownership of 'am' and any data it points to. */ > void > -ofproto_dpif_send_packet_in(struct ofproto_dpif *ofproto, > - struct ofproto_packet_in *pin) > +ofproto_dpif_send_async_msg(struct ofproto_dpif *ofproto, > + struct ofproto_async_msg *am) > { > - if (!guarded_list_push_back(&ofproto->pins, &pin->list_node, 1024)) { > + if (!guarded_list_push_back(&ofproto->ams, &am->list_node, 1024)) { > COVERAGE_INC(packet_in_overflow); > - free(CONST_CAST(void *, pin->up.packet)); > - free(pin); > + ofproto_async_msg_free(am); > } > > /* Wakes up main thread for packet-in I/O. */ > - seq_change(ofproto->pins_seq); > + seq_change(ofproto->ams_seq); > } > > /* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the > @@ -1329,7 +1328,7 @@ construct(struct ofproto *ofproto_) > ovs_mutex_init_adaptive(&ofproto->stats_mutex); > ovs_mutex_init(&ofproto->vsp_mutex); > > - guarded_list_init(&ofproto->pins); > + guarded_list_init(&ofproto->ams); > > hmap_init(&ofproto->vlandev_map); > hmap_init(&ofproto->realdev_vid_map); > @@ -1339,8 +1338,8 @@ construct(struct ofproto *ofproto_) > sset_init(&ofproto->port_poll_set); > ofproto->port_poll_errno = 0; > ofproto->change_seq = 0; > - ofproto->pins_seq = seq_create(); > - ofproto->pins_seqno = seq_read(ofproto->pins_seq); > + ofproto->ams_seq = seq_create(); > + ofproto->ams_seqno = seq_read(ofproto->ams_seq); > > > SHASH_FOR_EACH_SAFE (node, next, &init_ofp_ports) { > @@ -1444,10 +1443,10 @@ static void > destruct(struct ofproto *ofproto_) > { > struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); > - struct ofproto_packet_in *pin; > + struct ofproto_async_msg *am; > struct rule_dpif *rule; > struct oftable *table; > - struct ovs_list pins; > + struct ovs_list ams; > > ofproto->backer->need_revalidate = REV_RECONFIGURE; > xlate_txn_start(); > @@ -1467,12 +1466,11 @@ destruct(struct ofproto *ofproto_) > } > ofproto_group_delete_all(&ofproto->up); > > - guarded_list_pop_all(&ofproto->pins, &pins); > - LIST_FOR_EACH_POP (pin, list_node, &pins) { > - free(CONST_CAST(void *, pin->up.packet)); > - free(pin); > + guarded_list_pop_all(&ofproto->ams, &ams); > + LIST_FOR_EACH_POP (am, list_node, &ams) { > + ofproto_async_msg_free(am); > } > - guarded_list_destroy(&ofproto->pins); > + guarded_list_destroy(&ofproto->ams); > > recirc_free_ofproto(ofproto, ofproto->up.name); > > @@ -1495,7 +1493,7 @@ destruct(struct ofproto *ofproto_) > ovs_mutex_destroy(&ofproto->stats_mutex); > ovs_mutex_destroy(&ofproto->vsp_mutex); > > - seq_destroy(ofproto->pins_seq); > + seq_destroy(ofproto->ams_seq); > > close_dpif_backer(ofproto->backer); > } > @@ -1514,23 +1512,22 @@ run(struct ofproto *ofproto_) > mcast_snooping_mdb_flush(ofproto->ms); > } > > - /* Always updates the ofproto->pins_seqno to avoid frequent wakeup during > + /* Always updates the ofproto->ams_seqno to avoid frequent wakeup during > * flow restore. Even though nothing is processed during flow restore, > - * all queued 'pins' will be handled immediately when flow restore > + * all queued 'ams' will be handled immediately when flow restore > * completes. */ > - ofproto->pins_seqno = seq_read(ofproto->pins_seq); > + ofproto->ams_seqno = seq_read(ofproto->ams_seq); > > /* Do not perform any periodic activity required by 'ofproto' while > * waiting for flow restore to complete. */ > if (!ofproto_get_flow_restore_wait()) { > - struct ofproto_packet_in *pin; > - struct ovs_list pins; > + struct ofproto_async_msg *am; > + struct ovs_list ams; > > - guarded_list_pop_all(&ofproto->pins, &pins); > - LIST_FOR_EACH_POP (pin, list_node, &pins) { > - connmgr_send_packet_in(ofproto->up.connmgr, pin); > - free(CONST_CAST(void *, pin->up.packet)); > - free(pin); > + guarded_list_pop_all(&ofproto->ams, &ams); > + LIST_FOR_EACH_POP (am, list_node, &ams) { > + connmgr_send_async_msg(ofproto->up.connmgr, am); > + ofproto_async_msg_free(am); > } > } > > @@ -1641,7 +1638,7 @@ wait(struct ofproto *ofproto_) > } > > seq_wait(udpif_dump_seq(ofproto->backer->udpif), ofproto->dump_seq); > - seq_wait(ofproto->pins_seq, ofproto->pins_seqno); > + seq_wait(ofproto->ams_seq, ofproto->ams_seqno); > } > > static void > diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h > index dab422a..61a28ea 100644 > --- a/ofproto/ofproto-dpif.h > +++ b/ofproto/ofproto-dpif.h > @@ -33,8 +33,8 @@ > union user_action_cookie; > struct dpif_flow_stats; > struct ofproto; > +struct ofproto_async_msg; > struct ofproto_dpif; > -struct ofproto_packet_in; > struct ofport_dpif; > struct dpif_backer; > struct OVS_LOCKABLE rule_dpif; > @@ -157,8 +157,8 @@ int ofproto_dpif_execute_actions__(struct ofproto_dpif *, > const struct flow *, > struct rule_dpif *, const struct ofpact *, > size_t ofpacts_len, int recurse, > int resubmits, struct dp_packet *); > -void ofproto_dpif_send_packet_in(struct ofproto_dpif *, > - struct ofproto_packet_in *); > +void ofproto_dpif_send_async_msg(struct ofproto_dpif *, > + struct ofproto_async_msg *); > bool ofproto_dpif_wants_packet_in_on_miss(struct ofproto_dpif *); > int ofproto_dpif_send_packet(const struct ofport_dpif *, struct dp_packet *); > void ofproto_dpif_flow_mod(struct ofproto_dpif *, > -- > 2.1.3 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev
_______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev