Please find attached the first version of the netfilter mark patch. I've
not yet tested it extensively, but would welcome some initial feedback
or comments.

My comments are:

- The existing TOS patch cannot be disabled at runtime. As such, this
mark patch cannot be either. Would it be preferable to only enable them
both if the qos_flows config option is present? This would also have the
advantage of being able to add CAP_NET_ADMIN as appropriate at runtime.

- I have used sscanf instead of strtoul for both TOS and MARK in
QosConfig.cc (sscanf doesn't auto-detect the format of unsigned long
int). As a result, the tos variable could be changed to type char, which
is what it should be in my opinion. Should I do this?

- The code in forward.cc to obtain all the data needed to locate the
connection information is messy. Is there a better way to achieve it?
Conntrack needs to be passed local and remote port numbers and IP
addresses.

Is it too late to get this in v3.2? I will update the appropriate
release-notes once I know.

Thanks,

Andy

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: a...@andybev.com-20100801233324-uoy4sp2e3uszw5qn
# target_branch: file:///home/andrew/squid-repo/trunk/
# testament_sha1: 4bd1e0b517dc3322fa114f30fb26ff2483cb3410
# timestamp: 2010-08-02 00:34:42 +0100
# base_revision_id: squ...@treenet.co.nz-20100801134158-\
#   vhc003yv3ikwao7e
# 
# Begin patch
=== modified file 'configure.in'
--- configure.in	2010-08-01 06:29:48 +0000
+++ configure.in	2010-08-01 20:09:13 +0000
@@ -1146,6 +1146,32 @@
 fi
 AC_SUBST(SSLLIB)
 
