aboutsummaryrefslogtreecommitdiff
path: root/nixos/modules/kernel-patches/0065-net-add-an-optimization-for-dealing-with-raw-sockets.patch
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/kernel-patches/0065-net-add-an-optimization-for-dealing-with-raw-sockets.patch')
-rw-r--r--nixos/modules/kernel-patches/0065-net-add-an-optimization-for-dealing-with-raw-sockets.patch149
1 files changed, 149 insertions, 0 deletions
diff --git a/nixos/modules/kernel-patches/0065-net-add-an-optimization-for-dealing-with-raw-sockets.patch b/nixos/modules/kernel-patches/0065-net-add-an-optimization-for-dealing-with-raw-sockets.patch
new file mode 100644
index 0000000..23cc5a4
--- /dev/null
+++ b/nixos/modules/kernel-patches/0065-net-add-an-optimization-for-dealing-with-raw-sockets.patch
@@ -0,0 +1,149 @@
+From 439a16fc3f6ea86b301b4885c1a27b4579a3e7d1 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Tue, 27 Sep 2022 16:22:06 +0200
+Subject: [PATCH 65/96] net: add an optimization for dealing with raw sockets
+
+lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+ include/uapi/linux/if_packet.h | 3 +++
+ net/packet/af_packet.c | 34 +++++++++++++++++++++++++++-------
+ net/packet/internal.h | 1 +
+ 3 files changed, 31 insertions(+), 7 deletions(-)
+
+diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h
+index c07caf7b40db..baa5581b1fa9 100644
+--- a/include/uapi/linux/if_packet.h
++++ b/include/uapi/linux/if_packet.h
+@@ -33,6 +33,8 @@ struct sockaddr_ll {
+ #define PACKET_KERNEL 7 /* To kernel space */
+ /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
+ #define PACKET_FASTROUTE 6 /* Fastrouted frame */
++#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
++
+
+ /* Packet socket options */
+
+@@ -59,6 +61,7 @@ struct sockaddr_ll {
+ #define PACKET_ROLLOVER_STATS 21
+ #define PACKET_FANOUT_DATA 22
+ #define PACKET_IGNORE_OUTGOING 23
++#define PACKET_RECV_TYPE 24
+
+ #define PACKET_FANOUT_HASH 0
+ #define PACKET_FANOUT_LB 1
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 492bd35cccc0..e8746e713a25 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1861,6 +1861,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,
+ {
+ struct sock *sk;
+ struct sockaddr_pkt *spkt;
++ struct packet_sock *po;
+
+ /*
+ * When we registered the protocol we saved the socket in the data
+@@ -1868,6 +1869,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,
+ */
+
+ sk = pt->af_packet_priv;
++ po = pkt_sk(sk);
+
+ /*
+ * Yank back the headers [hope the device set this
+@@ -1880,7 +1882,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,
+ * 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)))
+@@ -2128,12 +2130,12 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
+ unsigned int snaplen, res;
+ bool is_drop_n_account = false;
+
+- 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;
+
+@@ -2260,12 +2262,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
+ BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
+ BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
+
+- 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;
+
+@@ -3372,6 +3374,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
+ mutex_init(&po->pg_vec_lock);
+ po->rollover = NULL;
+ 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;
+@@ -4011,6 +4014,16 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
+ po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
+ return 0;
+ }
++ case PACKET_RECV_TYPE:
++ {
++ unsigned int val;
++ if (optlen != sizeof(val))
++ return -EINVAL;
++ if (copy_from_sockptr(&val, optval, sizeof(val)))
++ return -EFAULT;
++ po->pkt_type = val & ~BIT(PACKET_LOOPBACK);
++ return 0;
++ }
+ default:
+ return -ENOPROTOOPT;
+ }
+@@ -4067,6 +4080,13 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
+ 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;
+diff --git a/net/packet/internal.h b/net/packet/internal.h
+index 48af35b1aed2..1361d2974453 100644
+--- a/net/packet/internal.h
++++ b/net/packet/internal.h
+@@ -137,6 +137,7 @@ struct packet_sock {
+ int (*xmit)(struct sk_buff *skb);
+ struct packet_type prot_hook ____cacheline_aligned_in_smp;
+ atomic_t tp_drops ____cacheline_aligned_in_smp;
++ unsigned int pkt_type;
+ };
+
+ static inline struct packet_sock *pkt_sk(struct sock *sk)
+--
+2.37.2
+