diff options
| -rw-r--r-- | target/linux/generic-2.6/patches-2.6.28/240-packet_socket_type.patch | 132 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches-2.6.29/240-packet_socket_type.patch | 132 | 
2 files changed, 264 insertions, 0 deletions
| diff --git a/target/linux/generic-2.6/patches-2.6.28/240-packet_socket_type.patch b/target/linux/generic-2.6/patches-2.6.28/240-packet_socket_type.patch new file mode 100644 index 000000000..741966bc6 --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.28/240-packet_socket_type.patch @@ -0,0 +1,132 @@ +This patch allows the user to specify desired packet types (outgoing, +broadcast, unicast, etc.) on packet sockets via setsockopt. +This can reduce the load in situations where only a limited number +of packet types are necessary + +Signed-off-by: Felix Fietkau <nbd@openwrt.org> + +--- a/include/linux/if_packet.h ++++ b/include/linux/if_packet.h +@@ -31,6 +31,8 @@ struct sockaddr_ll + /* These ones are invisible by user level */ + #define PACKET_LOOPBACK		5		/* MC/BRD frame looped back */ + #define PACKET_FASTROUTE	6		/* Fastrouted frame	*/ ++#define PACKET_ANY		0xffffffff ++ +  + /* Packet socket options */ +  +@@ -46,6 +48,7 @@ struct sockaddr_ll + #define PACKET_VERSION			10 + #define PACKET_HDRLEN			11 + #define PACKET_RESERVE			12 ++#define PACKET_RECV_TYPE		13 +  + struct tpacket_stats + { +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -192,6 +192,7 @@ struct packet_sock { + 	unsigned int		tp_hdrlen; + 	unsigned int		tp_reserve; + #endif ++	int			pkt_type; + }; +  + struct packet_skb_cb { +@@ -282,6 +283,7 @@ static int packet_rcv_spkt(struct sk_buf + { + 	struct sock *sk; + 	struct sockaddr_pkt *spkt; ++	struct packet_sock *po; +  + 	/* + 	 *	When we registered the protocol we saved the socket in the data +@@ -289,6 +291,7 @@ static int packet_rcv_spkt(struct sk_buf + 	 */ +  + 	sk = pt->af_packet_priv; ++	po = pkt_sk(sk); +  + 	/* + 	 *	Yank back the headers [hope the device set this +@@ -301,7 +304,7 @@ static int packet_rcv_spkt(struct sk_buf + 	 *	so that this procedure is noop. + 	 */ +  +-	if (skb->pkt_type == PACKET_LOOPBACK) ++	if (!(po->pkt_type & (1 << skb->pkt_type))) + 		goto out; +  + 	if (dev_net(dev) != sock_net(sk)) +@@ -486,12 +489,12 @@ static int packet_rcv(struct sk_buff *sk + 	int skb_len = skb->len; + 	unsigned int snaplen, res; +  +-	if (skb->pkt_type == PACKET_LOOPBACK) +-		goto drop; +- + 	sk = pt->af_packet_priv; + 	po = pkt_sk(sk); +  ++	if (!(po->pkt_type & (1 << skb->pkt_type))) ++		goto drop; ++ + 	if (dev_net(dev) != sock_net(sk)) + 		goto drop; +  +@@ -608,12 +611,12 @@ static int tpacket_rcv(struct sk_buff *s + 	struct timeval tv; + 	struct timespec ts; +  +-	if (skb->pkt_type == PACKET_LOOPBACK) +-		goto drop; +- + 	sk = pt->af_packet_priv; + 	po = pkt_sk(sk); +  ++	if (!(po->pkt_type & (1 << skb->pkt_type))) ++		goto drop; ++ + 	if (dev_net(dev) != sock_net(sk)) + 		goto drop; +  +@@ -1072,6 +1075,7 @@ static int packet_create(struct net *net + 	spin_lock_init(&po->bind_lock); + 	mutex_init(&po->pg_vec_lock); + 	po->prot_hook.func = packet_rcv; ++	po->pkt_type = PACKET_ANY & ~PACKET_LOOPBACK; +  + 	if (sock->type == SOCK_PACKET) + 		po->prot_hook.func = packet_rcv_spkt; +@@ -1411,6 +1415,16 @@ packet_setsockopt(struct socket *sock, i + 			ret = packet_mc_drop(sk, &mreq); + 		return ret; + 	} ++	case PACKET_RECV_TYPE: ++	{ ++		int val; ++		if (optlen != sizeof(val)) ++			return -EINVAL; ++		if (copy_from_user(&val, optval, sizeof(val))) ++			return -EFAULT; ++		po->pkt_type = val & ~PACKET_LOOPBACK; ++		return 0; ++	} +  + #ifdef CONFIG_PACKET_MMAP + 	case PACKET_RX_RING: +@@ -1542,6 +1556,13 @@ static int packet_getsockopt(struct sock +  + 		data = &val; + 		break; ++	case PACKET_RECV_TYPE: ++		if (len > sizeof(int)) ++			len = sizeof(int); ++		val = po->pkt_type; ++ ++		data = &val; ++		break; + #ifdef CONFIG_PACKET_MMAP + 	case PACKET_VERSION: + 		if (len > sizeof(int)) diff --git a/target/linux/generic-2.6/patches-2.6.29/240-packet_socket_type.patch b/target/linux/generic-2.6/patches-2.6.29/240-packet_socket_type.patch new file mode 100644 index 000000000..741966bc6 --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.29/240-packet_socket_type.patch @@ -0,0 +1,132 @@ +This patch allows the user to specify desired packet types (outgoing, +broadcast, unicast, etc.) on packet sockets via setsockopt. +This can reduce the load in situations where only a limited number +of packet types are necessary + +Signed-off-by: Felix Fietkau <nbd@openwrt.org> + +--- a/include/linux/if_packet.h ++++ b/include/linux/if_packet.h +@@ -31,6 +31,8 @@ struct sockaddr_ll + /* These ones are invisible by user level */ + #define PACKET_LOOPBACK		5		/* MC/BRD frame looped back */ + #define PACKET_FASTROUTE	6		/* Fastrouted frame	*/ ++#define PACKET_ANY		0xffffffff ++ +  + /* Packet socket options */ +  +@@ -46,6 +48,7 @@ struct sockaddr_ll + #define PACKET_VERSION			10 + #define PACKET_HDRLEN			11 + #define PACKET_RESERVE			12 ++#define PACKET_RECV_TYPE		13 +  + struct tpacket_stats + { +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -192,6 +192,7 @@ struct packet_sock { + 	unsigned int		tp_hdrlen; + 	unsigned int		tp_reserve; + #endif ++	int			pkt_type; + }; +  + struct packet_skb_cb { +@@ -282,6 +283,7 @@ static int packet_rcv_spkt(struct sk_buf + { + 	struct sock *sk; + 	struct sockaddr_pkt *spkt; ++	struct packet_sock *po; +  + 	/* + 	 *	When we registered the protocol we saved the socket in the data +@@ -289,6 +291,7 @@ static int packet_rcv_spkt(struct sk_buf + 	 */ +  + 	sk = pt->af_packet_priv; ++	po = pkt_sk(sk); +  + 	/* + 	 *	Yank back the headers [hope the device set this +@@ -301,7 +304,7 @@ static int packet_rcv_spkt(struct sk_buf + 	 *	so that this procedure is noop. + 	 */ +  +-	if (skb->pkt_type == PACKET_LOOPBACK) ++	if (!(po->pkt_type & (1 << skb->pkt_type))) + 		goto out; +  + 	if (dev_net(dev) != sock_net(sk)) +@@ -486,12 +489,12 @@ static int packet_rcv(struct sk_buff *sk + 	int skb_len = skb->len; + 	unsigned int snaplen, res; +  +-	if (skb->pkt_type == PACKET_LOOPBACK) +-		goto drop; +- + 	sk = pt->af_packet_priv; + 	po = pkt_sk(sk); +  ++	if (!(po->pkt_type & (1 << skb->pkt_type))) ++		goto drop; ++ + 	if (dev_net(dev) != sock_net(sk)) + 		goto drop; +  +@@ -608,12 +611,12 @@ static int tpacket_rcv(struct sk_buff *s + 	struct timeval tv; + 	struct timespec ts; +  +-	if (skb->pkt_type == PACKET_LOOPBACK) +-		goto drop; +- + 	sk = pt->af_packet_priv; + 	po = pkt_sk(sk); +  ++	if (!(po->pkt_type & (1 << skb->pkt_type))) ++		goto drop; ++ + 	if (dev_net(dev) != sock_net(sk)) + 		goto drop; +  +@@ -1072,6 +1075,7 @@ static int packet_create(struct net *net + 	spin_lock_init(&po->bind_lock); + 	mutex_init(&po->pg_vec_lock); + 	po->prot_hook.func = packet_rcv; ++	po->pkt_type = PACKET_ANY & ~PACKET_LOOPBACK; +  + 	if (sock->type == SOCK_PACKET) + 		po->prot_hook.func = packet_rcv_spkt; +@@ -1411,6 +1415,16 @@ packet_setsockopt(struct socket *sock, i + 			ret = packet_mc_drop(sk, &mreq); + 		return ret; + 	} ++	case PACKET_RECV_TYPE: ++	{ ++		int val; ++		if (optlen != sizeof(val)) ++			return -EINVAL; ++		if (copy_from_user(&val, optval, sizeof(val))) ++			return -EFAULT; ++		po->pkt_type = val & ~PACKET_LOOPBACK; ++		return 0; ++	} +  + #ifdef CONFIG_PACKET_MMAP + 	case PACKET_RX_RING: +@@ -1542,6 +1556,13 @@ static int packet_getsockopt(struct sock +  + 		data = &val; + 		break; ++	case PACKET_RECV_TYPE: ++		if (len > sizeof(int)) ++			len = sizeof(int); ++		val = po->pkt_type; ++ ++		data = &val; ++		break; + #ifdef CONFIG_PACKET_MMAP + 	case PACKET_VERSION: + 		if (len > sizeof(int)) | 
