1 From: Felix Fietkau <nbd@nbd.name>
2 Subject: net: add an optimization for dealing with raw sockets
4 lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6
5 Signed-off-by: Felix Fietkau <nbd@nbd.name>
7 include/uapi/linux/if_packet.h | 3 +++
8 net/packet/af_packet.c | 34 +++++++++++++++++++++++++++-------
9 net/packet/internal.h | 1 +
10 3 files changed, 31 insertions(+), 7 deletions(-)
12 --- a/include/uapi/linux/if_packet.h
13 +++ b/include/uapi/linux/if_packet.h
14 @@ -33,6 +33,8 @@ struct sockaddr_ll {
15 #define PACKET_KERNEL 7 /* To kernel space */
16 /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
17 #define PACKET_FASTROUTE 6 /* Fastrouted frame */
18 +#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
21 /* Packet socket options */
23 @@ -59,6 +61,7 @@ struct sockaddr_ll {
24 #define PACKET_ROLLOVER_STATS 21
25 #define PACKET_FANOUT_DATA 22
26 #define PACKET_IGNORE_OUTGOING 23
27 +#define PACKET_RECV_TYPE 24
29 #define PACKET_FANOUT_HASH 0
30 #define PACKET_FANOUT_LB 1
31 --- a/net/packet/af_packet.c
32 +++ b/net/packet/af_packet.c
33 @@ -1825,6 +1825,7 @@ static int packet_rcv_spkt(struct sk_buf
36 struct sockaddr_pkt *spkt;
37 + struct packet_sock *po;
40 * When we registered the protocol we saved the socket in the data
41 @@ -1832,6 +1833,7 @@ static int packet_rcv_spkt(struct sk_buf
44 sk = pt->af_packet_priv;
48 * Yank back the headers [hope the device set this
49 @@ -1844,7 +1846,7 @@ static int packet_rcv_spkt(struct sk_buf
50 * so that this procedure is noop.
53 - if (skb->pkt_type == PACKET_LOOPBACK)
54 + if (!(po->pkt_type & (1 << skb->pkt_type)))
57 if (!net_eq(dev_net(dev), sock_net(sk)))
58 @@ -2092,12 +2094,12 @@ static int packet_rcv(struct sk_buff *sk
59 unsigned int snaplen, res;
60 bool is_drop_n_account = false;
62 - if (skb->pkt_type == PACKET_LOOPBACK)
65 sk = pt->af_packet_priv;
68 + if (!(po->pkt_type & (1 << skb->pkt_type)))
71 if (!net_eq(dev_net(dev), sock_net(sk)))
74 @@ -2223,12 +2225,12 @@ static int tpacket_rcv(struct sk_buff *s
75 BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
76 BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
78 - if (skb->pkt_type == PACKET_LOOPBACK)
81 sk = pt->af_packet_priv;
84 + if (!(po->pkt_type & (1 << skb->pkt_type)))
87 if (!net_eq(dev_net(dev), sock_net(sk)))
90 @@ -3339,6 +3341,7 @@ static int packet_create(struct net *net
91 mutex_init(&po->pg_vec_lock);
93 po->prot_hook.func = packet_rcv;
94 + po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
96 if (sock->type == SOCK_PACKET)
97 po->prot_hook.func = packet_rcv_spkt;
98 @@ -3979,6 +3982,16 @@ packet_setsockopt(struct socket *sock, i
99 po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
102 + case PACKET_RECV_TYPE:
105 + if (optlen != sizeof(val))
107 + if (copy_from_sockptr(&val, optval, sizeof(val)))
109 + po->pkt_type = val & ~BIT(PACKET_LOOPBACK);
115 @@ -4035,6 +4048,13 @@ static int packet_getsockopt(struct sock
116 case PACKET_VNET_HDR:
117 val = po->has_vnet_hdr;
119 + case PACKET_RECV_TYPE:
120 + if (len > sizeof(unsigned int))
121 + len = sizeof(unsigned int);
122 + val = po->pkt_type;
127 val = po->tp_version;
129 --- a/net/packet/internal.h
130 +++ b/net/packet/internal.h
131 @@ -137,6 +137,7 @@ struct packet_sock {
132 int (*xmit)(struct sk_buff *skb);
133 struct packet_type prot_hook ____cacheline_aligned_in_smp;
134 atomic_t tp_drops ____cacheline_aligned_in_smp;
135 + unsigned int pkt_type;
138 static inline struct packet_sock *pkt_sk(struct sock *sk)