+dnl Allow user to specify libnetfilter_conntrack (needed for QOS netfilter marking)
+AC_ARG_WITH(netfilter-conntrack,
+  AS_HELP_STRING([--with-netfilter-conntrack=PATH],
+                 [Compile with the Netfilter conntrack libraries. The path to
+                  the development libraries and headers
+                  installation can be specified if outside of the
+                  system standard directories]), [ 
+case "$with_netfilter_conntrack" in
+  no)
+    : # Nothing special to do here
+    ;;
+  yes)
+    AC_CHECK_LIB([netfilter_conntrack], [nfct_query],,
+                  AC_MSG_ERROR([libnetfilter-conntrack library not found. Needed for netfilter-conntrack support]),
+                  [-lnetfilter_conntrack])
+    ;;
+  *)  
+    if test ! -d $withval ; then
+      AC_MSG_ERROR([--with-netfilter-conntrack path does not point to a directory])
+    fi
+    LDFLAGS="-L$with_netfilter_conntrack/lib $LDFLAGS"
+    CPPFLAGS="-I$with_netfilter_conntrack/include $CPPFLAGS"
+    with_netfilter_conntrack=yes
+    ;;
+  esac
+])
 
 AC_ARG_ENABLE(forw-via-db,
   AS_HELP_STRING([--enable-forw-via-db],[Enable Forw/Via database]), [
@@ -2061,6 +2087,15 @@
           [Enable Zero Penalty Hit QOS. When set, Squid will alter the
            TOS field of HIT responses to help policing network traffic])
 AC_MSG_NOTICE([ZPH QOS enabled: $enable_zph_qos])
+if test "$enable_zph_qos" = "yes" ; then
+    if test "$with_netfilter_conntrack" = "yes" ; then
+        SQUID_DEFINE_BOOL(USE_QOS_NFMARK,$with_netfilter_conntrack,
+                      [Enable support for QOS netfilter packet marking])
+    else
+        AC_MSG_WARN([--with-netfilter-conntrack not enabled. QOS features will not support Netfilter marking.])
+    fi
+    AC_MSG_NOTICE([QOS netfilter marking enabled: $with_netfilter_conntrack])
+fi
 
 dnl --with-maxfd present for compatibility with Squid-2.
 dnl undocumented in ./configure --help  to encourage using the Squid-3 directive.

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2010-07-29 13:04:44 +0000
+++ src/cf.data.pre	2010-08-01 20:09:13 +0000
@@ -1532,18 +1532,23 @@
 LOC: Ip::Qos::TheConfig
 DOC_START
 	Allows you to select a TOS/DSCP value to mark outgoing
-	connections with, based on where the reply was sourced.
+	connections with, based on where the reply was sourced.	For
+	platforms using netfilter, allows you to set a netfilter mark
+	value instead of, or in addition to, a TOS value.
 
 	TOS values really only have local significance - so you should
 	know what you're specifying. For more information, see RFC2474,
 	RFC2475, and RFC3260.
 
 	The TOS/DSCP byte must be exactly that - octet value 0x00-0xFF.
-	Note that in practice often only values up to 0x3F are usable
-	as the two highest bits have been redefined for use by ECN
-	(RFC3168).
-
-	This setting is configured by setting the source TOS values:
+	Note that in practice often only values up to 0x3F are usable as
+	the two highest bits have been redefined for use by ECN (RFC3168).
+
+        Mark values can be any unsigned integer value (normally up to 0xFFFFFFFF)
+
+	This setting is configured by setting the following values:
+
+        tos|mark                Whether to set TOS or netfilter mark values
 
 	local-hit=0xFF		Value to mark local cache hits.
 
@@ -1551,23 +1556,26 @@
 
 	parent-hit=0xFF		Value to mark hits from parent peers.
 
-
-	NOTE: 'miss' preserve feature is only possible on Linux at this time.
-
-	For the following to work correctly, you will need to patch your
-	linux kernel with the TOS preserving ZPH patch.
-	The kernel patch can be downloaded from http://zph.bratcheda.org
+	The following features are only possible on Linux at this time, and
+	in the case of TOS preservation require your kernel to be patch with
+	the TOS preserving ZPH patch, available from http://zph.bratcheda.org
+	No patch is needed to preserve the netfilter mark.
 
 	disable-preserve-miss
-		By default, the existing TOS value of the response coming
-		from the remote server will be retained and masked with
-		miss-mark. This option disables that feature.
+		This option disables the preservation of the TOS or netfilter
+		mark. By default, the existing TOS or netfilter mark value of
+		the response coming from the remote server will be retained
+		and masked with miss-mark.
+		NOTE: in the case of a netfilter mark, the mark must be set on
+		the connection (using the CONNMARK target) not on the packet
+		(MARK target).
 
 	miss-mask=0xFF
-		Allows you to mask certain bits in the TOS received from the
-		remote server, before copying the value to the TOS sent
-		towards clients.
-		Default: 0xFF (TOS from server is not changed).
+		Allows you to mask certain bits in the TOS or mark value
+		received from the remote server, before copying the value to
+		the TOS sent towards clients.
+		Default for tos: 0xFF (TOS from server is not changed).
+		Default for mark: 0xFFFFFFFF (mark from server is not changed).
 
 DOC_END
 

=== modified file 'src/client_side_reply.cc'
--- src/client_side_reply.cc	2010-04-17 10:38:50 +0000
+++ src/client_side_reply.cc	2010-08-01 22:33:49 +0000
@@ -1672,6 +1672,12 @@
             debugs(33, 2, "ZPH Local hit, TOS=" << Ip::Qos::TheConfig.tos_local_hit);
             comm_set_tos(http->getConn()->fd, Ip::Qos::TheConfig.tos_local_hit);
         }
+#if USE_QOS_NFMARK
+        if (Ip::Qos::TheConfig.mark_local_hit) {
+            debugs(33, 2, "ZPH Local hit, Mark=" << Ip::Qos::TheConfig.mark_local_hit);
+            comm_set_mark(http->getConn()->fd, Ip::Qos::TheConfig.mark_local_hit);
+        }
+#endif /* USE_QOS_NFMARK */
 #endif /* USE_ZPH_QOS */
         localTempBuffer.offset = reqofs;
         localTempBuffer.length = getNextNode()->readBuffer.length;
@@ -1966,8 +1972,22 @@
             debugs(33, 2, "ZPH: Preserving TOS on miss, TOS="<<tos);
         }
         comm_set_tos(fd,tos);
