1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* Kernel module to match L2TP header parameters. */ |
3 | |
4 | /* (C) 2013 James Chapman <jchapman@katalix.com> |
5 | */ |
6 | |
7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
8 | #include <linux/module.h> |
9 | #include <linux/skbuff.h> |
10 | #include <linux/if_ether.h> |
11 | #include <net/ip.h> |
12 | #include <linux/ipv6.h> |
13 | #include <net/ipv6.h> |
14 | #include <net/udp.h> |
15 | #include <linux/l2tp.h> |
16 | |
17 | #include <linux/netfilter_ipv4.h> |
18 | #include <linux/netfilter_ipv6.h> |
19 | #include <linux/netfilter_ipv4/ip_tables.h> |
20 | #include <linux/netfilter_ipv6/ip6_tables.h> |
21 | #include <linux/netfilter/x_tables.h> |
22 | #include <linux/netfilter/xt_tcpudp.h> |
23 | #include <linux/netfilter/xt_l2tp.h> |
24 | |
25 | /* L2TP header masks */ |
26 | #define L2TP_HDR_T_BIT 0x8000 |
27 | #define L2TP_HDR_L_BIT 0x4000 |
28 | #define L2TP_HDR_VER 0x000f |
29 | |
30 | MODULE_LICENSE("GPL" ); |
31 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>" ); |
32 | MODULE_DESCRIPTION("Xtables: L2TP header match" ); |
33 | MODULE_ALIAS("ipt_l2tp" ); |
34 | MODULE_ALIAS("ip6t_l2tp" ); |
35 | |
36 | /* The L2TP fields that can be matched */ |
37 | struct l2tp_data { |
38 | u32 tid; |
39 | u32 sid; |
40 | u8 type; |
41 | u8 version; |
42 | }; |
43 | |
44 | union l2tp_val { |
45 | __be16 val16[2]; |
46 | __be32 val32; |
47 | }; |
48 | |
49 | static bool l2tp_match(const struct xt_l2tp_info *info, struct l2tp_data *data) |
50 | { |
51 | if ((info->flags & XT_L2TP_TYPE) && (info->type != data->type)) |
52 | return false; |
53 | |
54 | if ((info->flags & XT_L2TP_VERSION) && (info->version != data->version)) |
55 | return false; |
56 | |
57 | /* Check tid only for L2TPv3 control or any L2TPv2 packets */ |
58 | if ((info->flags & XT_L2TP_TID) && |
59 | ((data->type == XT_L2TP_TYPE_CONTROL) || (data->version == 2)) && |
60 | (info->tid != data->tid)) |
61 | return false; |
62 | |
63 | /* Check sid only for L2TP data packets */ |
64 | if ((info->flags & XT_L2TP_SID) && (data->type == XT_L2TP_TYPE_DATA) && |
65 | (info->sid != data->sid)) |
66 | return false; |
67 | |
68 | return true; |
69 | } |
70 | |
71 | /* Parse L2TP header fields when UDP encapsulation is used. Handles |
72 | * L2TPv2 and L2TPv3. Note the L2TPv3 control and data packets have a |
73 | * different format. See |
74 | * RFC2661, Section 3.1, L2TPv2 Header Format |
75 | * RFC3931, Section 3.2.1, L2TPv3 Control Message Header |
76 | * RFC3931, Section 3.2.2, L2TPv3 Data Message Header |
77 | * RFC3931, Section 4.1.2.1, L2TPv3 Session Header over UDP |
78 | */ |
79 | static bool l2tp_udp_mt(const struct sk_buff *skb, struct xt_action_param *par, u16 thoff) |
80 | { |
81 | const struct xt_l2tp_info *info = par->matchinfo; |
82 | int uhlen = sizeof(struct udphdr); |
83 | int offs = thoff + uhlen; |
84 | union l2tp_val *lh; |
85 | union l2tp_val lhbuf; |
86 | u16 flags; |
87 | struct l2tp_data data = { 0, }; |
88 | |
89 | if (par->fragoff != 0) |
90 | return false; |
91 | |
92 | /* Extract L2TP header fields. The flags in the first 16 bits |
93 | * tell us where the other fields are. |
94 | */ |
95 | lh = skb_header_pointer(skb, offset: offs, len: 2, buffer: &lhbuf); |
96 | if (lh == NULL) |
97 | return false; |
98 | |
99 | flags = ntohs(lh->val16[0]); |
100 | if (flags & L2TP_HDR_T_BIT) |
101 | data.type = XT_L2TP_TYPE_CONTROL; |
102 | else |
103 | data.type = XT_L2TP_TYPE_DATA; |
104 | data.version = (u8) flags & L2TP_HDR_VER; |
105 | |
106 | /* Now extract the L2TP tid/sid. These are in different places |
107 | * for L2TPv2 (rfc2661) and L2TPv3 (rfc3931). For L2TPv2, we |
108 | * must also check to see if the length field is present, |
109 | * since this affects the offsets into the packet of the |
110 | * tid/sid fields. |
111 | */ |
112 | if (data.version == 3) { |
113 | lh = skb_header_pointer(skb, offset: offs + 4, len: 4, buffer: &lhbuf); |
114 | if (lh == NULL) |
115 | return false; |
116 | if (data.type == XT_L2TP_TYPE_CONTROL) |
117 | data.tid = ntohl(lh->val32); |
118 | else |
119 | data.sid = ntohl(lh->val32); |
120 | } else if (data.version == 2) { |
121 | if (flags & L2TP_HDR_L_BIT) |
122 | offs += 2; |
123 | lh = skb_header_pointer(skb, offset: offs + 2, len: 4, buffer: &lhbuf); |
124 | if (lh == NULL) |
125 | return false; |
126 | data.tid = (u32) ntohs(lh->val16[0]); |
127 | data.sid = (u32) ntohs(lh->val16[1]); |
128 | } else |
129 | return false; |
130 | |
131 | return l2tp_match(info, data: &data); |
132 | } |
133 | |
134 | /* Parse L2TP header fields for IP encapsulation (no UDP header). |
135 | * L2TPv3 data packets have a different form with IP encap. See |
136 | * RC3931, Section 4.1.1.1, L2TPv3 Session Header over IP. |
137 | * RC3931, Section 4.1.1.2, L2TPv3 Control and Data Traffic over IP. |
138 | */ |
139 | static bool l2tp_ip_mt(const struct sk_buff *skb, struct xt_action_param *par, u16 thoff) |
140 | { |
141 | const struct xt_l2tp_info *info = par->matchinfo; |
142 | union l2tp_val *lh; |
143 | union l2tp_val lhbuf; |
144 | struct l2tp_data data = { 0, }; |
145 | |
146 | /* For IP encap, the L2TP sid is the first 32-bits. */ |
147 | lh = skb_header_pointer(skb, offset: thoff, len: sizeof(lhbuf), buffer: &lhbuf); |
148 | if (lh == NULL) |
149 | return false; |
150 | if (lh->val32 == 0) { |
151 | /* Must be a control packet. The L2TP tid is further |
152 | * into the packet. |
153 | */ |
154 | data.type = XT_L2TP_TYPE_CONTROL; |
155 | lh = skb_header_pointer(skb, offset: thoff + 8, len: sizeof(lhbuf), |
156 | buffer: &lhbuf); |
157 | if (lh == NULL) |
158 | return false; |
159 | data.tid = ntohl(lh->val32); |
160 | } else { |
161 | data.sid = ntohl(lh->val32); |
162 | data.type = XT_L2TP_TYPE_DATA; |
163 | } |
164 | |
165 | data.version = 3; |
166 | |
167 | return l2tp_match(info, data: &data); |
168 | } |
169 | |
170 | static bool l2tp_mt4(const struct sk_buff *skb, struct xt_action_param *par) |
171 | { |
172 | struct iphdr *iph = ip_hdr(skb); |
173 | u8 ipproto = iph->protocol; |
174 | |
175 | /* l2tp_mt_check4 already restricts the transport protocol */ |
176 | switch (ipproto) { |
177 | case IPPROTO_UDP: |
178 | return l2tp_udp_mt(skb, par, thoff: par->thoff); |
179 | case IPPROTO_L2TP: |
180 | return l2tp_ip_mt(skb, par, thoff: par->thoff); |
181 | } |
182 | |
183 | return false; |
184 | } |
185 | |
186 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
187 | static bool l2tp_mt6(const struct sk_buff *skb, struct xt_action_param *par) |
188 | { |
189 | unsigned int thoff = 0; |
190 | unsigned short fragoff = 0; |
191 | int ipproto; |
192 | |
193 | ipproto = ipv6_find_hdr(skb, offset: &thoff, target: -1, fragoff: &fragoff, NULL); |
194 | if (fragoff != 0) |
195 | return false; |
196 | |
197 | /* l2tp_mt_check6 already restricts the transport protocol */ |
198 | switch (ipproto) { |
199 | case IPPROTO_UDP: |
200 | return l2tp_udp_mt(skb, par, thoff); |
201 | case IPPROTO_L2TP: |
202 | return l2tp_ip_mt(skb, par, thoff); |
203 | } |
204 | |
205 | return false; |
206 | } |
207 | #endif |
208 | |
209 | static int l2tp_mt_check(const struct xt_mtchk_param *par) |
210 | { |
211 | const struct xt_l2tp_info *info = par->matchinfo; |
212 | |
213 | /* Check for invalid flags */ |
214 | if (info->flags & ~(XT_L2TP_TID | XT_L2TP_SID | XT_L2TP_VERSION | |
215 | XT_L2TP_TYPE)) { |
216 | pr_info_ratelimited("unknown flags: %x\n" , info->flags); |
217 | return -EINVAL; |
218 | } |
219 | |
220 | /* At least one of tid, sid or type=control must be specified */ |
221 | if ((!(info->flags & XT_L2TP_TID)) && |
222 | (!(info->flags & XT_L2TP_SID)) && |
223 | ((!(info->flags & XT_L2TP_TYPE)) || |
224 | (info->type != XT_L2TP_TYPE_CONTROL))) { |
225 | pr_info_ratelimited("invalid flags combination: %x\n" , |
226 | info->flags); |
227 | return -EINVAL; |
228 | } |
229 | |
230 | /* If version 2 is specified, check that incompatible params |
231 | * are not supplied |
232 | */ |
233 | if (info->flags & XT_L2TP_VERSION) { |
234 | if ((info->version < 2) || (info->version > 3)) { |
235 | pr_info_ratelimited("wrong L2TP version: %u\n" , |
236 | info->version); |
237 | return -EINVAL; |
238 | } |
239 | |
240 | if (info->version == 2) { |
241 | if ((info->flags & XT_L2TP_TID) && |
242 | (info->tid > 0xffff)) { |
243 | pr_info_ratelimited("v2 tid > 0xffff: %u\n" , |
244 | info->tid); |
245 | return -EINVAL; |
246 | } |
247 | if ((info->flags & XT_L2TP_SID) && |
248 | (info->sid > 0xffff)) { |
249 | pr_info_ratelimited("v2 sid > 0xffff: %u\n" , |
250 | info->sid); |
251 | return -EINVAL; |
252 | } |
253 | } |
254 | } |
255 | |
256 | return 0; |
257 | } |
258 | |
259 | static int l2tp_mt_check4(const struct xt_mtchk_param *par) |
260 | { |
261 | const struct xt_l2tp_info *info = par->matchinfo; |
262 | const struct ipt_entry *e = par->entryinfo; |
263 | const struct ipt_ip *ip = &e->ip; |
264 | int ret; |
265 | |
266 | ret = l2tp_mt_check(par); |
267 | if (ret != 0) |
268 | return ret; |
269 | |
270 | if ((ip->proto != IPPROTO_UDP) && |
271 | (ip->proto != IPPROTO_L2TP)) { |
272 | pr_info_ratelimited("missing protocol rule (udp|l2tpip)\n" ); |
273 | return -EINVAL; |
274 | } |
275 | |
276 | if ((ip->proto == IPPROTO_L2TP) && |
277 | (info->version == 2)) { |
278 | pr_info_ratelimited("v2 doesn't support IP mode\n" ); |
279 | return -EINVAL; |
280 | } |
281 | |
282 | return 0; |
283 | } |
284 | |
285 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
286 | static int l2tp_mt_check6(const struct xt_mtchk_param *par) |
287 | { |
288 | const struct xt_l2tp_info *info = par->matchinfo; |
289 | const struct ip6t_entry *e = par->entryinfo; |
290 | const struct ip6t_ip6 *ip = &e->ipv6; |
291 | int ret; |
292 | |
293 | ret = l2tp_mt_check(par); |
294 | if (ret != 0) |
295 | return ret; |
296 | |
297 | if ((ip->proto != IPPROTO_UDP) && |
298 | (ip->proto != IPPROTO_L2TP)) { |
299 | pr_info_ratelimited("missing protocol rule (udp|l2tpip)\n" ); |
300 | return -EINVAL; |
301 | } |
302 | |
303 | if ((ip->proto == IPPROTO_L2TP) && |
304 | (info->version == 2)) { |
305 | pr_info_ratelimited("v2 doesn't support IP mode\n" ); |
306 | return -EINVAL; |
307 | } |
308 | |
309 | return 0; |
310 | } |
311 | #endif |
312 | |
313 | static struct xt_match l2tp_mt_reg[] __read_mostly = { |
314 | { |
315 | .name = "l2tp" , |
316 | .revision = 0, |
317 | .family = NFPROTO_IPV4, |
318 | .match = l2tp_mt4, |
319 | .matchsize = XT_ALIGN(sizeof(struct xt_l2tp_info)), |
320 | .checkentry = l2tp_mt_check4, |
321 | .hooks = ((1 << NF_INET_PRE_ROUTING) | |
322 | (1 << NF_INET_LOCAL_IN) | |
323 | (1 << NF_INET_LOCAL_OUT) | |
324 | (1 << NF_INET_FORWARD)), |
325 | .me = THIS_MODULE, |
326 | }, |
327 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
328 | { |
329 | .name = "l2tp" , |
330 | .revision = 0, |
331 | .family = NFPROTO_IPV6, |
332 | .match = l2tp_mt6, |
333 | .matchsize = XT_ALIGN(sizeof(struct xt_l2tp_info)), |
334 | .checkentry = l2tp_mt_check6, |
335 | .hooks = ((1 << NF_INET_PRE_ROUTING) | |
336 | (1 << NF_INET_LOCAL_IN) | |
337 | (1 << NF_INET_LOCAL_OUT) | |
338 | (1 << NF_INET_FORWARD)), |
339 | .me = THIS_MODULE, |
340 | }, |
341 | #endif |
342 | }; |
343 | |
344 | static int __init l2tp_mt_init(void) |
345 | { |
346 | return xt_register_matches(match: &l2tp_mt_reg[0], ARRAY_SIZE(l2tp_mt_reg)); |
347 | } |
348 | |
349 | static void __exit l2tp_mt_exit(void) |
350 | { |
351 | xt_unregister_matches(match: &l2tp_mt_reg[0], ARRAY_SIZE(l2tp_mt_reg)); |
352 | } |
353 | |
354 | module_init(l2tp_mt_init); |
355 | module_exit(l2tp_mt_exit); |
356 | |