/* Takes care of necessary 'sw' activity, except for receiving packets (which * the caller must do). */ void lswitch_run(struct lswitch *sw) { int i; rconn_run(sw->rconn); if (sw->state == S_CONNECTING) { if (rconn_get_version(sw->rconn) != -1) { lswitch_handshake(sw); sw->state = S_FEATURES_REPLY; } return; } for (i = 0; i < 50; i++) { struct ofpbuf *msg; msg = rconn_recv(sw->rconn); if (!msg) { break; } lswitch_process_packet(sw, msg); ofpbuf_delete(msg); } }
static bool fail_open_local_packet_cb(struct relay *r, void *fail_open_) { struct fail_open_data *fail_open = fail_open_; if (rconn_is_connected(fail_open->remote_rconn) || !fail_open->lswitch) { return false; } else { lswitch_process_packet(fail_open->lswitch, fail_open->local_rconn, r->halves[HALF_LOCAL].rxbuf); rconn_run(fail_open->local_rconn); return true; } }
static void remote_rconn_run(struct datapath *dp, struct remote *r, uint8_t conn_id) { struct rconn *rconn; ofl_err error; size_t i; if (conn_id == MAIN_CONNECTION) rconn = r->rconn; else if (conn_id == PTIN_CONNECTION) rconn = r->rconn_aux; rconn_run(rconn); /* Do some remote processing, but cap it at a reasonable amount so that * other processing doesn't starve. */ for (i = 0; i < 50; i++) { if (!r->cb_dump) { struct ofpbuf *buffer; buffer = rconn_recv(rconn); if (buffer == NULL) { break; } else { struct ofl_msg_header *msg; struct sender sender = {.remote = r, .conn_id = conn_id}; error = ofl_msg_unpack(buffer->data, buffer->size, &msg, &(sender.xid), dp->exp); if (!error) { error = handle_control_msg(dp, msg, &sender); if (error) { ofl_msg_free(msg, dp->exp); } } if (error) { struct ofl_msg_error err = {{.type = OFPT_ERROR}, .type = ofl_error_type(error), .code = ofl_error_code(error), .data_length = buffer->size, .data = buffer->data}; dp_send_message(dp, (struct ofl_msg_header *)&err, &sender); } ofpbuf_delete(buffer); } } else { if (r->n_txq < TXQ_LIMIT) {