static void ofconn_send(const struct ofconn *, struct ofpbuf *,
struct rconn_packet_counter *);
-static void do_send_packet_in(struct ofpbuf *, void *ofconn_);
+static void do_send_packet_ins(struct ofconn *, struct list *txq);
/* A listener for incoming OpenFlow "service" connections. */
struct ofservice {
size_t i;
for (i = 0; i < N_SCHEDULERS; i++) {
- pinsched_run(ofconn->schedulers[i], do_send_packet_in, ofconn);
+ struct list txq;
+
+ pinsched_run(ofconn->schedulers[i], &txq);
+ do_send_packet_ins(ofconn, &txq);
}
rconn_run(ofconn->rconn);
}
}
-/* pinsched callback for sending 'ofp_packet_in' on 'ofconn'. */
static void
-do_send_packet_in(struct ofpbuf *ofp_packet_in, void *ofconn_)
+do_send_packet_ins(struct ofconn *ofconn, struct list *txq)
{
- struct ofconn *ofconn = ofconn_;
+ struct ofpbuf *pin, *next_pin;
+
+ LIST_FOR_EACH_SAFE (pin, next_pin, list_node, txq) {
+ list_remove(&pin->list_node);
- rconn_send_with_limit(ofconn->rconn, ofp_packet_in,
- ofconn->packet_in_counter, 100);
+ rconn_send_with_limit(ofconn->rconn, pin,
+ ofconn->packet_in_counter, 100);
+ }
}
/* Takes 'pin', composes an OpenFlow packet-in message from it, and passes it
{
struct connmgr *mgr = ofconn->connmgr;
uint16_t controller_max_len;
+ struct list txq;
pin.up.total_len = pin.up.packet_len;
pin.up.packet_len = controller_max_len;
}
- /* Make OFPT_PACKET_IN and hand over to packet scheduler. It might
- * immediately call into do_send_packet_in() or it might buffer it for a
- * while (until a later call to pinsched_run()). */
+ /* Make OFPT_PACKET_IN and hand over to packet scheduler. */
pinsched_send(ofconn->schedulers[pin.up.reason == OFPR_NO_MATCH ? 0 : 1],
pin.up.fmd.in_port,
ofputil_encode_packet_in(&pin.up,
ofconn_get_protocol(ofconn),
ofconn->packet_in_format),
- do_send_packet_in, ofconn);
+ &txq);
+ do_send_packet_ins(ofconn, &txq);
}
\f
/* Fail-open settings. */