diff -Nru linux-2.4.20/Documentation/Configure.help linux-2.4.20-pom2patch/Documentation/Configure.help
--- linux-2.4.20/Documentation/Configure.help	2003-05-02 12:56:53.000000000 -0500
+++ linux-2.4.20-pom2patch/Documentation/Configure.help	2003-05-02 12:56:57.000000000 -0500
@@ -2522,6 +2522,28 @@
   If you want to compile it as a module, say 'M' here and read
   Documentation/modules.txt.  If unsure, say 'N'.
 
+Per connection mark support
+CONFIG_IP_NF_CONNTRACK_MARK
+  This option enables support for connection marks, used by the
+  `CONNMARK' target and `connmark' match. Similar to the mark value
+  of packets, but this mark value is kept in the conntrack session
+  instead of the individual packets.
+
+CONNMARK target support
+CONFIG_IP_NF_TARGET_CONNMARK
+  This option adds a `CONNMARK' target, which allows one to manipulate
+  the connection mark value.  Similar to the MARK target, but
+  affects the connection mark value rather than the packet mark value.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  The module will be called
+  ipt_CONNMARK.o.  If unsure, say `N'.
+
+connmark match support
+CONFIP_IP_NF_MATCH_CONNMARK
+  This option adds a `connmark' match, which allows you to match the
+  connection mark value previously set for the session by `CONNMARK'. 
+
 FTP protocol support
 CONFIG_IP_NF_FTP
   Tracking FTP connections is problematic: special helpers are
diff -Nru linux-2.4.20/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.20-pom2patch/include/linux/netfilter_ipv4/ip_conntrack.h
--- linux-2.4.20/include/linux/netfilter_ipv4/ip_conntrack.h	2002-11-28 17:53:15.000000000 -0600
+++ linux-2.4.20-pom2patch/include/linux/netfilter_ipv4/ip_conntrack.h	2003-05-02 12:56:57.000000000 -0500
@@ -198,6 +198,9 @@
 	} nat;
 #endif /* CONFIG_IP_NF_NAT_NEEDED */
 
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+	unsigned long mark;
+#endif
 };
 
 /* get master conntrack via master expectation */
diff -Nru linux-2.4.20/include/linux/netfilter_ipv4/ipt_CONNMARK.h linux-2.4.20-pom2patch/include/linux/netfilter_ipv4/ipt_CONNMARK.h
--- linux-2.4.20/include/linux/netfilter_ipv4/ipt_CONNMARK.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.4.20-pom2patch/include/linux/netfilter_ipv4/ipt_CONNMARK.h	2003-05-02 12:56:57.000000000 -0500
@@ -0,0 +1,15 @@
+#ifndef _IPT_CONNMARK_H_target
+#define _IPT_CONNMARK_H_target
+
+enum {
+    IPT_CONNMARK_SET = 0,
+    IPT_CONNMARK_SAVE,
+    IPT_CONNMARK_RESTORE
+};
+
+struct ipt_connmark_target_info {
+	unsigned long mark;
+	u_int8_t mode;
+};
+
+#endif /*_IPT_CONNMARK_H_target*/
diff -Nru linux-2.4.20/include/linux/netfilter_ipv4/ipt_connmark.h linux-2.4.20-pom2patch/include/linux/netfilter_ipv4/ipt_connmark.h
--- linux-2.4.20/include/linux/netfilter_ipv4/ipt_connmark.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.4.20-pom2patch/include/linux/netfilter_ipv4/ipt_connmark.h	2003-05-02 12:56:57.000000000 -0500
@@ -0,0 +1,9 @@
+#ifndef _IPT_CONNMARK_H
+#define _IPT_CONNMARK_H
+
+struct ipt_connmark_info {
+    unsigned long mark, mask;
+    u_int8_t invert;
+};
+
+#endif /*_IPT_CONNMARK_H*/
diff -Nru linux-2.4.20/net/ipv4/netfilter/Config.in linux-2.4.20-pom2patch/net/ipv4/netfilter/Config.in
--- linux-2.4.20/net/ipv4/netfilter/Config.in	2003-05-02 12:56:53.000000000 -0500
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/Config.in	2003-05-02 12:56:57.000000000 -0500
@@ -7,6 +7,7 @@
 tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP_NF_CONNTRACK
 if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
   dep_tristate '  FTP protocol support' CONFIG_IP_NF_FTP $CONFIG_IP_NF_CONNTRACK
+  bool '  Connection mark tracking support' CONFIG_IP_NF_CONNTRACK_MARK
   dep_tristate '  IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK
 fi
 
@@ -52,6 +53,9 @@
   fi
   if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
     dep_tristate '  Connection state match support' CONFIG_IP_NF_MATCH_STATE $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES 
+    if [ "$CONFIG_IP_NF_CONNTRACK_MARK" != "n" ]; then
+      dep_tristate '  Connection mark match support' CONFIG_IP_NF_MATCH_CONNMARK $CONFIG_IP_NF_IPTABLES
+    fi
     dep_tristate '  Connections/IP limit match support' CONFIG_IP_NF_MATCH_CONNLIMIT $CONFIG_IP_NF_IPTABLES
     dep_tristate '  Connection tracking match support' CONFIG_IP_NF_MATCH_CONNTRACK $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES 
   fi
@@ -112,6 +116,9 @@
     dep_tristate '    CLASSIFY target support (EXPERIMENTAL)' CONFIG_IP_NF_TARGET_CLASSIFY $CONFIG_IP_NF_FILTER
   fi
   dep_tristate '  LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES
