1/* IP tables module for matching the value of the IPv4/IPv6 DSCP field 2 * 3 * (C) 2002 by Harald Welte <laforge@netfilter.org> 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#include <linux/ip.h> 13#include <linux/ipv6.h> 14#include <net/dsfield.h> 15 16#include <linux/netfilter/xt_dscp.h> 17#include <linux/netfilter/x_tables.h> 18 19MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 20MODULE_DESCRIPTION("x_tables DSCP matching module"); 21MODULE_LICENSE("GPL"); 22MODULE_ALIAS("ipt_dscp"); 23MODULE_ALIAS("ip6t_dscp"); 24 25static int match(const struct sk_buff *skb, 26 const struct net_device *in, 27 const struct net_device *out, 28 const struct xt_match *match, 29 const void *matchinfo, 30 int offset, 31 unsigned int protoff, 32 int *hotdrop) 33{ 34 const struct xt_dscp_info *info = matchinfo; 35 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; 36 37 return (dscp == info->dscp) ^ !!info->invert; 38} 39 40static int match6(const struct sk_buff *skb, 41 const struct net_device *in, 42 const struct net_device *out, 43 const struct xt_match *match, 44 const void *matchinfo, 45 int offset, 46 unsigned int protoff, 47 int *hotdrop) 48{ 49 const struct xt_dscp_info *info = matchinfo; 50 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; 51 52 return (dscp == info->dscp) ^ !!info->invert; 53} 54 55static int checkentry(const char *tablename, 56 const void *info, 57 const struct xt_match *match, 58 void *matchinfo, 59 unsigned int hook_mask) 60{ 61 const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; 62 63 if (dscp > XT_DSCP_MAX) { 64 printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); 65 return 0; 66 } 67 68 return 1; 69} 70 71static struct xt_match xt_dscp_match[] = { 72 { 73 .name = "dscp", 74 .family = AF_INET, 75 .checkentry = checkentry, 76 .match = match, 77 .matchsize = sizeof(struct xt_dscp_info), 78 .me = THIS_MODULE, 79 }, 80 { 81 .name = "dscp", 82 .family = AF_INET6, 83 .checkentry = checkentry, 84 .match = match6, 85 .matchsize = sizeof(struct xt_dscp_info), 86 .me = THIS_MODULE, 87 }, 88}; 89 90static int __init xt_dscp_match_init(void) 91{ 92 return xt_register_matches(xt_dscp_match, ARRAY_SIZE(xt_dscp_match)); 93} 94 95static void __exit xt_dscp_match_fini(void) 96{ 97 xt_unregister_matches(xt_dscp_match, ARRAY_SIZE(xt_dscp_match)); 98} 99 100module_init(xt_dscp_match_init); 101module_exit(xt_dscp_match_fini); 102