IPMARK: import 20080304 code base

With truly minimal changes to make it compile.
This commit is contained in:
Jan Engelhardt
2008-04-02 08:50:10 +02:00
parent 05359d1ab2
commit d432d8041a
8 changed files with 291 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ obj-m += compat_xtables.o
obj-${build_CHAOS} += xt_CHAOS.o obj-${build_CHAOS} += xt_CHAOS.o
obj-${build_DELUDE} += xt_DELUDE.o obj-${build_DELUDE} += xt_DELUDE.o
obj-${build_ECHO} += xt_ECHO.o obj-${build_ECHO} += xt_ECHO.o
obj-${build_IPMARK} += xt_IPMARK.o
obj-${build_LOGMARK} += xt_LOGMARK.o obj-${build_LOGMARK} += xt_LOGMARK.o
obj-${build_TARPIT} += xt_TARPIT.o obj-${build_TARPIT} += xt_TARPIT.o
obj-${build_TEE} += xt_TEE.o obj-${build_TEE} += xt_TEE.o

View File

@@ -1,6 +1,7 @@
obj-${build_CHAOS} += libxt_CHAOS.so obj-${build_CHAOS} += libxt_CHAOS.so
obj-${build_DELUDE} += libxt_DELUDE.so obj-${build_DELUDE} += libxt_DELUDE.so
obj-${build_ECHO} += libxt_ECHO.so obj-${build_ECHO} += libxt_ECHO.so
obj-${build_IPMARK} += libxt_IPMARK.so
obj-${build_LOGMARK} += libxt_LOGMARK.so obj-${build_LOGMARK} += libxt_LOGMARK.so
obj-${build_TARPIT} += libxt_TARPIT.so obj-${build_TARPIT} += libxt_TARPIT.so
obj-${build_TEE} += libxt_TEE.so obj-${build_TEE} += libxt_TEE.so

159
extensions/libxt_IPMARK.c Normal file
View File

@@ -0,0 +1,159 @@
/* Shared library add-on to iptables to add IPMARK target support.
* (C) 2003 by Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>
*
* based on original MARK target
*
* This program is distributed under the terms of GNU GPL
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <xtables.h>
#include "xt_IPMARK.h"
#define IPT_ADDR_USED 1
#define IPT_AND_MASK_USED 2
#define IPT_OR_MASK_USED 4
/* Function which prints out usage message. */
static void
help(void)
{
printf(
"IPMARK target options:\n"
" --addr src/dst use source or destination ip address\n"
" --and-mask value logical AND ip address with this value becomes MARK\n"
" --or-mask value logical OR ip address with this value becomes MARK\n"
"\n");
}
static struct option opts[] = {
{ "addr", 1, 0, '1' },
{ "and-mask", 1, 0, '2' },
{ "or-mask", 1, 0, '3' },
{ 0 }
};
/* Initialize the target. */
static void
init(struct xt_entry_target *t)
{
struct ipt_ipmark_target_info *ipmarkinfo =
(struct ipt_ipmark_target_info *)t->data;
ipmarkinfo->andmask=0xffffffff;
ipmarkinfo->ormask=0;
}
/* Function which parses command options; returns true if it
ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **target)
{
struct ipt_ipmark_target_info *ipmarkinfo
= (struct ipt_ipmark_target_info *)(*target)->data;
switch (c) {
char *end;
case '1':
if(!strcmp(optarg, "src")) ipmarkinfo->addr=IPT_IPMARK_SRC;
else if(!strcmp(optarg, "dst")) ipmarkinfo->addr=IPT_IPMARK_DST;
else exit_error(PARAMETER_PROBLEM, "Bad addr value `%s' - should be `src' or `dst'", optarg);
if (*flags & IPT_ADDR_USED)
exit_error(PARAMETER_PROBLEM,
"IPMARK target: Can't specify --addr twice");
*flags |= IPT_ADDR_USED;
break;
case '2':
ipmarkinfo->andmask = strtoul(optarg, &end, 0);
if (*end != '\0' || end == optarg)
exit_error(PARAMETER_PROBLEM, "Bad and-mask value `%s'", optarg);
if (*flags & IPT_AND_MASK_USED)
exit_error(PARAMETER_PROBLEM,
"IPMARK target: Can't specify --and-mask twice");
*flags |= IPT_AND_MASK_USED;
break;
case '3':
ipmarkinfo->ormask = strtoul(optarg, &end, 0);
if (*end != '\0' || end == optarg)
exit_error(PARAMETER_PROBLEM, "Bad or-mask value `%s'", optarg);
if (*flags & IPT_OR_MASK_USED)
exit_error(PARAMETER_PROBLEM,
"IPMARK target: Can't specify --or-mask twice");
*flags |= IPT_OR_MASK_USED;
break;
default:
return 0;
}
return 1;
}
static void
final_check(unsigned int flags)
{
if (!(flags & IPT_ADDR_USED))
exit_error(PARAMETER_PROBLEM,
"IPMARK target: Parameter --addr is required");
if (!(flags & (IPT_AND_MASK_USED | IPT_OR_MASK_USED)))
exit_error(PARAMETER_PROBLEM,
"IPMARK target: Parameter --and-mask or --or-mask is required");
}
/* Prints out the targinfo. */
static void
print(const void *entry, const struct xt_entry_target *target,
int numeric)
{
const struct ipt_ipmark_target_info *ipmarkinfo =
(const struct ipt_ipmark_target_info *)target->data;
if(ipmarkinfo->addr == IPT_IPMARK_SRC)
printf("IPMARK src");
else
printf("IPMARK dst");
printf(" ip and 0x%lx or 0x%lx", ipmarkinfo->andmask, ipmarkinfo->ormask);
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
static void
save(const void *entry, const struct xt_entry_target *target)
{
const struct ipt_ipmark_target_info *ipmarkinfo =
(const struct ipt_ipmark_target_info *)target->data;
if(ipmarkinfo->addr == IPT_IPMARK_SRC)
printf("--addr=src ");
else
printf("--addr=dst ");
if(ipmarkinfo->andmask != 0xffffffff)
printf("--and-mask 0x%lx ", ipmarkinfo->andmask);
if(ipmarkinfo->ormask != 0)
printf("--or-mask 0x%lx ", ipmarkinfo->ormask);
}
static struct xtables_target ipmark = {
.next = NULL,
.name = "IPMARK",
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct ipt_ipmark_target_info)),
.userspacesize = XT_ALIGN(sizeof(struct ipt_ipmark_target_info)),
.help = &help,
.init = &init,
.parse = &parse,
.final_check = &final_check,
.print = &print,
.save = &save,
.extra_opts = opts
};
void _init(void)
{
xtables_register_target(&ipmark);
}

