static ofl_err
ofl_msg_unpack_flow_mod(struct ofp_header *src, size_t *len, struct ofl_msg_header **msg, struct ofl_exp *exp) {
    struct ofp_flow_mod *sm;
    struct ofl_msg_flow_mod *dm;
    struct ofp_instruction *inst;
    ofl_err error;
    size_t i;

    if (*len < (sizeof(struct ofp_flow_mod) - sizeof(struct ofp_match))) {
        OFL_LOG_WARN(LOG_MODULE, "Received FLOW_MOD message has invalid length (%zu).", *len);
        return ofl_error(OFPET_BAD_ACTION, OFPBRC_BAD_LEN);
    }
    *len -= (sizeof(struct ofp_flow_mod) - sizeof(struct ofp_match));

    sm = (struct ofp_flow_mod *)src;
    dm = (struct ofl_msg_flow_mod *)malloc(sizeof(struct ofl_msg_flow_mod));

    dm->cookie =       ntoh64(sm->cookie);
    dm->cookie_mask =  ntoh64(sm->cookie_mask);
    dm->table_id =            sm->table_id;
    dm->command =             (enum ofp_flow_mod_command)sm->command;
    dm->idle_timeout = ntohs( sm->idle_timeout);
    dm->hard_timeout = ntohs( sm->hard_timeout);
    dm->priority =     ntohs( sm->priority);
    dm->buffer_id =    ntohl( sm->buffer_id);
    dm->out_port =     ntohl( sm->out_port);
    dm->out_group =    ntohl( sm->out_group);
    dm->flags =        ntohs( sm->flags);

    error = ofl_structs_match_unpack(&(sm->match), len, &(dm->match), exp);

    if (error) {
        free(dm);
        return error;
    }

    error = ofl_utils_count_ofp_instructions(&(sm->instructions), *len, &dm->instructions_num);
    if (error) {
        ofl_structs_free_match(dm->match, exp);
        free(dm);
        return error;
    }

    dm->instructions = (struct ofl_instruction_header **)malloc(dm->instructions_num * sizeof(struct ofl_instruction_header *));
    inst = sm->instructions;
    for (i = 0; i < dm->instructions_num; i++) {
        error = ofl_structs_instructions_unpack(inst, len, &(dm->instructions[i]), exp);
        if (error) {
            OFL_UTILS_FREE_ARR_FUN2(dm->instructions, i,
                    ofl_structs_free_instruction, exp);
            ofl_structs_free_match(dm->match, exp);
            free(dm);
            return error;
        }
        inst = (struct ofp_instruction *)((uint8_t *)inst + ntohs(inst->len));
    }

    *msg = (struct ofl_msg_header *)dm;
    return 0;
}
Exemple #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); 
}
Exemple #3
0
static int
ofl_msg_free_stats_request(struct ofl_msg_stats_request_header *msg, struct ofl_exp *exp, char *errbuf) {
    switch (msg->type) {
        case OFPST_DESC: {
            break;
        }
        case OFPST_FLOW:
        case OFPST_AGGREGATE: {
            ofl_structs_free_match(((struct ofl_msg_stats_request_flow *)msg)->match, exp, errbuf);
            //TODO error
            break;
        }
        case OFPST_TABLE:
        case OFPST_PORT:
        case OFPST_QUEUE:
        case OFPST_GROUP:
        case OFPST_GROUP_DESC:
            break;
        case OFPST_EXPERIMENTER: {
            if (exp == NULL || exp->stats == NULL || exp->stats->req_free == NULL) {
                if (errbuf != NULL) {
                    snprintf(errbuf, OFL_ERRBUF_SIZE, "Trying to free EXPERIMENTER stats request, but no callback was given.");
                }
                free(msg);
                return -1;
            }
            exp->stats->req_free(msg);
            return 0;
        }
        default:
            return -1;
    }
    free(msg);
    return 0;
}
int
ofl_msg_free_flow_mod(struct ofl_msg_flow_mod *msg, bool with_match, bool with_instructions, struct ofl_exp *exp) {
    if (with_match) {
        ofl_structs_free_match(msg->match, exp);
    }
    if (with_instructions) {
        OFL_UTILS_FREE_ARR_FUN2(msg->instructions, msg->instructions_num,
                                ofl_structs_free_instruction, exp);
    }

    free(msg);
    return 0;
}
Exemple #5
0
int
ofl_msg_free_flow_mod(struct ofl_msg_flow_mod *msg, bool with_match, bool with_instructions, struct ofl_exp *exp, char *errbuf) {
    if (with_match) {
        ofl_structs_free_match(msg->match, exp, errbuf);
        //TODO error
    }
    if (with_instructions) {
        OFL_UTILS_FREE_ARR_FUN3(msg->instructions, msg->instructions_num,
                                ofl_structs_free_instruction, exp, errbuf);
        //TODO error
    }

    free(msg);
    return 0;
}
static int
ofl_msg_free_multipart_request(struct ofl_msg_multipart_request_header *msg, struct ofl_exp *exp) {
    switch (msg->type) {
        case OFPMP_DESC: {
            break;
        }
        case OFPMP_FLOW:
        case OFPMP_AGGREGATE: {
            ofl_structs_free_match(((struct ofl_msg_multipart_request_flow *)msg)->match, exp);
            break;
        }
        case OFPMP_TABLE:
        case OFPMP_PORT_STATS :
        case OFPMP_QUEUE:
        case OFPMP_GROUP:
        case OFPMP_GROUP_DESC:
        case OFPMP_GROUP_FEATURES:
        case OFPMP_METER:
        case OFPMP_METER_CONFIG:
        case OFPMP_METER_FEATURES:
            break;
        case OFPMP_TABLE_FEATURES:{
            struct ofl_msg_multipart_request_table_features *m = (struct ofl_msg_multipart_request_table_features *)msg;
            OFL_UTILS_FREE_ARR_FUN2(m->table_features, m->tables_num,
                                    ofl_structs_free_table_features, exp);
            break; 
        }
        case OFPMP_PORT_DESC:
            break;
        case OFPMP_EXPERIMENTER: {
            if (exp == NULL || exp->stats == NULL || exp->stats->req_free == NULL) {
                OFL_LOG_WARN(LOG_MODULE, "Trying to free EXPERIMENTER stats request, but no callback was given.");
                break;
            }
            exp->stats->req_free(msg);
            return 0;
        }
        default:
            return -1;
    }
    free(msg);
    return 0;
}
Exemple #7
0
ofl_err
ofl_structs_flow_stats_unpack(struct ofp_flow_stats *src, size_t *len, struct ofl_flow_stats **dst, struct ofl_exp *exp, char *errbuf) {
    struct ofl_flow_stats *s;
    struct ofp_instruction *inst;
    ofl_err error;
    size_t slen;
    size_t i;

    if (*len < (sizeof(struct ofp_flow_stats) - sizeof(struct ofp_match))) {
        if (errbuf != NULL) {
            snprintf(errbuf, OFL_ERRBUF_SIZE, "Received flow stats has invalid length (%zu).", *len);
        }
        return ofl_error(OFPET_BAD_ACTION, OFPBRC_BAD_LEN);
    }

    if (*len < ntohs(src->length)) {
        if (errbuf != NULL) {
            snprintf(errbuf, OFL_ERRBUF_SIZE, "Received flow stats reply has invalid length (set to %u, but only %zu received).", ntohs(src->length), *len);
        }
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }

    if (src->table_id == 0xff) {
        if (errbuf != NULL) {
            char *ts = ofl_table_to_string(src->table_id);
            snprintf(errbuf, OFL_ERRBUF_SIZE, "Received flow stats has invalid table_id (%s).", ts);
            free(ts);
        }
        return ofl_error(OFPET_BAD_ACTION, OFPBRC_BAD_LEN);
    }

    slen = ntohs(src->length) - (sizeof(struct ofp_flow_stats) - sizeof(struct ofp_match));

    s = (struct ofl_flow_stats *)malloc(sizeof(struct ofl_flow_stats));

    s->table_id =             src->table_id;
    s->duration_sec =  ntohl( src->duration_sec);
    s->duration_nsec = ntohl( src->duration_nsec);
    s->priority =      ntohs( src->priority);
    s->idle_timeout =  ntohs( src->idle_timeout);
    s->hard_timeout =  ntohs( src->hard_timeout);
    s->cookie =        ntoh64(src->cookie);
    s->packet_count =  ntoh64(src->packet_count);
    s->byte_count =    ntoh64(src->byte_count);

    error = ofl_structs_match_unpack(&(src->match), &slen, &(s->match), exp, errbuf);
    if (error) {
        free(s);
        return error;
    }

    error = ofl_utils_count_ofp_instructions(src->instructions, slen, &s->instructions_num, errbuf);
    if (error) {
        ofl_structs_free_match(s->match, exp, NULL);
        free(s);
        return error;
    }
    s->instructions = (struct ofl_instruction_header **)malloc(s->instructions_num * sizeof(struct ofl_instruction_header *));

    inst = src->instructions;
    for (i = 0; i < s->instructions_num; i++) {
        error = ofl_structs_instructions_unpack(inst, &slen, &(s->instructions[i]), exp, errbuf);
        if (error) {
            OFL_UTILS_FREE_ARR_FUN3(s->instructions, i,
                                    ofl_structs_free_instruction, exp, errbuf);
            free(s);
            return error;
        }
        inst = (struct ofp_instruction *)((uint8_t *)inst + ntohs(inst->len));
    }

    if (slen != 0) {
        *len = *len - ntohs(src->length) + slen;
        if (errbuf != NULL) {
            snprintf(errbuf, OFL_ERRBUF_SIZE, "The received flow stats contained extra bytes (%zu).", slen);
        }
        ofl_structs_free_flow_stats(s, exp, errbuf);
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }

    *len -= ntohs(src->length);
    *dst = s;
    return 0;
}
ofl_err
ofl_structs_flow_stats_unpack(struct ofp_flow_stats *src, uint8_t *buf, size_t *len, struct ofl_flow_stats **dst, struct ofl_exp *exp) {
    struct ofl_flow_stats *s;
    struct ofp_instruction *inst;
    ofl_err error;
    size_t slen;
    size_t i;
    int match_pos;
    if (*len < ( (sizeof(struct ofp_flow_stats) - sizeof(struct ofp_match)) + ROUND_UP(ntohs(src->match.length),8))) {
        OFL_LOG_WARN(LOG_MODULE, "Received flow stats has invalid length (%zu).", *len);
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }

    if (*len < ntohs(src->length)) {
        OFL_LOG_WARN(LOG_MODULE, "Received flow stats reply has invalid length (set to %u, but only %zu received).", ntohs(src->length), *len);
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }

    if (src->table_id >= PIPELINE_TABLES) {
        if (OFL_LOG_IS_WARN_ENABLED(LOG_MODULE)) {
            char *ts = ofl_table_to_string(src->table_id);
            OFL_LOG_WARN(LOG_MODULE, "Received flow stats has invalid table_id (%s).", ts);
            free(ts);
        }
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_TABLE_ID);
    }

    slen = ntohs(src->length) - (sizeof(struct ofp_flow_stats) - sizeof(struct ofp_match));

    s = (struct ofl_flow_stats *)malloc(sizeof(struct ofl_flow_stats));
    s->table_id =             src->table_id;
    s->duration_sec =  ntohl( src->duration_sec);
    s->duration_nsec = ntohl( src->duration_nsec);
    s->priority =      ntohs( src->priority);
    s->idle_timeout =  ntohs( src->idle_timeout);
    s->hard_timeout =  ntohs( src->hard_timeout);
    s->cookie =        ntoh64(src->cookie);
    s->packet_count =  ntoh64(src->packet_count);
    s->byte_count =    ntoh64(src->byte_count);

    match_pos = sizeof(struct ofp_flow_stats) - 4;

    error = ofl_structs_match_unpack(&(src->match),buf + match_pos , &slen, &(s->match), exp);
    if (error) {
        free(s);
        return error;
    }
    error = ofl_utils_count_ofp_instructions((struct ofp_instruction *) (buf + ROUND_UP(match_pos + s->match->length,8)), 
                                            slen, &s->instructions_num);
    
    if (error) {
        ofl_structs_free_match(s->match, exp);
        free(s);
        return error;
    }
   s->instructions = (struct ofl_instruction_header **)malloc(s->instructions_num * sizeof(struct ofl_instruction_header *));

   inst = (struct ofp_instruction *) (buf + ROUND_UP(match_pos + s->match->length,8));
   for (i = 0; i < s->instructions_num; i++) {
        error = ofl_structs_instructions_unpack(inst, &slen, &(s->instructions[i]), exp);
        if (error) {
            OFL_UTILS_FREE_ARR_FUN2(s->instructions, i,
                                    ofl_structs_free_instruction, exp);
            free(s);
            return error;
        }
        inst = (struct ofp_instruction *)((uint8_t *)inst + ntohs(inst->len));
    }

    if (slen != 0) {
        *len = *len - ntohs(src->length) + slen;
        OFL_LOG_WARN(LOG_MODULE, "The received flow stats contained extra bytes (%zu).", slen);
        ofl_structs_free_flow_stats(s, exp);
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }
    *len -= ntohs(src->length);
    *dst = s;
    return 0;
}
int
ofl_msg_free(struct ofl_msg_header *msg, struct ofl_exp *exp) {
     
    switch (msg->type) {
        case OFPT_HELLO: {
            break;
        }
        case OFPT_ERROR: {
            return ofl_msg_free_error((struct ofl_msg_error *)msg);
        }
        case OFPT_ECHO_REQUEST:
        case OFPT_ECHO_REPLY: {
            free(((struct ofl_msg_echo *)msg)->data);
            break;
        }
        case OFPT_EXPERIMENTER: {
            if (exp == NULL || exp->msg == NULL || exp->msg->free == NULL) {
                OFL_LOG_WARN(LOG_MODULE, "Trying to free EXPERIMENTER message, but no callback was given");
                break;
            }
            exp->msg->free((struct ofl_msg_experimenter *)msg);
            return 0;
        }
        case OFPT_FEATURES_REQUEST: {
            break;
        }
        case OFPT_FEATURES_REPLY: {
            break;
        }
        case OFPT_GET_CONFIG_REQUEST: {
            break;
        }
        case OFPT_GET_CONFIG_REPLY: {
            free(((struct ofl_msg_get_config_reply *)msg)->config);
            break;
        }
        case OFPT_SET_CONFIG: {
            free(((struct ofl_msg_set_config *)msg)->config);
            break;
        }
        case OFPT_PACKET_IN: {
            ofl_structs_free_match(((struct ofl_msg_packet_in *)msg)->match,NULL);
            free(((struct ofl_msg_packet_in *)msg)->data);
            break;
        }
        case OFPT_FLOW_REMOVED: {
            return ofl_msg_free_flow_removed((struct ofl_msg_flow_removed *)msg, true, exp);
            break;
        }
        case OFPT_PORT_STATUS: {
            free(((struct ofl_msg_port_status *)msg)->desc);
            break;
        }
        case OFPT_PACKET_OUT: {
            return ofl_msg_free_packet_out((struct ofl_msg_packet_out *)msg, true, exp);
        }
        case OFPT_FLOW_MOD: {
            return ofl_msg_free_flow_mod((struct ofl_msg_flow_mod *)msg, true, true, exp);
        }
        case OFPT_GROUP_MOD: {
            return ofl_msg_free_group_mod((struct ofl_msg_group_mod *)msg, true, exp);
        }
        case OFPT_PORT_MOD:
        case OFPT_TABLE_MOD: {
            break;
        }
        case OFPT_MULTIPART_REQUEST: {
            return ofl_msg_free_multipart_request((struct ofl_msg_multipart_request_header *)msg, exp);
        }
        case OFPT_MULTIPART_REPLY: {
            return ofl_msg_free_multipart_reply((struct ofl_msg_multipart_reply_header *)msg, exp);
        }
        case OFPT_BARRIER_REQUEST:
        case OFPT_BARRIER_REPLY:
        case OFPT_QUEUE_GET_CONFIG_REQUEST: {
            break;
        }
        case OFPT_ROLE_REPLY:
        case OFPT_ROLE_REQUEST:{
            break;
        }
        case OFPT_GET_ASYNC_REPLY:
        case OFPT_SET_ASYNC:
        case OFPT_GET_ASYNC_REQUEST:{
             break;
        }
        case OFPT_METER_MOD:{
            return ofl_msg_free_meter_mod((struct ofl_msg_meter_mod*)msg, true);
        }
        case OFPT_QUEUE_GET_CONFIG_REPLY: {
            struct ofl_msg_queue_get_config_reply *mod =
                                (struct ofl_msg_queue_get_config_reply *)msg;
            OFL_UTILS_FREE_ARR_FUN(mod->queues, mod->queues_num,
                                   ofl_structs_free_packet_queue);
            break;
        }
    }
    
    free(msg);
    return 0;
}