コード例 #1
0
ファイル: datapath.c プロジェクト: BiangHoo/ofsoftswitch13
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) {
コード例 #2
0
/* Handles barrier request messages. */
static ofl_err
handle_control_barrier_request(struct datapath *dp,
           struct ofl_msg_header *msg, const struct sender *sender) {

    /* Note: the implementation is single-threaded,
       so a barrier request can simply be replied. */
    struct ofl_msg_header reply =
            {.type = OFPT_BARRIER_REPLY};

    dp_send_message(dp, (struct ofl_msg_header *)&reply, sender);
    ofl_msg_free(msg, dp->exp);

    return 0;
}
コード例 #3
0
ファイル: ofp-read.c プロジェクト: CPqD/ofsoftswitch13
int main(int argc, char **argv)
{
	uint8_t *buf ,*buf0;
	size_t buf_len = 0;
	ofl_err err;
	struct ofl_msg_header *msg = NULL;
	uint32_t xid;
	FILE *msg_file;
	struct ofp_header *oh;

	if (argc < 2) {
		fprintf(stderr, "Expecting msg file.\n");
		return 1;
	}

	time_init();
	vlog_init();
	vlog_set_verbosity(NULL);

	msg_file = fopen(argv[1], "r");
	if (msg_file == NULL) {
		fprintf(stderr, "Cannot open msg file.\n");
		return 1;
	}
	buf_len = read_all(msg_file, &buf);
	buf0 = buf;

	while (buf_len > 0) {
		oh = (struct ofp_header *)buf;
		err = ofl_msg_unpack(buf, ntohs(oh->length), &msg, &xid, NULL);
		if (err == 0) {
			//printf("Success!\n");
			ofl_msg_print(stdout, msg, NULL);
			printf("\n\n");
			ofl_msg_free(msg, NULL);
		} else {
			free(buf);
			printf("Failed :-( error type: %d code %d\n", ofl_error_type(err), ofl_error_code(err));
			return 1;
		}
		buf_len -= ntohs(oh->length);
		buf += ntohs(oh->length);
	}
	free(buf0);
	return 0;
}
コード例 #4
0
ファイル: pipeline.c プロジェクト: ederlf/ofsoftswitch13
ofl_err
pipeline_handle_table_mod(struct pipeline *pl,
                          struct ofl_msg_table_mod *msg,
                          const struct sender *sender) {
                          
    if(sender->remote->role == OFPCR_ROLE_SLAVE)
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_IS_SLAVE);    
    
    if (msg->table_id == 0xff) {
        size_t i;

        for (i=0; i<PIPELINE_TABLES; i++) {
            pl->tables[i]->features->config = msg->config;
        }
    } else {
        pl->tables[msg->table_id]->features->config = msg->config;
    }

    ofl_msg_free((struct ofl_msg_header *)msg, pl->dp->exp);
    return 0;
}
コード例 #5
0
ファイル: ctrl.c プロジェクト: TrafficLab/ofss
/* Sends OpenFlow messages received from other threads via the appropriate functions.
 * Primarily used by DP to send messages to the controllers. */
static bool process_msg(void *ctrl_loop_, struct list_node *msg_) {
    struct ctrl_loop *ctrl_loop = (struct ctrl_loop *)ctrl_loop_;
    struct ctrl_msg *msg = (struct ctrl_msg *)msg_;

    if (msg->conn_id == CTRL_CONN_ALL) {
        size_t i;
        for (i=1; i<ctrl_loop->conns_num; i++) {
            ctrl_conn_send_msg(ctrl_loop->conns[i], msg->xid, msg->msg);
        }
    } else {
        if (ctrl_loop->conns[msg->conn_id] != NULL) {
            ctrl_conn_send_msg(ctrl_loop->conns[msg->conn_id], msg->xid, msg->msg);
        } else {
            logger_log(ctrl_loop->logger, LOG_WARN, "Request for message on non-existing connection.");
        }
    }
    ofl_msg_free(msg->msg, OFL_NO_EXP, NULL/*errbuf*/);
    free(msg);

    return true;
}
コード例 #6
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;
}