Example #1
0
File: em_cmp.c Project: 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;
}
Example #2
0
static int em_nbyte_match(struct sk_buff *skb, struct tcf_ematch *em,
			  struct tcf_pkt_info *info)
{
	struct nbyte_data *nbyte = (struct nbyte_data *) em->data;
	unsigned char *ptr = tcf_get_base_ptr(skb, nbyte->hdr.layer);

	ptr += nbyte->hdr.off;

	if (!tcf_valid_offset(skb, ptr, nbyte->hdr.len))
		return 0;

	return !memcmp(ptr + nbyte->hdr.off, nbyte->pattern, nbyte->hdr.len);
}
Example #3
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;
}
static int em_u32_match(struct sk_buff *skb, struct tcf_ematch *em,
			struct tcf_pkt_info *info)
{
	struct tc_u32_key *key = (struct tc_u32_key *) em->data;
	const unsigned char *ptr = skb_network_header(skb);

	if (info) {
		if (info->ptr)
			ptr = info->ptr;
		ptr += (info->nexthdr & key->offmask);
	}

	ptr += key->off;

	if (!tcf_valid_offset(skb, ptr, sizeof(u32)))
		return 0;

<<<<<<< HEAD
Example #5
0
static int em_u32_match(struct sk_buff *skb, struct tcf_ematch *em,
			struct tcf_pkt_info *info)
{
	struct tc_u32_key *key = (struct tc_u32_key *) em->data;
	unsigned char *ptr = skb->nh.raw;
	
	if (info) {
		if (info->ptr)
			ptr = info->ptr;
		ptr += (info->nexthdr & key->offmask);
	}

	ptr += key->off;

	if (!tcf_valid_offset(skb, ptr, sizeof(u32)))
		return 0;
	
	return !(((*(u32*) ptr)  ^ key->val) & key->mask);
}