From e6d3a5a94d01f0d6cad95583ccb4db75f0cc6949 Mon Sep 17 00:00:00 2001 From: Kees Bos Date: Fri, 26 Jun 2015 19:24:19 +0200 Subject: [PATCH 1/3] 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"\ "" From aae844450bb602bc5255d1f63e6b8502d0e56446 Mon Sep 17 00:00:00 2001 From: Kees Bos Date: Fri, 26 Jun 2015 22:27:32 +0200 Subject: [PATCH 2/3] Show rules in logical order --- controller/SqliteNetworkController.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp index 6bea57c5a..34b0283ee 100644 --- a/controller/SqliteNetworkController.cpp +++ b/controller/SqliteNetworkController.cpp @@ -166,7 +166,7 @@ SqliteNetworkController::SqliteNetworkController(const char *dbPath) : ||(sqlite3_prepare_v2(_db,"SELECT m.nodeId FROM Member AS m WHERE m.networkId = ? ORDER BY m.nodeId ASC",-1,&_sListNetworkMembers,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT m.authorized,m.activeBridge,n.identity,n.lastAt,n.lastSeen,n.firstSeen FROM Member AS m JOIN Node AS n ON n.id = m.nodeId WHERE m.networkId = ? AND m.nodeId = ?",-1,&_sGetMember2,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT ipNetwork,ipNetmaskBits,ipVersion FROM IpAssignmentPool WHERE networkId = ? ORDER BY ipNetwork ASC",-1,&_sGetIpAssignmentPools2,(const char **)0) != SQLITE_OK) - ||(sqlite3_prepare_v2(_db,"SELECT ruleNo,nodeId,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,vlanId,vlanPcp,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,\"flags\",invFlags,\"action\" FROM Rule WHERE networkId = ? ORDER BY nodeId, ruleNo ASC",-1,&_sListRules,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"INSERT INTO Rule (networkId,ruleNo,nodeId,vlanId,vlanPcP,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,\"action\") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",-1,&_sCreateRule,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"INSERT INTO Network (id,name,creationTime,revision) VALUES (?,?,?,1)",-1,&_sCreateNetwork,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT revision FROM Network WHERE id = ?",-1,&_sGetNetworkRevision,(const char **)0) != SQLITE_OK) @@ -1356,6 +1356,7 @@ unsigned int SqliteNetworkController::_doCPGet( bool firstRule = true; while (sqlite3_step(_sListRules) == SQLITE_ROW) { responseBody.append(firstRule ? "\n\t{\n" : ",{\n"); + firstRule = false; Utils::snprintf(json,sizeof(json),"\t\t\"ruleNo\": %lld,\n",sqlite3_column_int64(_sListRules,0)); responseBody.append(json); if (sqlite3_column_type(_sListRules,1) != SQLITE_NULL) { From 3f6a03c7a45ac5da3ff238a894bf70667f05e451 Mon Sep 17 00:00:00 2001 From: Kees Bos Date: Fri, 26 Jun 2015 23:44:36 +0200 Subject: [PATCH 3/3] Fix creation of rules --- controller/SqliteNetworkController.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp index 34b0283ee..e9d4f6964 100644 --- a/controller/SqliteNetworkController.cpp +++ b/controller/SqliteNetworkController.cpp @@ -167,7 +167,7 @@ SqliteNetworkController::SqliteNetworkController(const char *dbPath) : ||(sqlite3_prepare_v2(_db,"SELECT m.authorized,m.activeBridge,n.identity,n.lastAt,n.lastSeen,n.firstSeen FROM Member AS m JOIN Node AS n ON n.id = m.nodeId WHERE m.networkId = ? AND m.nodeId = ?",-1,&_sGetMember2,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT ipNetwork,ipNetmaskBits,ipVersion FROM IpAssignmentPool WHERE networkId = ? ORDER BY ipNetwork ASC",-1,&_sGetIpAssignmentPools2,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT ruleNo,nodeId,vlanId,vlanPcp,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,\"flags\",invFlags,\"action\" FROM Rule WHERE networkId = ? ORDER BY nodeId, ruleNo ASC",-1,&_sListRules,(const char **)0) != SQLITE_OK) - ||(sqlite3_prepare_v2(_db,"INSERT INTO Rule (networkId,ruleNo,nodeId,vlanId,vlanPcP,etherType,macSource,macDest,ipSource,ipDest,ipTos,ipProtocol,ipSourcePort,ipDestPort,\"action\") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",-1,&_sCreateRule,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO Rule (networkId,ruleNo,nodeId,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 Network (id,name,creationTime,revision) VALUES (?,?,?,1)",-1,&_sCreateNetwork,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT revision FROM Network WHERE id = ?",-1,&_sGetNetworkRevision,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"UPDATE Network SET revision = ? WHERE id = ?",-1,&_sSetNetworkRevision,(const char **)0) != SQLITE_OK) @@ -1015,7 +1015,8 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpPOST( if (rule.invFlags) sqlite3_bind_int64(_sCreateRule,16,(int64_t)*rule.invFlags); sqlite3_bind_text(_sCreateRule,17,rule.action,-1,SQLITE_STATIC); - sqlite3_step(_sCreateRule); + if (sqlite3_step(_sCreateRule) != SQLITE_DONE) + return 500; } } }