19ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai/* IP tables module for matching the value of the IPv4/IPv6 DSCP field 29ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai * 39ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai * (C) 2002 by Harald Welte <laforge@netfilter.org> 49ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai * 59ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai * This program is free software; you can redistribute it and/or modify 69ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai * it under the terms of the GNU General Public License version 2 as 79ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai * published by the Free Software Foundation. 89ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai */ 98bee4bad03c5b601bd6cea123c31025680587cccJan Engelhardt#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 109ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai#include <linux/module.h> 119ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai#include <linux/skbuff.h> 129ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai#include <linux/ip.h> 139ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai#include <linux/ipv6.h> 149ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai#include <net/dsfield.h> 159ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 169ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai#include <linux/netfilter/x_tables.h> 17c3b33e6a2cdefba38d83442ebae2ee42e853ea51Jan Engelhardt#include <linux/netfilter/xt_dscp.h> 189ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 199ba1627617d396135a4d679542a3623d5819e628Yasuyuki KozakaiMODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 202ae15b64e6a1608c840c60df38e8e5eef7b2b8c3Jan EngelhardtMODULE_DESCRIPTION("Xtables: DSCP/TOS field match"); 219ba1627617d396135a4d679542a3623d5819e628Yasuyuki KozakaiMODULE_LICENSE("GPL"); 229ba1627617d396135a4d679542a3623d5819e628Yasuyuki KozakaiMODULE_ALIAS("ipt_dscp"); 239ba1627617d396135a4d679542a3623d5819e628Yasuyuki KozakaiMODULE_ALIAS("ip6t_dscp"); 24c3b33e6a2cdefba38d83442ebae2ee42e853ea51Jan EngelhardtMODULE_ALIAS("ipt_tos"); 25f1095ab51d4297d4a84b64a65c71054183a73486Jan EngelhardtMODULE_ALIAS("ip6t_tos"); 269ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 27d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtstatic bool 2862fc8051083a334578c3f4b3488808f210b4565fJan Engelhardtdscp_mt(const struct sk_buff *skb, struct xt_action_param *par) 299ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai{ 30f7108a20dee44e5bb037f9e48f6a207b42e6ae1cJan Engelhardt const struct xt_dscp_info *info = par->matchinfo; 311d93a9cbad608f6398ba6c5b588c504ccd35a2caJan Engelhardt u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; 321d93a9cbad608f6398ba6c5b588c504ccd35a2caJan Engelhardt 331d93a9cbad608f6398ba6c5b588c504ccd35a2caJan Engelhardt return (dscp == info->dscp) ^ !!info->invert; 341d93a9cbad608f6398ba6c5b588c504ccd35a2caJan Engelhardt} 351d93a9cbad608f6398ba6c5b588c504ccd35a2caJan Engelhardt 36d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtstatic bool 3762fc8051083a334578c3f4b3488808f210b4565fJan Engelhardtdscp_mt6(const struct sk_buff *skb, struct xt_action_param *par) 381d93a9cbad608f6398ba6c5b588c504ccd35a2caJan Engelhardt{ 39f7108a20dee44e5bb037f9e48f6a207b42e6ae1cJan Engelhardt const struct xt_dscp_info *info = par->matchinfo; 400660e03f6b18f19b6bbafe7583265a51b90daf36Arnaldo Carvalho de Melo u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; 419ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 429ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai return (dscp == info->dscp) ^ !!info->invert; 439ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai} 449ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 45b0f38452ff73da7e9e0ddc68cd5c6b93c897ca0dJan Engelhardtstatic int dscp_mt_check(const struct xt_mtchk_param *par) 469ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai{ 479b4fce7a3508a9776534188b6065b206a9608ccfJan Engelhardt const struct xt_dscp_info *info = par->matchinfo; 489ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 499b4fce7a3508a9776534188b6065b206a9608ccfJan Engelhardt if (info->dscp > XT_DSCP_MAX) { 508bee4bad03c5b601bd6cea123c31025680587cccJan Engelhardt pr_info("dscp %x out of range\n", info->dscp); 514a5a5c73b7cfee46a0b1411903cfa0dea532deecJan Engelhardt return -EDOM; 529ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai } 539ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 54bd414ee605ff3ac5fcd79f57269a897879ee4cdeJan Engelhardt return 0; 559ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai} 569ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 5762fc8051083a334578c3f4b3488808f210b4565fJan Engelhardtstatic bool tos_mt(const struct sk_buff *skb, struct xt_action_param *par) 58f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt{ 59f7108a20dee44e5bb037f9e48f6a207b42e6ae1cJan Engelhardt const struct xt_tos_match_info *info = par->matchinfo; 60f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt 61aa5fa3185791aac71c9172d4fda3e8729164b5d1Jan Engelhardt if (par->family == NFPROTO_IPV4) 62f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt return ((ip_hdr(skb)->tos & info->tos_mask) == 63f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt info->tos_value) ^ !!info->invert; 64f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt else 65f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt return ((ipv6_get_dsfield(ipv6_hdr(skb)) & info->tos_mask) == 66f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt info->tos_value) ^ !!info->invert; 67f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt} 68f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt 69d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtstatic struct xt_match dscp_mt_reg[] __read_mostly = { 704470bbc749e5551cce914529309456f631e25120Patrick McHardy { 714470bbc749e5551cce914529309456f631e25120Patrick McHardy .name = "dscp", 72ee999d8b9573df1b547aacdc6d79f86eb79c25cdJan Engelhardt .family = NFPROTO_IPV4, 73d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardt .checkentry = dscp_mt_check, 74d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardt .match = dscp_mt, 754470bbc749e5551cce914529309456f631e25120Patrick McHardy .matchsize = sizeof(struct xt_dscp_info), 764470bbc749e5551cce914529309456f631e25120Patrick McHardy .me = THIS_MODULE, 774470bbc749e5551cce914529309456f631e25120Patrick McHardy }, 784470bbc749e5551cce914529309456f631e25120Patrick McHardy { 794470bbc749e5551cce914529309456f631e25120Patrick McHardy .name = "dscp", 80ee999d8b9573df1b547aacdc6d79f86eb79c25cdJan Engelhardt .family = NFPROTO_IPV6, 81d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardt .checkentry = dscp_mt_check, 82d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardt .match = dscp_mt6, 834470bbc749e5551cce914529309456f631e25120Patrick McHardy .matchsize = sizeof(struct xt_dscp_info), 844470bbc749e5551cce914529309456f631e25120Patrick McHardy .me = THIS_MODULE, 854470bbc749e5551cce914529309456f631e25120Patrick McHardy }, 86c3b33e6a2cdefba38d83442ebae2ee42e853ea51Jan Engelhardt { 87c3b33e6a2cdefba38d83442ebae2ee42e853ea51Jan Engelhardt .name = "tos", 88f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .revision = 1, 89ee999d8b9573df1b547aacdc6d79f86eb79c25cdJan Engelhardt .family = NFPROTO_IPV4, 90f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .match = tos_mt, 91f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .matchsize = sizeof(struct xt_tos_match_info), 92f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .me = THIS_MODULE, 93f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt }, 94f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt { 95f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .name = "tos", 96f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .revision = 1, 97ee999d8b9573df1b547aacdc6d79f86eb79c25cdJan Engelhardt .family = NFPROTO_IPV6, 98f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .match = tos_mt, 99f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .matchsize = sizeof(struct xt_tos_match_info), 100f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt .me = THIS_MODULE, 101f1095ab51d4297d4a84b64a65c71054183a73486Jan Engelhardt }, 1029ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai}; 1039ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 104d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtstatic int __init dscp_mt_init(void) 1059ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai{ 106d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardt return xt_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); 1079ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai} 1089ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 109d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtstatic void __exit dscp_mt_exit(void) 1109ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai{ 111d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardt xt_unregister_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); 1129ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai} 1139ba1627617d396135a4d679542a3623d5819e628Yasuyuki Kozakai 114d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtmodule_init(dscp_mt_init); 115d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtmodule_exit(dscp_mt_exit); 116