void
dp_run(struct datapath *dp) {
    time_t now;
    struct remote *r, *rn;
    size_t i;
    struct timeval time_check;
    uint64_t sched_sec;
    uint32_t sched_nsec;

    if (now != dp->last_timeout) {
        dp->last_timeout = now;
        meter_table_add_tokens(dp->meters);
        pipeline_timeout(dp->pipeline);
    }

    //TIME_EXTENTION_EXP
    gettimeofday(&time_check, 0);
    if((bundle_time_ctl.ctl.flags!=0) & (!bundle_time_ctl.discard) ){
    	sched_sec  = bundle_time_ctl.sched_time.seconds;
        sched_nsec = bundle_time_ctl.sched_time.nanoseconds;

    	if((time_check.tv_sec >sched_sec) || ((time_check.tv_sec == sched_sec) && ((time_check.tv_usec*1000) >= sched_nsec))){
    			printf("Commit Bundle in time sched :%lu.%09u\n",sched_sec,sched_nsec);
				printf("Commit Bundle in time actual:%u.%09u\n",time_check.tv_sec,time_check.tv_usec*1000);
	    		bundle_time_ctl.commiting_now=1;
	    		    // shutting down only time flag
					bundle_time_ctl.ctl.flags=bundle_time_ctl.ctl.flags & 0xFFFB;
					struct sender sender = {.remote = bundle_time_ctl.remote, .conn_id = bundle_time_ctl.conn_id , .xid = bundle_time_ctl.xid};
					handle_control_msg(dp, &bundle_time_ctl.ctl, &sender);
				bundle_time_ctl.commiting_now=0;
    		}
    }
示例#2
0
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) {
示例#3
0
/* Commit operation. */
static ofl_err
bundle_commit(struct datapath *dp,
              struct bundle_table *table,
              uint32_t bundle_id,
              uint16_t flags,
              const struct sender *sender) {
    struct bundle_table_entry *entry;
    struct bundle_message *bundle_msg;
    struct ofl_msg_header *msg;
    uint32_t xid;
    ofl_err error;
    ofl_err last_error = ofl_error(OFPET_BUNDLE_FAILED, OFPBFC_BAD_ID);

    /* Find and process commit operation for bundle ID */
    entry = bundle_table_entry_find(table, bundle_id);
    if (entry != NULL) {
        /* Ensure flags are consistent with flags specified previously */
        if (entry->flags != flags) {
            last_error = ofl_error(OFPET_BUNDLE_FAILED, OFPBFC_BAD_FLAGS);
        } else {
            /* Save state in case failure occurs */
            last_error = 0;

            dp_save_state(dp);

            /* Commit all messages in bundle, stopping at first error */
            LIST_FOR_EACH (bundle_msg, struct bundle_message, node, &entry->bundle_message_list) {
                VLOG_DBG_RL(LOG_MODULE, &rl, "Commit of message with type %u and length %u\n",
                       bundle_msg->message->type,
                       ntohs(bundle_msg->message->length));

                error = ofl_msg_unpack((uint8_t *)bundle_msg->message,
                                       ntohs(bundle_msg->message->length),
                                       &msg, &xid, dp->exp);

                if (!error) {
                    /* This prototype only properly supports bundling of
                     * messages that do not generate replies (other than
                     * error replies).  TODO: keep replies in a holding
                     * area and only release them to the controller when
                     * the commit succeeds. */
                    error = handle_control_msg(dp, msg, sender);

                    if (error) {
                        ofl_msg_free(msg, dp->exp);
                    }
                }

                if (error) {
                    last_error = error;
                    break;
                }
            }

            /* Restore state if failures occurred */
            if (last_error) {
                dp_restore_state(dp);
            } else {
                /* TODO free memory used to save state without restoring
                 * (not required currently as variables used to save/restore
                 * state are re-used) */
            }

	    /* We need to generate the error ourselves. The spec say that
	     * the error need to refer to the offending message in the budle.
	     * If we just return the error code, the error message would refer
	     * to the commit message. */
            if (last_error) {
                struct sender orig_sender = {.remote = sender->remote,
					     .conn_id = sender->conn_id,
					     .xid = xid};

		struct ofl_msg_error orig_err =
                            {{.type = OFPT_ERROR},
                             .type = ofl_error_type(last_error),
                             .code = ofl_error_code(last_error),
                             .data_length = ntohs(bundle_msg->message->length),
                             .data        = (uint8_t *)bundle_msg->message};
		dp_send_message(dp, (struct ofl_msg_header *)&orig_err, &orig_sender);
		/* Trigger second error message. */
		last_error = ofl_error(OFPET_BUNDLE_FAILED, OFPBFC_MSG_FAILED);
	    }
        }

        /* Whether or not commit succeeded: free entry for bundle ID */
        bundle_table_entry_destroy(entry);
    }

    return last_error;
}