diff options
author | Jonas Gorski <jogo@openwrt.org> | 2013-05-19 18:36:15 +0000 |
---|---|---|
committer | Jonas Gorski <jogo@openwrt.org> | 2013-05-19 18:36:15 +0000 |
commit | c0435a971e9c21ebf694b221717e7a73f12662ec (patch) | |
tree | 6daa92bd257c9376af180e7bb3649dca91589812 /target/linux/generic/patches-3.10/630-packet_socket_type.patch | |
parent | 87203c404996884334a9584fce0d8a251bf9fb43 (diff) | |
download | master-31e0f0ae-c0435a971e9c21ebf694b221717e7a73f12662ec.tar.gz master-31e0f0ae-c0435a971e9c21ebf694b221717e7a73f12662ec.tar.bz2 master-31e0f0ae-c0435a971e9c21ebf694b221717e7a73f12662ec.zip |
kernel: generic: add 3.10-rc1 support
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
SVN-Revision: 36663
Diffstat (limited to 'target/linux/generic/patches-3.10/630-packet_socket_type.patch')
-rw-r--r-- | target/linux/generic/patches-3.10/630-packet_socket_type.patch | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.10/630-packet_socket_type.patch b/target/linux/generic/patches-3.10/630-packet_socket_type.patch new file mode 100644 index 0000000000..7f43aff8f5 --- /dev/null +++ b/target/linux/generic/patches-3.10/630-packet_socket_type.patch @@ -0,0 +1,134 @@ +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/uapi/linux/if_packet.h ++++ b/include/uapi/linux/if_packet.h +@@ -29,6 +29,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_MASK_ANY 0xffffffff /* mask for packet type bits */ ++ + + /* Packet socket options */ + +@@ -51,6 +53,7 @@ struct sockaddr_ll { + #define PACKET_TIMESTAMP 17 + #define PACKET_FANOUT 18 + #define PACKET_TX_HAS_OFF 19 ++#define PACKET_RECV_TYPE 20 + + #define PACKET_FANOUT_HASH 0 + #define PACKET_FANOUT_LB 1 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -1375,6 +1375,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 +@@ -1382,6 +1383,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 +@@ -1394,7 +1396,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 (!net_eq(dev_net(dev), sock_net(sk))) +@@ -1601,12 +1603,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 (!net_eq(dev_net(dev), sock_net(sk))) + goto drop; + +@@ -1719,12 +1721,12 @@ static int tpacket_rcv(struct sk_buff *s + struct timespec ts; + __u32 ts_status; + +- 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 (!net_eq(dev_net(dev), sock_net(sk))) + goto drop; + +@@ -2614,6 +2616,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_MASK_ANY & ~(1 << PACKET_LOOPBACK); + + if (sock->type == SOCK_PACKET) + po->prot_hook.func = packet_rcv_spkt; +@@ -3227,6 +3230,16 @@ packet_setsockopt(struct socket *sock, i + po->tp_tx_has_off = !!val; + return 0; + } ++ case PACKET_RECV_TYPE: ++ { ++ unsigned 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; ++ } + default: + return -ENOPROTOOPT; + } +@@ -3276,6 +3289,13 @@ static int packet_getsockopt(struct sock + case PACKET_VNET_HDR: + val = po->has_vnet_hdr; + break; ++ case PACKET_RECV_TYPE: ++ if (len > sizeof(unsigned int)) ++ len = sizeof(unsigned int); ++ val = po->pkt_type; ++ ++ data = &val; ++ break; + case PACKET_VERSION: + val = po->tp_version; + break; +--- a/net/packet/internal.h ++++ b/net/packet/internal.h +@@ -114,6 +114,7 @@ struct packet_sock { + unsigned int tp_tx_has_off:1; + unsigned int tp_tstamp; + struct packet_type prot_hook ____cacheline_aligned_in_smp; ++ unsigned int pkt_type; + }; + + static struct packet_sock *pkt_sk(struct sock *sk) |