0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 #include <linux/module.h>
0010 #include <linux/skbuff.h>
0011 #include <linux/netfilter/x_tables.h>
0012 #include <linux/netfilter_ipv4/ip_tables.h>
0013 #include <net/tcp.h>
0014 #include <net/udp.h>
0015 #include <net/icmp.h>
0016 #include <net/sock.h>
0017 #include <net/inet_sock.h>
0018 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
0019
0020 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
0021 #include <linux/netfilter_ipv6/ip6_tables.h>
0022 #include <net/inet6_hashtables.h>
0023 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
0024 #endif
0025
0026 #include <net/netfilter/nf_socket.h>
0027 #include <linux/netfilter/xt_socket.h>
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 static bool
0049 socket_match(const struct sk_buff *skb, struct xt_action_param *par,
0050 const struct xt_socket_mtinfo1 *info)
0051 {
0052 struct sk_buff *pskb = (struct sk_buff *)skb;
0053 struct sock *sk = skb->sk;
0054
0055 if (sk && !net_eq(xt_net(par), sock_net(sk)))
0056 sk = NULL;
0057
0058 if (!sk)
0059 sk = nf_sk_lookup_slow_v4(xt_net(par), skb, xt_in(par));
0060
0061 if (sk) {
0062 bool wildcard;
0063 bool transparent = true;
0064
0065
0066
0067
0068 wildcard = (!(info->flags & XT_SOCKET_NOWILDCARD) &&
0069 sk_fullsock(sk) &&
0070 inet_sk(sk)->inet_rcv_saddr == 0);
0071
0072
0073
0074
0075 if (info->flags & XT_SOCKET_TRANSPARENT)
0076 transparent = inet_sk_transparent(sk);
0077
0078 if (info->flags & XT_SOCKET_RESTORESKMARK && !wildcard &&
0079 transparent && sk_fullsock(sk))
0080 pskb->mark = sk->sk_mark;
0081
0082 if (sk != skb->sk)
0083 sock_gen_put(sk);
0084
0085 if (wildcard || !transparent)
0086 sk = NULL;
0087 }
0088
0089 return sk != NULL;
0090 }
0091
0092 static bool
0093 socket_mt4_v0(const struct sk_buff *skb, struct xt_action_param *par)
0094 {
0095 static struct xt_socket_mtinfo1 xt_info_v0 = {
0096 .flags = 0,
0097 };
0098
0099 return socket_match(skb, par, &xt_info_v0);
0100 }
0101
0102 static bool
0103 socket_mt4_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par)
0104 {
0105 return socket_match(skb, par, par->matchinfo);
0106 }
0107
0108 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
0109 static bool
0110 socket_mt6_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par)
0111 {
0112 const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
0113 struct sk_buff *pskb = (struct sk_buff *)skb;
0114 struct sock *sk = skb->sk;
0115
0116 if (sk && !net_eq(xt_net(par), sock_net(sk)))
0117 sk = NULL;
0118
0119 if (!sk)
0120 sk = nf_sk_lookup_slow_v6(xt_net(par), skb, xt_in(par));
0121
0122 if (sk) {
0123 bool wildcard;
0124 bool transparent = true;
0125
0126
0127
0128
0129 wildcard = (!(info->flags & XT_SOCKET_NOWILDCARD) &&
0130 sk_fullsock(sk) &&
0131 ipv6_addr_any(&sk->sk_v6_rcv_saddr));
0132
0133
0134
0135
0136 if (info->flags & XT_SOCKET_TRANSPARENT)
0137 transparent = inet_sk_transparent(sk);
0138
0139 if (info->flags & XT_SOCKET_RESTORESKMARK && !wildcard &&
0140 transparent && sk_fullsock(sk))
0141 pskb->mark = sk->sk_mark;
0142
0143 if (sk != skb->sk)
0144 sock_gen_put(sk);
0145
0146 if (wildcard || !transparent)
0147 sk = NULL;
0148 }
0149
0150 return sk != NULL;
0151 }
0152 #endif
0153
0154 static int socket_mt_enable_defrag(struct net *net, int family)
0155 {
0156 switch (family) {
0157 case NFPROTO_IPV4:
0158 return nf_defrag_ipv4_enable(net);
0159 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
0160 case NFPROTO_IPV6:
0161 return nf_defrag_ipv6_enable(net);
0162 #endif
0163 }
0164 WARN_ONCE(1, "Unknown family %d\n", family);
0165 return 0;
0166 }
0167
0168 static int socket_mt_v1_check(const struct xt_mtchk_param *par)
0169 {
0170 const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
0171 int err;
0172
0173 err = socket_mt_enable_defrag(par->net, par->family);
0174 if (err)
0175 return err;
0176
0177 if (info->flags & ~XT_SOCKET_FLAGS_V1) {
0178 pr_info_ratelimited("unknown flags 0x%x\n",
0179 info->flags & ~XT_SOCKET_FLAGS_V1);
0180 return -EINVAL;
0181 }
0182 return 0;
0183 }
0184
0185 static int socket_mt_v2_check(const struct xt_mtchk_param *par)
0186 {
0187 const struct xt_socket_mtinfo2 *info = (struct xt_socket_mtinfo2 *) par->matchinfo;
0188 int err;
0189
0190 err = socket_mt_enable_defrag(par->net, par->family);
0191 if (err)
0192 return err;
0193
0194 if (info->flags & ~XT_SOCKET_FLAGS_V2) {
0195 pr_info_ratelimited("unknown flags 0x%x\n",
0196 info->flags & ~XT_SOCKET_FLAGS_V2);
0197 return -EINVAL;
0198 }
0199 return 0;
0200 }
0201
0202 static int socket_mt_v3_check(const struct xt_mtchk_param *par)
0203 {
0204 const struct xt_socket_mtinfo3 *info =
0205 (struct xt_socket_mtinfo3 *)par->matchinfo;
0206 int err;
0207
0208 err = socket_mt_enable_defrag(par->net, par->family);
0209 if (err)
0210 return err;
0211 if (info->flags & ~XT_SOCKET_FLAGS_V3) {
0212 pr_info_ratelimited("unknown flags 0x%x\n",
0213 info->flags & ~XT_SOCKET_FLAGS_V3);
0214 return -EINVAL;
0215 }
0216 return 0;
0217 }
0218
0219 static void socket_mt_destroy(const struct xt_mtdtor_param *par)
0220 {
0221 if (par->family == NFPROTO_IPV4)
0222 nf_defrag_ipv4_disable(par->net);
0223 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
0224 else if (par->family == NFPROTO_IPV6)
0225 nf_defrag_ipv6_disable(par->net);
0226 #endif
0227 }
0228
0229 static struct xt_match socket_mt_reg[] __read_mostly = {
0230 {
0231 .name = "socket",
0232 .revision = 0,
0233 .family = NFPROTO_IPV4,
0234 .match = socket_mt4_v0,
0235 .hooks = (1 << NF_INET_PRE_ROUTING) |
0236 (1 << NF_INET_LOCAL_IN),
0237 .me = THIS_MODULE,
0238 },
0239 {
0240 .name = "socket",
0241 .revision = 1,
0242 .family = NFPROTO_IPV4,
0243 .match = socket_mt4_v1_v2_v3,
0244 .destroy = socket_mt_destroy,
0245 .checkentry = socket_mt_v1_check,
0246 .matchsize = sizeof(struct xt_socket_mtinfo1),
0247 .hooks = (1 << NF_INET_PRE_ROUTING) |
0248 (1 << NF_INET_LOCAL_IN),
0249 .me = THIS_MODULE,
0250 },
0251 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
0252 {
0253 .name = "socket",
0254 .revision = 1,
0255 .family = NFPROTO_IPV6,
0256 .match = socket_mt6_v1_v2_v3,
0257 .checkentry = socket_mt_v1_check,
0258 .matchsize = sizeof(struct xt_socket_mtinfo1),
0259 .destroy = socket_mt_destroy,
0260 .hooks = (1 << NF_INET_PRE_ROUTING) |
0261 (1 << NF_INET_LOCAL_IN),
0262 .me = THIS_MODULE,
0263 },
0264 #endif
0265 {
0266 .name = "socket",
0267 .revision = 2,
0268 .family = NFPROTO_IPV4,
0269 .match = socket_mt4_v1_v2_v3,
0270 .checkentry = socket_mt_v2_check,
0271 .destroy = socket_mt_destroy,
0272 .matchsize = sizeof(struct xt_socket_mtinfo1),
0273 .hooks = (1 << NF_INET_PRE_ROUTING) |
0274 (1 << NF_INET_LOCAL_IN),
0275 .me = THIS_MODULE,
0276 },
0277 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
0278 {
0279 .name = "socket",
0280 .revision = 2,
0281 .family = NFPROTO_IPV6,
0282 .match = socket_mt6_v1_v2_v3,
0283 .checkentry = socket_mt_v2_check,
0284 .destroy = socket_mt_destroy,
0285 .matchsize = sizeof(struct xt_socket_mtinfo1),
0286 .hooks = (1 << NF_INET_PRE_ROUTING) |
0287 (1 << NF_INET_LOCAL_IN),
0288 .me = THIS_MODULE,
0289 },
0290 #endif
0291 {
0292 .name = "socket",
0293 .revision = 3,
0294 .family = NFPROTO_IPV4,
0295 .match = socket_mt4_v1_v2_v3,
0296 .checkentry = socket_mt_v3_check,
0297 .destroy = socket_mt_destroy,
0298 .matchsize = sizeof(struct xt_socket_mtinfo1),
0299 .hooks = (1 << NF_INET_PRE_ROUTING) |
0300 (1 << NF_INET_LOCAL_IN),
0301 .me = THIS_MODULE,
0302 },
0303 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
0304 {
0305 .name = "socket",
0306 .revision = 3,
0307 .family = NFPROTO_IPV6,
0308 .match = socket_mt6_v1_v2_v3,
0309 .checkentry = socket_mt_v3_check,
0310 .destroy = socket_mt_destroy,
0311 .matchsize = sizeof(struct xt_socket_mtinfo1),
0312 .hooks = (1 << NF_INET_PRE_ROUTING) |
0313 (1 << NF_INET_LOCAL_IN),
0314 .me = THIS_MODULE,
0315 },
0316 #endif
0317 };
0318
0319 static int __init socket_mt_init(void)
0320 {
0321 return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
0322 }
0323
0324 static void __exit socket_mt_exit(void)
0325 {
0326 xt_unregister_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
0327 }
0328
0329 module_init(socket_mt_init);
0330 module_exit(socket_mt_exit);
0331
0332 MODULE_LICENSE("GPL");
0333 MODULE_AUTHOR("Krisztian Kovacs, Balazs Scheidler");
0334 MODULE_DESCRIPTION("x_tables socket match module");
0335 MODULE_ALIAS("ipt_socket");
0336 MODULE_ALIAS("ip6t_socket");