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: leaf-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/leaf-user
Support Request -- http://leaf-project.org/

Reply via email to