+#if USE_QOS_NFMARK
+        unsigned int mark = 0;
+        if (Ip::Qos::TheConfig.mark_sibling_hit && http->request->hier.code==SIBLING_HIT ) {
+            mark = Ip::Qos::TheConfig.mark_sibling_hit;
+            debugs(33, 2, "ZPH: Sibling Peer hit with hier.code=" << http->request->hier.code << ", Mark=" << mark);
+        } else if (Ip::Qos::TheConfig.mark_parent_hit && http->request->hier.code==PARENT_HIT) {
+            mark = Ip::Qos::TheConfig.mark_parent_hit;
+            debugs(33, 2, "ZPH: Parent Peer hit with hier.code=" << http->request->hier.code << ", Mark=" << mark);
+        } else if (Ip::Qos::TheConfig.preserve_miss_tos) {
+            mark = fd_table[fd].upstreamMark & Ip::Qos::TheConfig.preserve_miss_mark_mask;
+            debugs(33, 2, "ZPH: Preserving mark on miss, Mark="<<mark);
+        }
+        comm_set_mark(fd,mark);
+#endif /* USE_QOS_NFMARK */
     }
-#endif
+#endif /* USE_ZPH_QOS */
 
     /* We've got the final data to start pushing... */
     flags.storelogiccomplete = 1;

=== modified file 'src/comm.cc'
--- src/comm.cc	2010-07-28 12:39:35 +0000
+++ src/comm.cc	2010-08-01 08:41:08 +0000
@@ -646,6 +646,20 @@
 #endif /* sockopt */
 }
 
+int
+comm_set_mark(int fd, unsigned int mark)
+{
+#ifdef SO_MARK
+    int x = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
+    if (x < 0)
+        debugs(50, 1, "comm_set_mark: setsockopt(SO_MARK) on FD " << fd << ": " << xstrerror());
+    return x;
+#else
+    debugs(50, 0, "WARNING: setsockopt(SO_MARK) not supported on this platform");
+    return -1;
+#endif
+}
+
 /**
  * Set the socket IP_TRANSPARENT option for Linux TPROXY v4 support.
  */

=== modified file 'src/comm.h'
--- src/comm.h	2010-07-06 23:09:44 +0000
+++ src/comm.h	2010-08-01 08:41:08 +0000
@@ -77,6 +77,7 @@
 SQUIDCEXTERN int comm_openex(int, int, Ip::Address &, int, unsigned char TOS, const char *);
 SQUIDCEXTERN u_short comm_local_port(int fd);
 SQUIDCEXTERN int comm_set_tos(int fd, int tos);
+SQUIDCEXTERN int comm_set_mark(int fd, unsigned int tos);
 
 SQUIDCEXTERN void commSetSelect(int, unsigned int, PF *, void *, time_t);
 SQUIDCEXTERN void commResetSelect(int);

=== modified file 'src/fde.h'
--- src/fde.h	2010-07-06 23:09:44 +0000
+++ src/fde.h	2010-08-01 08:41:08 +0000
@@ -111,6 +111,9 @@
 #endif
 #if USE_ZPH_QOS
     unsigned char upstreamTOS;			/* see FwdState::dispatch()  */
+#if USE_QOS_NFMARK
+    unsigned int upstreamMark;                  /* see FwdState::dispatch()  */
+#endif
 #endif
 
 private:

=== modified file 'src/forward.cc'
--- src/forward.cc	2010-08-01 04:33:31 +0000
+++ src/forward.cc	2010-08-01 21:48:03 +0000
@@ -49,6 +49,10 @@
 #include "icmp/net_db.h"
 #include "ip/Intercept.h"
 #include "ip/tools.h"
+#if USE_QOS_NFMARK
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
+#endif
 
 static PSC fwdStartCompleteWrapper;
 static PF fwdServerClosedWrapper;
@@ -965,6 +969,24 @@
     self = NULL;	// refcounted
 }
 
