mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-06 11:10:13 +00:00
More rules engine work: key/value pair matching for microsegmentation.
This commit is contained in:
parent
1e6e112806
commit
22e44c762b
@ -66,8 +66,8 @@
|
|||||||
// Stored in database as schemaVersion key in Config.
|
// Stored in database as schemaVersion key in Config.
|
||||||
// If not present, database is assumed to be empty and at the current schema version
|
// If not present, database is assumed to be empty and at the current schema version
|
||||||
// and this key/value is added automatically.
|
// and this key/value is added automatically.
|
||||||
#define ZT_NETCONF_SQLITE_SCHEMA_VERSION 4
|
#define ZT_NETCONF_SQLITE_SCHEMA_VERSION 5
|
||||||
#define ZT_NETCONF_SQLITE_SCHEMA_VERSION_STR "4"
|
#define ZT_NETCONF_SQLITE_SCHEMA_VERSION_STR "5"
|
||||||
|
|
||||||
// API version reported via JSON control plane
|
// API version reported via JSON control plane
|
||||||
#define ZT_NETCONF_CONTROLLER_API_VERSION 2
|
#define ZT_NETCONF_CONTROLLER_API_VERSION 2
|
||||||
@ -334,6 +334,38 @@ SqliteNetworkController::SqliteNetworkController(Node *node,const char *dbPath,c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (schemaVersion < 5) {
|
||||||
|
// Upgrade old rough draft Rule table to new release format
|
||||||
|
if (sqlite3_exec(_db,
|
||||||
|
"DROP INDEX Rule_networkId_ruleNo;\n"
|
||||||
|
"ALTER TABLE \"Rule\" RENAME TO RuleOld;\n"
|
||||||
|
"CREATE TABLE Rule (\n"
|
||||||
|
" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"
|
||||||
|
" policyId varchar(32),\n"
|
||||||
|
" ruleNo integer NOT NULL,\n"
|
||||||
|
" ruleType integer NOT NULL DEFAULT(0),\n"
|
||||||
|
" \"addr\" blob(16),\n"
|
||||||
|
" \"int1\" integer,\n"
|
||||||
|
" \"int2\" integer,\n"
|
||||||
|
" \"int3\" integer,\n"
|
||||||
|
" \"int4\" integer\n"
|
||||||
|
");\n"
|
||||||
|
"INSERT INTO \"Rule\" SELECT networkId,(ruleNo*2) AS ruleNo,37 AS \"ruleType\",etherType AS \"int1\" FROM RuleOld WHERE RuleOld.etherType IS NOT NULL AND RuleOld.etherType > 0;\n"
|
||||||
|
"INSERT INTO \"Rule\" SELECT networkId,((ruleNo*2)+1) AS ruleNo,1 AS \"ruleType\" FROM RuleOld;\n"
|
||||||
|
"DROP TABLE RuleOld;\n"
|
||||||
|
"CREATE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo);\n"
|
||||||
|
"CREATE INDEX Rule_networkId_policyId ON Rule (networkId, policyId);\n"
|
||||||
|
"UPDATE \"Config\" SET \"v\" = 5 WHERE \"k\" = 'schemaVersion';\n"
|
||||||
|
,0,0,0) != SQLITE_OK) {
|
||||||
|
char err[1024];
|
||||||
|
Utils::snprintf(err,sizeof(err),"SqliteNetworkController cannot upgrade the database to version 3: %s",sqlite3_errmsg(_db));
|
||||||
|
sqlite3_close(_db);
|
||||||
|
throw std::runtime_error(err);
|
||||||
|
} else {
|
||||||
|
schemaVersion = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (schemaVersion != ZT_NETCONF_SQLITE_SCHEMA_VERSION) {
|
if (schemaVersion != ZT_NETCONF_SQLITE_SCHEMA_VERSION) {
|
||||||
sqlite3_close(_db);
|
sqlite3_close(_db);
|
||||||
throw std::runtime_error("SqliteNetworkController database schema version mismatch");
|
throw std::runtime_error("SqliteNetworkController database schema version mismatch");
|
||||||
@ -365,8 +397,7 @@ SqliteNetworkController::SqliteNetworkController(Node *node,const char *dbPath,c
|
|||||||
||(sqlite3_prepare_v2(_db,"INSERT OR REPLACE INTO Node (id,identity) VALUES (?,?)",-1,&_sCreateOrReplaceNode,(const char **)0) != SQLITE_OK)
|
||(sqlite3_prepare_v2(_db,"INSERT OR REPLACE INTO Node (id,identity) VALUES (?,?)",-1,&_sCreateOrReplaceNode,(const char **)0) != SQLITE_OK)
|
||||||
|
|
||||||
/* Rule */
|
/* Rule */
|
||||||
||(sqlite3_prepare_v2(_db,"SELECT etherType FROM Rule WHERE networkId = ? AND \"action\" = 'accept'",-1,&_sGetEtherTypesFromRuleTable,(const char **)0) != SQLITE_OK)
|
||(sqlite3_prepare_v2(_db,"INSERT INTO Rule (networkId,ruleNo,nodeId,ztSource,ztDest,vlanId,vlanPcp,vlanDei,) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",-1,&_sCreateRule,(const char **)0) != SQLITE_OK)
|
||||||
||(sqlite3_prepare_v2(_db,"INSERT INTO Rule (networkId,ruleNo,nodeId,sourcePort,destPort,vlanId,vlanPcP,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,flags,invFlags,\"action\") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",-1,&_sCreateRule,(const char **)0) != SQLITE_OK)
|
|
||||||
||(sqlite3_prepare_v2(_db,"SELECT ruleNo,nodeId,sourcePort,destPort,vlanId,vlanPcp,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,\"flags\",invFlags,\"action\" FROM Rule WHERE networkId = ? ORDER BY ruleNo ASC",-1,&_sListRules,(const char **)0) != SQLITE_OK)
|
||(sqlite3_prepare_v2(_db,"SELECT ruleNo,nodeId,sourcePort,destPort,vlanId,vlanPcp,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,\"flags\",invFlags,\"action\" FROM Rule WHERE networkId = ? ORDER BY ruleNo ASC",-1,&_sListRules,(const char **)0) != SQLITE_OK)
|
||||||
||(sqlite3_prepare_v2(_db,"DELETE FROM Rule WHERE networkId = ?",-1,&_sDeleteRulesForNetwork,(const char **)0) != SQLITE_OK)
|
||(sqlite3_prepare_v2(_db,"DELETE FROM Rule WHERE networkId = ?",-1,&_sDeleteRulesForNetwork,(const char **)0) != SQLITE_OK)
|
||||||
|
|
||||||
@ -457,7 +488,6 @@ SqliteNetworkController::~SqliteNetworkController()
|
|||||||
sqlite3_finalize(_sCreateMember);
|
sqlite3_finalize(_sCreateMember);
|
||||||
sqlite3_finalize(_sGetNodeIdentity);
|
sqlite3_finalize(_sGetNodeIdentity);
|
||||||
sqlite3_finalize(_sCreateOrReplaceNode);
|
sqlite3_finalize(_sCreateOrReplaceNode);
|
||||||
sqlite3_finalize(_sGetEtherTypesFromRuleTable);
|
|
||||||
sqlite3_finalize(_sGetActiveBridges);
|
sqlite3_finalize(_sGetActiveBridges);
|
||||||
sqlite3_finalize(_sGetIpAssignmentsForNode);
|
sqlite3_finalize(_sGetIpAssignmentsForNode);
|
||||||
sqlite3_finalize(_sGetIpAssignmentPools);
|
sqlite3_finalize(_sGetIpAssignmentPools);
|
||||||
|
@ -137,7 +137,6 @@ private:
|
|||||||
sqlite3_stmt *_sCreateMember;
|
sqlite3_stmt *_sCreateMember;
|
||||||
sqlite3_stmt *_sGetNodeIdentity;
|
sqlite3_stmt *_sGetNodeIdentity;
|
||||||
sqlite3_stmt *_sCreateOrReplaceNode;
|
sqlite3_stmt *_sCreateOrReplaceNode;
|
||||||
sqlite3_stmt *_sGetEtherTypesFromRuleTable;
|
|
||||||
sqlite3_stmt *_sGetActiveBridges;
|
sqlite3_stmt *_sGetActiveBridges;
|
||||||
sqlite3_stmt *_sGetIpAssignmentsForNode;
|
sqlite3_stmt *_sGetIpAssignmentsForNode;
|
||||||
sqlite3_stmt *_sGetIpAssignmentPools;
|
sqlite3_stmt *_sGetIpAssignmentPools;
|
||||||
|
@ -96,24 +96,15 @@ CREATE UNIQUE INDEX Relay_networkId_address ON Relay (networkId,address);
|
|||||||
|
|
||||||
CREATE TABLE Rule (
|
CREATE TABLE Rule (
|
||||||
networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,
|
networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,
|
||||||
|
policyId varchar(32),
|
||||||
ruleNo integer NOT NULL,
|
ruleNo integer NOT NULL,
|
||||||
nodeId char(10) REFERENCES Node(id),
|
ruleType integer NOT NULL DEFAULT(0),
|
||||||
sourcePort char(10),
|
"addr" blob(16),
|
||||||
destPort char(10),
|
"int1" integer,
|
||||||
vlanId integer,
|
"int2" integer,
|
||||||
vlanPcp integer,
|
"int3" integer,
|
||||||
etherType integer,
|
"int4" integer
|
||||||
macSource char(12),
|
|
||||||
macDest char(12),
|
|
||||||
ipSource varchar(64),
|
|
||||||
ipDest varchar(64),
|
|
||||||
ipTos integer,
|
|
||||||
ipProtocol integer,
|
|
||||||
ipSourcePort integer,
|
|
||||||
ipDestPort integer,
|
|
||||||
flags integer,
|
|
||||||
invFlags integer,
|
|
||||||
"action" varchar(4096) NOT NULL DEFAULT('accept')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo);
|
CREATE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo);
|
||||||
|
CREATE INDEX Rule_networkId_policyId ON Rule (networkId, policyId);
|
||||||
|
@ -97,25 +97,16 @@
|
|||||||
"\n"\
|
"\n"\
|
||||||
"CREATE TABLE Rule (\n"\
|
"CREATE TABLE Rule (\n"\
|
||||||
" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\
|
" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\
|
||||||
|
" policyId varchar(32),\n"\
|
||||||
" ruleNo integer NOT NULL,\n"\
|
" ruleNo integer NOT NULL,\n"\
|
||||||
" nodeId char(10) REFERENCES Node(id),\n"\
|
" ruleType integer NOT NULL DEFAULT(0),\n"\
|
||||||
" sourcePort char(10),\n"\
|
" \"addr\" blob(16),\n"\
|
||||||
" destPort char(10),\n"\
|
" \"int1\" integer,\n"\
|
||||||
" vlanId integer,\n"\
|
" \"int2\" integer,\n"\
|
||||||
" vlanPcp integer,\n"\
|
" \"int3\" integer,\n"\
|
||||||
" etherType integer,\n"\
|
" \"int4\" integer\n"\
|
||||||
" macSource char(12),\n"\
|
|
||||||
" macDest char(12),\n"\
|
|
||||||
" ipSource varchar(64),\n"\
|
|
||||||
" ipDest varchar(64),\n"\
|
|
||||||
" ipTos integer,\n"\
|
|
||||||
" ipProtocol integer,\n"\
|
|
||||||
" ipSourcePort integer,\n"\
|
|
||||||
" ipDestPort integer,\n"\
|
|
||||||
" flags integer,\n"\
|
|
||||||
" invFlags integer,\n"\
|
|
||||||
" \"action\" varchar(4096) NOT NULL DEFAULT('accept')\n"\
|
|
||||||
");\n"\
|
");\n"\
|
||||||
"\n"\
|
"\n"\
|
||||||
"CREATE UNIQUE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo);\n"\
|
"CREATE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo);\n"\
|
||||||
|
"CREATE INDEX Rule_networkId_policyId ON Rule (networkId, policyId);\n"\
|
||||||
""
|
""
|
||||||
|
@ -391,12 +391,15 @@ enum ZT_VirtualNetworkType
|
|||||||
/**
|
/**
|
||||||
* The type of a virtual network rules table entry
|
* The type of a virtual network rules table entry
|
||||||
*
|
*
|
||||||
* These must range from 0 to 127 (0x7f).
|
* These must range from 0 to 127 (0x7f) because the most significant bit
|
||||||
|
* is reserved as a NOT flag.
|
||||||
*
|
*
|
||||||
* Each rule is composed of one or more MATCHes followed by an ACTION.
|
* Each rule is composed of one or more MATCHes followed by an ACTION.
|
||||||
*/
|
*/
|
||||||
enum ZT_VirtualNetworkRuleType
|
enum ZT_VirtualNetworkRuleType
|
||||||
{
|
{
|
||||||
|
// 0 to 31 reserved for actions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop frame
|
* Drop frame
|
||||||
*/
|
*/
|
||||||
@ -408,16 +411,16 @@ enum ZT_VirtualNetworkRuleType
|
|||||||
ZT_NETWORK_RULE_ACTION_ACCEPT = 1,
|
ZT_NETWORK_RULE_ACTION_ACCEPT = 1,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forward a copy of this frame to an observer
|
* Forward a copy of this frame to an observer (by ZT address)
|
||||||
*/
|
*/
|
||||||
ZT_NETWORK_RULE_ACTION_TEE = 2,
|
ZT_NETWORK_RULE_ACTION_TEE = 2,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Explicitly redirect this frame to another device (ignored if this is the target device)
|
* Drop and redirect this frame to another node (by ZT address)
|
||||||
*/
|
*/
|
||||||
ZT_NETWORK_RULE_ACTION_REDIRECT = 3,
|
ZT_NETWORK_RULE_ACTION_REDIRECT = 3,
|
||||||
|
|
||||||
// <32 == actions
|
// 32 to 127 reserved for match criteria
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source ZeroTier address -- analogous to an Ethernet port ID on a switch
|
* Source ZeroTier address -- analogous to an Ethernet port ID on a switch
|
||||||
|
@ -44,9 +44,9 @@
|
|||||||
#define ZT_NETWORK_COM_DEFAULT_REVISION_MAX_DELTA (ZT_NETWORK_AUTOCONF_DELAY * 5)
|
#define ZT_NETWORK_COM_DEFAULT_REVISION_MAX_DELTA (ZT_NETWORK_AUTOCONF_DELAY * 5)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of qualifiers in a COM
|
* Maximum number of qualifiers allowed in a COM (absolute max: 65535)
|
||||||
*/
|
*/
|
||||||
#define ZT_NETWORK_COM_MAX_QUALIFIERS 16
|
#define ZT_NETWORK_COM_MAX_QUALIFIERS 256
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
@ -87,14 +87,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
COM_UINT64_ED25519 = 1 // tuples of unsigned 64's signed with Ed25519
|
// tuples of unsigned 64's signed with Ed25519
|
||||||
|
COM_UINT64_ED25519 = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reserved qualifier IDs
|
* Reserved qualifier IDs
|
||||||
*
|
*
|
||||||
* IDs below 65536 should be considered reserved for future global
|
* IDs below 1024 are reserved for use as standard IDs. Others are available
|
||||||
* assignment here.
|
* for user-defined use.
|
||||||
*
|
*
|
||||||
* Addition of new required fields requires that code in hasRequiredFields
|
* Addition of new required fields requires that code in hasRequiredFields
|
||||||
* be updated as well.
|
* be updated as well.
|
||||||
@ -126,12 +127,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an empty certificate
|
* Create an empty certificate of membership
|
||||||
*/
|
*/
|
||||||
CertificateOfMembership() :
|
CertificateOfMembership()
|
||||||
_qualifierCount(0)
|
|
||||||
{
|
{
|
||||||
memset(_signature.data,0,_signature.size());
|
memset(this,0,sizeof(CertificateOfMembership));
|
||||||
}
|
}
|
||||||
|
|
||||||
CertificateOfMembership(const CertificateOfMembership &c)
|
CertificateOfMembership(const CertificateOfMembership &c)
|
||||||
@ -168,22 +168,6 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
|
|
||||||
/**
|
|
||||||
* Create from string-serialized data
|
|
||||||
*
|
|
||||||
* @param s String-serialized COM
|
|
||||||
*/
|
|
||||||
CertificateOfMembership(const char *s) { fromString(s); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create from string-serialized data
|
|
||||||
*
|
|
||||||
* @param s String-serialized COM
|
|
||||||
*/
|
|
||||||
CertificateOfMembership(const std::string &s) { fromString(s.c_str()); }
|
|
||||||
#endif // ZT_SUPPORT_OLD_STYLE_NETCONF
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create from binary-serialized COM in buffer
|
* Create from binary-serialized COM in buffer
|
||||||
*
|
*
|
||||||
@ -201,24 +185,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline operator bool() const throw() { return (_qualifierCount != 0); }
|
inline operator bool() const throw() { return (_qualifierCount != 0); }
|
||||||
|
|
||||||
/**
|
|
||||||
* Check for presence of all required fields common to all networks
|
|
||||||
*
|
|
||||||
* @return True if all required fields are present
|
|
||||||
*/
|
|
||||||
inline bool hasRequiredFields() const
|
|
||||||
{
|
|
||||||
if (_qualifierCount < 3)
|
|
||||||
return false;
|
|
||||||
if (_qualifiers[0].id != COM_RESERVED_ID_REVISION)
|
|
||||||
return false;
|
|
||||||
if (_qualifiers[1].id != COM_RESERVED_ID_NETWORK_ID)
|
|
||||||
return false;
|
|
||||||
if (_qualifiers[2].id != COM_RESERVED_ID_ISSUED_TO)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Maximum delta for mandatory revision field or 0 if field missing
|
* @return Maximum delta for mandatory revision field or 0 if field missing
|
||||||
*/
|
*/
|
||||||
@ -279,6 +245,21 @@ public:
|
|||||||
void setQualifier(uint64_t id,uint64_t value,uint64_t maxDelta);
|
void setQualifier(uint64_t id,uint64_t value,uint64_t maxDelta);
|
||||||
inline void setQualifier(ReservedId id,uint64_t value,uint64_t maxDelta) { setQualifier((uint64_t)id,value,maxDelta); }
|
inline void setQualifier(ReservedId id,uint64_t value,uint64_t maxDelta) { setQualifier((uint64_t)id,value,maxDelta); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of a qualifier field
|
||||||
|
*
|
||||||
|
* @param id Qualifier ID
|
||||||
|
* @return Value or 0 if not found
|
||||||
|
*/
|
||||||
|
inline uint64_t getQualifierValue(uint64_t id)
|
||||||
|
{
|
||||||
|
for(unsigned int i=0;i<_qualifierCount;++i) {
|
||||||
|
if (_qualifiers[i].id == id)
|
||||||
|
return _qualifiers[i].value;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
|
#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
|
||||||
/**
|
/**
|
||||||
* @return String-serialized representation of this certificate
|
* @return String-serialized representation of this certificate
|
||||||
|
@ -126,12 +126,17 @@ public:
|
|||||||
{
|
{
|
||||||
memset(&_tid,0,sizeof(_tid));
|
memset(&_tid,0,sizeof(_tid));
|
||||||
pthread_attr_init(&_tattr);
|
pthread_attr_init(&_tattr);
|
||||||
#ifdef __LINUX__
|
// This corrects for systems with abnormally small defaults (musl) and also
|
||||||
pthread_attr_setstacksize(&_tattr,8388608); // for MUSL libc and others, has no effect in normal glibc environments
|
// shrinks the stack on systems with large defaults to save a bit of memory.
|
||||||
#endif
|
pthread_attr_setstacksize(&_tattr,524288);
|
||||||
_started = false;
|
_started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Thread()
|
||||||
|
{
|
||||||
|
pthread_attr_destroy(&_tattr);
|
||||||
|
}
|
||||||
|
|
||||||
Thread(const Thread &t)
|
Thread(const Thread &t)
|
||||||
throw()
|
throw()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user