From e6d3a5a94d01f0d6cad95583ccb4db75f0cc6949 Mon Sep 17 00:00:00 2001 From: Kees Bos Date: Fri, 26 Jun 2015 19:24:19 +0200 Subject: [PATCH] Make rules either general or member specific When the nodeId is NULL in the Rule table, the rule is generic and used on member nodes that do not have specific rules set. --- controller/SqliteNetworkController.cpp | 14 +++++++++++--- controller/schema.sql | 5 +++-- controller/schema.sql.c | 5 +++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp index eb8e399b2..6bea57c5a 100644 --- a/controller/SqliteNetworkController.cpp +++ b/controller/SqliteNetworkController.cpp @@ -154,7 +154,7 @@ SqliteNetworkController::SqliteNetworkController(const char *dbPath) : ||(sqlite3_prepare_v2(_db,"INSERT INTO Node (id,identity,lastAt,lastSeen,firstSeen) VALUES (?,?,?,?,?)",-1,&_sCreateNode,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"UPDATE Node SET lastAt = ?,lastSeen = ? WHERE id = ?",-1,&_sUpdateNode,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"UPDATE Node SET lastSeen = ? WHERE id = ?",-1,&_sUpdateNode2,(const char **)0) != SQLITE_OK) - ||(sqlite3_prepare_v2(_db,"SELECT etherType FROM Rule WHERE networkId = ? AND \"action\" = 'accept'",-1,&_sGetEtherTypesFromRuleTable,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT etherType, CASE WHEN nodeId IS NULL THEN 1 ELSE 0 END AS general FROM Rule WHERE networkId = ? AND (nodeId = ? OR nodeId IS NULL) AND \"action\" = 'accept' ORDER BY general, ruleNo",-1,&_sGetEtherTypesFromRuleTable,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT nodeId FROM Member WHERE networkId = ? AND activeBridge > 0 AND authorized > 0",-1,&_sGetActiveBridges,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT ip,ipNetmaskBits FROM IpAssignment WHERE networkId = ? AND nodeId = ? AND ipVersion = ?",-1,&_sGetIpAssignmentsForNode,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT ipNetwork,ipNetmaskBits FROM IpAssignmentPool WHERE networkId = ? AND ipVersion = ?",-1,&_sGetIpAssignmentPools,(const char **)0) != SQLITE_OK) @@ -381,17 +381,25 @@ NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(co { std::vector allowedEtherTypes; + bool nodeRules = false; + // Add member specific rules or add general rules sqlite3_reset(_sGetEtherTypesFromRuleTable); sqlite3_bind_text(_sGetEtherTypesFromRuleTable,1,network.id,16,SQLITE_STATIC); + sqlite3_bind_text(_sGetEtherTypesFromRuleTable,2,member.nodeId,10,SQLITE_STATIC); while (sqlite3_step(_sGetEtherTypesFromRuleTable) == SQLITE_ROW) { int et = sqlite3_column_int(_sGetEtherTypesFromRuleTable,0); + int isGeneral = sqlite3_column_int(_sGetEtherTypesFromRuleTable,1); + if (!isGeneral) + nodeRules = true; + else if (nodeRules) + break; if ((et >= 0)&&(et <= 0xffff)) allowedEtherTypes.push_back(et); } std::sort(allowedEtherTypes.begin(),allowedEtherTypes.end()); - std::unique(allowedEtherTypes.begin(),allowedEtherTypes.end()); + std::vector::iterator end = std::unique(allowedEtherTypes.begin(),allowedEtherTypes.end()); std::string allowedEtherTypesCsv; - for(std::vector::const_iterator i(allowedEtherTypes.begin());i!=allowedEtherTypes.end();++i) { + for(std::vector::const_iterator i(allowedEtherTypes.begin());i!=end;++i) { if (allowedEtherTypesCsv.length()) allowedEtherTypesCsv.push_back(','); char tmp[16]; diff --git a/controller/schema.sql b/controller/schema.sql index d2261b2af..f5cba3943 100644 --- a/controller/schema.sql +++ b/controller/schema.sql @@ -76,7 +76,7 @@ CREATE INDEX Relay_networkId ON Relay (networkId); CREATE TABLE Rule ( networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, ruleNo integer NOT NULL, - nodeId char(10) NOT NULL REFERENCES Node(id) ON DELETE CASCADE, + nodeId char(10) REFERENCES Node(id) ON DELETE CASCADE, vlanId integer, vlanPcp integer, etherType integer, @@ -93,4 +93,5 @@ CREATE TABLE Rule ( "action" varchar(4096) NOT NULL DEFAULT('accept') ); -CREATE UNIQUE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo); +CREATE UNIQUE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo) WHERE nodeId IS NULL; +CREATE UNIQUE INDEX Rule_networkId_nodeId_ruleNo ON Rule (networkId, ruleNo, nodeId); diff --git a/controller/schema.sql.c b/controller/schema.sql.c index 1157facc5..c98ac9bdd 100644 --- a/controller/schema.sql.c +++ b/controller/schema.sql.c @@ -77,7 +77,7 @@ "CREATE TABLE Rule (\n"\ " networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ " ruleNo integer NOT NULL,\n"\ -" nodeId char(10) NOT NULL REFERENCES Node(id) ON DELETE CASCADE,\n"\ +" nodeId char(10) REFERENCES Node(id) ON DELETE CASCADE,\n"\ " vlanId integer,\n"\ " vlanPcp integer,\n"\ " etherType integer,\n"\ @@ -94,5 +94,6 @@ " \"action\" varchar(4096) NOT NULL DEFAULT('accept')\n"\ ");\n"\ "\n"\ -"CREATE UNIQUE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo);\n"\ +"CREATE UNIQUE INDEX Rule_networkId_ruleNo ON Rule (networkId, ruleNo) WHERE nodeId IS NULL;\n"\ +"CREATE UNIQUE INDEX Rule_networkId_nodeId_ruleNo ON Rule (networkId, ruleNo, nodeId);\n"\ ""