+#if USE_ZPH_QOS && USE_QOS_NFMARK && defined(_SQUID_LINUX_)
+/* Callback function to mark connection once it's been found */
+int FwdState::getNfctMark(enum nf_conntrack_msg_type type,
+              struct nf_conntrack *ct,
+              void *data)
+{
+        unsigned int mark;
+        fde *clientFde;
+        
+        mark = nfct_get_attr_u32(ct, ATTR_MARK);
+        clientFde = (fde *)data;
+        clientFde->upstreamMark = mark;
+        debugs(17, 3, "ZPH: Retrieved connection mark value: " << mark);
+
+        return NFCT_CB_CONTINUE;
+}
+#endif
+
 void
 FwdState::dispatch()
 {
@@ -991,14 +1013,90 @@
     netdbPingSite(request->GetHost());
 
 #if USE_ZPH_QOS && defined(_SQUID_LINUX_)
-    /* Bug 2537: This part of ZPH only applies to patched Linux kernels. */
+    /* Bug 2537: The TOS forward part of ZPH only applies to patched Linux kernels. */
 
-    /* Retrieves remote server TOS value, and stores it as part of the
+    /* Retrieves remote server TOS or MARK value, and stores it as part of the
      * original client request FD object. It is later used to forward
-     * remote server's TOS in the response to the client in case of a MISS.
+     * remote server's TOS/MARK in the response to the client in case of a MISS.
      */
     fde * clientFde = &fd_table[client_fd];
+#if USE_QOS_NFMARK
+    fde * servFde = &fd_table[server_fd];
+    if (clientFde && servFde) {
+
+	/* Register nfct callback in order to retrieve connection mark */
+        struct nfct_handle *h;  
+        struct nf_conntrack *ct;
+
+        ct = nfct_new();
+        if (ct) {
+
+            /* Prepare data needed to find the connection in the conntrack table.
+             * We need the local and remote IP address, and the local and remote
+             * port numbers.
+             */
+             
+            Ip::Address serv_fde_local_conn;
+            struct addrinfo *addr = NULL;
+            serv_fde_local_conn.InitAddrInfo(addr);
+            getsockname(server_fd, addr->ai_addr, &(addr->ai_addrlen));
+            serv_fde_local_conn = *addr;
+            serv_fde_local_conn.FreeAddrInfo(addr);
+            serv_fde_local_conn.GetAddrInfo(addr);
+
+            unsigned short serv_fde_local_port;
+            serv_fde_local_port = ((struct sockaddr_in*)addr->ai_addr)->sin_port;
+            struct in6_addr serv_fde_local_ip6;
+            struct in_addr serv_fde_local_ip;
+
+            if (Ip::EnableIpv6 && serv_fde_local_conn.IsIPv6()) {
+                serv_fde_local_ip6 = ((struct sockaddr_in6*)addr->ai_addr)->sin6_addr;
+                nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6);
+                struct in6_addr serv_fde_remote_ip6;
+                inet_pton(AF_INET6,servFde->ipaddr,(struct in6_addr*)&serv_fde_remote_ip6);
+                nfct_set_attr(ct, ATTR_IPV6_DST, serv_fde_remote_ip6.s6_addr);
+                nfct_set_attr(ct, ATTR_IPV6_SRC, serv_fde_local_ip6.s6_addr);
+            } else {
+                serv_fde_local_ip = ((struct sockaddr_in*)addr->ai_addr)->sin_addr;
+                nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
+                nfct_set_attr_u32(ct, ATTR_IPV4_DST, inet_addr(servFde->ipaddr));
+                nfct_set_attr_u32(ct, ATTR_IPV4_SRC, serv_fde_local_ip.s_addr);
+            }
+
+            nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_TCP);   
+            nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(servFde->remote_port));   
+            nfct_set_attr_u16(ct, ATTR_PORT_SRC, serv_fde_local_port);
+
+            h = nfct_open(CONNTRACK, 0);
+
+            if (h) {
+                /* Register the callback. This will retrieve the mark value. */
+                nfct_callback_register(h, NFCT_T_ALL, getNfctMark, (void *) clientFde);
+                int x = nfct_query(h, NFCT_Q_GET, ct);
+                if (x == -1) {
+                    char str[INET_ADDRSTRLEN];
+                    if (Ip::EnableIpv6 && serv_fde_local_conn.IsIPv6()) {
+                        inet_ntop(AF_INET6, &serv_fde_local_ip6, str, INET_ADDRSTRLEN);
+                    } else {
+                        inet_ntop(AF_INET, &serv_fde_local_ip, str, INET_ADDRSTRLEN);
+                    }
+                    debugs(17, 1, "Failed to retrieve connection mark: (" << x << ") " << strerror(errno)
+                      << " (Dest IP:" << servFde->ipaddr << ", src IP:" << str << ", dest port:"
+                      << servFde->remote_port << ", src port:" << ntohs(serv_fde_local_port) << ")" );
+                }
+                
+                nfct_close(h);
+
+            } else {
+            debugs(17, 1, "Failed to open handle on conntrack");
+            }
+
+        } else {
+            debugs(17, 1, "Failed to allocate new conntrack");
+        }
+#else
     if (clientFde) {
+#endif
         int tos = 1;
         int tos_len = sizeof(tos);
         clientFde->upstreamTOS = 0;

=== modified file 'src/forward.h'
--- src/forward.h	2010-05-02 19:32:42 +0000
+++ src/forward.h	2010-08-01 08:41:08 +0000
@@ -9,6 +9,10 @@
 #include "comm.h"
 #include "hier_code.h"
 #include "ip/Address.h"
+#if USE_QOS_NFMARK
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
+#endif
 
 class FwdServer
 {
@@ -33,6 +37,9 @@
     void complete();
     void handleUnregisteredServerEnd();
     int reforward();
+#if USE_QOS_NFMARK
+    static int getNfctMark(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *clientFde);
+#endif
     bool reforwardableStatus(http_status s);
     void serverClosed(int fd);
     void connectStart();

=== modified file 'src/ip/QosConfig.cc'
--- src/ip/QosConfig.cc	2010-04-17 02:29:04 +0000
+++ src/ip/QosConfig.cc	2010-08-01 23:21:02 +0000
@@ -11,7 +11,12 @@
         tos_sibling_hit(0),
         tos_parent_hit(0),
         preserve_miss_tos(1),
-        preserve_miss_tos_mask(255)
+        preserve_miss_tos_mask(255),
+        mark_local_hit(0),
+        mark_sibling_hit(0),
+        mark_parent_hit(0),
+        preserve_miss_mark(1),
+        preserve_miss_mark_mask(0xFFFFFFFF)
 {
     ;
 }
@@ -19,22 +24,53 @@
 void
 Ip::Qos::QosConfig::parseConfigLine()
 {
-    // %i honors 0 and 0x prefixes, which are important for things like umask
+    // strtoul honors 0 and 0x prefixes, which are important for things like umask
     /* parse options ... */
     char *token;
+    /* Assume that the option is for 'tos' not 'mark' (for backwards compatability) */
+    bool mark = false;
+    
     while ( (token = strtok(NULL, w_space)) ) {
-
-        if (strncmp(token, "local-hit=",10) == 0) {
-            sscanf(&token[10], "%i", &tos_local_hit);
+        if (strncmp(token, "mark",4) == 0) {
+#if USE_QOS_NFMARK
+            mark = true;
+#else
+            debugs(3, 0, "WARNING: netfilter marking not enabled in this build");
+#endif
+        } else if (strncmp(token, "tos",3) == 0) {
+            mark = false;
+        } else if (strncmp(token, "local-hit=",10) == 0) {
+            if (mark) {
+                mark_local_hit = (unsigned int)strtoul(&token[10], NULL, 0);
+            } else {
+                tos_local_hit = (int)strtoul(&token[10], NULL, 0);
+            }
         } else if (strncmp(token, "sibling-hit=",12) == 0) {
-            sscanf(&token[12], "%i", &tos_sibling_hit);
+            if (mark) {
+                mark_sibling_hit = (unsigned int)strtoul(&token[10], NULL, 0);
+            } else {
+                tos_sibling_hit = (int)strtoul(&token[10], NULL, 0);
+            }
         } else if (strncmp(token, "parent-hit=",11) == 0) {
-            sscanf(&token[11], "%i", &tos_parent_hit);
+            if (mark) {
+                mark_parent_hit = (unsigned int)strtoul(&token[10], NULL, 0);
+            } else {
+                tos_parent_hit = (int)strtoul(&token[10], NULL, 0);
+            }
         } else if (strcmp(token, "disable-preserve-miss") == 0) {
-            preserve_miss_tos = 0;
-            preserve_miss_tos_mask = 0;
-        } else if (preserve_miss_tos && strncmp(token, "miss-mask=",10) == 0) {
-            sscanf(&token[10], "%i", &preserve_miss_tos_mask);
+            if (mark) {
+                preserve_miss_mark = 0;
+                preserve_miss_mark_mask = 0;
+            } else {
+                preserve_miss_tos = 0;
+                preserve_miss_tos_mask = 0;
+            }
+        } else if (strncmp(token, "miss-mask=",10) == 0) {
+            if (mark && preserve_miss_mark) {
+                preserve_miss_mark_mask = (unsigned int)strtoul(&token[10], NULL, 0);
+            } else if (preserve_miss_tos) {
+                preserve_miss_tos_mask = (int)strtoul(&token[10], NULL, 0);
+            }
         }
     }
 }
@@ -52,24 +88,43 @@
     p += strlen(name);
 
     if (tos_local_hit >0) {
-        snprintf(p, 15, " local-hit=%2x", tos_local_hit);
+        snprintf(p, 15, " (TOS)local-hit=%2x", tos_local_hit);
         p += 15;
     }
-
     if (tos_sibling_hit >0) {
-        snprintf(p, 17, " sibling-hit=%2x", tos_sibling_hit);
+        snprintf(p, 17, " (TOS)sibling-hit=%2x", tos_sibling_hit);
         p += 17;
     }
     if (tos_parent_hit >0) {
-        snprintf(p, 16, " parent-hit=%2x", tos_parent_hit);
+        snprintf(p, 16, " (TOS)parent-hit=%2x", tos_parent_hit);
         p += 16;
     }
-    if (preserve_miss_tos != 0) {
-        snprintf(p, 22, " disable-preserve-miss");
+    if (preserve_miss_tos == 0) {
+        snprintf(p, 22, " (TOS)disable-preserve-miss");
         p += 22;
     }
     if (preserve_miss_tos && preserve_miss_tos_mask != 0) {
-        snprintf(p, 15, " miss-mask=%2x", preserve_miss_tos_mask);
+        snprintf(p, 15, " (TOS)miss-mask=%2x", preserve_miss_tos_mask);
+        p += 15;
+    }
+    if (mark_local_hit >0) {
+        snprintf(p, 15, " (mark)local-hit=%2x", tos_local_hit);
+        p += 15;
+    }
+    if (mark_sibling_hit >0) {
+        snprintf(p, 17, " (mark)sibling-hit=%2x", tos_sibling_hit);
+        p += 17;
+    }
+    if (mark_parent_hit >0) {
+        snprintf(p, 16, " (mark)parent-hit=%2x", tos_parent_hit);
+        p += 16;
+    }
+    if (preserve_miss_mark == 0) {
+        snprintf(p, 22, " (mark)disable-preserve-miss");
+        p += 22;
+    }
+    if (preserve_miss_mark && preserve_miss_mark_mask != 0) {
+        snprintf(p, 15, " (mark)miss-mask=%2x", preserve_miss_mark_mask);
         p += 15;
     }
     snprintf(p, 1, "\n");

=== modified file 'src/ip/QosConfig.h'
--- src/ip/QosConfig.h	2010-04-18 00:13:00 +0000
+++ src/ip/QosConfig.h	2010-08-01 08:41:08 +0000
@@ -19,6 +19,11 @@
     int tos_parent_hit;
     int preserve_miss_tos;
     int preserve_miss_tos_mask;
+    unsigned int mark_local_hit;
+    unsigned int mark_sibling_hit;
+    unsigned int mark_parent_hit;
+    int preserve_miss_mark;
+    unsigned int preserve_miss_mark_mask;
 
 public:
     QosConfig();

=== modified file 'src/tools.cc'
--- src/tools.cc	2010-07-25 08:10:12 +0000
+++ src/tools.cc	2010-08-01 08:41:08 +0000
@@ -1308,9 +1308,13 @@
         cap_value_t cap_list[10];
         cap_list[ncaps++] = CAP_NET_BIND_SERVICE;
 
+#if USE_QOS_NFMARK && defined(_SQUID_LINUX_)
+        cap_list[ncaps++] = CAP_NET_ADMIN;
+#else
         if (Ip::Interceptor.TransparentActive()) {
             cap_list[ncaps++] = CAP_NET_ADMIN;
         }
+#endif
 
         cap_clear_flag(caps, CAP_EFFECTIVE);
         rc |= cap_set_flag(caps, CAP_EFFECTIVE, ncaps, cap_list, CAP_SET);

# Begin bundle
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
KcKEhVYNszA=

Reply via email to