git://git.onelab.eu
/
ipfw.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
fdf658c
)
Added the code for xid matching. (The code is not yet enabled)
author
marta
<marta@8c455092-636d-4788-adf5-e71def0336e8>
Fri, 6 Nov 2009 11:54:02 +0000
(11:54 +0000)
committer
marta
<marta@8c455092-636d-4788-adf5-e71def0336e8>
Fri, 6 Nov 2009 11:54:02 +0000
(11:54 +0000)
Minor fixes, comments.
Makefile
patch
|
blob
|
history
dummynet/Makefile
patch
|
blob
|
history
dummynet/include/sys/malloc.h
patch
|
blob
|
history
dummynet/ip_dummynet.c
patch
|
blob
|
history
dummynet/ip_fw2.c
patch
|
blob
|
history
dummynet/ip_fw_pfil.c
patch
|
blob
|
history
dummynet/ipfw2_mod.c
patch
|
blob
|
history
dummynet/missing.h
patch
|
blob
|
history
glue.h
patch
|
blob
|
history
ipfw/Makefile
patch
|
blob
|
history
diff --git
a/Makefile
b/Makefile
index
69b6481
..
a35b722
100644
(file)
--- a/
Makefile
+++ b/
Makefile
@@
-3,6
+3,9
@@
# You can run it manually or also under the Planetlab build.
# Planetlab wants also the 'install' target.
# You can run it manually or also under the Planetlab build.
# Planetlab wants also the 'install' target.
+DATE ?= $(shell date +%Y%m%d)
+SNAPSHOT_NAME=ipfw_linux-$(DATE)
+
_all: all
all clean distclean:
_all: all
all clean distclean:
@@
-10,4
+13,11
@@
all clean distclean:
(cd ipfw && $(MAKE) $(@) )
(cd dummynet && $(MAKE) $(@) )
(cd ipfw && $(MAKE) $(@) )
(cd dummynet && $(MAKE) $(@) )
+snapshot:
+ -ln -s `pwd` /tmp/$(SNAPSHOT_NAME)
+ (cd /tmp; tar cvzhf $(SNAPSHOT_NAME).tgz --exclude .svn \
+ --exclude README.openwrt --exclude tags --exclude NOTES \
+ $(SNAPSHOT_NAME) )
+ -rm /tmp/$(SNAPSHOT_NAME)
+
install:
install:
diff --git
a/dummynet/Makefile
b/dummynet/Makefile
index
b361cba
..
ff68e55
100644
(file)
--- a/
dummynet/Makefile
+++ b/
dummynet/Makefile
@@
-12,8
+12,8
@@
# $(MOD)-y for each $MOD in obj-m, the list of objects
# obj-y same as above, for openwrt
# O_TARGET the link target, for openwrt
# $(MOD)-y for each $MOD in obj-m, the list of objects
# obj-y same as above, for openwrt
# O_TARGET the link target, for openwrt
-#
EXTRA_CFLAGS as the name says... in openwrt
-#
EXTRA_CFLAGS are
used in 2.6.22 module kernel compilation too
+# EXTRA_CFLAGS as the name says... in openwrt
+#
EXTRA_CFLAGS is
used in 2.6.22 module kernel compilation too
#---
$(warning including dummynet/Makefile)
#---
$(warning including dummynet/Makefile)
@@
-53,6
+53,7
@@
ifneq ($(shell echo $(VER)|grep '2.4'),)
WARN += -nostdinc -isystem /usr/lib/gcc/i486-linux-gnu/4.2.4/include
#WARN = -Wp,-MD,/home/luigi/ports-luigi/dummynet-branches/ipfw_mod/dummynet/.ipfw2_mod.o.d
#WARN += -Iinclude -include include/linux/autoconf.h
WARN += -nostdinc -isystem /usr/lib/gcc/i486-linux-gnu/4.2.4/include
#WARN = -Wp,-MD,/home/luigi/ports-luigi/dummynet-branches/ipfw_mod/dummynet/.ipfw2_mod.o.d
#WARN += -Iinclude -include include/linux/autoconf.h
+
WARN += -Wall -Wundef
WARN += -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
WARN += -fno-common -Werror-implicit-function-declaration
WARN += -Wall -Wundef
WARN += -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
WARN += -fno-common -Werror-implicit-function-declaration
@@
-93,13
+94,15
@@
all: include_e
$(MAKE) -C $(KERNELDIR) V=1 M=`pwd` modules
endif
$(MAKE) -C $(KERNELDIR) V=1 M=`pwd` modules
endif
-# the list of object use to build the module
+#-- back to the common section of code
+
+# the list of objects used to build the module
ipfw_mod-y = $(IPFW_SRCS:%.c=%.o)
ipfw_mod-y = $(IPFW_SRCS:%.c=%.o)
-#
Original ipfw + dummynet
+ FreeBSD stuff,
+#
Original ipfw and dummynet sources
+ FreeBSD stuff,
IPFW_SRCS = ip_fw2.c ip_dummynet.c ip_fw_pfil.c in_cksum.c
IPFW_SRCS = ip_fw2.c ip_dummynet.c ip_fw_pfil.c in_cksum.c
-#
m
odule glue and functions missing in linux
+#
M
odule glue and functions missing in linux
IPFW_SRCS += ipfw2_mod.c bsd_compat.c
IPFW_SRCS += ipfw2_mod.c bsd_compat.c
@@
-122,6
+125,7
@@
clean:
distclean: clean
-rm -f .*cmd modules.order opt_*
-rm -rf .tmp_versions include_e
distclean: clean
-rm -f .*cmd modules.order opt_*
-rm -rf .tmp_versions include_e
+ -rm -rf .ip_dummynet.o.d
# support to create empty dirs and files in include_e/
# EDIRS is the list of directories, EFILES is the list of files.
# support to create empty dirs and files in include_e/
# EDIRS is the list of directories, EFILES is the list of files.
diff --git
a/dummynet/include/sys/malloc.h
b/dummynet/include/sys/malloc.h
index
d103801
..
03b9dfb
100644
(file)
--- a/
dummynet/include/sys/malloc.h
+++ b/
dummynet/include/sys/malloc.h
@@
-8,11
+8,10
@@
*/
#ifndef _WIN32 /* this is the linux version */
*/
#ifndef _WIN32 /* this is the linux version */
-#ifndef LINUX_24
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)
+#if !defined (LINUX_24) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)
#define malloc(_size, type, flags) \
kmalloc(_size, GFP_ATOMIC | __GFP_ZERO)
#define malloc(_size, type, flags) \
kmalloc(_size, GFP_ATOMIC | __GFP_ZERO)
-#else /* LINUX < 2.6.22 and LINUX_24 */
+#else /* LINUX <
=
2.6.22 and LINUX_24 */
/* linux 2.6.22 does not zero allocated memory */
#define malloc(_size, type, flags) \
({ int _s = _size; \
/* linux 2.6.22 does not zero allocated memory */
#define malloc(_size, type, flags) \
({ int _s = _size; \
@@
-20,8
+19,7
@@
if (_ret) memset(_ret, 0, _s); \
(_ret); \
})
if (_ret) memset(_ret, 0, _s); \
(_ret); \
})
-#endif /* !LINUX_24 */
-#endif /* LINUX < 2.6.22 */
+#endif /* LINUX <= 2.6.22 */
#define calloc(_n, _s) malloc((_n * _s), NULL, GFP_ATOMIC | __GFP_ZERO)
#define free(_var, type) kfree(_var)
#define calloc(_n, _s) malloc((_n * _s), NULL, GFP_ATOMIC | __GFP_ZERO)
#define free(_var, type) kfree(_var)
diff --git
a/dummynet/ip_dummynet.c
b/dummynet/ip_dummynet.c
index
a613bbf
..
b8cbc2e
100644
(file)
--- a/
dummynet/ip_dummynet.c
+++ b/
dummynet/ip_dummynet.c
@@
-86,6
+86,7
@@
__FBSDID("$FreeBSD: src/sys/netinet/ip_dummynet.c,v 1.110.2.4 2008/10/31 12:58:1
#include <netinet6/ip6_var.h>
#include "missing.h"
#include <netinet6/ip6_var.h>
#include "missing.h"
+
/*
* We keep a private variable for the simulation time, but we could
* probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
/*
* We keep a private variable for the simulation time, but we could
* probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
@@
-959,6
+960,7
@@
dummynet_send(struct mbuf *m)
pkt = dn_tag_get(m);
dst = pkt->dn_dir;
}
pkt = dn_tag_get(m);
dst = pkt->dn_dir;
}
+
switch (dst) {
case DN_TO_IP_OUT:
ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
switch (dst) {
case DN_TO_IP_OUT:
ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
diff --git
a/dummynet/ip_fw2.c
b/dummynet/ip_fw2.c
index
039e084
..
39d6ab7
100644
(file)
--- a/
dummynet/ip_fw2.c
+++ b/
dummynet/ip_fw2.c
@@
-1978,7
+1978,7
@@
dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
}
#endif
}
#endif
-#if
0
+#if
ndef linux /* FreeBSD */
static void
fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
{
static void
fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
{
@@
-1990,57
+1990,45
@@
fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
ugp->fw_ngroups = cr->cr_ngroups;
bcopy(cr->cr_groups, ugp->fw_groups, sizeof(ugp->fw_groups));
}
ugp->fw_ngroups = cr->cr_ngroups;
bcopy(cr->cr_groups, ugp->fw_groups, sizeof(ugp->fw_groups));
}
-#endif
/* no uigid support */
+#endif
static int
check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
u_int16_t src_port, struct ip_fw_ugid *ugp, int *ugid_lookupp,
static int
check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
u_int16_t src_port, struct ip_fw_ugid *ugp, int *ugid_lookupp,
- struct inpcb *inp
, struct sk_buff *skb
)
+ struct inpcb *inp)
{
{
-#if 1 /* Linux */
-
- const struct file *filp;
-
- if (insn->o.opcode == O_JAIL)
- return 0;
+#ifdef linux
+ int match = 0;
+ struct sk_buff *skb = ((struct mbuf *)inp)->m_skb;
- if (skb->sk == NULL || skb->sk->sk_socket == NULL)
- return 0;
-
- filp = skb->sk->sk_socket->file;
- if (filp == NULL)
- return 0;
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,28)
-/* use the current's real uid/gid */
-#define UID f_uid
-#define GID f_gid
-#else /* 2.6.29 */
-/* use the current's file access real uid/gid */
-#define UID f_cred->fsuid
-#define GID f_cred->fsgid
+ if (insn->o.opcode == O_JAIL) {
+#ifdef IPFW_PLANETLAB
+ match = (skb->skb_tag == insn->d[0]);
#endif
#endif
-
- if (insn->o.opcode == O_UID) {
- if (filp->UID != (uid_t)insn->d[0])
- return 0;
+ return match;
}
}
- if (insn->o.opcode == O_GID) {
- if (filp->GID != (gid_t)insn->d[0])
- return 0;
- }
+ if (*ugid_lookupp == 0) { /* actively lookup and copy in cache */
+
+ /* returns null if any element of the chain up to file is null.
+ * if sk != NULL then we also have a reference
+ */
+ *ugid_lookupp = linux_lookup(proto,
+ src_ip.s_addr, htons(src_port),
+ dst_ip.s_addr, htons(dst_port),
+ skb, oif ? 1 : 0, ugp);
- /* check for slice_id matching */
- if (insn->o.opcode == O_GID) {
- if (filp->GID != (gid_t)insn->d[0])
- return 0;
}
}
+ if (*ugid_lookupp < 0)
+ return 0;
- return 1;
+ if (insn->o.opcode == O_UID)
+ match = (ugp->fw_uid == (uid_t)insn->d[0]);
+ return match;
+
+#else /* FreeBSD */
-#else /* FreeBSD original code */
struct inpcbinfo *pi;
int wildcard;
struct inpcb *pcb;
struct inpcbinfo *pi;
int wildcard;
struct inpcb *pcb;
@@
-2650,7
+2638,7
@@
check_body:
proto, oif,
dst_ip, dst_port,
src_ip, src_port, &fw_ugid_cache,
proto, oif,
dst_ip, dst_port,
src_ip, src_port, &fw_ugid_cache,
- &ugid_lookup,
args->inp, m->m_skb
);
+ &ugid_lookup,
(struct inpcb *)args->m
);
break;
case O_RECV:
break;
case O_RECV:
diff --git
a/dummynet/ip_fw_pfil.c
b/dummynet/ip_fw_pfil.c
index
9d65e7f
..
bc1f011
100644
(file)
--- a/
dummynet/ip_fw_pfil.c
+++ b/
dummynet/ip_fw_pfil.c
@@
-122,7
+122,7
@@
again:
args.m = *m0;
args.inp = inp;
ipfw = ipfw_chk(&args);
args.m = *m0;
args.inp = inp;
ipfw = ipfw_chk(&args);
- *m0 = args.m;
+ *m0 = args.m;
/* args.m can be modified by ipfw_chk */
tee = 0;
KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
tee = 0;
KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
@@
-151,6
+151,7
@@
again:
goto drop;
break; /* not reached */
goto drop;
break; /* not reached */
+ /* here packets come after the ipfw classification */
case IP_FW_DUMMYNET:
if (ip_dn_io_ptr == NULL)
goto drop;
case IP_FW_DUMMYNET:
if (ip_dn_io_ptr == NULL)
goto drop;
@@
-248,7
+249,7
@@
again:
args.oif = ifp;
args.inp = inp;
ipfw = ipfw_chk(&args);
args.oif = ifp;
args.inp = inp;
ipfw = ipfw_chk(&args);
- *m0 = args.m;
+ *m0 = args.m;
/* args.m can be modified by ipfw_chk */
tee = 0;
KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
tee = 0;
KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
diff --git
a/dummynet/ipfw2_mod.c
b/dummynet/ipfw2_mod.c
index
26fb5d9
..
ebb16b2
100644
(file)
--- a/
dummynet/ipfw2_mod.c
+++ b/
dummynet/ipfw2_mod.c
@@
-180,7
+180,7
@@
ipfw_ctl_h(struct sockopt *s, int cmd, int dir, int len, void __user *user)
memset(&t, 0, sizeof(t));
s->sopt_td = &t;
memset(&t, 0, sizeof(t));
s->sopt_td = &t;
- printf("%s called with cmd %d len %d\n", __FUNCTION__, cmd, len);
+
//
printf("%s called with cmd %d len %d\n", __FUNCTION__, cmd, len);
if (cmd < IP_DUMMYNET_CONFIGURE && ip_fw_ctl_ptr)
ret = ip_fw_ctl_ptr(s);
if (cmd < IP_DUMMYNET_CONFIGURE && ip_fw_ctl_ptr)
ret = ip_fw_ctl_ptr(s);
@@
-281,6
+281,19
@@
static struct nf_sockopt_ops ipfw_sockopts = {
#define NF_IP_POST_ROUTING NF_INET_POST_ROUTING
#endif
#define NF_IP_POST_ROUTING NF_INET_POST_ROUTING
#endif
+/*
+ * ipfw hooks the POST_ROUTING and the PRE_ROUTING chain.
+ * PlanetLab tags the xid in the LOCAL_INPUT and in the
+ * POST_ROUTING chain, so if we want to intercept the
+ * traffic by using the id we need to hook the LOCAL_INPUT
+ * chain instead of the PRE_ROUTING.
+ */
+#ifdef IPFW_PLANETLAB
+#define IPFW_HOOK_IN NF_IP_LOCAL_IN
+#else
+#define IPFW_HOOK_IN NF_IP_PRE_ROUTING
+#endif
+
/*
* The main netfilter hook.
* To make life simple, we queue everything and then do all the
/*
* The main netfilter hook.
* To make life simple, we queue everything and then do all the
@@
-383,7
+396,7
@@
ipfw2_queue_handler(QH_ARGS)
#endif
/* XXX add the interface */
#endif
/* XXX add the interface */
- if (info->hook ==
NF_IP_PRE_ROUTING
) {
+ if (info->hook ==
IPFW_HOOK_IN
) {
ret = ipfw_check_in(NULL, &m, info->indev, PFIL_IN, NULL);
} else {
ret = ipfw_check_out(NULL, &m, info->outdev, PFIL_OUT, NULL);
ret = ipfw_check_in(NULL, &m, info->indev, PFIL_IN, NULL);
} else {
ret = ipfw_check_out(NULL, &m, info->outdev, PFIL_OUT, NULL);
@@
-460,6
+473,8
@@
linux_lookup(const int proto, const __be32 saddr, const __be16 sport,
{
struct sock *sk;
int ret = -1; /* default return value */
{
struct sock *sk;
int ret = -1; /* default return value */
+ int uid = -1; /* user id */
+ int st = -1; /* state */
if (proto != IPPROTO_TCP)
return -1;
if (proto != IPPROTO_TCP)
return -1;
@@
-495,10
+510,13
@@
linux_lookup(const int proto, const __be32 saddr, const __be16 sport,
/*
* On a match, sk is returned with a refcount.
/*
* On a match, sk is returned with a refcount.
- * In tcp states less that TCP_TIME_WAIT sk references a struct sock
- * which is what we want,
- * otherwise it references a struct inet_timewait_sock which does
- * not point to credentials.
+ * In tcp some states reference a valid struct sock
+ * which is what we want, otherwise the struct sock
+ * referenced can be invalid, as in the case of the
+ * TCP_TIME_WAIT state, when it references a
+ * struct inet_timewait_sock which does not point to credentials.
+ * To be safe we exclude TCP_CLOSE and TCP_LAST_ACK states too.
+ *
* Once again we need conditional code because the UID and GID
* location changes between the two kernels.
*/
* Once again we need conditional code because the UID and GID
* location changes between the two kernels.
*/
@@
-511,15
+529,18
@@
linux_lookup(const int proto, const __be32 saddr, const __be16 sport,
#define _CURR_UID f_cred->fsuid
#define _CURR_GID f_cred->fsgid
#endif
#define _CURR_UID f_cred->fsuid
#define _CURR_GID f_cred->fsgid
#endif
- if (sk->sk_state < TCP_TIME_WAIT && sk->sk_socket && sk->sk_socket->file) {
+ st = sk->sk_state;
+ if (st != TCP_TIME_WAIT && st != TCP_CLOSE && st != TCP_LAST_ACK &&
+ sk->sk_socket && sk->sk_socket->file) {
ugp->fw_uid = sk->sk_socket->file->_CURR_UID;
ugp->fw_uid = sk->sk_socket->file->_CURR_UID;
+ uid = ugp->fw_uid;
ret = 1;
}
sock_put(sk);
#undef _CURR_UID
#undef _CURR_GID
ret = 1;
}
sock_put(sk);
#undef _CURR_UID
#undef _CURR_GID
- //printf("%s dir %d s
kb->dst %p skb->dev %p ret %d\n", __FUNCTION__, dir, skb->dst, skb->dev, re
t);
+ //printf("%s dir %d s
b>dst %p sb>dev %p ret %d id %d st%d\n", __FUNCTION__, dir, skb->dst, skb->dev, ret, uid, s
t);
return ret;
}
return ret;
}
@@
-577,7
+598,7
@@
static struct nf_hook_ops ipfw_ops[] __read_mostly = {
{
.hook = call_ipfw,
.pf = PF_INET,
{
.hook = call_ipfw,
.pf = PF_INET,
- .hooknum =
NF_IP_PRE_ROUTING
,
+ .hooknum =
IPFW_HOOK_IN
,
.priority = NF_IP_PRI_FILTER,
SET_MOD_OWNER
},
.priority = NF_IP_PRI_FILTER,
SET_MOD_OWNER
},
diff --git
a/dummynet/missing.h
b/dummynet/missing.h
index
76b8153
..
c47b117
100644
(file)
--- a/
dummynet/missing.h
+++ b/
dummynet/missing.h
@@
-415,4
+415,10
@@
int in_localaddr(struct in_addr in);
int fnmatch(const char *pattern, const char *string, int flags);
int fnmatch(const char *pattern, const char *string, int flags);
+struct ip_fw_ugid;
+int
+linux_lookup(const int proto, const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const __be16 dport,
+ struct sk_buff *skb, int dir, struct ip_fw_ugid *ugp);
+
#endif /* !_MISSING_H_ */
#endif /* !_MISSING_H_ */
diff --git
a/glue.h
b/glue.h
index
d3571a4
..
ff7ef07
100644
(file)
--- a/
glue.h
+++ b/
glue.h
@@
-86,7
+86,7
@@
enum sopt_dir { SOPT_GET, SOPT_SET };
* so early include this file (to be solved) */
#include <linux/list.h>
#include <linux/in.h> /* struct in_addr */
* so early include this file (to be solved) */
#include <linux/list.h>
#include <linux/in.h> /* struct in_addr */
-#include <linux/in6.h> /* struct in_addr */
+#include <linux/in6.h> /* struct in
6
_addr */
#include <linux/icmp.h>
/*
* LIST_HEAD in queue.h conflict with linux/list.h
#include <linux/icmp.h>
/*
* LIST_HEAD in queue.h conflict with linux/list.h
@@
-206,10
+206,13
@@
struct clockinfo {
int profhz; /* profiling clock frequency */
};
int profhz; /* profiling clock frequency */
};
-
-/*
- *
linux does not have heapsort
+/*
+ * linux does not have a reentrant version of qsort,
+ *
so we the FreeBSD stdlib version.
*/
*/
+void
+qsort_r(void *a, size_t n, size_t es, void *thunk,
+ int cmp_t(void *, const void *, const void *));
#define heapsort(_a, _b, _c, _d) qsort(_a, _b, _c, _d)
#define setprogname(x) /* not present in linux */
#define heapsort(_a, _b, _c, _d) qsort(_a, _b, _c, _d)
#define setprogname(x) /* not present in linux */
@@
-260,6
+263,7
@@
enum ipfw_msg_type {
IP_FW_FLUSH,
IP_FW_ZERO,
IP_FW_GET,
IP_FW_FLUSH,
IP_FW_ZERO,
IP_FW_GET,
+ IP_FW_DYN_GET,
IP_FW_RESETLOG,
IP_FW_NAT_CFG,
IP_FW_RESETLOG,
IP_FW_NAT_CFG,
diff --git
a/ipfw/Makefile
b/ipfw/Makefile
index
5c3ba6a
..
a8a4f47
100644
(file)
--- a/
ipfw/Makefile
+++ b/
ipfw/Makefile
@@
-7,7
+7,7
@@
# Do not set with = or := so we can inherit from the caller
$(warning Building userland ipfw for $(VER))
EXTRA_CFLAGS +=
# Do not set with = or := so we can inherit from the caller
$(warning Building userland ipfw for $(VER))
EXTRA_CFLAGS +=
-EXTRA_CFLAGS += -O
0
+EXTRA_CFLAGS += -O
1
EXTRA_CFLAGS += -include ../glue.h
LDFLAGS=
EXTRA_CFLAGS += -include ../glue.h
LDFLAGS=