summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--controller/EmbeddedNetworkController.cpp8
-rw-r--r--include/ZeroTierOne.h5
-rw-r--r--node/Capability.hpp10
-rw-r--r--node/Network.cpp8
4 files changed, 22 insertions, 9 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp
index 90018f0d..e798a80c 100644
--- a/controller/EmbeddedNetworkController.cpp
+++ b/controller/EmbeddedNetworkController.cpp
@@ -150,7 +150,9 @@ static json _renderRule(ZT_VirtualNetworkRule &rule)
break;
case ZT_NETWORK_RULE_MATCH_IP_TOS:
r["type"] = "MATCH_IP_TOS";
- r["ipTos"] = (unsigned int)rule.v.ipTos;
+ r["mask"] = (unsigned int)rule.v.ipTos.mask;
+ r["start"] = (unsigned int)rule.v.ipTos.value[0];
+ r["end"] = (unsigned int)rule.v.ipTos.value[1];
break;
case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
r["type"] = "MATCH_IP_PROTOCOL";
@@ -329,7 +331,9 @@ static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule)
return true;
} else if (t == "MATCH_IP_TOS") {
rule.t |= ZT_NETWORK_RULE_MATCH_IP_TOS;
- rule.v.ipTos = (uint8_t)(OSUtils::jsonInt(r["ipTos"],0ULL) & 0xffULL);
+ rule.v.ipTos.mask = (uint8_t)(OSUtils::jsonInt(r["mask"],0ULL) & 0xffULL);
+ rule.v.ipTos.value[0] = (uint8_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffULL);
+ rule.v.ipTos.value[1] = (uint8_t)(OSUtils::jsonInt(r["end"],0ULL) & 0xffULL);
return true;
} else if (t == "MATCH_IP_PROTOCOL") {
rule.t |= ZT_NETWORK_RULE_MATCH_IP_PROTOCOL;
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h
index 860343ba..583f9b6a 100644
--- a/include/ZeroTierOne.h
+++ b/include/ZeroTierOne.h
@@ -705,7 +705,10 @@ typedef struct
/**
* IP type of service a.k.a. DSCP field
*/
- uint8_t ipTos;
+ struct {
+ uint8_t mask;
+ uint8_t value[2];
+ } ipTos;
/**
* Ethernet packet size in host byte order (start-end, inclusive)
diff --git a/node/Capability.hpp b/node/Capability.hpp
index ddbfd9ee..08714038 100644
--- a/node/Capability.hpp
+++ b/node/Capability.hpp
@@ -216,8 +216,10 @@ public:
b.append((uint8_t)rules[i].v.ipv6.mask);
break;
case ZT_NETWORK_RULE_MATCH_IP_TOS:
- b.append((uint8_t)1);
- b.append((uint8_t)rules[i].v.ipTos);
+ b.append((uint8_t)3);
+ b.append((uint8_t)rules[i].v.ipTos.mask);
+ b.append((uint8_t)rules[i].v.ipTos.value[0]);
+ b.append((uint8_t)rules[i].v.ipTos.value[1]);
break;
case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
b.append((uint8_t)1);
@@ -308,7 +310,9 @@ public:
rules[ruleCount].v.ipv6.mask = (uint8_t)b[p + 16];
break;
case ZT_NETWORK_RULE_MATCH_IP_TOS:
- rules[ruleCount].v.ipTos = (uint8_t)b[p];
+ rules[ruleCount].v.ipTos.mask = (uint8_t)b[p];
+ rules[ruleCount].v.ipTos.value[0] = (uint8_t)b[p+1];
+ rules[ruleCount].v.ipTos.value[1] = (uint8_t)b[p+2];
break;
case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
rules[ruleCount].v.ipProtocol = (uint8_t)b[p];
diff --git a/node/Network.cpp b/node/Network.cpp
index 5961b087..7412e3e7 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -368,11 +368,13 @@ static _doZtFilterResult _doZtFilter(
break;
case ZT_NETWORK_RULE_MATCH_IP_TOS:
if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
- thisRuleMatches = (uint8_t)(rules[rn].v.ipTos == ((frameData[1] & 0xfc) >> 2));
+ //thisRuleMatches = (uint8_t)(rules[rn].v.ipTos == ((frameData[1] & 0xfc) >> 2));
+ const uint8_t tosMasked = frameData[1] & rules[rn].v.ipTos.mask;
+ thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0])&&(tosMasked <= rules[rn].v.ipTos.value[1]));
FILTER_TRACE("%u %s %c (IPv4) %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.ipTos,(unsigned int)((frameData[1] & 0xfc) >> 2),(unsigned int)thisRuleMatches);
} else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
- const uint8_t trafficClass = ((frameData[0] << 4) & 0xf0) | ((frameData[1] >> 4) & 0x0f);
- thisRuleMatches = (uint8_t)(rules[rn].v.ipTos == ((trafficClass & 0xfc) >> 2));
+ const uint8_t tosMasked = (((frameData[0] << 4) & 0xf0) | ((frameData[1] >> 4) & 0x0f)) & rules[rn].v.ipTos.mask;
+ thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0])&&(tosMasked <= rules[rn].v.ipTos.value[1]));
FILTER_TRACE("%u %s %c (IPv6) %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.ipTos,(unsigned int)((trafficClass & 0xfc) >> 2),(unsigned int)thisRuleMatches);
} else {
thisRuleMatches = 0;