12e4e6a17SHarald Welte /* This kernel module matches connection mark values set by the 22e4e6a17SHarald Welte * CONNMARK target 32e4e6a17SHarald Welte * 42e4e6a17SHarald Welte * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 52e4e6a17SHarald Welte * by Henrik Nordstrom <hno@marasystems.com> 62e4e6a17SHarald Welte * 72e4e6a17SHarald Welte * This program is free software; you can redistribute it and/or modify 82e4e6a17SHarald Welte * it under the terms of the GNU General Public License as published by 92e4e6a17SHarald Welte * the Free Software Foundation; either version 2 of the License, or 102e4e6a17SHarald Welte * (at your option) any later version. 112e4e6a17SHarald Welte * 122e4e6a17SHarald Welte * This program is distributed in the hope that it will be useful, 132e4e6a17SHarald Welte * but WITHOUT ANY WARRANTY; without even the implied warranty of 142e4e6a17SHarald Welte * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 152e4e6a17SHarald Welte * GNU General Public License for more details. 162e4e6a17SHarald Welte * 172e4e6a17SHarald Welte * You should have received a copy of the GNU General Public License 182e4e6a17SHarald Welte * along with this program; if not, write to the Free Software 192e4e6a17SHarald Welte * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 202e4e6a17SHarald Welte */ 212e4e6a17SHarald Welte 222e4e6a17SHarald Welte #include <linux/module.h> 232e4e6a17SHarald Welte #include <linux/skbuff.h> 242e4e6a17SHarald Welte 252e4e6a17SHarald Welte MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 262e4e6a17SHarald Welte MODULE_DESCRIPTION("IP tables connmark match module"); 272e4e6a17SHarald Welte MODULE_LICENSE("GPL"); 282e4e6a17SHarald Welte MODULE_ALIAS("ipt_connmark"); 292e4e6a17SHarald Welte 302e4e6a17SHarald Welte #include <linux/netfilter/x_tables.h> 312e4e6a17SHarald Welte #include <linux/netfilter/xt_connmark.h> 322e4e6a17SHarald Welte #include <net/netfilter/nf_conntrack_compat.h> 332e4e6a17SHarald Welte 342e4e6a17SHarald Welte static int 352e4e6a17SHarald Welte match(const struct sk_buff *skb, 362e4e6a17SHarald Welte const struct net_device *in, 372e4e6a17SHarald Welte const struct net_device *out, 38c4986734SPatrick McHardy const struct xt_match *match, 392e4e6a17SHarald Welte const void *matchinfo, 402e4e6a17SHarald Welte int offset, 412e4e6a17SHarald Welte unsigned int protoff, 422e4e6a17SHarald Welte int *hotdrop) 432e4e6a17SHarald Welte { 442e4e6a17SHarald Welte const struct xt_connmark_info *info = matchinfo; 452e4e6a17SHarald Welte u_int32_t ctinfo; 462e4e6a17SHarald Welte const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); 472e4e6a17SHarald Welte if (!ctmark) 482e4e6a17SHarald Welte return 0; 492e4e6a17SHarald Welte 502e4e6a17SHarald Welte return (((*ctmark) & info->mask) == info->mark) ^ info->invert; 512e4e6a17SHarald Welte } 522e4e6a17SHarald Welte 532e4e6a17SHarald Welte static int 542e4e6a17SHarald Welte checkentry(const char *tablename, 552e4e6a17SHarald Welte const void *ip, 56c4986734SPatrick McHardy const struct xt_match *match, 572e4e6a17SHarald Welte void *matchinfo, 582e4e6a17SHarald Welte unsigned int matchsize, 592e4e6a17SHarald Welte unsigned int hook_mask) 602e4e6a17SHarald Welte { 615d04bff0SPatrick McHardy struct xt_connmark_info *cm = (struct xt_connmark_info *)matchinfo; 622e4e6a17SHarald Welte 632e4e6a17SHarald Welte if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 642e4e6a17SHarald Welte printk(KERN_WARNING "connmark: only support 32bit mark\n"); 652e4e6a17SHarald Welte return 0; 662e4e6a17SHarald Welte } 67b9f78f9fSPablo Neira Ayuso #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 68b9f78f9fSPablo Neira Ayuso if (nf_ct_l3proto_try_module_get(match->family) < 0) { 69b9f78f9fSPablo Neira Ayuso printk(KERN_WARNING "can't load nf_conntrack support for " 70b9f78f9fSPablo Neira Ayuso "proto=%d\n", match->family); 71b9f78f9fSPablo Neira Ayuso return 0; 72b9f78f9fSPablo Neira Ayuso } 73b9f78f9fSPablo Neira Ayuso #endif 742e4e6a17SHarald Welte return 1; 752e4e6a17SHarald Welte } 762e4e6a17SHarald Welte 77b9f78f9fSPablo Neira Ayuso static void 78b9f78f9fSPablo Neira Ayuso destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) 79b9f78f9fSPablo Neira Ayuso { 80b9f78f9fSPablo Neira Ayuso #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 81b9f78f9fSPablo Neira Ayuso nf_ct_l3proto_module_put(match->family); 82b9f78f9fSPablo Neira Ayuso #endif 83b9f78f9fSPablo Neira Ayuso } 84b9f78f9fSPablo Neira Ayuso 852e4e6a17SHarald Welte static struct xt_match connmark_match = { 862e4e6a17SHarald Welte .name = "connmark", 875d04bff0SPatrick McHardy .match = match, 885d04bff0SPatrick McHardy .matchsize = sizeof(struct xt_connmark_info), 895d04bff0SPatrick McHardy .checkentry = checkentry, 90b9f78f9fSPablo Neira Ayuso .destroy = destroy, 91a45049c5SPablo Neira Ayuso .family = AF_INET, 922e4e6a17SHarald Welte .me = THIS_MODULE 932e4e6a17SHarald Welte }; 942e4e6a17SHarald Welte 955d04bff0SPatrick McHardy static struct xt_match connmark6_match = { 965d04bff0SPatrick McHardy .name = "connmark", 975d04bff0SPatrick McHardy .match = match, 985d04bff0SPatrick McHardy .matchsize = sizeof(struct xt_connmark_info), 995d04bff0SPatrick McHardy .checkentry = checkentry, 100b9f78f9fSPablo Neira Ayuso .destroy = destroy, 101a45049c5SPablo Neira Ayuso .family = AF_INET6, 1025d04bff0SPatrick McHardy .me = THIS_MODULE 1035d04bff0SPatrick McHardy }; 1042e4e6a17SHarald Welte 10565b4b4e8SAndrew Morton static int __init xt_connmark_init(void) 1062e4e6a17SHarald Welte { 1072e4e6a17SHarald Welte int ret; 1082e4e6a17SHarald Welte 1092e4e6a17SHarald Welte need_conntrack(); 1102e4e6a17SHarald Welte 111a45049c5SPablo Neira Ayuso ret = xt_register_match(&connmark_match); 1122e4e6a17SHarald Welte if (ret) 1132e4e6a17SHarald Welte return ret; 1142e4e6a17SHarald Welte 115a45049c5SPablo Neira Ayuso ret = xt_register_match(&connmark6_match); 1162e4e6a17SHarald Welte if (ret) 117a45049c5SPablo Neira Ayuso xt_unregister_match(&connmark_match); 1182e4e6a17SHarald Welte return ret; 1192e4e6a17SHarald Welte } 1202e4e6a17SHarald Welte 12165b4b4e8SAndrew Morton static void __exit xt_connmark_fini(void) 1222e4e6a17SHarald Welte { 123a45049c5SPablo Neira Ayuso xt_unregister_match(&connmark6_match); 124a45049c5SPablo Neira Ayuso xt_unregister_match(&connmark_match); 1252e4e6a17SHarald Welte } 1262e4e6a17SHarald Welte 12765b4b4e8SAndrew Morton module_init(xt_connmark_init); 12865b4b4e8SAndrew Morton module_exit(xt_connmark_fini); 129