root/net/netfilter/xt_DSCP.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dscp_tg
  2. dscp_tg6
  3. dscp_tg_check
  4. tos_tg
  5. tos_tg6
  6. dscp_tg_init
  7. dscp_tg_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* x_tables module for setting the IPv4/IPv6 DSCP field, Version 1.8
   3  *
   4  * (C) 2002 by Harald Welte <laforge@netfilter.org>
   5  * based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <mgm@paktronix.com>
   6  *
   7  * See RFC2474 for a description of the DSCP field within the IP Header.
   8 */
   9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  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 
  19 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
  20 MODULE_DESCRIPTION("Xtables: DSCP/TOS field modification");
  21 MODULE_LICENSE("GPL");
  22 MODULE_ALIAS("ipt_DSCP");
  23 MODULE_ALIAS("ip6t_DSCP");
  24 MODULE_ALIAS("ipt_TOS");
  25 MODULE_ALIAS("ip6t_TOS");
  26 
  27 static unsigned int
  28 dscp_tg(struct sk_buff *skb, const struct xt_action_param *par)
  29 {
  30         const struct xt_DSCP_info *dinfo = par->targinfo;
  31         u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
  32 
  33         if (dscp != dinfo->dscp) {
  34                 if (skb_ensure_writable(skb, sizeof(struct iphdr)))
  35                         return NF_DROP;
  36 
  37                 ipv4_change_dsfield(ip_hdr(skb),
  38                                     (__force __u8)(~XT_DSCP_MASK),
  39                                     dinfo->dscp << XT_DSCP_SHIFT);
  40 
  41         }
  42         return XT_CONTINUE;
  43 }
  44 
  45 static unsigned int
  46 dscp_tg6(struct sk_buff *skb, const struct xt_action_param *par)
  47 {
  48         const struct xt_DSCP_info *dinfo = par->targinfo;
  49         u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
  50 
  51         if (dscp != dinfo->dscp) {
  52                 if (skb_ensure_writable(skb, sizeof(struct ipv6hdr)))
  53                         return NF_DROP;
  54 
  55                 ipv6_change_dsfield(ipv6_hdr(skb),
  56                                     (__force __u8)(~XT_DSCP_MASK),
  57                                     dinfo->dscp << XT_DSCP_SHIFT);
  58         }
  59         return XT_CONTINUE;
  60 }
  61 
  62 static int dscp_tg_check(const struct xt_tgchk_param *par)
  63 {
  64         const struct xt_DSCP_info *info = par->targinfo;
  65 
  66         if (info->dscp > XT_DSCP_MAX)
  67                 return -EDOM;
  68         return 0;
  69 }
  70 
  71 static unsigned int
  72 tos_tg(struct sk_buff *skb, const struct xt_action_param *par)
  73 {
  74         const struct xt_tos_target_info *info = par->targinfo;
  75         struct iphdr *iph = ip_hdr(skb);
  76         u_int8_t orig, nv;
  77 
  78         orig = ipv4_get_dsfield(iph);
  79         nv   = (orig & ~info->tos_mask) ^ info->tos_value;
  80 
  81         if (orig != nv) {
  82                 if (skb_ensure_writable(skb, sizeof(struct iphdr)))
  83                         return NF_DROP;
  84                 iph = ip_hdr(skb);
  85                 ipv4_change_dsfield(iph, 0, nv);
  86         }
  87 
  88         return XT_CONTINUE;
  89 }
  90 
  91 static unsigned int
  92 tos_tg6(struct sk_buff *skb, const struct xt_action_param *par)
  93 {
  94         const struct xt_tos_target_info *info = par->targinfo;
  95         struct ipv6hdr *iph = ipv6_hdr(skb);
  96         u_int8_t orig, nv;
  97 
  98         orig = ipv6_get_dsfield(iph);
  99         nv   = (orig & ~info->tos_mask) ^ info->tos_value;
 100 
 101         if (orig != nv) {
 102                 if (skb_ensure_writable(skb, sizeof(struct iphdr)))
 103                         return NF_DROP;
 104                 iph = ipv6_hdr(skb);
 105                 ipv6_change_dsfield(iph, 0, nv);
 106         }
 107 
 108         return XT_CONTINUE;
 109 }
 110 
 111 static struct xt_target dscp_tg_reg[] __read_mostly = {
 112         {
 113                 .name           = "DSCP",
 114                 .family         = NFPROTO_IPV4,
 115                 .checkentry     = dscp_tg_check,
 116                 .target         = dscp_tg,
 117                 .targetsize     = sizeof(struct xt_DSCP_info),
 118                 .table          = "mangle",
 119                 .me             = THIS_MODULE,
 120         },
 121         {
 122                 .name           = "DSCP",
 123                 .family         = NFPROTO_IPV6,
 124                 .checkentry     = dscp_tg_check,
 125                 .target         = dscp_tg6,
 126                 .targetsize     = sizeof(struct xt_DSCP_info),
 127                 .table          = "mangle",
 128                 .me             = THIS_MODULE,
 129         },
 130         {
 131                 .name           = "TOS",
 132                 .revision       = 1,
 133                 .family         = NFPROTO_IPV4,
 134                 .table          = "mangle",
 135                 .target         = tos_tg,
 136                 .targetsize     = sizeof(struct xt_tos_target_info),
 137                 .me             = THIS_MODULE,
 138         },
 139         {
 140                 .name           = "TOS",
 141                 .revision       = 1,
 142                 .family         = NFPROTO_IPV6,
 143                 .table          = "mangle",
 144                 .target         = tos_tg6,
 145                 .targetsize     = sizeof(struct xt_tos_target_info),
 146                 .me             = THIS_MODULE,
 147         },
 148 };
 149 
 150 static int __init dscp_tg_init(void)
 151 {
 152         return xt_register_targets(dscp_tg_reg, ARRAY_SIZE(dscp_tg_reg));
 153 }
 154 
 155 static void __exit dscp_tg_exit(void)
 156 {
 157         xt_unregister_targets(dscp_tg_reg, ARRAY_SIZE(dscp_tg_reg));
 158 }
 159 
 160 module_init(dscp_tg_init);
 161 module_exit(dscp_tg_exit);

/* [<][>][^][v][top][bottom][index][help] */