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"\ ""