Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b05b2a4 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NET]: Consolidate common code in net/core/filter.c

parent 6935d46c
Loading
Loading
Loading
Loading
+33 −57
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
#include <linux/filter.h>

/* No hurry in this branch */
static u8 *load_pointer(struct sk_buff *skb, int k)
static void *__load_pointer(struct sk_buff *skb, int k)
{
	u8 *ptr = NULL;

@@ -50,6 +50,18 @@ static u8 *load_pointer(struct sk_buff *skb, int k)
	return NULL;
}

static inline void *load_pointer(struct sk_buff *skb, int k,
                                 unsigned int size, void *buffer)
{
	if (k >= 0)
		return skb_header_pointer(skb, k, size, buffer);
	else {
		if (k >= SKF_AD_OFF)
			return NULL;
		return __load_pointer(skb, k);
	}
}

/**
 *	sk_run_filter	- 	run a filter on a socket
 *	@skb: buffer to run the filter on
@@ -64,15 +76,16 @@ static u8 *load_pointer(struct sk_buff *skb, int k)
 
int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
{
	unsigned char *data = skb->data;
	/* len is UNSIGNED. Byte wide insns relies only on implicit
	   type casts to prevent reading arbitrary memory locations.
	 */
	unsigned int len = skb->len-skb->data_len;
	struct sock_filter *fentry;	/* We walk down these */
	void *ptr;
	u32 A = 0;	   		/* Accumulator */
	u32 X = 0;   			/* Index Register */
	u32 mem[BPF_MEMWORDS];		/* Scratch Memory Store */
	u32 tmp;
	int k;
	int pc;

@@ -168,68 +181,29 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
		case BPF_LD|BPF_W|BPF_ABS:
			k = fentry->k;
 load_w:
			if (k < 0) {
				u8 *ptr;

				if (k >= SKF_AD_OFF)
					break;
				ptr = load_pointer(skb, k);
				if (ptr) {
			ptr = load_pointer(skb, k, 4, &tmp);
			if (ptr != NULL) {
				A = ntohl(*(u32 *)ptr);
				continue;
			}
			} else {
				u32 _tmp, *p;
				p = skb_header_pointer(skb, k, 4, &_tmp);
				if (p != NULL) {
					A = ntohl(*p);
					continue;
				}
			}
			return 0;
		case BPF_LD|BPF_H|BPF_ABS:
			k = fentry->k;
 load_h:
			if (k < 0) {
				u8 *ptr;

				if (k >= SKF_AD_OFF)
					break;
				ptr = load_pointer(skb, k);
				if (ptr) {
			ptr = load_pointer(skb, k, 2, &tmp);
			if (ptr != NULL) {
				A = ntohs(*(u16 *)ptr);
				continue;
			}
			} else {
				u16 _tmp, *p;
				p = skb_header_pointer(skb, k, 2, &_tmp);
				if (p != NULL) {
					A = ntohs(*p);
					continue;
				}
			}
			return 0;
		case BPF_LD|BPF_B|BPF_ABS:
			k = fentry->k;
load_b:
			if (k < 0) {
				u8 *ptr;

				if (k >= SKF_AD_OFF)
					break;
				ptr = load_pointer(skb, k);
				if (ptr) {
					A = *ptr;
			ptr = load_pointer(skb, k, 1, &tmp);
			if (ptr != NULL) {
				A = *(u8 *)ptr;
				continue;
			}
			} else {
				u8 _tmp, *p;
				p = skb_header_pointer(skb, k, 1, &_tmp);
				if (p != NULL) {
					A = *p;
					continue;
				}
			}
			return 0;
		case BPF_LD|BPF_W|BPF_LEN:
			A = len;
@@ -247,10 +221,12 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
			k = X + fentry->k;
			goto load_b;
		case BPF_LDX|BPF_B|BPF_MSH:
			if (fentry->k >= len)
				return 0;
			X = (data[fentry->k] & 0xf) << 2;
			ptr = load_pointer(skb, fentry->k, 1, &tmp);
			if (ptr != NULL) {
				X = (*(u8 *)ptr & 0xf) << 2;
				continue;
			}
			return 0;
		case BPF_LD|BPF_IMM:
			A = fentry->k;
			continue;