Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says:

====================
This batch contains one single patch with the l2tp match
for xtables, from James Chapman.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

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