44#include " swssnet.h"
55#include " crmorch.h"
66#include " routeorch.h"
7+ #include " errororch.h"
8+ #include " tokenize.h"
9+ #include " sai_serialize.h"
10+ #include " redisclient.h"
11+
12+ #include " swss/json.hpp"
13+ using json = nlohmann::json;
714
815extern sai_neighbor_api_t * sai_neighbor_api;
916extern sai_next_hop_api_t * sai_next_hop_api;
@@ -12,13 +19,22 @@ extern PortsOrch *gPortsOrch;
1219extern sai_object_id_t gSwitchId ;
1320extern CrmOrch *gCrmOrch ;
1421extern RouteOrch *gRouteOrch ;
22+ extern ErrorOrch *gErrorOrch ;
23+ extern std::shared_ptr<swss::RedisClient> g_redisClientAsicDb;
24+ extern std::shared_ptr<swss::RedisClient> g_redisClientCountersDb;
1525
1626const int neighorch_pri = 30 ;
1727
1828NeighOrch::NeighOrch (DBConnector *db, string tableName, IntfsOrch *intfsOrch) :
1929 Orch(db, tableName, neighorch_pri), m_intfsOrch(intfsOrch)
2030{
2131 SWSS_LOG_ENTER ();
32+
33+ if (gErrorOrch ->mappingHandlerRegister (APP_NEIGH_TABLE_NAME, this ) == false )
34+ {
35+ SWSS_LOG_ERROR (" Failed to register with Error Handling Framework for %s" ,
36+ APP_NEIGH_TABLE_NAME);
37+ }
2238}
2339
2440bool NeighOrch::hasNextHop (const NextHopKey &nexthop)
@@ -581,3 +597,129 @@ bool NeighOrch::removeNeighbor(const NeighborEntry &neighborEntry)
581597
582598 return true ;
583599}
600+
601+ bool NeighOrch::mapToErrorDbFormat (sai_object_type_t & object_type, std::vector<FieldValueTuple> &asicValues,
602+ std::vector<FieldValueTuple> &appValues)
603+ {
604+ SWSS_LOG_ENTER ();
605+
606+ if (object_type != SAI_OBJECT_TYPE_NEIGHBOR_ENTRY)
607+ {
608+ return false ;
609+ }
610+
611+ /*
612+ 127.0.0.1:6379> hgetall "NEIGH_TABLE:Ethernet0:2.2.2.2"
613+ 1) "neigh"
614+ 2) "00:00:3a:3e:9e:a7"
615+ 3) "family"
616+ 4) "IPv4"
617+
618+ 127.0.0.1:6379[1]> hgetall "ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:{\"ip\":\"2.2.2.2\",\"rif\":\"oid:0x60000000006f3\",\"switch_id\":\"oid:0x21000000000000\"}"
619+ 1) "SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS"
620+ 2) "00:00:3A:3E:9E:A7"
621+ 127.0.0.1:6379[1]>
622+
623+ 127.0.0.1:6379[2]> hgetall "COUNTERS_PORT_NAME_MAP"
624+ 25) "Ethernet0"
625+ 26) "oid:0x100000000000e"
626+ */
627+
628+ const auto & values = asicValues;
629+ std::string asicKV, strNbrIP, strRifOid, strMac;
630+ std::string strIntfName, strRtrIntfType;
631+ for (size_t i = 0 ; i < values.size (); i++)
632+ {
633+ if (fvField (values[i]) == " key" )
634+ {
635+ /* Extract Neighbor IP and Router Interface ID from the "key" field */
636+ asicKV = fvValue (values[i]);
637+ auto tokens = tokenize (asicKV, ' :' , 1 );
638+ json j = json::parse (tokens[1 ]);
639+ strNbrIP = j[" ip" ];
640+ strRifOid = j[" rif" ];
641+ SWSS_LOG_DEBUG (" Neighbor IP is %s, router interface ID is %s" ,
642+ strNbrIP.c_str (), strRifOid.c_str ());
643+
644+ /* Extract Port OID from Router Interface OID */
645+ std::string strRtrIfKey = " ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE:" + strRifOid;
646+ std::string strIntfOid;
647+ /* OID in neighbor entry points to ROUTER_INTERFACE
648+ * Port based routing interface
649+ * ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE:oid:0x60000000006d9
650+ * SAI_ROUTER_INTERFACE_ATTR_TYPE = SAI_ROUTER_INTERFACE_TYPE_PORT
651+ * SAI_ROUTER_INTERFACE_ATTR_PORT_ID = oid:0x100000000000e
652+ * Check above oid in COUNTERS_PORT_NAME_MAP in COUNTERS_DB to get the physical interface name
653+ *
654+ * VLAN based routing interface
655+ * ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE:oid:0x60000000006f6
656+ * SAI_ROUTER_INTERFACE_ATTR_TYPE -> SAI_ROUTER_INTERFACE_TYPE_VLAN
657+ * SAI_ROUTER_INTERFACE_ATTR_VLAN_ID -> oid:0x260000000006f3
658+ * Check above oid in "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x260000000006f3"
659+ */
660+
661+ auto hashRif = g_redisClientAsicDb->hgetall (strRtrIfKey);
662+ for (auto &kv: hashRif)
663+ {
664+ const std::string &skey = kv.first ;
665+ const std::string &svalue = kv.second ;
666+
667+ if (skey == " SAI_ROUTER_INTERFACE_ATTR_TYPE" )
668+ {
669+ strRtrIntfType = svalue;
670+ }
671+ if (skey == " SAI_ROUTER_INTERFACE_ATTR_PORT_ID" || skey == " SAI_ROUTER_INTERFACE_ATTR_VLAN_ID" )
672+ {
673+ strIntfOid = svalue;
674+ }
675+ }
676+ SWSS_LOG_DEBUG (" Router interface type is %s, interface ID is %s" ,
677+ strRtrIntfType.c_str (), strIntfOid.c_str ());
678+
679+ /* Extract Port name from the Port OID */
680+ if (strRtrIntfType == " SAI_ROUTER_INTERFACE_TYPE_PORT" )
681+ {
682+ auto hashCntr = g_redisClientCountersDb->hgetall (" COUNTERS_PORT_NAME_MAP" );
683+ for (auto &kv: hashCntr)
684+ {
685+ const std::string &skey = kv.first ;
686+ const std::string &svalue = kv.second ;
687+ if (svalue == strIntfOid)
688+ {
689+ strIntfName = skey;
690+ break ;
691+ }
692+ }
693+ }
694+ else if (strRtrIntfType == " SAI_ROUTER_INTERFACE_TYPE_VLAN" )
695+ {
696+ std::string strVlanKey = " ASIC_STATE:SAI_OBJECT_TYPE_VLAN:" + strIntfOid;
697+ auto hashVlan = g_redisClientAsicDb->hgetall (strVlanKey);
698+ for (auto &kv: hashVlan)
699+ {
700+ const std::string &skey = kv.first ;
701+ const std::string &svalue = kv.second ;
702+ if (skey == " SAI_VLAN_ATTR_VLAN_ID" )
703+ {
704+ strIntfName = " Vlan" + svalue;
705+ break ;
706+ }
707+ }
708+ }
709+ SWSS_LOG_DEBUG (" Interface name is %s" , strIntfName.c_str ());
710+ } /* End of if(fvField(values[i]) == "key") */
711+
712+ /* Extract MAC address */
713+ if (fvField (values[i]) == " SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS" )
714+ {
715+ strMac = fvValue (values[i]);
716+ }
717+ } /* End of for (size_t i = 0; i < values.size(); i++) */
718+
719+ std::string appKey = strIntfName + " :" + strNbrIP;
720+ appValues.emplace_back (" key" , appKey);
721+ appValues.emplace_back (" neigh" , strMac);
722+
723+ return true ;
724+ }
725+
0 commit comments