In response to my last question, I had to recompile both the kernel and the
ppp modules to get ppp multilink support to work. With that now functionnal, I
hit another wall with netfilter. Since I have multiple ISP accounts and
multiple broadband connections, being able to use connection tracking and
extended MARK target (to use Shorewall's HIGH_ROUTE_MARKS) was necessary. Here
are the required kernel and iptables patches needed to get both working.
For kernel 2.4.34.6:
*** linux-2.4.34.6.orig/include/linux/netfilter_ipv4/ipt_MARK.h 2007-07-22
09:50:47.000000000 -0400
--- linux-2.4.34.6/include/linux/netfilter_ipv4/ipt_MARK.h 2008-10-22
15:44:35.000000000 -0400
***************
*** 3,8 ****
--- 3,15 ----
struct ipt_mark_target_info {
unsigned long mark;
+ u_int8_t mode;
+ };
+
+ enum {
+ IPT_MARK_SET=0,
+ IPT_MARK_AND,
+ IPT_MARK_OR
};
#endif /*_IPT_MARK_H_target*/
*** linux-2.4.34.6.orig/net/ipv4/netfilter/ip_conntrack_core.c 2008-10-22
12:47:22.000000000 -0400
--- linux-2.4.34.6/net/ipv4/netfilter/ip_conntrack_core.c 2008-10-20
12:22:36.000000000 -0400
***************
*** 746,752 ****
__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = expected;
expected->sibling = conntrack;
! #if CONFIG_IP_NF_CONNTRACK_MARK
conntrack->mark = expected->expectant->mark;
#endif
LIST_DELETE(&ip_conntrack_expect_list, expected);
--- 746,752 ----
__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = expected;
expected->sibling = conntrack;
! #if defined(CONFIG_IP_NF_CONNTRACK_MARK)
conntrack->mark = expected->expectant->mark;
#endif
LIST_DELETE(&ip_conntrack_expect_list, expected);
*** linux-2.4.34.6.orig/net/ipv4/netfilter/ipt_MARK.c 2007-07-22
09:50:47.000000000 -0400
--- linux-2.4.34.6/net/ipv4/netfilter/ipt_MARK.c 2008-10-22
12:59:55.000000000
-0400
***************
*** 16,29 ****
void *userinfo)
{
const struct ipt_mark_target_info *markinfo = targinfo;
! if((*pskb)->nfmark != markinfo->mark) {
! (*pskb)->nfmark = markinfo->mark;
(*pskb)->nfcache |= NFC_ALTERED;
}
return IPT_CONTINUE;
}
static int
checkentry(const char *tablename,
const struct ipt_entry *e,
--- 16,45 ----
void *userinfo)
{
const struct ipt_mark_target_info *markinfo = targinfo;
+ int mark = 0;
! switch (markinfo->mode) {
! case IPT_MARK_SET:
! mark = markinfo->mark;
! break;
!
! case IPT_MARK_AND:
! mark = (*pskb)->nfmark & markinfo->mark;
! break;
!
! case IPT_MARK_OR:
! mark = (*pskb)->nfmark | markinfo->mark;
! break;
! }
!
! if((*pskb)->nfmark != mark) {
! (*pskb)->nfmark = mark;
(*pskb)->nfcache |= NFC_ALTERED;
}
return IPT_CONTINUE;
}
+
static int
checkentry(const char *tablename,
const struct ipt_entry *e,
***************
*** 31,37 ****
unsigned int targinfosize,
unsigned int hook_mask)
{
! if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) {
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_mark_target_info)));
--- 47,55 ----
unsigned int targinfosize,
unsigned int hook_mask)
{
! struct ipt_mark_target_info *markinfo = targinfo;
!
! if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))){
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_mark_target_info)));
***************
*** 43,48 ****
--- 61,74 ----
return 0;
}
+ if (markinfo->mode != IPT_MARK_SET
+ && markinfo->mode != IPT_MARK_AND
+ && markinfo->mode != IPT_MARK_OR) {
+ printk(KERN_WARNING "MARK: unknown mode %u\n",
+ markinfo->mode);
+ return 0;
+ }
+
return 1;
}
***************
*** 51,60 ****
static int __init init(void)
{
! if (ipt_register_target(&ipt_mark_reg))
! return -EINVAL;
! return 0;
}
static void __exit fini(void)
--- 77,86 ----
static int __init init(void)
{
! int err;
! err = ipt_register_target(&ipt_mark_reg);
! return err;
}
static void __exit fini(void)
And for iptables 1.3.5:
*** iptables-1.3.5.orig/include/linux/netfilter_ipv4/ipt_MARK.h 2005-01-04
05:38:28.000000000 -0500
--- iptables-1.3.5/include/linux/netfilter_ipv4/ipt_MARK.h 2008-10-20
11:58:25.000000000 -0400
***************
*** 7,12 ****
--- 7,13 ----
#else
unsigned long mark;
#endif
+ u_int8_t mode;
};
enum {
*** iptables-1.3.5.orig/include/linux/netfilter_ipv4/ipt_conntrack.h
2006-02-01 07:48:01.000000000 -0500
--- iptables-1.3.5/include/linux/netfilter_ipv4/ipt_conntrack.h 2008-10-22
12:01:18.000000000 -0400
***************
*** 6,11 ****
--- 6,12 ----
#define _IPT_CONNTRACK_H
#include <linux/netfilter_ipv4/ip_conntrack.h>
+ #include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
/* backwards compatibility crap. only exists in userspace - HW */
#include <linux/version.h>
***************
*** 64,70 ****
{
unsigned int statemask, statusmask;
! struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
#ifdef KERNEL_64_USERSPACE_32
--- 65,71 ----
{
unsigned int statemask, statusmask;
! struct ip_conntrack_tuple tuple[IP_CT_DIR_MAX];
struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
#ifdef KERNEL_64_USERSPACE_32
*** iptables-1.3.5.orig/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
1969-12-31 19:00:00.000000000 -0500
--- iptables-1.3.5/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
2008-10-22 11:59:02.000000000 -0400
***************
*** 0 ****
--- 1,151 ----
+ #ifndef _IP_CONNTRACK_TUPLE_H
+ #define _IP_CONNTRACK_TUPLE_H
+
+ /* A `tuple' is a structure containing the information to uniquely
+ identify a connection. ie. if two packets have the same tuple, they
+ are in the same connection; if not, they are not.
+
+ We divide the structure along "manipulatable" and
+ "non-manipulatable" lines, for the benefit of the NAT code.
+ */
+
+ /* The protocol-specific manipulable parts of the tuple: always in
+ network order! */
+ union ip_conntrack_manip_proto
+ {
+ /* Add other protocols here. */
+ u_int32_t all;
+
+ struct {
+ u_int16_t port;
+ } tcp;
+ struct {
+ u_int16_t port;
+ } udp;
+ struct {
+ u_int16_t id;
+ } icmp;
+ struct {
+ u_int32_t key;
+ } gre;
+ };
+
+ /* The manipulable part of the tuple. */
+ struct ip_conntrack_manip
+ {
+ u_int32_t ip;
+ union ip_conntrack_manip_proto u;
+ };
+
+ /* This contains the information to distinguish a connection. */
+ struct ip_conntrack_tuple
+ {
+ struct ip_conntrack_manip src;
+
+ /* These are the parts of the tuple which are fixed. */
+ struct {
+ u_int32_t ip;
+ union {
+ /* Add other protocols here. */
+ u_int32_t all;
+
+ struct {
+ u_int16_t port;
+ } tcp;
+ struct {
+ u_int16_t port;
+ } udp;
+ struct {
+ u_int8_t type, code;
+ } icmp;
+ struct {
+ u_int32_t key;
+ } gre;
+ } u;
+
+ /* The protocol. */
+ u_int16_t protonum;
+ } dst;
+ };
+
+ /* This is optimized opposed to a memset of the whole structure. Everything
we
+ * really care about is the source/destination unions */
+ #define IP_CT_TUPLE_U_BLANK(tuple) \
+ do { \
+ (tuple)->src.u.all = 0; \
+ (tuple)->dst.u.all = 0; \
+ } while (0)
+
+ enum ip_conntrack_dir
+ {
+ IP_CT_DIR_ORIGINAL,
+ IP_CT_DIR_REPLY,
+ IP_CT_DIR_MAX
+ };
+
+ #ifdef __KERNEL__
+
+ #define DUMP_TUPLE(tp) \
+ DEBUGP("tuple %p: %u %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", \
+ (tp), (tp)->dst.protonum, \
+ NIPQUAD((tp)->src.ip), ntohl((tp)->src.u.all), \
+ NIPQUAD((tp)->dst.ip), ntohl((tp)->dst.u.all))
+
+ #define DUMP_TUPLE_RAW(x) \
+ DEBUGP("tuple %p: %u %u.%u.%u.%u:0x%08x -> %u.%u.%u.%u:0x%08x\n",\
+ (x), (x)->dst.protonum, \
+ NIPQUAD((x)->src.ip), ntohl((x)->src.u.all), \
+ NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.all))
+
+ #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY :
IP_CT_DIR_ORIGINAL)
+
+ /* If we're the first tuple, it's the original dir. */
+ #define DIRECTION(h) ((enum ip_conntrack_dir)(&(h)->ctrack->tuplehash[1] ==
(h)))
+
+ /* Connections have two entries in the hash table: one for each way */
+ struct ip_conntrack_tuple_hash
+ {
+ struct list_head list;
+
+ struct ip_conntrack_tuple tuple;
+
+ /* this == &ctrack->tuplehash[DIRECTION(this)]. */
+ struct ip_conntrack *ctrack;
+ };
+
+ #endif /* __KERNEL__ */
+
+ static inline int ip_ct_tuple_src_equal(const struct ip_conntrack_tuple
*t1,
+ const struct ip_conntrack_tuple *t2)
+ {
+ return t1->src.ip == t2->src.ip
+ && t1->src.u.all == t2->src.u.all;
+ }
+
+ static inline int ip_ct_tuple_dst_equal(const struct ip_conntrack_tuple
*t1,
+ const struct ip_conntrack_tuple *t2)
+ {
+ return t1->dst.ip == t2->dst.ip
+ && t1->dst.u.all == t2->dst.u.all
+ && t1->dst.protonum == t2->dst.protonum;
+ }
+
+ static inline int ip_ct_tuple_equal(const struct ip_conntrack_tuple *t1,
+ const struct ip_conntrack_tuple *t2)
+ {
+ return ip_ct_tuple_src_equal(t1, t2) && ip_ct_tuple_dst_equal(t1, t2);
+ }
+
+ static inline int ip_ct_tuple_mask_cmp(const struct ip_conntrack_tuple *t,
+ const struct ip_conntrack_tuple *tuple,
+ const struct ip_conntrack_tuple *mask)
+ {
+ return !(((t->src.ip ^ tuple->src.ip) & mask->src.ip)
+ || ((t->dst.ip ^ tuple->dst.ip) & mask->dst.ip)
+ || ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all)
+ || ((t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all)
+ || ((t->dst.protonum ^ tuple->dst.protonum)
+ & mask->dst.protonum));
+ }
+
+ #endif /* _IP_CONNTRACK_TUPLE_H */
pgm
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
------------------------------------------------------------------------
leaf-user mailing list: [email protected]
https://lists.sourceforge.net/lists/listinfo/leaf-user
Support Request -- http://leaf-project.org/