diff options
-rw-r--r-- | controller/EmbeddedNetworkController.cpp | 11 | ||||
-rw-r--r-- | include/ZeroTierOne.h | 5 | ||||
-rw-r--r-- | node/Capability.hpp | 1 | ||||
-rw-r--r-- | node/Network.cpp | 6 |
4 files changed, 22 insertions, 1 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 7fa66224..aa95ac64 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -287,6 +287,12 @@ static json _renderRule(ZT_VirtualNetworkRule &rule) r["id"] = rule.v.tag.id; r["value"] = rule.v.tag.value; break; + case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL: + r["type"] = "MATCH_TAGS_EQUAL"; + r["not"] = ((rule.t & 0x80) != 0); + r["id"] = rule.v.tag.id; + r["value"] = rule.v.tag.value; + break; } return r; } @@ -458,6 +464,11 @@ static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule) rule.v.tag.id = (uint32_t)(_jI(r["id"],0ULL) & 0xffffffffULL); rule.v.tag.value = (uint32_t)(_jI(r["value"],0ULL) & 0xffffffffULL); return true; + } else if (t == "MATCH_TAGS_EQUAL") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_EQUAL; + rule.v.tag.id = (uint32_t)(_jI(r["id"],0ULL) & 0xffffffffULL); + rule.v.tag.value = (uint32_t)(_jI(r["value"],0ULL) & 0xffffffffULL); + return true; } return false; } diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index e231ae62..8d7b0cd4 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -659,6 +659,11 @@ enum ZT_VirtualNetworkRuleType ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR = 55, /** + * Match if local and remote tags both equal a value + */ + ZT_NETWORK_RULE_MATCH_TAGS_EQUAL = 56, + + /** * Maximum ID allowed for a MATCH entry in the rules table */ ZT_NETWORK_RULE_MATCH__MAX_ID = 127 diff --git a/node/Capability.hpp b/node/Capability.hpp index f757639d..99980ce7 100644 --- a/node/Capability.hpp +++ b/node/Capability.hpp @@ -340,6 +340,7 @@ public: case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND: case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR: case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR: + case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL: rules[ruleCount].v.tag.id = b.template at<uint32_t>(p); rules[ruleCount].v.tag.value = b.template at<uint32_t>(p + 4); break; diff --git a/node/Network.cpp b/node/Network.cpp index 8b9f6e3d..00c201ba 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -511,7 +511,8 @@ static _doZtFilterResult _doZtFilter( case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE: case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND: case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR: - case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR: { + case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR: + case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL: { const Tag *const localTag = std::lower_bound(&(nconf.tags[0]),&(nconf.tags[nconf.tagCount]),rules[rn].v.tag.id,Tag::IdComparePredicate()); if ((localTag != &(nconf.tags[nconf.tagCount]))&&(localTag->id() == rules[rn].v.tag.id)) { const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0); @@ -531,6 +532,9 @@ static _doZtFilterResult _doZtFilter( } else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR) { thisRuleMatches = (uint8_t)((ltv ^ rtv) == rules[rn].v.tag.value); FILTER_TRACE("%u %s %c TAG %u local:%.8x ^ remote:%.8x == %.8x -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id,ltv,rtv,(unsigned int)rules[rn].v.tag.value,(unsigned int)thisRuleMatches); + } else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_EQUAL) { + thisRuleMatches = (uint8_t)((ltv == rules[rn].v.tag.value)&&(rtv == rules[rn].v.tag.value)); + FILTER_TRACE("%u %s %c TAG %u local:%.8x and remote:%.8x == %.8x -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id,ltv,rtv,(unsigned int)rules[rn].v.tag.value,(unsigned int)thisRuleMatches); } else { // sanity check, can't really happen thisRuleMatches = 0; } |