OpenWrt – Diff between revs 2 and 3
?pathlinks?
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 | |