summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2017-02-07 09:33:39 -0800
committerAdam Ierymenko <adam.ierymenko@gmail.com>2017-02-07 09:33:39 -0800
commit672f17c6e9ae981a70c51fdd62882e4847c5b6ba (patch)
tree176f8ec5a5864c490c1d6ad009af6e79cdcf326f
parent723a9a6e9aa4254c7d740f9af6596ba8450924ac (diff)
downloadinfinitytier-672f17c6e9ae981a70c51fdd62882e4847c5b6ba.tar.gz
infinitytier-672f17c6e9ae981a70c51fdd62882e4847c5b6ba.zip
Add a mask and value range to the IP tos rule field. This allows TOS to be matched more usefully. This will break anyone using tos in the beta, but nobody seems to be and its pre-release so now is the time.
-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;