Root/target/linux/generic/patches-3.7/630-packet_socket_type.patch

1This patch allows the user to specify desired packet types (outgoing,
2broadcast, unicast, etc.) on packet sockets via setsockopt.
3This can reduce the load in situations where only a limited number
4of packet types are necessary
5
6Signed-off-by: Felix Fietkau <nbd@openwrt.org>
7
8--- a/include/uapi/linux/if_packet.h
9+++ b/include/uapi/linux/if_packet.h
10@@ -29,6 +29,8 @@ struct sockaddr_ll {
11 /* These ones are invisible by user level */
12 #define PACKET_LOOPBACK 5 /* MC/BRD frame looped back */
13 #define PACKET_FASTROUTE 6 /* Fastrouted frame */
14+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
15+
16 
17 /* Packet socket options */
18 
19@@ -50,6 +52,7 @@ struct sockaddr_ll {
20 #define PACKET_TX_TIMESTAMP 16
21 #define PACKET_TIMESTAMP 17
22 #define PACKET_FANOUT 18
23+#define PACKET_RECV_TYPE 19
24 
25 #define PACKET_FANOUT_HASH 0
26 #define PACKET_FANOUT_LB 1
27--- a/net/packet/af_packet.c
28+++ b/net/packet/af_packet.c
29@@ -1273,6 +1273,7 @@ static int packet_rcv_spkt(struct sk_buf
30 {
31     struct sock *sk;
32     struct sockaddr_pkt *spkt;
33+ struct packet_sock *po;
34 
35     /*
36      * When we registered the protocol we saved the socket in the data
37@@ -1280,6 +1281,7 @@ static int packet_rcv_spkt(struct sk_buf
38      */
39 
40     sk = pt->af_packet_priv;
41+ po = pkt_sk(sk);
42 
43     /*
44      * Yank back the headers [hope the device set this
45@@ -1292,7 +1294,7 @@ static int packet_rcv_spkt(struct sk_buf
46      * so that this procedure is noop.
47      */
48 
49- if (skb->pkt_type == PACKET_LOOPBACK)
50+ if (!(po->pkt_type & (1 << skb->pkt_type)))
51         goto out;
52 
53     if (!net_eq(dev_net(dev), sock_net(sk)))
54@@ -1498,12 +1500,12 @@ static int packet_rcv(struct sk_buff *sk
55     int skb_len = skb->len;
56     unsigned int snaplen, res;
57 
58- if (skb->pkt_type == PACKET_LOOPBACK)
59- goto drop;
60-
61     sk = pt->af_packet_priv;
62     po = pkt_sk(sk);
63 
64+ if (!(po->pkt_type & (1 << skb->pkt_type)))
65+ goto drop;
66+
67     if (!net_eq(dev_net(dev), sock_net(sk)))
68         goto drop;
69 
70@@ -1622,12 +1624,12 @@ static int tpacket_rcv(struct sk_buff *s
71     struct timespec ts;
72     struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
73 
74- if (skb->pkt_type == PACKET_LOOPBACK)
75- goto drop;
76-
77     sk = pt->af_packet_priv;
78     po = pkt_sk(sk);
79 
80+ if (!(po->pkt_type & (1 << skb->pkt_type)))
81+ goto drop;
82+
83     if (!net_eq(dev_net(dev), sock_net(sk)))
84         goto drop;
85 
86@@ -2511,6 +2513,7 @@ static int packet_create(struct net *net
87     spin_lock_init(&po->bind_lock);
88     mutex_init(&po->pg_vec_lock);
89     po->prot_hook.func = packet_rcv;
90+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
91 
92     if (sock->type == SOCK_PACKET)
93         po->prot_hook.func = packet_rcv_spkt;
94@@ -3111,6 +3114,16 @@ packet_setsockopt(struct socket *sock, i
95 
96         return fanout_add(sk, val & 0xffff, val >> 16);
97     }
98+ case PACKET_RECV_TYPE:
99+ {
100+ unsigned int val;
101+ if (optlen != sizeof(val))
102+ return -EINVAL;
103+ if (copy_from_user(&val, optval, sizeof(val)))
104+ return -EFAULT;
105+ po->pkt_type = val & ~PACKET_LOOPBACK;
106+ return 0;
107+ }
108     default:
109         return -ENOPROTOOPT;
110     }
111@@ -3165,6 +3178,13 @@ static int packet_getsockopt(struct sock
112     case PACKET_VNET_HDR:
113         val = po->has_vnet_hdr;
114         break;
115+ case PACKET_RECV_TYPE:
116+ if (len > sizeof(unsigned int))
117+ len = sizeof(unsigned int);
118+ val = po->pkt_type;
119+
120+ data = &val;
121+ break;
122     case PACKET_VERSION:
123         val = po->tp_version;
124         break;
125--- a/net/packet/internal.h
126+++ b/net/packet/internal.h
127@@ -111,6 +111,7 @@ struct packet_sock {
128     unsigned int tp_loss:1;
129     unsigned int tp_tstamp;
130     struct packet_type prot_hook ____cacheline_aligned_in_smp;
131+ unsigned int pkt_type;
132 };
133 
134 static struct packet_sock *pkt_sk(struct sock *sk)
135

Archive Download this file



interactive