Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.27-rc6 145 lines 4.0 kB view raw
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/x_tables.h> 17#include <linux/netfilter/xt_dscp.h> 18#include <linux/netfilter_ipv4/ipt_tos.h> 19 20MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 21MODULE_DESCRIPTION("Xtables: DSCP/TOS field match"); 22MODULE_LICENSE("GPL"); 23MODULE_ALIAS("ipt_dscp"); 24MODULE_ALIAS("ip6t_dscp"); 25MODULE_ALIAS("ipt_tos"); 26MODULE_ALIAS("ip6t_tos"); 27 28static bool 29dscp_mt(const struct sk_buff *skb, const struct net_device *in, 30 const struct net_device *out, const struct xt_match *match, 31 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) 32{ 33 const struct xt_dscp_info *info = matchinfo; 34 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; 35 36 return (dscp == info->dscp) ^ !!info->invert; 37} 38 39static bool 40dscp_mt6(const struct sk_buff *skb, const struct net_device *in, 41 const struct net_device *out, const struct xt_match *match, 42 const void *matchinfo, int offset, unsigned int protoff, 43 bool *hotdrop) 44{ 45 const struct xt_dscp_info *info = matchinfo; 46 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; 47 48 return (dscp == info->dscp) ^ !!info->invert; 49} 50 51static bool 52dscp_mt_check(const char *tablename, const void *info, 53 const struct xt_match *match, void *matchinfo, 54 unsigned int hook_mask) 55{ 56 const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; 57 58 if (dscp > XT_DSCP_MAX) { 59 printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); 60 return false; 61 } 62 63 return true; 64} 65 66static bool tos_mt_v0(const struct sk_buff *skb, const struct net_device *in, 67 const struct net_device *out, 68 const struct xt_match *match, const void *matchinfo, 69 int offset, unsigned int protoff, bool *hotdrop) 70{ 71 const struct ipt_tos_info *info = matchinfo; 72 73 return (ip_hdr(skb)->tos == info->tos) ^ info->invert; 74} 75 76static bool tos_mt(const struct sk_buff *skb, const struct net_device *in, 77 const struct net_device *out, const struct xt_match *match, 78 const void *matchinfo, int offset, unsigned int protoff, 79 bool *hotdrop) 80{ 81 const struct xt_tos_match_info *info = matchinfo; 82 83 if (match->family == AF_INET) 84 return ((ip_hdr(skb)->tos & info->tos_mask) == 85 info->tos_value) ^ !!info->invert; 86 else 87 return ((ipv6_get_dsfield(ipv6_hdr(skb)) & info->tos_mask) == 88 info->tos_value) ^ !!info->invert; 89} 90 91static struct xt_match dscp_mt_reg[] __read_mostly = { 92 { 93 .name = "dscp", 94 .family = AF_INET, 95 .checkentry = dscp_mt_check, 96 .match = dscp_mt, 97 .matchsize = sizeof(struct xt_dscp_info), 98 .me = THIS_MODULE, 99 }, 100 { 101 .name = "dscp", 102 .family = AF_INET6, 103 .checkentry = dscp_mt_check, 104 .match = dscp_mt6, 105 .matchsize = sizeof(struct xt_dscp_info), 106 .me = THIS_MODULE, 107 }, 108 { 109 .name = "tos", 110 .revision = 0, 111 .family = AF_INET, 112 .match = tos_mt_v0, 113 .matchsize = sizeof(struct ipt_tos_info), 114 .me = THIS_MODULE, 115 }, 116 { 117 .name = "tos", 118 .revision = 1, 119 .family = AF_INET, 120 .match = tos_mt, 121 .matchsize = sizeof(struct xt_tos_match_info), 122 .me = THIS_MODULE, 123 }, 124 { 125 .name = "tos", 126 .revision = 1, 127 .family = AF_INET6, 128 .match = tos_mt, 129 .matchsize = sizeof(struct xt_tos_match_info), 130 .me = THIS_MODULE, 131 }, 132}; 133 134static int __init dscp_mt_init(void) 135{ 136 return xt_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); 137} 138 139static void __exit dscp_mt_exit(void) 140{ 141 xt_unregister_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); 142} 143 144module_init(dscp_mt_init); 145module_exit(dscp_mt_exit);