Ejemplo n.º 1
0
int
ofl_msg_free_flow_removed(struct ofl_msg_flow_removed *msg, bool with_stats, struct ofl_exp *exp) {
    if (with_stats) {
        ofl_structs_free_flow_stats(msg->stats, exp);
    }
    free(msg);
    return 0;
}
Ejemplo n.º 2
0
int
ofl_msg_free_flow_removed(struct ofl_msg_flow_removed *msg, bool with_stats, struct ofl_exp *exp, char *errbuf) {
    if (with_stats) {
        ofl_structs_free_flow_stats(msg->stats, exp, errbuf);
        //TODO error
    }
    free(msg);
    return 0;
}
Ejemplo n.º 3
0
void
flow_entry_destroy(struct flow_entry *entry) {
    // NOTE: This will be called when the group entry itself destroys the
    //       flow; but it won't be a problem.
    del_group_refs(entry);
    ofl_structs_free_flow_stats(entry->stats, entry->dp->exp);
    // assumes it is a standard match
    //free(entry->match);
    free(entry);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}