Example #1
0
/* Sends a packet to the controller in a packet_in message */
static void
send_packet_to_controller(struct pipeline *pl, struct packet *pkt, uint8_t table_id, uint8_t reason) {

    dp_buffers_save(pl->dp->buffers, pkt);
    
    {
        struct ofl_msg_packet_in msg =
                {{.type = OFPT_PACKET_IN},
                 .buffer_id   = pkt->buffer_id,
                 .total_len   = pkt->buffer->size,
                 .reason      = reason,
                 .table_id    = table_id,
                 .data_length = MIN(pl->dp->config.miss_send_len, pkt->buffer->size),
                 .data        = pkt->buffer->data};
        struct ofl_match *m = xmalloc (sizeof(struct ofl_match));
        ofl_structs_match_init(m);
        /* In this implementation the fields in_port and in_phy_port 
            always will be the same, because we are not considering logical
            ports                                 */
        ofl_structs_match_put32(m,OXM_OF_IN_PORT,pkt->in_port);
        ofl_structs_match_put32(m,OXM_OF_IN_PHY_PORT,pkt->in_port);
        
        msg.match = (struct ofl_match_header*)m;
        
        dp_send_message(pl->dp, (struct ofl_msg_header *)&msg, NULL);
    }
Example #2
0
/* Sends a packet to the controller in a packet_in message */
static void
send_packet_to_controller(struct pipeline *pl, struct packet *pkt, uint8_t table_id, uint8_t reason) {

    struct ofl_msg_packet_in msg;
    struct ofl_match *m;
    msg.header.type = OFPT_PACKET_IN;
    msg.total_len   = pkt->buffer->size;
    msg.reason      = reason;
    msg.table_id    = table_id;
    msg.cookie      = 0xffffffffffffffff;
    msg.data = pkt->buffer->data;
         
          
    /* A max_len of OFPCML_NO_BUFFER means that the complete
        packet should be sent, and it should not be buffered.*/
    if (pl->dp->config.miss_send_len != OFPCML_NO_BUFFER){
        dp_buffers_save(pl->dp->buffers, pkt);
        msg.buffer_id   = pkt->buffer_id;
        msg.data_length = MIN(pl->dp->config.miss_send_len, pkt->buffer->size);
    }else {
        msg.buffer_id   = OFP_NO_BUFFER;
        msg.data_length = pkt->buffer->size;
    }
 
    m = xmalloc (sizeof(struct ofl_match));
    ofl_structs_match_init(m);
    /* In this implementation the fields in_port and in_phy_port 
        always will be the same, because we are not considering logical
        ports                                 */
    ofl_structs_match_convert_pktf2oflm(&pkt->handle_std->match.match_fields, m);
    msg.match = (struct ofl_match_header*)m;
    dp_send_message(pl->dp, (struct ofl_msg_header *)&msg, NULL);
    ofl_structs_free_match((struct ofl_match_header* ) m, NULL); 
}
Example #3
0
void
flow_entry_remove(struct flow_entry *entry, uint8_t reason) {
    if (entry->send_removed) {
        flow_entry_update(entry);
        {
            struct ofl_msg_flow_removed msg =
                    {{.type = OFPT_FLOW_REMOVED},
                     .reason = reason,
                     .stats  = entry->stats};

            dp_send_message(entry->dp, (struct ofl_msg_header *)&msg, NULL);
        }
Example #4
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) {
/* 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;
}
/* Sends a packet to the controller in a packet_in message */
static void
send_packet_to_controller(struct pipeline *pl, struct packet *pkt, uint8_t table_id, uint8_t reason) {
    dp_buffers_save(pl->dp->buffers, pkt);

    {
        struct ofl_msg_packet_in msg =
                {{.type = OFPT_PACKET_IN},
                 .buffer_id   = pkt->buffer_id,
                 .in_port     = pkt->in_port,
                 .in_phy_port = pkt->in_port, // TODO: how to get phy port for v.port?
                 .total_len   = pkt->buffer->size,
                 .reason      = reason,
                 .table_id    = table_id,
                 .data_length = MIN(pl->dp->config.miss_send_len, pkt->buffer->size),
                 .data        = pkt->buffer->data};

        dp_send_message(pl->dp, (struct ofl_msg_header *)&msg, NULL);
    }
Example #7
0
static void port_status_check(struct datapath *dp) 
{
    #define OTN_INTERFACES_FILE "/tmp/otn_interfaces.ini"
    #define BUFFSIZE 1024
    uint32_t port_no;
    char command[BUFFSIZE];
    char buff[BUFFSIZE];
    struct sw_port *port = NULL;
    FILE *fp = NULL;
 
    for (port_no = 1; port_no < DP_MAX_PORTS; port_no++) {
        port = &dp->ports[port_no];
        if (port && port->conf) {
            sprintf(command, "grep %s " OTN_INTERFACES_FILE " | cut -d',' -f2 ",
                            port->conf->name);
            fp = popen(command, "r");
            memset(buff, 0, BUFFSIZE);
            if (fp == NULL) {
                printf(  "Failed to run command: %s", strerror(errno));
                continue;
            }
            if (fgets(buff, sizeof(buff), fp) != NULL) {
                buff[strlen(buff) - 1] = '\0';

                if ((strcmp(buff, "up") == 0) && !(port->conf->state & OFPPS_LIVE) ) {
                    port->conf->state = 0x00000000 | OFPPS_LIVE;
                } else if ((strcmp(buff, "down") == 0) && !(port->conf->state & OFPPS_LINK_DOWN)) {
                    port->conf->state = 0x00000000 | OFPPS_LINK_DOWN;
                } else {
                    goto close_fp;
                }

                /* Send the port status */
                struct ofl_msg_port_status status_msg =
                   {{.type = OFPT_PORT_STATUS},
                    .reason = OFPPR_MODIFY,
                    .desc = port->conf};
	        dp_send_message(dp, (struct ofl_msg_header *)&status_msg,
                                    NULL/*sender*/);
            }
Example #8
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;
}