summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--controller/EmbeddedNetworkController.cpp11
-rw-r--r--include/ZeroTierOne.h5
-rw-r--r--node/Capability.hpp1
-rw-r--r--node/Network.cpp6
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;
}