Skip to content

Commit de762b8

Browse files
authored
PAC infra sonic interface files (#18638)
1 parent 193dce0 commit de762b8

File tree

5 files changed

+810
-0
lines changed

5 files changed

+810
-0
lines changed
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2024 Broadcom Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <iostream>
18+
#include <cstring>
19+
#include <string>
20+
21+
using namespace std;
22+
23+
extern "C" {
24+
25+
#include "pacinfra_common.h"
26+
#include "fpSonicUtils.h"
27+
28+
}
29+
30+
const string INTFS_PREFIX = "E";
31+
32+
using namespace std;
33+
34+
int fpGetIntIfNumFromHostIfName(const char *ifName, uint32 *outIntfNum)
35+
36+
{
37+
size_t pos;
38+
std::string::size_type sz;
39+
std::string name = (char*)ifName;
40+
41+
if(name.find(INTFS_PREFIX) == string::npos)
42+
{
43+
return -1;
44+
}
45+
46+
if((pos = name.find("/")) == string::npos)
47+
{
48+
pos = name.find("_");
49+
}
50+
51+
if(pos == string::npos)
52+
{
53+
pos = 7; // assume Ethernetx format
54+
*outIntfNum = (std::stoi(name.substr(pos+1), &sz)) + 1;
55+
}
56+
else
57+
{
58+
*outIntfNum = std::stoi(name.substr(pos+1), &sz);
59+
}
60+
61+
return 0;
62+
}
63+
64+
65+
int fpGetHostIntfName(uint32 physPort, uchar8 *ifName)
66+
{
67+
string tmp = "Ethernet" + to_string(physPort-1);
68+
strcpy((char*)ifName, tmp.c_str());
69+
return 0;
70+
}
71+
72+
73+
74+

src/sonic-pac/fpinfra/fpnim.cpp

+282
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
/*
2+
* Copyright 2024 Broadcom Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include <vector>
17+
#include <iostream>
18+
#include <string>
19+
#include <swss/subscriberstatetable.h>
20+
#include "fpnim.h"
21+
#include "netdispatcher.h"
22+
#include "netlink.h"
23+
#include "nimsync.h"
24+
#include "fpinfra.h"
25+
26+
extern "C" {
27+
#include "datatypes.h"
28+
#include "commdefs.h"
29+
#include "pacinfra_common.h"
30+
#include "log.h"
31+
#include "osapi.h"
32+
#include "resources.h"
33+
#include "nim_cnfgr.h"
34+
#include "sysapi.h"
35+
#include "sysapi_hpc.h"
36+
#include "nim_events.h"
37+
#include "nimapi.h"
38+
#include "osapi_priv.h"
39+
#include "nim_startup.h"
40+
}
41+
42+
using namespace swss;
43+
using namespace std;
44+
45+
extern pthread_key_t osapi_task_key;
46+
extern int osapi_task_key_created;
47+
48+
/* Initialize static member*/
49+
FpNim *FpNim::instance = 0;
50+
51+
FpNim::FpNim(DBConnector *applDb, DBConnector *cfgDb) :
52+
m_portTable(applDb, APP_PORT_TABLE_NAME),
53+
m_devMetaTbl(cfgDb, CFG_DEVICE_METADATA_TABLE_NAME){ }
54+
55+
FpNim* FpNim::getInstance() {
56+
return instance;
57+
}
58+
59+
FpNim* FpNim::getInstance(DBConnector *applDb, DBConnector * cfgDb) {
60+
if (!instance) {
61+
instance = new FpNim(applDb, cfgDb);
62+
instance->applDb = applDb;
63+
instance->cfgDb = cfgDb;
64+
}
65+
return instance;
66+
}
67+
68+
void FpNim::init(void) {
69+
if(nimPhaseOneInit() != SUCCESS)
70+
return;
71+
72+
if(nimPhaseTwoInit() != SUCCESS)
73+
return;
74+
75+
if(nimPhaseThreeInit() != SUCCESS)
76+
return;
77+
78+
if(nimPhaseExecInit() != SUCCESS)
79+
return;
80+
}
81+
82+
void FpNim::nimStartupInvoke(void) {
83+
84+
/* Wait till the component registers with NIM */
85+
nimStartUpTreeData_t startupData;
86+
while(nimStartUpFirstGet(&startupData) != SUCCESS)
87+
{
88+
sleep(1);
89+
}
90+
91+
/* Now make startup callback */
92+
nimStartupCallbackInvoke(NIM_INTERFACE_CREATE_STARTUP);
93+
nimStartupCallbackInvoke(NIM_INTERFACE_ACTIVATE_STARTUP);
94+
}
95+
96+
void FpNim::createAllPorts(NimSync & sync) {
97+
int port = 0;
98+
int unit = 1;
99+
int slot = 0;
100+
vector<string> keys;
101+
m_portTable.getKeys(keys);
102+
SWSS_LOG_NOTICE("m_portTable->getKeys %zd", keys.size());
103+
104+
SYSAPI_HPC_PORT_DESCRIPTOR_t portData =
105+
{
106+
IANA_GIGABIT_ETHERNET,
107+
PORTCTRL_PORTSPEED_FULL_10GSX,
108+
PHY_CAP_PORTSPEED_ALL,
109+
/* MTRJ,*/
110+
PORT_FEC_DISABLE,
111+
CAP_FEC_NONE
112+
};
113+
114+
enetMacAddr_t macAddr;
115+
if (getSystemMac(macAddr.addr) != 0)
116+
{
117+
SWSS_LOG_ERROR("Failed to read system Mac");
118+
}
119+
120+
for (const auto& alias: keys)
121+
{
122+
NimPort p(0, 0);
123+
124+
if(alias.find(INTFS_PREFIX) == string::npos)
125+
continue;
126+
127+
SWSS_LOG_NOTICE("Keys %s", alias.c_str());
128+
sync.setPort(alias, p);
129+
130+
try
131+
{
132+
if(alias.length() > 8)
133+
{
134+
port = std::stoi(alias.substr(8)) + 1; //FP ports starts from 1 whereas SONiC has Ethernet0
135+
}
136+
else
137+
{
138+
port = std::stoi(alias.substr(5)); //FP ports starts from 1 whereas SONiC has Eth1/1
139+
}
140+
}
141+
catch (...)
142+
{
143+
SWSS_LOG_NOTICE("Invalid interface %s", alias.c_str());
144+
continue;
145+
}
146+
147+
if(nimCmgrNewIntfChangeCallback(unit, slot, port, 0, CREATE, &portData, &macAddr) != SUCCESS)
148+
{
149+
SWSS_LOG_NOTICE("Failed to add interface %s", alias.c_str());
150+
continue;
151+
}
152+
153+
uint32 intIfNum;
154+
nimUSP_t usp;
155+
usp.unit = unit;
156+
usp.slot = slot;
157+
usp.port = port;
158+
/* Set Alias in native (Ethernet0) format for applications to make use of it */
159+
if(nimGetIntIfNumFromUSP(&usp, &intIfNum) != SUCCESS)
160+
{
161+
SWSS_LOG_NOTICE("Failed to get IntIfNum for interface %s", alias.c_str());
162+
continue;
163+
}
164+
nimSetIntfifAlias(intIfNum, ( uchar8 *) alias.c_str());
165+
166+
NIM_EVENT_NOTIFY_INFO_t eventInfo;
167+
eventInfo.component = CARDMGR_COMPONENT_ID;
168+
eventInfo.pCbFunc = NULL;
169+
NIM_HANDLE_t handle;
170+
171+
/* Generate Attach event*/
172+
eventInfo.event = ATTACH;
173+
eventInfo.intIfNum = intIfNum;
174+
if (nimEventIntfNotify(eventInfo,&handle) != SUCCESS)
175+
{
176+
SWSS_LOG_NOTICE("Failed to generate Attach %s event ", alias.c_str());
177+
}
178+
}
179+
}
180+
181+
/* To check the port init is done or not */
182+
bool FpNim::isPortInitDone() {
183+
bool portInit = 0;
184+
long cnt = 0;
185+
186+
while(!portInit) {
187+
std::vector<FieldValueTuple> tuples;
188+
portInit = m_portTable.get("PortInitDone", tuples);
189+
190+
if(portInit)
191+
break;
192+
sleep(1);
193+
cnt++;
194+
}
195+
SWSS_LOG_NOTICE("PORT_INIT_DONE : %d %ld", portInit, cnt);
196+
return portInit;
197+
}
198+
199+
std::string FpNim::getSystemMac() {
200+
std::string macStr;
201+
m_devMetaTbl.hget("localhost", "mac", macStr);
202+
SWSS_LOG_NOTICE("getSystemMac(): %s", macStr.c_str());
203+
return macStr;
204+
}
205+
206+
int FpNim::getSystemMac(unsigned char *addr) {
207+
return macstr_to_mac(getSystemMac().c_str(), addr);
208+
}
209+
210+
void pacHandleDumpError(void *cbData)
211+
{
212+
NetLink *netlink = (NetLink *)cbData;
213+
SWSS_LOG_NOTICE("Netlink dump failed with NLE_DUMP_INTR, resending dump request");
214+
netlink->dumpRequest(RTM_GETLINK);
215+
}
216+
217+
void* fpinfraTask(void * nimPtr) {
218+
219+
FpNim * nim = (FpNim *) nimPtr;
220+
try {
221+
nim->isPortInitDone();
222+
223+
NimSync sync;
224+
nim->createAllPorts(sync);
225+
nim->nimStartupInvoke();
226+
227+
//register for the table events
228+
NetLink netlink;
229+
netlink.registerGroup(RTNLGRP_LINK);
230+
netlink.dumpRequest(RTM_GETLINK);
231+
cout << "Listen to Netlink messages..." << endl;
232+
NetDispatcher::getInstance().registerMessageHandler(RTM_NEWLINK, (swss::NetMsg*)&sync);
233+
NetDispatcher::getInstance().registerMessageHandler(RTM_DELLINK, (swss::NetMsg*)&sync);
234+
235+
swss::Select s;
236+
s.addSelectable(&netlink);
237+
238+
//wait for the events and process them
239+
while (true)
240+
{
241+
SWSS_LOG_NOTICE("Waiting for Netlink Events");
242+
swss::Selectable *sel = NULL;
243+
s.select(&sel);
244+
}
245+
} catch (const exception &e) {
246+
SWSS_LOG_ERROR("Run-Time error: %s", e.what());
247+
}
248+
}
249+
250+
// Glabal variable used to protect against multiple invocation of fpinfraInit()
251+
int fpinfraInitialized;
252+
253+
int fpinfraInit(void) {
254+
255+
// Only the first call is serviced
256+
if(fpinfraInitialized)
257+
return 0;
258+
259+
fpinfraInitialized = 1;
260+
//swss::Logger::linkToDbNative("fpInfra");
261+
SWSS_LOG_NOTICE("-----Initializing fpInfra -----");
262+
263+
/* Initialize sysapi */
264+
(void)sysapiSystemInit();
265+
266+
// connect to the databases
267+
swss::DBConnector *applDb = new swss::DBConnector("APPL_DB", 0);
268+
swss::DBConnector *cfgDb = new swss::DBConnector("CONFIG_DB", 0);
269+
270+
FpNim * nim = FpNim::getInstance(applDb, cfgDb);
271+
nim->init();
272+
273+
if (osapiTaskCreate("nimDbThread", (void*) fpinfraTask, -1, nim,
274+
DEFAULT_STACK_SIZE,
275+
DEFAULT_TASK_PRIORITY,
276+
DEFAULT_TASK_SLICE ) == NULL)
277+
{
278+
return -1;
279+
}
280+
281+
return 0;
282+
}

0 commit comments

Comments
 (0)