mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-29 15:43:52 +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.
|
||||
// If not present, database is assumed to be empty and at the current schema version
|
||||
// and this key/value is added automatically.
|
||||
#define ZT_NETCONF_SQLITE_SCHEMA_VERSION 4
|
||||
#define ZT_NETCONF_SQLITE_SCHEMA_VERSION_STR "4"
|
||||
#define ZT_NETCONF_SQLITE_SCHEMA_VERSION 5
|
||||
#define ZT_NETCONF_SQLITE_SCHEMA_VERSION_STR "5"
|
||||
|
||||
// API version reported via JSON control plane
|
||||
#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) {
|
||||
sqlite3_close(_db);
|
||||
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)
|
||||
|
||||
/* 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,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,"INSERT INTO Rule (networkId,ruleNo,nodeId,ztSource,ztDest,vlanId,vlanPcp,vlanDei,) 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,"DELETE FROM Rule WHERE networkId = ?",-1,&_sDeleteRulesForNetwork,(const char **)0) != SQLITE_OK)
|
||||
|
||||
@ -457,7 +488,6 @@ SqliteNetworkController::~SqliteNetworkController()
|
||||
sqlite3_finalize(_sCreateMember);
|
||||
sqlite3_finalize(_sGetNodeIdentity);
|
||||
sqlite3_finalize(_sCreateOrReplaceNode);
|
||||
sqlite3_finalize(_sGetEtherTypesFromRuleTable);
|
||||
sqlite3_finalize(_sGetActiveBridges);
|
||||
sqlite3_finalize(_sGetIpAssignmentsForNode);
|
||||
sqlite3_finalize(_sGetIpAssignmentPools);
|
||||
|
@ -137,7 +137,6 @@ private:
|
||||
sqlite3_stmt *_sCreateMember;
|
||||
sqlite3_stmt *_sGetNodeIdentity;
|
||||
sqlite3_stmt *_sCreateOrReplaceNode;
|
||||
sqlite3_stmt *_sGetEtherTypesFromRuleTable;
|
||||
sqlite3_stmt *_sGetActiveBridges;
|
||||
sqlite3_stmt *_sGetIpAssignmentsForNode;
|
||||
sqlite3_stmt *_sGetIpAssignmentPools;
|
||||
|
@ -96,24 +96,15 @@ CREATE UNIQUE INDEX Relay_networkId_address ON Relay (networkId,address);
|
||||
|
||||
CREATE TABLE Rule (
|
||||
networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,
|
||||
policyId varchar(32),
|
||||
ruleNo integer NOT NULL,
|
||||
nodeId char(10) REFERENCES Node(id),
|
||||
sourcePort char(10),
|
||||
destPort char(10),
|
||||
vlanId integer,
|
||||
vlanPcp integer,
|
||||
etherType 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')
|
||||
ruleType integer NOT NULL DEFAULT(0),
|
||||
"addr" blob(16),
|
||||
"int1" integer,
|
||||
"int2" integer,
|
||||
"int3" integer,
|
||||
"int4" integer
|
||||
);
|
||||
|
||||
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"\
|
||||
"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"\
|
||||
" nodeId char(10) REFERENCES Node(id),\n"\
|
||||
" sourcePort char(10),\n"\
|
||||
" destPort char(10),\n"\
|
||||
" vlanId integer,\n"\
|
||||
" vlanPcp integer,\n"\
|
||||
" etherType 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"\
|
||||
" ruleType integer NOT NULL DEFAULT(0),\n"\
|
||||
" \"addr\" blob(16),\n"\
|
||||
" \"int1\" integer,\n"\
|
||||
" \"int2\" integer,\n"\
|
||||
" \"int3\" integer,\n"\
|
||||
" \"int4\" integer\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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
enum ZT_VirtualNetworkRuleType
|
||||
{
|
||||
// 0 to 31 reserved for actions
|
||||
|
||||
/**
|
||||
* Drop frame
|
||||
*/
|
||||
@ -408,16 +411,16 @@ enum ZT_VirtualNetworkRuleType
|
||||
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,
|
||||
|
||||
/**
|
||||
* 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,
|
||||
|
||||
// <32 == actions
|
||||
// 32 to 127 reserved for match criteria
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
@ -87,14 +87,15 @@ public:
|
||||
*/
|
||||
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
|
||||
*
|
||||
* IDs below 65536 should be considered reserved for future global
|
||||
* assignment here.
|
||||
* IDs below 1024 are reserved for use as standard IDs. Others are available
|
||||
* for user-defined use.
|
||||
*
|
||||
* Addition of new required fields requires that code in hasRequiredFields
|
||||
* be updated as well.
|
||||
@ -126,12 +127,11 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an empty certificate
|
||||
* Create an empty certificate of membership
|
||||
*/
|
||||
CertificateOfMembership() :
|
||||
_qualifierCount(0)
|
||||
CertificateOfMembership()
|
||||
{
|
||||
memset(_signature.data,0,_signature.size());
|
||||
memset(this,0,sizeof(CertificateOfMembership));
|
||||
}
|
||||
|
||||
CertificateOfMembership(const CertificateOfMembership &c)
|
||||
@ -168,22 +168,6 @@ public:
|
||||
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
|
||||
*
|
||||
@ -201,24 +185,6 @@ public:
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@ -279,6 +245,21 @@ public:
|
||||
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); }
|
||||
|
||||
/**
|
||||
* 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
|
||||
/**
|
||||
* @return String-serialized representation of this certificate
|
||||
|
@ -126,12 +126,17 @@ public:
|
||||
{
|
||||
memset(&_tid,0,sizeof(_tid));
|
||||
pthread_attr_init(&_tattr);
|
||||
#ifdef __LINUX__
|
||||
pthread_attr_setstacksize(&_tattr,8388608); // for MUSL libc and others, has no effect in normal glibc environments
|
||||
#endif
|
||||
// This corrects for systems with abnormally small defaults (musl) and also
|
||||
// shrinks the stack on systems with large defaults to save a bit of memory.
|
||||
pthread_attr_setstacksize(&_tattr,524288);
|
||||
_started = false;
|
||||
}
|
||||
|
||||
~Thread()
|
||||
{
|
||||
pthread_attr_destroy(&_tattr);
|
||||
}
|
||||
|
||||
Thread(const Thread &t)
|
||||
throw()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user