View File

@@ -0,0 +1,45 @@
Allows you to mark a received packet basing on its IP address. This
can replace many mangle/mark entries with only one, if you use
firewall based classifier.
This target is to be used inside the mangle table, in the PREROUTING,
POSTROUTING or FORWARD hooks.
.TP
.BI "--addr " "src/dst"
Use source or destination IP address.
.TP
.BI "--and-mask " "mask"
Perform bitwise `and' on the IP address and this mask.
.TP
.BI "--or-mask " "mask"
Perform bitwise `or' on the IP address and this mask.
.P
The order of IP address bytes is reversed to meet "human order of bytes":
192.168.0.1 is 0xc0a80001. At first the `and' operation is performed, then
`or'.
Examples:
We create a queue for each user, the queue number is adequate
to the IP address of the user, e.g.: all packets going to/from 192.168.5.2
are directed to 1:0502 queue, 192.168.5.12 -> 1:050c etc.
We have one classifier rule:
.IP
tc filter add dev eth3 parent 1:0 protocol ip fw
.P
Earlier we had many rules just like below:
.IP
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.2 -j MARK
--set-mark 0x10502
.IP
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.3 -j MARK
--set-mark 0x10503
.P
Using IPMARK target we can replace all the mangle/mark rules with only one:
.IP
iptables -t mangle -A POSTROUTING -o eth3 -j IPMARK --addr=dst
--and-mask=0xffff --or-mask=0x10000
.P
On the routers with hundreds of users there should be significant load
decrease (e.g. twice).

View File

@@ -0,0 +1,12 @@
config NETFILTER_XT_TARGET_IPMARK
tristate '"IPMARK" target support'
depends on NETFILTER_XTABLES && NETFILTER_ADVANCED
depends on IP_NF_MANGLE || IP6_NF_MANGLE
---help---
This option adds an "IPMARK" target, which allows you to create
rules in the "mangle" table which alter the netfilter mark field
basing on the source or destination ip address of the packet.
This is very useful for very fast massive shaping -- using only one
rule you can direct packets to houndreds different queues. You
will probably find it helpful only if your linux machine acts as a
shaper for many others computers.

59
extensions/xt_IPMARK.c Normal file
View File

@@ -0,0 +1,59 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/version.h>
#include <linux/ip.h>
#include <net/checksum.h>
#include <linux/netfilter/x_tables.h>
#include "xt_IPMARK.h"
#include "compat_xtables.h"
MODULE_AUTHOR("Grzegorz Janoszka <Grzegorz@Janoszka.pl>");
MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address");
MODULE_LICENSE("GPL");
static unsigned int
ipmark_tg(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
{
const struct ipt_ipmark_target_info *ipmarkinfo = targinfo;
struct iphdr *iph = ip_hdr(skb);
unsigned long mark;
if (ipmarkinfo->addr == IPT_IPMARK_SRC)
mark = (unsigned long) ntohl(iph->saddr);
else
mark = (unsigned long) ntohl(iph->daddr);
mark &= ipmarkinfo->andmask;
mark |= ipmarkinfo->ormask;
skb_nfmark(skb) = mark;
return XT_CONTINUE;
}
static struct xt_target ipt_ipmark_reg = {
.name = "IPMARK",
.family = AF_INET,
.table = "mangle",
.target = ipmark_tg,
.targetsize = sizeof(struct ipt_ipmark_target_info),
.me = THIS_MODULE
};
static int __init ipmark_tg_init(void)
{
return xt_register_target(&ipt_ipmark_reg);
}
static void __exit ipmark_tg_exit(void)
{
xt_unregister_target(&ipt_ipmark_reg);
}
module_init(ipmark_tg_init);
module_exit(ipmark_tg_exit);

13
extensions/xt_IPMARK.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef _IPT_IPMARK_H_target
#define _IPT_IPMARK_H_target
struct ipt_ipmark_target_info {
unsigned long andmask;
unsigned long ormask;
unsigned char addr;
};
#define IPT_IPMARK_SRC 0
#define IPT_IPMARK_DST 1
#endif /*_IPT_IPMARK_H_target*/

View File

@@ -3,6 +3,7 @@
build_CHAOS=m build_CHAOS=m
build_DELUDE=m build_DELUDE=m
build_ECHO= build_ECHO=
build_IPMARK=m
build_LOGMARK=m build_LOGMARK=m
build_TARPIT=m build_TARPIT=m
build_TEE=m build_TEE=m