-
Notifications
You must be signed in to change notification settings - Fork 596
[cfgmgr]: Add vrfmgrd #621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
b310a9c
[cfgmgr]: Add vrfmgrd
marian-pritsak d42830c
Fix comments
marian-pritsak 6a27177
[vrfmgrd]: Recover VRF info from linux after restart
marian-pritsak 6eebd6f
[vrfmgrd]: Set Table ID range from 1001 to 2000
marian-pritsak 710feed
Throw when cmd fails
marian-pritsak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
#include <string.h> | ||
#include "logger.h" | ||
#include "dbconnector.h" | ||
#include "producerstatetable.h" | ||
#include "tokenize.h" | ||
#include "ipprefix.h" | ||
#include "vrfmgr.h" | ||
#include "exec.h" | ||
#include "shellcmd.h" | ||
|
||
#define VRF_TABLE_START 1001 | ||
#define VRF_TABLE_END 2000 | ||
|
||
using namespace swss; | ||
|
||
VrfMgr::VrfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector<string> &tableNames) : | ||
Orch(cfgDb, tableNames) | ||
{ | ||
for (uint32_t i = VRF_TABLE_START; i < VRF_TABLE_END; i++) | ||
{ | ||
m_freeTables.emplace(i); | ||
} | ||
|
||
/* Get existing VRFs from Linux */ | ||
stringstream cmd; | ||
string res; | ||
|
||
cmd << IP_CMD << " -d link show type vrf"; | ||
EXEC_WITH_ERROR_THROW(cmd.str(), res); | ||
|
||
enum IpShowRowType | ||
{ | ||
LINK_ROW, | ||
MAC_ROW, | ||
DETAILS_ROW, | ||
}; | ||
|
||
string vrfName; | ||
uint32_t table; | ||
IpShowRowType rowType = LINK_ROW; | ||
const auto& rows = tokenize(res, '\n'); | ||
for (const auto& row : rows) | ||
{ | ||
const auto& items = tokenize(row, ' '); | ||
switch(rowType) | ||
{ | ||
case LINK_ROW: | ||
vrfName = items[1]; | ||
vrfName.pop_back(); | ||
rowType = MAC_ROW; | ||
break; | ||
case MAC_ROW: | ||
rowType = DETAILS_ROW; | ||
break; | ||
case DETAILS_ROW: | ||
table = static_cast<uint32_t>(stoul(items[6])); | ||
m_vrfTableMap[vrfName] = table; | ||
m_freeTables.erase(table); | ||
rowType = LINK_ROW; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
uint32_t VrfMgr::getFreeTable(void) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
if (m_freeTables.empty()) | ||
{ | ||
return 0; | ||
} | ||
|
||
uint32_t table = *m_freeTables.begin(); | ||
m_freeTables.erase(table); | ||
|
||
return table; | ||
} | ||
|
||
void VrfMgr::recycleTable(uint32_t table) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
m_freeTables.emplace(table); | ||
} | ||
|
||
bool VrfMgr::delLink(const string& vrfName) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
stringstream cmd; | ||
string res; | ||
|
||
if (m_vrfTableMap.find(vrfName) == m_vrfTableMap.end()) | ||
{ | ||
return false; | ||
} | ||
|
||
cmd << IP_CMD << " link del " << vrfName; | ||
EXEC_WITH_ERROR_THROW(cmd.str(), res); | ||
|
||
recycleTable(m_vrfTableMap[vrfName]); | ||
m_vrfTableMap.erase(vrfName); | ||
|
||
return true; | ||
} | ||
|
||
bool VrfMgr::setLink(const string& vrfName) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
stringstream cmd; | ||
string res; | ||
|
||
if (m_vrfTableMap.find(vrfName) != m_vrfTableMap.end()) | ||
{ | ||
return true; | ||
} | ||
|
||
uint32_t table = getFreeTable(); | ||
if (table == 0) | ||
{ | ||
return false; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we check the vrfTableMap, if it is there means the vrf has been created, then we can just return true. Instead of creating a new one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
cmd << IP_CMD << " link add " << vrfName << " type vrf table " << table; | ||
EXEC_WITH_ERROR_THROW(cmd.str(), res); | ||
|
||
m_vrfTableMap.emplace(vrfName, table); | ||
|
||
cmd.str(""); | ||
cmd.clear(); | ||
cmd << IP_CMD << " link set " << vrfName << " up"; | ||
EXEC_WITH_ERROR_THROW(cmd.str(), res); | ||
|
||
return true; | ||
} | ||
|
||
void VrfMgr::doTask(Consumer &consumer) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
auto it = consumer.m_toSync.begin(); | ||
while (it != consumer.m_toSync.end()) | ||
{ | ||
KeyOpFieldsValuesTuple t = it->second; | ||
auto vrfName = kfvKey(t); | ||
|
||
string op = kfvOp(t); | ||
if (op == SET_COMMAND) | ||
{ | ||
if (!setLink(vrfName)) | ||
{ | ||
SWSS_LOG_ERROR("Failed to create vrf netdev %s", vrfName.c_str()); | ||
} | ||
|
||
SWSS_LOG_NOTICE("Created vrf netdev %s", vrfName.c_str()); | ||
} | ||
else if (op == DEL_COMMAND) | ||
{ | ||
if (!delLink(vrfName)) | ||
{ | ||
SWSS_LOG_ERROR("Failed to remove vrf netdev %s", vrfName.c_str()); | ||
} | ||
|
||
SWSS_LOG_NOTICE("Removed vrf netdev %s", vrfName.c_str()); | ||
} | ||
else | ||
{ | ||
SWSS_LOG_ERROR("Unknown operation: %s", op.c_str()); | ||
} | ||
|
||
it = consumer.m_toSync.erase(it); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef __VRFMGR__ | ||
#define __VRFMGR__ | ||
|
||
#include <string> | ||
#include <map> | ||
#include <set> | ||
#include "dbconnector.h" | ||
#include "producerstatetable.h" | ||
#include "orch.h" | ||
|
||
using namespace std; | ||
|
||
namespace swss { | ||
|
||
class VrfMgr : public Orch | ||
{ | ||
public: | ||
VrfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector<string> &tableNames); | ||
using Orch::doTask; | ||
|
||
private: | ||
bool delLink(const string& vrfName); | ||
bool setLink(const string& vrfName); | ||
void recycleTable(uint32_t table); | ||
uint32_t getFreeTable(void); | ||
void doTask(Consumer &consumer); | ||
|
||
map<string, uint32_t> m_vrfTableMap; | ||
set<uint32_t> m_freeTables; | ||
}; | ||
|
||
} | ||
|
||
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include <unistd.h> | ||
#include <vector> | ||
#include <mutex> | ||
#include "dbconnector.h" | ||
#include "select.h" | ||
#include "exec.h" | ||
#include "schema.h" | ||
#include "vrfmgr.h" | ||
#include <fstream> | ||
#include <iostream> | ||
|
||
using namespace std; | ||
using namespace swss; | ||
|
||
/* select() function timeout retry time, in millisecond */ | ||
#define SELECT_TIMEOUT 1000 | ||
|
||
/* | ||
* Following global variables are defined here for the purpose of | ||
* using existing Orch class which is to be refactored soon to | ||
* eliminate the direct exposure of the global variables. | ||
* | ||
* Once Orch class refactoring is done, these global variables | ||
* should be removed from here. | ||
*/ | ||
int gBatchSize = 0; | ||
bool gSwssRecord = false; | ||
bool gLogRotate = false; | ||
ofstream gRecordOfs; | ||
string gRecordFile; | ||
/* Global database mutex */ | ||
mutex gDbMutex; | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
Logger::linkToDbNative("vrfmgrd"); | ||
SWSS_LOG_ENTER(); | ||
|
||
SWSS_LOG_NOTICE("--- Starting vrfmgrd ---"); | ||
|
||
try | ||
{ | ||
vector<string> cfg_vrf_tables = { | ||
CFG_VRF_TABLE_NAME, | ||
}; | ||
|
||
DBConnector cfgDb(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0); | ||
DBConnector appDb(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0); | ||
DBConnector stateDb(STATE_DB, DBConnector::DEFAULT_UNIXSOCKET, 0); | ||
|
||
VrfMgr vrfmgr(&cfgDb, &appDb, &stateDb, cfg_vrf_tables); | ||
|
||
// TODO: add tables in stateDB which interface depends on to monitor list | ||
std::vector<Orch *> cfgOrchList = {&vrfmgr}; | ||
|
||
swss::Select s; | ||
for (Orch *o : cfgOrchList) | ||
{ | ||
s.addSelectables(o->getSelectables()); | ||
} | ||
|
||
SWSS_LOG_NOTICE("starting main loop"); | ||
while (true) | ||
{ | ||
Selectable *sel; | ||
int ret; | ||
|
||
ret = s.select(&sel, SELECT_TIMEOUT); | ||
if (ret == Select::ERROR) | ||
{ | ||
SWSS_LOG_NOTICE("Error: %s!", strerror(errno)); | ||
continue; | ||
} | ||
if (ret == Select::TIMEOUT) | ||
{ | ||
vrfmgr.doTask(); | ||
continue; | ||
} | ||
|
||
auto *c = (Executor *)sel; | ||
c->execute(); | ||
} | ||
} | ||
catch(const std::exception &e) | ||
{ | ||
SWSS_LOG_ERROR("Runtime error: %s", e.what()); | ||
} | ||
return -1; | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since every daemon here is taking "$(top_srcdir)/orchagent/orch.cpp $(top_srcdir)/orchagent/request_parser.cpp shellcmd.h", would it make sense to have a macro for them like
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, but I don't like mixing that kind of refactoring with new features in a single PR