ofl_err
ofl_structs_meter_stats_unpack(struct ofp_meter_stats *src, size_t *len, struct ofl_meter_stats **dst) {
    struct ofl_meter_stats *s;
    struct ofp_meter_band_stats *c;
    ofl_err error;
    size_t slen;
    size_t i;

    if (*len < sizeof(struct ofp_meter_stats)) {
        OFL_LOG_WARN(LOG_MODULE, "Received meter stats reply is too short (%zu).", *len);
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }

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

    slen = ntohs(src->len) - sizeof(struct ofp_meter_stats);

    s = (struct ofl_meter_stats *) malloc(sizeof(struct ofl_meter_stats));
    s->meter_id = ntohl(src->meter_id);
    s->len = ntohs(src->len);
    
    s->flow_count = ntohl(src->flow_count);
    s->packet_in_count = ntoh64(src->packet_in_count);
    s->byte_in_count = ntoh64(src->byte_in_count);
    s->duration_sec =  htonl(src->duration_sec);
    s->duration_nsec =  htonl(src->duration_nsec);

    error = ofl_utils_count_ofp_meter_band_stats(src->band_stats, slen, &s->meter_bands_num);
    if (error) {
        free(s);
        return error;
    }
    s->band_stats = (struct ofl_meter_band_stats **)malloc(s->meter_bands_num * sizeof(struct ofl_meter_band_stats *));

    c = src->band_stats;
    for (i = 0; i < s->meter_bands_num; i++) {
        error = ofl_structs_meter_band_stats_unpack(c, &slen, &(s->band_stats[i]));
        if (error) {
            OFL_UTILS_FREE_ARR(s->band_stats, i);
            free(s);
            return error;
        }
        c = (struct ofp_meter_band_stats *)((uint8_t *)c + sizeof(struct ofp_meter_band_stats));
    }

    if (slen != 0) {
        *len = *len - ntohs(src->len) + slen;
        OFL_LOG_WARN(LOG_MODULE, "The received meter stats contained extra bytes (%zu).", slen);
        ofl_structs_free_meter_stats(s);
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }
    *len -= ntohs(src->len);
    *dst = s;
    return 0;
}
ofl_err
ofl_structs_meter_config_unpack(struct ofp_meter_config *src, size_t *len, struct ofl_meter_config **dst) {
    struct ofl_meter_config *s;
    struct ofp_meter_band_header *b;
    ofl_err error;
    size_t slen;
    size_t i;

    if (*len < sizeof(struct ofp_meter_config)) {
        OFL_LOG_WARN(LOG_MODULE, "Received meter config reply is too short (%zu).", *len);
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }

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

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

    s = (struct ofl_meter_config *) malloc(sizeof(struct ofl_meter_config));
    s->meter_id = ntohl(src->meter_id);
    s->length = ntohs(src->length);
    
    s->flags = ntohs(src->flags);

    error = ofl_utils_count_ofp_meter_bands(src->bands, slen, &s->meter_bands_num);
    if (error) {
        free(s);
        return error;
    }
    s->bands = (struct ofl_meter_band_header **)malloc(s->meter_bands_num * sizeof(struct ofl_meter_band_header *));

    b= src->bands;
    for (i = 0; i < s->meter_bands_num; i++) {
        error = ofl_structs_meter_band_unpack(b, &slen, &(s->bands[i]));
        if (error) {
            OFL_UTILS_FREE_ARR(s->bands, i);
            free(s);
            return error;
        }
        b = (struct ofp_meter_band_header *)((uint8_t *)b + ntohs(b->len));
    }

    if (slen != 0) {
        *len = *len - ntohs(src->length) + slen;
        OFL_LOG_WARN(LOG_MODULE, "The received meter config contained extra bytes (%zu).", slen);
        //ofl_structs_free_meter_stats(s);
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }
    *len -= ntohs(src->length);
    *dst = s;
    return 0;
}
示例#3
0
void
meter_entry_destroy(struct meter_entry *entry) {
    struct flow_ref_entry *ref, *next;

    // remove all referencing flows
    LIST_FOR_EACH_SAFE(ref, next, struct flow_ref_entry, node, &entry->flow_refs) {
        flow_entry_remove(ref->entry, OFPRR_METER_DELETE);// METER_DELETE ???????
        // Note: the flow_ref_entryf will be destroyed after a chain of calls in flow_entry_remove
    }

    OFL_UTILS_FREE_ARR_FUN(entry->config->bands, entry->config->meter_bands_num, ofl_structs_free_meter_bands);
    free(entry->config);

    OFL_UTILS_FREE_ARR(entry->stats->band_stats, entry->stats->meter_bands_num);
    free(entry->stats);
    free(entry);
}
示例#4
0
static ofl_err
ofl_msg_unpack_features_reply(struct ofp_header *src, size_t *len, struct ofl_msg_header **msg, char *errbuf) {
    struct ofp_switch_features *sr;
    struct ofl_msg_features_reply *dr;
    struct ofp_port *port;
    ofl_err error = 0;
    size_t i;

    if (*len < sizeof(struct ofp_switch_features)) {
        if (errbuf != NULL) {
            snprintf(errbuf, OFL_ERRBUF_SIZE, "Received FEATURES_REPLY message has invalid length (%zu).", *len);
        }
        return ofl_error(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }
    *len -= sizeof(struct ofp_switch_features);

    sr = (struct ofp_switch_features *)src;
    dr = (struct ofl_msg_features_reply *)malloc(sizeof(struct ofl_msg_features_reply));

    dr->datapath_id  = ntoh64(sr->datapath_id);
    dr->n_buffers    = ntohl( sr->n_buffers);
    dr->n_tables     = ntohl( sr->n_tables);
    dr->capabilities = ntohl( sr->capabilities);

    error = ofl_utils_count_ofp_ports(&(sr->ports), *len, &dr->ports_num);
    if (error) {
        free(dr);
        return error;
    }

    dr->ports = (struct ofl_port **)malloc(dr->ports_num * sizeof(struct ofl_port *));

    port = sr->ports;
    for (i = 0; i < dr->ports_num; i++) {
        error = ofl_structs_port_unpack(port, len, &(dr->ports[i]), errbuf);
        if (error) {
            OFL_UTILS_FREE_ARR(dr->ports, i);
            free(dr);
            return error;
        }
        port = (struct ofp_port *)((uint8_t *)port + sizeof(struct ofp_port));
    }

    *msg = (struct ofl_msg_header *)dr;
    return 0;
}
示例#5
0
ofl_err
ofl_structs_group_stats_unpack(struct ofp_group_stats *src, size_t *len, struct ofl_group_stats **dst, char *errbuf) {
    struct ofl_group_stats *s;
    struct ofp_bucket_counter *c;
    ofl_err error;
    size_t slen;
    size_t i;

    if (*len < sizeof(struct ofp_group_stats)) {
        if (errbuf != NULL) {
            snprintf(errbuf, OFL_ERRBUF_SIZE, "Received group desc stats reply is too short (%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 group 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 (ntohl(src->group_id) > OFPG_MAX) {
        if (errbuf != NULL) {
            char *gs = ofl_group_to_string(ntohl(src->group_id));
            snprintf(errbuf, OFL_ERRBUF_SIZE, "Received group stats has invalid group_id (%s).", gs);
            free(gs);
        }
        return ofl_error(OFPET_BAD_ACTION, OFPBRC_BAD_LEN);
    }
    slen = ntohs(src->length) - sizeof(struct ofp_group_stats);

    s = (struct ofl_group_stats *)malloc(sizeof(struct ofl_group_stats));
    s->group_id = ntohl(src->group_id);
    s->ref_count = ntohl(src->ref_count);
    s->packet_count = ntoh64(src->packet_count);
    s->byte_count = ntoh64(src->byte_count);

    error = ofl_utils_count_ofp_bucket_counters(src->bucket_stats, slen, &s->counters_num);
    if (error) {
        free(s);
        return error;
    }
    s->counters = (struct ofl_bucket_counter **)malloc(s->counters_num * sizeof(struct ofl_bucket_counter *));

    c = src->bucket_stats;
    for (i = 0; i < s->counters_num; i++) {
        error = ofl_structs_bucket_counter_unpack(c, &slen, &(s->counters[i]), errbuf);
        if (error) {
            OFL_UTILS_FREE_ARR(s->counters, i);
            free(s);
            return error;
        }
        c = (struct ofp_bucket_counter *)((uint8_t *)c + sizeof(struct ofp_bucket_counter));
    }

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

    *len -= ntohs(src->length);
    *dst = s;
    return 0;
}
示例#6
0
/* Frees the OFlib stats reply message along with any dynamically allocated
 * structures. */
static int
ofl_msg_free_stats_reply(struct ofl_msg_stats_reply_header *msg, struct ofl_exp *exp, char *errbuf) {
    switch (msg->type) {
        case OFPST_DESC: {
            struct ofl_msg_stats_reply_desc *stat = (struct ofl_msg_stats_reply_desc *)msg;
            free(stat->mfr_desc);
            free(stat->hw_desc);
            free(stat->sw_desc);
            free(stat->serial_num);
            free(stat->dp_desc);
            break;
        }
        case OFPST_FLOW: {
            struct ofl_msg_stats_reply_flow *stat = (struct ofl_msg_stats_reply_flow *)msg;
            OFL_UTILS_FREE_ARR_FUN3(stat->stats, stat->stats_num,
                                    ofl_structs_free_flow_stats, exp, errbuf);
            //TODO error
            break;
        }
        case OFPST_AGGREGATE: {
            break;
        }
        case OFPST_TABLE: {
            struct ofl_msg_stats_reply_table *stat = (struct ofl_msg_stats_reply_table *)msg;
            OFL_UTILS_FREE_ARR_FUN(stat->stats, stat->stats_num,
                                   ofl_structs_free_table_stats);
            break;
        }
        case OFPST_PORT: {
            struct ofl_msg_stats_reply_port *stat = (struct ofl_msg_stats_reply_port *)msg;
            OFL_UTILS_FREE_ARR(stat->stats, stat->stats_num);
            break;
        }
        case OFPST_QUEUE: {
            struct ofl_msg_stats_reply_queue *stat = (struct ofl_msg_stats_reply_queue *)msg;
            OFL_UTILS_FREE_ARR(stat->stats, stat->stats_num);
            break;
        }
        case OFPST_GROUP: {
            struct ofl_msg_stats_reply_group *stat = (struct ofl_msg_stats_reply_group *)msg;
            OFL_UTILS_FREE_ARR_FUN(stat->stats, stat->stats_num,
                                   ofl_structs_free_group_stats);
            break;
        }
        case OFPST_GROUP_DESC: {
            struct ofl_msg_stats_reply_group_desc *stat = (struct ofl_msg_stats_reply_group_desc *)msg;
            OFL_UTILS_FREE_ARR_FUN3(stat->stats, stat->stats_num,
                                    ofl_structs_free_group_desc_stats, exp, errbuf);
            //TODO error
            break;
        }
        case OFPST_EXPERIMENTER: {
            if (exp == NULL || exp->stats || exp->stats->reply_free == NULL) {
                if (errbuf != NULL) {
                    snprintf(errbuf, OFL_ERRBUF_SIZE, "Trying to free EXPERIMENTER stats reply, but no callback was given.");
                }
                free(msg);
                return -1;
            }
            exp->stats->reply_free(msg);
            return 0;
        }
        default: {
            return -1;
        }
    }

    free(msg);
    return 0;
}
示例#7
0
/* Frees the OFlib stats reply message along with any dynamically allocated
 * structures. */
static int
ofl_msg_free_multipart_reply(struct ofl_msg_multipart_reply_header *msg, struct ofl_exp *exp) {
    switch (msg->type) {
        case OFPMP_DESC: {
            struct ofl_msg_reply_desc *stat = (struct ofl_msg_reply_desc *) msg;
            free(stat->mfr_desc);
            free(stat->hw_desc);
            free(stat->sw_desc);
            free(stat->serial_num);
            free(stat->dp_desc);
            break;
        }
        case OFPMP_FLOW: {
            struct ofl_msg_multipart_reply_flow *stat = (struct ofl_msg_multipart_reply_flow *)msg;
            OFL_UTILS_FREE_ARR_FUN2(stat->stats, stat->stats_num,
                                    ofl_structs_free_flow_stats, exp);
        }
        case OFPMP_AGGREGATE: {
            break;
        }
        case OFPMP_TABLE: {
            struct ofl_msg_multipart_reply_table *stat = (struct ofl_msg_multipart_reply_table *)msg;
            OFL_UTILS_FREE_ARR_FUN(stat->stats, stat->stats_num,
                                   ofl_structs_free_table_stats);
            break;
        }
        case OFPMP_PORT_STATS: {
            struct ofl_msg_multipart_reply_port *stat = (struct ofl_msg_multipart_reply_port *)msg;
            OFL_UTILS_FREE_ARR(stat->stats, stat->stats_num);
            break;
        }
        case OFPMP_QUEUE: {
            struct ofl_msg_multipart_reply_queue *stat = (struct ofl_msg_multipart_reply_queue *)msg;
            OFL_UTILS_FREE_ARR(stat->stats, stat->stats_num);
            break;
        }
        case OFPMP_GROUP: {
            struct ofl_msg_multipart_reply_group *stat = (struct ofl_msg_multipart_reply_group *)msg;
            OFL_UTILS_FREE_ARR_FUN(stat->stats, stat->stats_num,
                                   ofl_structs_free_group_stats);
            break;
        }
        case OFPMP_METER:{
            struct ofl_msg_multipart_reply_meter *stat = (struct ofl_msg_multipart_reply_meter*)msg;
            OFL_UTILS_FREE_ARR_FUN(stat->stats, stat->stats_num,
                                   ofl_structs_free_meter_stats);            
            break;
        }
        case OFPMP_METER_CONFIG:{
            struct ofl_msg_multipart_reply_meter_conf *conf = (struct ofl_msg_multipart_reply_meter_conf *)msg;
            OFL_UTILS_FREE_ARR_FUN(conf->stats, conf->stats_num,
                                   ofl_structs_free_meter_config);             
            break;
        }
        case OFPMP_METER_FEATURES:{
            struct ofl_msg_multipart_reply_meter_features *feat = (struct ofl_msg_multipart_reply_meter_features *)msg;
            free(feat->features);
            break;
        }
        case OFPMP_GROUP_DESC: {
            struct ofl_msg_multipart_reply_group_desc *stat = (struct ofl_msg_multipart_reply_group_desc *)msg;
            OFL_UTILS_FREE_ARR_FUN2(stat->stats, stat->stats_num,
                                    ofl_structs_free_group_desc_stats, exp);
            break;
        }
        case OFPMP_PORT_DESC:{
            struct ofl_msg_multipart_reply_port_desc *stat = (struct ofl_msg_multipart_reply_port_desc *)msg;        
            OFL_UTILS_FREE_ARR_FUN(stat->stats, stat->stats_num,
                                    ofl_structs_free_port);
            break;            
        }
        case OFPMP_TABLE_FEATURES:{
            struct ofl_msg_multipart_reply_table_features *m = (struct ofl_msg_multipart_reply_table_features *)msg;
            OFL_UTILS_FREE_ARR_FUN2(m->table_features, m->tables_num,
                                    ofl_structs_free_table_features, exp);
            break;        
        }
        case OFPMP_EXPERIMENTER: {
            if (exp == NULL || exp->stats || exp->stats->reply_free == NULL) {
                OFL_LOG_WARN(LOG_MODULE, "Trying to free EXPERIMENTER stats reply, but no callback was given.");
                break;
            }
            exp->stats->reply_free(msg);
            return 0;
        }
        case OFPMP_GROUP_FEATURES:{
            break;
        }
        default: {
            return -1;
        }
    }

    free(msg);
    return 0;
}