+  if [ "$CONFIG_IP_NF_CONNTRACK_MARK" != "n" ]; then
+    dep_tristate '  CONNMARK target support' CONFIG_IP_NF_TARGET_CONNMARK $CONFIG_IP_NF_IPTABLES
+  fi
   dep_tristate '  TTL target support' CONFIG_IP_NF_TARGET_TTL $CONFIG_IP_NF_IPTABLES
   dep_tristate '  ULOG target support' CONFIG_IP_NF_TARGET_ULOG $CONFIG_IP_NF_IPTABLES
   dep_tristate '  TCPMSS target support' CONFIG_IP_NF_TARGET_TCPMSS $CONFIG_IP_NF_IPTABLES
diff -Nru linux-2.4.20/net/ipv4/netfilter/Makefile linux-2.4.20-pom2patch/net/ipv4/netfilter/Makefile
--- linux-2.4.20/net/ipv4/netfilter/Makefile	2003-05-02 12:56:53.000000000 -0500
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/Makefile	2003-05-02 12:56:57.000000000 -0500
@@ -93,6 +93,7 @@
 
 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
+obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
 obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
 obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
@@ -113,6 +114,7 @@
 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
+obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
 
 obj-$(CONFIG_IP_NF_TARGET_NETLINK) += ipt_NETLINK.o
diff -Nru linux-2.4.20/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.20-pom2patch/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.4.20/net/ipv4/netfilter/ip_conntrack_core.c	2003-05-02 12:54:45.000000000 -0500
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/ip_conntrack_core.c	2003-05-02 12:56:57.000000000 -0500
@@ -723,6 +723,9 @@
 		conntrack->status = IPS_EXPECTED;
 		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);
 		expected->expectant->expecting--;
 		nf_conntrack_get(&master_ct(conntrack)->infos[0]);
diff -Nru linux-2.4.20/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.20-pom2patch/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux-2.4.20/net/ipv4/netfilter/ip_conntrack_standalone.c	2002-11-28 17:53:15.000000000 -0600
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/ip_conntrack_standalone.c	2003-05-02 12:56:57.000000000 -0500
@@ -104,6 +104,9 @@
 		len += sprintf(buffer + len, "[ASSURED] ");
 	len += sprintf(buffer + len, "use=%u ",
 		       atomic_read(&conntrack->ct_general.use));
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+	len += sprintf(buffer + len, "mark=%d ", conntrack->mark);
+#endif
 	len += sprintf(buffer + len, "\n");
 
 	return len;
diff -Nru linux-2.4.20/net/ipv4/netfilter/ipt_CONNMARK.c linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_CONNMARK.c
--- linux-2.4.20/net/ipv4/netfilter/ipt_CONNMARK.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_CONNMARK.c	2003-05-02 12:56:57.000000000 -0500
@@ -0,0 +1,87 @@
+/* This is a module which is used for setting/remembering the mark field of
+ * an connection, or optionally restore it to the skb
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+
+static unsigned int
+target(struct sk_buff **pskb,
+       unsigned int hooknum,
+       const struct net_device *in,
+       const struct net_device *out,
+       const void *targinfo,
+       void *userinfo)
+{
+	const struct ipt_connmark_target_info *markinfo = targinfo;
+
+	enum ip_conntrack_info ctinfo;
+	struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
+	if (ct) {
+	    switch(markinfo->mode) {
+	    case IPT_CONNMARK_SET:
+		ct->mark = markinfo->mark;
+		break;
+	    case IPT_CONNMARK_SAVE:
+		ct->mark = (*pskb)->nfmark;
+		break;
+	    case IPT_CONNMARK_RESTORE:
+		if (ct->mark != (*pskb)->nfmark) {
+		    (*pskb)->nfmark = ct->mark;
+		    (*pskb)->nfcache |= NFC_ALTERED;
+		}
+		break;
+	    }
+	}
+
+	return IPT_CONTINUE;
+}
+
+static int
+checkentry(const char *tablename,
+	   const struct ipt_entry *e,
+           void *targinfo,
+           unsigned int targinfosize,
+           unsigned int hook_mask)
+{
+	struct ipt_connmark_target_info *matchinfo = targinfo;
+	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
+		printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
+		       targinfosize,
+		       IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
+		return 0;
+	}
+
+	if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
+	    if (strcmp(tablename, "mangle") != 0) {
+		    printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
+		    return 0;
+	    }
+	}
+
+	return 1;
+}
+
+static struct ipt_target ipt_connmark_reg
+= { { NULL, NULL }, "CONNMARK", target, checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	if (ipt_register_target(&ipt_connmark_reg))
+		return -EINVAL;
+
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_target(&ipt_connmark_reg);
+}
+
+module_init(init);
+module_exit(fini);
diff -Nru linux-2.4.20/net/ipv4/netfilter/ipt_connmark.c linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_connmark.c
--- linux-2.4.20/net/ipv4/netfilter/ipt_connmark.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_connmark.c	2003-05-02 12:56:57.000000000 -0500
@@ -0,0 +1,55 @@
+/* Kernel module to match connection mark values. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_connmark.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *hdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+	const struct ipt_connmark_info *info = matchinfo;
+	enum ip_conntrack_info ctinfo;
+	struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
+	if (!ct)
+	    return 0;
+
+	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
+}
+
+static int
+checkentry(const char *tablename,
+           const struct ipt_ip *ip,
+           void *matchinfo,
+           unsigned int matchsize,
+           unsigned int hook_mask)
+{
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
+		return 0;
+
+	return 1;
+}
+
+static struct ipt_match connmark_match
+= { { NULL, NULL }, "connmark", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	return ipt_register_match(&connmark_match);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&connmark_match);
+}
+
+module_init(init);
+module_exit(fini);
