1/* Kernel module to match NFMARK values. */ 2 3/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 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#include <linux/module.h> 11#include <linux/skbuff.h> 12 13#include <linux/netfilter/xt_mark.h> 14#include <linux/netfilter/x_tables.h> 15 16MODULE_LICENSE("GPL"); 17MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 18MODULE_DESCRIPTION("iptables mark matching module"); 19MODULE_ALIAS("ipt_mark"); 20MODULE_ALIAS("ip6t_mark"); 21 22static int 23match(const struct sk_buff *skb, 24 const struct net_device *in, 25 const struct net_device *out, 26 const struct xt_match *match, 27 const void *matchinfo, 28 int offset, 29 unsigned int protoff, 30 int *hotdrop) 31{ 32 const struct xt_mark_info *info = matchinfo; 33 34 return ((skb->mark & info->mask) == info->mark) ^ info->invert; 35} 36 37static int 38checkentry(const char *tablename, 39 const void *entry, 40 const struct xt_match *match, 41 void *matchinfo, 42 unsigned int hook_mask) 43{ 44 const struct xt_mark_info *minfo = matchinfo; 45 46 if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 47 printk(KERN_WARNING "mark: only supports 32bit mark\n"); 48 return 0; 49 } 50 return 1; 51} 52 53#ifdef CONFIG_COMPAT 54struct compat_xt_mark_info { 55 compat_ulong_t mark, mask; 56 u_int8_t invert; 57 u_int8_t __pad1; 58 u_int16_t __pad2; 59}; 60 61static void compat_from_user(void *dst, void *src) 62{ 63 struct compat_xt_mark_info *cm = src; 64 struct xt_mark_info m = { 65 .mark = cm->mark, 66 .mask = cm->mask, 67 .invert = cm->invert, 68 }; 69 memcpy(dst, &m, sizeof(m)); 70} 71 72static int compat_to_user(void __user *dst, void *src) 73{ 74 struct xt_mark_info *m = src; 75 struct compat_xt_mark_info cm = { 76 .mark = m->mark, 77 .mask = m->mask, 78 .invert = m->invert, 79 }; 80 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; 81} 82#endif /* CONFIG_COMPAT */ 83 84static struct xt_match xt_mark_match[] = { 85 { 86 .name = "mark", 87 .family = AF_INET, 88 .checkentry = checkentry, 89 .match = match, 90 .matchsize = sizeof(struct xt_mark_info), 91#ifdef CONFIG_COMPAT 92 .compatsize = sizeof(struct compat_xt_mark_info), 93 .compat_from_user = compat_from_user, 94 .compat_to_user = compat_to_user, 95#endif 96 .me = THIS_MODULE, 97 }, 98 { 99 .name = "mark", 100 .family = AF_INET6, 101 .checkentry = checkentry, 102 .match = match, 103 .matchsize = sizeof(struct xt_mark_info), 104 .me = THIS_MODULE, 105 }, 106}; 107 108static int __init xt_mark_init(void) 109{ 110 return xt_register_matches(xt_mark_match, ARRAY_SIZE(xt_mark_match)); 111} 112 113static void __exit xt_mark_fini(void) 114{ 115 xt_unregister_matches(xt_mark_match, ARRAY_SIZE(xt_mark_match)); 116} 117 118module_init(xt_mark_init); 119module_exit(xt_mark_fini); 120