예제 #1
0
/* Two flow matches overlap if there exists a packet which both match structures match on.
 * Conversely, two flow matches do not overlap if they share at least one match field with
 * incompatible value/mask fields that can't match any packet.
 */
bool
match_std_overlap(struct ofl_match *a, struct ofl_match *b, struct ofl_exp *exp)
{
	uint64_t all_mask[2] = {~0L, ~0L};

    struct ofl_match_tlv *f_a;
    struct ofl_match_tlv *f_b;
    int header, header_m;
    int field_len;
    uint8_t *val_a, *mask_a;
    uint8_t *val_b, *mask_b;

    /* Loop through the match fields in flow entry a */
    HMAP_FOR_EACH(f_a, struct ofl_match_tlv, hmap_node, &a->match_fields)
    {
        val_a = f_a->value;
        
        switch (OXM_VENDOR(f_a->header))
        {
            case (OFPXMC_OPENFLOW_BASIC):
                field_len = OXM_LENGTH(f_a->header); 
                if (OXM_HASMASK(f_a->header)) {
                    field_len /= 2;
                    header = (f_a->header & 0xfffffe00) | field_len;
                    header_m = f_a->header;
                    mask_a = f_a->value + field_len;
                } else {
                    header = f_a->header;
                    header_m = (f_a->header & 0xfffffe00) | 0x100 | (field_len << 1);
                    /* Set a dummy mask with all bits set to 0 (valid) */
                    mask_a = (uint8_t *) all_mask;
                }
                break;
            case (OFPXMC_EXPERIMENTER):
                if (exp == NULL || exp->field == NULL || exp->field->overlap_a == NULL) {
                    VLOG_WARN(LOG_MODULE,"Received match is experimental, but no callback was given.");
                    ofl_error(OFPET_BAD_MATCH, OFPBMC_BAD_TYPE);
                }
                exp->field->overlap_a(f_a, &field_len, &val_a, &mask_a, &header, &header_m, all_mask);
                break;
            default:
                break;
        } /*switch class*/

        /* Check presence of corresponding match field in flow entry b
         * Need to check for both masked and non-masked field */
        f_b = oxm_match_lookup(header, b);
        if (!f_b) f_b = oxm_match_lookup(header_m, b);

        if (f_b) {
            switch (OXM_VENDOR(f_b->header))
                {
                    case (OFPXMC_OPENFLOW_BASIC):
                        val_b = f_b->value;
                        if (OXM_HASMASK(f_b->header)) {
                            mask_b = f_b->value + field_len;
                        } else {
                            /* Set a dummy mask with all bits set to 0 (valid) */
                            mask_b = (uint8_t *) all_mask;
                        }                     
                        break;
                    case (OFPXMC_EXPERIMENTER):
                        if (exp == NULL || exp->field == NULL || exp->field->overlap_b == NULL) {
                            VLOG_WARN(LOG_MODULE,"Received match is experimental, but no callback was given.");
                            ofl_error(OFPET_BAD_MATCH, OFPBMC_BAD_TYPE);
                        }
                        exp->field->overlap_b(f_b, &field_len, &val_b, &mask_b, all_mask);
                        break;
                    default:
                        break;
                } /*switch class*/            

            switch (field_len) {
                case 1:
                    if (incompatible_8(val_a, val_b, mask_a, mask_b)) {
                        return false;
                    }
                    break;
                case 2:
                    if (incompatible_16(val_a, val_b, mask_a, mask_b)) {
                        return false;
                    }
                    break;
                case 4:
                    if (incompatible_32(val_a, val_b, mask_a, mask_b)) {
                        return false;
                    }
                    break;
                case 6:
                    if (incompatible_48(val_a, val_b, mask_a, mask_b)) {
                        return false;
                    }
                    break;
                case 8:
                    if (incompatible_64(val_a, val_b, mask_a, mask_b)) {
                        return false;
                    }
                    break;
                case 16:
                    if (incompatible_128(val_a, val_b, mask_a, mask_b)) {
                        return false;
                    }
                    break;
                default:
                    /* Should never happen */
                    break;
            } /* switch (field_len) */

        } /* if (f_b) */

    } /* HMAP_FOR_EACH */

/* If we get here, none of the common match fields in a and b were found incompatible.
* The flow entries overlap */
return true;
}
예제 #2
0
bool
match_std_overlap(struct ofl_match *a, struct ofl_match *b)
{
    uint64_t all_mask[2] = {0, 0};
    struct ofl_match_tlv *f_a;
    struct ofl_match_tlv *f_b;
    int	header, header_m;
    int field_len;
    uint8_t *val_a, *mask_a;
    uint8_t *val_b, *mask_b;

    /* Loop through the match fields in flow entry a */
    HMAP_FOR_EACH(f_a, struct ofl_match_tlv, hmap_node, &a->match_fields)
    {
        field_len = OXM_LENGTH(f_a->header);
        val_a = f_a->value;
        if (OXM_HASMASK(f_a->header)) {
            field_len /= 2;
            header = (f_a->header & 0xfffffe00) | field_len;
            header_m = f_a->header;
            mask_a = f_a->value + field_len;
        } else {
            header = f_a->header;
            header_m = (f_a->header & 0xfffffe00) | 0x100 | (field_len << 1);
            /* Set a dummy mask with all bits set to 0 (valid) */
            mask_a = (uint8_t *) all_mask;
        }

        /* Check presence of corresponding match field in flow entry b
         * Need to check for both masked and non-masked field */
        f_b = oxm_match_lookup(header, b);
        if (!f_b) f_b = oxm_match_lookup(header_m, b);

        if (f_b) {
            val_b = f_b->value;
            if (OXM_HASMASK(f_b->header)) {
                mask_b = f_b->value + field_len;
            } else {
                /* Set a dummy mask with all bits set to 0 (valid) */
                mask_b = (uint8_t *) all_mask;
            }
            switch (field_len) {
            case 1:
                if (incompatible_8(val_a, val_b, mask_a, mask_b)) {
                    return false;
                }
                break;
            case 2:
                if (incompatible_16(val_a, val_b, mask_a, mask_b)) {
                    return false;
                }
                break;
            case 4:
                if (incompatible_32(val_a, val_b, mask_a, mask_b)) {
                    return false;
                }
                break;
            case 6:
                if (incompatible_48(val_a, val_b, mask_a, mask_b)) {
                    return false;
                }
                break;
            case 8:
                if (incompatible_64(val_a, val_b, mask_a, mask_b)) {
                    return false;
                }
                break;
            case 16:
                if (incompatible_128(val_a, val_b, mask_a, mask_b)) {
                    return false;
                }
                break;
            default:
                /* Should never happen */
                break;
            } /* switch (field_len) */

        } /* if (f_b) */

    } /* HMAP_FOR_EACH */

    /* If we get here, none of the common match fields in a and b were found incompatible.
     * The flow entries overlap */
    return true;
}