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.

This commit is contained in:
Adam Ierymenko 2017-02-07 09:33:39 -08:00
parent 723a9a6e9a
commit 672f17c6e9
4 changed files with 22 additions and 9 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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];

View File

@ -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;