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, 382e4e6a17SHarald Welte const void *matchinfo, 392e4e6a17SHarald Welte int offset, 402e4e6a17SHarald Welte unsigned int protoff, 412e4e6a17SHarald Welte int *hotdrop) 422e4e6a17SHarald Welte { 432e4e6a17SHarald Welte const struct xt_connmark_info *info = matchinfo; 442e4e6a17SHarald Welte u_int32_t ctinfo; 452e4e6a17SHarald Welte const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); 462e4e6a17SHarald Welte if (!ctmark) 472e4e6a17SHarald Welte return 0; 482e4e6a17SHarald Welte 492e4e6a17SHarald Welte return (((*ctmark) & info->mask) == info->mark) ^ info->invert; 502e4e6a17SHarald Welte } 512e4e6a17SHarald Welte 522e4e6a17SHarald Welte static int 532e4e6a17SHarald Welte checkentry(const char *tablename, 542e4e6a17SHarald Welte const void *ip, 552e4e6a17SHarald Welte void *matchinfo, 562e4e6a17SHarald Welte unsigned int matchsize, 572e4e6a17SHarald Welte unsigned int hook_mask) 582e4e6a17SHarald Welte { 595d04bff0SPatrick McHardy struct xt_connmark_info *cm = (struct xt_connmark_info *)matchinfo; 602e4e6a17SHarald Welte 612e4e6a17SHarald Welte if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 622e4e6a17SHarald Welte printk(KERN_WARNING "connmark: only support 32bit mark\n"); 632e4e6a17SHarald Welte return 0; 642e4e6a17SHarald Welte } 652e4e6a17SHarald Welte return 1; 662e4e6a17SHarald Welte } 672e4e6a17SHarald Welte 682e4e6a17SHarald Welte static struct xt_match connmark_match = { 692e4e6a17SHarald Welte .name = "connmark", 705d04bff0SPatrick McHardy .match = match, 715d04bff0SPatrick McHardy .matchsize = sizeof(struct xt_connmark_info), 725d04bff0SPatrick McHardy .checkentry = checkentry, 732e4e6a17SHarald Welte .me = THIS_MODULE 742e4e6a17SHarald Welte }; 752e4e6a17SHarald Welte 765d04bff0SPatrick McHardy static struct xt_match connmark6_match = { 775d04bff0SPatrick McHardy .name = "connmark", 785d04bff0SPatrick McHardy .match = match, 795d04bff0SPatrick McHardy .matchsize = sizeof(struct xt_connmark_info), 805d04bff0SPatrick McHardy .checkentry = checkentry, 815d04bff0SPatrick McHardy .me = THIS_MODULE 825d04bff0SPatrick McHardy }; 832e4e6a17SHarald Welte 842e4e6a17SHarald Welte static int __init init(void) 852e4e6a17SHarald Welte { 862e4e6a17SHarald Welte int ret; 872e4e6a17SHarald Welte 882e4e6a17SHarald Welte need_conntrack(); 892e4e6a17SHarald Welte 902e4e6a17SHarald Welte ret = xt_register_match(AF_INET, &connmark_match); 912e4e6a17SHarald Welte if (ret) 922e4e6a17SHarald Welte return ret; 932e4e6a17SHarald Welte 942e4e6a17SHarald Welte ret = xt_register_match(AF_INET6, &connmark6_match); 952e4e6a17SHarald Welte if (ret) 962e4e6a17SHarald Welte xt_unregister_match(AF_INET, &connmark_match); 972e4e6a17SHarald Welte return ret; 982e4e6a17SHarald Welte } 992e4e6a17SHarald Welte 1002e4e6a17SHarald Welte static void __exit fini(void) 1012e4e6a17SHarald Welte { 1022e4e6a17SHarald Welte xt_unregister_match(AF_INET6, &connmark6_match); 1032e4e6a17SHarald Welte xt_unregister_match(AF_INET, &connmark_match); 1042e4e6a17SHarald Welte } 1052e4e6a17SHarald Welte 1062e4e6a17SHarald Welte module_init(init); 1072e4e6a17SHarald Welte module_exit(fini); 108