OpenWrt – Diff between revs 2 and 3

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 2 Rev 3
1 From: Felix Fietkau <nbd@nbd.name> 1 From: Felix Fietkau <nbd@nbd.name>
2 Subject: net: add an optimization for dealing with raw sockets 2 Subject: net: add an optimization for dealing with raw sockets
3   3  
4 lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6 4 lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6
5 Signed-off-by: Felix Fietkau <nbd@nbd.name> 5 Signed-off-by: Felix Fietkau <nbd@nbd.name>
6 --- 6 ---
7 include/uapi/linux/if_packet.h | 3 +++ 7 include/uapi/linux/if_packet.h | 3 +++
8 net/packet/af_packet.c | 34 +++++++++++++++++++++++++++------- 8 net/packet/af_packet.c | 34 +++++++++++++++++++++++++++-------
9 net/packet/internal.h | 1 + 9 net/packet/internal.h | 1 +
10 3 files changed, 31 insertions(+), 7 deletions(-) 10 3 files changed, 31 insertions(+), 7 deletions(-)
11   11  
12 --- a/include/uapi/linux/if_packet.h 12 --- a/include/uapi/linux/if_packet.h
13 +++ b/include/uapi/linux/if_packet.h 13 +++ b/include/uapi/linux/if_packet.h
14 @@ -31,6 +31,8 @@ struct sockaddr_ll { 14 @@ -31,6 +31,8 @@ struct sockaddr_ll {
15 #define PACKET_KERNEL 7 /* To kernel space */ 15 #define PACKET_KERNEL 7 /* To kernel space */
16 /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */ 16 /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
17 #define PACKET_FASTROUTE 6 /* Fastrouted frame */ 17 #define PACKET_FASTROUTE 6 /* Fastrouted frame */
18 +#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */ 18 +#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
19 + 19 +
20 20
21 /* Packet socket options */ 21 /* Packet socket options */
22 22
23 @@ -56,6 +58,7 @@ struct sockaddr_ll { 23 @@ -56,6 +58,7 @@ struct sockaddr_ll {
24 #define PACKET_QDISC_BYPASS 20 24 #define PACKET_QDISC_BYPASS 20
25 #define PACKET_ROLLOVER_STATS 21 25 #define PACKET_ROLLOVER_STATS 21
26 #define PACKET_FANOUT_DATA 22 26 #define PACKET_FANOUT_DATA 22
27 +#define PACKET_RECV_TYPE 23 27 +#define PACKET_RECV_TYPE 23
28 28
29 #define PACKET_FANOUT_HASH 0 29 #define PACKET_FANOUT_HASH 0
30 #define PACKET_FANOUT_LB 1 30 #define PACKET_FANOUT_LB 1
31 --- a/net/packet/af_packet.c 31 --- a/net/packet/af_packet.c
32 +++ b/net/packet/af_packet.c 32 +++ b/net/packet/af_packet.c
33 @@ -1780,6 +1780,7 @@ static int packet_rcv_spkt(struct sk_buf 33 @@ -1780,6 +1780,7 @@ static int packet_rcv_spkt(struct sk_buf
34 { 34 {
35 struct sock *sk; 35 struct sock *sk;
36 struct sockaddr_pkt *spkt; 36 struct sockaddr_pkt *spkt;
37 + struct packet_sock *po; 37 + struct packet_sock *po;
38 38
39 /* 39 /*
40 * When we registered the protocol we saved the socket in the data 40 * When we registered the protocol we saved the socket in the data
41 @@ -1787,6 +1788,7 @@ static int packet_rcv_spkt(struct sk_buf 41 @@ -1787,6 +1788,7 @@ static int packet_rcv_spkt(struct sk_buf
42 */ 42 */
43 43
44 sk = pt->af_packet_priv; 44 sk = pt->af_packet_priv;
45 + po = pkt_sk(sk); 45 + po = pkt_sk(sk);
46 46
47 /* 47 /*
48 * Yank back the headers [hope the device set this 48 * Yank back the headers [hope the device set this
49 @@ -1799,7 +1801,7 @@ static int packet_rcv_spkt(struct sk_buf 49 @@ -1799,7 +1801,7 @@ static int packet_rcv_spkt(struct sk_buf
50 * so that this procedure is noop. 50 * so that this procedure is noop.
51 */ 51 */
52 52
53 - if (skb->pkt_type == PACKET_LOOPBACK) 53 - if (skb->pkt_type == PACKET_LOOPBACK)
54 + if (!(po->pkt_type & (1 << skb->pkt_type))) 54 + if (!(po->pkt_type & (1 << skb->pkt_type)))
55 goto out; 55 goto out;
56 56
57 if (!net_eq(dev_net(dev), sock_net(sk))) 57 if (!net_eq(dev_net(dev), sock_net(sk)))
58 @@ -2037,12 +2039,12 @@ static int packet_rcv(struct sk_buff *sk 58 @@ -2037,12 +2039,12 @@ static int packet_rcv(struct sk_buff *sk
59 unsigned int snaplen, res; 59 unsigned int snaplen, res;
60 bool is_drop_n_account = false; 60 bool is_drop_n_account = false;
61 61
62 - if (skb->pkt_type == PACKET_LOOPBACK) 62 - if (skb->pkt_type == PACKET_LOOPBACK)
63 - goto drop; 63 - goto drop;
64 - 64 -
65 sk = pt->af_packet_priv; 65 sk = pt->af_packet_priv;
66 po = pkt_sk(sk); 66 po = pkt_sk(sk);
67 67
68 + if (!(po->pkt_type & (1 << skb->pkt_type))) 68 + if (!(po->pkt_type & (1 << skb->pkt_type)))
69 + goto drop; 69 + goto drop;
70 + 70 +
71 if (!net_eq(dev_net(dev), sock_net(sk))) 71 if (!net_eq(dev_net(dev), sock_net(sk)))
72 goto drop; 72 goto drop;
73 73
74 @@ -2168,12 +2170,12 @@ static int tpacket_rcv(struct sk_buff *s 74 @@ -2168,12 +2170,12 @@ static int tpacket_rcv(struct sk_buff *s
75 BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32); 75 BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
76 BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48); 76 BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
77 77
78 - if (skb->pkt_type == PACKET_LOOPBACK) 78 - if (skb->pkt_type == PACKET_LOOPBACK)
79 - goto drop; 79 - goto drop;
80 - 80 -
81 sk = pt->af_packet_priv; 81 sk = pt->af_packet_priv;
82 po = pkt_sk(sk); 82 po = pkt_sk(sk);
83 83
84 + if (!(po->pkt_type & (1 << skb->pkt_type))) 84 + if (!(po->pkt_type & (1 << skb->pkt_type)))
85 + goto drop; 85 + goto drop;
86 + 86 +
87 if (!net_eq(dev_net(dev), sock_net(sk))) 87 if (!net_eq(dev_net(dev), sock_net(sk)))
88 goto drop; 88 goto drop;
89 89
90 @@ -3266,6 +3268,7 @@ static int packet_create(struct net *net 90 @@ -3260,6 +3262,7 @@ static int packet_create(struct net *net
91 mutex_init(&po->pg_vec_lock); 91 mutex_init(&po->pg_vec_lock);
92 po->rollover = NULL; 92 po->rollover = NULL;
93 po->prot_hook.func = packet_rcv; 93 po->prot_hook.func = packet_rcv;
94 + po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); 94 + po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
95 95
96 if (sock->type == SOCK_PACKET) 96 if (sock->type == SOCK_PACKET)
97 po->prot_hook.func = packet_rcv_spkt; 97 po->prot_hook.func = packet_rcv_spkt;
98 @@ -3879,6 +3882,16 @@ packet_setsockopt(struct socket *sock, i 98 @@ -3873,6 +3876,16 @@ packet_setsockopt(struct socket *sock, i
99 po->xmit = val ? packet_direct_xmit : dev_queue_xmit; 99 po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
100 return 0; 100 return 0;
101 } 101 }
102 + case PACKET_RECV_TYPE: 102 + case PACKET_RECV_TYPE:
103 + { 103 + {
104 + unsigned int val; 104 + unsigned int val;
105 + if (optlen != sizeof(val)) 105 + if (optlen != sizeof(val))
106 + return -EINVAL; 106 + return -EINVAL;
107 + if (copy_from_user(&val, optval, sizeof(val))) 107 + if (copy_from_user(&val, optval, sizeof(val)))
108 + return -EFAULT; 108 + return -EFAULT;
109 + po->pkt_type = val & ~BIT(PACKET_LOOPBACK); 109 + po->pkt_type = val & ~BIT(PACKET_LOOPBACK);
110 + return 0; 110 + return 0;
111 + } 111 + }
112 default: 112 default:
113 return -ENOPROTOOPT; 113 return -ENOPROTOOPT;
114 } 114 }
115 @@ -3931,6 +3944,13 @@ static int packet_getsockopt(struct sock 115 @@ -3925,6 +3938,13 @@ static int packet_getsockopt(struct sock
116 case PACKET_VNET_HDR: 116 case PACKET_VNET_HDR:
117 val = po->has_vnet_hdr; 117 val = po->has_vnet_hdr;
118 break; 118 break;
119 + case PACKET_RECV_TYPE: 119 + case PACKET_RECV_TYPE:
120 + if (len > sizeof(unsigned int)) 120 + if (len > sizeof(unsigned int))
121 + len = sizeof(unsigned int); 121 + len = sizeof(unsigned int);
122 + val = po->pkt_type; 122 + val = po->pkt_type;
123 + 123 +
124 + data = &val; 124 + data = &val;
125 + break; 125 + break;
126 case PACKET_VERSION: 126 case PACKET_VERSION:
127 val = po->tp_version; 127 val = po->tp_version;
128 break; 128 break;
129 --- a/net/packet/internal.h 129 --- a/net/packet/internal.h
130 +++ b/net/packet/internal.h 130 +++ b/net/packet/internal.h
131 @@ -128,6 +128,7 @@ struct packet_sock { 131 @@ -128,6 +128,7 @@ struct packet_sock {
132 struct net_device __rcu *cached_dev; 132 struct net_device __rcu *cached_dev;
133 int (*xmit)(struct sk_buff *skb); 133 int (*xmit)(struct sk_buff *skb);
134 struct packet_type prot_hook ____cacheline_aligned_in_smp; 134 struct packet_type prot_hook ____cacheline_aligned_in_smp;
135 + unsigned int pkt_type; 135 + unsigned int pkt_type;
136 }; 136 };
137 137
138 static struct packet_sock *pkt_sk(struct sock *sk) 138 static struct packet_sock *pkt_sk(struct sock *sk)
139   139