diff --git a/orchagent/Makefile.am b/orchagent/Makefile.am index c227ee71d02..db68e6d06cb 100644 --- a/orchagent/Makefile.am +++ b/orchagent/Makefile.am @@ -10,7 +10,7 @@ else DBGFLAGS = -g endif -orchagent_SOURCES = main.cpp orchdaemon.cpp orch.cpp routeorch.cpp neighorch.cpp intfsorch.cpp portsorch.cpp +orchagent_SOURCES = main.cpp orchdaemon.cpp orch.cpp routeorch.cpp neighorch.cpp intfsorch.cpp portsorch.cpp qosorch.cpp orchagent_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) orchagent_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) diff --git a/orchagent/intfsorch.cpp b/orchagent/intfsorch.cpp index 1e062c62b9b..d2ed2f05ea6 100644 --- a/orchagent/intfsorch.cpp +++ b/orchagent/intfsorch.cpp @@ -18,13 +18,13 @@ IntfsOrch::IntfsOrch(DBConnector *db, string tableName, PortsOrch *portsOrch) : { } -void IntfsOrch::doTask() +void IntfsOrch::doTask(_in_ Consumer& consumer_info) { - if (m_toSync.empty()) + if (consumer_info.m_toSync.empty()) return; - auto it = m_toSync.begin(); - while (it != m_toSync.end()) + auto it = consumer_info.m_toSync.begin(); + while (it != consumer_info.m_toSync.end()) { KeyOpFieldsValuesTuple t = it->second; @@ -33,7 +33,7 @@ void IntfsOrch::doTask() if (found == string::npos) { SWSS_LOG_ERROR("Failed to parse task key %s\n", key.c_str()); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } string alias = key.substr(0, found); @@ -41,7 +41,7 @@ void IntfsOrch::doTask() IpPrefix ip_prefix(key.substr(found+1)); if (!ip_prefix.isV4()) { - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } @@ -52,7 +52,7 @@ void IntfsOrch::doTask() /* Duplicate entry */ if (m_intfs.find(alias) != m_intfs.end() && m_intfs[alias] == ip_prefix.getIp()) { - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } @@ -60,7 +60,7 @@ void IntfsOrch::doTask() if (!m_portsOrch->getPort(alias, p)) { SWSS_LOG_ERROR("Failed to locate interface %s\n", alias.c_str()); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } @@ -110,7 +110,7 @@ void IntfsOrch::doTask() { SWSS_LOG_NOTICE("Create packet action trap route ip:%s\n", ip_prefix.getIp().to_string().c_str()); m_intfs[alias] = ip_prefix.getIp(); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } } else if (op == DEL_COMMAND) @@ -119,7 +119,7 @@ void IntfsOrch::doTask() if (!m_portsOrch->getPort(alias, p)) { SWSS_LOG_ERROR("Failed to locate interface %s\n", alias.c_str()); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } @@ -152,7 +152,7 @@ void IntfsOrch::doTask() { SWSS_LOG_NOTICE("Remove packet action trap route ip:%s\n", ip_prefix.getIp().to_string().c_str()); m_intfs.erase(alias); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } } } diff --git a/orchagent/intfsorch.h b/orchagent/intfsorch.h index 4b7a3ada43d..6d3be0823fc 100644 --- a/orchagent/intfsorch.h +++ b/orchagent/intfsorch.h @@ -16,8 +16,7 @@ class IntfsOrch : public Orch public: IntfsOrch(DBConnector *db, string tableName, PortsOrch *portsOrch); private: - void doTask(); - + virtual void doTask(_in_ Consumer& consumer_info); PortsOrch *m_portsOrch; IntfsTable m_intfs; }; diff --git a/orchagent/neighorch.cpp b/orchagent/neighorch.cpp index 83dcde6c4e4..998025438b6 100644 --- a/orchagent/neighorch.cpp +++ b/orchagent/neighorch.cpp @@ -5,22 +5,22 @@ extern sai_neighbor_api_t* sai_neighbor_api; extern sai_next_hop_api_t* sai_next_hop_api; -void NeighOrch::doTask() +void NeighOrch::doTask(_in_ Consumer& consumer_info) { - if (m_toSync.empty()) + if (consumer_info.m_toSync.empty()) return; - auto it = m_toSync.begin(); - while (it != m_toSync.end()) + auto it = consumer_info.m_toSync.begin(); + while (it != consumer_info.m_toSync.end()) { KeyOpFieldsValuesTuple t = it->second; string key = kfvKey(t); - size_t found = key.find(':'); + size_t found = key.find(delimiter); if (found == string::npos) { SWSS_LOG_ERROR("Failed to parse task key %s\n", key.c_str()); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } string alias = key.substr(0, found); @@ -28,14 +28,14 @@ void NeighOrch::doTask() if (!m_portsOrch->getPort(alias, p)) { - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } IpAddress ip_address(key.substr(found+1)); if (!ip_address.isV4()) { - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } @@ -49,37 +49,37 @@ void NeighOrch::doTask() for (auto i = kfvFieldsValues(t).begin(); i != kfvFieldsValues(t).end(); i++) { - if (fvField(*i) == "neigh") + if (fvField(*i) == neigh_field_name) mac_address = MacAddress(fvValue(*i)); } if (m_syncdNeighbors.find(neighbor_entry) == m_syncdNeighbors.end() || m_syncdNeighbors[neighbor_entry] != mac_address) { if (addNeighbor(neighbor_entry, mac_address)) - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); else it++; } else - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } else if (op == DEL_COMMAND) { if (m_syncdNeighbors.find(neighbor_entry) != m_syncdNeighbors.end()) { if (removeNeighbor(neighbor_entry)) - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); else it++; } /* Cannot locate the neighbor */ else - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } else { SWSS_LOG_ERROR("Unknown operation type %s\n", op.c_str()); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } } } @@ -143,8 +143,8 @@ bool NeighOrch::addNeighbor(NeighborEntry neighborEntry, MacAddress macAddress) } else { - // XXX: The neighbor entry is already there - // XXX: MAC change + // TODO: The neighbor entry is already there + // TODO: MAC change } return true; diff --git a/orchagent/neighorch.h b/orchagent/neighorch.h index 3e2f6be743c..6026530eb56 100644 --- a/orchagent/neighorch.h +++ b/orchagent/neighorch.h @@ -23,14 +23,15 @@ typedef map NeighborTable; class NeighOrch : public Orch { public: - NeighOrch(DBConnector *db, string tableName, PortsOrch *portsOrch, RouteOrch *routeOrch) : Orch(db, tableName), m_portsOrch(portsOrch), m_routeOrch(routeOrch) {}; + const char* const delimiter = ";"; + const char* const neigh_field_name = "neigh"; private: PortsOrch *m_portsOrch; RouteOrch *m_routeOrch; - void doTask(); + virtual void doTask(_in_ Consumer& consumer_info); NeighborTable m_syncdNeighbors; diff --git a/orchagent/orch.cpp b/orchagent/orch.cpp index 2b2c59d6b1b..3b584d5d36f 100644 --- a/orchagent/orch.cpp +++ b/orchagent/orch.cpp @@ -1,66 +1,105 @@ #include "orch.h" - #include "logger.h" +using namespace swss; + Orch::Orch(DBConnector *db, string tableName) : - m_db(db), m_name(tableName) + m_db(db) { - m_consumer = new ConsumerTable(m_db, tableName); + Consumer c_info(new ConsumerTable(m_db, tableName)); + m_consumer_map.insert(ConsumerMapPair(tableName, c_info)); +} + +Orch::Orch(DBConnector *db, vector &tableNames) : + m_db(db) +{ + for( auto it = tableNames.begin(); it != tableNames.end(); it++) { + Consumer c_info(new ConsumerTable(m_db, *it)); + m_consumer_map.insert(ConsumerMapPair(*it, c_info)); + } } Orch::~Orch() { delete(m_db); - delete(m_consumer); + for(auto it : m_consumer_map) { + delete it.second.m_consumer; + } } -void Orch::execute() +void Orch::getSelectables(_out_ std::vector &consumers) { - KeyOpFieldsValuesTuple t; - m_consumer->pop(t); + consumers.clear(); + for(auto it : m_consumer_map) { + consumers.push_back(it.second.m_consumer); + } +} + +bool Orch::is_owned_consumer(ConsumerTable*consumer) const +{ + for(auto it : m_consumer_map) { + if(it.second.m_consumer == consumer) { + return true; + } + } + return false; +} + +bool Orch::execute(string tableName) +{ + auto consumer_it = m_consumer_map.find(tableName); + if(consumer_it == m_consumer_map.end()) { + SWSS_LOG_ERROR("Unrecognized tableName:%s\n", tableName.c_str()); + return false; + } + Consumer& consumer = consumer_it->second; + + KeyOpFieldsValuesTuple new_data; + consumer.m_consumer->pop(new_data); - string key = kfvKey(t); - string op = kfvOp(t); + string key = kfvKey(new_data); + string op = kfvOp(new_data); #ifdef DEBUG - string debug = "Orch : " + m_name + " key : " + kfvKey(t) + " op : " + kfvOp(t); - for (auto i = kfvFieldsValues(t).begin(); i != kfvFieldsValues(t).end(); i++) + string debug = "Table : " + consumer.m_consumer.getTableName() + " key : " + kfvKey(new_data) + " op : " + kfvOp(new_data); + for (auto i = kfvFieldsValues(new_data).begin(); i != kfvFieldsValues(new_data).end(); i++) debug += " " + fvField(*i) + " : " + fvValue(*i); SWSS_LOG_DEBUG("%s\n", debug.c_str()); #endif - /* If a new task comes or if a DEL task comes, we directly put it into m_toSync map */ - if ( m_toSync.find(key) == m_toSync.end() || op == DEL_COMMAND) + /* If a new task comes or if a DEL task comes, we directly put it into consumer.m_toSync map */ + if ( consumer.m_toSync.find(key) == consumer.m_toSync.end() || op == DEL_COMMAND) { - m_toSync[key] = t; + consumer.m_toSync[key] = new_data; } /* If an old task is still there, we combine the old task with new task */ else { - KeyOpFieldsValuesTuple u = m_toSync[key]; + KeyOpFieldsValuesTuple existing_data = consumer.m_toSync[key]; - auto tt = kfvFieldsValues(t); - auto uu = kfvFieldsValues(u); + auto new_values = kfvFieldsValues(new_data); + auto existing_values = kfvFieldsValues(existing_data); - for (auto it = tt.begin(); it != tt.end(); it++) + for (auto it = new_values.begin(); it != new_values.end(); it++) { string field = fvField(*it); string value = fvValue(*it); - auto iu = uu.begin(); - while (iu != uu.end()) + auto iu = existing_values.begin(); + while (iu != existing_values.end()) { string ofield = fvField(*iu); if (field == ofield) - iu = uu.erase(iu); + iu = existing_values.erase(iu); else iu++; } - uu.push_back(FieldValueTuple(field, value)); + existing_values.push_back(FieldValueTuple(field, value)); } - m_toSync[key] = KeyOpFieldsValuesTuple(key, op, uu); + consumer.m_toSync[key] = KeyOpFieldsValuesTuple(key, op, existing_values); } - doTask(); + doTask(consumer); + return true; } diff --git a/orchagent/orch.h b/orchagent/orch.h index 0209771354d..cbc5d7ddf14 100644 --- a/orchagent/orch.h +++ b/orchagent/orch.h @@ -15,28 +15,38 @@ extern "C" { using namespace std; using namespace swss; +typedef map SyncMap; +struct Consumer { + Consumer(ConsumerTable* consumer) :m_consumer(consumer) { } + ConsumerTable* m_consumer; + /* Store the latest 'golden' status */ + SyncMap m_toSync; +}; +typedef std::pair ConsumerMapPair; +typedef map ConsumerMap; + class Orch { public: Orch(DBConnector *db, string tableName); + Orch(DBConnector *db, vector &tableNames); ~Orch(); - inline ConsumerTable *getConsumer() { return m_consumer; } + void getSelectables( _out_ std::vector& selectables); + bool is_owned_consumer(ConsumerTable* s)const; - void execute(); - virtual void doTask() = 0; + bool execute(string tableName); inline string getOrchName() { return m_name; } +protected: + virtual void doTask(_in_ Consumer& consumer_info) = 0; private: DBConnector *m_db; - const string m_name; + const string m_name;// TODO: where is this field initialized?? protected: - ConsumerTable *m_consumer; - - /* Store the latest 'golden' status */ - map m_toSync; + ConsumerMap m_consumer_map; }; diff --git a/orchagent/orchdaemon.cpp b/orchagent/orchdaemon.cpp index a3bf3ee7902..92442007320 100644 --- a/orchagent/orchdaemon.cpp +++ b/orchagent/orchdaemon.cpp @@ -6,6 +6,8 @@ #include +using namespace swss; + OrchDaemon::OrchDaemon() { m_applDb = nullptr; @@ -29,7 +31,16 @@ bool OrchDaemon::init() m_intfsO = new IntfsOrch(m_applDb, APP_INTF_TABLE_NAME, m_portsO); m_routeO = new RouteOrch(m_applDb, APP_ROUTE_TABLE_NAME, m_portsO); m_neighO = new NeighOrch(m_applDb, APP_NEIGH_TABLE_NAME, m_portsO, m_routeO); - + std::vector qos_tables = { + APP_TC_TO_QUEUE_MAP_TABLE_NAME, + APP_SCHEDULER_TABLE_NAME, + APP_DSCP_TO_TC_MAP_TABLE_NAME, + APP_QUEUE_TABLE_NAME, + APP_PORT_QOS_MAP_TABLE_NAME, + APP_WRED_PROFILE_TABLE_NAME + }; + + m_qosO = new QosOrch(m_applDb, qos_tables, m_portsO); m_select = new Select(); return true; @@ -38,11 +49,22 @@ bool OrchDaemon::init() void OrchDaemon::start() { int ret; - - m_select->addSelectable(m_portsO->getConsumer()); - m_select->addSelectable(m_intfsO->getConsumer()); - m_select->addSelectable(m_neighO->getConsumer()); - m_select->addSelectable(m_routeO->getConsumer()); + std::vector selectables; + + m_portsO->getSelectables(selectables); + m_select->addSelectables(selectables); + + m_intfsO->getSelectables(selectables); + m_select->addSelectables(selectables); + + m_neighO->getSelectables(selectables); + m_select->addSelectables(selectables); + + m_routeO->getSelectables(selectables); + m_select->addSelectables(selectables); + + m_qosO->getSelectables(selectables); + m_select->addSelectables(selectables); while (true) { @@ -51,27 +73,27 @@ void OrchDaemon::start() ret = m_select->select(&s, &fd, 1); if (ret == Select::ERROR) - SWSS_LOG_NOTICE("Error!\n"); + SWSS_LOG_ERROR("Failed to obtain selectable\n"); if (ret == Select::TIMEOUT) continue; - Orch *o = getOrchByConsumer((ConsumerTable *)s); + Orch *o = getOrchByConsumer((ConsumerTable *)s);// NOTE: o can be nullptr SWSS_LOG_INFO("Get message from Orch: %s\n", o->getOrchName().c_str()); - o->execute(); + o->execute(((ConsumerTable *)s)->getTableName()); } } Orch *OrchDaemon::getOrchByConsumer(ConsumerTable *c) { - if (m_portsO->getConsumer() == c) + if (m_portsO->is_owned_consumer(c)) return m_portsO; - if (m_intfsO->getConsumer() == c) + if (m_intfsO->is_owned_consumer(c)) return m_intfsO; - if (m_neighO->getConsumer() == c) + if (m_neighO->is_owned_consumer(c)) return m_neighO; - if (m_routeO->getConsumer() == c) + if (m_routeO->is_owned_consumer(c)) return m_routeO; return nullptr; } diff --git a/orchagent/orchdaemon.h b/orchagent/orchdaemon.h index 76560215150..3c5b1ead6d9 100644 --- a/orchagent/orchdaemon.h +++ b/orchagent/orchdaemon.h @@ -10,6 +10,8 @@ #include "intfsorch.h" #include "neighorch.h" #include "routeorch.h" +#include "qosorch.h" + using namespace swss; @@ -29,6 +31,7 @@ class OrchDaemon IntfsOrch *m_intfsO; NeighOrch *m_neighO; RouteOrch *m_routeO; + QosOrch *m_qosO; Select *m_select; diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 93fbf76415c..84943988e74 100644 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -149,13 +149,13 @@ bool PortsOrch::setPortAdminStatus(sai_object_id_t id, bool up) return true; } -void PortsOrch::doTask() +void PortsOrch::doTask(_in_ Consumer& consumer_info) { - if (m_toSync.empty()) + if (consumer_info.m_toSync.empty()) return; - auto it = m_toSync.begin(); - while (it != m_toSync.end()) + auto it = consumer_info.m_toSync.begin(); + while (it != consumer_info.m_toSync.end()) { KeyOpFieldsValuesTuple t = it->second; @@ -203,7 +203,7 @@ void PortsOrch::doTask() { Port p(alias, Port::PHY_PORT); - p.m_index = m_portList.size(); // XXX: Assume no deletion of physical port + p.m_index = m_portList.size(); // TODO: Assume no deletion of physical port p.m_port_id = id; /* Initialize the port and create router interface and host interface */ @@ -243,7 +243,7 @@ void PortsOrch::doTask() else SWSS_LOG_ERROR("Unknown operation type %s\n", op.c_str()); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } } @@ -271,8 +271,8 @@ bool PortsOrch::initializePort(Port &p) return false; } - // XXX: Assure if_nametoindex(p.m_alias.c_str()) != 0 - // XXX: Get port oper status + // TODO: Assure if_nametoindex(p.m_alias.c_str()) != 0 + // TODO: Get port oper status #if 0 p.m_ifindex = if_nametoindex(p.m_alias.c_str()); diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index 0f1394b3a3b..1dbbb15c261 100644 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -17,7 +17,7 @@ class PortsOrch : public Orch bool setPortAdminStatus(sai_object_id_t id, bool up); private: - void doTask(); + virtual void doTask(_in_ Consumer& consumer_info); sai_object_id_t m_cpuPort; diff --git a/orchagent/qosorch.cpp b/orchagent/qosorch.cpp new file mode 100644 index 00000000000..79dc54f1cd9 --- /dev/null +++ b/orchagent/qosorch.cpp @@ -0,0 +1,11 @@ +#include "qosorch.h" +#include "logger.h" + +namespace swss { + +void QosOrch::doTask(_in_ Consumer& consumer_info) +{ +} + +} + diff --git a/orchagent/qosorch.h b/orchagent/qosorch.h new file mode 100644 index 00000000000..626c3d7d4df --- /dev/null +++ b/orchagent/qosorch.h @@ -0,0 +1,20 @@ +#pragma once + +#include "portsorch.h" +#include "orch.h" +#include + +namespace swss { +class QosOrch : public Orch +{ +public: + + QosOrch(DBConnector *db, vector &tableNames, PortsOrch *portsOrch) : + Orch(db, tableNames), m_portsOrch(portsOrch) {}; +private: + virtual void doTask(Consumer& consumer_info); + PortsOrch *m_portsOrch; +}; + +} + diff --git a/orchagent/routeorch.cpp b/orchagent/routeorch.cpp index e05dae8cb75..b67a3d6b92a 100644 --- a/orchagent/routeorch.cpp +++ b/orchagent/routeorch.cpp @@ -7,13 +7,13 @@ extern sai_next_hop_group_api_t* sai_next_hop_group_api; extern sai_object_id_t gVirtualRouterId; -void RouteOrch::doTask() +void RouteOrch::doTask(Consumer& consumer_info) { - if (m_toSync.empty()) + if (consumer_info.m_toSync.empty()) return; - auto it = m_toSync.begin(); - while (it != m_toSync.end()) + auto it = consumer_info.m_toSync.begin(); + while (it != consumer_info.m_toSync.end()) { KeyOpFieldsValuesTuple t = it->second; @@ -32,13 +32,13 @@ void RouteOrch::doTask() { if (op == "SET") { - /* Mark all current routes as dirty (DEL) in m_toSync map */ + /* Mark all current routes as dirty (DEL) in consumer_info.m_toSync map */ SWSS_LOG_NOTICE("Start resync routes\n"); for (auto i = m_syncdRoutes.begin(); i != m_syncdRoutes.end(); i++) { vector v; auto x = KeyOpFieldsValuesTuple(i->first.to_string(), DEL_COMMAND, v); - m_toSync[i->first.to_string()] = x; + consumer_info.m_toSync[i->first.to_string()] = x; } m_resync = true; } @@ -48,7 +48,7 @@ void RouteOrch::doTask() m_resync = false; } - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } @@ -61,7 +61,7 @@ void RouteOrch::doTask() IpPrefix ip_prefix = IpPrefix(key); if (!ip_prefix.isV4()) { - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } @@ -80,49 +80,49 @@ void RouteOrch::doTask() alias = fvValue(*i); } - // XXX: set to blackhold if nexthop is empty? + // TODO: set to blackhold if nexthop is empty? if (ip_addresses.getSize() == 0) { - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } - // XXX: cannot trust m_portsOrch->getPortIdByAlias because sometimes alias is empty - // XXX: need to split aliases with ',' and verify the next hops? + // TODO: cannot trust m_portsOrch->getPortIdByAlias because sometimes alias is empty + // TODO: need to split aliases with ',' and verify the next hops? if (alias == "eth0" || alias == "lo" || alias == "docker0") { - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); continue; } if (m_syncdRoutes.find(ip_prefix) == m_syncdRoutes.end() || m_syncdRoutes[ip_prefix] != ip_addresses) { if (addRoute(ip_prefix, ip_addresses)) - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); else it++; } else /* Duplicate entry */ - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } else if (op == DEL_COMMAND) { if (m_syncdRoutes.find(ip_prefix) != m_syncdRoutes.end()) { if (removeRoute(ip_prefix)) - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); else it++; } /* Cannot locate the route */ else - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } else { SWSS_LOG_ERROR("Unknown operation type %s\n", op.c_str()); - it = m_toSync.erase(it); + it = consumer_info.m_toSync.erase(it); } } } diff --git a/orchagent/routeorch.h b/orchagent/routeorch.h index 550accd4b48..7b7d8f2a3f9 100644 --- a/orchagent/routeorch.h +++ b/orchagent/routeorch.h @@ -35,8 +35,6 @@ class RouteOrch : public Orch m_nextHopGroupCount(0), m_resync(false) {}; - void doTask(); - bool createNextHopEntry(IpAddress, sai_object_id_t); bool createNextHopEntry(IpAddresses, sai_object_id_t); bool removeNextHopEntry(IpAddress); @@ -46,6 +44,9 @@ class RouteOrch : public Orch int getNextHopRefCount(IpAddress); int getNextHopRefCount(IpAddresses); +private: + virtual void doTask(Consumer& consumer_info); + private: PortsOrch *m_portsOrch;