diff --git a/cfgmgr/buffermgr.h b/cfgmgr/buffermgr.h index d3ef1d50a8..a8ce998546 100644 --- a/cfgmgr/buffermgr.h +++ b/cfgmgr/buffermgr.h @@ -14,22 +14,22 @@ namespace swss { #define LOSSLESS_PGS "3-4" typedef struct{ - string size; - string xon; - string xon_offset; - string xoff; - string threshold; + std::string size; + std::string xon; + std::string xon_offset; + std::string xoff; + std::string threshold; } pg_profile_t; -typedef map speed_map_t; -typedef map pg_profile_lookup_t; +typedef std::map speed_map_t; +typedef std::map pg_profile_lookup_t; -typedef map port_cable_length_t; +typedef std::map port_cable_length_t; class BufferMgr : public Orch { public: - BufferMgr(DBConnector *cfgDb, DBConnector *stateDb, string pg_lookup_file, const vector &tableNames); + BufferMgr(DBConnector *cfgDb, DBConnector *stateDb, std::string pg_lookup_file, const std::vector &tableNames); using Orch::doTask; private: @@ -44,8 +44,8 @@ class BufferMgr : public Orch port_cable_length_t m_cableLenLookup; std::string getPgPoolMode(); void readPgProfileLookupFile(std::string); - task_process_status doCableTask(string port, string cable_length); - task_process_status doSpeedUpdateTask(string port, string speed); + task_process_status doCableTask(std::string port, std::string cable_length); + task_process_status doSpeedUpdateTask(std::string port, std::string speed); void doTask(Consumer &consumer); }; diff --git a/cfgmgr/intfmgr.h b/cfgmgr/intfmgr.h index a250ff65fb..a0746e723e 100644 --- a/cfgmgr/intfmgr.h +++ b/cfgmgr/intfmgr.h @@ -13,7 +13,7 @@ namespace swss { class IntfMgr : public Orch { public: - IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector &tableNames); + IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector &tableNames); using Orch::doTask; private: @@ -21,12 +21,12 @@ class IntfMgr : public Orch Table m_cfgIntfTable, m_cfgVlanIntfTable; Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateVrfTable, m_stateIntfTable; - void setIntfIp(const string &alias, const string &opCmd, const IpPrefix &ipPrefix); - void setIntfVrf(const string &alias, const string vrfName); - bool doIntfGeneralTask(const vector& keys, const vector& data, const string& op); - bool doIntfAddrTask(const vector& keys, const vector& data, const string& op); + void setIntfIp(const std::string &alias, const std::string &opCmd, const IpPrefix &ipPrefix); + void setIntfVrf(const std::string &alias, const std::string vrfName); + bool doIntfGeneralTask(const std::vector& keys, const std::vector& data, const std::string& op); + bool doIntfAddrTask(const std::vector& keys, const std::vector& data, const std::string& op); void doTask(Consumer &consumer); - bool isIntfStateOk(const string &alias); + bool isIntfStateOk(const std::string &alias); }; } diff --git a/cfgmgr/nbrmgr.h b/cfgmgr/nbrmgr.h index 24d83971a1..6b0c664c80 100644 --- a/cfgmgr/nbrmgr.h +++ b/cfgmgr/nbrmgr.h @@ -17,14 +17,14 @@ namespace swss { class NbrMgr : public Orch { public: - NbrMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector &tableNames); + NbrMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector &tableNames); using Orch::doTask; bool isNeighRestoreDone(); private: - bool isIntfStateOk(const string &alias); - bool setNeighbor(const string& alias, const IpAddress& ip, const MacAddress& mac); + bool isIntfStateOk(const std::string &alias); + bool setNeighbor(const std::string& alias, const IpAddress& ip, const MacAddress& mac); void doTask(Consumer &consumer); diff --git a/cfgmgr/portmgr.h b/cfgmgr/portmgr.h index d7b365922f..a9724365a7 100644 --- a/cfgmgr/portmgr.h +++ b/cfgmgr/portmgr.h @@ -17,7 +17,7 @@ namespace swss { class PortMgr : public Orch { public: - PortMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector &tableNames); + PortMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector &tableNames); using Orch::doTask; private: @@ -26,13 +26,13 @@ class PortMgr : public Orch Table m_statePortTable; ProducerStateTable m_appPortTable; - set m_portList; + std::set m_portList; void doTask(Consumer &consumer); - bool setPortMtu(const string &alias, const string &mtu); - bool setPortAdminStatus(const string &alias, const bool up); - bool setPortLearnMode(const string &alias, const string &learn_mode); - bool isPortStateOk(const string &alias); + bool setPortMtu(const std::string &alias, const std::string &mtu); + bool setPortAdminStatus(const std::string &alias, const bool up); + bool setPortLearnMode(const std::string &alias, const std::string &learn_mode); + bool isPortStateOk(const std::string &alias); }; } diff --git a/cfgmgr/teammgr.h b/cfgmgr/teammgr.h index 753f27d632..99055298df 100644 --- a/cfgmgr/teammgr.h +++ b/cfgmgr/teammgr.h @@ -14,7 +14,7 @@ class TeamMgr : public Orch { public: TeamMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *staDb, - const vector &tables); + const std::vector &tables); using Orch::doTask; private: @@ -28,7 +28,7 @@ class TeamMgr : public Orch ProducerStateTable m_appPortTable; ProducerStateTable m_appLagTable; - set m_lagList; + std::set m_lagList; MacAddress m_mac; @@ -37,20 +37,20 @@ class TeamMgr : public Orch void doLagMemberTask(Consumer &consumer); void doPortUpdateTask(Consumer &consumer); - task_process_status addLag(const string &alias, int min_links, bool fall_back); - bool removeLag(const string &alias); - task_process_status addLagMember(const string &lag, const string &member); - bool removeLagMember(const string &lag, const string &member); + task_process_status addLag(const std::string &alias, int min_links, bool fall_back); + bool removeLag(const std::string &alias); + task_process_status addLagMember(const std::string &lag, const std::string &member); + bool removeLagMember(const std::string &lag, const std::string &member); - bool setLagAdminStatus(const string &alias, const string &admin_status); - bool setLagMtu(const string &alias, const string &mtu); - bool setLagLearnMode(const string &alias, const string &learn_mode); + bool setLagAdminStatus(const std::string &alias, const std::string &admin_status); + bool setLagMtu(const std::string &alias, const std::string &mtu); + bool setLagLearnMode(const std::tring &alias, const std::string &learn_mode); - bool isPortEnslaved(const string &); - bool findPortMaster(string &, const string &); - bool checkPortIffUp(const string &); - bool isPortStateOk(const string&); - bool isLagStateOk(const string&); + bool isPortEnslaved(const std::string &); + bool findPortMaster(std::string &, const std::string &); + bool checkPortIffUp(const std::string &); + bool isPortStateOk(const std::string&); + bool isLagStateOk(const std::string&); }; } diff --git a/cfgmgr/vlanmgr.h b/cfgmgr/vlanmgr.h index aff14999c2..469f16ccaf 100644 --- a/cfgmgr/vlanmgr.h +++ b/cfgmgr/vlanmgr.h @@ -14,7 +14,7 @@ namespace swss { class VlanMgr : public Orch { public: - VlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector &tableNames); + VlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector &tableNames); using Orch::doTask; private: @@ -27,18 +27,18 @@ class VlanMgr : public Orch void doTask(Consumer &consumer); void doVlanTask(Consumer &consumer); void doVlanMemberTask(Consumer &consumer); - void processUntaggedVlanMembers(string vlan, const string &members); + void processUntaggedVlanMembers(std::string vlan, const std::string &members); bool addHostVlan(int vlan_id); bool removeHostVlan(int vlan_id); - bool setHostVlanAdminState(int vlan_id, const string &admin_status); + bool setHostVlanAdminState(int vlan_id, const std::string &admin_status); bool setHostVlanMtu(int vlan_id, uint32_t mtu); - bool addHostVlanMember(int vlan_id, const string &port_alias, const string& tagging_mode); - bool removeHostVlanMember(int vlan_id, const string &port_alias); - bool isMemberStateOk(const string &alias); - bool isVlanStateOk(const string &alias); + bool addHostVlanMember(int vlan_id, const std::string &port_alias, const std::string& tagging_mode); + bool removeHostVlanMember(int vlan_id, const std::string &port_alias); + bool isMemberStateOk(const std::string &alias); + bool isVlanStateOk(const std::string &alias); bool isVlanMacOk(); - bool isVlanMemberStateOk(const string &vlanMemberKey); + bool isVlanMemberStateOk(const std::string &vlanMemberKey); }; } diff --git a/cfgmgr/vrfmgr.h b/cfgmgr/vrfmgr.h index ab20b7ffd3..aae82a906c 100644 --- a/cfgmgr/vrfmgr.h +++ b/cfgmgr/vrfmgr.h @@ -15,18 +15,18 @@ namespace swss { class VrfMgr : public Orch { public: - VrfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector &tableNames); + VrfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector &tableNames); using Orch::doTask; private: - bool delLink(const string& vrfName); - bool setLink(const string& vrfName); + bool delLink(const std::string& vrfName); + bool setLink(const std::string& vrfName); void recycleTable(uint32_t table); uint32_t getFreeTable(void); void handleVnetConfigSet(KeyOpFieldsValuesTuple &t); void doTask(Consumer &consumer); - map m_vrfTableMap; + std::map m_vrfTableMap; set m_freeTables; Table m_stateVrfTable; diff --git a/cfgmgr/vxlanmgr.h b/cfgmgr/vxlanmgr.h index ab3a81938d..a916bf8bdd 100644 --- a/cfgmgr/vxlanmgr.h +++ b/cfgmgr/vxlanmgr.h @@ -14,7 +14,7 @@ namespace swss { class VxlanMgr : public Orch { public: - VxlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector &tableNames); + VxlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector &tableNames); using Orch::doTask; typedef struct VxlanInfo diff --git a/debian/changelog b/debian/changelog index 2d2dba5fc1..be24b1de98 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,9 @@ sonic (1.0.0) stable; urgency=medium + * next-hop key add ifname + + -- Tyler Li Thu, 19 Sep 2019 04:00:00 -0700 + * Initial release. -- Shuotian Cheng Wed, 09 Mar 2016 12:00:00 -0800 diff --git a/doc/swss-schema.md b/doc/swss-schema.md index ac7e25ce5e..b58d7cc81f 100644 --- a/doc/swss-schema.md +++ b/doc/swss-schema.md @@ -456,8 +456,10 @@ Stores rules associated with a specific ACL table on the switch. ; it could be: : name of physical port. Example: "Ethernet10" : name of LAG port Example: "PortChannel5" - : next-hop ip address Example: "10.0.0.1" - : next-hop group set of addresses Example: "10.0.0.1,10.0.0.3" + : next-hop ip address (in global) Example: "10.0.0.1" + : next-hop ip address and vrf Example: "10.0.0.2@Vrf2" + : next-hop ip address and ifname Example: "10.0.0.3@Ethernet1" + : next-hop group set of next-hop Example: "10.0.0.1,10.0.0.3@Ethernet1" redirect_action = 1*255CHAR ; redirect parameter ; This parameter defines a destination for redirected packets diff --git a/fpmsyncd/routesync.cpp b/fpmsyncd/routesync.cpp index 6f45372965..9e7a9adf4e 100644 --- a/fpmsyncd/routesync.cpp +++ b/fpmsyncd/routesync.cpp @@ -334,6 +334,17 @@ string RouteSync::getNextHopGw(struct rtnl_route *route_obj) nl_addr2str(addr, gw_ip, MAX_ADDR_SIZE); result += gw_ip; } + else + { + if (rtnl_route_get_family(route_obj) == AF_INET) + { + result += "0.0.0.0"; + } + else + { + result += "::"; + } + } if (i + 1 < rtnl_route_get_nnexthops(route_obj)) { diff --git a/orchagent/aclorch.cpp b/orchagent/aclorch.cpp index 21496c05fd..24104fd484 100644 --- a/orchagent/aclorch.cpp +++ b/orchagent/aclorch.cpp @@ -546,12 +546,12 @@ void AclRule::decreaseNextHopRefCount() { if (!m_redirect_target_next_hop.empty()) { - m_pAclOrch->m_neighOrch->decreaseNextHopRefCount(IpAddress(m_redirect_target_next_hop)); + m_pAclOrch->m_neighOrch->decreaseNextHopRefCount(NextHopKey(m_redirect_target_next_hop)); m_redirect_target_next_hop.clear(); } if (!m_redirect_target_next_hop_group.empty()) { - IpAddresses target = IpAddresses(m_redirect_target_next_hop_group); + NextHopGroupKey target = NextHopGroupKey(m_redirect_target_next_hop_group); m_pAclOrch->m_routeOrch->decreaseNextHopRefCount(target); // remove next hop group in case it's not used by anything else if (m_pAclOrch->m_routeOrch->isRefCounterZero(target)) @@ -880,44 +880,44 @@ sai_object_id_t AclRuleL3::getRedirectObjectId(const string& redirect_value) } } - // Try to parse nexthop ip address + // Try to parse nexthop ip address and interface name try { - IpAddress ip(target); - if (!m_pAclOrch->m_neighOrch->hasNextHop(ip)) + NextHopKey nh(target); + if (!m_pAclOrch->m_neighOrch->hasNextHop(nh)) { - SWSS_LOG_ERROR("ACL Redirect action target next hop ip: '%s' doesn't exist on the switch", ip.to_string().c_str()); + SWSS_LOG_ERROR("ACL Redirect action target next hop ip: '%s' doesn't exist on the switch", nh.to_string().c_str()); return SAI_NULL_OBJECT_ID; } m_redirect_target_next_hop = target; - m_pAclOrch->m_neighOrch->increaseNextHopRefCount(ip); - return m_pAclOrch->m_neighOrch->getNextHopId(ip); + m_pAclOrch->m_neighOrch->increaseNextHopRefCount(nh); + return m_pAclOrch->m_neighOrch->getNextHopId(nh); } catch (...) { // no error, just try next variant } - // try to parse nh group ip addresses + // try to parse nh group the set of try { - IpAddresses ips(target); - if (!m_pAclOrch->m_routeOrch->hasNextHopGroup(ips)) + NextHopGroupKey nhg(target); + if (!m_pAclOrch->m_routeOrch->hasNextHopGroup(nhg)) { - SWSS_LOG_INFO("ACL Redirect action target next hop group: '%s' doesn't exist on the switch. Creating it.", ips.to_string().c_str()); + SWSS_LOG_INFO("ACL Redirect action target next hop group: '%s' doesn't exist on the switch. Creating it.", nhg.to_string().c_str()); - if (!m_pAclOrch->m_routeOrch->addNextHopGroup(ips)) + if (!m_pAclOrch->m_routeOrch->addNextHopGroup(nhg)) { - SWSS_LOG_ERROR("Can't create required target next hop group '%s'", ips.to_string().c_str()); + SWSS_LOG_ERROR("Can't create required target next hop group '%s'", nhg.to_string().c_str()); return SAI_NULL_OBJECT_ID; } - SWSS_LOG_DEBUG("Created acl redirect target next hop group '%s'", ips.to_string().c_str()); + SWSS_LOG_DEBUG("Created acl redirect target next hop group '%s'", nhg.to_string().c_str()); } m_redirect_target_next_hop_group = target; - m_pAclOrch->m_routeOrch->increaseNextHopRefCount(ips); - return m_pAclOrch->m_routeOrch->getNextHopGroupId(ips); + m_pAclOrch->m_routeOrch->increaseNextHopRefCount(nhg); + return m_pAclOrch->m_routeOrch->getNextHopGroupId(nhg); } catch (...) { diff --git a/orchagent/copporch.h b/orchagent/copporch.h index 7f02935c84..5fc5bc2ae8 100644 --- a/orchagent/copporch.h +++ b/orchagent/copporch.h @@ -6,33 +6,33 @@ #include "orch.h" // trap fields -const string copp_trap_id_list = "trap_ids"; -const string copp_trap_action_field = "trap_action"; -const string copp_trap_priority_field = "trap_priority"; +const std::string copp_trap_id_list = "trap_ids"; +const std::string copp_trap_action_field = "trap_action"; +const std::string copp_trap_priority_field = "trap_priority"; -const string copp_queue_field = "queue"; +const std::string copp_queue_field = "queue"; // policer fields -const string copp_policer_meter_type_field = "meter_type"; -const string copp_policer_mode_field = "mode"; -const string copp_policer_color_field = "color"; -const string copp_policer_cbs_field = "cbs"; -const string copp_policer_cir_field = "cir"; -const string copp_policer_pbs_field = "pbs"; -const string copp_policer_pir_field = "pir"; -const string copp_policer_action_green_field = "green_action"; -const string copp_policer_action_red_field = "red_action"; -const string copp_policer_action_yellow_field = "yellow_action"; +const std::string copp_policer_meter_type_field = "meter_type"; +const std::string copp_policer_mode_field = "mode"; +const std::string copp_policer_color_field = "color"; +const std::string copp_policer_cbs_field = "cbs"; +const std::string copp_policer_cir_field = "cir"; +const std::string copp_policer_pbs_field = "pbs"; +const std::string copp_policer_pir_field = "pir"; +const std::string copp_policer_action_green_field = "green_action"; +const std::string copp_policer_action_red_field = "red_action"; +const std::string copp_policer_action_yellow_field = "yellow_action"; /* TrapGroupPolicerTable: trap group ID, policer ID */ -typedef map TrapGroupPolicerTable; +typedef std::map TrapGroupPolicerTable; /* TrapIdTrapGroupTable: trap ID, trap group ID */ -typedef map TrapIdTrapGroupTable; +typedef std::map TrapIdTrapGroupTable; class CoppOrch : public Orch { public: - CoppOrch(DBConnector *db, string tableName); + CoppOrch(swss::DBConnector *db, std::string tableName); protected: object_map m_trap_group_map; @@ -44,15 +44,15 @@ class CoppOrch : public Orch void initDefaultTrapIds(); task_process_status processCoppRule(Consumer& consumer); - bool isValidList(vector &trap_id_list, vector &all_items) const; - void getTrapIdList(vector &trap_id_name_list, vector &trap_id_list) const; - bool applyTrapIds(sai_object_id_t trap_group, vector &trap_id_name_list, vector &trap_id_attribs); - bool applyAttributesToTrapIds(sai_object_id_t trap_group_id, const vector &trap_id_list, vector &trap_id_attribs); + bool isValidList(std::vector &trap_id_list, std::vector &all_items) const; + void getTrapIdList(std::vector &trap_id_name_list, std::vector &trap_id_list) const; + bool applyTrapIds(sai_object_id_t trap_group, std::vector &trap_id_name_list, std::vector &trap_id_attribs); + bool applyAttributesToTrapIds(sai_object_id_t trap_group_id, const std::vector &trap_id_list, std::vector &trap_id_attribs); - bool createPolicer(string trap_group, vector &policer_attribs); - bool removePolicer(string trap_group_name); + bool createPolicer(std::string trap_group, std::vector &policer_attribs); + bool removePolicer(std::string trap_group_name); - sai_object_id_t getPolicer(string trap_group_name); + sai_object_id_t getPolicer(std::string trap_group_name); virtual void doTask(Consumer& consumer); }; diff --git a/orchagent/countercheckorch.h b/orchagent/countercheckorch.h index 7d951728bd..ec25344a5d 100644 --- a/orchagent/countercheckorch.h +++ b/orchagent/countercheckorch.h @@ -12,31 +12,31 @@ extern "C" { #include "sai.h" } -typedef vector QueueMcCounters; -typedef array PfcFrameCounters; +typedef std::vector QueueMcCounters; +typedef std::array PfcFrameCounters; class CounterCheckOrch: public Orch { public: - static CounterCheckOrch& getInstance(DBConnector *db = nullptr); - virtual void doTask(SelectableTimer &timer); + static CounterCheckOrch& getInstance(swss::DBConnector *db = nullptr); + virtual void doTask(swss::SelectableTimer &timer); virtual void doTask(Consumer &consumer) {} - void addPort(const Port& port); - void removePort(const Port& port); + void addPort(const swss::Port& port); + void removePort(const swss::Port& port); private: - CounterCheckOrch(DBConnector *db, vector &tableNames); + CounterCheckOrch(swss::DBConnector *db, std::vector &tableNames); virtual ~CounterCheckOrch(void); - QueueMcCounters getQueueMcCounters(const Port& port); + QueueMcCounters getQueueMcCounters(const swss::Port& port); PfcFrameCounters getPfcFrameCounters(sai_object_id_t portId); void mcCounterCheck(); void pfcFrameCounterCheck(); - map m_mcCountersMap; - map m_pfcFrameCountersMap; + std::map m_mcCountersMap; + std::map m_pfcFrameCountersMap; - shared_ptr m_countersDb = nullptr; - shared_ptr m_countersTable = nullptr; + std::shared_ptr m_countersDb = nullptr; + std::shared_ptr m_countersTable = nullptr; }; #endif diff --git a/orchagent/crmorch.cpp b/orchagent/crmorch.cpp index 9e26cd58aa..03dcea26dd 100644 --- a/orchagent/crmorch.cpp +++ b/orchagent/crmorch.cpp @@ -20,6 +20,7 @@ extern sai_switch_api_t *sai_switch_api; extern sai_acl_api_t *sai_acl_api; using namespace std; +using namespace swss; const map crmResTypeNameMap = diff --git a/orchagent/crmorch.h b/orchagent/crmorch.h index eac50da992..488a18b3a7 100644 --- a/orchagent/crmorch.h +++ b/orchagent/crmorch.h @@ -37,7 +37,7 @@ enum class CrmThresholdType class CrmOrch : public Orch { public: - CrmOrch(DBConnector *db, string tableName); + CrmOrch(swss::DBConnector *db, std::string tableName); void incCrmResUsedCounter(CrmResourceType resource); void decCrmResUsedCounter(CrmResourceType resource); // Increment "used" counter for the ACL table/group CRM resources @@ -50,9 +50,9 @@ class CrmOrch : public Orch void decCrmAclTableUsedCounter(CrmResourceType resource, sai_object_id_t tableId); private: - shared_ptr m_countersDb = nullptr; - shared_ptr
m_countersCrmTable = nullptr; - SelectableTimer *m_timer = nullptr; + std::shared_ptr m_countersDb = nullptr; + std::shared_ptr m_countersCrmTable = nullptr; + swss::SelectableTimer *m_timer = nullptr; struct CrmResourceCounter { @@ -63,29 +63,29 @@ class CrmOrch : public Orch struct CrmResourceEntry { - CrmResourceEntry(string name, CrmThresholdType thresholdType, uint32_t lowThreshold, uint32_t highThreshold); + CrmResourceEntry(std::string name, CrmThresholdType thresholdType, uint32_t lowThreshold, uint32_t highThreshold); - string name; + std::string name; CrmThresholdType thresholdType = CrmThresholdType::CRM_PERCENTAGE; uint32_t lowThreshold = 70; uint32_t highThreshold = 85; - map countersMap; + std::map countersMap; uint32_t exceededLogCounter = 0; }; - chrono::seconds m_pollingInterval; + std::chrono::seconds m_pollingInterval; - map m_resourcesMap; + std::map m_resourcesMap; void doTask(Consumer &consumer); - void handleSetCommand(const string& key, const vector& data); - void doTask(SelectableTimer &timer); + void handleSetCommand(const std::string& key, const std::vector& data); + void doTask(swss::SelectableTimer &timer); void getResAvailableCounters(); void updateCrmCountersTable(); void checkCrmThresholds(); - string getCrmAclKey(sai_acl_stage_t stage, sai_acl_bind_point_type_t bindPoint); - string getCrmAclTableKey(sai_object_id_t id); + std::string getCrmAclKey(sai_acl_stage_t stage, sai_acl_bind_point_type_t bindPoint); + std::string getCrmAclTableKey(sai_object_id_t id); }; diff --git a/orchagent/flexcounterorch.h b/orchagent/flexcounterorch.h index c651a49d38..27f6e64ab1 100644 --- a/orchagent/flexcounterorch.h +++ b/orchagent/flexcounterorch.h @@ -13,12 +13,12 @@ class FlexCounterOrch: public Orch { public: void doTask(Consumer &consumer); - FlexCounterOrch(DBConnector *db, vector &tableNames); + FlexCounterOrch(swss::DBConnector *db, std::vector &tableNames); virtual ~FlexCounterOrch(void); private: - shared_ptr m_flexCounterDb = nullptr; - shared_ptr m_flexCounterGroupTable = nullptr; + std::shared_ptr m_flexCounterDb = nullptr; + std::shared_ptr m_flexCounterGroupTable = nullptr; }; #endif diff --git a/orchagent/intfsorch.cpp b/orchagent/intfsorch.cpp index c36e6757c9..cf6a926cfd 100644 --- a/orchagent/intfsorch.cpp +++ b/orchagent/intfsorch.cpp @@ -79,10 +79,35 @@ sai_object_id_t IntfsOrch::getRouterIntfsId(const string &alias) { Port port; gPortsOrch->getPort(alias, port); - assert(port.m_rif_id); return port.m_rif_id; } +string IntfsOrch::getRouterIntfsAlias(const IpAddress &ip, const string &vrf_name) +{ + sai_object_id_t vrf_id = gVirtualRouterId; + + if (!vrf_name.empty()) + { + vrf_id = m_vrfOrch->getVRFid(vrf_name); + } + + for (const auto &it_intfs: m_syncdIntfses) + { + if (it_intfs.second.vrf_id != vrf_id) + { + continue; + } + for (const auto &prefixIt: it_intfs.second.ip_addresses) + { + if (prefixIt.isAddressInSubnet(ip)) + { + return it_intfs.first; + } + } + } + return string(); +} + void IntfsOrch::increaseRouterIntfsRefCount(const string &alias) { SWSS_LOG_ENTER(); @@ -154,6 +179,7 @@ bool IntfsOrch::setIntf(const string& alias, sai_object_id_t vrf_id, const IpPre gPortsOrch->increasePortRefCount(alias); IntfsEntry intfs_entry; intfs_entry.ref_count = 0; + intfs_entry.vrf_id = vrf_id; m_syncdIntfses[alias] = intfs_entry; } else @@ -328,6 +354,7 @@ void IntfsOrch::doTask(Consumer &consumer) IntfsEntry intfs_entry; intfs_entry.ref_count = 0; + intfs_entry.vrf_id = vrf_id; intfs_entry.ip_addresses.insert(ip_prefix); m_syncdIntfses[alias] = intfs_entry; addIp2Me = true; @@ -629,7 +656,7 @@ void IntfsOrch::addSubnetRoute(const Port &port, const IpPrefix &ip_prefix) gCrmOrch->incCrmResUsedCounter(CrmResourceType::CRM_IPV6_ROUTE); } - gRouteOrch->notifyNextHopChangeObservers(ip_prefix, IpAddresses(), true); + gRouteOrch->notifyNextHopChangeObservers(ip_prefix, NextHopGroupKey(), true); } void IntfsOrch::removeSubnetRoute(const Port &port, const IpPrefix &ip_prefix) @@ -661,7 +688,7 @@ void IntfsOrch::removeSubnetRoute(const Port &port, const IpPrefix &ip_prefix) gCrmOrch->decCrmResUsedCounter(CrmResourceType::CRM_IPV6_ROUTE); } - gRouteOrch->notifyNextHopChangeObservers(ip_prefix, IpAddresses(), false); + gRouteOrch->notifyNextHopChangeObservers(ip_prefix, NextHopGroupKey(), false); } void IntfsOrch::addIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix) diff --git a/orchagent/intfsorch.h b/orchagent/intfsorch.h index 9030186387..acf1276a62 100644 --- a/orchagent/intfsorch.h +++ b/orchagent/intfsorch.h @@ -22,6 +22,7 @@ struct IntfsEntry { std::set ip_addresses; int ref_count; + sai_object_id_t vrf_id; }; typedef map IntfsTable; @@ -32,6 +33,7 @@ class IntfsOrch : public Orch IntfsOrch(DBConnector *db, string tableName, VRFOrch *vrf_orch); sai_object_id_t getRouterIntfsId(const string&); + string getRouterIntfsAlias(const IpAddress &ip, const string &vrf_name = ""); void increaseRouterIntfsRefCount(const string&); void decreaseRouterIntfsRefCount(const string&); diff --git a/orchagent/mirrororch.cpp b/orchagent/mirrororch.cpp index 91b07aa81a..23e1a881bf 100644 --- a/orchagent/mirrororch.cpp +++ b/orchagent/mirrororch.cpp @@ -60,7 +60,7 @@ MirrorEntry::MirrorEntry(const string& platform) : } nexthopInfo.prefix = IpPrefix("0.0.0.0/0"); - nexthopInfo.nexthop = IpAddress("0.0.0.0"); + nexthopInfo.nexthop = NextHopKey("0.0.0.0", ""); } MirrorOrch::MirrorOrch(TableConnector stateDbConnector, TableConnector confDbConnector, @@ -456,7 +456,7 @@ bool MirrorOrch::getNeighborInfo(const string& name, MirrorEntry& session) // 3) Otherwise, return false. if (!m_neighOrch->getNeighborEntry(session.dstIp, session.neighborInfo.neighbor, session.neighborInfo.mac) && - (session.nexthopInfo.nexthop.isZero() || + (session.nexthopInfo.nexthop.ip_address.isZero() || !m_neighOrch->getNeighborEntry(session.nexthopInfo.nexthop, session.neighborInfo.neighbor, session.neighborInfo.mac))) { @@ -894,8 +894,8 @@ void MirrorOrch::updateNextHop(const NextHopUpdate& update) // This is the ECMP scenario that the new next hop group contains the previous // next hop. There is no need to update this session's monitor port. - if (update.nexthopGroup != IpAddresses() && - update.nexthopGroup.getIpAddresses().count(session.nexthopInfo.nexthop)) + if (update.nexthopGroup != NextHopGroupKey() && + update.nexthopGroup.getNextHops().count(session.nexthopInfo.nexthop)) { continue; @@ -904,18 +904,18 @@ void MirrorOrch::updateNextHop(const NextHopUpdate& update) SWSS_LOG_NOTICE("Updating mirror session %s with route %s", name.c_str(), update.prefix.to_string().c_str()); - if (update.nexthopGroup != IpAddresses()) + if (update.nexthopGroup != NextHopGroupKey()) { SWSS_LOG_NOTICE(" next hop IPs: %s", update.nexthopGroup.to_string().c_str()); // Recover the session based on the state database information if (m_recoverySessionMap.find(name) != m_recoverySessionMap.end()) { - IpAddress nexthop = IpAddress(tokenize(m_recoverySessionMap[name], + NextHopKey nexthop = NextHopKey(tokenize(m_recoverySessionMap[name], state_db_key_delimiter, 1)[1]); // Check if recovered next hop IP is within the update's next hop IPs - if (update.nexthopGroup.getIpAddresses().count(nexthop)) + if (update.nexthopGroup.getNextHops().count(nexthop)) { SWSS_LOG_NOTICE("Recover mirror session %s with next hop %s", name.c_str(), nexthop.to_string().c_str()); @@ -927,18 +927,18 @@ void MirrorOrch::updateNextHop(const NextHopUpdate& update) SWSS_LOG_NOTICE("Correct mirror session %s next hop from %s to %s", name.c_str(), session.nexthopInfo.nexthop.to_string().c_str(), nexthop.to_string().c_str()); - session.nexthopInfo.nexthop = *update.nexthopGroup.getIpAddresses().begin(); + session.nexthopInfo.nexthop = *update.nexthopGroup.getNextHops().begin(); } } else { // Pick the first one from the next hop group - session.nexthopInfo.nexthop = *update.nexthopGroup.getIpAddresses().begin(); + session.nexthopInfo.nexthop = *update.nexthopGroup.getNextHops().begin(); } } else { - session.nexthopInfo.nexthop = IpAddress(0); + session.nexthopInfo.nexthop = NextHopKey("0.0.0.0", ""); } // Resolve the neighbor of the new next hop @@ -960,7 +960,7 @@ void MirrorOrch::updateNeighbor(const NeighborUpdate& update) // Check if the session's destination IP matches the neighbor's update IP // or if the session's next hop IP matches the neighbor's update IP if (session.dstIp != update.entry.ip_address && - session.nexthopInfo.nexthop != update.entry.ip_address) + session.nexthopInfo.nexthop.ip_address != update.entry.ip_address) { continue; } diff --git a/orchagent/mirrororch.h b/orchagent/mirrororch.h index 1635012a18..b367e4fba8 100644 --- a/orchagent/mirrororch.h +++ b/orchagent/mirrororch.h @@ -36,7 +36,7 @@ struct MirrorEntry struct { IpPrefix prefix; - IpAddress nexthop; + NextHopKey nexthop; } nexthopInfo; struct diff --git a/orchagent/neighorch.cpp b/orchagent/neighorch.cpp index f416841800..5f81e4ba73 100644 --- a/orchagent/neighorch.cpp +++ b/orchagent/neighorch.cpp @@ -21,12 +21,12 @@ NeighOrch::NeighOrch(DBConnector *db, string tableName, IntfsOrch *intfsOrch) : SWSS_LOG_ENTER(); } -bool NeighOrch::hasNextHop(IpAddress ipAddress) +bool NeighOrch::hasNextHop(const NextHopKey &nexthop) { - return m_syncdNextHops.find(ipAddress) != m_syncdNextHops.end(); + return m_syncdNextHops.find(nexthop) != m_syncdNextHops.end(); } -bool NeighOrch::addNextHop(IpAddress ipAddress, string alias) +bool NeighOrch::addNextHop(const IpAddress &ipAddress, const string &alias) { SWSS_LOG_ENTER(); @@ -38,7 +38,8 @@ bool NeighOrch::addNextHop(IpAddress ipAddress, string alias) return false; } - assert(!hasNextHop(ipAddress)); + NextHopKey nexthop = { ipAddress, alias }; + assert(!hasNextHop(nexthop)); sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsId(alias); vector next_hop_attrs; @@ -72,8 +73,7 @@ bool NeighOrch::addNextHop(IpAddress ipAddress, string alias) next_hop_entry.next_hop_id = next_hop_id; next_hop_entry.ref_count = 0; next_hop_entry.nh_flags = 0; - next_hop_entry.if_alias = alias; - m_syncdNextHops[ipAddress] = next_hop_entry; + m_syncdNextHops[nexthop] = next_hop_entry; m_intfsOrch->increaseRouterIntfsRefCount(alias); @@ -92,7 +92,7 @@ bool NeighOrch::addNextHop(IpAddress ipAddress, string alias) // is processed after incoming port is down. if (p.m_oper_status == SAI_PORT_OPER_STATUS_DOWN) { - if (setNextHopFlag(ipAddress, NHFLAGS_IFDOWN) == false) + if (setNextHopFlag(nexthop, NHFLAGS_IFDOWN) == false) { SWSS_LOG_WARN("Failed to set NHFLAGS_IFDOWN on nexthop %s for interface %s", ipAddress.to_string().c_str(), alias.c_str()); @@ -101,11 +101,11 @@ bool NeighOrch::addNextHop(IpAddress ipAddress, string alias) return true; } -bool NeighOrch::setNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag) +bool NeighOrch::setNextHopFlag(const NextHopKey &nexthop, const uint32_t nh_flag) { SWSS_LOG_ENTER(); - auto nhop = m_syncdNextHops.find(ipaddr); + auto nhop = m_syncdNextHops.find(nexthop); bool rc = false; assert(nhop != m_syncdNextHops.end()); @@ -120,7 +120,7 @@ bool NeighOrch::setNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag) switch (nh_flag) { case NHFLAGS_IFDOWN: - rc = gRouteOrch->invalidnexthopinNextHopGroup(ipaddr); + rc = gRouteOrch->invalidnexthopinNextHopGroup(nexthop); break; default: assert(0); @@ -130,11 +130,11 @@ bool NeighOrch::setNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag) return rc; } -bool NeighOrch::clearNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag) +bool NeighOrch::clearNextHopFlag(const NextHopKey &nexthop, const uint32_t nh_flag) { SWSS_LOG_ENTER(); - auto nhop = m_syncdNextHops.find(ipaddr); + auto nhop = m_syncdNextHops.find(nexthop); bool rc = false; assert(nhop != m_syncdNextHops.end()); @@ -149,7 +149,7 @@ bool NeighOrch::clearNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag switch (nh_flag) { case NHFLAGS_IFDOWN: - rc = gRouteOrch->validnexthopinNextHopGroup(ipaddr); + rc = gRouteOrch->validnexthopinNextHopGroup(nexthop); break; default: assert(0); @@ -159,11 +159,11 @@ bool NeighOrch::clearNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag return rc; } -bool NeighOrch::isNextHopFlagSet(const IpAddress &ipaddr, const uint32_t nh_flag) +bool NeighOrch::isNextHopFlagSet(const NextHopKey &nexthop, const uint32_t nh_flag) { SWSS_LOG_ENTER(); - auto nhop = m_syncdNextHops.find(ipaddr); + auto nhop = m_syncdNextHops.find(nexthop); assert(nhop != m_syncdNextHops.end()); @@ -182,7 +182,7 @@ bool NeighOrch::ifChangeInformNextHop(const string &alias, bool if_up) for (auto nhop = m_syncdNextHops.begin(); nhop != m_syncdNextHops.end(); ++nhop) { - if (nhop->second.if_alias != alias) + if (nhop->first.alias != alias) { continue; } @@ -209,58 +209,59 @@ bool NeighOrch::ifChangeInformNextHop(const string &alias, bool if_up) return rc; } -bool NeighOrch::removeNextHop(IpAddress ipAddress, string alias) +bool NeighOrch::removeNextHop(const IpAddress &ipAddress, const string &alias) { SWSS_LOG_ENTER(); - assert(hasNextHop(ipAddress)); + NextHopKey nexthop = { ipAddress, alias }; + assert(hasNextHop(nexthop)); - if (m_syncdNextHops[ipAddress].ref_count > 0) + if (m_syncdNextHops[nexthop].ref_count > 0) { SWSS_LOG_ERROR("Failed to remove still referenced next hop %s on %s", ipAddress.to_string().c_str(), alias.c_str()); return false; } - m_syncdNextHops.erase(ipAddress); + m_syncdNextHops.erase(nexthop); m_intfsOrch->decreaseRouterIntfsRefCount(alias); return true; } -sai_object_id_t NeighOrch::getNextHopId(const IpAddress &ipAddress) +sai_object_id_t NeighOrch::getNextHopId(const NextHopKey &nexthop) { - assert(hasNextHop(ipAddress)); - return m_syncdNextHops[ipAddress].next_hop_id; + assert(hasNextHop(nexthop)); + return m_syncdNextHops[nexthop].next_hop_id; } -int NeighOrch::getNextHopRefCount(const IpAddress &ipAddress) +int NeighOrch::getNextHopRefCount(const NextHopKey &nexthop) { - assert(hasNextHop(ipAddress)); - return m_syncdNextHops[ipAddress].ref_count; + assert(hasNextHop(nexthop)); + return m_syncdNextHops[nexthop].ref_count; } -void NeighOrch::increaseNextHopRefCount(const IpAddress &ipAddress) +void NeighOrch::increaseNextHopRefCount(const NextHopKey &nexthop) { - assert(hasNextHop(ipAddress)); - m_syncdNextHops[ipAddress].ref_count ++; + assert(hasNextHop(nexthop)); + m_syncdNextHops[nexthop].ref_count ++; } -void NeighOrch::decreaseNextHopRefCount(const IpAddress &ipAddress) +void NeighOrch::decreaseNextHopRefCount(const NextHopKey &nexthop) { - assert(hasNextHop(ipAddress)); - m_syncdNextHops[ipAddress].ref_count --; + assert(hasNextHop(nexthop)); + m_syncdNextHops[nexthop].ref_count --; } -bool NeighOrch::getNeighborEntry(const IpAddress &ipAddress, NeighborEntry &neighborEntry, MacAddress &macAddress) +bool NeighOrch::getNeighborEntry(const NextHopKey &nexthop, NeighborEntry &neighborEntry, MacAddress &macAddress) { - if (!hasNextHop(ipAddress)) + if (!hasNextHop(nexthop)) { return false; } for (const auto &entry : m_syncdNeighbors) { - if (entry.first.ip_address == ipAddress) + if (entry.first.ip_address == nexthop.ip_address && entry.first.alias == nexthop.alias) { neighborEntry = entry.first; macAddress = entry.second; @@ -271,6 +272,18 @@ bool NeighOrch::getNeighborEntry(const IpAddress &ipAddress, NeighborEntry &neig return false; } +bool NeighOrch::getNeighborEntry(const IpAddress &ipAddress, NeighborEntry &neighborEntry, MacAddress &macAddress) +{ + string alias = m_intfsOrch->getRouterIntfsAlias(ipAddress); + if (alias.empty()) + { + return false; + } + + NextHopKey nexthop(ipAddress, alias); + return getNeighborEntry(nexthop, neighborEntry, macAddress); +} + void NeighOrch::doTask(Consumer &consumer) { SWSS_LOG_ENTER(); @@ -369,7 +382,7 @@ void NeighOrch::doTask(Consumer &consumer) } } -bool NeighOrch::addNeighbor(NeighborEntry neighborEntry, MacAddress macAddress) +bool NeighOrch::addNeighbor(const NeighborEntry &neighborEntry, const MacAddress &macAddress) { SWSS_LOG_ENTER(); @@ -378,6 +391,11 @@ bool NeighOrch::addNeighbor(NeighborEntry neighborEntry, MacAddress macAddress) string alias = neighborEntry.alias; sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsId(alias); + if (rif_id == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_INFO("Failed to get rif_id for %s", alias.c_str()); + return false; + } sai_neighbor_entry_t neighbor_entry; neighbor_entry.rif_id = rif_id; @@ -463,20 +481,21 @@ bool NeighOrch::addNeighbor(NeighborEntry neighborEntry, MacAddress macAddress) return true; } -bool NeighOrch::removeNeighbor(NeighborEntry neighborEntry) +bool NeighOrch::removeNeighbor(const NeighborEntry &neighborEntry) { SWSS_LOG_ENTER(); sai_status_t status; IpAddress ip_address = neighborEntry.ip_address; string alias = neighborEntry.alias; + NextHopKey nexthop = { ip_address, alias }; if (m_syncdNeighbors.find(neighborEntry) == m_syncdNeighbors.end()) { return true; } - if (m_syncdNextHops[ip_address].ref_count > 0) + if (m_syncdNextHops[nexthop].ref_count > 0) { SWSS_LOG_INFO("Failed to remove still referenced neighbor %s on %s", m_syncdNeighbors[neighborEntry].to_string().c_str(), alias.c_str()); @@ -490,7 +509,7 @@ bool NeighOrch::removeNeighbor(NeighborEntry neighborEntry) neighbor_entry.switch_id = gSwitchId; copy(neighbor_entry.ip_address, ip_address); - sai_object_id_t next_hop_id = m_syncdNextHops[ip_address].next_hop_id; + sai_object_id_t next_hop_id = m_syncdNextHops[nexthop].next_hop_id; status = sai_next_hop_api->remove_next_hop(next_hop_id); if (status != SAI_STATUS_SUCCESS) { diff --git a/orchagent/neighorch.h b/orchagent/neighorch.h index 71257d1415..60c40f9053 100644 --- a/orchagent/neighorch.h +++ b/orchagent/neighorch.h @@ -7,42 +7,23 @@ #include "intfsorch.h" #include "ipaddress.h" +#include "nexthopkey.h" #define NHFLAGS_IFDOWN 0x1 // nexthop's outbound i/f is down -struct NeighborEntry -{ - IpAddress ip_address; // neighbor IP address - string alias; // incoming interface alias - - bool operator<(const NeighborEntry &o) const - { - return tie(ip_address, alias) < tie(o.ip_address, o.alias); - } - - bool operator==(const NeighborEntry &o) const - { - return (ip_address == o.ip_address) && (alias == o.alias); - } - - bool operator!=(const NeighborEntry &o) const - { - return !(*this == o); - } -}; +typedef NextHopKey NeighborEntry; struct NextHopEntry { sai_object_id_t next_hop_id; // next hop id int ref_count; // reference count uint32_t nh_flags; // flags - string if_alias; // i/f name alias }; /* NeighborTable: NeighborEntry, neighbor MAC address */ typedef map NeighborTable; -/* NextHopTable: next hop IP address, NextHopEntry */ -typedef map NextHopTable; +/* NextHopTable: NextHopKey, NextHopEntry */ +typedef map NextHopTable; struct NeighborUpdate { @@ -56,18 +37,19 @@ class NeighOrch : public Orch, public Subject public: NeighOrch(DBConnector *db, string tableName, IntfsOrch *intfsOrch); - bool hasNextHop(IpAddress); + bool hasNextHop(const NextHopKey&); - sai_object_id_t getNextHopId(const IpAddress&); - int getNextHopRefCount(const IpAddress&); + sai_object_id_t getNextHopId(const NextHopKey&); + int getNextHopRefCount(const NextHopKey&); - void increaseNextHopRefCount(const IpAddress&); - void decreaseNextHopRefCount(const IpAddress&); + void increaseNextHopRefCount(const NextHopKey&); + void decreaseNextHopRefCount(const NextHopKey&); + bool getNeighborEntry(const NextHopKey&, NeighborEntry&, MacAddress&); bool getNeighborEntry(const IpAddress&, NeighborEntry&, MacAddress&); bool ifChangeInformNextHop(const string &, bool); - bool isNextHopFlagSet(const IpAddress &, const uint32_t); + bool isNextHopFlagSet(const NextHopKey &, const uint32_t); private: IntfsOrch *m_intfsOrch; @@ -75,14 +57,14 @@ class NeighOrch : public Orch, public Subject NeighborTable m_syncdNeighbors; NextHopTable m_syncdNextHops; - bool addNextHop(IpAddress, string); - bool removeNextHop(IpAddress, string); + bool addNextHop(const IpAddress&, const string&); + bool removeNextHop(const IpAddress&, const string&); - bool addNeighbor(NeighborEntry, MacAddress); - bool removeNeighbor(NeighborEntry); + bool addNeighbor(const NeighborEntry&, const MacAddress&); + bool removeNeighbor(const NeighborEntry&); - bool setNextHopFlag(const IpAddress &, const uint32_t); - bool clearNextHopFlag(const IpAddress &, const uint32_t); + bool setNextHopFlag(const NextHopKey &, const uint32_t); + bool clearNextHopFlag(const NextHopKey &, const uint32_t); void doTask(Consumer &consumer); }; diff --git a/orchagent/nexthopgroupkey.h b/orchagent/nexthopgroupkey.h new file mode 100644 index 0000000000..6e90845d90 --- /dev/null +++ b/orchagent/nexthopgroupkey.h @@ -0,0 +1,126 @@ +#ifndef SWSS_NEXTHOPGROUPKEY_H +#define SWSS_NEXTHOPGROUPKEY_H + +#include "nexthopkey.h" + +class NextHopGroupKey +{ +public: + NextHopGroupKey() = default; + + /* ip_string@if_alias separated by ',' */ + NextHopGroupKey(const std::string &nexthops) + { + auto nhv = tokenize(nexthops, NHG_DELIMITER); + for (const auto &nh : nhv) + { + m_nexthops.insert(nh); + } + } + + inline const std::set &getNextHops() const + { + return m_nexthops; + } + + inline size_t getSize() const + { + return m_nexthops.size(); + } + + inline bool operator<(const NextHopGroupKey &o) const + { + return m_nexthops < o.m_nexthops; + } + + inline bool operator==(const NextHopGroupKey &o) const + { + return m_nexthops == o.m_nexthops; + } + + inline bool operator!=(const NextHopGroupKey &o) const + { + return !(*this == o); + } + + void add(const std::string &ip, const std::string &alias) + { + m_nexthops.emplace(ip, alias); + } + + void add(const std::string &nh) + { + m_nexthops.insert(nh); + } + + void add(const NextHopKey &nh) + { + m_nexthops.insert(nh); + } + + bool contains(const std::string &ip, const std::string &alias) const + { + NextHopKey nh(ip, alias); + return m_nexthops.find(nh) != m_nexthops.end(); + } + + bool contains(const std::string &nh) const + { + return m_nexthops.find(nh) != m_nexthops.end(); + } + + bool contains(const NextHopKey &nh) const + { + return m_nexthops.find(nh) != m_nexthops.end(); + } + + bool contains(const NextHopGroupKey &nhs) const + { + for (const auto &nh : nhs.getNextHops()) + { + if (!contains(nh)) + { + return false; + } + } + return true; + } + + void remove(const std::string &ip, const std::string &alias) + { + NextHopKey nh(ip, alias); + m_nexthops.erase(nh); + } + + void remove(const std::string &nh) + { + m_nexthops.erase(nh); + } + + void remove(const NextHopKey &nh) + { + m_nexthops.erase(nh); + } + + const std::string to_string() const + { + string nhs_str; + + for (auto it = m_nexthops.begin(); it != m_nexthops.end(); ++it) + { + if (it != m_nexthops.begin()) + { + nhs_str += NHG_DELIMITER; + } + + nhs_str += it->to_string(); + } + + return nhs_str; + } + +private: + std::set m_nexthops; +}; + +#endif /* SWSS_NEXTHOPGROUPKEY_H */ diff --git a/orchagent/nexthopkey.h b/orchagent/nexthopkey.h new file mode 100644 index 0000000000..a86aac2cc1 --- /dev/null +++ b/orchagent/nexthopkey.h @@ -0,0 +1,69 @@ +#ifndef SWSS_NEXTHOPKEY_H +#define SWSS_NEXTHOPKEY_H + +#include "ipaddress.h" +#include "tokenize.h" + +#define NH_DELIMITER '@' +#define NHG_DELIMITER ',' +#define VRF_PREFIX "Vrf" +extern IntfsOrch *gIntfsOrch; + +struct NextHopKey +{ + IpAddress ip_address; // neighbor IP address + string alias; // incoming interface alias + + NextHopKey() = default; + NextHopKey(const std::string &ipstr, const std::string &alias) : ip_address(ipstr), alias(alias) {} + NextHopKey(const IpAddress &ip, const std::string &alias) : ip_address(ip), alias(alias) {} + NextHopKey(const std::string &str) + { + if (str.find(NHG_DELIMITER) != string::npos) + { + std::string err = "Error converting " + str + " to NextHop"; + throw std::invalid_argument(err); + } + auto keys = tokenize(str, NH_DELIMITER); + if (keys.size() == 1) + { + ip_address = keys[0]; + alias = gIntfsOrch->getRouterIntfsAlias(ip_address); + } + else if (keys.size() == 2) + { + ip_address = keys[0]; + alias = keys[1]; + if (!alias.compare(0, strlen(VRF_PREFIX), VRF_PREFIX)) + { + alias = gIntfsOrch->getRouterIntfsAlias(ip_address, alias); + } + } + else + { + std::string err = "Error converting " + str + " to NextHop"; + throw std::invalid_argument(err); + } + } + const std::string to_string() const + { + return ip_address.to_string() + NH_DELIMITER + alias; + } + + bool operator<(const NextHopKey &o) const + { + return tie(ip_address, alias) < tie(o.ip_address, o.alias); + } + + bool operator==(const NextHopKey &o) const + { + return (ip_address == o.ip_address) && (alias == o.alias); + } + + bool operator!=(const NextHopKey &o) const + { + return !(*this == o); + } +}; + +#endif /* SWSS_NEXTHOPKEY_H */ diff --git a/orchagent/notifier.h b/orchagent/notifier.h index ca9011f23d..2df9c7ff6c 100644 --- a/orchagent/notifier.h +++ b/orchagent/notifier.h @@ -2,14 +2,14 @@ class Notifier : public Executor { public: - Notifier(NotificationConsumer *select, Orch *orch, const string &name) + Notifier(swss::NotificationConsumer *select, Orch *orch, const std::string &name) : Executor(select, orch, name) { } - NotificationConsumer *getNotificationConsumer() const + swss::NotificationConsumer *getNotificationConsumer() const { - return static_cast(getSelectable()); + return static_cast(getSelectable()); } void execute() diff --git a/orchagent/orch.h b/orchagent/orch.h index 8b2a130823..202aa91e21 100644 --- a/orchagent/orch.h +++ b/orchagent/orch.h @@ -20,9 +20,6 @@ extern "C" { #include "selectabletimer.h" #include "macaddress.h" -using namespace std; -using namespace swss; - const char delimiter = ':'; const char list_item_delimiter = ','; const char ref_start = '['; @@ -53,14 +50,14 @@ typedef enum task_ignore } task_process_status; -typedef map object_map; -typedef pair object_map_pair; +typedef std::map object_map; +typedef std::pair object_map_pair; -typedef map type_map; -typedef pair type_map_pair; -typedef map SyncMap; +typedef std::map type_map; +typedef std::pair type_map_pair; +typedef std::map SyncMap; -typedef pair table_name_with_pri_t; +typedef std::pair table_name_with_pri_t; class Orch; @@ -68,10 +65,10 @@ class Orch; // 1. one Orch can have one or more Executor // 2. one Executor must belong to one and only one Orch // 3. Executor will hold an pointer to new-ed selectable, and delete it during dtor -class Executor : public Selectable +class Executor : public swss::Selectable { public: - Executor(Selectable *selectable, Orch *orch, const string &name) + Executor(swss::Selectable *selectable, Orch *orch, const std::string &name) : m_selectable(selectable) , m_orch(orch) , m_name(name) @@ -95,35 +92,35 @@ class Executor : public Selectable virtual void execute() { } virtual void drain() { } - virtual string getName() const + virtual std::string getName() const { return m_name; } protected: - Selectable *m_selectable; + swss::Selectable *m_selectable; Orch *m_orch; // Name for Executor - string m_name; + std::string m_name; // Get the underlying selectable - Selectable *getSelectable() const { return m_selectable; } + swss::Selectable *getSelectable() const { return m_selectable; } }; class Consumer : public Executor { public: - Consumer(ConsumerTableBase *select, Orch *orch, const string &name) + Consumer(swss::ConsumerTableBase *select, Orch *orch, const std::string &name) : Executor(select, orch, name) { } - ConsumerTableBase *getConsumerTable() const + swss::ConsumerTableBase *getConsumerTable() const { - return static_cast(getSelectable()); + return static_cast(getSelectable()); } - string getTableName() const + std::string getTableName() const { return getConsumerTable()->getTableName(); } @@ -133,11 +130,11 @@ class Consumer : public Executor { return getConsumerTable()->getDbId(); } - string dumpTuple(KeyOpFieldsValuesTuple &tuple); - void dumpPendingTasks(vector &ts); + std::string dumpTuple(swss::KeyOpFieldsValuesTuple &tuple); + void dumpPendingTasks(std::vector &ts); size_t refillToSync(); - size_t refillToSync(Table* table); + size_t refillToSync(swss::Table* table); void execute(); void drain(); @@ -147,10 +144,10 @@ class Consumer : public Executor { protected: // Returns: the number of entries added to m_toSync - size_t addToSync(std::deque &entries); + size_t addToSync(std::deque &entries); }; -typedef map> ConsumerMap; +typedef std::map> ConsumerMap; typedef enum { @@ -162,23 +159,23 @@ typedef enum failure } ref_resolve_status; -typedef pair TableConnector; -typedef pair> TablesConnector; +typedef std::pair TableConnector; +typedef std::pair> TablesConnector; class Orch { public: - Orch(DBConnector *db, const string tableName, int pri = default_orch_pri); - Orch(DBConnector *db, const vector &tableNames); - Orch(DBConnector *db, const vector &tableNameWithPri); - Orch(const vector& tables); + Orch(swss::DBConnector *db, const std::string tableName, int pri = default_orch_pri); + Orch(swss::DBConnector *db, const std::vector &tableNames); + Orch(swss::DBConnector *db, const std::vector &tableNameWithPri); + Orch(const std::vector& tables); virtual ~Orch(); - vector getSelectables(); + std::vector getSelectables(); // add the existing table data (left by warm reboot) to the consumer todo task list. - size_t addExistingData(Table *table); - size_t addExistingData(const string& tableName); + size_t addExistingData(swss::Table *table); + size_t addExistingData(const std::string& tableName); // Prepare for warm start if Redis contains valid input data // otherwise fallback to cold start @@ -191,28 +188,28 @@ class Orch /* Run doTask against a specific executor */ virtual void doTask(Consumer &consumer) = 0; - virtual void doTask(NotificationConsumer &consumer) { } - virtual void doTask(SelectableTimer &timer) { } + virtual void doTask(swss::NotificationConsumer &consumer) { } + virtual void doTask(swss::SelectableTimer &timer) { } /* TODO: refactor recording */ - static void recordTuple(Consumer &consumer, KeyOpFieldsValuesTuple &tuple); + static void recordTuple(Consumer &consumer, swss::KeyOpFieldsValuesTuple &tuple); - void dumpPendingTasks(vector &ts); + void dumpPendingTasks(std::vector &ts); protected: ConsumerMap m_consumerMap; static void logfileReopen(); - string dumpTuple(Consumer &consumer, KeyOpFieldsValuesTuple &tuple); - ref_resolve_status resolveFieldRefValue(type_map&, const string&, KeyOpFieldsValuesTuple&, sai_object_id_t&); - bool parseIndexRange(const string &input, sai_uint32_t &range_low, sai_uint32_t &range_high); - bool parseReference(type_map &type_maps, string &ref, string &table_name, string &object_name); - ref_resolve_status resolveFieldRefArray(type_map&, const string&, KeyOpFieldsValuesTuple&, vector&); + std::string dumpTuple(Consumer &consumer, swss::KeyOpFieldsValuesTuple &tuple); + ref_resolve_status resolveFieldRefValue(type_map&, const std::string&, swss::KeyOpFieldsValuesTuple&, sai_object_id_t&); + bool parseIndexRange(const std::string &input, sai_uint32_t &range_low, sai_uint32_t &range_high); + bool parseReference(type_map &type_maps, std::string &ref, std::string &table_name, std::string &object_name); + ref_resolve_status resolveFieldRefArray(type_map&, const std::string&, swss::KeyOpFieldsValuesTuple&, std::vector&); /* Note: consumer will be owned by this class */ void addExecutor(Executor* executor); - Executor *getExecutor(string executorName); + Executor *getExecutor(std::string executorName); private: - void addConsumer(DBConnector *db, string tableName, int pri = default_orch_pri); + void addConsumer(swss::DBConnector *db, std::string tableName, int pri = default_orch_pri); }; #include "request_parser.h" @@ -220,12 +217,12 @@ class Orch class Orch2 : public Orch { public: - Orch2(DBConnector *db, const std::string& tableName, Request& request, int pri=default_orch_pri) + Orch2(swss::DBConnector *db, const std::string& tableName, Request& request, int pri=default_orch_pri) : Orch(db, tableName, pri), request_(request) { } - Orch2(DBConnector *db, const vector &tableNames, Request& request) + Orch2(swss::DBConnector *db, const std::vector &tableNames, Request& request) : Orch(db, tableNames), request_(request) { } diff --git a/orchagent/request_parser.cpp b/orchagent/request_parser.cpp index 610b191454..cdd74c3d40 100644 --- a/orchagent/request_parser.cpp +++ b/orchagent/request_parser.cpp @@ -12,6 +12,9 @@ #include "orch.h" #include "request_parser.h" +using namespace std; +using namespace swss; + void Request::parse(const KeyOpFieldsValuesTuple& request) { diff --git a/orchagent/request_parser.h b/orchagent/request_parser.h index 442e1a8f12..8c06e37eb0 100644 --- a/orchagent/request_parser.h +++ b/orchagent/request_parser.h @@ -30,7 +30,7 @@ typedef struct _request_description class Request { public: - void parse(const KeyOpFieldsValuesTuple& request); + void parse(const swss::KeyOpFieldsValuesTuple& request); void clear(); const std::string& getOperation() const @@ -51,19 +51,19 @@ class Request return key_item_strings_.at(position); } - const MacAddress& getKeyMacAddress(int position) const + const swss::MacAddress& getKeyMacAddress(int position) const { assert(is_parsed_); return key_item_mac_addresses_.at(position); } - const IpAddress& getKeyIpAddress(int position) const + const swss::IpAddress& getKeyIpAddress(int position) const { assert(is_parsed_); return key_item_ip_addresses_.at(position); } - const IpPrefix& getKeyIpPrefix(int position) const + const swss::IpPrefix& getKeyIpPrefix(int position) const { assert(is_parsed_); return key_item_ip_prefix_.at(position); @@ -93,7 +93,7 @@ class Request return attr_item_bools_.at(attr_name); } - const MacAddress& getAttrMacAddress(const std::string& attr_name) const + const swss::MacAddress& getAttrMacAddress(const std::string& attr_name) const { assert(is_parsed_); return attr_item_mac_addresses_.at(attr_name); @@ -111,7 +111,7 @@ class Request return attr_item_vlan_.at(attr_name); } - IpAddress getAttrIP(const std::string& attr_name) const + swss::IpAddress getAttrIP(const std::string& attr_name) const { assert(is_parsed_); return attr_item_ip_.at(attr_name); @@ -123,7 +123,7 @@ class Request return attr_item_uint_.at(attr_name); } - const set& getAttrSet(const std::string& attr_name) const + const std::set& getAttrSet(const std::string& attr_name) const { assert(is_parsed_); return attr_item_set_.at(attr_name); @@ -151,16 +151,16 @@ class Request private: - void parseOperation(const KeyOpFieldsValuesTuple& request); - void parseKey(const KeyOpFieldsValuesTuple& request); - void parseAttrs(const KeyOpFieldsValuesTuple& request); + void parseOperation(const swss::KeyOpFieldsValuesTuple& request); + void parseKey(const swss::KeyOpFieldsValuesTuple& request); + void parseAttrs(const swss::KeyOpFieldsValuesTuple& request); bool parseBool(const std::string& str); - MacAddress parseMacAddress(const std::string& str); - IpAddress parseIpAddress(const std::string& str); - IpPrefix parseIpPrefix(const std::string& str); + swss::MacAddress parseMacAddress(const std::string& str); + swss::IpAddress parseIpAddress(const std::string& str); + swss::IpPrefix parseIpPrefix(const std::string& str); uint64_t parseUint(const std::string& str); uint16_t parseVlan(const std::string& str); - set parseSet(const std::string& str); + std::set parseSet(const std::string& str); sai_packet_action_t parsePacketAction(const std::string& str); @@ -173,20 +173,20 @@ class Request std::string operation_; std::string full_key_; std::unordered_map key_item_strings_; - std::unordered_map key_item_mac_addresses_; - std::unordered_map key_item_ip_addresses_; - std::unordered_map key_item_ip_prefix_; + std::unordered_map key_item_mac_addresses_; + std::unordered_map key_item_ip_addresses_; + std::unordered_map key_item_ip_prefix_; std::unordered_map key_item_uint_; std::unordered_set attr_names_; // FIXME: Make one union with all the values, except string std::unordered_map attr_item_strings_; std::unordered_map attr_item_bools_; - std::unordered_map attr_item_mac_addresses_; + std::unordered_map attr_item_mac_addresses_; std::unordered_map attr_item_packet_actions_; std::unordered_map attr_item_vlan_; - std::unordered_map attr_item_ip_; + std::unordered_map attr_item_ip_; std::unordered_map attr_item_uint_; - std::unordered_map> attr_item_set_; + std::unordered_map> attr_item_set_; }; #endif // __REQUEST_PARSER_H diff --git a/orchagent/routeorch.cpp b/orchagent/routeorch.cpp index bff955b60d..1b611ca890 100644 --- a/orchagent/routeorch.cpp +++ b/orchagent/routeorch.cpp @@ -82,7 +82,7 @@ RouteOrch::RouteOrch(DBConnector *db, string tableName, NeighOrch *neighOrch) : gCrmOrch->incCrmResUsedCounter(CrmResourceType::CRM_IPV4_ROUTE); /* Add default IPv4 route into the m_syncdRoutes */ - m_syncdRoutes[default_ip_prefix] = IpAddresses(); + m_syncdRoutes[default_ip_prefix] = NextHopGroupKey(); SWSS_LOG_NOTICE("Create IPv4 default route with packet action drop"); @@ -101,7 +101,7 @@ RouteOrch::RouteOrch(DBConnector *db, string tableName, NeighOrch *neighOrch) : gCrmOrch->incCrmResUsedCounter(CrmResourceType::CRM_IPV6_ROUTE); /* Add default IPv6 route into the m_syncdRoutes */ - m_syncdRoutes[v6_default_ip_prefix] = IpAddresses(); + m_syncdRoutes[v6_default_ip_prefix] = NextHopGroupKey(); SWSS_LOG_NOTICE("Create IPv6 default route with packet action drop"); @@ -191,15 +191,15 @@ void RouteOrch::addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu", linklocal_prefix.to_string().c_str()); } -bool RouteOrch::hasNextHopGroup(const IpAddresses& ipAddresses) const +bool RouteOrch::hasNextHopGroup(const NextHopGroupKey& nexthops) const { - return m_syncdNextHopGroups.find(ipAddresses) != m_syncdNextHopGroups.end(); + return m_syncdNextHopGroups.find(nexthops) != m_syncdNextHopGroups.end(); } -sai_object_id_t RouteOrch::getNextHopGroupId(const IpAddresses& ipAddresses) +sai_object_id_t RouteOrch::getNextHopGroupId(const NextHopGroupKey& nexthops) { - assert(hasNextHopGroup(ipAddresses)); - return m_syncdNextHopGroups[ipAddresses].next_hop_group_id; + assert(hasNextHopGroup(nexthops)); + return m_syncdNextHopGroups[nexthops].next_hop_group_id; } void RouteOrch::attach(Observer *observer, const IpAddress& dstAddr) @@ -234,7 +234,7 @@ void RouteOrch::attach(Observer *observer, const IpAddress& dstAddr) if (prefix.isAddressInSubnet(dstAddr)) { observerEntry->second.routeTable.emplace( - prefix, IpAddresses()); + prefix, NextHopGroupKey()); } } } @@ -290,7 +290,7 @@ void RouteOrch::detach(Observer *observer, const IpAddress& dstAddr) } } -bool RouteOrch::validnexthopinNextHopGroup(const IpAddress &ipaddr) +bool RouteOrch::validnexthopinNextHopGroup(const NextHopKey &nexthop) { SWSS_LOG_ENTER(); @@ -301,7 +301,7 @@ bool RouteOrch::validnexthopinNextHopGroup(const IpAddress &ipaddr) nhopgroup != m_syncdNextHopGroups.end(); ++nhopgroup) { - if (!(nhopgroup->first.contains(ipaddr))) + if (!(nhopgroup->first.contains(nexthop))) { continue; } @@ -314,7 +314,7 @@ bool RouteOrch::validnexthopinNextHopGroup(const IpAddress &ipaddr) nhgm_attrs.push_back(nhgm_attr); nhgm_attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID; - nhgm_attr.value.oid = m_neighOrch->getNextHopId(ipaddr); + nhgm_attr.value.oid = m_neighOrch->getNextHopId(nexthop); nhgm_attrs.push_back(nhgm_attr); status = sai_next_hop_group_api->create_next_hop_group_member(&nexthop_id, gSwitchId, @@ -329,13 +329,13 @@ bool RouteOrch::validnexthopinNextHopGroup(const IpAddress &ipaddr) } gCrmOrch->incCrmResUsedCounter(CrmResourceType::CRM_NEXTHOP_GROUP_MEMBER); - nhopgroup->second.nhopgroup_members[ipaddr] = nexthop_id; + nhopgroup->second.nhopgroup_members[nexthop] = nexthop_id; } return true; } -bool RouteOrch::invalidnexthopinNextHopGroup(const IpAddress &ipaddr) +bool RouteOrch::invalidnexthopinNextHopGroup(const NextHopKey &nexthop) { SWSS_LOG_ENTER(); @@ -346,12 +346,12 @@ bool RouteOrch::invalidnexthopinNextHopGroup(const IpAddress &ipaddr) nhopgroup != m_syncdNextHopGroups.end(); ++nhopgroup) { - if (!(nhopgroup->first.contains(ipaddr))) + if (!(nhopgroup->first.contains(nexthop))) { continue; } - nexthop_id = nhopgroup->second.nhopgroup_members[ipaddr]; + nexthop_id = nhopgroup->second.nhopgroup_members[nexthop]; status = sai_next_hop_group_api->remove_next_hop_group_member(nexthop_id); if (status != SAI_STATUS_SUCCESS) @@ -426,28 +426,32 @@ void RouteOrch::doTask(Consumer& consumer) if (op == SET_COMMAND) { - IpAddresses ip_addresses; - string alias; + string ips; + string aliases; + bool excp_intfs_flag = false; for (auto i : kfvFieldsValues(t)) { if (fvField(i) == "nexthop") - ip_addresses = IpAddresses(fvValue(i)); + ips = fvValue(i); if (fvField(i) == "ifname") - alias = fvValue(i); + aliases = fvValue(i); } + vector ipv = tokenize(ips, ','); + vector alsv = tokenize(aliases, ','); - // TODO: set to blackhold if nexthop is empty? - if (ip_addresses.getSize() == 0) + for (auto alias : alsv) { - it = consumer.m_toSync.erase(it); - continue; + if (alias == "eth0" || alias == "lo" || alias == "docker0") + { + excp_intfs_flag = true; + break; + } } // 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") + if (excp_intfs_flag) { /* If any existing routes are updated to point to the * above interfaces, remove them from the ASIC. */ @@ -463,9 +467,23 @@ void RouteOrch::doTask(Consumer& consumer) continue; } - if (m_syncdRoutes.find(ip_prefix) == m_syncdRoutes.end() || m_syncdRoutes[ip_prefix] != ip_addresses) + string nhg_str = ipv[0] + NH_DELIMITER + alsv[0]; + for (uint32_t i = 1; i < ipv.size(); i++) + { + nhg_str += NHG_DELIMITER + ipv[i] + NH_DELIMITER + alsv[i]; + } + + NextHopGroupKey nhg(nhg_str); + + if (ipv.size() == 1 && IpAddress(ipv[0]).isZero()) { - if (addRoute(ip_prefix, ip_addresses)) + it = consumer.m_toSync.erase(it); + continue; + } + + if (m_syncdRoutes.find(ip_prefix) == m_syncdRoutes.end() || m_syncdRoutes[ip_prefix] != nhg) + { + if (addRoute(ip_prefix, nhg)) it = consumer.m_toSync.erase(it); else it++; @@ -495,7 +513,7 @@ void RouteOrch::doTask(Consumer& consumer) } } -void RouteOrch::notifyNextHopChangeObservers(IpPrefix prefix, IpAddresses nexthops, bool add) +void RouteOrch::notifyNextHopChangeObservers(const IpPrefix &prefix, const NextHopGroupKey &nexthops, bool add) { SWSS_LOG_ENTER(); @@ -576,57 +594,56 @@ void RouteOrch::notifyNextHopChangeObservers(IpPrefix prefix, IpAddresses nextho } } -void RouteOrch::increaseNextHopRefCount(IpAddresses ipAddresses) +void RouteOrch::increaseNextHopRefCount(const NextHopGroupKey &nexthops) { /* Return when there is no next hop (dropped) */ - if (ipAddresses.getSize() == 0) + if (nexthops.getSize() == 0) { return; } - else if (ipAddresses.getSize() == 1) + else if (nexthops.getSize() == 1) { - IpAddress ip_address(ipAddresses.to_string()); - m_neighOrch->increaseNextHopRefCount(ip_address); + NextHopKey nexthop(nexthops.to_string()); + m_neighOrch->increaseNextHopRefCount(nexthop); } else { - m_syncdNextHopGroups[ipAddresses].ref_count ++; + m_syncdNextHopGroups[nexthops].ref_count ++; } } -void RouteOrch::decreaseNextHopRefCount(IpAddresses ipAddresses) +void RouteOrch::decreaseNextHopRefCount(const NextHopGroupKey &nexthops) { /* Return when there is no next hop (dropped) */ - if (ipAddresses.getSize() == 0) + if (nexthops.getSize() == 0) { return; } - else if (ipAddresses.getSize() == 1) + else if (nexthops.getSize() == 1) { - IpAddress ip_address(ipAddresses.to_string()); - - m_neighOrch->decreaseNextHopRefCount(ip_address); + NextHopKey nexthop(nexthops.to_string()); + m_neighOrch->decreaseNextHopRefCount(nexthop); } else { - m_syncdNextHopGroups[ipAddresses].ref_count --; + m_syncdNextHopGroups[nexthops].ref_count --; } } -bool RouteOrch::isRefCounterZero(const IpAddresses& ipAddresses) const +bool RouteOrch::isRefCounterZero(const NextHopGroupKey &nexthops) const { - if (!hasNextHopGroup(ipAddresses)) + if (!hasNextHopGroup(nexthops)) { return true; } - return m_syncdNextHopGroups.at(ipAddresses).ref_count == 0; + return m_syncdNextHopGroups.at(nexthops).ref_count == 0; } -bool RouteOrch::addNextHopGroup(IpAddresses ipAddresses) +bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops) { SWSS_LOG_ENTER(); - assert(!hasNextHopGroup(ipAddresses)); + assert(!hasNextHopGroup(nexthops)); if (m_nextHopGroupCount >= m_maxNextHopGroupCount) { @@ -636,8 +653,8 @@ bool RouteOrch::addNextHopGroup(IpAddresses ipAddresses) } vector next_hop_ids; - set next_hop_set = ipAddresses.getIpAddresses(); - std::map nhopgroup_members_set; + set next_hop_set = nexthops.getNextHops(); + std::map nhopgroup_members_set; /* Assert each IP address exists in m_syncdNextHops table, * and add the corresponding next_hop_id to next_hop_ids. */ @@ -646,7 +663,7 @@ bool RouteOrch::addNextHopGroup(IpAddresses ipAddresses) if (!m_neighOrch->hasNextHop(it)) { SWSS_LOG_INFO("Failed to get next hop %s in %s", - it.to_string().c_str(), ipAddresses.to_string().c_str()); + it.to_string().c_str(), nexthops.to_string().c_str()); return false; } @@ -671,12 +688,12 @@ bool RouteOrch::addNextHopGroup(IpAddresses ipAddresses) if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("Failed to create next hop group %s, rv:%d", - ipAddresses.to_string().c_str(), status); + nexthops.to_string().c_str(), status); return false; } m_nextHopGroupCount ++; - SWSS_LOG_NOTICE("Create next hop group %s", ipAddresses.to_string().c_str()); + SWSS_LOG_NOTICE("Create next hop group %s", nexthops.to_string().c_str()); gCrmOrch->incCrmResUsedCounter(CrmResourceType::CRM_NEXTHOP_GROUP); @@ -732,18 +749,18 @@ bool RouteOrch::addNextHopGroup(IpAddresses ipAddresses) * count will increase once the route is successfully syncd. */ next_hop_group_entry.ref_count = 0; - m_syncdNextHopGroups[ipAddresses] = next_hop_group_entry; + m_syncdNextHopGroups[nexthops] = next_hop_group_entry; return true; } -bool RouteOrch::removeNextHopGroup(IpAddresses ipAddresses) +bool RouteOrch::removeNextHopGroup(const NextHopGroupKey &nexthops) { SWSS_LOG_ENTER(); sai_object_id_t next_hop_group_id; - auto next_hop_group_entry = m_syncdNextHopGroups.find(ipAddresses); + auto next_hop_group_entry = m_syncdNextHopGroups.find(nexthops); sai_status_t status; assert(next_hop_group_entry != m_syncdNextHopGroups.end()); @@ -754,7 +771,7 @@ bool RouteOrch::removeNextHopGroup(IpAddresses ipAddresses) } next_hop_group_id = next_hop_group_entry->second.next_hop_group_id; - SWSS_LOG_NOTICE("Delete next hop group %s", ipAddresses.to_string().c_str()); + SWSS_LOG_NOTICE("Delete next hop group %s", nexthops.to_string().c_str()); for (auto nhop = next_hop_group_entry->second.nhopgroup_members.begin(); nhop != next_hop_group_entry->second.nhopgroup_members.end();) @@ -789,21 +806,21 @@ bool RouteOrch::removeNextHopGroup(IpAddresses ipAddresses) m_nextHopGroupCount --; gCrmOrch->decCrmResUsedCounter(CrmResourceType::CRM_NEXTHOP_GROUP); - set ip_address_set = ipAddresses.getIpAddresses(); - for (auto it : ip_address_set) + set next_hop_set = nexthops.getNextHops(); + for (auto it : next_hop_set) { m_neighOrch->decreaseNextHopRefCount(it); } - m_syncdNextHopGroups.erase(ipAddresses); + m_syncdNextHopGroups.erase(nexthops); return true; } -void RouteOrch::addTempRoute(IpPrefix ipPrefix, IpAddresses nextHops) +void RouteOrch::addTempRoute(const IpPrefix &ipPrefix, const NextHopGroupKey &nextHops) { SWSS_LOG_ENTER(); - auto next_hop_set = nextHops.getIpAddresses(); + auto next_hop_set = nextHops.getNextHops(); /* Remove next hops that are not in m_syncdNextHops */ for (auto it = next_hop_set.begin(); it != next_hop_set.end();) @@ -827,11 +844,11 @@ void RouteOrch::addTempRoute(IpPrefix ipPrefix, IpAddresses nextHops) advance(it, rand() % next_hop_set.size()); /* Set the route's temporary next hop to be the randomly picked one */ - IpAddresses tmp_next_hop((*it).to_string()); + NextHopGroupKey tmp_next_hop((*it).to_string()); addRoute(ipPrefix, tmp_next_hop); } -bool RouteOrch::addRoute(IpPrefix ipPrefix, IpAddresses nextHops) +bool RouteOrch::addRoute(const IpPrefix &ipPrefix, const NextHopGroupKey &nextHops) { SWSS_LOG_ENTER(); @@ -842,10 +859,10 @@ bool RouteOrch::addRoute(IpPrefix ipPrefix, IpAddresses nextHops) /* The route is pointing to a next hop */ if (nextHops.getSize() == 1) { - IpAddress ip_address(nextHops.to_string()); - if (m_neighOrch->hasNextHop(ip_address)) + NextHopKey nexthop(nextHops.to_string()); + if (m_neighOrch->hasNextHop(nexthop)) { - next_hop_id = m_neighOrch->getNextHopId(ip_address); + next_hop_id = m_neighOrch->getNextHopId(nexthop); } else { @@ -869,8 +886,8 @@ bool RouteOrch::addRoute(IpPrefix ipPrefix, IpAddresses nextHops) * then return false and no need to add another temporary route. */ if (it_route != m_syncdRoutes.end() && it_route->second.getSize() == 1) { - IpAddress ip_address(it_route->second.to_string()); - if (nextHops.contains(ip_address)) + NextHopKey nexthop(it_route->second.to_string()); + if (nextHops.contains(nexthop)) { return false; } @@ -985,7 +1002,7 @@ bool RouteOrch::addRoute(IpPrefix ipPrefix, IpAddresses nextHops) return true; } -bool RouteOrch::removeRoute(IpPrefix ipPrefix) +bool RouteOrch::removeRoute(const IpPrefix &ipPrefix) { SWSS_LOG_ENTER(); @@ -1065,7 +1082,7 @@ bool RouteOrch::removeRoute(IpPrefix ipPrefix) if (ipPrefix.isDefaultRoute()) { - m_syncdRoutes[ipPrefix] = IpAddresses(); + m_syncdRoutes[ipPrefix] = NextHopGroupKey(); /* Notify about default route next hop change */ notifyNextHopChangeObservers(ipPrefix, m_syncdRoutes[ipPrefix], true); @@ -1075,7 +1092,7 @@ bool RouteOrch::removeRoute(IpPrefix ipPrefix) m_syncdRoutes.erase(ipPrefix); /* Notify about the route next hop removal */ - notifyNextHopChangeObservers(ipPrefix, IpAddresses(), false); + notifyNextHopChangeObservers(ipPrefix, NextHopGroupKey(), false); } return true; diff --git a/orchagent/routeorch.h b/orchagent/routeorch.h index 310e93cd87..e00223245c 100644 --- a/orchagent/routeorch.h +++ b/orchagent/routeorch.h @@ -9,37 +9,37 @@ #include "ipaddress.h" #include "ipaddresses.h" #include "ipprefix.h" +#include "nexthopgroupkey.h" #include /* Maximum next hop group number */ #define NHGRP_MAX_SIZE 128 - /* Length of the Interface Id value in EUI64 format */ #define EUI64_INTF_ID_LEN 8 -typedef std::map NextHopGroupMembers; +typedef std::map NextHopGroupMembers; struct NextHopGroupEntry { sai_object_id_t next_hop_group_id; // next hop group id int ref_count; // reference count - NextHopGroupMembers nhopgroup_members; // ids of members indexed by ip address + NextHopGroupMembers nhopgroup_members; // ids of members indexed by }; struct NextHopUpdate { IpAddress destination; IpPrefix prefix; - IpAddresses nexthopGroup; + NextHopGroupKey nexthopGroup; }; struct NextHopObserverEntry; -/* NextHopGroupTable: next hop group IP addersses, NextHopGroupEntry */ -typedef std::map NextHopGroupTable; -/* RouteTable: destination network, next hop IP address(es) */ -typedef std::map RouteTable; +/* NextHopGroupTable: NextHopGroupKey, NextHopGroupEntry */ +typedef std::map NextHopGroupTable; +/* RouteTable: destination network, NextHopGroupKey */ +typedef std::map RouteTable; /* NextHopObserverTable: Destination IP address, next hop observer entry */ typedef std::map NextHopObserverTable; @@ -54,23 +54,23 @@ class RouteOrch : public Orch, public Subject public: RouteOrch(DBConnector *db, string tableName, NeighOrch *neighOrch); - bool hasNextHopGroup(const IpAddresses&) const; - sai_object_id_t getNextHopGroupId(const IpAddresses&); + bool hasNextHopGroup(const NextHopGroupKey&) const; + sai_object_id_t getNextHopGroupId(const NextHopGroupKey&); void attach(Observer *, const IpAddress&); void detach(Observer *, const IpAddress&); - void increaseNextHopRefCount(IpAddresses); - void decreaseNextHopRefCount(IpAddresses); - bool isRefCounterZero(const IpAddresses&) const; + void increaseNextHopRefCount(const NextHopGroupKey&); + void decreaseNextHopRefCount(const NextHopGroupKey&); + bool isRefCounterZero(const NextHopGroupKey&) const; - bool addNextHopGroup(IpAddresses); - bool removeNextHopGroup(IpAddresses); + bool addNextHopGroup(const NextHopGroupKey&); + bool removeNextHopGroup(const NextHopGroupKey&); - bool validnexthopinNextHopGroup(const IpAddress &); - bool invalidnexthopinNextHopGroup(const IpAddress &); + bool validnexthopinNextHopGroup(const NextHopKey&); + bool invalidnexthopinNextHopGroup(const NextHopKey&); - void notifyNextHopChangeObservers(IpPrefix, IpAddresses, bool); + void notifyNextHopChangeObservers(const IpPrefix&, const NextHopGroupKey&, bool); private: NeighOrch *m_neighOrch; @@ -83,9 +83,9 @@ class RouteOrch : public Orch, public Subject NextHopObserverTable m_nextHopObservers; - void addTempRoute(IpPrefix, IpAddresses); - bool addRoute(IpPrefix, IpAddresses); - bool removeRoute(IpPrefix); + void addTempRoute(const IpPrefix&, const NextHopGroupKey&); + bool addRoute(const IpPrefix&, const NextHopGroupKey&); + bool removeRoute(const IpPrefix&); std::string getLinkLocalEui64Addr(void); void addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix); diff --git a/orchagent/switchorch.h b/orchagent/switchorch.h index e30def4826..594226dc3d 100644 --- a/orchagent/switchorch.h +++ b/orchagent/switchorch.h @@ -12,20 +12,20 @@ struct WarmRestartCheck class SwitchOrch : public Orch { public: - SwitchOrch(DBConnector *db, string tableName); + SwitchOrch(swss::DBConnector *db, std::string tableName); bool checkRestartReady() { return m_warmRestartCheck.checkRestartReadyState; } bool checkRestartNoFreeze() { return m_warmRestartCheck.noFreeze; } bool skipPendingTaskCheck() { return m_warmRestartCheck.skipPendingTaskCheck; } void checkRestartReadyDone() { m_warmRestartCheck.checkRestartReadyState = false; } - void restartCheckReply(const string &op, const string &data, std::vector &values); + void restartCheckReply(const std::string &op, const std::string &data, std::vector &values); bool setAgingFDB(uint32_t sec); private: void doTask(Consumer &consumer); - NotificationConsumer* m_restartCheckNotificationConsumer; - void doTask(NotificationConsumer& consumer); - DBConnector *m_db; + swss::NotificationConsumer* m_restartCheckNotificationConsumer; + void doTask(swss::NotificationConsumer& consumer); + swss::DBConnector *m_db; // Information contained in the request from // external program for orchagent pre-shutdown state check diff --git a/orchagent/timer.h b/orchagent/timer.h index 732f8f4ebf..275d3f60e3 100644 --- a/orchagent/timer.h +++ b/orchagent/timer.h @@ -8,14 +8,14 @@ namespace swss { class ExecutableTimer : public Executor { public: - ExecutableTimer(SelectableTimer *timer, Orch *orch, const string &name) + ExecutableTimer(swss::SelectableTimer *timer, Orch *orch, const std::string &name) : Executor(timer, orch, name) { } - SelectableTimer *getSelectableTimer() + swss::SelectableTimer *getSelectableTimer() { - return static_cast(getSelectable()); + return static_cast(getSelectable()); } void execute() diff --git a/orchagent/tunneldecaporch.h b/orchagent/tunneldecaporch.h index dbd3126df9..31ca853e3d 100644 --- a/orchagent/tunneldecaporch.h +++ b/orchagent/tunneldecaporch.h @@ -11,40 +11,40 @@ struct TunnelTermEntry { - sai_object_id_t tunnel_term_id; - string ip_address; + sai_object_id_t tunnel_term_id; + std::string ip_address; }; struct TunnelEntry { - sai_object_id_t tunnel_id; // tunnel id - sai_object_id_t overlay_intf_id; // overlay interface id - vector tunnel_term_info; // tunnel_entry ids related to the tunnel abd ips related to the tunnel (all ips for tunnel entries that refer to this tunnel) + sai_object_id_t tunnel_id; // tunnel id + sai_object_id_t overlay_intf_id; // overlay interface id + std::vector tunnel_term_info; // tunnel_entry ids related to the tunnel abd ips related to the tunnel (all ips for tunnel entries that refer to this tunnel) }; /* TunnelTable: key string, tunnel object id */ -typedef map TunnelTable; +typedef std::map TunnelTable; /* ExistingIps: ips that currently have term entries */ -typedef unordered_set ExistingIps; +typedef std::unordered_set ExistingIps; class TunnelDecapOrch : public Orch { public: - TunnelDecapOrch(DBConnector *db, string tableName); + TunnelDecapOrch(swss::DBConnector *db, std::string tableName); private: TunnelTable tunnelTable; ExistingIps existingIps; - bool addDecapTunnel(string key, string type, IpAddresses dst_ip, IpAddress* p_src_ip, string dscp, string ecn, string ttl); - bool removeDecapTunnel(string key); + bool addDecapTunnel(std::string key, std::string type, swss::IpAddresses dst_ip, swss::IpAddress* p_src_ip, std::string dscp, std::string ecn, std::string ttl); + bool removeDecapTunnel(std::string key); - bool addDecapTunnelTermEntries(string tunnelKey, IpAddresses dst_ip, sai_object_id_t tunnel_id); - bool removeDecapTunnelTermEntry(sai_object_id_t tunnel_term_id, string ip); + bool addDecapTunnelTermEntries(std::string tunnelKey, swss::IpAddresses dst_ip, sai_object_id_t tunnel_id); + bool removeDecapTunnelTermEntry(sai_object_id_t tunnel_term_id, std::string ip); - bool setTunnelAttribute(string field, string value, sai_object_id_t existing_tunnel_id); - bool setIpAttribute(string key, IpAddresses new_ip_addresses, sai_object_id_t tunnel_id); + bool setTunnelAttribute(std::string field, std::string value, sai_object_id_t existing_tunnel_id); + bool setIpAttribute(std::string key, swss::IpAddresses new_ip_addresses, sai_object_id_t tunnel_id); void doTask(Consumer& consumer); }; diff --git a/orchagent/vnetorch.cpp b/orchagent/vnetorch.cpp index b1122f366e..9346ba1a58 100644 --- a/orchagent/vnetorch.cpp +++ b/orchagent/vnetorch.cpp @@ -1165,7 +1165,7 @@ bool VNetBitmapObject::addRoute(IpPrefix& ipPrefix, nextHop& nh) Port port; RouteInfo routeInfo; - bool is_subnet = (!nh.ips.getSize()) ? true : false; + bool is_subnet = (!nh.ips.getSize() || nh.ips.contains("0.0.0.0")) ? true : false; if (is_subnet && (!gPortsOrch->getPort(nh.ifname, port) || (port.m_rif_id == SAI_NULL_OBJECT_ID))) { @@ -1199,15 +1199,15 @@ bool VNetBitmapObject::addRoute(IpPrefix& ipPrefix, nextHop& nh) } else if (nh.ips.getSize() == 1) { - IpAddress ip_address(nh.ips.to_string()); - if (gNeighOrch->hasNextHop(ip_address)) + NextHopKey nexthop(nh.ips.to_string(), nh.ifname); + if (gNeighOrch->hasNextHop(nexthop)) { - nh_id = gNeighOrch->getNextHopId(ip_address); + nh_id = gNeighOrch->getNextHopId(nexthop); } else { SWSS_LOG_INFO("Failed to get next hop %s for %s", - ip_address.to_string().c_str(), ipPrefix.to_string().c_str()); + nexthop.to_string().c_str(), ipPrefix.to_string().c_str()); return false; } @@ -1721,7 +1721,7 @@ bool VNetRouteOrch::doRouteTask(const string& vnet, IpPrefix& ipP return true; } - bool is_subnet = (!nh.ips.getSize())?true:false; + bool is_subnet = (!nh.ips.getSize() || nh.ips.contains("0.0.0.0")) ? true : false; Port port; if (is_subnet && (!gPortsOrch->getPort(nh.ifname, port) || (port.m_rif_id == SAI_NULL_OBJECT_ID))) @@ -1778,15 +1778,15 @@ bool VNetRouteOrch::doRouteTask(const string& vnet, IpPrefix& ipP } else if (nh.ips.getSize() == 1) { - IpAddress ip_address(nh.ips.to_string()); - if (gNeighOrch->hasNextHop(ip_address)) + NextHopKey nexthop(nh.ips.to_string(), nh.ifname); + if (gNeighOrch->hasNextHop(nexthop)) { - nh_id = gNeighOrch->getNextHopId(ip_address); + nh_id = gNeighOrch->getNextHopId(nexthop); } else { SWSS_LOG_INFO("Failed to get next hop %s for %s", - ip_address.to_string().c_str(), ipPrefix.to_string().c_str()); + nexthop.to_string().c_str(), ipPrefix.to_string().c_str()); return false; } } diff --git a/orchagent/vrforch.cpp b/orchagent/vrforch.cpp index a67e6734bd..8258aacc90 100644 --- a/orchagent/vrforch.cpp +++ b/orchagent/vrforch.cpp @@ -11,6 +11,10 @@ #include "request_parser.h" #include "vrforch.h" +using namespace std; +using namespace swss; + + extern sai_virtual_router_api_t* sai_virtual_router_api; extern sai_object_id_t gSwitchId; diff --git a/orchagent/vrforch.h b/orchagent/vrforch.h index 22f5c64307..7512c51a41 100644 --- a/orchagent/vrforch.h +++ b/orchagent/vrforch.h @@ -30,7 +30,7 @@ class VRFRequest : public Request class VRFOrch : public Orch2 { public: - VRFOrch(DBConnector *db, const std::string& tableName) : Orch2(db, tableName, request_) + VRFOrch(swss::DBConnector *db, const std::string& tableName) : Orch2(db, tableName, request_) { } diff --git a/orchagent/watermarkorch.h b/orchagent/watermarkorch.h index 35279efbab..11a9ae5ab5 100644 --- a/orchagent/watermarkorch.h +++ b/orchagent/watermarkorch.h @@ -12,7 +12,7 @@ const uint8_t queue_wm_status_mask = 1 << 0; const uint8_t pg_wm_status_mask = 1 << 1; -static const map groupToMask = +static const std::map groupToMask = { { "QUEUE_WATERMARK", queue_wm_status_mask }, { "PG_WATERMARK", pg_wm_status_mask } @@ -21,28 +21,28 @@ static const map groupToMask = class WatermarkOrch : public Orch { public: - WatermarkOrch(DBConnector *db, const vector &tables); + WatermarkOrch(swss::DBConnector *db, const std::vector &tables); virtual ~WatermarkOrch(void); void doTask(Consumer &consumer); - void doTask(NotificationConsumer &consumer); - void doTask(SelectableTimer &timer); + void doTask(swss::NotificationConsumer &consumer); + void doTask(swss::SelectableTimer &timer); void init_pg_ids(); void init_queue_ids(); - void handleWmConfigUpdate(const std::string &key, const std::vector &fvt); - void handleFcConfigUpdate(const std::string &key, const std::vector &fvt); + void handleWmConfigUpdate(const std::string &key, const std::vector &fvt); + void handleFcConfigUpdate(const std::string &key, const std::vector &fvt); - void clearSingleWm(Table *table, string wm_name, vector &obj_ids); - void clearSingleWm(Table *table, string wm_name, const object_map &nameOidMap); + void clearSingleWm(swss::Table *table, std::string wm_name, std::vector &obj_ids); + void clearSingleWm(swss::Table *table, std::string wm_name, const object_map &nameOidMap); - shared_ptr
getCountersTable(void) + std::shared_ptr getCountersTable(void) { return m_countersTable; } - shared_ptr getCountersDb(void) + std::shared_ptr getCountersDb(void) { return m_countersDb; } @@ -56,19 +56,19 @@ class WatermarkOrch : public Orch uint8_t m_wmStatus = 0; bool m_timerChanged = false; - shared_ptr m_countersDb = nullptr; - shared_ptr m_appDb = nullptr; - shared_ptr
m_countersTable = nullptr; - shared_ptr
m_periodicWatermarkTable = nullptr; - shared_ptr
m_persistentWatermarkTable = nullptr; - shared_ptr
m_userWatermarkTable = nullptr; + std::shared_ptr m_countersDb = nullptr; + std::shared_ptr m_appDb = nullptr; + std::shared_ptr m_countersTable = nullptr; + std::shared_ptr m_periodicWatermarkTable = nullptr; + std::shared_ptr m_persistentWatermarkTable = nullptr; + std::shared_ptr m_userWatermarkTable = nullptr; - NotificationConsumer* m_clearNotificationConsumer = nullptr; - SelectableTimer* m_telemetryTimer = nullptr; + swss::NotificationConsumer* m_clearNotificationConsumer = nullptr; + swss::SelectableTimer* m_telemetryTimer = nullptr; - vector m_unicast_queue_ids; - vector m_multicast_queue_ids; - vector m_pg_ids; + std::vector m_unicast_queue_ids; + std::vector m_multicast_queue_ids; + std::vector m_pg_ids; }; #endif // WATERMARKORCH_H diff --git a/teamsyncd/teamsync.cpp b/teamsyncd/teamsync.cpp index d6f9555667..a194f5dd9c 100644 --- a/teamsyncd/teamsync.cpp +++ b/teamsyncd/teamsync.cpp @@ -109,8 +109,11 @@ void TeamSync::onMsg(int nlmsg_type, struct nl_object *obj) if (nlmsg_type == RTM_DELLINK) { - /* Remove LAG ports and delete LAG */ - removeLag(lagName); + if (m_teamSelectables.find(lagName) != m_teamSelectables.end()) + { + /* Remove LAG ports and delete LAG */ + removeLag(lagName); + } return; }