Ejemplo n.º 1
0
Archivo: em_cmp.c Proyecto: 274914765/C
static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
            struct tcf_pkt_info *info)
{
    struct tcf_em_cmp *cmp = (struct tcf_em_cmp *) em->data;
    unsigned char *ptr = tcf_get_base_ptr(skb, cmp->layer) + cmp->off;
    u32 val = 0;

    if (!tcf_valid_offset(skb, ptr, cmp->align))
        return 0;

    switch (cmp->align) {
        case TCF_EM_ALIGN_U8:
            val = *ptr;
            break;

        case TCF_EM_ALIGN_U16:
            val = *ptr << 8;
            val |= *(ptr+1);

            if (cmp_needs_transformation(cmp))
                val = be16_to_cpu(val);
            break;

        case TCF_EM_ALIGN_U32:
            /* Worth checking boundries? The branching seems
             * to get worse. Visit again. */
            val = *ptr << 24;
            val |= *(ptr+1) << 16;
            val |= *(ptr+2) << 8;
            val |= *(ptr+3);

            if (cmp_needs_transformation(cmp))
                val = be32_to_cpu(val);
            break;

        default:
            return 0;
    }

    if (cmp->mask)
        val &= cmp->mask;

    switch (cmp->opnd) {
        case TCF_EM_OPND_EQ:
            return val == cmp->val;
        case TCF_EM_OPND_LT:
            return val < cmp->val;
        case TCF_EM_OPND_GT:
            return val > cmp->val;
    }

    return 0;
}
Ejemplo n.º 2
0
static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
			struct tcf_pkt_info *info)
{
	struct tcf_em_cmp *cmp = (struct tcf_em_cmp *) em->data;
	unsigned char *ptr = tcf_get_base_ptr(skb, cmp->layer) + cmp->off;
	u32 val = 0;

	if (!tcf_valid_offset(skb, ptr, cmp->align))
		return 0;

	switch (cmp->align) {
	case TCF_EM_ALIGN_U8:
		val = *ptr;
		break;

	case TCF_EM_ALIGN_U16:
		val = get_unaligned_be16(ptr);

		if (cmp_needs_transformation(cmp))
			val = be16_to_cpu(val);
		break;

	case TCF_EM_ALIGN_U32:
		val = get_unaligned_be32(ptr);

		if (cmp_needs_transformation(cmp))
			val = be32_to_cpu(val);
		break;

	default:
		return 0;
	}

	if (cmp->mask)
		val &= cmp->mask;

	switch (cmp->opnd) {
	case TCF_EM_OPND_EQ:
		return val == cmp->val;
	case TCF_EM_OPND_LT:
		return val < cmp->val;
	case TCF_EM_OPND_GT:
		return val > cmp->val;
	}

	return 0;
}