This patch adds a mask option to the qos_flows miss configuration value. This is to allow the preserved mark/TOS value from the server to be altered slightly rather than overwritten completely. Example usage. The following will preserve the netfilter mark, but will ensure that the (9th) bit specified in the miss value will be set to 1 in the preserved mark: qos_flows mark miss=0x100/0xF00 === modified file 'src/cf.data.pre' --- src/cf.data.pre 2011-10-28 19:43:45 +0000 +++ src/cf.data.pre 2011-10-31 23:00:03 +0000 @@ -1699,8 +1699,10 @@ parent-hit=0xFF Value to mark hits from parent peers. - miss=0xFF Value to mark cache misses. Takes precedence - over the preserve-miss feature (see below). + miss=0xFF[/mask] Value to mark cache misses. Takes precedence + over the preserve-miss feature (see below), unless + mask is specified, in which case only the bits + specified in the mask are written. The TOS variant of the following features are only possible on Linux and require your kernel to be patched with the TOS preserving ZPH === modified file 'src/ip/QosConfig.cc' --- src/ip/QosConfig.cc 2011-05-13 08:13:01 +0000 +++ src/ip/QosConfig.cc 2011-10-31 23:30:51 +0000 @@ -128,12 +128,13 @@ } else if (Ip::Qos::TheConfig.tosParentHit && hierCode==PARENT_HIT) { tos = Ip::Qos::TheConfig.tosParentHit; debugs(33, 2, "QOS: Parent Peer hit with hier code=" << hierCode << ", TOS=" << int(tos)); + } else if (Ip::Qos::TheConfig.preserveMissTos) { + tos = fd_table[conn->fd].tosFromServer & Ip::Qos::TheConfig.preserveMissTosMask; + tos = (tos & ~Ip::Qos::TheConfig.tosMissMask) | (Ip::Qos::TheConfig.tosMiss & Ip::Qos::TheConfig.tosMissMask); + debugs(33, 2, "QOS: Preserving TOS on miss, TOS=" << int(tos)); } else if (Ip::Qos::TheConfig.tosMiss) { - tos = Ip::Qos::TheConfig.tosMiss; + tos = Ip::Qos::TheConfig.tosMiss & Ip::Qos::TheConfig.tosMissMask; debugs(33, 2, "QOS: Cache miss, setting TOS=" << int(tos)); - } else if (Ip::Qos::TheConfig.preserveMissTos && Ip::Qos::TheConfig.preserveMissTosMask) { - tos = fd_table[conn->fd].tosFromServer & Ip::Qos::TheConfig.preserveMissTosMask; - debugs(33, 2, "QOS: Preserving TOS on miss, TOS=" << int(tos)); } return setSockTos(conn, tos); } @@ -148,12 +149,13 @@ } else if (Ip::Qos::TheConfig.markParentHit && hierCode==PARENT_HIT) { mark = Ip::Qos::TheConfig.markParentHit; debugs(33, 2, "QOS: Parent Peer hit with hier code=" << hierCode << ", Mark=" << mark); - } else if (Ip::Qos::TheConfig.markMiss) { - mark = Ip::Qos::TheConfig.markMiss; - debugs(33, 2, "QOS: Cache miss, setting Mark=" << mark); } else if (Ip::Qos::TheConfig.preserveMissMark) { mark = fd_table[conn->fd].nfmarkFromServer & Ip::Qos::TheConfig.preserveMissMarkMask; + mark = (mark & ~Ip::Qos::TheConfig.markMissMask) | (Ip::Qos::TheConfig.markMiss & Ip::Qos::TheConfig.markMissMask); debugs(33, 2, "QOS: Preserving mark on miss, Mark=" << mark); + } else if (Ip::Qos::TheConfig.markMiss) { + mark = Ip::Qos::TheConfig.markMiss & Ip::Qos::TheConfig.markMissMask; + debugs(33, 2, "QOS: Cache miss, setting Mark=" << mark); } return setSockNfmark(conn, mark); } @@ -182,12 +184,14 @@ tosSiblingHit = 0; tosParentHit = 0; tosMiss = 0; + tosMissMask = 0; preserveMissTos = false; preserveMissTosMask = 0xFF; markLocalHit = 0; markSiblingHit = 0; markParentHit = 0; markMiss = 0; + markMissMask = 0; preserveMissMark = false; preserveMissMarkMask = 0xFFFFFFFF; } @@ -290,18 +294,37 @@ } else if (strncmp(token, "miss=",5) == 0) { + char *end; + if (mark) { - if (!xstrtoui(&token[5], NULL, &markMiss, 0, std::numeric_limits::max())) { + if (!xstrtoui(&token[5], &end, &markMiss, 0, std::numeric_limits::max())) { debugs(3, DBG_CRITICAL, "ERROR: Bad mark miss value " << &token[5]); self_destruct(); } + if (*end == '/') { + if (!xstrtoui(end + 1, NULL, &markMissMask, 0, std::numeric_limits::max())) { + debugs(3, DBG_CRITICAL, "ERROR: Bad mark miss mask value " << (end + 1)); + self_destruct(); + } + } else { + markMissMask = 0xFFFFFFFF; + } } else { unsigned int v = 0; - if (!xstrtoui(&token[5], NULL, &v, 0, std::numeric_limits::max())) { + if (!xstrtoui(&token[5], &end, &v, 0, std::numeric_limits::max())) { debugs(3, DBG_CRITICAL, "ERROR: Bad TOS miss value " << &token[5]); self_destruct(); } tosMiss = (tos_t)v; + if (*end == '/') { + if (!xstrtoui(end + 1, NULL, &v, 0, std::numeric_limits::max())) { + debugs(3, DBG_CRITICAL, "ERROR: Bad TOS miss mask value " << (end + 1)); + self_destruct(); + } + tosMissMask = (tos_t)v; + } else { + tosMissMask = 0xFF; + } } } else if (strcmp(token, "disable-preserve-miss") == 0) { @@ -366,6 +389,9 @@ } if (tosMiss > 0) { p += snprintf(p, 11, " miss=0x%02X", tosMiss); + if (tosMissMask!=0xFFU) { + p += snprintf(p, 6, "/0x%02X", markMissMask); + } } if (preserveMissTos == 0) { p += snprintf(p, 23, " disable-preserve-miss"); @@ -391,6 +417,9 @@ } if (markMiss > 0) { p += snprintf(p, 17, " miss=0x%02X", markMiss); + if (markMissMask!=0xFFFFFFFFU) { + p += snprintf(p, 12, "/0x%02X", markMissMask); + } } if (preserveMissMark == false) { p += snprintf(p, 23, " disable-preserve-miss"); === modified file 'src/ip/QosConfig.h' --- src/ip/QosConfig.h 2011-06-18 00:12:51 +0000 +++ src/ip/QosConfig.h 2011-10-31 23:14:10 +0000 @@ -158,15 +158,17 @@ tos_t tosSiblingHit; ///< TOS value to apply to hits from siblings tos_t tosParentHit; ///< TOS value to apply to hits from parent tos_t tosMiss; ///< TOS value to apply to cache misses + tos_t tosMissMask; ///< Mask for TOS value to apply to cache misses. Applied to the tosMiss value. bool preserveMissTos; ///< Whether to preserve the TOS value of the inbound packet for misses - tos_t preserveMissTosMask; ///< The mask to apply when preserving the TOS of misses + tos_t preserveMissTosMask; ///< The mask to apply when preserving the TOS of misses. Applies to preserved value from upstream. nfmark_t markLocalHit; ///< Netfilter mark value to apply to local cache hits nfmark_t markSiblingHit; ///< Netfilter mark value to apply to hits from siblings nfmark_t markParentHit; ///< Netfilter mark value to apply to hits from parent nfmark_t markMiss; ///< Netfilter mark value to apply to cache misses + nfmark_t markMissMask; ///< Mask for netfilter mark value to apply to cache misses. Applied to the markMiss value. bool preserveMissMark; ///< Whether to preserve netfilter mark value of inbound connection - nfmark_t preserveMissMarkMask; ///< The mask to apply when preserving the netfilter mark of misses + nfmark_t preserveMissMarkMask; ///< The mask to apply when preserving the netfilter mark of misses. Applied to preserved value from upstream. acl_tos *tosToServer; ///< The TOS that packets to the web server should be marked with, based on ACL acl_tos *tosToClient; ///< The TOS that packets to the client should be marked with, based on ACL