blob: ba88f7584ce49e9cbb2952fd61da13db0d06945e [file] [log] [blame]
/*
* Copyright (c) 2003-2013 Patrick McHardy <kaber@trash.net>
*/
#include <stdio.h>
#include <xtables.h>
#include <linux/netfilter/xt_CLASSIFY.h>
#include <linux/pkt_sched.h>
enum {
O_SET_CLASS = 0,
};
static void
CLASSIFY_help(void)
{
printf(
"CLASSIFY target options:\n"
"--set-class MAJOR:MINOR Set skb->priority value (always hexadecimal!)\n");
}
static const struct xt_option_entry CLASSIFY_opts[] = {
{.name = "set-class", .id = O_SET_CLASS, .type = XTTYPE_STRING,
.flags = XTOPT_MAND},
XTOPT_TABLEEND,
};
static int CLASSIFY_string_to_priority(const char *s, unsigned int *p)
{
unsigned int i, j;
if (sscanf(s, "%x:%x", &i, &j) != 2)
return 1;
*p = TC_H_MAKE(i<<16, j);
return 0;
}
static void CLASSIFY_parse(struct xt_option_call *cb)
{
struct xt_classify_target_info *clinfo = cb->data;
xtables_option_parse(cb);
if (CLASSIFY_string_to_priority(cb->arg, &clinfo->priority))
xtables_error(PARAMETER_PROBLEM,
"Bad class value \"%s\"", cb->arg);
}
static void
CLASSIFY_print_class(unsigned int priority, int numeric)
{
printf(" %x:%x", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
}
static void
CLASSIFY_print(const void *ip,
const struct xt_entry_target *target,
int numeric)
{
const struct xt_classify_target_info *clinfo =
(const struct xt_classify_target_info *)target->data;
printf(" CLASSIFY set");
CLASSIFY_print_class(clinfo->priority, numeric);
}
static void
CLASSIFY_save(const void *ip, const struct xt_entry_target *target)
{
const struct xt_classify_target_info *clinfo =
(const struct xt_classify_target_info *)target->data;
printf(" --set-class %.4x:%.4x",
TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
}
static void
arpCLASSIFY_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
CLASSIFY_save(ip, target);
}
static int CLASSIFY_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct xt_classify_target_info *clinfo =
(const struct xt_classify_target_info *)params->target->data;
__u32 handle = clinfo->priority;
xt_xlate_add(xl, "meta priority set ");
switch (handle) {
case TC_H_ROOT:
xt_xlate_add(xl, "root");
break;
case TC_H_UNSPEC:
xt_xlate_add(xl, "none");
break;
default:
xt_xlate_add(xl, "%0x:%0x", TC_H_MAJ(handle) >> 16,
TC_H_MIN(handle));
break;
}
return 1;
}
static struct xtables_target classify_target[] = {
{
.family = NFPROTO_UNSPEC,
.name = "CLASSIFY",
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_classify_target_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)),
.help = CLASSIFY_help,
.print = CLASSIFY_print,
.save = CLASSIFY_save,
.x6_parse = CLASSIFY_parse,
.x6_options = CLASSIFY_opts,
.xlate = CLASSIFY_xlate,
},
{
.family = NFPROTO_ARP,
.name = "CLASSIFY",
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_classify_target_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)),
.help = CLASSIFY_help,
.print = arpCLASSIFY_print,
.x6_parse = CLASSIFY_parse,
.x6_options = CLASSIFY_opts,
.xlate = CLASSIFY_xlate,
},
};
void _init(void)
{
xtables_register_targets(classify_target, ARRAY_SIZE(classify_target));
}