devlink.c 266 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * net/core/devlink.c - Network physical/parent device Netlink interface
  4. *
  5. * Heavily inspired by net/wireless/
  6. * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
  7. * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/types.h>
  12. #include <linux/slab.h>
  13. #include <linux/gfp.h>
  14. #include <linux/device.h>
  15. #include <linux/list.h>
  16. #include <linux/netdevice.h>
  17. #include <linux/spinlock.h>
  18. #include <linux/refcount.h>
  19. #include <linux/workqueue.h>
  20. #include <linux/u64_stats_sync.h>
  21. #include <linux/timekeeping.h>
  22. #include <rdma/ib_verbs.h>
  23. #include <net/netlink.h>
  24. #include <net/genetlink.h>
  25. #include <net/rtnetlink.h>
  26. #include <net/net_namespace.h>
  27. #include <net/sock.h>
  28. #include <net/devlink.h>
  29. #define CREATE_TRACE_POINTS
  30. #include <trace/events/devlink.h>
  31. static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
  32. {
  33. .name = "destination mac",
  34. .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
  35. .bitwidth = 48,
  36. },
  37. };
  38. struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
  39. .name = "ethernet",
  40. .id = DEVLINK_DPIPE_HEADER_ETHERNET,
  41. .fields = devlink_dpipe_fields_ethernet,
  42. .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
  43. .global = true,
  44. };
  45. EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
  46. static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
  47. {
  48. .name = "destination ip",
  49. .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
  50. .bitwidth = 32,
  51. },
  52. };
  53. struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
  54. .name = "ipv4",
  55. .id = DEVLINK_DPIPE_HEADER_IPV4,
  56. .fields = devlink_dpipe_fields_ipv4,
  57. .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
  58. .global = true,
  59. };
  60. EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
  61. static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
  62. {
  63. .name = "destination ip",
  64. .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
  65. .bitwidth = 128,
  66. },
  67. };
  68. struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
  69. .name = "ipv6",
  70. .id = DEVLINK_DPIPE_HEADER_IPV6,
  71. .fields = devlink_dpipe_fields_ipv6,
  72. .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
  73. .global = true,
  74. };
  75. EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
  76. EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
  77. EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
  78. EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
  79. static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
  80. [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
  81. };
  82. static LIST_HEAD(devlink_list);
  83. /* devlink_mutex
  84. *
  85. * An overall lock guarding every operation coming from userspace.
  86. * It also guards devlink devices list and it is taken when
  87. * driver registers/unregisters it.
  88. */
  89. static DEFINE_MUTEX(devlink_mutex);
  90. struct net *devlink_net(const struct devlink *devlink)
  91. {
  92. return read_pnet(&devlink->_net);
  93. }
  94. EXPORT_SYMBOL_GPL(devlink_net);
  95. static void __devlink_net_set(struct devlink *devlink, struct net *net)
  96. {
  97. write_pnet(&devlink->_net, net);
  98. }
  99. void devlink_net_set(struct devlink *devlink, struct net *net)
  100. {
  101. if (WARN_ON(devlink->registered))
  102. return;
  103. __devlink_net_set(devlink, net);
  104. }
  105. EXPORT_SYMBOL_GPL(devlink_net_set);
  106. static struct devlink *devlink_get_from_attrs(struct net *net,
  107. struct nlattr **attrs)
  108. {
  109. struct devlink *devlink;
  110. char *busname;
  111. char *devname;
  112. if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
  113. return ERR_PTR(-EINVAL);
  114. busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
  115. devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
  116. lockdep_assert_held(&devlink_mutex);
  117. list_for_each_entry(devlink, &devlink_list, list) {
  118. if (strcmp(devlink->dev->bus->name, busname) == 0 &&
  119. strcmp(dev_name(devlink->dev), devname) == 0 &&
  120. net_eq(devlink_net(devlink), net))
  121. return devlink;
  122. }
  123. return ERR_PTR(-ENODEV);
  124. }
  125. static struct devlink *devlink_get_from_info(struct genl_info *info)
  126. {
  127. return devlink_get_from_attrs(genl_info_net(info), info->attrs);
  128. }
  129. static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
  130. unsigned int port_index)
  131. {
  132. struct devlink_port *devlink_port;
  133. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  134. if (devlink_port->index == port_index)
  135. return devlink_port;
  136. }
  137. return NULL;
  138. }
  139. static bool devlink_port_index_exists(struct devlink *devlink,
  140. unsigned int port_index)
  141. {
  142. return devlink_port_get_by_index(devlink, port_index);
  143. }
  144. static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
  145. struct nlattr **attrs)
  146. {
  147. if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
  148. u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
  149. struct devlink_port *devlink_port;
  150. devlink_port = devlink_port_get_by_index(devlink, port_index);
  151. if (!devlink_port)
  152. return ERR_PTR(-ENODEV);
  153. return devlink_port;
  154. }
  155. return ERR_PTR(-EINVAL);
  156. }
  157. static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
  158. struct genl_info *info)
  159. {
  160. return devlink_port_get_from_attrs(devlink, info->attrs);
  161. }
  162. struct devlink_sb {
  163. struct list_head list;
  164. unsigned int index;
  165. u32 size;
  166. u16 ingress_pools_count;
  167. u16 egress_pools_count;
  168. u16 ingress_tc_count;
  169. u16 egress_tc_count;
  170. };
  171. static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
  172. {
  173. return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
  174. }
  175. static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
  176. unsigned int sb_index)
  177. {
  178. struct devlink_sb *devlink_sb;
  179. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  180. if (devlink_sb->index == sb_index)
  181. return devlink_sb;
  182. }
  183. return NULL;
  184. }
  185. static bool devlink_sb_index_exists(struct devlink *devlink,
  186. unsigned int sb_index)
  187. {
  188. return devlink_sb_get_by_index(devlink, sb_index);
  189. }
  190. static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
  191. struct nlattr **attrs)
  192. {
  193. if (attrs[DEVLINK_ATTR_SB_INDEX]) {
  194. u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
  195. struct devlink_sb *devlink_sb;
  196. devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
  197. if (!devlink_sb)
  198. return ERR_PTR(-ENODEV);
  199. return devlink_sb;
  200. }
  201. return ERR_PTR(-EINVAL);
  202. }
  203. static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
  204. struct genl_info *info)
  205. {
  206. return devlink_sb_get_from_attrs(devlink, info->attrs);
  207. }
  208. static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
  209. struct nlattr **attrs,
  210. u16 *p_pool_index)
  211. {
  212. u16 val;
  213. if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
  214. return -EINVAL;
  215. val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
  216. if (val >= devlink_sb_pool_count(devlink_sb))
  217. return -EINVAL;
  218. *p_pool_index = val;
  219. return 0;
  220. }
  221. static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
  222. struct genl_info *info,
  223. u16 *p_pool_index)
  224. {
  225. return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
  226. p_pool_index);
  227. }
  228. static int
  229. devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
  230. enum devlink_sb_pool_type *p_pool_type)
  231. {
  232. u8 val;
  233. if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
  234. return -EINVAL;
  235. val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
  236. if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
  237. val != DEVLINK_SB_POOL_TYPE_EGRESS)
  238. return -EINVAL;
  239. *p_pool_type = val;
  240. return 0;
  241. }
  242. static int
  243. devlink_sb_pool_type_get_from_info(struct genl_info *info,
  244. enum devlink_sb_pool_type *p_pool_type)
  245. {
  246. return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
  247. }
  248. static int
  249. devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
  250. enum devlink_sb_threshold_type *p_th_type)
  251. {
  252. u8 val;
  253. if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
  254. return -EINVAL;
  255. val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
  256. if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
  257. val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
  258. return -EINVAL;
  259. *p_th_type = val;
  260. return 0;
  261. }
  262. static int
  263. devlink_sb_th_type_get_from_info(struct genl_info *info,
  264. enum devlink_sb_threshold_type *p_th_type)
  265. {
  266. return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
  267. }
  268. static int
  269. devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
  270. struct nlattr **attrs,
  271. enum devlink_sb_pool_type pool_type,
  272. u16 *p_tc_index)
  273. {
  274. u16 val;
  275. if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
  276. return -EINVAL;
  277. val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
  278. if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
  279. val >= devlink_sb->ingress_tc_count)
  280. return -EINVAL;
  281. if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
  282. val >= devlink_sb->egress_tc_count)
  283. return -EINVAL;
  284. *p_tc_index = val;
  285. return 0;
  286. }
  287. static int
  288. devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
  289. struct genl_info *info,
  290. enum devlink_sb_pool_type pool_type,
  291. u16 *p_tc_index)
  292. {
  293. return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
  294. pool_type, p_tc_index);
  295. }
  296. struct devlink_region {
  297. struct devlink *devlink;
  298. struct devlink_port *port;
  299. struct list_head list;
  300. union {
  301. const struct devlink_region_ops *ops;
  302. const struct devlink_port_region_ops *port_ops;
  303. };
  304. struct list_head snapshot_list;
  305. u32 max_snapshots;
  306. u32 cur_snapshots;
  307. u64 size;
  308. };
  309. struct devlink_snapshot {
  310. struct list_head list;
  311. struct devlink_region *region;
  312. u8 *data;
  313. u32 id;
  314. };
  315. static struct devlink_region *
  316. devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
  317. {
  318. struct devlink_region *region;
  319. list_for_each_entry(region, &devlink->region_list, list)
  320. if (!strcmp(region->ops->name, region_name))
  321. return region;
  322. return NULL;
  323. }
  324. static struct devlink_region *
  325. devlink_port_region_get_by_name(struct devlink_port *port,
  326. const char *region_name)
  327. {
  328. struct devlink_region *region;
  329. list_for_each_entry(region, &port->region_list, list)
  330. if (!strcmp(region->ops->name, region_name))
  331. return region;
  332. return NULL;
  333. }
  334. static struct devlink_snapshot *
  335. devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
  336. {
  337. struct devlink_snapshot *snapshot;
  338. list_for_each_entry(snapshot, &region->snapshot_list, list)
  339. if (snapshot->id == id)
  340. return snapshot;
  341. return NULL;
  342. }
  343. #define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
  344. #define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1)
  345. /* The per devlink instance lock is taken by default in the pre-doit
  346. * operation, yet several commands do not require this. The global
  347. * devlink lock is taken and protects from disruption by user-calls.
  348. */
  349. #define DEVLINK_NL_FLAG_NO_LOCK BIT(2)
  350. static int devlink_nl_pre_doit(const struct genl_ops *ops,
  351. struct sk_buff *skb, struct genl_info *info)
  352. {
  353. struct devlink_port *devlink_port;
  354. struct devlink *devlink;
  355. int err;
  356. mutex_lock(&devlink_mutex);
  357. devlink = devlink_get_from_info(info);
  358. if (IS_ERR(devlink)) {
  359. mutex_unlock(&devlink_mutex);
  360. return PTR_ERR(devlink);
  361. }
  362. if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
  363. mutex_lock(&devlink->lock);
  364. info->user_ptr[0] = devlink;
  365. if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
  366. devlink_port = devlink_port_get_from_info(devlink, info);
  367. if (IS_ERR(devlink_port)) {
  368. err = PTR_ERR(devlink_port);
  369. goto unlock;
  370. }
  371. info->user_ptr[1] = devlink_port;
  372. } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) {
  373. devlink_port = devlink_port_get_from_info(devlink, info);
  374. if (!IS_ERR(devlink_port))
  375. info->user_ptr[1] = devlink_port;
  376. }
  377. return 0;
  378. unlock:
  379. if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
  380. mutex_unlock(&devlink->lock);
  381. mutex_unlock(&devlink_mutex);
  382. return err;
  383. }
  384. static void devlink_nl_post_doit(const struct genl_ops *ops,
  385. struct sk_buff *skb, struct genl_info *info)
  386. {
  387. struct devlink *devlink;
  388. devlink = info->user_ptr[0];
  389. if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
  390. mutex_unlock(&devlink->lock);
  391. mutex_unlock(&devlink_mutex);
  392. }
  393. static struct genl_family devlink_nl_family;
  394. enum devlink_multicast_groups {
  395. DEVLINK_MCGRP_CONFIG,
  396. };
  397. static const struct genl_multicast_group devlink_nl_mcgrps[] = {
  398. [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
  399. };
  400. static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
  401. {
  402. if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
  403. return -EMSGSIZE;
  404. if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
  405. return -EMSGSIZE;
  406. return 0;
  407. }
  408. struct devlink_reload_combination {
  409. enum devlink_reload_action action;
  410. enum devlink_reload_limit limit;
  411. };
  412. static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
  413. {
  414. /* can't reinitialize driver with no down time */
  415. .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
  416. .limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
  417. },
  418. };
  419. static bool
  420. devlink_reload_combination_is_invalid(enum devlink_reload_action action,
  421. enum devlink_reload_limit limit)
  422. {
  423. int i;
  424. for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
  425. if (devlink_reload_invalid_combinations[i].action == action &&
  426. devlink_reload_invalid_combinations[i].limit == limit)
  427. return true;
  428. return false;
  429. }
  430. static bool
  431. devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
  432. {
  433. return test_bit(action, &devlink->ops->reload_actions);
  434. }
  435. static bool
  436. devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
  437. {
  438. return test_bit(limit, &devlink->ops->reload_limits);
  439. }
  440. static int devlink_reload_stat_put(struct sk_buff *msg,
  441. enum devlink_reload_limit limit, u32 value)
  442. {
  443. struct nlattr *reload_stats_entry;
  444. reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
  445. if (!reload_stats_entry)
  446. return -EMSGSIZE;
  447. if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
  448. nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
  449. goto nla_put_failure;
  450. nla_nest_end(msg, reload_stats_entry);
  451. return 0;
  452. nla_put_failure:
  453. nla_nest_cancel(msg, reload_stats_entry);
  454. return -EMSGSIZE;
  455. }
  456. static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
  457. {
  458. struct nlattr *reload_stats_attr, *act_info, *act_stats;
  459. int i, j, stat_idx;
  460. u32 value;
  461. if (!is_remote)
  462. reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
  463. else
  464. reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
  465. if (!reload_stats_attr)
  466. return -EMSGSIZE;
  467. for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
  468. if ((!is_remote &&
  469. !devlink_reload_action_is_supported(devlink, i)) ||
  470. i == DEVLINK_RELOAD_ACTION_UNSPEC)
  471. continue;
  472. act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
  473. if (!act_info)
  474. goto nla_put_failure;
  475. if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
  476. goto action_info_nest_cancel;
  477. act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
  478. if (!act_stats)
  479. goto action_info_nest_cancel;
  480. for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
  481. /* Remote stats are shown even if not locally supported.
  482. * Stats of actions with unspecified limit are shown
  483. * though drivers don't need to register unspecified
  484. * limit.
  485. */
  486. if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
  487. !devlink_reload_limit_is_supported(devlink, j)) ||
  488. devlink_reload_combination_is_invalid(i, j))
  489. continue;
  490. stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
  491. if (!is_remote)
  492. value = devlink->stats.reload_stats[stat_idx];
  493. else
  494. value = devlink->stats.remote_reload_stats[stat_idx];
  495. if (devlink_reload_stat_put(msg, j, value))
  496. goto action_stats_nest_cancel;
  497. }
  498. nla_nest_end(msg, act_stats);
  499. nla_nest_end(msg, act_info);
  500. }
  501. nla_nest_end(msg, reload_stats_attr);
  502. return 0;
  503. action_stats_nest_cancel:
  504. nla_nest_cancel(msg, act_stats);
  505. action_info_nest_cancel:
  506. nla_nest_cancel(msg, act_info);
  507. nla_put_failure:
  508. nla_nest_cancel(msg, reload_stats_attr);
  509. return -EMSGSIZE;
  510. }
  511. static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
  512. enum devlink_command cmd, u32 portid,
  513. u32 seq, int flags)
  514. {
  515. struct nlattr *dev_stats;
  516. void *hdr;
  517. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  518. if (!hdr)
  519. return -EMSGSIZE;
  520. if (devlink_nl_put_handle(msg, devlink))
  521. goto nla_put_failure;
  522. if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
  523. goto nla_put_failure;
  524. dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
  525. if (!dev_stats)
  526. goto nla_put_failure;
  527. if (devlink_reload_stats_put(msg, devlink, false))
  528. goto dev_stats_nest_cancel;
  529. if (devlink_reload_stats_put(msg, devlink, true))
  530. goto dev_stats_nest_cancel;
  531. nla_nest_end(msg, dev_stats);
  532. genlmsg_end(msg, hdr);
  533. return 0;
  534. dev_stats_nest_cancel:
  535. nla_nest_cancel(msg, dev_stats);
  536. nla_put_failure:
  537. genlmsg_cancel(msg, hdr);
  538. return -EMSGSIZE;
  539. }
  540. static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
  541. {
  542. struct sk_buff *msg;
  543. int err;
  544. WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
  545. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  546. if (!msg)
  547. return;
  548. err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
  549. if (err) {
  550. nlmsg_free(msg);
  551. return;
  552. }
  553. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  554. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  555. }
  556. static int devlink_nl_port_attrs_put(struct sk_buff *msg,
  557. struct devlink_port *devlink_port)
  558. {
  559. struct devlink_port_attrs *attrs = &devlink_port->attrs;
  560. if (!devlink_port->attrs_set)
  561. return 0;
  562. if (attrs->lanes) {
  563. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
  564. return -EMSGSIZE;
  565. }
  566. if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
  567. return -EMSGSIZE;
  568. if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
  569. return -EMSGSIZE;
  570. switch (devlink_port->attrs.flavour) {
  571. case DEVLINK_PORT_FLAVOUR_PCI_PF:
  572. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
  573. attrs->pci_pf.controller) ||
  574. nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
  575. return -EMSGSIZE;
  576. if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
  577. return -EMSGSIZE;
  578. break;
  579. case DEVLINK_PORT_FLAVOUR_PCI_VF:
  580. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
  581. attrs->pci_vf.controller) ||
  582. nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
  583. nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
  584. return -EMSGSIZE;
  585. if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
  586. return -EMSGSIZE;
  587. break;
  588. case DEVLINK_PORT_FLAVOUR_PHYSICAL:
  589. case DEVLINK_PORT_FLAVOUR_CPU:
  590. case DEVLINK_PORT_FLAVOUR_DSA:
  591. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
  592. attrs->phys.port_number))
  593. return -EMSGSIZE;
  594. if (!attrs->split)
  595. return 0;
  596. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
  597. attrs->phys.port_number))
  598. return -EMSGSIZE;
  599. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
  600. attrs->phys.split_subport_number))
  601. return -EMSGSIZE;
  602. break;
  603. default:
  604. break;
  605. }
  606. return 0;
  607. }
  608. static int
  609. devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
  610. struct netlink_ext_ack *extack)
  611. {
  612. struct devlink *devlink = port->devlink;
  613. const struct devlink_ops *ops;
  614. struct nlattr *function_attr;
  615. bool empty_nest = true;
  616. int err = 0;
  617. function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
  618. if (!function_attr)
  619. return -EMSGSIZE;
  620. ops = devlink->ops;
  621. if (ops->port_function_hw_addr_get) {
  622. int hw_addr_len;
  623. u8 hw_addr[MAX_ADDR_LEN];
  624. err = ops->port_function_hw_addr_get(devlink, port, hw_addr, &hw_addr_len, extack);
  625. if (err == -EOPNOTSUPP) {
  626. /* Port function attributes are optional for a port. If port doesn't
  627. * support function attribute, returning -EOPNOTSUPP is not an error.
  628. */
  629. err = 0;
  630. goto out;
  631. } else if (err) {
  632. goto out;
  633. }
  634. err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
  635. if (err)
  636. goto out;
  637. empty_nest = false;
  638. }
  639. out:
  640. if (err || empty_nest)
  641. nla_nest_cancel(msg, function_attr);
  642. else
  643. nla_nest_end(msg, function_attr);
  644. return err;
  645. }
  646. static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
  647. struct devlink_port *devlink_port,
  648. enum devlink_command cmd, u32 portid,
  649. u32 seq, int flags,
  650. struct netlink_ext_ack *extack)
  651. {
  652. void *hdr;
  653. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  654. if (!hdr)
  655. return -EMSGSIZE;
  656. if (devlink_nl_put_handle(msg, devlink))
  657. goto nla_put_failure;
  658. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
  659. goto nla_put_failure;
  660. /* Hold rtnl lock while accessing port's netdev attributes. */
  661. rtnl_lock();
  662. spin_lock_bh(&devlink_port->type_lock);
  663. if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
  664. goto nla_put_failure_type_locked;
  665. if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
  666. nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
  667. devlink_port->desired_type))
  668. goto nla_put_failure_type_locked;
  669. if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
  670. struct net *net = devlink_net(devlink_port->devlink);
  671. struct net_device *netdev = devlink_port->type_dev;
  672. if (netdev && net_eq(net, dev_net(netdev)) &&
  673. (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
  674. netdev->ifindex) ||
  675. nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
  676. netdev->name)))
  677. goto nla_put_failure_type_locked;
  678. }
  679. if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
  680. struct ib_device *ibdev = devlink_port->type_dev;
  681. if (ibdev &&
  682. nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
  683. ibdev->name))
  684. goto nla_put_failure_type_locked;
  685. }
  686. spin_unlock_bh(&devlink_port->type_lock);
  687. rtnl_unlock();
  688. if (devlink_nl_port_attrs_put(msg, devlink_port))
  689. goto nla_put_failure;
  690. if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
  691. goto nla_put_failure;
  692. genlmsg_end(msg, hdr);
  693. return 0;
  694. nla_put_failure_type_locked:
  695. spin_unlock_bh(&devlink_port->type_lock);
  696. rtnl_unlock();
  697. nla_put_failure:
  698. genlmsg_cancel(msg, hdr);
  699. return -EMSGSIZE;
  700. }
  701. static void devlink_port_notify(struct devlink_port *devlink_port,
  702. enum devlink_command cmd)
  703. {
  704. struct devlink *devlink = devlink_port->devlink;
  705. struct sk_buff *msg;
  706. int err;
  707. if (!devlink_port->registered)
  708. return;
  709. WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
  710. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  711. if (!msg)
  712. return;
  713. err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0,
  714. NULL);
  715. if (err) {
  716. nlmsg_free(msg);
  717. return;
  718. }
  719. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  720. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  721. }
  722. static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
  723. {
  724. struct devlink *devlink = info->user_ptr[0];
  725. struct sk_buff *msg;
  726. int err;
  727. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  728. if (!msg)
  729. return -ENOMEM;
  730. err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
  731. info->snd_portid, info->snd_seq, 0);
  732. if (err) {
  733. nlmsg_free(msg);
  734. return err;
  735. }
  736. return genlmsg_reply(msg, info);
  737. }
  738. static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
  739. struct netlink_callback *cb)
  740. {
  741. struct devlink *devlink;
  742. int start = cb->args[0];
  743. int idx = 0;
  744. int err;
  745. mutex_lock(&devlink_mutex);
  746. list_for_each_entry(devlink, &devlink_list, list) {
  747. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  748. continue;
  749. if (idx < start) {
  750. idx++;
  751. continue;
  752. }
  753. err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
  754. NETLINK_CB(cb->skb).portid,
  755. cb->nlh->nlmsg_seq, NLM_F_MULTI);
  756. if (err)
  757. goto out;
  758. idx++;
  759. }
  760. out:
  761. mutex_unlock(&devlink_mutex);
  762. cb->args[0] = idx;
  763. return msg->len;
  764. }
  765. static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
  766. struct genl_info *info)
  767. {
  768. struct devlink_port *devlink_port = info->user_ptr[1];
  769. struct devlink *devlink = devlink_port->devlink;
  770. struct sk_buff *msg;
  771. int err;
  772. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  773. if (!msg)
  774. return -ENOMEM;
  775. err = devlink_nl_port_fill(msg, devlink, devlink_port,
  776. DEVLINK_CMD_PORT_NEW,
  777. info->snd_portid, info->snd_seq, 0,
  778. info->extack);
  779. if (err) {
  780. nlmsg_free(msg);
  781. return err;
  782. }
  783. return genlmsg_reply(msg, info);
  784. }
  785. static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
  786. struct netlink_callback *cb)
  787. {
  788. struct devlink *devlink;
  789. struct devlink_port *devlink_port;
  790. int start = cb->args[0];
  791. int idx = 0;
  792. int err;
  793. mutex_lock(&devlink_mutex);
  794. list_for_each_entry(devlink, &devlink_list, list) {
  795. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  796. continue;
  797. mutex_lock(&devlink->lock);
  798. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  799. if (idx < start) {
  800. idx++;
  801. continue;
  802. }
  803. err = devlink_nl_port_fill(msg, devlink, devlink_port,
  804. DEVLINK_CMD_NEW,
  805. NETLINK_CB(cb->skb).portid,
  806. cb->nlh->nlmsg_seq,
  807. NLM_F_MULTI,
  808. cb->extack);
  809. if (err) {
  810. mutex_unlock(&devlink->lock);
  811. goto out;
  812. }
  813. idx++;
  814. }
  815. mutex_unlock(&devlink->lock);
  816. }
  817. out:
  818. mutex_unlock(&devlink_mutex);
  819. cb->args[0] = idx;
  820. return msg->len;
  821. }
  822. static int devlink_port_type_set(struct devlink *devlink,
  823. struct devlink_port *devlink_port,
  824. enum devlink_port_type port_type)
  825. {
  826. int err;
  827. if (devlink->ops->port_type_set) {
  828. if (port_type == devlink_port->type)
  829. return 0;
  830. err = devlink->ops->port_type_set(devlink_port, port_type);
  831. if (err)
  832. return err;
  833. devlink_port->desired_type = port_type;
  834. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  835. return 0;
  836. }
  837. return -EOPNOTSUPP;
  838. }
  839. static int
  840. devlink_port_function_hw_addr_set(struct devlink *devlink, struct devlink_port *port,
  841. const struct nlattr *attr, struct netlink_ext_ack *extack)
  842. {
  843. const struct devlink_ops *ops;
  844. const u8 *hw_addr;
  845. int hw_addr_len;
  846. int err;
  847. hw_addr = nla_data(attr);
  848. hw_addr_len = nla_len(attr);
  849. if (hw_addr_len > MAX_ADDR_LEN) {
  850. NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
  851. return -EINVAL;
  852. }
  853. if (port->type == DEVLINK_PORT_TYPE_ETH) {
  854. if (hw_addr_len != ETH_ALEN) {
  855. NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
  856. return -EINVAL;
  857. }
  858. if (!is_unicast_ether_addr(hw_addr)) {
  859. NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
  860. return -EINVAL;
  861. }
  862. }
  863. ops = devlink->ops;
  864. if (!ops->port_function_hw_addr_set) {
  865. NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes");
  866. return -EOPNOTSUPP;
  867. }
  868. err = ops->port_function_hw_addr_set(devlink, port, hw_addr, hw_addr_len, extack);
  869. if (err)
  870. return err;
  871. devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
  872. return 0;
  873. }
  874. static int
  875. devlink_port_function_set(struct devlink *devlink, struct devlink_port *port,
  876. const struct nlattr *attr, struct netlink_ext_ack *extack)
  877. {
  878. struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
  879. int err;
  880. err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
  881. devlink_function_nl_policy, extack);
  882. if (err < 0) {
  883. NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
  884. return err;
  885. }
  886. attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
  887. if (attr)
  888. err = devlink_port_function_hw_addr_set(devlink, port, attr, extack);
  889. return err;
  890. }
  891. static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
  892. struct genl_info *info)
  893. {
  894. struct devlink_port *devlink_port = info->user_ptr[1];
  895. struct devlink *devlink = devlink_port->devlink;
  896. int err;
  897. if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
  898. enum devlink_port_type port_type;
  899. port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
  900. err = devlink_port_type_set(devlink, devlink_port, port_type);
  901. if (err)
  902. return err;
  903. }
  904. if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
  905. struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
  906. struct netlink_ext_ack *extack = info->extack;
  907. err = devlink_port_function_set(devlink, devlink_port, attr, extack);
  908. if (err)
  909. return err;
  910. }
  911. return 0;
  912. }
  913. static int devlink_port_split(struct devlink *devlink, u32 port_index,
  914. u32 count, struct netlink_ext_ack *extack)
  915. {
  916. if (devlink->ops->port_split)
  917. return devlink->ops->port_split(devlink, port_index, count,
  918. extack);
  919. return -EOPNOTSUPP;
  920. }
  921. static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
  922. struct genl_info *info)
  923. {
  924. struct devlink *devlink = info->user_ptr[0];
  925. struct devlink_port *devlink_port;
  926. u32 port_index;
  927. u32 count;
  928. if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
  929. !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
  930. return -EINVAL;
  931. devlink_port = devlink_port_get_from_info(devlink, info);
  932. port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  933. count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
  934. if (IS_ERR(devlink_port))
  935. return -EINVAL;
  936. if (!devlink_port->attrs.splittable) {
  937. /* Split ports cannot be split. */
  938. if (devlink_port->attrs.split)
  939. NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further");
  940. else
  941. NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
  942. return -EINVAL;
  943. }
  944. if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
  945. NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count");
  946. return -EINVAL;
  947. }
  948. return devlink_port_split(devlink, port_index, count, info->extack);
  949. }
  950. static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
  951. struct netlink_ext_ack *extack)
  952. {
  953. if (devlink->ops->port_unsplit)
  954. return devlink->ops->port_unsplit(devlink, port_index, extack);
  955. return -EOPNOTSUPP;
  956. }
  957. static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
  958. struct genl_info *info)
  959. {
  960. struct devlink *devlink = info->user_ptr[0];
  961. u32 port_index;
  962. if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
  963. return -EINVAL;
  964. port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  965. return devlink_port_unsplit(devlink, port_index, info->extack);
  966. }
  967. static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
  968. struct devlink_sb *devlink_sb,
  969. enum devlink_command cmd, u32 portid,
  970. u32 seq, int flags)
  971. {
  972. void *hdr;
  973. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  974. if (!hdr)
  975. return -EMSGSIZE;
  976. if (devlink_nl_put_handle(msg, devlink))
  977. goto nla_put_failure;
  978. if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
  979. goto nla_put_failure;
  980. if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
  981. goto nla_put_failure;
  982. if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
  983. devlink_sb->ingress_pools_count))
  984. goto nla_put_failure;
  985. if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
  986. devlink_sb->egress_pools_count))
  987. goto nla_put_failure;
  988. if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
  989. devlink_sb->ingress_tc_count))
  990. goto nla_put_failure;
  991. if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
  992. devlink_sb->egress_tc_count))
  993. goto nla_put_failure;
  994. genlmsg_end(msg, hdr);
  995. return 0;
  996. nla_put_failure:
  997. genlmsg_cancel(msg, hdr);
  998. return -EMSGSIZE;
  999. }
  1000. static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
  1001. struct genl_info *info)
  1002. {
  1003. struct devlink *devlink = info->user_ptr[0];
  1004. struct devlink_sb *devlink_sb;
  1005. struct sk_buff *msg;
  1006. int err;
  1007. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1008. if (IS_ERR(devlink_sb))
  1009. return PTR_ERR(devlink_sb);
  1010. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  1011. if (!msg)
  1012. return -ENOMEM;
  1013. err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
  1014. DEVLINK_CMD_SB_NEW,
  1015. info->snd_portid, info->snd_seq, 0);
  1016. if (err) {
  1017. nlmsg_free(msg);
  1018. return err;
  1019. }
  1020. return genlmsg_reply(msg, info);
  1021. }
  1022. static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
  1023. struct netlink_callback *cb)
  1024. {
  1025. struct devlink *devlink;
  1026. struct devlink_sb *devlink_sb;
  1027. int start = cb->args[0];
  1028. int idx = 0;
  1029. int err;
  1030. mutex_lock(&devlink_mutex);
  1031. list_for_each_entry(devlink, &devlink_list, list) {
  1032. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  1033. continue;
  1034. mutex_lock(&devlink->lock);
  1035. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  1036. if (idx < start) {
  1037. idx++;
  1038. continue;
  1039. }
  1040. err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
  1041. DEVLINK_CMD_SB_NEW,
  1042. NETLINK_CB(cb->skb).portid,
  1043. cb->nlh->nlmsg_seq,
  1044. NLM_F_MULTI);
  1045. if (err) {
  1046. mutex_unlock(&devlink->lock);
  1047. goto out;
  1048. }
  1049. idx++;
  1050. }
  1051. mutex_unlock(&devlink->lock);
  1052. }
  1053. out:
  1054. mutex_unlock(&devlink_mutex);
  1055. cb->args[0] = idx;
  1056. return msg->len;
  1057. }
  1058. static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
  1059. struct devlink_sb *devlink_sb,
  1060. u16 pool_index, enum devlink_command cmd,
  1061. u32 portid, u32 seq, int flags)
  1062. {
  1063. struct devlink_sb_pool_info pool_info;
  1064. void *hdr;
  1065. int err;
  1066. err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
  1067. pool_index, &pool_info);
  1068. if (err)
  1069. return err;
  1070. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  1071. if (!hdr)
  1072. return -EMSGSIZE;
  1073. if (devlink_nl_put_handle(msg, devlink))
  1074. goto nla_put_failure;
  1075. if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
  1076. goto nla_put_failure;
  1077. if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
  1078. goto nla_put_failure;
  1079. if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
  1080. goto nla_put_failure;
  1081. if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
  1082. goto nla_put_failure;
  1083. if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
  1084. pool_info.threshold_type))
  1085. goto nla_put_failure;
  1086. if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
  1087. pool_info.cell_size))
  1088. goto nla_put_failure;
  1089. genlmsg_end(msg, hdr);
  1090. return 0;
  1091. nla_put_failure:
  1092. genlmsg_cancel(msg, hdr);
  1093. return -EMSGSIZE;
  1094. }
  1095. static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
  1096. struct genl_info *info)
  1097. {
  1098. struct devlink *devlink = info->user_ptr[0];
  1099. struct devlink_sb *devlink_sb;
  1100. struct sk_buff *msg;
  1101. u16 pool_index;
  1102. int err;
  1103. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1104. if (IS_ERR(devlink_sb))
  1105. return PTR_ERR(devlink_sb);
  1106. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  1107. &pool_index);
  1108. if (err)
  1109. return err;
  1110. if (!devlink->ops->sb_pool_get)
  1111. return -EOPNOTSUPP;
  1112. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  1113. if (!msg)
  1114. return -ENOMEM;
  1115. err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
  1116. DEVLINK_CMD_SB_POOL_NEW,
  1117. info->snd_portid, info->snd_seq, 0);
  1118. if (err) {
  1119. nlmsg_free(msg);
  1120. return err;
  1121. }
  1122. return genlmsg_reply(msg, info);
  1123. }
  1124. static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
  1125. struct devlink *devlink,
  1126. struct devlink_sb *devlink_sb,
  1127. u32 portid, u32 seq)
  1128. {
  1129. u16 pool_count = devlink_sb_pool_count(devlink_sb);
  1130. u16 pool_index;
  1131. int err;
  1132. for (pool_index = 0; pool_index < pool_count; pool_index++) {
  1133. if (*p_idx < start) {
  1134. (*p_idx)++;
  1135. continue;
  1136. }
  1137. err = devlink_nl_sb_pool_fill(msg, devlink,
  1138. devlink_sb,
  1139. pool_index,
  1140. DEVLINK_CMD_SB_POOL_NEW,
  1141. portid, seq, NLM_F_MULTI);
  1142. if (err)
  1143. return err;
  1144. (*p_idx)++;
  1145. }
  1146. return 0;
  1147. }
  1148. static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
  1149. struct netlink_callback *cb)
  1150. {
  1151. struct devlink *devlink;
  1152. struct devlink_sb *devlink_sb;
  1153. int start = cb->args[0];
  1154. int idx = 0;
  1155. int err = 0;
  1156. mutex_lock(&devlink_mutex);
  1157. list_for_each_entry(devlink, &devlink_list, list) {
  1158. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
  1159. !devlink->ops->sb_pool_get)
  1160. continue;
  1161. mutex_lock(&devlink->lock);
  1162. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  1163. err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
  1164. devlink_sb,
  1165. NETLINK_CB(cb->skb).portid,
  1166. cb->nlh->nlmsg_seq);
  1167. if (err == -EOPNOTSUPP) {
  1168. err = 0;
  1169. } else if (err) {
  1170. mutex_unlock(&devlink->lock);
  1171. goto out;
  1172. }
  1173. }
  1174. mutex_unlock(&devlink->lock);
  1175. }
  1176. out:
  1177. mutex_unlock(&devlink_mutex);
  1178. if (err != -EMSGSIZE)
  1179. return err;
  1180. cb->args[0] = idx;
  1181. return msg->len;
  1182. }
  1183. static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
  1184. u16 pool_index, u32 size,
  1185. enum devlink_sb_threshold_type threshold_type,
  1186. struct netlink_ext_ack *extack)
  1187. {
  1188. const struct devlink_ops *ops = devlink->ops;
  1189. if (ops->sb_pool_set)
  1190. return ops->sb_pool_set(devlink, sb_index, pool_index,
  1191. size, threshold_type, extack);
  1192. return -EOPNOTSUPP;
  1193. }
  1194. static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
  1195. struct genl_info *info)
  1196. {
  1197. struct devlink *devlink = info->user_ptr[0];
  1198. enum devlink_sb_threshold_type threshold_type;
  1199. struct devlink_sb *devlink_sb;
  1200. u16 pool_index;
  1201. u32 size;
  1202. int err;
  1203. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1204. if (IS_ERR(devlink_sb))
  1205. return PTR_ERR(devlink_sb);
  1206. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  1207. &pool_index);
  1208. if (err)
  1209. return err;
  1210. err = devlink_sb_th_type_get_from_info(info, &threshold_type);
  1211. if (err)
  1212. return err;
  1213. if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
  1214. return -EINVAL;
  1215. size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
  1216. return devlink_sb_pool_set(devlink, devlink_sb->index,
  1217. pool_index, size, threshold_type,
  1218. info->extack);
  1219. }
  1220. static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
  1221. struct devlink *devlink,
  1222. struct devlink_port *devlink_port,
  1223. struct devlink_sb *devlink_sb,
  1224. u16 pool_index,
  1225. enum devlink_command cmd,
  1226. u32 portid, u32 seq, int flags)
  1227. {
  1228. const struct devlink_ops *ops = devlink->ops;
  1229. u32 threshold;
  1230. void *hdr;
  1231. int err;
  1232. err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
  1233. pool_index, &threshold);
  1234. if (err)
  1235. return err;
  1236. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  1237. if (!hdr)
  1238. return -EMSGSIZE;
  1239. if (devlink_nl_put_handle(msg, devlink))
  1240. goto nla_put_failure;
  1241. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
  1242. goto nla_put_failure;
  1243. if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
  1244. goto nla_put_failure;
  1245. if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
  1246. goto nla_put_failure;
  1247. if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
  1248. goto nla_put_failure;
  1249. if (ops->sb_occ_port_pool_get) {
  1250. u32 cur;
  1251. u32 max;
  1252. err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
  1253. pool_index, &cur, &max);
  1254. if (err && err != -EOPNOTSUPP)
  1255. goto sb_occ_get_failure;
  1256. if (!err) {
  1257. if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
  1258. goto nla_put_failure;
  1259. if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
  1260. goto nla_put_failure;
  1261. }
  1262. }
  1263. genlmsg_end(msg, hdr);
  1264. return 0;
  1265. nla_put_failure:
  1266. err = -EMSGSIZE;
  1267. sb_occ_get_failure:
  1268. genlmsg_cancel(msg, hdr);
  1269. return err;
  1270. }
  1271. static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
  1272. struct genl_info *info)
  1273. {
  1274. struct devlink_port *devlink_port = info->user_ptr[1];
  1275. struct devlink *devlink = devlink_port->devlink;
  1276. struct devlink_sb *devlink_sb;
  1277. struct sk_buff *msg;
  1278. u16 pool_index;
  1279. int err;
  1280. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1281. if (IS_ERR(devlink_sb))
  1282. return PTR_ERR(devlink_sb);
  1283. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  1284. &pool_index);
  1285. if (err)
  1286. return err;
  1287. if (!devlink->ops->sb_port_pool_get)
  1288. return -EOPNOTSUPP;
  1289. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  1290. if (!msg)
  1291. return -ENOMEM;
  1292. err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
  1293. devlink_sb, pool_index,
  1294. DEVLINK_CMD_SB_PORT_POOL_NEW,
  1295. info->snd_portid, info->snd_seq, 0);
  1296. if (err) {
  1297. nlmsg_free(msg);
  1298. return err;
  1299. }
  1300. return genlmsg_reply(msg, info);
  1301. }
  1302. static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
  1303. struct devlink *devlink,
  1304. struct devlink_sb *devlink_sb,
  1305. u32 portid, u32 seq)
  1306. {
  1307. struct devlink_port *devlink_port;
  1308. u16 pool_count = devlink_sb_pool_count(devlink_sb);
  1309. u16 pool_index;
  1310. int err;
  1311. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  1312. for (pool_index = 0; pool_index < pool_count; pool_index++) {
  1313. if (*p_idx < start) {
  1314. (*p_idx)++;
  1315. continue;
  1316. }
  1317. err = devlink_nl_sb_port_pool_fill(msg, devlink,
  1318. devlink_port,
  1319. devlink_sb,
  1320. pool_index,
  1321. DEVLINK_CMD_SB_PORT_POOL_NEW,
  1322. portid, seq,
  1323. NLM_F_MULTI);
  1324. if (err)
  1325. return err;
  1326. (*p_idx)++;
  1327. }
  1328. }
  1329. return 0;
  1330. }
  1331. static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
  1332. struct netlink_callback *cb)
  1333. {
  1334. struct devlink *devlink;
  1335. struct devlink_sb *devlink_sb;
  1336. int start = cb->args[0];
  1337. int idx = 0;
  1338. int err = 0;
  1339. mutex_lock(&devlink_mutex);
  1340. list_for_each_entry(devlink, &devlink_list, list) {
  1341. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
  1342. !devlink->ops->sb_port_pool_get)
  1343. continue;
  1344. mutex_lock(&devlink->lock);
  1345. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  1346. err = __sb_port_pool_get_dumpit(msg, start, &idx,
  1347. devlink, devlink_sb,
  1348. NETLINK_CB(cb->skb).portid,
  1349. cb->nlh->nlmsg_seq);
  1350. if (err == -EOPNOTSUPP) {
  1351. err = 0;
  1352. } else if (err) {
  1353. mutex_unlock(&devlink->lock);
  1354. goto out;
  1355. }
  1356. }
  1357. mutex_unlock(&devlink->lock);
  1358. }
  1359. out:
  1360. mutex_unlock(&devlink_mutex);
  1361. if (err != -EMSGSIZE)
  1362. return err;
  1363. cb->args[0] = idx;
  1364. return msg->len;
  1365. }
  1366. static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
  1367. unsigned int sb_index, u16 pool_index,
  1368. u32 threshold,
  1369. struct netlink_ext_ack *extack)
  1370. {
  1371. const struct devlink_ops *ops = devlink_port->devlink->ops;
  1372. if (ops->sb_port_pool_set)
  1373. return ops->sb_port_pool_set(devlink_port, sb_index,
  1374. pool_index, threshold, extack);
  1375. return -EOPNOTSUPP;
  1376. }
  1377. static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
  1378. struct genl_info *info)
  1379. {
  1380. struct devlink_port *devlink_port = info->user_ptr[1];
  1381. struct devlink *devlink = info->user_ptr[0];
  1382. struct devlink_sb *devlink_sb;
  1383. u16 pool_index;
  1384. u32 threshold;
  1385. int err;
  1386. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1387. if (IS_ERR(devlink_sb))
  1388. return PTR_ERR(devlink_sb);
  1389. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  1390. &pool_index);
  1391. if (err)
  1392. return err;
  1393. if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
  1394. return -EINVAL;
  1395. threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
  1396. return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
  1397. pool_index, threshold, info->extack);
  1398. }
  1399. static int
  1400. devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
  1401. struct devlink_port *devlink_port,
  1402. struct devlink_sb *devlink_sb, u16 tc_index,
  1403. enum devlink_sb_pool_type pool_type,
  1404. enum devlink_command cmd,
  1405. u32 portid, u32 seq, int flags)
  1406. {
  1407. const struct devlink_ops *ops = devlink->ops;
  1408. u16 pool_index;
  1409. u32 threshold;
  1410. void *hdr;
  1411. int err;
  1412. err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
  1413. tc_index, pool_type,
  1414. &pool_index, &threshold);
  1415. if (err)
  1416. return err;
  1417. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  1418. if (!hdr)
  1419. return -EMSGSIZE;
  1420. if (devlink_nl_put_handle(msg, devlink))
  1421. goto nla_put_failure;
  1422. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
  1423. goto nla_put_failure;
  1424. if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
  1425. goto nla_put_failure;
  1426. if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
  1427. goto nla_put_failure;
  1428. if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
  1429. goto nla_put_failure;
  1430. if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
  1431. goto nla_put_failure;
  1432. if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
  1433. goto nla_put_failure;
  1434. if (ops->sb_occ_tc_port_bind_get) {
  1435. u32 cur;
  1436. u32 max;
  1437. err = ops->sb_occ_tc_port_bind_get(devlink_port,
  1438. devlink_sb->index,
  1439. tc_index, pool_type,
  1440. &cur, &max);
  1441. if (err && err != -EOPNOTSUPP)
  1442. return err;
  1443. if (!err) {
  1444. if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
  1445. goto nla_put_failure;
  1446. if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
  1447. goto nla_put_failure;
  1448. }
  1449. }
  1450. genlmsg_end(msg, hdr);
  1451. return 0;
  1452. nla_put_failure:
  1453. genlmsg_cancel(msg, hdr);
  1454. return -EMSGSIZE;
  1455. }
  1456. static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
  1457. struct genl_info *info)
  1458. {
  1459. struct devlink_port *devlink_port = info->user_ptr[1];
  1460. struct devlink *devlink = devlink_port->devlink;
  1461. struct devlink_sb *devlink_sb;
  1462. struct sk_buff *msg;
  1463. enum devlink_sb_pool_type pool_type;
  1464. u16 tc_index;
  1465. int err;
  1466. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1467. if (IS_ERR(devlink_sb))
  1468. return PTR_ERR(devlink_sb);
  1469. err = devlink_sb_pool_type_get_from_info(info, &pool_type);
  1470. if (err)
  1471. return err;
  1472. err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
  1473. pool_type, &tc_index);
  1474. if (err)
  1475. return err;
  1476. if (!devlink->ops->sb_tc_pool_bind_get)
  1477. return -EOPNOTSUPP;
  1478. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  1479. if (!msg)
  1480. return -ENOMEM;
  1481. err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
  1482. devlink_sb, tc_index, pool_type,
  1483. DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
  1484. info->snd_portid,
  1485. info->snd_seq, 0);
  1486. if (err) {
  1487. nlmsg_free(msg);
  1488. return err;
  1489. }
  1490. return genlmsg_reply(msg, info);
  1491. }
  1492. static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
  1493. int start, int *p_idx,
  1494. struct devlink *devlink,
  1495. struct devlink_sb *devlink_sb,
  1496. u32 portid, u32 seq)
  1497. {
  1498. struct devlink_port *devlink_port;
  1499. u16 tc_index;
  1500. int err;
  1501. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  1502. for (tc_index = 0;
  1503. tc_index < devlink_sb->ingress_tc_count; tc_index++) {
  1504. if (*p_idx < start) {
  1505. (*p_idx)++;
  1506. continue;
  1507. }
  1508. err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
  1509. devlink_port,
  1510. devlink_sb,
  1511. tc_index,
  1512. DEVLINK_SB_POOL_TYPE_INGRESS,
  1513. DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
  1514. portid, seq,
  1515. NLM_F_MULTI);
  1516. if (err)
  1517. return err;
  1518. (*p_idx)++;
  1519. }
  1520. for (tc_index = 0;
  1521. tc_index < devlink_sb->egress_tc_count; tc_index++) {
  1522. if (*p_idx < start) {
  1523. (*p_idx)++;
  1524. continue;
  1525. }
  1526. err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
  1527. devlink_port,
  1528. devlink_sb,
  1529. tc_index,
  1530. DEVLINK_SB_POOL_TYPE_EGRESS,
  1531. DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
  1532. portid, seq,
  1533. NLM_F_MULTI);
  1534. if (err)
  1535. return err;
  1536. (*p_idx)++;
  1537. }
  1538. }
  1539. return 0;
  1540. }
  1541. static int
  1542. devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
  1543. struct netlink_callback *cb)
  1544. {
  1545. struct devlink *devlink;
  1546. struct devlink_sb *devlink_sb;
  1547. int start = cb->args[0];
  1548. int idx = 0;
  1549. int err = 0;
  1550. mutex_lock(&devlink_mutex);
  1551. list_for_each_entry(devlink, &devlink_list, list) {
  1552. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
  1553. !devlink->ops->sb_tc_pool_bind_get)
  1554. continue;
  1555. mutex_lock(&devlink->lock);
  1556. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  1557. err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
  1558. devlink,
  1559. devlink_sb,
  1560. NETLINK_CB(cb->skb).portid,
  1561. cb->nlh->nlmsg_seq);
  1562. if (err == -EOPNOTSUPP) {
  1563. err = 0;
  1564. } else if (err) {
  1565. mutex_unlock(&devlink->lock);
  1566. goto out;
  1567. }
  1568. }
  1569. mutex_unlock(&devlink->lock);
  1570. }
  1571. out:
  1572. mutex_unlock(&devlink_mutex);
  1573. if (err != -EMSGSIZE)
  1574. return err;
  1575. cb->args[0] = idx;
  1576. return msg->len;
  1577. }
  1578. static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
  1579. unsigned int sb_index, u16 tc_index,
  1580. enum devlink_sb_pool_type pool_type,
  1581. u16 pool_index, u32 threshold,
  1582. struct netlink_ext_ack *extack)
  1583. {
  1584. const struct devlink_ops *ops = devlink_port->devlink->ops;
  1585. if (ops->sb_tc_pool_bind_set)
  1586. return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
  1587. tc_index, pool_type,
  1588. pool_index, threshold, extack);
  1589. return -EOPNOTSUPP;
  1590. }
  1591. static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
  1592. struct genl_info *info)
  1593. {
  1594. struct devlink_port *devlink_port = info->user_ptr[1];
  1595. struct devlink *devlink = info->user_ptr[0];
  1596. enum devlink_sb_pool_type pool_type;
  1597. struct devlink_sb *devlink_sb;
  1598. u16 tc_index;
  1599. u16 pool_index;
  1600. u32 threshold;
  1601. int err;
  1602. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1603. if (IS_ERR(devlink_sb))
  1604. return PTR_ERR(devlink_sb);
  1605. err = devlink_sb_pool_type_get_from_info(info, &pool_type);
  1606. if (err)
  1607. return err;
  1608. err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
  1609. pool_type, &tc_index);
  1610. if (err)
  1611. return err;
  1612. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  1613. &pool_index);
  1614. if (err)
  1615. return err;
  1616. if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
  1617. return -EINVAL;
  1618. threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
  1619. return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
  1620. tc_index, pool_type,
  1621. pool_index, threshold, info->extack);
  1622. }
  1623. static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
  1624. struct genl_info *info)
  1625. {
  1626. struct devlink *devlink = info->user_ptr[0];
  1627. const struct devlink_ops *ops = devlink->ops;
  1628. struct devlink_sb *devlink_sb;
  1629. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1630. if (IS_ERR(devlink_sb))
  1631. return PTR_ERR(devlink_sb);
  1632. if (ops->sb_occ_snapshot)
  1633. return ops->sb_occ_snapshot(devlink, devlink_sb->index);
  1634. return -EOPNOTSUPP;
  1635. }
  1636. static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
  1637. struct genl_info *info)
  1638. {
  1639. struct devlink *devlink = info->user_ptr[0];
  1640. const struct devlink_ops *ops = devlink->ops;
  1641. struct devlink_sb *devlink_sb;
  1642. devlink_sb = devlink_sb_get_from_info(devlink, info);
  1643. if (IS_ERR(devlink_sb))
  1644. return PTR_ERR(devlink_sb);
  1645. if (ops->sb_occ_max_clear)
  1646. return ops->sb_occ_max_clear(devlink, devlink_sb->index);
  1647. return -EOPNOTSUPP;
  1648. }
  1649. static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
  1650. enum devlink_command cmd, u32 portid,
  1651. u32 seq, int flags)
  1652. {
  1653. const struct devlink_ops *ops = devlink->ops;
  1654. enum devlink_eswitch_encap_mode encap_mode;
  1655. u8 inline_mode;
  1656. void *hdr;
  1657. int err = 0;
  1658. u16 mode;
  1659. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  1660. if (!hdr)
  1661. return -EMSGSIZE;
  1662. err = devlink_nl_put_handle(msg, devlink);
  1663. if (err)
  1664. goto nla_put_failure;
  1665. if (ops->eswitch_mode_get) {
  1666. err = ops->eswitch_mode_get(devlink, &mode);
  1667. if (err)
  1668. goto nla_put_failure;
  1669. err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
  1670. if (err)
  1671. goto nla_put_failure;
  1672. }
  1673. if (ops->eswitch_inline_mode_get) {
  1674. err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
  1675. if (err)
  1676. goto nla_put_failure;
  1677. err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
  1678. inline_mode);
  1679. if (err)
  1680. goto nla_put_failure;
  1681. }
  1682. if (ops->eswitch_encap_mode_get) {
  1683. err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
  1684. if (err)
  1685. goto nla_put_failure;
  1686. err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
  1687. if (err)
  1688. goto nla_put_failure;
  1689. }
  1690. genlmsg_end(msg, hdr);
  1691. return 0;
  1692. nla_put_failure:
  1693. genlmsg_cancel(msg, hdr);
  1694. return err;
  1695. }
  1696. static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
  1697. struct genl_info *info)
  1698. {
  1699. struct devlink *devlink = info->user_ptr[0];
  1700. struct sk_buff *msg;
  1701. int err;
  1702. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  1703. if (!msg)
  1704. return -ENOMEM;
  1705. err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
  1706. info->snd_portid, info->snd_seq, 0);
  1707. if (err) {
  1708. nlmsg_free(msg);
  1709. return err;
  1710. }
  1711. return genlmsg_reply(msg, info);
  1712. }
  1713. static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
  1714. struct genl_info *info)
  1715. {
  1716. struct devlink *devlink = info->user_ptr[0];
  1717. const struct devlink_ops *ops = devlink->ops;
  1718. enum devlink_eswitch_encap_mode encap_mode;
  1719. u8 inline_mode;
  1720. int err = 0;
  1721. u16 mode;
  1722. if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
  1723. if (!ops->eswitch_mode_set)
  1724. return -EOPNOTSUPP;
  1725. mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
  1726. err = ops->eswitch_mode_set(devlink, mode, info->extack);
  1727. if (err)
  1728. return err;
  1729. }
  1730. if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
  1731. if (!ops->eswitch_inline_mode_set)
  1732. return -EOPNOTSUPP;
  1733. inline_mode = nla_get_u8(
  1734. info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
  1735. err = ops->eswitch_inline_mode_set(devlink, inline_mode,
  1736. info->extack);
  1737. if (err)
  1738. return err;
  1739. }
  1740. if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
  1741. if (!ops->eswitch_encap_mode_set)
  1742. return -EOPNOTSUPP;
  1743. encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
  1744. err = ops->eswitch_encap_mode_set(devlink, encap_mode,
  1745. info->extack);
  1746. if (err)
  1747. return err;
  1748. }
  1749. return 0;
  1750. }
  1751. int devlink_dpipe_match_put(struct sk_buff *skb,
  1752. struct devlink_dpipe_match *match)
  1753. {
  1754. struct devlink_dpipe_header *header = match->header;
  1755. struct devlink_dpipe_field *field = &header->fields[match->field_id];
  1756. struct nlattr *match_attr;
  1757. match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
  1758. if (!match_attr)
  1759. return -EMSGSIZE;
  1760. if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
  1761. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
  1762. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
  1763. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
  1764. nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
  1765. goto nla_put_failure;
  1766. nla_nest_end(skb, match_attr);
  1767. return 0;
  1768. nla_put_failure:
  1769. nla_nest_cancel(skb, match_attr);
  1770. return -EMSGSIZE;
  1771. }
  1772. EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
  1773. static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
  1774. struct sk_buff *skb)
  1775. {
  1776. struct nlattr *matches_attr;
  1777. matches_attr = nla_nest_start_noflag(skb,
  1778. DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
  1779. if (!matches_attr)
  1780. return -EMSGSIZE;
  1781. if (table->table_ops->matches_dump(table->priv, skb))
  1782. goto nla_put_failure;
  1783. nla_nest_end(skb, matches_attr);
  1784. return 0;
  1785. nla_put_failure:
  1786. nla_nest_cancel(skb, matches_attr);
  1787. return -EMSGSIZE;
  1788. }
  1789. int devlink_dpipe_action_put(struct sk_buff *skb,
  1790. struct devlink_dpipe_action *action)
  1791. {
  1792. struct devlink_dpipe_header *header = action->header;
  1793. struct devlink_dpipe_field *field = &header->fields[action->field_id];
  1794. struct nlattr *action_attr;
  1795. action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
  1796. if (!action_attr)
  1797. return -EMSGSIZE;
  1798. if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
  1799. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
  1800. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
  1801. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
  1802. nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
  1803. goto nla_put_failure;
  1804. nla_nest_end(skb, action_attr);
  1805. return 0;
  1806. nla_put_failure:
  1807. nla_nest_cancel(skb, action_attr);
  1808. return -EMSGSIZE;
  1809. }
  1810. EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
  1811. static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
  1812. struct sk_buff *skb)
  1813. {
  1814. struct nlattr *actions_attr;
  1815. actions_attr = nla_nest_start_noflag(skb,
  1816. DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
  1817. if (!actions_attr)
  1818. return -EMSGSIZE;
  1819. if (table->table_ops->actions_dump(table->priv, skb))
  1820. goto nla_put_failure;
  1821. nla_nest_end(skb, actions_attr);
  1822. return 0;
  1823. nla_put_failure:
  1824. nla_nest_cancel(skb, actions_attr);
  1825. return -EMSGSIZE;
  1826. }
  1827. static int devlink_dpipe_table_put(struct sk_buff *skb,
  1828. struct devlink_dpipe_table *table)
  1829. {
  1830. struct nlattr *table_attr;
  1831. u64 table_size;
  1832. table_size = table->table_ops->size_get(table->priv);
  1833. table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
  1834. if (!table_attr)
  1835. return -EMSGSIZE;
  1836. if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
  1837. nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
  1838. DEVLINK_ATTR_PAD))
  1839. goto nla_put_failure;
  1840. if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
  1841. table->counters_enabled))
  1842. goto nla_put_failure;
  1843. if (table->resource_valid) {
  1844. if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
  1845. table->resource_id, DEVLINK_ATTR_PAD) ||
  1846. nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
  1847. table->resource_units, DEVLINK_ATTR_PAD))
  1848. goto nla_put_failure;
  1849. }
  1850. if (devlink_dpipe_matches_put(table, skb))
  1851. goto nla_put_failure;
  1852. if (devlink_dpipe_actions_put(table, skb))
  1853. goto nla_put_failure;
  1854. nla_nest_end(skb, table_attr);
  1855. return 0;
  1856. nla_put_failure:
  1857. nla_nest_cancel(skb, table_attr);
  1858. return -EMSGSIZE;
  1859. }
  1860. static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
  1861. struct genl_info *info)
  1862. {
  1863. int err;
  1864. if (*pskb) {
  1865. err = genlmsg_reply(*pskb, info);
  1866. if (err)
  1867. return err;
  1868. }
  1869. *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  1870. if (!*pskb)
  1871. return -ENOMEM;
  1872. return 0;
  1873. }
  1874. static int devlink_dpipe_tables_fill(struct genl_info *info,
  1875. enum devlink_command cmd, int flags,
  1876. struct list_head *dpipe_tables,
  1877. const char *table_name)
  1878. {
  1879. struct devlink *devlink = info->user_ptr[0];
  1880. struct devlink_dpipe_table *table;
  1881. struct nlattr *tables_attr;
  1882. struct sk_buff *skb = NULL;
  1883. struct nlmsghdr *nlh;
  1884. bool incomplete;
  1885. void *hdr;
  1886. int i;
  1887. int err;
  1888. table = list_first_entry(dpipe_tables,
  1889. struct devlink_dpipe_table, list);
  1890. start_again:
  1891. err = devlink_dpipe_send_and_alloc_skb(&skb, info);
  1892. if (err)
  1893. return err;
  1894. hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
  1895. &devlink_nl_family, NLM_F_MULTI, cmd);
  1896. if (!hdr) {
  1897. nlmsg_free(skb);
  1898. return -EMSGSIZE;
  1899. }
  1900. if (devlink_nl_put_handle(skb, devlink))
  1901. goto nla_put_failure;
  1902. tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
  1903. if (!tables_attr)
  1904. goto nla_put_failure;
  1905. i = 0;
  1906. incomplete = false;
  1907. list_for_each_entry_from(table, dpipe_tables, list) {
  1908. if (!table_name) {
  1909. err = devlink_dpipe_table_put(skb, table);
  1910. if (err) {
  1911. if (!i)
  1912. goto err_table_put;
  1913. incomplete = true;
  1914. break;
  1915. }
  1916. } else {
  1917. if (!strcmp(table->name, table_name)) {
  1918. err = devlink_dpipe_table_put(skb, table);
  1919. if (err)
  1920. break;
  1921. }
  1922. }
  1923. i++;
  1924. }
  1925. nla_nest_end(skb, tables_attr);
  1926. genlmsg_end(skb, hdr);
  1927. if (incomplete)
  1928. goto start_again;
  1929. send_done:
  1930. nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
  1931. NLMSG_DONE, 0, flags | NLM_F_MULTI);
  1932. if (!nlh) {
  1933. err = devlink_dpipe_send_and_alloc_skb(&skb, info);
  1934. if (err)
  1935. return err;
  1936. goto send_done;
  1937. }
  1938. return genlmsg_reply(skb, info);
  1939. nla_put_failure:
  1940. err = -EMSGSIZE;
  1941. err_table_put:
  1942. nlmsg_free(skb);
  1943. return err;
  1944. }
  1945. static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
  1946. struct genl_info *info)
  1947. {
  1948. struct devlink *devlink = info->user_ptr[0];
  1949. const char *table_name = NULL;
  1950. if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
  1951. table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
  1952. return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
  1953. &devlink->dpipe_table_list,
  1954. table_name);
  1955. }
  1956. static int devlink_dpipe_value_put(struct sk_buff *skb,
  1957. struct devlink_dpipe_value *value)
  1958. {
  1959. if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
  1960. value->value_size, value->value))
  1961. return -EMSGSIZE;
  1962. if (value->mask)
  1963. if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
  1964. value->value_size, value->mask))
  1965. return -EMSGSIZE;
  1966. if (value->mapping_valid)
  1967. if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
  1968. value->mapping_value))
  1969. return -EMSGSIZE;
  1970. return 0;
  1971. }
  1972. static int devlink_dpipe_action_value_put(struct sk_buff *skb,
  1973. struct devlink_dpipe_value *value)
  1974. {
  1975. if (!value->action)
  1976. return -EINVAL;
  1977. if (devlink_dpipe_action_put(skb, value->action))
  1978. return -EMSGSIZE;
  1979. if (devlink_dpipe_value_put(skb, value))
  1980. return -EMSGSIZE;
  1981. return 0;
  1982. }
  1983. static int devlink_dpipe_action_values_put(struct sk_buff *skb,
  1984. struct devlink_dpipe_value *values,
  1985. unsigned int values_count)
  1986. {
  1987. struct nlattr *action_attr;
  1988. int i;
  1989. int err;
  1990. for (i = 0; i < values_count; i++) {
  1991. action_attr = nla_nest_start_noflag(skb,
  1992. DEVLINK_ATTR_DPIPE_ACTION_VALUE);
  1993. if (!action_attr)
  1994. return -EMSGSIZE;
  1995. err = devlink_dpipe_action_value_put(skb, &values[i]);
  1996. if (err)
  1997. goto err_action_value_put;
  1998. nla_nest_end(skb, action_attr);
  1999. }
  2000. return 0;
  2001. err_action_value_put:
  2002. nla_nest_cancel(skb, action_attr);
  2003. return err;
  2004. }
  2005. static int devlink_dpipe_match_value_put(struct sk_buff *skb,
  2006. struct devlink_dpipe_value *value)
  2007. {
  2008. if (!value->match)
  2009. return -EINVAL;
  2010. if (devlink_dpipe_match_put(skb, value->match))
  2011. return -EMSGSIZE;
  2012. if (devlink_dpipe_value_put(skb, value))
  2013. return -EMSGSIZE;
  2014. return 0;
  2015. }
  2016. static int devlink_dpipe_match_values_put(struct sk_buff *skb,
  2017. struct devlink_dpipe_value *values,
  2018. unsigned int values_count)
  2019. {
  2020. struct nlattr *match_attr;
  2021. int i;
  2022. int err;
  2023. for (i = 0; i < values_count; i++) {
  2024. match_attr = nla_nest_start_noflag(skb,
  2025. DEVLINK_ATTR_DPIPE_MATCH_VALUE);
  2026. if (!match_attr)
  2027. return -EMSGSIZE;
  2028. err = devlink_dpipe_match_value_put(skb, &values[i]);
  2029. if (err)
  2030. goto err_match_value_put;
  2031. nla_nest_end(skb, match_attr);
  2032. }
  2033. return 0;
  2034. err_match_value_put:
  2035. nla_nest_cancel(skb, match_attr);
  2036. return err;
  2037. }
  2038. static int devlink_dpipe_entry_put(struct sk_buff *skb,
  2039. struct devlink_dpipe_entry *entry)
  2040. {
  2041. struct nlattr *entry_attr, *matches_attr, *actions_attr;
  2042. int err;
  2043. entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
  2044. if (!entry_attr)
  2045. return -EMSGSIZE;
  2046. if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
  2047. DEVLINK_ATTR_PAD))
  2048. goto nla_put_failure;
  2049. if (entry->counter_valid)
  2050. if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
  2051. entry->counter, DEVLINK_ATTR_PAD))
  2052. goto nla_put_failure;
  2053. matches_attr = nla_nest_start_noflag(skb,
  2054. DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
  2055. if (!matches_attr)
  2056. goto nla_put_failure;
  2057. err = devlink_dpipe_match_values_put(skb, entry->match_values,
  2058. entry->match_values_count);
  2059. if (err) {
  2060. nla_nest_cancel(skb, matches_attr);
  2061. goto err_match_values_put;
  2062. }
  2063. nla_nest_end(skb, matches_attr);
  2064. actions_attr = nla_nest_start_noflag(skb,
  2065. DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
  2066. if (!actions_attr)
  2067. goto nla_put_failure;
  2068. err = devlink_dpipe_action_values_put(skb, entry->action_values,
  2069. entry->action_values_count);
  2070. if (err) {
  2071. nla_nest_cancel(skb, actions_attr);
  2072. goto err_action_values_put;
  2073. }
  2074. nla_nest_end(skb, actions_attr);
  2075. nla_nest_end(skb, entry_attr);
  2076. return 0;
  2077. nla_put_failure:
  2078. err = -EMSGSIZE;
  2079. err_match_values_put:
  2080. err_action_values_put:
  2081. nla_nest_cancel(skb, entry_attr);
  2082. return err;
  2083. }
  2084. static struct devlink_dpipe_table *
  2085. devlink_dpipe_table_find(struct list_head *dpipe_tables,
  2086. const char *table_name, struct devlink *devlink)
  2087. {
  2088. struct devlink_dpipe_table *table;
  2089. list_for_each_entry_rcu(table, dpipe_tables, list,
  2090. lockdep_is_held(&devlink->lock)) {
  2091. if (!strcmp(table->name, table_name))
  2092. return table;
  2093. }
  2094. return NULL;
  2095. }
  2096. int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
  2097. {
  2098. struct devlink *devlink;
  2099. int err;
  2100. err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
  2101. dump_ctx->info);
  2102. if (err)
  2103. return err;
  2104. dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
  2105. dump_ctx->info->snd_portid,
  2106. dump_ctx->info->snd_seq,
  2107. &devlink_nl_family, NLM_F_MULTI,
  2108. dump_ctx->cmd);
  2109. if (!dump_ctx->hdr)
  2110. goto nla_put_failure;
  2111. devlink = dump_ctx->info->user_ptr[0];
  2112. if (devlink_nl_put_handle(dump_ctx->skb, devlink))
  2113. goto nla_put_failure;
  2114. dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
  2115. DEVLINK_ATTR_DPIPE_ENTRIES);
  2116. if (!dump_ctx->nest)
  2117. goto nla_put_failure;
  2118. return 0;
  2119. nla_put_failure:
  2120. nlmsg_free(dump_ctx->skb);
  2121. return -EMSGSIZE;
  2122. }
  2123. EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
  2124. int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
  2125. struct devlink_dpipe_entry *entry)
  2126. {
  2127. return devlink_dpipe_entry_put(dump_ctx->skb, entry);
  2128. }
  2129. EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
  2130. int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
  2131. {
  2132. nla_nest_end(dump_ctx->skb, dump_ctx->nest);
  2133. genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
  2134. return 0;
  2135. }
  2136. EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
  2137. void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
  2138. {
  2139. unsigned int value_count, value_index;
  2140. struct devlink_dpipe_value *value;
  2141. value = entry->action_values;
  2142. value_count = entry->action_values_count;
  2143. for (value_index = 0; value_index < value_count; value_index++) {
  2144. kfree(value[value_index].value);
  2145. kfree(value[value_index].mask);
  2146. }
  2147. value = entry->match_values;
  2148. value_count = entry->match_values_count;
  2149. for (value_index = 0; value_index < value_count; value_index++) {
  2150. kfree(value[value_index].value);
  2151. kfree(value[value_index].mask);
  2152. }
  2153. }
  2154. EXPORT_SYMBOL(devlink_dpipe_entry_clear);
  2155. static int devlink_dpipe_entries_fill(struct genl_info *info,
  2156. enum devlink_command cmd, int flags,
  2157. struct devlink_dpipe_table *table)
  2158. {
  2159. struct devlink_dpipe_dump_ctx dump_ctx;
  2160. struct nlmsghdr *nlh;
  2161. int err;
  2162. dump_ctx.skb = NULL;
  2163. dump_ctx.cmd = cmd;
  2164. dump_ctx.info = info;
  2165. err = table->table_ops->entries_dump(table->priv,
  2166. table->counters_enabled,
  2167. &dump_ctx);
  2168. if (err)
  2169. return err;
  2170. send_done:
  2171. nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
  2172. NLMSG_DONE, 0, flags | NLM_F_MULTI);
  2173. if (!nlh) {
  2174. err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
  2175. if (err)
  2176. return err;
  2177. goto send_done;
  2178. }
  2179. return genlmsg_reply(dump_ctx.skb, info);
  2180. }
  2181. static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
  2182. struct genl_info *info)
  2183. {
  2184. struct devlink *devlink = info->user_ptr[0];
  2185. struct devlink_dpipe_table *table;
  2186. const char *table_name;
  2187. if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
  2188. return -EINVAL;
  2189. table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
  2190. table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
  2191. table_name, devlink);
  2192. if (!table)
  2193. return -EINVAL;
  2194. if (!table->table_ops->entries_dump)
  2195. return -EINVAL;
  2196. return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
  2197. 0, table);
  2198. }
  2199. static int devlink_dpipe_fields_put(struct sk_buff *skb,
  2200. const struct devlink_dpipe_header *header)
  2201. {
  2202. struct devlink_dpipe_field *field;
  2203. struct nlattr *field_attr;
  2204. int i;
  2205. for (i = 0; i < header->fields_count; i++) {
  2206. field = &header->fields[i];
  2207. field_attr = nla_nest_start_noflag(skb,
  2208. DEVLINK_ATTR_DPIPE_FIELD);
  2209. if (!field_attr)
  2210. return -EMSGSIZE;
  2211. if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
  2212. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
  2213. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
  2214. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
  2215. goto nla_put_failure;
  2216. nla_nest_end(skb, field_attr);
  2217. }
  2218. return 0;
  2219. nla_put_failure:
  2220. nla_nest_cancel(skb, field_attr);
  2221. return -EMSGSIZE;
  2222. }
  2223. static int devlink_dpipe_header_put(struct sk_buff *skb,
  2224. struct devlink_dpipe_header *header)
  2225. {
  2226. struct nlattr *fields_attr, *header_attr;
  2227. int err;
  2228. header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
  2229. if (!header_attr)
  2230. return -EMSGSIZE;
  2231. if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
  2232. nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
  2233. nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
  2234. goto nla_put_failure;
  2235. fields_attr = nla_nest_start_noflag(skb,
  2236. DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
  2237. if (!fields_attr)
  2238. goto nla_put_failure;
  2239. err = devlink_dpipe_fields_put(skb, header);
  2240. if (err) {
  2241. nla_nest_cancel(skb, fields_attr);
  2242. goto nla_put_failure;
  2243. }
  2244. nla_nest_end(skb, fields_attr);
  2245. nla_nest_end(skb, header_attr);
  2246. return 0;
  2247. nla_put_failure:
  2248. err = -EMSGSIZE;
  2249. nla_nest_cancel(skb, header_attr);
  2250. return err;
  2251. }
  2252. static int devlink_dpipe_headers_fill(struct genl_info *info,
  2253. enum devlink_command cmd, int flags,
  2254. struct devlink_dpipe_headers *
  2255. dpipe_headers)
  2256. {
  2257. struct devlink *devlink = info->user_ptr[0];
  2258. struct nlattr *headers_attr;
  2259. struct sk_buff *skb = NULL;
  2260. struct nlmsghdr *nlh;
  2261. void *hdr;
  2262. int i, j;
  2263. int err;
  2264. i = 0;
  2265. start_again:
  2266. err = devlink_dpipe_send_and_alloc_skb(&skb, info);
  2267. if (err)
  2268. return err;
  2269. hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
  2270. &devlink_nl_family, NLM_F_MULTI, cmd);
  2271. if (!hdr) {
  2272. nlmsg_free(skb);
  2273. return -EMSGSIZE;
  2274. }
  2275. if (devlink_nl_put_handle(skb, devlink))
  2276. goto nla_put_failure;
  2277. headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
  2278. if (!headers_attr)
  2279. goto nla_put_failure;
  2280. j = 0;
  2281. for (; i < dpipe_headers->headers_count; i++) {
  2282. err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
  2283. if (err) {
  2284. if (!j)
  2285. goto err_table_put;
  2286. break;
  2287. }
  2288. j++;
  2289. }
  2290. nla_nest_end(skb, headers_attr);
  2291. genlmsg_end(skb, hdr);
  2292. if (i != dpipe_headers->headers_count)
  2293. goto start_again;
  2294. send_done:
  2295. nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
  2296. NLMSG_DONE, 0, flags | NLM_F_MULTI);
  2297. if (!nlh) {
  2298. err = devlink_dpipe_send_and_alloc_skb(&skb, info);
  2299. if (err)
  2300. return err;
  2301. goto send_done;
  2302. }
  2303. return genlmsg_reply(skb, info);
  2304. nla_put_failure:
  2305. err = -EMSGSIZE;
  2306. err_table_put:
  2307. nlmsg_free(skb);
  2308. return err;
  2309. }
  2310. static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
  2311. struct genl_info *info)
  2312. {
  2313. struct devlink *devlink = info->user_ptr[0];
  2314. if (!devlink->dpipe_headers)
  2315. return -EOPNOTSUPP;
  2316. return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
  2317. 0, devlink->dpipe_headers);
  2318. }
  2319. static int devlink_dpipe_table_counters_set(struct devlink *devlink,
  2320. const char *table_name,
  2321. bool enable)
  2322. {
  2323. struct devlink_dpipe_table *table;
  2324. table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
  2325. table_name, devlink);
  2326. if (!table)
  2327. return -EINVAL;
  2328. if (table->counter_control_extern)
  2329. return -EOPNOTSUPP;
  2330. if (!(table->counters_enabled ^ enable))
  2331. return 0;
  2332. table->counters_enabled = enable;
  2333. if (table->table_ops->counters_set_update)
  2334. table->table_ops->counters_set_update(table->priv, enable);
  2335. return 0;
  2336. }
  2337. static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
  2338. struct genl_info *info)
  2339. {
  2340. struct devlink *devlink = info->user_ptr[0];
  2341. const char *table_name;
  2342. bool counters_enable;
  2343. if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
  2344. !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
  2345. return -EINVAL;
  2346. table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
  2347. counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
  2348. return devlink_dpipe_table_counters_set(devlink, table_name,
  2349. counters_enable);
  2350. }
  2351. static struct devlink_resource *
  2352. devlink_resource_find(struct devlink *devlink,
  2353. struct devlink_resource *resource, u64 resource_id)
  2354. {
  2355. struct list_head *resource_list;
  2356. if (resource)
  2357. resource_list = &resource->resource_list;
  2358. else
  2359. resource_list = &devlink->resource_list;
  2360. list_for_each_entry(resource, resource_list, list) {
  2361. struct devlink_resource *child_resource;
  2362. if (resource->id == resource_id)
  2363. return resource;
  2364. child_resource = devlink_resource_find(devlink, resource,
  2365. resource_id);
  2366. if (child_resource)
  2367. return child_resource;
  2368. }
  2369. return NULL;
  2370. }
  2371. static void
  2372. devlink_resource_validate_children(struct devlink_resource *resource)
  2373. {
  2374. struct devlink_resource *child_resource;
  2375. bool size_valid = true;
  2376. u64 parts_size = 0;
  2377. if (list_empty(&resource->resource_list))
  2378. goto out;
  2379. list_for_each_entry(child_resource, &resource->resource_list, list)
  2380. parts_size += child_resource->size_new;
  2381. if (parts_size > resource->size_new)
  2382. size_valid = false;
  2383. out:
  2384. resource->size_valid = size_valid;
  2385. }
  2386. static int
  2387. devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
  2388. struct netlink_ext_ack *extack)
  2389. {
  2390. u64 reminder;
  2391. int err = 0;
  2392. if (size > resource->size_params.size_max) {
  2393. NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
  2394. err = -EINVAL;
  2395. }
  2396. if (size < resource->size_params.size_min) {
  2397. NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
  2398. err = -EINVAL;
  2399. }
  2400. div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
  2401. if (reminder) {
  2402. NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
  2403. err = -EINVAL;
  2404. }
  2405. return err;
  2406. }
  2407. static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
  2408. struct genl_info *info)
  2409. {
  2410. struct devlink *devlink = info->user_ptr[0];
  2411. struct devlink_resource *resource;
  2412. u64 resource_id;
  2413. u64 size;
  2414. int err;
  2415. if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
  2416. !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
  2417. return -EINVAL;
  2418. resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
  2419. resource = devlink_resource_find(devlink, NULL, resource_id);
  2420. if (!resource)
  2421. return -EINVAL;
  2422. size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
  2423. err = devlink_resource_validate_size(resource, size, info->extack);
  2424. if (err)
  2425. return err;
  2426. resource->size_new = size;
  2427. devlink_resource_validate_children(resource);
  2428. if (resource->parent)
  2429. devlink_resource_validate_children(resource->parent);
  2430. return 0;
  2431. }
  2432. static int
  2433. devlink_resource_size_params_put(struct devlink_resource *resource,
  2434. struct sk_buff *skb)
  2435. {
  2436. struct devlink_resource_size_params *size_params;
  2437. size_params = &resource->size_params;
  2438. if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
  2439. size_params->size_granularity, DEVLINK_ATTR_PAD) ||
  2440. nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
  2441. size_params->size_max, DEVLINK_ATTR_PAD) ||
  2442. nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
  2443. size_params->size_min, DEVLINK_ATTR_PAD) ||
  2444. nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
  2445. return -EMSGSIZE;
  2446. return 0;
  2447. }
  2448. static int devlink_resource_occ_put(struct devlink_resource *resource,
  2449. struct sk_buff *skb)
  2450. {
  2451. if (!resource->occ_get)
  2452. return 0;
  2453. return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
  2454. resource->occ_get(resource->occ_get_priv),
  2455. DEVLINK_ATTR_PAD);
  2456. }
  2457. static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
  2458. struct devlink_resource *resource)
  2459. {
  2460. struct devlink_resource *child_resource;
  2461. struct nlattr *child_resource_attr;
  2462. struct nlattr *resource_attr;
  2463. resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
  2464. if (!resource_attr)
  2465. return -EMSGSIZE;
  2466. if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
  2467. nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
  2468. DEVLINK_ATTR_PAD) ||
  2469. nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
  2470. DEVLINK_ATTR_PAD))
  2471. goto nla_put_failure;
  2472. if (resource->size != resource->size_new)
  2473. nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
  2474. resource->size_new, DEVLINK_ATTR_PAD);
  2475. if (devlink_resource_occ_put(resource, skb))
  2476. goto nla_put_failure;
  2477. if (devlink_resource_size_params_put(resource, skb))
  2478. goto nla_put_failure;
  2479. if (list_empty(&resource->resource_list))
  2480. goto out;
  2481. if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
  2482. resource->size_valid))
  2483. goto nla_put_failure;
  2484. child_resource_attr = nla_nest_start_noflag(skb,
  2485. DEVLINK_ATTR_RESOURCE_LIST);
  2486. if (!child_resource_attr)
  2487. goto nla_put_failure;
  2488. list_for_each_entry(child_resource, &resource->resource_list, list) {
  2489. if (devlink_resource_put(devlink, skb, child_resource))
  2490. goto resource_put_failure;
  2491. }
  2492. nla_nest_end(skb, child_resource_attr);
  2493. out:
  2494. nla_nest_end(skb, resource_attr);
  2495. return 0;
  2496. resource_put_failure:
  2497. nla_nest_cancel(skb, child_resource_attr);
  2498. nla_put_failure:
  2499. nla_nest_cancel(skb, resource_attr);
  2500. return -EMSGSIZE;
  2501. }
  2502. static int devlink_resource_fill(struct genl_info *info,
  2503. enum devlink_command cmd, int flags)
  2504. {
  2505. struct devlink *devlink = info->user_ptr[0];
  2506. struct devlink_resource *resource;
  2507. struct nlattr *resources_attr;
  2508. struct sk_buff *skb = NULL;
  2509. struct nlmsghdr *nlh;
  2510. bool incomplete;
  2511. void *hdr;
  2512. int i;
  2513. int err;
  2514. resource = list_first_entry(&devlink->resource_list,
  2515. struct devlink_resource, list);
  2516. start_again:
  2517. err = devlink_dpipe_send_and_alloc_skb(&skb, info);
  2518. if (err)
  2519. return err;
  2520. hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
  2521. &devlink_nl_family, NLM_F_MULTI, cmd);
  2522. if (!hdr) {
  2523. nlmsg_free(skb);
  2524. return -EMSGSIZE;
  2525. }
  2526. if (devlink_nl_put_handle(skb, devlink))
  2527. goto nla_put_failure;
  2528. resources_attr = nla_nest_start_noflag(skb,
  2529. DEVLINK_ATTR_RESOURCE_LIST);
  2530. if (!resources_attr)
  2531. goto nla_put_failure;
  2532. incomplete = false;
  2533. i = 0;
  2534. list_for_each_entry_from(resource, &devlink->resource_list, list) {
  2535. err = devlink_resource_put(devlink, skb, resource);
  2536. if (err) {
  2537. if (!i)
  2538. goto err_resource_put;
  2539. incomplete = true;
  2540. break;
  2541. }
  2542. i++;
  2543. }
  2544. nla_nest_end(skb, resources_attr);
  2545. genlmsg_end(skb, hdr);
  2546. if (incomplete)
  2547. goto start_again;
  2548. send_done:
  2549. nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
  2550. NLMSG_DONE, 0, flags | NLM_F_MULTI);
  2551. if (!nlh) {
  2552. err = devlink_dpipe_send_and_alloc_skb(&skb, info);
  2553. if (err)
  2554. return err;
  2555. goto send_done;
  2556. }
  2557. return genlmsg_reply(skb, info);
  2558. nla_put_failure:
  2559. err = -EMSGSIZE;
  2560. err_resource_put:
  2561. nlmsg_free(skb);
  2562. return err;
  2563. }
  2564. static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
  2565. struct genl_info *info)
  2566. {
  2567. struct devlink *devlink = info->user_ptr[0];
  2568. if (list_empty(&devlink->resource_list))
  2569. return -EOPNOTSUPP;
  2570. return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
  2571. }
  2572. static int
  2573. devlink_resources_validate(struct devlink *devlink,
  2574. struct devlink_resource *resource,
  2575. struct genl_info *info)
  2576. {
  2577. struct list_head *resource_list;
  2578. int err = 0;
  2579. if (resource)
  2580. resource_list = &resource->resource_list;
  2581. else
  2582. resource_list = &devlink->resource_list;
  2583. list_for_each_entry(resource, resource_list, list) {
  2584. if (!resource->size_valid)
  2585. return -EINVAL;
  2586. err = devlink_resources_validate(devlink, resource, info);
  2587. if (err)
  2588. return err;
  2589. }
  2590. return err;
  2591. }
  2592. static struct net *devlink_netns_get(struct sk_buff *skb,
  2593. struct genl_info *info)
  2594. {
  2595. struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
  2596. struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
  2597. struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
  2598. struct net *net;
  2599. if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
  2600. NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified");
  2601. return ERR_PTR(-EINVAL);
  2602. }
  2603. if (netns_pid_attr) {
  2604. net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
  2605. } else if (netns_fd_attr) {
  2606. net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
  2607. } else if (netns_id_attr) {
  2608. net = get_net_ns_by_id(sock_net(skb->sk),
  2609. nla_get_u32(netns_id_attr));
  2610. if (!net)
  2611. net = ERR_PTR(-EINVAL);
  2612. } else {
  2613. WARN_ON(1);
  2614. net = ERR_PTR(-EINVAL);
  2615. }
  2616. if (IS_ERR(net)) {
  2617. NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
  2618. return ERR_PTR(-EINVAL);
  2619. }
  2620. if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
  2621. put_net(net);
  2622. return ERR_PTR(-EPERM);
  2623. }
  2624. return net;
  2625. }
  2626. static void devlink_param_notify(struct devlink *devlink,
  2627. unsigned int port_index,
  2628. struct devlink_param_item *param_item,
  2629. enum devlink_command cmd);
  2630. static void devlink_ns_change_notify(struct devlink *devlink,
  2631. struct net *dest_net, struct net *curr_net,
  2632. bool new)
  2633. {
  2634. struct devlink_param_item *param_item;
  2635. enum devlink_command cmd;
  2636. /* Userspace needs to be notified about devlink objects
  2637. * removed from original and entering new network namespace.
  2638. * The rest of the devlink objects are re-created during
  2639. * reload process so the notifications are generated separatelly.
  2640. */
  2641. if (!dest_net || net_eq(dest_net, curr_net))
  2642. return;
  2643. if (new)
  2644. devlink_notify(devlink, DEVLINK_CMD_NEW);
  2645. cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL;
  2646. list_for_each_entry(param_item, &devlink->param_list, list)
  2647. devlink_param_notify(devlink, 0, param_item, cmd);
  2648. if (!new)
  2649. devlink_notify(devlink, DEVLINK_CMD_DEL);
  2650. }
  2651. static bool devlink_reload_supported(const struct devlink_ops *ops)
  2652. {
  2653. return ops->reload_down && ops->reload_up;
  2654. }
  2655. static void devlink_reload_failed_set(struct devlink *devlink,
  2656. bool reload_failed)
  2657. {
  2658. if (devlink->reload_failed == reload_failed)
  2659. return;
  2660. devlink->reload_failed = reload_failed;
  2661. devlink_notify(devlink, DEVLINK_CMD_NEW);
  2662. }
  2663. bool devlink_is_reload_failed(const struct devlink *devlink)
  2664. {
  2665. return devlink->reload_failed;
  2666. }
  2667. EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
  2668. static void
  2669. __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats,
  2670. enum devlink_reload_limit limit, u32 actions_performed)
  2671. {
  2672. unsigned long actions = actions_performed;
  2673. int stat_idx;
  2674. int action;
  2675. for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) {
  2676. stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action;
  2677. reload_stats[stat_idx]++;
  2678. }
  2679. devlink_notify(devlink, DEVLINK_CMD_NEW);
  2680. }
  2681. static void
  2682. devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit,
  2683. u32 actions_performed)
  2684. {
  2685. __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit,
  2686. actions_performed);
  2687. }
  2688. /**
  2689. * devlink_remote_reload_actions_performed - Update devlink on reload actions
  2690. * performed which are not a direct result of devlink reload call.
  2691. *
  2692. * This should be called by a driver after performing reload actions in case it was not
  2693. * a result of devlink reload call. For example fw_activate was performed as a result
  2694. * of devlink reload triggered fw_activate on another host.
  2695. * The motivation for this function is to keep data on reload actions performed on this
  2696. * function whether it was done due to direct devlink reload call or not.
  2697. *
  2698. * @devlink: devlink
  2699. * @limit: reload limit
  2700. * @actions_performed: bitmask of actions performed
  2701. */
  2702. void devlink_remote_reload_actions_performed(struct devlink *devlink,
  2703. enum devlink_reload_limit limit,
  2704. u32 actions_performed)
  2705. {
  2706. if (WARN_ON(!actions_performed ||
  2707. actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
  2708. actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) ||
  2709. limit > DEVLINK_RELOAD_LIMIT_MAX))
  2710. return;
  2711. __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit,
  2712. actions_performed);
  2713. }
  2714. EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed);
  2715. static int devlink_reload(struct devlink *devlink, struct net *dest_net,
  2716. enum devlink_reload_action action, enum devlink_reload_limit limit,
  2717. u32 *actions_performed, struct netlink_ext_ack *extack)
  2718. {
  2719. u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
  2720. struct net *curr_net;
  2721. int err;
  2722. if (!devlink->reload_enabled)
  2723. return -EOPNOTSUPP;
  2724. memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
  2725. sizeof(remote_reload_stats));
  2726. curr_net = devlink_net(devlink);
  2727. devlink_ns_change_notify(devlink, dest_net, curr_net, false);
  2728. err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
  2729. if (err)
  2730. return err;
  2731. if (dest_net && !net_eq(dest_net, curr_net))
  2732. __devlink_net_set(devlink, dest_net);
  2733. err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
  2734. devlink_reload_failed_set(devlink, !!err);
  2735. if (err)
  2736. return err;
  2737. devlink_ns_change_notify(devlink, dest_net, curr_net, true);
  2738. WARN_ON(!(*actions_performed & BIT(action)));
  2739. /* Catch driver on updating the remote action within devlink reload */
  2740. WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
  2741. sizeof(remote_reload_stats)));
  2742. devlink_reload_stats_update(devlink, limit, *actions_performed);
  2743. return 0;
  2744. }
  2745. static int
  2746. devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
  2747. enum devlink_command cmd, struct genl_info *info)
  2748. {
  2749. struct sk_buff *msg;
  2750. void *hdr;
  2751. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  2752. if (!msg)
  2753. return -ENOMEM;
  2754. hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
  2755. if (!hdr)
  2756. goto free_msg;
  2757. if (devlink_nl_put_handle(msg, devlink))
  2758. goto nla_put_failure;
  2759. if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
  2760. actions_performed))
  2761. goto nla_put_failure;
  2762. genlmsg_end(msg, hdr);
  2763. return genlmsg_reply(msg, info);
  2764. nla_put_failure:
  2765. genlmsg_cancel(msg, hdr);
  2766. free_msg:
  2767. nlmsg_free(msg);
  2768. return -EMSGSIZE;
  2769. }
  2770. static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
  2771. {
  2772. struct devlink *devlink = info->user_ptr[0];
  2773. enum devlink_reload_action action;
  2774. enum devlink_reload_limit limit;
  2775. struct net *dest_net = NULL;
  2776. u32 actions_performed;
  2777. int err;
  2778. if (!devlink_reload_supported(devlink->ops))
  2779. return -EOPNOTSUPP;
  2780. err = devlink_resources_validate(devlink, NULL, info);
  2781. if (err) {
  2782. NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
  2783. return err;
  2784. }
  2785. if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
  2786. action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
  2787. else
  2788. action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
  2789. if (!devlink_reload_action_is_supported(devlink, action)) {
  2790. NL_SET_ERR_MSG_MOD(info->extack,
  2791. "Requested reload action is not supported by the driver");
  2792. return -EOPNOTSUPP;
  2793. }
  2794. limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
  2795. if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
  2796. struct nla_bitfield32 limits;
  2797. u32 limits_selected;
  2798. limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
  2799. limits_selected = limits.value & limits.selector;
  2800. if (!limits_selected) {
  2801. NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected");
  2802. return -EINVAL;
  2803. }
  2804. for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
  2805. if (limits_selected & BIT(limit))
  2806. break;
  2807. /* UAPI enables multiselection, but currently it is not used */
  2808. if (limits_selected != BIT(limit)) {
  2809. NL_SET_ERR_MSG_MOD(info->extack,
  2810. "Multiselection of limit is not supported");
  2811. return -EOPNOTSUPP;
  2812. }
  2813. if (!devlink_reload_limit_is_supported(devlink, limit)) {
  2814. NL_SET_ERR_MSG_MOD(info->extack,
  2815. "Requested limit is not supported by the driver");
  2816. return -EOPNOTSUPP;
  2817. }
  2818. if (devlink_reload_combination_is_invalid(action, limit)) {
  2819. NL_SET_ERR_MSG_MOD(info->extack,
  2820. "Requested limit is invalid for this action");
  2821. return -EINVAL;
  2822. }
  2823. }
  2824. if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
  2825. info->attrs[DEVLINK_ATTR_NETNS_FD] ||
  2826. info->attrs[DEVLINK_ATTR_NETNS_ID]) {
  2827. dest_net = devlink_netns_get(skb, info);
  2828. if (IS_ERR(dest_net))
  2829. return PTR_ERR(dest_net);
  2830. }
  2831. err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
  2832. if (dest_net)
  2833. put_net(dest_net);
  2834. if (err)
  2835. return err;
  2836. /* For backward compatibility generate reply only if attributes used by user */
  2837. if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
  2838. return 0;
  2839. return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
  2840. DEVLINK_CMD_RELOAD, info);
  2841. }
  2842. static int devlink_nl_flash_update_fill(struct sk_buff *msg,
  2843. struct devlink *devlink,
  2844. enum devlink_command cmd,
  2845. struct devlink_flash_notify *params)
  2846. {
  2847. void *hdr;
  2848. hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
  2849. if (!hdr)
  2850. return -EMSGSIZE;
  2851. if (devlink_nl_put_handle(msg, devlink))
  2852. goto nla_put_failure;
  2853. if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
  2854. goto out;
  2855. if (params->status_msg &&
  2856. nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
  2857. params->status_msg))
  2858. goto nla_put_failure;
  2859. if (params->component &&
  2860. nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
  2861. params->component))
  2862. goto nla_put_failure;
  2863. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
  2864. params->done, DEVLINK_ATTR_PAD))
  2865. goto nla_put_failure;
  2866. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
  2867. params->total, DEVLINK_ATTR_PAD))
  2868. goto nla_put_failure;
  2869. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT,
  2870. params->timeout, DEVLINK_ATTR_PAD))
  2871. goto nla_put_failure;
  2872. out:
  2873. genlmsg_end(msg, hdr);
  2874. return 0;
  2875. nla_put_failure:
  2876. genlmsg_cancel(msg, hdr);
  2877. return -EMSGSIZE;
  2878. }
  2879. static void __devlink_flash_update_notify(struct devlink *devlink,
  2880. enum devlink_command cmd,
  2881. struct devlink_flash_notify *params)
  2882. {
  2883. struct sk_buff *msg;
  2884. int err;
  2885. WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
  2886. cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
  2887. cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
  2888. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  2889. if (!msg)
  2890. return;
  2891. err = devlink_nl_flash_update_fill(msg, devlink, cmd, params);
  2892. if (err)
  2893. goto out_free_msg;
  2894. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  2895. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  2896. return;
  2897. out_free_msg:
  2898. nlmsg_free(msg);
  2899. }
  2900. void devlink_flash_update_begin_notify(struct devlink *devlink)
  2901. {
  2902. struct devlink_flash_notify params = {};
  2903. __devlink_flash_update_notify(devlink,
  2904. DEVLINK_CMD_FLASH_UPDATE,
  2905. &params);
  2906. }
  2907. EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify);
  2908. void devlink_flash_update_end_notify(struct devlink *devlink)
  2909. {
  2910. struct devlink_flash_notify params = {};
  2911. __devlink_flash_update_notify(devlink,
  2912. DEVLINK_CMD_FLASH_UPDATE_END,
  2913. &params);
  2914. }
  2915. EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify);
  2916. void devlink_flash_update_status_notify(struct devlink *devlink,
  2917. const char *status_msg,
  2918. const char *component,
  2919. unsigned long done,
  2920. unsigned long total)
  2921. {
  2922. struct devlink_flash_notify params = {
  2923. .status_msg = status_msg,
  2924. .component = component,
  2925. .done = done,
  2926. .total = total,
  2927. };
  2928. __devlink_flash_update_notify(devlink,
  2929. DEVLINK_CMD_FLASH_UPDATE_STATUS,
  2930. &params);
  2931. }
  2932. EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
  2933. void devlink_flash_update_timeout_notify(struct devlink *devlink,
  2934. const char *status_msg,
  2935. const char *component,
  2936. unsigned long timeout)
  2937. {
  2938. struct devlink_flash_notify params = {
  2939. .status_msg = status_msg,
  2940. .component = component,
  2941. .timeout = timeout,
  2942. };
  2943. __devlink_flash_update_notify(devlink,
  2944. DEVLINK_CMD_FLASH_UPDATE_STATUS,
  2945. &params);
  2946. }
  2947. EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
  2948. static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
  2949. struct genl_info *info)
  2950. {
  2951. struct nlattr *nla_component, *nla_overwrite_mask;
  2952. struct devlink_flash_update_params params = {};
  2953. struct devlink *devlink = info->user_ptr[0];
  2954. u32 supported_params;
  2955. if (!devlink->ops->flash_update)
  2956. return -EOPNOTSUPP;
  2957. if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
  2958. return -EINVAL;
  2959. supported_params = devlink->ops->supported_flash_update_params;
  2960. params.file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
  2961. nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
  2962. if (nla_component) {
  2963. if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT)) {
  2964. NL_SET_ERR_MSG_ATTR(info->extack, nla_component,
  2965. "component update is not supported by this device");
  2966. return -EOPNOTSUPP;
  2967. }
  2968. params.component = nla_data(nla_component);
  2969. }
  2970. nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
  2971. if (nla_overwrite_mask) {
  2972. struct nla_bitfield32 sections;
  2973. if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
  2974. NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask,
  2975. "overwrite settings are not supported by this device");
  2976. return -EOPNOTSUPP;
  2977. }
  2978. sections = nla_get_bitfield32(nla_overwrite_mask);
  2979. params.overwrite_mask = sections.value & sections.selector;
  2980. }
  2981. return devlink->ops->flash_update(devlink, &params, info->extack);
  2982. }
  2983. static const struct devlink_param devlink_param_generic[] = {
  2984. {
  2985. .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
  2986. .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
  2987. .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
  2988. },
  2989. {
  2990. .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
  2991. .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
  2992. .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
  2993. },
  2994. {
  2995. .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
  2996. .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
  2997. .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
  2998. },
  2999. {
  3000. .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
  3001. .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
  3002. .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
  3003. },
  3004. {
  3005. .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
  3006. .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
  3007. .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
  3008. },
  3009. {
  3010. .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
  3011. .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
  3012. .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
  3013. },
  3014. {
  3015. .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
  3016. .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
  3017. .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
  3018. },
  3019. {
  3020. .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
  3021. .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
  3022. .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
  3023. },
  3024. {
  3025. .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
  3026. .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
  3027. .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
  3028. },
  3029. {
  3030. .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
  3031. .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
  3032. .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
  3033. },
  3034. {
  3035. .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
  3036. .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
  3037. .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
  3038. },
  3039. };
  3040. static int devlink_param_generic_verify(const struct devlink_param *param)
  3041. {
  3042. /* verify it match generic parameter by id and name */
  3043. if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
  3044. return -EINVAL;
  3045. if (strcmp(param->name, devlink_param_generic[param->id].name))
  3046. return -ENOENT;
  3047. WARN_ON(param->type != devlink_param_generic[param->id].type);
  3048. return 0;
  3049. }
  3050. static int devlink_param_driver_verify(const struct devlink_param *param)
  3051. {
  3052. int i;
  3053. if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
  3054. return -EINVAL;
  3055. /* verify no such name in generic params */
  3056. for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
  3057. if (!strcmp(param->name, devlink_param_generic[i].name))
  3058. return -EEXIST;
  3059. return 0;
  3060. }
  3061. static struct devlink_param_item *
  3062. devlink_param_find_by_name(struct list_head *param_list,
  3063. const char *param_name)
  3064. {
  3065. struct devlink_param_item *param_item;
  3066. list_for_each_entry(param_item, param_list, list)
  3067. if (!strcmp(param_item->param->name, param_name))
  3068. return param_item;
  3069. return NULL;
  3070. }
  3071. static struct devlink_param_item *
  3072. devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
  3073. {
  3074. struct devlink_param_item *param_item;
  3075. list_for_each_entry(param_item, param_list, list)
  3076. if (param_item->param->id == param_id)
  3077. return param_item;
  3078. return NULL;
  3079. }
  3080. static bool
  3081. devlink_param_cmode_is_supported(const struct devlink_param *param,
  3082. enum devlink_param_cmode cmode)
  3083. {
  3084. return test_bit(cmode, &param->supported_cmodes);
  3085. }
  3086. static int devlink_param_get(struct devlink *devlink,
  3087. const struct devlink_param *param,
  3088. struct devlink_param_gset_ctx *ctx)
  3089. {
  3090. if (!param->get)
  3091. return -EOPNOTSUPP;
  3092. return param->get(devlink, param->id, ctx);
  3093. }
  3094. static int devlink_param_set(struct devlink *devlink,
  3095. const struct devlink_param *param,
  3096. struct devlink_param_gset_ctx *ctx)
  3097. {
  3098. if (!param->set)
  3099. return -EOPNOTSUPP;
  3100. return param->set(devlink, param->id, ctx);
  3101. }
  3102. static int
  3103. devlink_param_type_to_nla_type(enum devlink_param_type param_type)
  3104. {
  3105. switch (param_type) {
  3106. case DEVLINK_PARAM_TYPE_U8:
  3107. return NLA_U8;
  3108. case DEVLINK_PARAM_TYPE_U16:
  3109. return NLA_U16;
  3110. case DEVLINK_PARAM_TYPE_U32:
  3111. return NLA_U32;
  3112. case DEVLINK_PARAM_TYPE_STRING:
  3113. return NLA_STRING;
  3114. case DEVLINK_PARAM_TYPE_BOOL:
  3115. return NLA_FLAG;
  3116. default:
  3117. return -EINVAL;
  3118. }
  3119. }
  3120. static int
  3121. devlink_nl_param_value_fill_one(struct sk_buff *msg,
  3122. enum devlink_param_type type,
  3123. enum devlink_param_cmode cmode,
  3124. union devlink_param_value val)
  3125. {
  3126. struct nlattr *param_value_attr;
  3127. param_value_attr = nla_nest_start_noflag(msg,
  3128. DEVLINK_ATTR_PARAM_VALUE);
  3129. if (!param_value_attr)
  3130. goto nla_put_failure;
  3131. if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
  3132. goto value_nest_cancel;
  3133. switch (type) {
  3134. case DEVLINK_PARAM_TYPE_U8:
  3135. if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
  3136. goto value_nest_cancel;
  3137. break;
  3138. case DEVLINK_PARAM_TYPE_U16:
  3139. if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
  3140. goto value_nest_cancel;
  3141. break;
  3142. case DEVLINK_PARAM_TYPE_U32:
  3143. if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
  3144. goto value_nest_cancel;
  3145. break;
  3146. case DEVLINK_PARAM_TYPE_STRING:
  3147. if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
  3148. val.vstr))
  3149. goto value_nest_cancel;
  3150. break;
  3151. case DEVLINK_PARAM_TYPE_BOOL:
  3152. if (val.vbool &&
  3153. nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
  3154. goto value_nest_cancel;
  3155. break;
  3156. }
  3157. nla_nest_end(msg, param_value_attr);
  3158. return 0;
  3159. value_nest_cancel:
  3160. nla_nest_cancel(msg, param_value_attr);
  3161. nla_put_failure:
  3162. return -EMSGSIZE;
  3163. }
  3164. static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
  3165. unsigned int port_index,
  3166. struct devlink_param_item *param_item,
  3167. enum devlink_command cmd,
  3168. u32 portid, u32 seq, int flags)
  3169. {
  3170. union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
  3171. bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
  3172. const struct devlink_param *param = param_item->param;
  3173. struct devlink_param_gset_ctx ctx;
  3174. struct nlattr *param_values_list;
  3175. struct nlattr *param_attr;
  3176. int nla_type;
  3177. void *hdr;
  3178. int err;
  3179. int i;
  3180. /* Get value from driver part to driverinit configuration mode */
  3181. for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
  3182. if (!devlink_param_cmode_is_supported(param, i))
  3183. continue;
  3184. if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
  3185. if (!param_item->driverinit_value_valid)
  3186. return -EOPNOTSUPP;
  3187. param_value[i] = param_item->driverinit_value;
  3188. } else {
  3189. if (!param_item->published)
  3190. continue;
  3191. ctx.cmode = i;
  3192. err = devlink_param_get(devlink, param, &ctx);
  3193. if (err)
  3194. return err;
  3195. param_value[i] = ctx.val;
  3196. }
  3197. param_value_set[i] = true;
  3198. }
  3199. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  3200. if (!hdr)
  3201. return -EMSGSIZE;
  3202. if (devlink_nl_put_handle(msg, devlink))
  3203. goto genlmsg_cancel;
  3204. if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
  3205. cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
  3206. cmd == DEVLINK_CMD_PORT_PARAM_DEL)
  3207. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
  3208. goto genlmsg_cancel;
  3209. param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
  3210. if (!param_attr)
  3211. goto genlmsg_cancel;
  3212. if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
  3213. goto param_nest_cancel;
  3214. if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
  3215. goto param_nest_cancel;
  3216. nla_type = devlink_param_type_to_nla_type(param->type);
  3217. if (nla_type < 0)
  3218. goto param_nest_cancel;
  3219. if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
  3220. goto param_nest_cancel;
  3221. param_values_list = nla_nest_start_noflag(msg,
  3222. DEVLINK_ATTR_PARAM_VALUES_LIST);
  3223. if (!param_values_list)
  3224. goto param_nest_cancel;
  3225. for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
  3226. if (!param_value_set[i])
  3227. continue;
  3228. err = devlink_nl_param_value_fill_one(msg, param->type,
  3229. i, param_value[i]);
  3230. if (err)
  3231. goto values_list_nest_cancel;
  3232. }
  3233. nla_nest_end(msg, param_values_list);
  3234. nla_nest_end(msg, param_attr);
  3235. genlmsg_end(msg, hdr);
  3236. return 0;
  3237. values_list_nest_cancel:
  3238. nla_nest_end(msg, param_values_list);
  3239. param_nest_cancel:
  3240. nla_nest_cancel(msg, param_attr);
  3241. genlmsg_cancel:
  3242. genlmsg_cancel(msg, hdr);
  3243. return -EMSGSIZE;
  3244. }
  3245. static void devlink_param_notify(struct devlink *devlink,
  3246. unsigned int port_index,
  3247. struct devlink_param_item *param_item,
  3248. enum devlink_command cmd)
  3249. {
  3250. struct sk_buff *msg;
  3251. int err;
  3252. WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
  3253. cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
  3254. cmd != DEVLINK_CMD_PORT_PARAM_DEL);
  3255. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  3256. if (!msg)
  3257. return;
  3258. err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
  3259. 0, 0, 0);
  3260. if (err) {
  3261. nlmsg_free(msg);
  3262. return;
  3263. }
  3264. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  3265. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  3266. }
  3267. static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
  3268. struct netlink_callback *cb)
  3269. {
  3270. struct devlink_param_item *param_item;
  3271. struct devlink *devlink;
  3272. int start = cb->args[0];
  3273. int idx = 0;
  3274. int err = 0;
  3275. mutex_lock(&devlink_mutex);
  3276. list_for_each_entry(devlink, &devlink_list, list) {
  3277. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  3278. continue;
  3279. mutex_lock(&devlink->lock);
  3280. list_for_each_entry(param_item, &devlink->param_list, list) {
  3281. if (idx < start) {
  3282. idx++;
  3283. continue;
  3284. }
  3285. err = devlink_nl_param_fill(msg, devlink, 0, param_item,
  3286. DEVLINK_CMD_PARAM_GET,
  3287. NETLINK_CB(cb->skb).portid,
  3288. cb->nlh->nlmsg_seq,
  3289. NLM_F_MULTI);
  3290. if (err == -EOPNOTSUPP) {
  3291. err = 0;
  3292. } else if (err) {
  3293. mutex_unlock(&devlink->lock);
  3294. goto out;
  3295. }
  3296. idx++;
  3297. }
  3298. mutex_unlock(&devlink->lock);
  3299. }
  3300. out:
  3301. mutex_unlock(&devlink_mutex);
  3302. if (err != -EMSGSIZE)
  3303. return err;
  3304. cb->args[0] = idx;
  3305. return msg->len;
  3306. }
  3307. static int
  3308. devlink_param_type_get_from_info(struct genl_info *info,
  3309. enum devlink_param_type *param_type)
  3310. {
  3311. if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
  3312. return -EINVAL;
  3313. switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
  3314. case NLA_U8:
  3315. *param_type = DEVLINK_PARAM_TYPE_U8;
  3316. break;
  3317. case NLA_U16:
  3318. *param_type = DEVLINK_PARAM_TYPE_U16;
  3319. break;
  3320. case NLA_U32:
  3321. *param_type = DEVLINK_PARAM_TYPE_U32;
  3322. break;
  3323. case NLA_STRING:
  3324. *param_type = DEVLINK_PARAM_TYPE_STRING;
  3325. break;
  3326. case NLA_FLAG:
  3327. *param_type = DEVLINK_PARAM_TYPE_BOOL;
  3328. break;
  3329. default:
  3330. return -EINVAL;
  3331. }
  3332. return 0;
  3333. }
  3334. static int
  3335. devlink_param_value_get_from_info(const struct devlink_param *param,
  3336. struct genl_info *info,
  3337. union devlink_param_value *value)
  3338. {
  3339. struct nlattr *param_data;
  3340. int len;
  3341. param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
  3342. if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
  3343. return -EINVAL;
  3344. switch (param->type) {
  3345. case DEVLINK_PARAM_TYPE_U8:
  3346. if (nla_len(param_data) != sizeof(u8))
  3347. return -EINVAL;
  3348. value->vu8 = nla_get_u8(param_data);
  3349. break;
  3350. case DEVLINK_PARAM_TYPE_U16:
  3351. if (nla_len(param_data) != sizeof(u16))
  3352. return -EINVAL;
  3353. value->vu16 = nla_get_u16(param_data);
  3354. break;
  3355. case DEVLINK_PARAM_TYPE_U32:
  3356. if (nla_len(param_data) != sizeof(u32))
  3357. return -EINVAL;
  3358. value->vu32 = nla_get_u32(param_data);
  3359. break;
  3360. case DEVLINK_PARAM_TYPE_STRING:
  3361. len = strnlen(nla_data(param_data), nla_len(param_data));
  3362. if (len == nla_len(param_data) ||
  3363. len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
  3364. return -EINVAL;
  3365. strcpy(value->vstr, nla_data(param_data));
  3366. break;
  3367. case DEVLINK_PARAM_TYPE_BOOL:
  3368. if (param_data && nla_len(param_data))
  3369. return -EINVAL;
  3370. value->vbool = nla_get_flag(param_data);
  3371. break;
  3372. }
  3373. return 0;
  3374. }
  3375. static struct devlink_param_item *
  3376. devlink_param_get_from_info(struct list_head *param_list,
  3377. struct genl_info *info)
  3378. {
  3379. char *param_name;
  3380. if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
  3381. return NULL;
  3382. param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
  3383. return devlink_param_find_by_name(param_list, param_name);
  3384. }
  3385. static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
  3386. struct genl_info *info)
  3387. {
  3388. struct devlink *devlink = info->user_ptr[0];
  3389. struct devlink_param_item *param_item;
  3390. struct sk_buff *msg;
  3391. int err;
  3392. param_item = devlink_param_get_from_info(&devlink->param_list, info);
  3393. if (!param_item)
  3394. return -EINVAL;
  3395. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  3396. if (!msg)
  3397. return -ENOMEM;
  3398. err = devlink_nl_param_fill(msg, devlink, 0, param_item,
  3399. DEVLINK_CMD_PARAM_GET,
  3400. info->snd_portid, info->snd_seq, 0);
  3401. if (err) {
  3402. nlmsg_free(msg);
  3403. return err;
  3404. }
  3405. return genlmsg_reply(msg, info);
  3406. }
  3407. static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
  3408. unsigned int port_index,
  3409. struct list_head *param_list,
  3410. struct genl_info *info,
  3411. enum devlink_command cmd)
  3412. {
  3413. enum devlink_param_type param_type;
  3414. struct devlink_param_gset_ctx ctx;
  3415. enum devlink_param_cmode cmode;
  3416. struct devlink_param_item *param_item;
  3417. const struct devlink_param *param;
  3418. union devlink_param_value value;
  3419. int err = 0;
  3420. param_item = devlink_param_get_from_info(param_list, info);
  3421. if (!param_item)
  3422. return -EINVAL;
  3423. param = param_item->param;
  3424. err = devlink_param_type_get_from_info(info, &param_type);
  3425. if (err)
  3426. return err;
  3427. if (param_type != param->type)
  3428. return -EINVAL;
  3429. err = devlink_param_value_get_from_info(param, info, &value);
  3430. if (err)
  3431. return err;
  3432. if (param->validate) {
  3433. err = param->validate(devlink, param->id, value, info->extack);
  3434. if (err)
  3435. return err;
  3436. }
  3437. if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
  3438. return -EINVAL;
  3439. cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
  3440. if (!devlink_param_cmode_is_supported(param, cmode))
  3441. return -EOPNOTSUPP;
  3442. if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
  3443. if (param->type == DEVLINK_PARAM_TYPE_STRING)
  3444. strcpy(param_item->driverinit_value.vstr, value.vstr);
  3445. else
  3446. param_item->driverinit_value = value;
  3447. param_item->driverinit_value_valid = true;
  3448. } else {
  3449. if (!param->set)
  3450. return -EOPNOTSUPP;
  3451. ctx.val = value;
  3452. ctx.cmode = cmode;
  3453. err = devlink_param_set(devlink, param, &ctx);
  3454. if (err)
  3455. return err;
  3456. }
  3457. devlink_param_notify(devlink, port_index, param_item, cmd);
  3458. return 0;
  3459. }
  3460. static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
  3461. struct genl_info *info)
  3462. {
  3463. struct devlink *devlink = info->user_ptr[0];
  3464. return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
  3465. info, DEVLINK_CMD_PARAM_NEW);
  3466. }
  3467. static int devlink_param_register_one(struct devlink *devlink,
  3468. unsigned int port_index,
  3469. struct list_head *param_list,
  3470. const struct devlink_param *param,
  3471. enum devlink_command cmd)
  3472. {
  3473. struct devlink_param_item *param_item;
  3474. if (devlink_param_find_by_name(param_list, param->name))
  3475. return -EEXIST;
  3476. if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
  3477. WARN_ON(param->get || param->set);
  3478. else
  3479. WARN_ON(!param->get || !param->set);
  3480. param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
  3481. if (!param_item)
  3482. return -ENOMEM;
  3483. param_item->param = param;
  3484. list_add_tail(&param_item->list, param_list);
  3485. devlink_param_notify(devlink, port_index, param_item, cmd);
  3486. return 0;
  3487. }
  3488. static void devlink_param_unregister_one(struct devlink *devlink,
  3489. unsigned int port_index,
  3490. struct list_head *param_list,
  3491. const struct devlink_param *param,
  3492. enum devlink_command cmd)
  3493. {
  3494. struct devlink_param_item *param_item;
  3495. param_item = devlink_param_find_by_name(param_list, param->name);
  3496. WARN_ON(!param_item);
  3497. devlink_param_notify(devlink, port_index, param_item, cmd);
  3498. list_del(&param_item->list);
  3499. kfree(param_item);
  3500. }
  3501. static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
  3502. struct netlink_callback *cb)
  3503. {
  3504. struct devlink_param_item *param_item;
  3505. struct devlink_port *devlink_port;
  3506. struct devlink *devlink;
  3507. int start = cb->args[0];
  3508. int idx = 0;
  3509. int err = 0;
  3510. mutex_lock(&devlink_mutex);
  3511. list_for_each_entry(devlink, &devlink_list, list) {
  3512. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  3513. continue;
  3514. mutex_lock(&devlink->lock);
  3515. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  3516. list_for_each_entry(param_item,
  3517. &devlink_port->param_list, list) {
  3518. if (idx < start) {
  3519. idx++;
  3520. continue;
  3521. }
  3522. err = devlink_nl_param_fill(msg,
  3523. devlink_port->devlink,
  3524. devlink_port->index, param_item,
  3525. DEVLINK_CMD_PORT_PARAM_GET,
  3526. NETLINK_CB(cb->skb).portid,
  3527. cb->nlh->nlmsg_seq,
  3528. NLM_F_MULTI);
  3529. if (err == -EOPNOTSUPP) {
  3530. err = 0;
  3531. } else if (err) {
  3532. mutex_unlock(&devlink->lock);
  3533. goto out;
  3534. }
  3535. idx++;
  3536. }
  3537. }
  3538. mutex_unlock(&devlink->lock);
  3539. }
  3540. out:
  3541. mutex_unlock(&devlink_mutex);
  3542. if (err != -EMSGSIZE)
  3543. return err;
  3544. cb->args[0] = idx;
  3545. return msg->len;
  3546. }
  3547. static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
  3548. struct genl_info *info)
  3549. {
  3550. struct devlink_port *devlink_port = info->user_ptr[1];
  3551. struct devlink_param_item *param_item;
  3552. struct sk_buff *msg;
  3553. int err;
  3554. param_item = devlink_param_get_from_info(&devlink_port->param_list,
  3555. info);
  3556. if (!param_item)
  3557. return -EINVAL;
  3558. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  3559. if (!msg)
  3560. return -ENOMEM;
  3561. err = devlink_nl_param_fill(msg, devlink_port->devlink,
  3562. devlink_port->index, param_item,
  3563. DEVLINK_CMD_PORT_PARAM_GET,
  3564. info->snd_portid, info->snd_seq, 0);
  3565. if (err) {
  3566. nlmsg_free(msg);
  3567. return err;
  3568. }
  3569. return genlmsg_reply(msg, info);
  3570. }
  3571. static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
  3572. struct genl_info *info)
  3573. {
  3574. struct devlink_port *devlink_port = info->user_ptr[1];
  3575. return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
  3576. devlink_port->index,
  3577. &devlink_port->param_list, info,
  3578. DEVLINK_CMD_PORT_PARAM_NEW);
  3579. }
  3580. static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
  3581. struct devlink *devlink,
  3582. struct devlink_snapshot *snapshot)
  3583. {
  3584. struct nlattr *snap_attr;
  3585. int err;
  3586. snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
  3587. if (!snap_attr)
  3588. return -EINVAL;
  3589. err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
  3590. if (err)
  3591. goto nla_put_failure;
  3592. nla_nest_end(msg, snap_attr);
  3593. return 0;
  3594. nla_put_failure:
  3595. nla_nest_cancel(msg, snap_attr);
  3596. return err;
  3597. }
  3598. static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
  3599. struct devlink *devlink,
  3600. struct devlink_region *region)
  3601. {
  3602. struct devlink_snapshot *snapshot;
  3603. struct nlattr *snapshots_attr;
  3604. int err;
  3605. snapshots_attr = nla_nest_start_noflag(msg,
  3606. DEVLINK_ATTR_REGION_SNAPSHOTS);
  3607. if (!snapshots_attr)
  3608. return -EINVAL;
  3609. list_for_each_entry(snapshot, &region->snapshot_list, list) {
  3610. err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
  3611. if (err)
  3612. goto nla_put_failure;
  3613. }
  3614. nla_nest_end(msg, snapshots_attr);
  3615. return 0;
  3616. nla_put_failure:
  3617. nla_nest_cancel(msg, snapshots_attr);
  3618. return err;
  3619. }
  3620. static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
  3621. enum devlink_command cmd, u32 portid,
  3622. u32 seq, int flags,
  3623. struct devlink_region *region)
  3624. {
  3625. void *hdr;
  3626. int err;
  3627. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  3628. if (!hdr)
  3629. return -EMSGSIZE;
  3630. err = devlink_nl_put_handle(msg, devlink);
  3631. if (err)
  3632. goto nla_put_failure;
  3633. if (region->port) {
  3634. err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
  3635. region->port->index);
  3636. if (err)
  3637. goto nla_put_failure;
  3638. }
  3639. err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
  3640. if (err)
  3641. goto nla_put_failure;
  3642. err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
  3643. region->size,
  3644. DEVLINK_ATTR_PAD);
  3645. if (err)
  3646. goto nla_put_failure;
  3647. err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
  3648. if (err)
  3649. goto nla_put_failure;
  3650. genlmsg_end(msg, hdr);
  3651. return 0;
  3652. nla_put_failure:
  3653. genlmsg_cancel(msg, hdr);
  3654. return err;
  3655. }
  3656. static struct sk_buff *
  3657. devlink_nl_region_notify_build(struct devlink_region *region,
  3658. struct devlink_snapshot *snapshot,
  3659. enum devlink_command cmd, u32 portid, u32 seq)
  3660. {
  3661. struct devlink *devlink = region->devlink;
  3662. struct sk_buff *msg;
  3663. void *hdr;
  3664. int err;
  3665. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  3666. if (!msg)
  3667. return ERR_PTR(-ENOMEM);
  3668. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
  3669. if (!hdr) {
  3670. err = -EMSGSIZE;
  3671. goto out_free_msg;
  3672. }
  3673. err = devlink_nl_put_handle(msg, devlink);
  3674. if (err)
  3675. goto out_cancel_msg;
  3676. if (region->port) {
  3677. err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
  3678. region->port->index);
  3679. if (err)
  3680. goto out_cancel_msg;
  3681. }
  3682. err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
  3683. region->ops->name);
  3684. if (err)
  3685. goto out_cancel_msg;
  3686. if (snapshot) {
  3687. err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
  3688. snapshot->id);
  3689. if (err)
  3690. goto out_cancel_msg;
  3691. } else {
  3692. err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
  3693. region->size, DEVLINK_ATTR_PAD);
  3694. if (err)
  3695. goto out_cancel_msg;
  3696. }
  3697. genlmsg_end(msg, hdr);
  3698. return msg;
  3699. out_cancel_msg:
  3700. genlmsg_cancel(msg, hdr);
  3701. out_free_msg:
  3702. nlmsg_free(msg);
  3703. return ERR_PTR(err);
  3704. }
  3705. static void devlink_nl_region_notify(struct devlink_region *region,
  3706. struct devlink_snapshot *snapshot,
  3707. enum devlink_command cmd)
  3708. {
  3709. struct devlink *devlink = region->devlink;
  3710. struct sk_buff *msg;
  3711. WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
  3712. msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
  3713. if (IS_ERR(msg))
  3714. return;
  3715. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  3716. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  3717. }
  3718. /**
  3719. * __devlink_snapshot_id_increment - Increment number of snapshots using an id
  3720. * @devlink: devlink instance
  3721. * @id: the snapshot id
  3722. *
  3723. * Track when a new snapshot begins using an id. Load the count for the
  3724. * given id from the snapshot xarray, increment it, and store it back.
  3725. *
  3726. * Called when a new snapshot is created with the given id.
  3727. *
  3728. * The id *must* have been previously allocated by
  3729. * devlink_region_snapshot_id_get().
  3730. *
  3731. * Returns 0 on success, or an error on failure.
  3732. */
  3733. static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
  3734. {
  3735. unsigned long count;
  3736. void *p;
  3737. lockdep_assert_held(&devlink->lock);
  3738. p = xa_load(&devlink->snapshot_ids, id);
  3739. if (WARN_ON(!p))
  3740. return -EINVAL;
  3741. if (WARN_ON(!xa_is_value(p)))
  3742. return -EINVAL;
  3743. count = xa_to_value(p);
  3744. count++;
  3745. return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
  3746. GFP_KERNEL));
  3747. }
  3748. /**
  3749. * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
  3750. * @devlink: devlink instance
  3751. * @id: the snapshot id
  3752. *
  3753. * Track when a snapshot is deleted and stops using an id. Load the count
  3754. * for the given id from the snapshot xarray, decrement it, and store it
  3755. * back.
  3756. *
  3757. * If the count reaches zero, erase this id from the xarray, freeing it
  3758. * up for future re-use by devlink_region_snapshot_id_get().
  3759. *
  3760. * Called when a snapshot using the given id is deleted, and when the
  3761. * initial allocator of the id is finished using it.
  3762. */
  3763. static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
  3764. {
  3765. unsigned long count;
  3766. void *p;
  3767. lockdep_assert_held(&devlink->lock);
  3768. p = xa_load(&devlink->snapshot_ids, id);
  3769. if (WARN_ON(!p))
  3770. return;
  3771. if (WARN_ON(!xa_is_value(p)))
  3772. return;
  3773. count = xa_to_value(p);
  3774. if (count > 1) {
  3775. count--;
  3776. xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
  3777. GFP_KERNEL);
  3778. } else {
  3779. /* If this was the last user, we can erase this id */
  3780. xa_erase(&devlink->snapshot_ids, id);
  3781. }
  3782. }
  3783. /**
  3784. * __devlink_snapshot_id_insert - Insert a specific snapshot ID
  3785. * @devlink: devlink instance
  3786. * @id: the snapshot id
  3787. *
  3788. * Mark the given snapshot id as used by inserting a zero value into the
  3789. * snapshot xarray.
  3790. *
  3791. * This must be called while holding the devlink instance lock. Unlike
  3792. * devlink_snapshot_id_get, the initial reference count is zero, not one.
  3793. * It is expected that the id will immediately be used before
  3794. * releasing the devlink instance lock.
  3795. *
  3796. * Returns zero on success, or an error code if the snapshot id could not
  3797. * be inserted.
  3798. */
  3799. static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
  3800. {
  3801. lockdep_assert_held(&devlink->lock);
  3802. if (xa_load(&devlink->snapshot_ids, id))
  3803. return -EEXIST;
  3804. return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
  3805. GFP_KERNEL));
  3806. }
  3807. /**
  3808. * __devlink_region_snapshot_id_get - get snapshot ID
  3809. * @devlink: devlink instance
  3810. * @id: storage to return snapshot id
  3811. *
  3812. * Allocates a new snapshot id. Returns zero on success, or a negative
  3813. * error on failure. Must be called while holding the devlink instance
  3814. * lock.
  3815. *
  3816. * Snapshot IDs are tracked using an xarray which stores the number of
  3817. * users of the snapshot id.
  3818. *
  3819. * Note that the caller of this function counts as a 'user', in order to
  3820. * avoid race conditions. The caller must release its hold on the
  3821. * snapshot by using devlink_region_snapshot_id_put.
  3822. */
  3823. static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
  3824. {
  3825. lockdep_assert_held(&devlink->lock);
  3826. return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
  3827. xa_limit_32b, GFP_KERNEL);
  3828. }
  3829. /**
  3830. * __devlink_region_snapshot_create - create a new snapshot
  3831. * This will add a new snapshot of a region. The snapshot
  3832. * will be stored on the region struct and can be accessed
  3833. * from devlink. This is useful for future analyses of snapshots.
  3834. * Multiple snapshots can be created on a region.
  3835. * The @snapshot_id should be obtained using the getter function.
  3836. *
  3837. * Must be called only while holding the devlink instance lock.
  3838. *
  3839. * @region: devlink region of the snapshot
  3840. * @data: snapshot data
  3841. * @snapshot_id: snapshot id to be created
  3842. */
  3843. static int
  3844. __devlink_region_snapshot_create(struct devlink_region *region,
  3845. u8 *data, u32 snapshot_id)
  3846. {
  3847. struct devlink *devlink = region->devlink;
  3848. struct devlink_snapshot *snapshot;
  3849. int err;
  3850. lockdep_assert_held(&devlink->lock);
  3851. /* check if region can hold one more snapshot */
  3852. if (region->cur_snapshots == region->max_snapshots)
  3853. return -ENOSPC;
  3854. if (devlink_region_snapshot_get_by_id(region, snapshot_id))
  3855. return -EEXIST;
  3856. snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
  3857. if (!snapshot)
  3858. return -ENOMEM;
  3859. err = __devlink_snapshot_id_increment(devlink, snapshot_id);
  3860. if (err)
  3861. goto err_snapshot_id_increment;
  3862. snapshot->id = snapshot_id;
  3863. snapshot->region = region;
  3864. snapshot->data = data;
  3865. list_add_tail(&snapshot->list, &region->snapshot_list);
  3866. region->cur_snapshots++;
  3867. devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
  3868. return 0;
  3869. err_snapshot_id_increment:
  3870. kfree(snapshot);
  3871. return err;
  3872. }
  3873. static void devlink_region_snapshot_del(struct devlink_region *region,
  3874. struct devlink_snapshot *snapshot)
  3875. {
  3876. struct devlink *devlink = region->devlink;
  3877. lockdep_assert_held(&devlink->lock);
  3878. devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
  3879. region->cur_snapshots--;
  3880. list_del(&snapshot->list);
  3881. region->ops->destructor(snapshot->data);
  3882. __devlink_snapshot_id_decrement(devlink, snapshot->id);
  3883. kfree(snapshot);
  3884. }
  3885. static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
  3886. struct genl_info *info)
  3887. {
  3888. struct devlink *devlink = info->user_ptr[0];
  3889. struct devlink_port *port = NULL;
  3890. struct devlink_region *region;
  3891. const char *region_name;
  3892. struct sk_buff *msg;
  3893. unsigned int index;
  3894. int err;
  3895. if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
  3896. return -EINVAL;
  3897. if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
  3898. index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  3899. port = devlink_port_get_by_index(devlink, index);
  3900. if (!port)
  3901. return -ENODEV;
  3902. }
  3903. region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
  3904. if (port)
  3905. region = devlink_port_region_get_by_name(port, region_name);
  3906. else
  3907. region = devlink_region_get_by_name(devlink, region_name);
  3908. if (!region)
  3909. return -EINVAL;
  3910. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  3911. if (!msg)
  3912. return -ENOMEM;
  3913. err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
  3914. info->snd_portid, info->snd_seq, 0,
  3915. region);
  3916. if (err) {
  3917. nlmsg_free(msg);
  3918. return err;
  3919. }
  3920. return genlmsg_reply(msg, info);
  3921. }
  3922. static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
  3923. struct netlink_callback *cb,
  3924. struct devlink_port *port,
  3925. int *idx,
  3926. int start)
  3927. {
  3928. struct devlink_region *region;
  3929. int err = 0;
  3930. list_for_each_entry(region, &port->region_list, list) {
  3931. if (*idx < start) {
  3932. (*idx)++;
  3933. continue;
  3934. }
  3935. err = devlink_nl_region_fill(msg, port->devlink,
  3936. DEVLINK_CMD_REGION_GET,
  3937. NETLINK_CB(cb->skb).portid,
  3938. cb->nlh->nlmsg_seq,
  3939. NLM_F_MULTI, region);
  3940. if (err)
  3941. goto out;
  3942. (*idx)++;
  3943. }
  3944. out:
  3945. return err;
  3946. }
  3947. static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg,
  3948. struct netlink_callback *cb,
  3949. struct devlink *devlink,
  3950. int *idx,
  3951. int start)
  3952. {
  3953. struct devlink_region *region;
  3954. struct devlink_port *port;
  3955. int err = 0;
  3956. mutex_lock(&devlink->lock);
  3957. list_for_each_entry(region, &devlink->region_list, list) {
  3958. if (*idx < start) {
  3959. (*idx)++;
  3960. continue;
  3961. }
  3962. err = devlink_nl_region_fill(msg, devlink,
  3963. DEVLINK_CMD_REGION_GET,
  3964. NETLINK_CB(cb->skb).portid,
  3965. cb->nlh->nlmsg_seq,
  3966. NLM_F_MULTI, region);
  3967. if (err)
  3968. goto out;
  3969. (*idx)++;
  3970. }
  3971. list_for_each_entry(port, &devlink->port_list, list) {
  3972. err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx,
  3973. start);
  3974. if (err)
  3975. goto out;
  3976. }
  3977. out:
  3978. mutex_unlock(&devlink->lock);
  3979. return err;
  3980. }
  3981. static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
  3982. struct netlink_callback *cb)
  3983. {
  3984. struct devlink *devlink;
  3985. int start = cb->args[0];
  3986. int idx = 0;
  3987. int err;
  3988. mutex_lock(&devlink_mutex);
  3989. list_for_each_entry(devlink, &devlink_list, list) {
  3990. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  3991. continue;
  3992. err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink,
  3993. &idx, start);
  3994. if (err)
  3995. goto out;
  3996. }
  3997. out:
  3998. mutex_unlock(&devlink_mutex);
  3999. cb->args[0] = idx;
  4000. return msg->len;
  4001. }
  4002. static int devlink_nl_cmd_region_del(struct sk_buff *skb,
  4003. struct genl_info *info)
  4004. {
  4005. struct devlink *devlink = info->user_ptr[0];
  4006. struct devlink_snapshot *snapshot;
  4007. struct devlink_port *port = NULL;
  4008. struct devlink_region *region;
  4009. const char *region_name;
  4010. unsigned int index;
  4011. u32 snapshot_id;
  4012. if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
  4013. !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
  4014. return -EINVAL;
  4015. region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
  4016. snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
  4017. if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
  4018. index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  4019. port = devlink_port_get_by_index(devlink, index);
  4020. if (!port)
  4021. return -ENODEV;
  4022. }
  4023. if (port)
  4024. region = devlink_port_region_get_by_name(port, region_name);
  4025. else
  4026. region = devlink_region_get_by_name(devlink, region_name);
  4027. if (!region)
  4028. return -EINVAL;
  4029. snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
  4030. if (!snapshot)
  4031. return -EINVAL;
  4032. devlink_region_snapshot_del(region, snapshot);
  4033. return 0;
  4034. }
  4035. static int
  4036. devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
  4037. {
  4038. struct devlink *devlink = info->user_ptr[0];
  4039. struct devlink_snapshot *snapshot;
  4040. struct devlink_port *port = NULL;
  4041. struct nlattr *snapshot_id_attr;
  4042. struct devlink_region *region;
  4043. const char *region_name;
  4044. unsigned int index;
  4045. u32 snapshot_id;
  4046. u8 *data;
  4047. int err;
  4048. if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) {
  4049. NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
  4050. return -EINVAL;
  4051. }
  4052. region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
  4053. if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
  4054. index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  4055. port = devlink_port_get_by_index(devlink, index);
  4056. if (!port)
  4057. return -ENODEV;
  4058. }
  4059. if (port)
  4060. region = devlink_port_region_get_by_name(port, region_name);
  4061. else
  4062. region = devlink_region_get_by_name(devlink, region_name);
  4063. if (!region) {
  4064. NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
  4065. return -EINVAL;
  4066. }
  4067. if (!region->ops->snapshot) {
  4068. NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
  4069. return -EOPNOTSUPP;
  4070. }
  4071. if (region->cur_snapshots == region->max_snapshots) {
  4072. NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
  4073. return -ENOSPC;
  4074. }
  4075. snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
  4076. if (snapshot_id_attr) {
  4077. snapshot_id = nla_get_u32(snapshot_id_attr);
  4078. if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
  4079. NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
  4080. return -EEXIST;
  4081. }
  4082. err = __devlink_snapshot_id_insert(devlink, snapshot_id);
  4083. if (err)
  4084. return err;
  4085. } else {
  4086. err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
  4087. if (err) {
  4088. NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
  4089. return err;
  4090. }
  4091. }
  4092. if (port)
  4093. err = region->port_ops->snapshot(port, region->port_ops,
  4094. info->extack, &data);
  4095. else
  4096. err = region->ops->snapshot(devlink, region->ops,
  4097. info->extack, &data);
  4098. if (err)
  4099. goto err_snapshot_capture;
  4100. err = __devlink_region_snapshot_create(region, data, snapshot_id);
  4101. if (err)
  4102. goto err_snapshot_create;
  4103. if (!snapshot_id_attr) {
  4104. struct sk_buff *msg;
  4105. snapshot = devlink_region_snapshot_get_by_id(region,
  4106. snapshot_id);
  4107. if (WARN_ON(!snapshot))
  4108. return -EINVAL;
  4109. msg = devlink_nl_region_notify_build(region, snapshot,
  4110. DEVLINK_CMD_REGION_NEW,
  4111. info->snd_portid,
  4112. info->snd_seq);
  4113. err = PTR_ERR_OR_ZERO(msg);
  4114. if (err)
  4115. goto err_notify;
  4116. err = genlmsg_reply(msg, info);
  4117. if (err)
  4118. goto err_notify;
  4119. }
  4120. return 0;
  4121. err_snapshot_create:
  4122. region->ops->destructor(data);
  4123. err_snapshot_capture:
  4124. __devlink_snapshot_id_decrement(devlink, snapshot_id);
  4125. return err;
  4126. err_notify:
  4127. devlink_region_snapshot_del(region, snapshot);
  4128. return err;
  4129. }
  4130. static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
  4131. struct devlink *devlink,
  4132. u8 *chunk, u32 chunk_size,
  4133. u64 addr)
  4134. {
  4135. struct nlattr *chunk_attr;
  4136. int err;
  4137. chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
  4138. if (!chunk_attr)
  4139. return -EINVAL;
  4140. err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
  4141. if (err)
  4142. goto nla_put_failure;
  4143. err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
  4144. DEVLINK_ATTR_PAD);
  4145. if (err)
  4146. goto nla_put_failure;
  4147. nla_nest_end(msg, chunk_attr);
  4148. return 0;
  4149. nla_put_failure:
  4150. nla_nest_cancel(msg, chunk_attr);
  4151. return err;
  4152. }
  4153. #define DEVLINK_REGION_READ_CHUNK_SIZE 256
  4154. static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
  4155. struct devlink *devlink,
  4156. struct devlink_region *region,
  4157. struct nlattr **attrs,
  4158. u64 start_offset,
  4159. u64 end_offset,
  4160. u64 *new_offset)
  4161. {
  4162. struct devlink_snapshot *snapshot;
  4163. u64 curr_offset = start_offset;
  4164. u32 snapshot_id;
  4165. int err = 0;
  4166. *new_offset = start_offset;
  4167. snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
  4168. snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
  4169. if (!snapshot)
  4170. return -EINVAL;
  4171. while (curr_offset < end_offset) {
  4172. u32 data_size;
  4173. u8 *data;
  4174. if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
  4175. data_size = end_offset - curr_offset;
  4176. else
  4177. data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
  4178. data = &snapshot->data[curr_offset];
  4179. err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
  4180. data, data_size,
  4181. curr_offset);
  4182. if (err)
  4183. break;
  4184. curr_offset += data_size;
  4185. }
  4186. *new_offset = curr_offset;
  4187. return err;
  4188. }
  4189. static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
  4190. struct netlink_callback *cb)
  4191. {
  4192. const struct genl_dumpit_info *info = genl_dumpit_info(cb);
  4193. u64 ret_offset, start_offset, end_offset = U64_MAX;
  4194. struct nlattr **attrs = info->attrs;
  4195. struct devlink_port *port = NULL;
  4196. struct devlink_region *region;
  4197. struct nlattr *chunks_attr;
  4198. const char *region_name;
  4199. struct devlink *devlink;
  4200. unsigned int index;
  4201. void *hdr;
  4202. int err;
  4203. start_offset = *((u64 *)&cb->args[0]);
  4204. mutex_lock(&devlink_mutex);
  4205. devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
  4206. if (IS_ERR(devlink)) {
  4207. err = PTR_ERR(devlink);
  4208. goto out_dev;
  4209. }
  4210. mutex_lock(&devlink->lock);
  4211. if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
  4212. !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
  4213. err = -EINVAL;
  4214. goto out_unlock;
  4215. }
  4216. if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
  4217. index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  4218. port = devlink_port_get_by_index(devlink, index);
  4219. if (!port) {
  4220. err = -ENODEV;
  4221. goto out_unlock;
  4222. }
  4223. }
  4224. region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
  4225. if (port)
  4226. region = devlink_port_region_get_by_name(port, region_name);
  4227. else
  4228. region = devlink_region_get_by_name(devlink, region_name);
  4229. if (!region) {
  4230. err = -EINVAL;
  4231. goto out_unlock;
  4232. }
  4233. if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
  4234. attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
  4235. if (!start_offset)
  4236. start_offset =
  4237. nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
  4238. end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
  4239. end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
  4240. }
  4241. if (end_offset > region->size)
  4242. end_offset = region->size;
  4243. /* return 0 if there is no further data to read */
  4244. if (start_offset == end_offset) {
  4245. err = 0;
  4246. goto out_unlock;
  4247. }
  4248. hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
  4249. &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
  4250. DEVLINK_CMD_REGION_READ);
  4251. if (!hdr) {
  4252. err = -EMSGSIZE;
  4253. goto out_unlock;
  4254. }
  4255. err = devlink_nl_put_handle(skb, devlink);
  4256. if (err)
  4257. goto nla_put_failure;
  4258. if (region->port) {
  4259. err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
  4260. region->port->index);
  4261. if (err)
  4262. goto nla_put_failure;
  4263. }
  4264. err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
  4265. if (err)
  4266. goto nla_put_failure;
  4267. chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
  4268. if (!chunks_attr) {
  4269. err = -EMSGSIZE;
  4270. goto nla_put_failure;
  4271. }
  4272. err = devlink_nl_region_read_snapshot_fill(skb, devlink,
  4273. region, attrs,
  4274. start_offset,
  4275. end_offset, &ret_offset);
  4276. if (err && err != -EMSGSIZE)
  4277. goto nla_put_failure;
  4278. /* Check if there was any progress done to prevent infinite loop */
  4279. if (ret_offset == start_offset) {
  4280. err = -EINVAL;
  4281. goto nla_put_failure;
  4282. }
  4283. *((u64 *)&cb->args[0]) = ret_offset;
  4284. nla_nest_end(skb, chunks_attr);
  4285. genlmsg_end(skb, hdr);
  4286. mutex_unlock(&devlink->lock);
  4287. mutex_unlock(&devlink_mutex);
  4288. return skb->len;
  4289. nla_put_failure:
  4290. genlmsg_cancel(skb, hdr);
  4291. out_unlock:
  4292. mutex_unlock(&devlink->lock);
  4293. out_dev:
  4294. mutex_unlock(&devlink_mutex);
  4295. return err;
  4296. }
  4297. struct devlink_info_req {
  4298. struct sk_buff *msg;
  4299. };
  4300. int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
  4301. {
  4302. return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
  4303. }
  4304. EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
  4305. int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
  4306. {
  4307. return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
  4308. }
  4309. EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
  4310. int devlink_info_board_serial_number_put(struct devlink_info_req *req,
  4311. const char *bsn)
  4312. {
  4313. return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
  4314. bsn);
  4315. }
  4316. EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
  4317. static int devlink_info_version_put(struct devlink_info_req *req, int attr,
  4318. const char *version_name,
  4319. const char *version_value)
  4320. {
  4321. struct nlattr *nest;
  4322. int err;
  4323. nest = nla_nest_start_noflag(req->msg, attr);
  4324. if (!nest)
  4325. return -EMSGSIZE;
  4326. err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
  4327. version_name);
  4328. if (err)
  4329. goto nla_put_failure;
  4330. err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
  4331. version_value);
  4332. if (err)
  4333. goto nla_put_failure;
  4334. nla_nest_end(req->msg, nest);
  4335. return 0;
  4336. nla_put_failure:
  4337. nla_nest_cancel(req->msg, nest);
  4338. return err;
  4339. }
  4340. int devlink_info_version_fixed_put(struct devlink_info_req *req,
  4341. const char *version_name,
  4342. const char *version_value)
  4343. {
  4344. return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
  4345. version_name, version_value);
  4346. }
  4347. EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
  4348. int devlink_info_version_stored_put(struct devlink_info_req *req,
  4349. const char *version_name,
  4350. const char *version_value)
  4351. {
  4352. return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
  4353. version_name, version_value);
  4354. }
  4355. EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
  4356. int devlink_info_version_running_put(struct devlink_info_req *req,
  4357. const char *version_name,
  4358. const char *version_value)
  4359. {
  4360. return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
  4361. version_name, version_value);
  4362. }
  4363. EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
  4364. static int
  4365. devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
  4366. enum devlink_command cmd, u32 portid,
  4367. u32 seq, int flags, struct netlink_ext_ack *extack)
  4368. {
  4369. struct devlink_info_req req;
  4370. void *hdr;
  4371. int err;
  4372. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  4373. if (!hdr)
  4374. return -EMSGSIZE;
  4375. err = -EMSGSIZE;
  4376. if (devlink_nl_put_handle(msg, devlink))
  4377. goto err_cancel_msg;
  4378. req.msg = msg;
  4379. err = devlink->ops->info_get(devlink, &req, extack);
  4380. if (err)
  4381. goto err_cancel_msg;
  4382. genlmsg_end(msg, hdr);
  4383. return 0;
  4384. err_cancel_msg:
  4385. genlmsg_cancel(msg, hdr);
  4386. return err;
  4387. }
  4388. static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
  4389. struct genl_info *info)
  4390. {
  4391. struct devlink *devlink = info->user_ptr[0];
  4392. struct sk_buff *msg;
  4393. int err;
  4394. if (!devlink->ops->info_get)
  4395. return -EOPNOTSUPP;
  4396. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  4397. if (!msg)
  4398. return -ENOMEM;
  4399. err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
  4400. info->snd_portid, info->snd_seq, 0,
  4401. info->extack);
  4402. if (err) {
  4403. nlmsg_free(msg);
  4404. return err;
  4405. }
  4406. return genlmsg_reply(msg, info);
  4407. }
  4408. static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
  4409. struct netlink_callback *cb)
  4410. {
  4411. struct devlink *devlink;
  4412. int start = cb->args[0];
  4413. int idx = 0;
  4414. int err = 0;
  4415. mutex_lock(&devlink_mutex);
  4416. list_for_each_entry(devlink, &devlink_list, list) {
  4417. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  4418. continue;
  4419. if (idx < start) {
  4420. idx++;
  4421. continue;
  4422. }
  4423. if (!devlink->ops->info_get) {
  4424. idx++;
  4425. continue;
  4426. }
  4427. mutex_lock(&devlink->lock);
  4428. err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
  4429. NETLINK_CB(cb->skb).portid,
  4430. cb->nlh->nlmsg_seq, NLM_F_MULTI,
  4431. cb->extack);
  4432. mutex_unlock(&devlink->lock);
  4433. if (err == -EOPNOTSUPP)
  4434. err = 0;
  4435. else if (err)
  4436. break;
  4437. idx++;
  4438. }
  4439. mutex_unlock(&devlink_mutex);
  4440. if (err != -EMSGSIZE)
  4441. return err;
  4442. cb->args[0] = idx;
  4443. return msg->len;
  4444. }
  4445. struct devlink_fmsg_item {
  4446. struct list_head list;
  4447. int attrtype;
  4448. u8 nla_type;
  4449. u16 len;
  4450. int value[];
  4451. };
  4452. struct devlink_fmsg {
  4453. struct list_head item_list;
  4454. bool putting_binary; /* This flag forces enclosing of binary data
  4455. * in an array brackets. It forces using
  4456. * of designated API:
  4457. * devlink_fmsg_binary_pair_nest_start()
  4458. * devlink_fmsg_binary_pair_nest_end()
  4459. */
  4460. };
  4461. static struct devlink_fmsg *devlink_fmsg_alloc(void)
  4462. {
  4463. struct devlink_fmsg *fmsg;
  4464. fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
  4465. if (!fmsg)
  4466. return NULL;
  4467. INIT_LIST_HEAD(&fmsg->item_list);
  4468. return fmsg;
  4469. }
  4470. static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
  4471. {
  4472. struct devlink_fmsg_item *item, *tmp;
  4473. list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
  4474. list_del(&item->list);
  4475. kfree(item);
  4476. }
  4477. kfree(fmsg);
  4478. }
  4479. static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
  4480. int attrtype)
  4481. {
  4482. struct devlink_fmsg_item *item;
  4483. item = kzalloc(sizeof(*item), GFP_KERNEL);
  4484. if (!item)
  4485. return -ENOMEM;
  4486. item->attrtype = attrtype;
  4487. list_add_tail(&item->list, &fmsg->item_list);
  4488. return 0;
  4489. }
  4490. int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
  4491. {
  4492. if (fmsg->putting_binary)
  4493. return -EINVAL;
  4494. return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
  4495. }
  4496. EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
  4497. static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
  4498. {
  4499. if (fmsg->putting_binary)
  4500. return -EINVAL;
  4501. return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
  4502. }
  4503. int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
  4504. {
  4505. if (fmsg->putting_binary)
  4506. return -EINVAL;
  4507. return devlink_fmsg_nest_end(fmsg);
  4508. }
  4509. EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
  4510. #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
  4511. static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
  4512. {
  4513. struct devlink_fmsg_item *item;
  4514. if (fmsg->putting_binary)
  4515. return -EINVAL;
  4516. if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
  4517. return -EMSGSIZE;
  4518. item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
  4519. if (!item)
  4520. return -ENOMEM;
  4521. item->nla_type = NLA_NUL_STRING;
  4522. item->len = strlen(name) + 1;
  4523. item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
  4524. memcpy(&item->value, name, item->len);
  4525. list_add_tail(&item->list, &fmsg->item_list);
  4526. return 0;
  4527. }
  4528. int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
  4529. {
  4530. int err;
  4531. if (fmsg->putting_binary)
  4532. return -EINVAL;
  4533. err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
  4534. if (err)
  4535. return err;
  4536. err = devlink_fmsg_put_name(fmsg, name);
  4537. if (err)
  4538. return err;
  4539. return 0;
  4540. }
  4541. EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
  4542. int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
  4543. {
  4544. if (fmsg->putting_binary)
  4545. return -EINVAL;
  4546. return devlink_fmsg_nest_end(fmsg);
  4547. }
  4548. EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
  4549. int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
  4550. const char *name)
  4551. {
  4552. int err;
  4553. if (fmsg->putting_binary)
  4554. return -EINVAL;
  4555. err = devlink_fmsg_pair_nest_start(fmsg, name);
  4556. if (err)
  4557. return err;
  4558. err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
  4559. if (err)
  4560. return err;
  4561. return 0;
  4562. }
  4563. EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
  4564. int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
  4565. {
  4566. int err;
  4567. if (fmsg->putting_binary)
  4568. return -EINVAL;
  4569. err = devlink_fmsg_nest_end(fmsg);
  4570. if (err)
  4571. return err;
  4572. err = devlink_fmsg_nest_end(fmsg);
  4573. if (err)
  4574. return err;
  4575. return 0;
  4576. }
  4577. EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
  4578. int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
  4579. const char *name)
  4580. {
  4581. int err;
  4582. err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
  4583. if (err)
  4584. return err;
  4585. fmsg->putting_binary = true;
  4586. return err;
  4587. }
  4588. EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
  4589. int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
  4590. {
  4591. if (!fmsg->putting_binary)
  4592. return -EINVAL;
  4593. fmsg->putting_binary = false;
  4594. return devlink_fmsg_arr_pair_nest_end(fmsg);
  4595. }
  4596. EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
  4597. static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
  4598. const void *value, u16 value_len,
  4599. u8 value_nla_type)
  4600. {
  4601. struct devlink_fmsg_item *item;
  4602. if (value_len > DEVLINK_FMSG_MAX_SIZE)
  4603. return -EMSGSIZE;
  4604. item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
  4605. if (!item)
  4606. return -ENOMEM;
  4607. item->nla_type = value_nla_type;
  4608. item->len = value_len;
  4609. item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
  4610. memcpy(&item->value, value, item->len);
  4611. list_add_tail(&item->list, &fmsg->item_list);
  4612. return 0;
  4613. }
  4614. int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
  4615. {
  4616. if (fmsg->putting_binary)
  4617. return -EINVAL;
  4618. return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
  4619. }
  4620. EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
  4621. int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
  4622. {
  4623. if (fmsg->putting_binary)
  4624. return -EINVAL;
  4625. return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
  4626. }
  4627. EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
  4628. int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
  4629. {
  4630. if (fmsg->putting_binary)
  4631. return -EINVAL;
  4632. return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
  4633. }
  4634. EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
  4635. int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
  4636. {
  4637. if (fmsg->putting_binary)
  4638. return -EINVAL;
  4639. return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
  4640. }
  4641. EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
  4642. int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
  4643. {
  4644. if (fmsg->putting_binary)
  4645. return -EINVAL;
  4646. return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
  4647. NLA_NUL_STRING);
  4648. }
  4649. EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
  4650. int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
  4651. u16 value_len)
  4652. {
  4653. if (!fmsg->putting_binary)
  4654. return -EINVAL;
  4655. return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
  4656. }
  4657. EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
  4658. int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
  4659. bool value)
  4660. {
  4661. int err;
  4662. err = devlink_fmsg_pair_nest_start(fmsg, name);
  4663. if (err)
  4664. return err;
  4665. err = devlink_fmsg_bool_put(fmsg, value);
  4666. if (err)
  4667. return err;
  4668. err = devlink_fmsg_pair_nest_end(fmsg);
  4669. if (err)
  4670. return err;
  4671. return 0;
  4672. }
  4673. EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
  4674. int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
  4675. u8 value)
  4676. {
  4677. int err;
  4678. err = devlink_fmsg_pair_nest_start(fmsg, name);
  4679. if (err)
  4680. return err;
  4681. err = devlink_fmsg_u8_put(fmsg, value);
  4682. if (err)
  4683. return err;
  4684. err = devlink_fmsg_pair_nest_end(fmsg);
  4685. if (err)
  4686. return err;
  4687. return 0;
  4688. }
  4689. EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
  4690. int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
  4691. u32 value)
  4692. {
  4693. int err;
  4694. err = devlink_fmsg_pair_nest_start(fmsg, name);
  4695. if (err)
  4696. return err;
  4697. err = devlink_fmsg_u32_put(fmsg, value);
  4698. if (err)
  4699. return err;
  4700. err = devlink_fmsg_pair_nest_end(fmsg);
  4701. if (err)
  4702. return err;
  4703. return 0;
  4704. }
  4705. EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
  4706. int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
  4707. u64 value)
  4708. {
  4709. int err;
  4710. err = devlink_fmsg_pair_nest_start(fmsg, name);
  4711. if (err)
  4712. return err;
  4713. err = devlink_fmsg_u64_put(fmsg, value);
  4714. if (err)
  4715. return err;
  4716. err = devlink_fmsg_pair_nest_end(fmsg);
  4717. if (err)
  4718. return err;
  4719. return 0;
  4720. }
  4721. EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
  4722. int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
  4723. const char *value)
  4724. {
  4725. int err;
  4726. err = devlink_fmsg_pair_nest_start(fmsg, name);
  4727. if (err)
  4728. return err;
  4729. err = devlink_fmsg_string_put(fmsg, value);
  4730. if (err)
  4731. return err;
  4732. err = devlink_fmsg_pair_nest_end(fmsg);
  4733. if (err)
  4734. return err;
  4735. return 0;
  4736. }
  4737. EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
  4738. int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
  4739. const void *value, u32 value_len)
  4740. {
  4741. u32 data_size;
  4742. int end_err;
  4743. u32 offset;
  4744. int err;
  4745. err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
  4746. if (err)
  4747. return err;
  4748. for (offset = 0; offset < value_len; offset += data_size) {
  4749. data_size = value_len - offset;
  4750. if (data_size > DEVLINK_FMSG_MAX_SIZE)
  4751. data_size = DEVLINK_FMSG_MAX_SIZE;
  4752. err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
  4753. if (err)
  4754. break;
  4755. /* Exit from loop with a break (instead of
  4756. * return) to make sure putting_binary is turned off in
  4757. * devlink_fmsg_binary_pair_nest_end
  4758. */
  4759. }
  4760. end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
  4761. if (end_err)
  4762. err = end_err;
  4763. return err;
  4764. }
  4765. EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
  4766. static int
  4767. devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
  4768. {
  4769. switch (msg->nla_type) {
  4770. case NLA_FLAG:
  4771. case NLA_U8:
  4772. case NLA_U32:
  4773. case NLA_U64:
  4774. case NLA_NUL_STRING:
  4775. case NLA_BINARY:
  4776. return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
  4777. msg->nla_type);
  4778. default:
  4779. return -EINVAL;
  4780. }
  4781. }
  4782. static int
  4783. devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
  4784. {
  4785. int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
  4786. u8 tmp;
  4787. switch (msg->nla_type) {
  4788. case NLA_FLAG:
  4789. /* Always provide flag data, regardless of its value */
  4790. tmp = *(bool *) msg->value;
  4791. return nla_put_u8(skb, attrtype, tmp);
  4792. case NLA_U8:
  4793. return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
  4794. case NLA_U32:
  4795. return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
  4796. case NLA_U64:
  4797. return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
  4798. DEVLINK_ATTR_PAD);
  4799. case NLA_NUL_STRING:
  4800. return nla_put_string(skb, attrtype, (char *) &msg->value);
  4801. case NLA_BINARY:
  4802. return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
  4803. default:
  4804. return -EINVAL;
  4805. }
  4806. }
  4807. static int
  4808. devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
  4809. int *start)
  4810. {
  4811. struct devlink_fmsg_item *item;
  4812. struct nlattr *fmsg_nlattr;
  4813. int i = 0;
  4814. int err;
  4815. fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
  4816. if (!fmsg_nlattr)
  4817. return -EMSGSIZE;
  4818. list_for_each_entry(item, &fmsg->item_list, list) {
  4819. if (i < *start) {
  4820. i++;
  4821. continue;
  4822. }
  4823. switch (item->attrtype) {
  4824. case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
  4825. case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
  4826. case DEVLINK_ATTR_FMSG_ARR_NEST_START:
  4827. case DEVLINK_ATTR_FMSG_NEST_END:
  4828. err = nla_put_flag(skb, item->attrtype);
  4829. break;
  4830. case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
  4831. err = devlink_fmsg_item_fill_type(item, skb);
  4832. if (err)
  4833. break;
  4834. err = devlink_fmsg_item_fill_data(item, skb);
  4835. break;
  4836. case DEVLINK_ATTR_FMSG_OBJ_NAME:
  4837. err = nla_put_string(skb, item->attrtype,
  4838. (char *) &item->value);
  4839. break;
  4840. default:
  4841. err = -EINVAL;
  4842. break;
  4843. }
  4844. if (!err)
  4845. *start = ++i;
  4846. else
  4847. break;
  4848. }
  4849. nla_nest_end(skb, fmsg_nlattr);
  4850. return err;
  4851. }
  4852. static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
  4853. struct genl_info *info,
  4854. enum devlink_command cmd, int flags)
  4855. {
  4856. struct nlmsghdr *nlh;
  4857. struct sk_buff *skb;
  4858. bool last = false;
  4859. int index = 0;
  4860. void *hdr;
  4861. int err;
  4862. while (!last) {
  4863. int tmp_index = index;
  4864. skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  4865. if (!skb)
  4866. return -ENOMEM;
  4867. hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
  4868. &devlink_nl_family, flags | NLM_F_MULTI, cmd);
  4869. if (!hdr) {
  4870. err = -EMSGSIZE;
  4871. goto nla_put_failure;
  4872. }
  4873. err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
  4874. if (!err)
  4875. last = true;
  4876. else if (err != -EMSGSIZE || tmp_index == index)
  4877. goto nla_put_failure;
  4878. genlmsg_end(skb, hdr);
  4879. err = genlmsg_reply(skb, info);
  4880. if (err)
  4881. return err;
  4882. }
  4883. skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  4884. if (!skb)
  4885. return -ENOMEM;
  4886. nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
  4887. NLMSG_DONE, 0, flags | NLM_F_MULTI);
  4888. if (!nlh) {
  4889. err = -EMSGSIZE;
  4890. goto nla_put_failure;
  4891. }
  4892. return genlmsg_reply(skb, info);
  4893. nla_put_failure:
  4894. nlmsg_free(skb);
  4895. return err;
  4896. }
  4897. static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
  4898. struct netlink_callback *cb,
  4899. enum devlink_command cmd)
  4900. {
  4901. int index = cb->args[0];
  4902. int tmp_index = index;
  4903. void *hdr;
  4904. int err;
  4905. hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
  4906. &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
  4907. if (!hdr) {
  4908. err = -EMSGSIZE;
  4909. goto nla_put_failure;
  4910. }
  4911. err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
  4912. if ((err && err != -EMSGSIZE) || tmp_index == index)
  4913. goto nla_put_failure;
  4914. cb->args[0] = index;
  4915. genlmsg_end(skb, hdr);
  4916. return skb->len;
  4917. nla_put_failure:
  4918. genlmsg_cancel(skb, hdr);
  4919. return err;
  4920. }
  4921. struct devlink_health_reporter {
  4922. struct list_head list;
  4923. void *priv;
  4924. const struct devlink_health_reporter_ops *ops;
  4925. struct devlink *devlink;
  4926. struct devlink_port *devlink_port;
  4927. struct devlink_fmsg *dump_fmsg;
  4928. struct mutex dump_lock; /* lock parallel read/write from dump buffers */
  4929. u64 graceful_period;
  4930. bool auto_recover;
  4931. bool auto_dump;
  4932. u8 health_state;
  4933. u64 dump_ts;
  4934. u64 dump_real_ts;
  4935. u64 error_count;
  4936. u64 recovery_count;
  4937. u64 last_recovery_ts;
  4938. refcount_t refcount;
  4939. };
  4940. void *
  4941. devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
  4942. {
  4943. return reporter->priv;
  4944. }
  4945. EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
  4946. static struct devlink_health_reporter *
  4947. __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
  4948. struct mutex *list_lock,
  4949. const char *reporter_name)
  4950. {
  4951. struct devlink_health_reporter *reporter;
  4952. lockdep_assert_held(list_lock);
  4953. list_for_each_entry(reporter, reporter_list, list)
  4954. if (!strcmp(reporter->ops->name, reporter_name))
  4955. return reporter;
  4956. return NULL;
  4957. }
  4958. static struct devlink_health_reporter *
  4959. devlink_health_reporter_find_by_name(struct devlink *devlink,
  4960. const char *reporter_name)
  4961. {
  4962. return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
  4963. &devlink->reporters_lock,
  4964. reporter_name);
  4965. }
  4966. static struct devlink_health_reporter *
  4967. devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
  4968. const char *reporter_name)
  4969. {
  4970. return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
  4971. &devlink_port->reporters_lock,
  4972. reporter_name);
  4973. }
  4974. static struct devlink_health_reporter *
  4975. __devlink_health_reporter_create(struct devlink *devlink,
  4976. const struct devlink_health_reporter_ops *ops,
  4977. u64 graceful_period, void *priv)
  4978. {
  4979. struct devlink_health_reporter *reporter;
  4980. if (WARN_ON(graceful_period && !ops->recover))
  4981. return ERR_PTR(-EINVAL);
  4982. reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
  4983. if (!reporter)
  4984. return ERR_PTR(-ENOMEM);
  4985. reporter->priv = priv;
  4986. reporter->ops = ops;
  4987. reporter->devlink = devlink;
  4988. reporter->graceful_period = graceful_period;
  4989. reporter->auto_recover = !!ops->recover;
  4990. reporter->auto_dump = !!ops->dump;
  4991. mutex_init(&reporter->dump_lock);
  4992. refcount_set(&reporter->refcount, 1);
  4993. return reporter;
  4994. }
  4995. /**
  4996. * devlink_port_health_reporter_create - create devlink health reporter for
  4997. * specified port instance
  4998. *
  4999. * @port: devlink_port which should contain the new reporter
  5000. * @ops: ops
  5001. * @graceful_period: to avoid recovery loops, in msecs
  5002. * @priv: priv
  5003. */
  5004. struct devlink_health_reporter *
  5005. devlink_port_health_reporter_create(struct devlink_port *port,
  5006. const struct devlink_health_reporter_ops *ops,
  5007. u64 graceful_period, void *priv)
  5008. {
  5009. struct devlink_health_reporter *reporter;
  5010. mutex_lock(&port->reporters_lock);
  5011. if (__devlink_health_reporter_find_by_name(&port->reporter_list,
  5012. &port->reporters_lock, ops->name)) {
  5013. reporter = ERR_PTR(-EEXIST);
  5014. goto unlock;
  5015. }
  5016. reporter = __devlink_health_reporter_create(port->devlink, ops,
  5017. graceful_period, priv);
  5018. if (IS_ERR(reporter))
  5019. goto unlock;
  5020. reporter->devlink_port = port;
  5021. list_add_tail(&reporter->list, &port->reporter_list);
  5022. unlock:
  5023. mutex_unlock(&port->reporters_lock);
  5024. return reporter;
  5025. }
  5026. EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
  5027. /**
  5028. * devlink_health_reporter_create - create devlink health reporter
  5029. *
  5030. * @devlink: devlink
  5031. * @ops: ops
  5032. * @graceful_period: to avoid recovery loops, in msecs
  5033. * @priv: priv
  5034. */
  5035. struct devlink_health_reporter *
  5036. devlink_health_reporter_create(struct devlink *devlink,
  5037. const struct devlink_health_reporter_ops *ops,
  5038. u64 graceful_period, void *priv)
  5039. {
  5040. struct devlink_health_reporter *reporter;
  5041. mutex_lock(&devlink->reporters_lock);
  5042. if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
  5043. reporter = ERR_PTR(-EEXIST);
  5044. goto unlock;
  5045. }
  5046. reporter = __devlink_health_reporter_create(devlink, ops,
  5047. graceful_period, priv);
  5048. if (IS_ERR(reporter))
  5049. goto unlock;
  5050. list_add_tail(&reporter->list, &devlink->reporter_list);
  5051. unlock:
  5052. mutex_unlock(&devlink->reporters_lock);
  5053. return reporter;
  5054. }
  5055. EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
  5056. static void
  5057. devlink_health_reporter_free(struct devlink_health_reporter *reporter)
  5058. {
  5059. mutex_destroy(&reporter->dump_lock);
  5060. if (reporter->dump_fmsg)
  5061. devlink_fmsg_free(reporter->dump_fmsg);
  5062. kfree(reporter);
  5063. }
  5064. static void
  5065. devlink_health_reporter_put(struct devlink_health_reporter *reporter)
  5066. {
  5067. if (refcount_dec_and_test(&reporter->refcount))
  5068. devlink_health_reporter_free(reporter);
  5069. }
  5070. static void
  5071. __devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
  5072. {
  5073. list_del(&reporter->list);
  5074. devlink_health_reporter_put(reporter);
  5075. }
  5076. /**
  5077. * devlink_health_reporter_destroy - destroy devlink health reporter
  5078. *
  5079. * @reporter: devlink health reporter to destroy
  5080. */
  5081. void
  5082. devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
  5083. {
  5084. struct mutex *lock = &reporter->devlink->reporters_lock;
  5085. mutex_lock(lock);
  5086. __devlink_health_reporter_destroy(reporter);
  5087. mutex_unlock(lock);
  5088. }
  5089. EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
  5090. /**
  5091. * devlink_port_health_reporter_destroy - destroy devlink port health reporter
  5092. *
  5093. * @reporter: devlink health reporter to destroy
  5094. */
  5095. void
  5096. devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter)
  5097. {
  5098. struct mutex *lock = &reporter->devlink_port->reporters_lock;
  5099. mutex_lock(lock);
  5100. __devlink_health_reporter_destroy(reporter);
  5101. mutex_unlock(lock);
  5102. }
  5103. EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy);
  5104. static int
  5105. devlink_nl_health_reporter_fill(struct sk_buff *msg,
  5106. struct devlink *devlink,
  5107. struct devlink_health_reporter *reporter,
  5108. enum devlink_command cmd, u32 portid,
  5109. u32 seq, int flags)
  5110. {
  5111. struct nlattr *reporter_attr;
  5112. void *hdr;
  5113. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  5114. if (!hdr)
  5115. return -EMSGSIZE;
  5116. if (devlink_nl_put_handle(msg, devlink))
  5117. goto genlmsg_cancel;
  5118. if (reporter->devlink_port) {
  5119. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
  5120. goto genlmsg_cancel;
  5121. }
  5122. reporter_attr = nla_nest_start_noflag(msg,
  5123. DEVLINK_ATTR_HEALTH_REPORTER);
  5124. if (!reporter_attr)
  5125. goto genlmsg_cancel;
  5126. if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
  5127. reporter->ops->name))
  5128. goto reporter_nest_cancel;
  5129. if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
  5130. reporter->health_state))
  5131. goto reporter_nest_cancel;
  5132. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
  5133. reporter->error_count, DEVLINK_ATTR_PAD))
  5134. goto reporter_nest_cancel;
  5135. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
  5136. reporter->recovery_count, DEVLINK_ATTR_PAD))
  5137. goto reporter_nest_cancel;
  5138. if (reporter->ops->recover &&
  5139. nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
  5140. reporter->graceful_period,
  5141. DEVLINK_ATTR_PAD))
  5142. goto reporter_nest_cancel;
  5143. if (reporter->ops->recover &&
  5144. nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
  5145. reporter->auto_recover))
  5146. goto reporter_nest_cancel;
  5147. if (reporter->dump_fmsg &&
  5148. nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
  5149. jiffies_to_msecs(reporter->dump_ts),
  5150. DEVLINK_ATTR_PAD))
  5151. goto reporter_nest_cancel;
  5152. if (reporter->dump_fmsg &&
  5153. nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
  5154. reporter->dump_real_ts, DEVLINK_ATTR_PAD))
  5155. goto reporter_nest_cancel;
  5156. if (reporter->ops->dump &&
  5157. nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
  5158. reporter->auto_dump))
  5159. goto reporter_nest_cancel;
  5160. nla_nest_end(msg, reporter_attr);
  5161. genlmsg_end(msg, hdr);
  5162. return 0;
  5163. reporter_nest_cancel:
  5164. nla_nest_end(msg, reporter_attr);
  5165. genlmsg_cancel:
  5166. genlmsg_cancel(msg, hdr);
  5167. return -EMSGSIZE;
  5168. }
  5169. static void devlink_recover_notify(struct devlink_health_reporter *reporter,
  5170. enum devlink_command cmd)
  5171. {
  5172. struct sk_buff *msg;
  5173. int err;
  5174. WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
  5175. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  5176. if (!msg)
  5177. return;
  5178. err = devlink_nl_health_reporter_fill(msg, reporter->devlink,
  5179. reporter, cmd, 0, 0, 0);
  5180. if (err) {
  5181. nlmsg_free(msg);
  5182. return;
  5183. }
  5184. genlmsg_multicast_netns(&devlink_nl_family,
  5185. devlink_net(reporter->devlink),
  5186. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  5187. }
  5188. void
  5189. devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
  5190. {
  5191. reporter->recovery_count++;
  5192. reporter->last_recovery_ts = jiffies;
  5193. }
  5194. EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
  5195. static int
  5196. devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
  5197. void *priv_ctx, struct netlink_ext_ack *extack)
  5198. {
  5199. int err;
  5200. if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
  5201. return 0;
  5202. if (!reporter->ops->recover)
  5203. return -EOPNOTSUPP;
  5204. err = reporter->ops->recover(reporter, priv_ctx, extack);
  5205. if (err)
  5206. return err;
  5207. devlink_health_reporter_recovery_done(reporter);
  5208. reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
  5209. devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
  5210. return 0;
  5211. }
  5212. static void
  5213. devlink_health_dump_clear(struct devlink_health_reporter *reporter)
  5214. {
  5215. if (!reporter->dump_fmsg)
  5216. return;
  5217. devlink_fmsg_free(reporter->dump_fmsg);
  5218. reporter->dump_fmsg = NULL;
  5219. }
  5220. static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
  5221. void *priv_ctx,
  5222. struct netlink_ext_ack *extack)
  5223. {
  5224. int err;
  5225. if (!reporter->ops->dump)
  5226. return 0;
  5227. if (reporter->dump_fmsg)
  5228. return 0;
  5229. reporter->dump_fmsg = devlink_fmsg_alloc();
  5230. if (!reporter->dump_fmsg) {
  5231. err = -ENOMEM;
  5232. return err;
  5233. }
  5234. err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
  5235. if (err)
  5236. goto dump_err;
  5237. err = reporter->ops->dump(reporter, reporter->dump_fmsg,
  5238. priv_ctx, extack);
  5239. if (err)
  5240. goto dump_err;
  5241. err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
  5242. if (err)
  5243. goto dump_err;
  5244. reporter->dump_ts = jiffies;
  5245. reporter->dump_real_ts = ktime_get_real_ns();
  5246. return 0;
  5247. dump_err:
  5248. devlink_health_dump_clear(reporter);
  5249. return err;
  5250. }
  5251. int devlink_health_report(struct devlink_health_reporter *reporter,
  5252. const char *msg, void *priv_ctx)
  5253. {
  5254. enum devlink_health_reporter_state prev_health_state;
  5255. struct devlink *devlink = reporter->devlink;
  5256. unsigned long recover_ts_threshold;
  5257. /* write a log message of the current error */
  5258. WARN_ON(!msg);
  5259. trace_devlink_health_report(devlink, reporter->ops->name, msg);
  5260. reporter->error_count++;
  5261. prev_health_state = reporter->health_state;
  5262. reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
  5263. devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
  5264. /* abort if the previous error wasn't recovered */
  5265. recover_ts_threshold = reporter->last_recovery_ts +
  5266. msecs_to_jiffies(reporter->graceful_period);
  5267. if (reporter->auto_recover &&
  5268. (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
  5269. (reporter->last_recovery_ts && reporter->recovery_count &&
  5270. time_is_after_jiffies(recover_ts_threshold)))) {
  5271. trace_devlink_health_recover_aborted(devlink,
  5272. reporter->ops->name,
  5273. reporter->health_state,
  5274. jiffies -
  5275. reporter->last_recovery_ts);
  5276. return -ECANCELED;
  5277. }
  5278. reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
  5279. if (reporter->auto_dump) {
  5280. mutex_lock(&reporter->dump_lock);
  5281. /* store current dump of current error, for later analysis */
  5282. devlink_health_do_dump(reporter, priv_ctx, NULL);
  5283. mutex_unlock(&reporter->dump_lock);
  5284. }
  5285. if (reporter->auto_recover)
  5286. return devlink_health_reporter_recover(reporter,
  5287. priv_ctx, NULL);
  5288. return 0;
  5289. }
  5290. EXPORT_SYMBOL_GPL(devlink_health_report);
  5291. static struct devlink_health_reporter *
  5292. devlink_health_reporter_get_from_attrs(struct devlink *devlink,
  5293. struct nlattr **attrs)
  5294. {
  5295. struct devlink_health_reporter *reporter;
  5296. struct devlink_port *devlink_port;
  5297. char *reporter_name;
  5298. if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
  5299. return NULL;
  5300. reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
  5301. devlink_port = devlink_port_get_from_attrs(devlink, attrs);
  5302. if (IS_ERR(devlink_port)) {
  5303. mutex_lock(&devlink->reporters_lock);
  5304. reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
  5305. if (reporter)
  5306. refcount_inc(&reporter->refcount);
  5307. mutex_unlock(&devlink->reporters_lock);
  5308. } else {
  5309. mutex_lock(&devlink_port->reporters_lock);
  5310. reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name);
  5311. if (reporter)
  5312. refcount_inc(&reporter->refcount);
  5313. mutex_unlock(&devlink_port->reporters_lock);
  5314. }
  5315. return reporter;
  5316. }
  5317. static struct devlink_health_reporter *
  5318. devlink_health_reporter_get_from_info(struct devlink *devlink,
  5319. struct genl_info *info)
  5320. {
  5321. return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
  5322. }
  5323. static struct devlink_health_reporter *
  5324. devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
  5325. {
  5326. const struct genl_dumpit_info *info = genl_dumpit_info(cb);
  5327. struct devlink_health_reporter *reporter;
  5328. struct nlattr **attrs = info->attrs;
  5329. struct devlink *devlink;
  5330. mutex_lock(&devlink_mutex);
  5331. devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
  5332. if (IS_ERR(devlink))
  5333. goto unlock;
  5334. reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
  5335. mutex_unlock(&devlink_mutex);
  5336. return reporter;
  5337. unlock:
  5338. mutex_unlock(&devlink_mutex);
  5339. return NULL;
  5340. }
  5341. void
  5342. devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
  5343. enum devlink_health_reporter_state state)
  5344. {
  5345. if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
  5346. state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
  5347. return;
  5348. if (reporter->health_state == state)
  5349. return;
  5350. reporter->health_state = state;
  5351. trace_devlink_health_reporter_state_update(reporter->devlink,
  5352. reporter->ops->name, state);
  5353. devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
  5354. }
  5355. EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
  5356. static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
  5357. struct genl_info *info)
  5358. {
  5359. struct devlink *devlink = info->user_ptr[0];
  5360. struct devlink_health_reporter *reporter;
  5361. struct sk_buff *msg;
  5362. int err;
  5363. reporter = devlink_health_reporter_get_from_info(devlink, info);
  5364. if (!reporter)
  5365. return -EINVAL;
  5366. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  5367. if (!msg) {
  5368. err = -ENOMEM;
  5369. goto out;
  5370. }
  5371. err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
  5372. DEVLINK_CMD_HEALTH_REPORTER_GET,
  5373. info->snd_portid, info->snd_seq,
  5374. 0);
  5375. if (err) {
  5376. nlmsg_free(msg);
  5377. goto out;
  5378. }
  5379. err = genlmsg_reply(msg, info);
  5380. out:
  5381. devlink_health_reporter_put(reporter);
  5382. return err;
  5383. }
  5384. static int
  5385. devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
  5386. struct netlink_callback *cb)
  5387. {
  5388. struct devlink_health_reporter *reporter;
  5389. struct devlink_port *port;
  5390. struct devlink *devlink;
  5391. int start = cb->args[0];
  5392. int idx = 0;
  5393. int err;
  5394. mutex_lock(&devlink_mutex);
  5395. list_for_each_entry(devlink, &devlink_list, list) {
  5396. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  5397. continue;
  5398. mutex_lock(&devlink->reporters_lock);
  5399. list_for_each_entry(reporter, &devlink->reporter_list,
  5400. list) {
  5401. if (idx < start) {
  5402. idx++;
  5403. continue;
  5404. }
  5405. err = devlink_nl_health_reporter_fill(msg, devlink,
  5406. reporter,
  5407. DEVLINK_CMD_HEALTH_REPORTER_GET,
  5408. NETLINK_CB(cb->skb).portid,
  5409. cb->nlh->nlmsg_seq,
  5410. NLM_F_MULTI);
  5411. if (err) {
  5412. mutex_unlock(&devlink->reporters_lock);
  5413. goto out;
  5414. }
  5415. idx++;
  5416. }
  5417. mutex_unlock(&devlink->reporters_lock);
  5418. }
  5419. list_for_each_entry(devlink, &devlink_list, list) {
  5420. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  5421. continue;
  5422. mutex_lock(&devlink->lock);
  5423. list_for_each_entry(port, &devlink->port_list, list) {
  5424. mutex_lock(&port->reporters_lock);
  5425. list_for_each_entry(reporter, &port->reporter_list, list) {
  5426. if (idx < start) {
  5427. idx++;
  5428. continue;
  5429. }
  5430. err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
  5431. DEVLINK_CMD_HEALTH_REPORTER_GET,
  5432. NETLINK_CB(cb->skb).portid,
  5433. cb->nlh->nlmsg_seq,
  5434. NLM_F_MULTI);
  5435. if (err) {
  5436. mutex_unlock(&port->reporters_lock);
  5437. mutex_unlock(&devlink->lock);
  5438. goto out;
  5439. }
  5440. idx++;
  5441. }
  5442. mutex_unlock(&port->reporters_lock);
  5443. }
  5444. mutex_unlock(&devlink->lock);
  5445. }
  5446. out:
  5447. mutex_unlock(&devlink_mutex);
  5448. cb->args[0] = idx;
  5449. return msg->len;
  5450. }
  5451. static int
  5452. devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
  5453. struct genl_info *info)
  5454. {
  5455. struct devlink *devlink = info->user_ptr[0];
  5456. struct devlink_health_reporter *reporter;
  5457. int err;
  5458. reporter = devlink_health_reporter_get_from_info(devlink, info);
  5459. if (!reporter)
  5460. return -EINVAL;
  5461. if (!reporter->ops->recover &&
  5462. (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
  5463. info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
  5464. err = -EOPNOTSUPP;
  5465. goto out;
  5466. }
  5467. if (!reporter->ops->dump &&
  5468. info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) {
  5469. err = -EOPNOTSUPP;
  5470. goto out;
  5471. }
  5472. if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
  5473. reporter->graceful_period =
  5474. nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
  5475. if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
  5476. reporter->auto_recover =
  5477. nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
  5478. if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
  5479. reporter->auto_dump =
  5480. nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
  5481. devlink_health_reporter_put(reporter);
  5482. return 0;
  5483. out:
  5484. devlink_health_reporter_put(reporter);
  5485. return err;
  5486. }
  5487. static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
  5488. struct genl_info *info)
  5489. {
  5490. struct devlink *devlink = info->user_ptr[0];
  5491. struct devlink_health_reporter *reporter;
  5492. int err;
  5493. reporter = devlink_health_reporter_get_from_info(devlink, info);
  5494. if (!reporter)
  5495. return -EINVAL;
  5496. err = devlink_health_reporter_recover(reporter, NULL, info->extack);
  5497. devlink_health_reporter_put(reporter);
  5498. return err;
  5499. }
  5500. static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
  5501. struct genl_info *info)
  5502. {
  5503. struct devlink *devlink = info->user_ptr[0];
  5504. struct devlink_health_reporter *reporter;
  5505. struct devlink_fmsg *fmsg;
  5506. int err;
  5507. reporter = devlink_health_reporter_get_from_info(devlink, info);
  5508. if (!reporter)
  5509. return -EINVAL;
  5510. if (!reporter->ops->diagnose) {
  5511. devlink_health_reporter_put(reporter);
  5512. return -EOPNOTSUPP;
  5513. }
  5514. fmsg = devlink_fmsg_alloc();
  5515. if (!fmsg) {
  5516. devlink_health_reporter_put(reporter);
  5517. return -ENOMEM;
  5518. }
  5519. err = devlink_fmsg_obj_nest_start(fmsg);
  5520. if (err)
  5521. goto out;
  5522. err = reporter->ops->diagnose(reporter, fmsg, info->extack);
  5523. if (err)
  5524. goto out;
  5525. err = devlink_fmsg_obj_nest_end(fmsg);
  5526. if (err)
  5527. goto out;
  5528. err = devlink_fmsg_snd(fmsg, info,
  5529. DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
  5530. out:
  5531. devlink_fmsg_free(fmsg);
  5532. devlink_health_reporter_put(reporter);
  5533. return err;
  5534. }
  5535. static int
  5536. devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
  5537. struct netlink_callback *cb)
  5538. {
  5539. struct devlink_health_reporter *reporter;
  5540. u64 start = cb->args[0];
  5541. int err;
  5542. reporter = devlink_health_reporter_get_from_cb(cb);
  5543. if (!reporter)
  5544. return -EINVAL;
  5545. if (!reporter->ops->dump) {
  5546. err = -EOPNOTSUPP;
  5547. goto out;
  5548. }
  5549. mutex_lock(&reporter->dump_lock);
  5550. if (!start) {
  5551. err = devlink_health_do_dump(reporter, NULL, cb->extack);
  5552. if (err)
  5553. goto unlock;
  5554. cb->args[1] = reporter->dump_ts;
  5555. }
  5556. if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
  5557. NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
  5558. err = -EAGAIN;
  5559. goto unlock;
  5560. }
  5561. err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
  5562. DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
  5563. unlock:
  5564. mutex_unlock(&reporter->dump_lock);
  5565. out:
  5566. devlink_health_reporter_put(reporter);
  5567. return err;
  5568. }
  5569. static int
  5570. devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
  5571. struct genl_info *info)
  5572. {
  5573. struct devlink *devlink = info->user_ptr[0];
  5574. struct devlink_health_reporter *reporter;
  5575. reporter = devlink_health_reporter_get_from_info(devlink, info);
  5576. if (!reporter)
  5577. return -EINVAL;
  5578. if (!reporter->ops->dump) {
  5579. devlink_health_reporter_put(reporter);
  5580. return -EOPNOTSUPP;
  5581. }
  5582. mutex_lock(&reporter->dump_lock);
  5583. devlink_health_dump_clear(reporter);
  5584. mutex_unlock(&reporter->dump_lock);
  5585. devlink_health_reporter_put(reporter);
  5586. return 0;
  5587. }
  5588. static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
  5589. struct genl_info *info)
  5590. {
  5591. struct devlink *devlink = info->user_ptr[0];
  5592. struct devlink_health_reporter *reporter;
  5593. int err;
  5594. reporter = devlink_health_reporter_get_from_info(devlink, info);
  5595. if (!reporter)
  5596. return -EINVAL;
  5597. if (!reporter->ops->test) {
  5598. devlink_health_reporter_put(reporter);
  5599. return -EOPNOTSUPP;
  5600. }
  5601. err = reporter->ops->test(reporter, info->extack);
  5602. devlink_health_reporter_put(reporter);
  5603. return err;
  5604. }
  5605. struct devlink_stats {
  5606. u64 rx_bytes;
  5607. u64 rx_packets;
  5608. struct u64_stats_sync syncp;
  5609. };
  5610. /**
  5611. * struct devlink_trap_policer_item - Packet trap policer attributes.
  5612. * @policer: Immutable packet trap policer attributes.
  5613. * @rate: Rate in packets / sec.
  5614. * @burst: Burst size in packets.
  5615. * @list: trap_policer_list member.
  5616. *
  5617. * Describes packet trap policer attributes. Created by devlink during trap
  5618. * policer registration.
  5619. */
  5620. struct devlink_trap_policer_item {
  5621. const struct devlink_trap_policer *policer;
  5622. u64 rate;
  5623. u64 burst;
  5624. struct list_head list;
  5625. };
  5626. /**
  5627. * struct devlink_trap_group_item - Packet trap group attributes.
  5628. * @group: Immutable packet trap group attributes.
  5629. * @policer_item: Associated policer item. Can be NULL.
  5630. * @list: trap_group_list member.
  5631. * @stats: Trap group statistics.
  5632. *
  5633. * Describes packet trap group attributes. Created by devlink during trap
  5634. * group registration.
  5635. */
  5636. struct devlink_trap_group_item {
  5637. const struct devlink_trap_group *group;
  5638. struct devlink_trap_policer_item *policer_item;
  5639. struct list_head list;
  5640. struct devlink_stats __percpu *stats;
  5641. };
  5642. /**
  5643. * struct devlink_trap_item - Packet trap attributes.
  5644. * @trap: Immutable packet trap attributes.
  5645. * @group_item: Associated group item.
  5646. * @list: trap_list member.
  5647. * @action: Trap action.
  5648. * @stats: Trap statistics.
  5649. * @priv: Driver private information.
  5650. *
  5651. * Describes both mutable and immutable packet trap attributes. Created by
  5652. * devlink during trap registration and used for all trap related operations.
  5653. */
  5654. struct devlink_trap_item {
  5655. const struct devlink_trap *trap;
  5656. struct devlink_trap_group_item *group_item;
  5657. struct list_head list;
  5658. enum devlink_trap_action action;
  5659. struct devlink_stats __percpu *stats;
  5660. void *priv;
  5661. };
  5662. static struct devlink_trap_policer_item *
  5663. devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
  5664. {
  5665. struct devlink_trap_policer_item *policer_item;
  5666. list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
  5667. if (policer_item->policer->id == id)
  5668. return policer_item;
  5669. }
  5670. return NULL;
  5671. }
  5672. static struct devlink_trap_item *
  5673. devlink_trap_item_lookup(struct devlink *devlink, const char *name)
  5674. {
  5675. struct devlink_trap_item *trap_item;
  5676. list_for_each_entry(trap_item, &devlink->trap_list, list) {
  5677. if (!strcmp(trap_item->trap->name, name))
  5678. return trap_item;
  5679. }
  5680. return NULL;
  5681. }
  5682. static struct devlink_trap_item *
  5683. devlink_trap_item_get_from_info(struct devlink *devlink,
  5684. struct genl_info *info)
  5685. {
  5686. struct nlattr *attr;
  5687. if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
  5688. return NULL;
  5689. attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
  5690. return devlink_trap_item_lookup(devlink, nla_data(attr));
  5691. }
  5692. static int
  5693. devlink_trap_action_get_from_info(struct genl_info *info,
  5694. enum devlink_trap_action *p_trap_action)
  5695. {
  5696. u8 val;
  5697. val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
  5698. switch (val) {
  5699. case DEVLINK_TRAP_ACTION_DROP:
  5700. case DEVLINK_TRAP_ACTION_TRAP:
  5701. case DEVLINK_TRAP_ACTION_MIRROR:
  5702. *p_trap_action = val;
  5703. break;
  5704. default:
  5705. return -EINVAL;
  5706. }
  5707. return 0;
  5708. }
  5709. static int devlink_trap_metadata_put(struct sk_buff *msg,
  5710. const struct devlink_trap *trap)
  5711. {
  5712. struct nlattr *attr;
  5713. attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
  5714. if (!attr)
  5715. return -EMSGSIZE;
  5716. if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
  5717. nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
  5718. goto nla_put_failure;
  5719. if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
  5720. nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
  5721. goto nla_put_failure;
  5722. nla_nest_end(msg, attr);
  5723. return 0;
  5724. nla_put_failure:
  5725. nla_nest_cancel(msg, attr);
  5726. return -EMSGSIZE;
  5727. }
  5728. static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
  5729. struct devlink_stats *stats)
  5730. {
  5731. int i;
  5732. memset(stats, 0, sizeof(*stats));
  5733. for_each_possible_cpu(i) {
  5734. struct devlink_stats *cpu_stats;
  5735. u64 rx_packets, rx_bytes;
  5736. unsigned int start;
  5737. cpu_stats = per_cpu_ptr(trap_stats, i);
  5738. do {
  5739. start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
  5740. rx_packets = cpu_stats->rx_packets;
  5741. rx_bytes = cpu_stats->rx_bytes;
  5742. } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
  5743. stats->rx_packets += rx_packets;
  5744. stats->rx_bytes += rx_bytes;
  5745. }
  5746. }
  5747. static int devlink_trap_stats_put(struct sk_buff *msg,
  5748. struct devlink_stats __percpu *trap_stats)
  5749. {
  5750. struct devlink_stats stats;
  5751. struct nlattr *attr;
  5752. devlink_trap_stats_read(trap_stats, &stats);
  5753. attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
  5754. if (!attr)
  5755. return -EMSGSIZE;
  5756. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
  5757. stats.rx_packets, DEVLINK_ATTR_PAD))
  5758. goto nla_put_failure;
  5759. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
  5760. stats.rx_bytes, DEVLINK_ATTR_PAD))
  5761. goto nla_put_failure;
  5762. nla_nest_end(msg, attr);
  5763. return 0;
  5764. nla_put_failure:
  5765. nla_nest_cancel(msg, attr);
  5766. return -EMSGSIZE;
  5767. }
  5768. static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
  5769. const struct devlink_trap_item *trap_item,
  5770. enum devlink_command cmd, u32 portid, u32 seq,
  5771. int flags)
  5772. {
  5773. struct devlink_trap_group_item *group_item = trap_item->group_item;
  5774. void *hdr;
  5775. int err;
  5776. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  5777. if (!hdr)
  5778. return -EMSGSIZE;
  5779. if (devlink_nl_put_handle(msg, devlink))
  5780. goto nla_put_failure;
  5781. if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
  5782. group_item->group->name))
  5783. goto nla_put_failure;
  5784. if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
  5785. goto nla_put_failure;
  5786. if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
  5787. goto nla_put_failure;
  5788. if (trap_item->trap->generic &&
  5789. nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
  5790. goto nla_put_failure;
  5791. if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
  5792. goto nla_put_failure;
  5793. err = devlink_trap_metadata_put(msg, trap_item->trap);
  5794. if (err)
  5795. goto nla_put_failure;
  5796. err = devlink_trap_stats_put(msg, trap_item->stats);
  5797. if (err)
  5798. goto nla_put_failure;
  5799. genlmsg_end(msg, hdr);
  5800. return 0;
  5801. nla_put_failure:
  5802. genlmsg_cancel(msg, hdr);
  5803. return -EMSGSIZE;
  5804. }
  5805. static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
  5806. struct genl_info *info)
  5807. {
  5808. struct netlink_ext_ack *extack = info->extack;
  5809. struct devlink *devlink = info->user_ptr[0];
  5810. struct devlink_trap_item *trap_item;
  5811. struct sk_buff *msg;
  5812. int err;
  5813. if (list_empty(&devlink->trap_list))
  5814. return -EOPNOTSUPP;
  5815. trap_item = devlink_trap_item_get_from_info(devlink, info);
  5816. if (!trap_item) {
  5817. NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
  5818. return -ENOENT;
  5819. }
  5820. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  5821. if (!msg)
  5822. return -ENOMEM;
  5823. err = devlink_nl_trap_fill(msg, devlink, trap_item,
  5824. DEVLINK_CMD_TRAP_NEW, info->snd_portid,
  5825. info->snd_seq, 0);
  5826. if (err)
  5827. goto err_trap_fill;
  5828. return genlmsg_reply(msg, info);
  5829. err_trap_fill:
  5830. nlmsg_free(msg);
  5831. return err;
  5832. }
  5833. static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
  5834. struct netlink_callback *cb)
  5835. {
  5836. struct devlink_trap_item *trap_item;
  5837. struct devlink *devlink;
  5838. int start = cb->args[0];
  5839. int idx = 0;
  5840. int err;
  5841. mutex_lock(&devlink_mutex);
  5842. list_for_each_entry(devlink, &devlink_list, list) {
  5843. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  5844. continue;
  5845. mutex_lock(&devlink->lock);
  5846. list_for_each_entry(trap_item, &devlink->trap_list, list) {
  5847. if (idx < start) {
  5848. idx++;
  5849. continue;
  5850. }
  5851. err = devlink_nl_trap_fill(msg, devlink, trap_item,
  5852. DEVLINK_CMD_TRAP_NEW,
  5853. NETLINK_CB(cb->skb).portid,
  5854. cb->nlh->nlmsg_seq,
  5855. NLM_F_MULTI);
  5856. if (err) {
  5857. mutex_unlock(&devlink->lock);
  5858. goto out;
  5859. }
  5860. idx++;
  5861. }
  5862. mutex_unlock(&devlink->lock);
  5863. }
  5864. out:
  5865. mutex_unlock(&devlink_mutex);
  5866. cb->args[0] = idx;
  5867. return msg->len;
  5868. }
  5869. static int __devlink_trap_action_set(struct devlink *devlink,
  5870. struct devlink_trap_item *trap_item,
  5871. enum devlink_trap_action trap_action,
  5872. struct netlink_ext_ack *extack)
  5873. {
  5874. int err;
  5875. if (trap_item->action != trap_action &&
  5876. trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
  5877. NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
  5878. return 0;
  5879. }
  5880. err = devlink->ops->trap_action_set(devlink, trap_item->trap,
  5881. trap_action, extack);
  5882. if (err)
  5883. return err;
  5884. trap_item->action = trap_action;
  5885. return 0;
  5886. }
  5887. static int devlink_trap_action_set(struct devlink *devlink,
  5888. struct devlink_trap_item *trap_item,
  5889. struct genl_info *info)
  5890. {
  5891. enum devlink_trap_action trap_action;
  5892. int err;
  5893. if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
  5894. return 0;
  5895. err = devlink_trap_action_get_from_info(info, &trap_action);
  5896. if (err) {
  5897. NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
  5898. return -EINVAL;
  5899. }
  5900. return __devlink_trap_action_set(devlink, trap_item, trap_action,
  5901. info->extack);
  5902. }
  5903. static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
  5904. struct genl_info *info)
  5905. {
  5906. struct netlink_ext_ack *extack = info->extack;
  5907. struct devlink *devlink = info->user_ptr[0];
  5908. struct devlink_trap_item *trap_item;
  5909. int err;
  5910. if (list_empty(&devlink->trap_list))
  5911. return -EOPNOTSUPP;
  5912. trap_item = devlink_trap_item_get_from_info(devlink, info);
  5913. if (!trap_item) {
  5914. NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
  5915. return -ENOENT;
  5916. }
  5917. err = devlink_trap_action_set(devlink, trap_item, info);
  5918. if (err)
  5919. return err;
  5920. return 0;
  5921. }
  5922. static struct devlink_trap_group_item *
  5923. devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
  5924. {
  5925. struct devlink_trap_group_item *group_item;
  5926. list_for_each_entry(group_item, &devlink->trap_group_list, list) {
  5927. if (!strcmp(group_item->group->name, name))
  5928. return group_item;
  5929. }
  5930. return NULL;
  5931. }
  5932. static struct devlink_trap_group_item *
  5933. devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
  5934. {
  5935. struct devlink_trap_group_item *group_item;
  5936. list_for_each_entry(group_item, &devlink->trap_group_list, list) {
  5937. if (group_item->group->id == id)
  5938. return group_item;
  5939. }
  5940. return NULL;
  5941. }
  5942. static struct devlink_trap_group_item *
  5943. devlink_trap_group_item_get_from_info(struct devlink *devlink,
  5944. struct genl_info *info)
  5945. {
  5946. char *name;
  5947. if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
  5948. return NULL;
  5949. name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
  5950. return devlink_trap_group_item_lookup(devlink, name);
  5951. }
  5952. static int
  5953. devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
  5954. const struct devlink_trap_group_item *group_item,
  5955. enum devlink_command cmd, u32 portid, u32 seq,
  5956. int flags)
  5957. {
  5958. void *hdr;
  5959. int err;
  5960. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  5961. if (!hdr)
  5962. return -EMSGSIZE;
  5963. if (devlink_nl_put_handle(msg, devlink))
  5964. goto nla_put_failure;
  5965. if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
  5966. group_item->group->name))
  5967. goto nla_put_failure;
  5968. if (group_item->group->generic &&
  5969. nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
  5970. goto nla_put_failure;
  5971. if (group_item->policer_item &&
  5972. nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
  5973. group_item->policer_item->policer->id))
  5974. goto nla_put_failure;
  5975. err = devlink_trap_stats_put(msg, group_item->stats);
  5976. if (err)
  5977. goto nla_put_failure;
  5978. genlmsg_end(msg, hdr);
  5979. return 0;
  5980. nla_put_failure:
  5981. genlmsg_cancel(msg, hdr);
  5982. return -EMSGSIZE;
  5983. }
  5984. static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
  5985. struct genl_info *info)
  5986. {
  5987. struct netlink_ext_ack *extack = info->extack;
  5988. struct devlink *devlink = info->user_ptr[0];
  5989. struct devlink_trap_group_item *group_item;
  5990. struct sk_buff *msg;
  5991. int err;
  5992. if (list_empty(&devlink->trap_group_list))
  5993. return -EOPNOTSUPP;
  5994. group_item = devlink_trap_group_item_get_from_info(devlink, info);
  5995. if (!group_item) {
  5996. NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
  5997. return -ENOENT;
  5998. }
  5999. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  6000. if (!msg)
  6001. return -ENOMEM;
  6002. err = devlink_nl_trap_group_fill(msg, devlink, group_item,
  6003. DEVLINK_CMD_TRAP_GROUP_NEW,
  6004. info->snd_portid, info->snd_seq, 0);
  6005. if (err)
  6006. goto err_trap_group_fill;
  6007. return genlmsg_reply(msg, info);
  6008. err_trap_group_fill:
  6009. nlmsg_free(msg);
  6010. return err;
  6011. }
  6012. static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
  6013. struct netlink_callback *cb)
  6014. {
  6015. enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
  6016. struct devlink_trap_group_item *group_item;
  6017. u32 portid = NETLINK_CB(cb->skb).portid;
  6018. struct devlink *devlink;
  6019. int start = cb->args[0];
  6020. int idx = 0;
  6021. int err;
  6022. mutex_lock(&devlink_mutex);
  6023. list_for_each_entry(devlink, &devlink_list, list) {
  6024. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  6025. continue;
  6026. mutex_lock(&devlink->lock);
  6027. list_for_each_entry(group_item, &devlink->trap_group_list,
  6028. list) {
  6029. if (idx < start) {
  6030. idx++;
  6031. continue;
  6032. }
  6033. err = devlink_nl_trap_group_fill(msg, devlink,
  6034. group_item, cmd,
  6035. portid,
  6036. cb->nlh->nlmsg_seq,
  6037. NLM_F_MULTI);
  6038. if (err) {
  6039. mutex_unlock(&devlink->lock);
  6040. goto out;
  6041. }
  6042. idx++;
  6043. }
  6044. mutex_unlock(&devlink->lock);
  6045. }
  6046. out:
  6047. mutex_unlock(&devlink_mutex);
  6048. cb->args[0] = idx;
  6049. return msg->len;
  6050. }
  6051. static int
  6052. __devlink_trap_group_action_set(struct devlink *devlink,
  6053. struct devlink_trap_group_item *group_item,
  6054. enum devlink_trap_action trap_action,
  6055. struct netlink_ext_ack *extack)
  6056. {
  6057. const char *group_name = group_item->group->name;
  6058. struct devlink_trap_item *trap_item;
  6059. int err;
  6060. if (devlink->ops->trap_group_action_set) {
  6061. err = devlink->ops->trap_group_action_set(devlink, group_item->group,
  6062. trap_action, extack);
  6063. if (err)
  6064. return err;
  6065. list_for_each_entry(trap_item, &devlink->trap_list, list) {
  6066. if (strcmp(trap_item->group_item->group->name, group_name))
  6067. continue;
  6068. if (trap_item->action != trap_action &&
  6069. trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
  6070. continue;
  6071. trap_item->action = trap_action;
  6072. }
  6073. return 0;
  6074. }
  6075. list_for_each_entry(trap_item, &devlink->trap_list, list) {
  6076. if (strcmp(trap_item->group_item->group->name, group_name))
  6077. continue;
  6078. err = __devlink_trap_action_set(devlink, trap_item,
  6079. trap_action, extack);
  6080. if (err)
  6081. return err;
  6082. }
  6083. return 0;
  6084. }
  6085. static int
  6086. devlink_trap_group_action_set(struct devlink *devlink,
  6087. struct devlink_trap_group_item *group_item,
  6088. struct genl_info *info, bool *p_modified)
  6089. {
  6090. enum devlink_trap_action trap_action;
  6091. int err;
  6092. if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
  6093. return 0;
  6094. err = devlink_trap_action_get_from_info(info, &trap_action);
  6095. if (err) {
  6096. NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
  6097. return -EINVAL;
  6098. }
  6099. err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
  6100. info->extack);
  6101. if (err)
  6102. return err;
  6103. *p_modified = true;
  6104. return 0;
  6105. }
  6106. static int devlink_trap_group_set(struct devlink *devlink,
  6107. struct devlink_trap_group_item *group_item,
  6108. struct genl_info *info)
  6109. {
  6110. struct devlink_trap_policer_item *policer_item;
  6111. struct netlink_ext_ack *extack = info->extack;
  6112. const struct devlink_trap_policer *policer;
  6113. struct nlattr **attrs = info->attrs;
  6114. int err;
  6115. if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
  6116. return 0;
  6117. if (!devlink->ops->trap_group_set)
  6118. return -EOPNOTSUPP;
  6119. policer_item = group_item->policer_item;
  6120. if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) {
  6121. u32 policer_id;
  6122. policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
  6123. policer_item = devlink_trap_policer_item_lookup(devlink,
  6124. policer_id);
  6125. if (policer_id && !policer_item) {
  6126. NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
  6127. return -ENOENT;
  6128. }
  6129. }
  6130. policer = policer_item ? policer_item->policer : NULL;
  6131. err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
  6132. extack);
  6133. if (err)
  6134. return err;
  6135. group_item->policer_item = policer_item;
  6136. return 0;
  6137. }
  6138. static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
  6139. struct genl_info *info)
  6140. {
  6141. struct netlink_ext_ack *extack = info->extack;
  6142. struct devlink *devlink = info->user_ptr[0];
  6143. struct devlink_trap_group_item *group_item;
  6144. bool modified = false;
  6145. int err;
  6146. if (list_empty(&devlink->trap_group_list))
  6147. return -EOPNOTSUPP;
  6148. group_item = devlink_trap_group_item_get_from_info(devlink, info);
  6149. if (!group_item) {
  6150. NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
  6151. return -ENOENT;
  6152. }
  6153. err = devlink_trap_group_action_set(devlink, group_item, info,
  6154. &modified);
  6155. if (err)
  6156. return err;
  6157. err = devlink_trap_group_set(devlink, group_item, info);
  6158. if (err)
  6159. goto err_trap_group_set;
  6160. return 0;
  6161. err_trap_group_set:
  6162. if (modified)
  6163. NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
  6164. return err;
  6165. }
  6166. static struct devlink_trap_policer_item *
  6167. devlink_trap_policer_item_get_from_info(struct devlink *devlink,
  6168. struct genl_info *info)
  6169. {
  6170. u32 id;
  6171. if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
  6172. return NULL;
  6173. id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
  6174. return devlink_trap_policer_item_lookup(devlink, id);
  6175. }
  6176. static int
  6177. devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
  6178. const struct devlink_trap_policer *policer)
  6179. {
  6180. struct nlattr *attr;
  6181. u64 drops;
  6182. int err;
  6183. if (!devlink->ops->trap_policer_counter_get)
  6184. return 0;
  6185. err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
  6186. if (err)
  6187. return err;
  6188. attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
  6189. if (!attr)
  6190. return -EMSGSIZE;
  6191. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
  6192. DEVLINK_ATTR_PAD))
  6193. goto nla_put_failure;
  6194. nla_nest_end(msg, attr);
  6195. return 0;
  6196. nla_put_failure:
  6197. nla_nest_cancel(msg, attr);
  6198. return -EMSGSIZE;
  6199. }
  6200. static int
  6201. devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
  6202. const struct devlink_trap_policer_item *policer_item,
  6203. enum devlink_command cmd, u32 portid, u32 seq,
  6204. int flags)
  6205. {
  6206. void *hdr;
  6207. int err;
  6208. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  6209. if (!hdr)
  6210. return -EMSGSIZE;
  6211. if (devlink_nl_put_handle(msg, devlink))
  6212. goto nla_put_failure;
  6213. if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
  6214. policer_item->policer->id))
  6215. goto nla_put_failure;
  6216. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
  6217. policer_item->rate, DEVLINK_ATTR_PAD))
  6218. goto nla_put_failure;
  6219. if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
  6220. policer_item->burst, DEVLINK_ATTR_PAD))
  6221. goto nla_put_failure;
  6222. err = devlink_trap_policer_stats_put(msg, devlink,
  6223. policer_item->policer);
  6224. if (err)
  6225. goto nla_put_failure;
  6226. genlmsg_end(msg, hdr);
  6227. return 0;
  6228. nla_put_failure:
  6229. genlmsg_cancel(msg, hdr);
  6230. return -EMSGSIZE;
  6231. }
  6232. static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
  6233. struct genl_info *info)
  6234. {
  6235. struct devlink_trap_policer_item *policer_item;
  6236. struct netlink_ext_ack *extack = info->extack;
  6237. struct devlink *devlink = info->user_ptr[0];
  6238. struct sk_buff *msg;
  6239. int err;
  6240. if (list_empty(&devlink->trap_policer_list))
  6241. return -EOPNOTSUPP;
  6242. policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
  6243. if (!policer_item) {
  6244. NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
  6245. return -ENOENT;
  6246. }
  6247. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  6248. if (!msg)
  6249. return -ENOMEM;
  6250. err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
  6251. DEVLINK_CMD_TRAP_POLICER_NEW,
  6252. info->snd_portid, info->snd_seq, 0);
  6253. if (err)
  6254. goto err_trap_policer_fill;
  6255. return genlmsg_reply(msg, info);
  6256. err_trap_policer_fill:
  6257. nlmsg_free(msg);
  6258. return err;
  6259. }
  6260. static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
  6261. struct netlink_callback *cb)
  6262. {
  6263. enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
  6264. struct devlink_trap_policer_item *policer_item;
  6265. u32 portid = NETLINK_CB(cb->skb).portid;
  6266. struct devlink *devlink;
  6267. int start = cb->args[0];
  6268. int idx = 0;
  6269. int err;
  6270. mutex_lock(&devlink_mutex);
  6271. list_for_each_entry(devlink, &devlink_list, list) {
  6272. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  6273. continue;
  6274. mutex_lock(&devlink->lock);
  6275. list_for_each_entry(policer_item, &devlink->trap_policer_list,
  6276. list) {
  6277. if (idx < start) {
  6278. idx++;
  6279. continue;
  6280. }
  6281. err = devlink_nl_trap_policer_fill(msg, devlink,
  6282. policer_item, cmd,
  6283. portid,
  6284. cb->nlh->nlmsg_seq,
  6285. NLM_F_MULTI);
  6286. if (err) {
  6287. mutex_unlock(&devlink->lock);
  6288. goto out;
  6289. }
  6290. idx++;
  6291. }
  6292. mutex_unlock(&devlink->lock);
  6293. }
  6294. out:
  6295. mutex_unlock(&devlink_mutex);
  6296. cb->args[0] = idx;
  6297. return msg->len;
  6298. }
  6299. static int
  6300. devlink_trap_policer_set(struct devlink *devlink,
  6301. struct devlink_trap_policer_item *policer_item,
  6302. struct genl_info *info)
  6303. {
  6304. struct netlink_ext_ack *extack = info->extack;
  6305. struct nlattr **attrs = info->attrs;
  6306. u64 rate, burst;
  6307. int err;
  6308. rate = policer_item->rate;
  6309. burst = policer_item->burst;
  6310. if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
  6311. rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
  6312. if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
  6313. burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
  6314. if (rate < policer_item->policer->min_rate) {
  6315. NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
  6316. return -EINVAL;
  6317. }
  6318. if (rate > policer_item->policer->max_rate) {
  6319. NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
  6320. return -EINVAL;
  6321. }
  6322. if (burst < policer_item->policer->min_burst) {
  6323. NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
  6324. return -EINVAL;
  6325. }
  6326. if (burst > policer_item->policer->max_burst) {
  6327. NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
  6328. return -EINVAL;
  6329. }
  6330. err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
  6331. rate, burst, info->extack);
  6332. if (err)
  6333. return err;
  6334. policer_item->rate = rate;
  6335. policer_item->burst = burst;
  6336. return 0;
  6337. }
  6338. static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
  6339. struct genl_info *info)
  6340. {
  6341. struct devlink_trap_policer_item *policer_item;
  6342. struct netlink_ext_ack *extack = info->extack;
  6343. struct devlink *devlink = info->user_ptr[0];
  6344. if (list_empty(&devlink->trap_policer_list))
  6345. return -EOPNOTSUPP;
  6346. if (!devlink->ops->trap_policer_set)
  6347. return -EOPNOTSUPP;
  6348. policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
  6349. if (!policer_item) {
  6350. NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
  6351. return -ENOENT;
  6352. }
  6353. return devlink_trap_policer_set(devlink, policer_item, info);
  6354. }
  6355. static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
  6356. [DEVLINK_ATTR_UNSPEC] = { .strict_start_type =
  6357. DEVLINK_ATTR_TRAP_POLICER_ID },
  6358. [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
  6359. [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
  6360. [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
  6361. [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO,
  6362. DEVLINK_PORT_TYPE_IB),
  6363. [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
  6364. [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
  6365. [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
  6366. [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
  6367. [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
  6368. [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
  6369. [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
  6370. [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
  6371. [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY,
  6372. DEVLINK_ESWITCH_MODE_SWITCHDEV),
  6373. [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
  6374. [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
  6375. [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
  6376. [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
  6377. [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
  6378. [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
  6379. [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
  6380. [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
  6381. [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
  6382. [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
  6383. [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
  6384. [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 },
  6385. [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 },
  6386. [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
  6387. [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
  6388. [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
  6389. [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
  6390. [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
  6391. [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] =
  6392. NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS),
  6393. [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
  6394. [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
  6395. [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
  6396. [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 },
  6397. [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 },
  6398. [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 },
  6399. [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 },
  6400. [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 },
  6401. [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 },
  6402. [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 },
  6403. [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
  6404. [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
  6405. DEVLINK_RELOAD_ACTION_MAX),
  6406. [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
  6407. };
  6408. static const struct genl_small_ops devlink_nl_ops[] = {
  6409. {
  6410. .cmd = DEVLINK_CMD_GET,
  6411. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6412. .doit = devlink_nl_cmd_get_doit,
  6413. .dumpit = devlink_nl_cmd_get_dumpit,
  6414. /* can be retrieved by unprivileged users */
  6415. },
  6416. {
  6417. .cmd = DEVLINK_CMD_PORT_GET,
  6418. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6419. .doit = devlink_nl_cmd_port_get_doit,
  6420. .dumpit = devlink_nl_cmd_port_get_dumpit,
  6421. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  6422. /* can be retrieved by unprivileged users */
  6423. },
  6424. {
  6425. .cmd = DEVLINK_CMD_PORT_SET,
  6426. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6427. .doit = devlink_nl_cmd_port_set_doit,
  6428. .flags = GENL_ADMIN_PERM,
  6429. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  6430. },
  6431. {
  6432. .cmd = DEVLINK_CMD_PORT_SPLIT,
  6433. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6434. .doit = devlink_nl_cmd_port_split_doit,
  6435. .flags = GENL_ADMIN_PERM,
  6436. .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
  6437. },
  6438. {
  6439. .cmd = DEVLINK_CMD_PORT_UNSPLIT,
  6440. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6441. .doit = devlink_nl_cmd_port_unsplit_doit,
  6442. .flags = GENL_ADMIN_PERM,
  6443. .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
  6444. },
  6445. {
  6446. .cmd = DEVLINK_CMD_SB_GET,
  6447. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6448. .doit = devlink_nl_cmd_sb_get_doit,
  6449. .dumpit = devlink_nl_cmd_sb_get_dumpit,
  6450. /* can be retrieved by unprivileged users */
  6451. },
  6452. {
  6453. .cmd = DEVLINK_CMD_SB_POOL_GET,
  6454. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6455. .doit = devlink_nl_cmd_sb_pool_get_doit,
  6456. .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
  6457. /* can be retrieved by unprivileged users */
  6458. },
  6459. {
  6460. .cmd = DEVLINK_CMD_SB_POOL_SET,
  6461. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6462. .doit = devlink_nl_cmd_sb_pool_set_doit,
  6463. .flags = GENL_ADMIN_PERM,
  6464. },
  6465. {
  6466. .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
  6467. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6468. .doit = devlink_nl_cmd_sb_port_pool_get_doit,
  6469. .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
  6470. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  6471. /* can be retrieved by unprivileged users */
  6472. },
  6473. {
  6474. .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
  6475. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6476. .doit = devlink_nl_cmd_sb_port_pool_set_doit,
  6477. .flags = GENL_ADMIN_PERM,
  6478. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  6479. },
  6480. {
  6481. .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
  6482. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6483. .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
  6484. .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
  6485. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  6486. /* can be retrieved by unprivileged users */
  6487. },
  6488. {
  6489. .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
  6490. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6491. .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
  6492. .flags = GENL_ADMIN_PERM,
  6493. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  6494. },
  6495. {
  6496. .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
  6497. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6498. .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
  6499. .flags = GENL_ADMIN_PERM,
  6500. },
  6501. {
  6502. .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
  6503. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6504. .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
  6505. .flags = GENL_ADMIN_PERM,
  6506. },
  6507. {
  6508. .cmd = DEVLINK_CMD_ESWITCH_GET,
  6509. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6510. .doit = devlink_nl_cmd_eswitch_get_doit,
  6511. .flags = GENL_ADMIN_PERM,
  6512. .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
  6513. },
  6514. {
  6515. .cmd = DEVLINK_CMD_ESWITCH_SET,
  6516. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6517. .doit = devlink_nl_cmd_eswitch_set_doit,
  6518. .flags = GENL_ADMIN_PERM,
  6519. .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
  6520. },
  6521. {
  6522. .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
  6523. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6524. .doit = devlink_nl_cmd_dpipe_table_get,
  6525. /* can be retrieved by unprivileged users */
  6526. },
  6527. {
  6528. .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
  6529. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6530. .doit = devlink_nl_cmd_dpipe_entries_get,
  6531. /* can be retrieved by unprivileged users */
  6532. },
  6533. {
  6534. .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
  6535. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6536. .doit = devlink_nl_cmd_dpipe_headers_get,
  6537. /* can be retrieved by unprivileged users */
  6538. },
  6539. {
  6540. .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
  6541. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6542. .doit = devlink_nl_cmd_dpipe_table_counters_set,
  6543. .flags = GENL_ADMIN_PERM,
  6544. },
  6545. {
  6546. .cmd = DEVLINK_CMD_RESOURCE_SET,
  6547. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6548. .doit = devlink_nl_cmd_resource_set,
  6549. .flags = GENL_ADMIN_PERM,
  6550. },
  6551. {
  6552. .cmd = DEVLINK_CMD_RESOURCE_DUMP,
  6553. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6554. .doit = devlink_nl_cmd_resource_dump,
  6555. /* can be retrieved by unprivileged users */
  6556. },
  6557. {
  6558. .cmd = DEVLINK_CMD_RELOAD,
  6559. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6560. .doit = devlink_nl_cmd_reload,
  6561. .flags = GENL_ADMIN_PERM,
  6562. .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
  6563. },
  6564. {
  6565. .cmd = DEVLINK_CMD_PARAM_GET,
  6566. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6567. .doit = devlink_nl_cmd_param_get_doit,
  6568. .dumpit = devlink_nl_cmd_param_get_dumpit,
  6569. /* can be retrieved by unprivileged users */
  6570. },
  6571. {
  6572. .cmd = DEVLINK_CMD_PARAM_SET,
  6573. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6574. .doit = devlink_nl_cmd_param_set_doit,
  6575. .flags = GENL_ADMIN_PERM,
  6576. },
  6577. {
  6578. .cmd = DEVLINK_CMD_PORT_PARAM_GET,
  6579. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6580. .doit = devlink_nl_cmd_port_param_get_doit,
  6581. .dumpit = devlink_nl_cmd_port_param_get_dumpit,
  6582. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  6583. /* can be retrieved by unprivileged users */
  6584. },
  6585. {
  6586. .cmd = DEVLINK_CMD_PORT_PARAM_SET,
  6587. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6588. .doit = devlink_nl_cmd_port_param_set_doit,
  6589. .flags = GENL_ADMIN_PERM,
  6590. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  6591. },
  6592. {
  6593. .cmd = DEVLINK_CMD_REGION_GET,
  6594. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6595. .doit = devlink_nl_cmd_region_get_doit,
  6596. .dumpit = devlink_nl_cmd_region_get_dumpit,
  6597. .flags = GENL_ADMIN_PERM,
  6598. },
  6599. {
  6600. .cmd = DEVLINK_CMD_REGION_NEW,
  6601. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6602. .doit = devlink_nl_cmd_region_new,
  6603. .flags = GENL_ADMIN_PERM,
  6604. },
  6605. {
  6606. .cmd = DEVLINK_CMD_REGION_DEL,
  6607. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6608. .doit = devlink_nl_cmd_region_del,
  6609. .flags = GENL_ADMIN_PERM,
  6610. },
  6611. {
  6612. .cmd = DEVLINK_CMD_REGION_READ,
  6613. .validate = GENL_DONT_VALIDATE_STRICT |
  6614. GENL_DONT_VALIDATE_DUMP_STRICT,
  6615. .dumpit = devlink_nl_cmd_region_read_dumpit,
  6616. .flags = GENL_ADMIN_PERM,
  6617. },
  6618. {
  6619. .cmd = DEVLINK_CMD_INFO_GET,
  6620. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6621. .doit = devlink_nl_cmd_info_get_doit,
  6622. .dumpit = devlink_nl_cmd_info_get_dumpit,
  6623. /* can be retrieved by unprivileged users */
  6624. },
  6625. {
  6626. .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
  6627. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6628. .doit = devlink_nl_cmd_health_reporter_get_doit,
  6629. .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
  6630. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
  6631. DEVLINK_NL_FLAG_NO_LOCK,
  6632. /* can be retrieved by unprivileged users */
  6633. },
  6634. {
  6635. .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
  6636. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6637. .doit = devlink_nl_cmd_health_reporter_set_doit,
  6638. .flags = GENL_ADMIN_PERM,
  6639. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
  6640. DEVLINK_NL_FLAG_NO_LOCK,
  6641. },
  6642. {
  6643. .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
  6644. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6645. .doit = devlink_nl_cmd_health_reporter_recover_doit,
  6646. .flags = GENL_ADMIN_PERM,
  6647. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
  6648. DEVLINK_NL_FLAG_NO_LOCK,
  6649. },
  6650. {
  6651. .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
  6652. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6653. .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
  6654. .flags = GENL_ADMIN_PERM,
  6655. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
  6656. DEVLINK_NL_FLAG_NO_LOCK,
  6657. },
  6658. {
  6659. .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
  6660. .validate = GENL_DONT_VALIDATE_STRICT |
  6661. GENL_DONT_VALIDATE_DUMP_STRICT,
  6662. .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
  6663. .flags = GENL_ADMIN_PERM,
  6664. },
  6665. {
  6666. .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
  6667. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6668. .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
  6669. .flags = GENL_ADMIN_PERM,
  6670. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
  6671. DEVLINK_NL_FLAG_NO_LOCK,
  6672. },
  6673. {
  6674. .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
  6675. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6676. .doit = devlink_nl_cmd_health_reporter_test_doit,
  6677. .flags = GENL_ADMIN_PERM,
  6678. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
  6679. DEVLINK_NL_FLAG_NO_LOCK,
  6680. },
  6681. {
  6682. .cmd = DEVLINK_CMD_FLASH_UPDATE,
  6683. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  6684. .doit = devlink_nl_cmd_flash_update,
  6685. .flags = GENL_ADMIN_PERM,
  6686. },
  6687. {
  6688. .cmd = DEVLINK_CMD_TRAP_GET,
  6689. .doit = devlink_nl_cmd_trap_get_doit,
  6690. .dumpit = devlink_nl_cmd_trap_get_dumpit,
  6691. /* can be retrieved by unprivileged users */
  6692. },
  6693. {
  6694. .cmd = DEVLINK_CMD_TRAP_SET,
  6695. .doit = devlink_nl_cmd_trap_set_doit,
  6696. .flags = GENL_ADMIN_PERM,
  6697. },
  6698. {
  6699. .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
  6700. .doit = devlink_nl_cmd_trap_group_get_doit,
  6701. .dumpit = devlink_nl_cmd_trap_group_get_dumpit,
  6702. /* can be retrieved by unprivileged users */
  6703. },
  6704. {
  6705. .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
  6706. .doit = devlink_nl_cmd_trap_group_set_doit,
  6707. .flags = GENL_ADMIN_PERM,
  6708. },
  6709. {
  6710. .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
  6711. .doit = devlink_nl_cmd_trap_policer_get_doit,
  6712. .dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
  6713. /* can be retrieved by unprivileged users */
  6714. },
  6715. {
  6716. .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
  6717. .doit = devlink_nl_cmd_trap_policer_set_doit,
  6718. .flags = GENL_ADMIN_PERM,
  6719. },
  6720. };
  6721. static struct genl_family devlink_nl_family __ro_after_init = {
  6722. .name = DEVLINK_GENL_NAME,
  6723. .version = DEVLINK_GENL_VERSION,
  6724. .maxattr = DEVLINK_ATTR_MAX,
  6725. .policy = devlink_nl_policy,
  6726. .netnsok = true,
  6727. .pre_doit = devlink_nl_pre_doit,
  6728. .post_doit = devlink_nl_post_doit,
  6729. .module = THIS_MODULE,
  6730. .small_ops = devlink_nl_ops,
  6731. .n_small_ops = ARRAY_SIZE(devlink_nl_ops),
  6732. .mcgrps = devlink_nl_mcgrps,
  6733. .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
  6734. };
  6735. static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
  6736. {
  6737. const struct devlink_reload_combination *comb;
  6738. int i;
  6739. if (!devlink_reload_supported(ops)) {
  6740. if (WARN_ON(ops->reload_actions))
  6741. return false;
  6742. return true;
  6743. }
  6744. if (WARN_ON(!ops->reload_actions ||
  6745. ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
  6746. ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
  6747. return false;
  6748. if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
  6749. ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
  6750. return false;
  6751. for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) {
  6752. comb = &devlink_reload_invalid_combinations[i];
  6753. if (ops->reload_actions == BIT(comb->action) &&
  6754. ops->reload_limits == BIT(comb->limit))
  6755. return false;
  6756. }
  6757. return true;
  6758. }
  6759. /**
  6760. * devlink_alloc - Allocate new devlink instance resources
  6761. *
  6762. * @ops: ops
  6763. * @priv_size: size of user private data
  6764. *
  6765. * Allocate new devlink instance resources, including devlink index
  6766. * and name.
  6767. */
  6768. struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
  6769. {
  6770. struct devlink *devlink;
  6771. if (WARN_ON(!ops))
  6772. return NULL;
  6773. if (!devlink_reload_actions_valid(ops))
  6774. return NULL;
  6775. devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
  6776. if (!devlink)
  6777. return NULL;
  6778. devlink->ops = ops;
  6779. xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
  6780. __devlink_net_set(devlink, &init_net);
  6781. INIT_LIST_HEAD(&devlink->port_list);
  6782. INIT_LIST_HEAD(&devlink->sb_list);
  6783. INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
  6784. INIT_LIST_HEAD(&devlink->resource_list);
  6785. INIT_LIST_HEAD(&devlink->param_list);
  6786. INIT_LIST_HEAD(&devlink->region_list);
  6787. INIT_LIST_HEAD(&devlink->reporter_list);
  6788. INIT_LIST_HEAD(&devlink->trap_list);
  6789. INIT_LIST_HEAD(&devlink->trap_group_list);
  6790. INIT_LIST_HEAD(&devlink->trap_policer_list);
  6791. mutex_init(&devlink->lock);
  6792. mutex_init(&devlink->reporters_lock);
  6793. return devlink;
  6794. }
  6795. EXPORT_SYMBOL_GPL(devlink_alloc);
  6796. /**
  6797. * devlink_register - Register devlink instance
  6798. *
  6799. * @devlink: devlink
  6800. * @dev: parent device
  6801. */
  6802. int devlink_register(struct devlink *devlink, struct device *dev)
  6803. {
  6804. devlink->dev = dev;
  6805. devlink->registered = true;
  6806. mutex_lock(&devlink_mutex);
  6807. list_add_tail(&devlink->list, &devlink_list);
  6808. devlink_notify(devlink, DEVLINK_CMD_NEW);
  6809. mutex_unlock(&devlink_mutex);
  6810. return 0;
  6811. }
  6812. EXPORT_SYMBOL_GPL(devlink_register);
  6813. /**
  6814. * devlink_unregister - Unregister devlink instance
  6815. *
  6816. * @devlink: devlink
  6817. */
  6818. void devlink_unregister(struct devlink *devlink)
  6819. {
  6820. mutex_lock(&devlink_mutex);
  6821. WARN_ON(devlink_reload_supported(devlink->ops) &&
  6822. devlink->reload_enabled);
  6823. devlink_notify(devlink, DEVLINK_CMD_DEL);
  6824. list_del(&devlink->list);
  6825. mutex_unlock(&devlink_mutex);
  6826. }
  6827. EXPORT_SYMBOL_GPL(devlink_unregister);
  6828. /**
  6829. * devlink_reload_enable - Enable reload of devlink instance
  6830. *
  6831. * @devlink: devlink
  6832. *
  6833. * Should be called at end of device initialization
  6834. * process when reload operation is supported.
  6835. */
  6836. void devlink_reload_enable(struct devlink *devlink)
  6837. {
  6838. mutex_lock(&devlink_mutex);
  6839. devlink->reload_enabled = true;
  6840. mutex_unlock(&devlink_mutex);
  6841. }
  6842. EXPORT_SYMBOL_GPL(devlink_reload_enable);
  6843. /**
  6844. * devlink_reload_disable - Disable reload of devlink instance
  6845. *
  6846. * @devlink: devlink
  6847. *
  6848. * Should be called at the beginning of device cleanup
  6849. * process when reload operation is supported.
  6850. */
  6851. void devlink_reload_disable(struct devlink *devlink)
  6852. {
  6853. mutex_lock(&devlink_mutex);
  6854. /* Mutex is taken which ensures that no reload operation is in
  6855. * progress while setting up forbidded flag.
  6856. */
  6857. devlink->reload_enabled = false;
  6858. mutex_unlock(&devlink_mutex);
  6859. }
  6860. EXPORT_SYMBOL_GPL(devlink_reload_disable);
  6861. /**
  6862. * devlink_free - Free devlink instance resources
  6863. *
  6864. * @devlink: devlink
  6865. */
  6866. void devlink_free(struct devlink *devlink)
  6867. {
  6868. mutex_destroy(&devlink->reporters_lock);
  6869. mutex_destroy(&devlink->lock);
  6870. WARN_ON(!list_empty(&devlink->trap_policer_list));
  6871. WARN_ON(!list_empty(&devlink->trap_group_list));
  6872. WARN_ON(!list_empty(&devlink->trap_list));
  6873. WARN_ON(!list_empty(&devlink->reporter_list));
  6874. WARN_ON(!list_empty(&devlink->region_list));
  6875. WARN_ON(!list_empty(&devlink->param_list));
  6876. WARN_ON(!list_empty(&devlink->resource_list));
  6877. WARN_ON(!list_empty(&devlink->dpipe_table_list));
  6878. WARN_ON(!list_empty(&devlink->sb_list));
  6879. WARN_ON(!list_empty(&devlink->port_list));
  6880. xa_destroy(&devlink->snapshot_ids);
  6881. kfree(devlink);
  6882. }
  6883. EXPORT_SYMBOL_GPL(devlink_free);
  6884. static void devlink_port_type_warn(struct work_struct *work)
  6885. {
  6886. WARN(true, "Type was not set for devlink port.");
  6887. }
  6888. static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
  6889. {
  6890. /* Ignore CPU and DSA flavours. */
  6891. return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
  6892. devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
  6893. devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
  6894. }
  6895. #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
  6896. static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
  6897. {
  6898. if (!devlink_port_type_should_warn(devlink_port))
  6899. return;
  6900. /* Schedule a work to WARN in case driver does not set port
  6901. * type within timeout.
  6902. */
  6903. schedule_delayed_work(&devlink_port->type_warn_dw,
  6904. DEVLINK_PORT_TYPE_WARN_TIMEOUT);
  6905. }
  6906. static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
  6907. {
  6908. if (!devlink_port_type_should_warn(devlink_port))
  6909. return;
  6910. cancel_delayed_work_sync(&devlink_port->type_warn_dw);
  6911. }
  6912. /**
  6913. * devlink_port_register - Register devlink port
  6914. *
  6915. * @devlink: devlink
  6916. * @devlink_port: devlink port
  6917. * @port_index: driver-specific numerical identifier of the port
  6918. *
  6919. * Register devlink port with provided port index. User can use
  6920. * any indexing, even hw-related one. devlink_port structure
  6921. * is convenient to be embedded inside user driver private structure.
  6922. * Note that the caller should take care of zeroing the devlink_port
  6923. * structure.
  6924. */
  6925. int devlink_port_register(struct devlink *devlink,
  6926. struct devlink_port *devlink_port,
  6927. unsigned int port_index)
  6928. {
  6929. mutex_lock(&devlink->lock);
  6930. if (devlink_port_index_exists(devlink, port_index)) {
  6931. mutex_unlock(&devlink->lock);
  6932. return -EEXIST;
  6933. }
  6934. devlink_port->devlink = devlink;
  6935. devlink_port->index = port_index;
  6936. devlink_port->registered = true;
  6937. spin_lock_init(&devlink_port->type_lock);
  6938. INIT_LIST_HEAD(&devlink_port->reporter_list);
  6939. mutex_init(&devlink_port->reporters_lock);
  6940. list_add_tail(&devlink_port->list, &devlink->port_list);
  6941. INIT_LIST_HEAD(&devlink_port->param_list);
  6942. INIT_LIST_HEAD(&devlink_port->region_list);
  6943. mutex_unlock(&devlink->lock);
  6944. INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
  6945. devlink_port_type_warn_schedule(devlink_port);
  6946. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  6947. return 0;
  6948. }
  6949. EXPORT_SYMBOL_GPL(devlink_port_register);
  6950. /**
  6951. * devlink_port_unregister - Unregister devlink port
  6952. *
  6953. * @devlink_port: devlink port
  6954. */
  6955. void devlink_port_unregister(struct devlink_port *devlink_port)
  6956. {
  6957. struct devlink *devlink = devlink_port->devlink;
  6958. devlink_port_type_warn_cancel(devlink_port);
  6959. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
  6960. mutex_lock(&devlink->lock);
  6961. list_del(&devlink_port->list);
  6962. mutex_unlock(&devlink->lock);
  6963. WARN_ON(!list_empty(&devlink_port->reporter_list));
  6964. WARN_ON(!list_empty(&devlink_port->region_list));
  6965. mutex_destroy(&devlink_port->reporters_lock);
  6966. }
  6967. EXPORT_SYMBOL_GPL(devlink_port_unregister);
  6968. static void __devlink_port_type_set(struct devlink_port *devlink_port,
  6969. enum devlink_port_type type,
  6970. void *type_dev)
  6971. {
  6972. if (WARN_ON(!devlink_port->registered))
  6973. return;
  6974. devlink_port_type_warn_cancel(devlink_port);
  6975. spin_lock_bh(&devlink_port->type_lock);
  6976. devlink_port->type = type;
  6977. devlink_port->type_dev = type_dev;
  6978. spin_unlock_bh(&devlink_port->type_lock);
  6979. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  6980. }
  6981. static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
  6982. struct net_device *netdev)
  6983. {
  6984. const struct net_device_ops *ops = netdev->netdev_ops;
  6985. /* If driver registers devlink port, it should set devlink port
  6986. * attributes accordingly so the compat functions are called
  6987. * and the original ops are not used.
  6988. */
  6989. if (ops->ndo_get_phys_port_name) {
  6990. /* Some drivers use the same set of ndos for netdevs
  6991. * that have devlink_port registered and also for
  6992. * those who don't. Make sure that ndo_get_phys_port_name
  6993. * returns -EOPNOTSUPP here in case it is defined.
  6994. * Warn if not.
  6995. */
  6996. char name[IFNAMSIZ];
  6997. int err;
  6998. err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
  6999. WARN_ON(err != -EOPNOTSUPP);
  7000. }
  7001. if (ops->ndo_get_port_parent_id) {
  7002. /* Some drivers use the same set of ndos for netdevs
  7003. * that have devlink_port registered and also for
  7004. * those who don't. Make sure that ndo_get_port_parent_id
  7005. * returns -EOPNOTSUPP here in case it is defined.
  7006. * Warn if not.
  7007. */
  7008. struct netdev_phys_item_id ppid;
  7009. int err;
  7010. err = ops->ndo_get_port_parent_id(netdev, &ppid);
  7011. WARN_ON(err != -EOPNOTSUPP);
  7012. }
  7013. }
  7014. /**
  7015. * devlink_port_type_eth_set - Set port type to Ethernet
  7016. *
  7017. * @devlink_port: devlink port
  7018. * @netdev: related netdevice
  7019. */
  7020. void devlink_port_type_eth_set(struct devlink_port *devlink_port,
  7021. struct net_device *netdev)
  7022. {
  7023. if (netdev)
  7024. devlink_port_type_netdev_checks(devlink_port, netdev);
  7025. else
  7026. dev_warn(devlink_port->devlink->dev,
  7027. "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
  7028. devlink_port->index);
  7029. __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
  7030. }
  7031. EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
  7032. /**
  7033. * devlink_port_type_ib_set - Set port type to InfiniBand
  7034. *
  7035. * @devlink_port: devlink port
  7036. * @ibdev: related IB device
  7037. */
  7038. void devlink_port_type_ib_set(struct devlink_port *devlink_port,
  7039. struct ib_device *ibdev)
  7040. {
  7041. __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
  7042. }
  7043. EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
  7044. /**
  7045. * devlink_port_type_clear - Clear port type
  7046. *
  7047. * @devlink_port: devlink port
  7048. */
  7049. void devlink_port_type_clear(struct devlink_port *devlink_port)
  7050. {
  7051. __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
  7052. devlink_port_type_warn_schedule(devlink_port);
  7053. }
  7054. EXPORT_SYMBOL_GPL(devlink_port_type_clear);
  7055. static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
  7056. enum devlink_port_flavour flavour)
  7057. {
  7058. struct devlink_port_attrs *attrs = &devlink_port->attrs;
  7059. devlink_port->attrs_set = true;
  7060. attrs->flavour = flavour;
  7061. if (attrs->switch_id.id_len) {
  7062. devlink_port->switch_port = true;
  7063. if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
  7064. attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
  7065. } else {
  7066. devlink_port->switch_port = false;
  7067. }
  7068. return 0;
  7069. }
  7070. /**
  7071. * devlink_port_attrs_set - Set port attributes
  7072. *
  7073. * @devlink_port: devlink port
  7074. * @attrs: devlink port attrs
  7075. */
  7076. void devlink_port_attrs_set(struct devlink_port *devlink_port,
  7077. struct devlink_port_attrs *attrs)
  7078. {
  7079. int ret;
  7080. if (WARN_ON(devlink_port->registered))
  7081. return;
  7082. devlink_port->attrs = *attrs;
  7083. ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
  7084. if (ret)
  7085. return;
  7086. WARN_ON(attrs->splittable && attrs->split);
  7087. }
  7088. EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
  7089. /**
  7090. * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
  7091. *
  7092. * @devlink_port: devlink port
  7093. * @controller: associated controller number for the devlink port instance
  7094. * @pf: associated PF for the devlink port instance
  7095. * @external: indicates if the port is for an external controller
  7096. */
  7097. void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
  7098. u16 pf, bool external)
  7099. {
  7100. struct devlink_port_attrs *attrs = &devlink_port->attrs;
  7101. int ret;
  7102. if (WARN_ON(devlink_port->registered))
  7103. return;
  7104. ret = __devlink_port_attrs_set(devlink_port,
  7105. DEVLINK_PORT_FLAVOUR_PCI_PF);
  7106. if (ret)
  7107. return;
  7108. attrs->pci_pf.controller = controller;
  7109. attrs->pci_pf.pf = pf;
  7110. attrs->pci_pf.external = external;
  7111. }
  7112. EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
  7113. /**
  7114. * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
  7115. *
  7116. * @devlink_port: devlink port
  7117. * @controller: associated controller number for the devlink port instance
  7118. * @pf: associated PF for the devlink port instance
  7119. * @vf: associated VF of a PF for the devlink port instance
  7120. * @external: indicates if the port is for an external controller
  7121. */
  7122. void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
  7123. u16 pf, u16 vf, bool external)
  7124. {
  7125. struct devlink_port_attrs *attrs = &devlink_port->attrs;
  7126. int ret;
  7127. if (WARN_ON(devlink_port->registered))
  7128. return;
  7129. ret = __devlink_port_attrs_set(devlink_port,
  7130. DEVLINK_PORT_FLAVOUR_PCI_VF);
  7131. if (ret)
  7132. return;
  7133. attrs->pci_vf.controller = controller;
  7134. attrs->pci_vf.pf = pf;
  7135. attrs->pci_vf.vf = vf;
  7136. attrs->pci_vf.external = external;
  7137. }
  7138. EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
  7139. static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
  7140. char *name, size_t len)
  7141. {
  7142. struct devlink_port_attrs *attrs = &devlink_port->attrs;
  7143. int n = 0;
  7144. if (!devlink_port->attrs_set)
  7145. return -EOPNOTSUPP;
  7146. switch (attrs->flavour) {
  7147. case DEVLINK_PORT_FLAVOUR_PHYSICAL:
  7148. if (!attrs->split)
  7149. n = snprintf(name, len, "p%u", attrs->phys.port_number);
  7150. else
  7151. n = snprintf(name, len, "p%us%u",
  7152. attrs->phys.port_number,
  7153. attrs->phys.split_subport_number);
  7154. break;
  7155. case DEVLINK_PORT_FLAVOUR_CPU:
  7156. case DEVLINK_PORT_FLAVOUR_DSA:
  7157. case DEVLINK_PORT_FLAVOUR_UNUSED:
  7158. /* As CPU and DSA ports do not have a netdevice associated
  7159. * case should not ever happen.
  7160. */
  7161. WARN_ON(1);
  7162. return -EINVAL;
  7163. case DEVLINK_PORT_FLAVOUR_PCI_PF:
  7164. if (attrs->pci_pf.external) {
  7165. n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
  7166. if (n >= len)
  7167. return -EINVAL;
  7168. len -= n;
  7169. name += n;
  7170. }
  7171. n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
  7172. break;
  7173. case DEVLINK_PORT_FLAVOUR_PCI_VF:
  7174. if (attrs->pci_vf.external) {
  7175. n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
  7176. if (n >= len)
  7177. return -EINVAL;
  7178. len -= n;
  7179. name += n;
  7180. }
  7181. n = snprintf(name, len, "pf%uvf%u",
  7182. attrs->pci_vf.pf, attrs->pci_vf.vf);
  7183. break;
  7184. case DEVLINK_PORT_FLAVOUR_VIRTUAL:
  7185. return -EOPNOTSUPP;
  7186. }
  7187. if (n >= len)
  7188. return -EINVAL;
  7189. return 0;
  7190. }
  7191. int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
  7192. u32 size, u16 ingress_pools_count,
  7193. u16 egress_pools_count, u16 ingress_tc_count,
  7194. u16 egress_tc_count)
  7195. {
  7196. struct devlink_sb *devlink_sb;
  7197. int err = 0;
  7198. mutex_lock(&devlink->lock);
  7199. if (devlink_sb_index_exists(devlink, sb_index)) {
  7200. err = -EEXIST;
  7201. goto unlock;
  7202. }
  7203. devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
  7204. if (!devlink_sb) {
  7205. err = -ENOMEM;
  7206. goto unlock;
  7207. }
  7208. devlink_sb->index = sb_index;
  7209. devlink_sb->size = size;
  7210. devlink_sb->ingress_pools_count = ingress_pools_count;
  7211. devlink_sb->egress_pools_count = egress_pools_count;
  7212. devlink_sb->ingress_tc_count = ingress_tc_count;
  7213. devlink_sb->egress_tc_count = egress_tc_count;
  7214. list_add_tail(&devlink_sb->list, &devlink->sb_list);
  7215. unlock:
  7216. mutex_unlock(&devlink->lock);
  7217. return err;
  7218. }
  7219. EXPORT_SYMBOL_GPL(devlink_sb_register);
  7220. void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
  7221. {
  7222. struct devlink_sb *devlink_sb;
  7223. mutex_lock(&devlink->lock);
  7224. devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
  7225. WARN_ON(!devlink_sb);
  7226. list_del(&devlink_sb->list);
  7227. mutex_unlock(&devlink->lock);
  7228. kfree(devlink_sb);
  7229. }
  7230. EXPORT_SYMBOL_GPL(devlink_sb_unregister);
  7231. /**
  7232. * devlink_dpipe_headers_register - register dpipe headers
  7233. *
  7234. * @devlink: devlink
  7235. * @dpipe_headers: dpipe header array
  7236. *
  7237. * Register the headers supported by hardware.
  7238. */
  7239. int devlink_dpipe_headers_register(struct devlink *devlink,
  7240. struct devlink_dpipe_headers *dpipe_headers)
  7241. {
  7242. mutex_lock(&devlink->lock);
  7243. devlink->dpipe_headers = dpipe_headers;
  7244. mutex_unlock(&devlink->lock);
  7245. return 0;
  7246. }
  7247. EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
  7248. /**
  7249. * devlink_dpipe_headers_unregister - unregister dpipe headers
  7250. *
  7251. * @devlink: devlink
  7252. *
  7253. * Unregister the headers supported by hardware.
  7254. */
  7255. void devlink_dpipe_headers_unregister(struct devlink *devlink)
  7256. {
  7257. mutex_lock(&devlink->lock);
  7258. devlink->dpipe_headers = NULL;
  7259. mutex_unlock(&devlink->lock);
  7260. }
  7261. EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
  7262. /**
  7263. * devlink_dpipe_table_counter_enabled - check if counter allocation
  7264. * required
  7265. * @devlink: devlink
  7266. * @table_name: tables name
  7267. *
  7268. * Used by driver to check if counter allocation is required.
  7269. * After counter allocation is turned on the table entries
  7270. * are updated to include counter statistics.
  7271. *
  7272. * After that point on the driver must respect the counter
  7273. * state so that each entry added to the table is added
  7274. * with a counter.
  7275. */
  7276. bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
  7277. const char *table_name)
  7278. {
  7279. struct devlink_dpipe_table *table;
  7280. bool enabled;
  7281. rcu_read_lock();
  7282. table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
  7283. table_name, devlink);
  7284. enabled = false;
  7285. if (table)
  7286. enabled = table->counters_enabled;
  7287. rcu_read_unlock();
  7288. return enabled;
  7289. }
  7290. EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
  7291. /**
  7292. * devlink_dpipe_table_register - register dpipe table
  7293. *
  7294. * @devlink: devlink
  7295. * @table_name: table name
  7296. * @table_ops: table ops
  7297. * @priv: priv
  7298. * @counter_control_extern: external control for counters
  7299. */
  7300. int devlink_dpipe_table_register(struct devlink *devlink,
  7301. const char *table_name,
  7302. struct devlink_dpipe_table_ops *table_ops,
  7303. void *priv, bool counter_control_extern)
  7304. {
  7305. struct devlink_dpipe_table *table;
  7306. int err = 0;
  7307. if (WARN_ON(!table_ops->size_get))
  7308. return -EINVAL;
  7309. mutex_lock(&devlink->lock);
  7310. if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
  7311. devlink)) {
  7312. err = -EEXIST;
  7313. goto unlock;
  7314. }
  7315. table = kzalloc(sizeof(*table), GFP_KERNEL);
  7316. if (!table) {
  7317. err = -ENOMEM;
  7318. goto unlock;
  7319. }
  7320. table->name = table_name;
  7321. table->table_ops = table_ops;
  7322. table->priv = priv;
  7323. table->counter_control_extern = counter_control_extern;
  7324. list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
  7325. unlock:
  7326. mutex_unlock(&devlink->lock);
  7327. return err;
  7328. }
  7329. EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
  7330. /**
  7331. * devlink_dpipe_table_unregister - unregister dpipe table
  7332. *
  7333. * @devlink: devlink
  7334. * @table_name: table name
  7335. */
  7336. void devlink_dpipe_table_unregister(struct devlink *devlink,
  7337. const char *table_name)
  7338. {
  7339. struct devlink_dpipe_table *table;
  7340. mutex_lock(&devlink->lock);
  7341. table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
  7342. table_name, devlink);
  7343. if (!table)
  7344. goto unlock;
  7345. list_del_rcu(&table->list);
  7346. mutex_unlock(&devlink->lock);
  7347. kfree_rcu(table, rcu);
  7348. return;
  7349. unlock:
  7350. mutex_unlock(&devlink->lock);
  7351. }
  7352. EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
  7353. /**
  7354. * devlink_resource_register - devlink resource register
  7355. *
  7356. * @devlink: devlink
  7357. * @resource_name: resource's name
  7358. * @resource_size: resource's size
  7359. * @resource_id: resource's id
  7360. * @parent_resource_id: resource's parent id
  7361. * @size_params: size parameters
  7362. */
  7363. int devlink_resource_register(struct devlink *devlink,
  7364. const char *resource_name,
  7365. u64 resource_size,
  7366. u64 resource_id,
  7367. u64 parent_resource_id,
  7368. const struct devlink_resource_size_params *size_params)
  7369. {
  7370. struct devlink_resource *resource;
  7371. struct list_head *resource_list;
  7372. bool top_hierarchy;
  7373. int err = 0;
  7374. top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
  7375. mutex_lock(&devlink->lock);
  7376. resource = devlink_resource_find(devlink, NULL, resource_id);
  7377. if (resource) {
  7378. err = -EINVAL;
  7379. goto out;
  7380. }
  7381. resource = kzalloc(sizeof(*resource), GFP_KERNEL);
  7382. if (!resource) {
  7383. err = -ENOMEM;
  7384. goto out;
  7385. }
  7386. if (top_hierarchy) {
  7387. resource_list = &devlink->resource_list;
  7388. } else {
  7389. struct devlink_resource *parent_resource;
  7390. parent_resource = devlink_resource_find(devlink, NULL,
  7391. parent_resource_id);
  7392. if (parent_resource) {
  7393. resource_list = &parent_resource->resource_list;
  7394. resource->parent = parent_resource;
  7395. } else {
  7396. kfree(resource);
  7397. err = -EINVAL;
  7398. goto out;
  7399. }
  7400. }
  7401. resource->name = resource_name;
  7402. resource->size = resource_size;
  7403. resource->size_new = resource_size;
  7404. resource->id = resource_id;
  7405. resource->size_valid = true;
  7406. memcpy(&resource->size_params, size_params,
  7407. sizeof(resource->size_params));
  7408. INIT_LIST_HEAD(&resource->resource_list);
  7409. list_add_tail(&resource->list, resource_list);
  7410. out:
  7411. mutex_unlock(&devlink->lock);
  7412. return err;
  7413. }
  7414. EXPORT_SYMBOL_GPL(devlink_resource_register);
  7415. /**
  7416. * devlink_resources_unregister - free all resources
  7417. *
  7418. * @devlink: devlink
  7419. * @resource: resource
  7420. */
  7421. void devlink_resources_unregister(struct devlink *devlink,
  7422. struct devlink_resource *resource)
  7423. {
  7424. struct devlink_resource *tmp, *child_resource;
  7425. struct list_head *resource_list;
  7426. if (resource)
  7427. resource_list = &resource->resource_list;
  7428. else
  7429. resource_list = &devlink->resource_list;
  7430. if (!resource)
  7431. mutex_lock(&devlink->lock);
  7432. list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
  7433. devlink_resources_unregister(devlink, child_resource);
  7434. list_del(&child_resource->list);
  7435. kfree(child_resource);
  7436. }
  7437. if (!resource)
  7438. mutex_unlock(&devlink->lock);
  7439. }
  7440. EXPORT_SYMBOL_GPL(devlink_resources_unregister);
  7441. /**
  7442. * devlink_resource_size_get - get and update size
  7443. *
  7444. * @devlink: devlink
  7445. * @resource_id: the requested resource id
  7446. * @p_resource_size: ptr to update
  7447. */
  7448. int devlink_resource_size_get(struct devlink *devlink,
  7449. u64 resource_id,
  7450. u64 *p_resource_size)
  7451. {
  7452. struct devlink_resource *resource;
  7453. int err = 0;
  7454. mutex_lock(&devlink->lock);
  7455. resource = devlink_resource_find(devlink, NULL, resource_id);
  7456. if (!resource) {
  7457. err = -EINVAL;
  7458. goto out;
  7459. }
  7460. *p_resource_size = resource->size_new;
  7461. resource->size = resource->size_new;
  7462. out:
  7463. mutex_unlock(&devlink->lock);
  7464. return err;
  7465. }
  7466. EXPORT_SYMBOL_GPL(devlink_resource_size_get);
  7467. /**
  7468. * devlink_dpipe_table_resource_set - set the resource id
  7469. *
  7470. * @devlink: devlink
  7471. * @table_name: table name
  7472. * @resource_id: resource id
  7473. * @resource_units: number of resource's units consumed per table's entry
  7474. */
  7475. int devlink_dpipe_table_resource_set(struct devlink *devlink,
  7476. const char *table_name, u64 resource_id,
  7477. u64 resource_units)
  7478. {
  7479. struct devlink_dpipe_table *table;
  7480. int err = 0;
  7481. mutex_lock(&devlink->lock);
  7482. table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
  7483. table_name, devlink);
  7484. if (!table) {
  7485. err = -EINVAL;
  7486. goto out;
  7487. }
  7488. table->resource_id = resource_id;
  7489. table->resource_units = resource_units;
  7490. table->resource_valid = true;
  7491. out:
  7492. mutex_unlock(&devlink->lock);
  7493. return err;
  7494. }
  7495. EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
  7496. /**
  7497. * devlink_resource_occ_get_register - register occupancy getter
  7498. *
  7499. * @devlink: devlink
  7500. * @resource_id: resource id
  7501. * @occ_get: occupancy getter callback
  7502. * @occ_get_priv: occupancy getter callback priv
  7503. */
  7504. void devlink_resource_occ_get_register(struct devlink *devlink,
  7505. u64 resource_id,
  7506. devlink_resource_occ_get_t *occ_get,
  7507. void *occ_get_priv)
  7508. {
  7509. struct devlink_resource *resource;
  7510. mutex_lock(&devlink->lock);
  7511. resource = devlink_resource_find(devlink, NULL, resource_id);
  7512. if (WARN_ON(!resource))
  7513. goto out;
  7514. WARN_ON(resource->occ_get);
  7515. resource->occ_get = occ_get;
  7516. resource->occ_get_priv = occ_get_priv;
  7517. out:
  7518. mutex_unlock(&devlink->lock);
  7519. }
  7520. EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
  7521. /**
  7522. * devlink_resource_occ_get_unregister - unregister occupancy getter
  7523. *
  7524. * @devlink: devlink
  7525. * @resource_id: resource id
  7526. */
  7527. void devlink_resource_occ_get_unregister(struct devlink *devlink,
  7528. u64 resource_id)
  7529. {
  7530. struct devlink_resource *resource;
  7531. mutex_lock(&devlink->lock);
  7532. resource = devlink_resource_find(devlink, NULL, resource_id);
  7533. if (WARN_ON(!resource))
  7534. goto out;
  7535. WARN_ON(!resource->occ_get);
  7536. resource->occ_get = NULL;
  7537. resource->occ_get_priv = NULL;
  7538. out:
  7539. mutex_unlock(&devlink->lock);
  7540. }
  7541. EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
  7542. static int devlink_param_verify(const struct devlink_param *param)
  7543. {
  7544. if (!param || !param->name || !param->supported_cmodes)
  7545. return -EINVAL;
  7546. if (param->generic)
  7547. return devlink_param_generic_verify(param);
  7548. else
  7549. return devlink_param_driver_verify(param);
  7550. }
  7551. static int __devlink_params_register(struct devlink *devlink,
  7552. unsigned int port_index,
  7553. struct list_head *param_list,
  7554. const struct devlink_param *params,
  7555. size_t params_count,
  7556. enum devlink_command reg_cmd,
  7557. enum devlink_command unreg_cmd)
  7558. {
  7559. const struct devlink_param *param = params;
  7560. int i;
  7561. int err;
  7562. mutex_lock(&devlink->lock);
  7563. for (i = 0; i < params_count; i++, param++) {
  7564. err = devlink_param_verify(param);
  7565. if (err)
  7566. goto rollback;
  7567. err = devlink_param_register_one(devlink, port_index,
  7568. param_list, param, reg_cmd);
  7569. if (err)
  7570. goto rollback;
  7571. }
  7572. mutex_unlock(&devlink->lock);
  7573. return 0;
  7574. rollback:
  7575. if (!i)
  7576. goto unlock;
  7577. for (param--; i > 0; i--, param--)
  7578. devlink_param_unregister_one(devlink, port_index, param_list,
  7579. param, unreg_cmd);
  7580. unlock:
  7581. mutex_unlock(&devlink->lock);
  7582. return err;
  7583. }
  7584. static void __devlink_params_unregister(struct devlink *devlink,
  7585. unsigned int port_index,
  7586. struct list_head *param_list,
  7587. const struct devlink_param *params,
  7588. size_t params_count,
  7589. enum devlink_command cmd)
  7590. {
  7591. const struct devlink_param *param = params;
  7592. int i;
  7593. mutex_lock(&devlink->lock);
  7594. for (i = 0; i < params_count; i++, param++)
  7595. devlink_param_unregister_one(devlink, 0, param_list, param,
  7596. cmd);
  7597. mutex_unlock(&devlink->lock);
  7598. }
  7599. /**
  7600. * devlink_params_register - register configuration parameters
  7601. *
  7602. * @devlink: devlink
  7603. * @params: configuration parameters array
  7604. * @params_count: number of parameters provided
  7605. *
  7606. * Register the configuration parameters supported by the driver.
  7607. */
  7608. int devlink_params_register(struct devlink *devlink,
  7609. const struct devlink_param *params,
  7610. size_t params_count)
  7611. {
  7612. return __devlink_params_register(devlink, 0, &devlink->param_list,
  7613. params, params_count,
  7614. DEVLINK_CMD_PARAM_NEW,
  7615. DEVLINK_CMD_PARAM_DEL);
  7616. }
  7617. EXPORT_SYMBOL_GPL(devlink_params_register);
  7618. /**
  7619. * devlink_params_unregister - unregister configuration parameters
  7620. * @devlink: devlink
  7621. * @params: configuration parameters to unregister
  7622. * @params_count: number of parameters provided
  7623. */
  7624. void devlink_params_unregister(struct devlink *devlink,
  7625. const struct devlink_param *params,
  7626. size_t params_count)
  7627. {
  7628. return __devlink_params_unregister(devlink, 0, &devlink->param_list,
  7629. params, params_count,
  7630. DEVLINK_CMD_PARAM_DEL);
  7631. }
  7632. EXPORT_SYMBOL_GPL(devlink_params_unregister);
  7633. /**
  7634. * devlink_params_publish - publish configuration parameters
  7635. *
  7636. * @devlink: devlink
  7637. *
  7638. * Publish previously registered configuration parameters.
  7639. */
  7640. void devlink_params_publish(struct devlink *devlink)
  7641. {
  7642. struct devlink_param_item *param_item;
  7643. list_for_each_entry(param_item, &devlink->param_list, list) {
  7644. if (param_item->published)
  7645. continue;
  7646. param_item->published = true;
  7647. devlink_param_notify(devlink, 0, param_item,
  7648. DEVLINK_CMD_PARAM_NEW);
  7649. }
  7650. }
  7651. EXPORT_SYMBOL_GPL(devlink_params_publish);
  7652. /**
  7653. * devlink_params_unpublish - unpublish configuration parameters
  7654. *
  7655. * @devlink: devlink
  7656. *
  7657. * Unpublish previously registered configuration parameters.
  7658. */
  7659. void devlink_params_unpublish(struct devlink *devlink)
  7660. {
  7661. struct devlink_param_item *param_item;
  7662. list_for_each_entry(param_item, &devlink->param_list, list) {
  7663. if (!param_item->published)
  7664. continue;
  7665. param_item->published = false;
  7666. devlink_param_notify(devlink, 0, param_item,
  7667. DEVLINK_CMD_PARAM_DEL);
  7668. }
  7669. }
  7670. EXPORT_SYMBOL_GPL(devlink_params_unpublish);
  7671. /**
  7672. * devlink_port_params_register - register port configuration parameters
  7673. *
  7674. * @devlink_port: devlink port
  7675. * @params: configuration parameters array
  7676. * @params_count: number of parameters provided
  7677. *
  7678. * Register the configuration parameters supported by the port.
  7679. */
  7680. int devlink_port_params_register(struct devlink_port *devlink_port,
  7681. const struct devlink_param *params,
  7682. size_t params_count)
  7683. {
  7684. return __devlink_params_register(devlink_port->devlink,
  7685. devlink_port->index,
  7686. &devlink_port->param_list, params,
  7687. params_count,
  7688. DEVLINK_CMD_PORT_PARAM_NEW,
  7689. DEVLINK_CMD_PORT_PARAM_DEL);
  7690. }
  7691. EXPORT_SYMBOL_GPL(devlink_port_params_register);
  7692. /**
  7693. * devlink_port_params_unregister - unregister port configuration
  7694. * parameters
  7695. *
  7696. * @devlink_port: devlink port
  7697. * @params: configuration parameters array
  7698. * @params_count: number of parameters provided
  7699. */
  7700. void devlink_port_params_unregister(struct devlink_port *devlink_port,
  7701. const struct devlink_param *params,
  7702. size_t params_count)
  7703. {
  7704. return __devlink_params_unregister(devlink_port->devlink,
  7705. devlink_port->index,
  7706. &devlink_port->param_list,
  7707. params, params_count,
  7708. DEVLINK_CMD_PORT_PARAM_DEL);
  7709. }
  7710. EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
  7711. static int
  7712. __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
  7713. union devlink_param_value *init_val)
  7714. {
  7715. struct devlink_param_item *param_item;
  7716. param_item = devlink_param_find_by_id(param_list, param_id);
  7717. if (!param_item)
  7718. return -EINVAL;
  7719. if (!param_item->driverinit_value_valid ||
  7720. !devlink_param_cmode_is_supported(param_item->param,
  7721. DEVLINK_PARAM_CMODE_DRIVERINIT))
  7722. return -EOPNOTSUPP;
  7723. if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
  7724. strcpy(init_val->vstr, param_item->driverinit_value.vstr);
  7725. else
  7726. *init_val = param_item->driverinit_value;
  7727. return 0;
  7728. }
  7729. static int
  7730. __devlink_param_driverinit_value_set(struct devlink *devlink,
  7731. unsigned int port_index,
  7732. struct list_head *param_list, u32 param_id,
  7733. union devlink_param_value init_val,
  7734. enum devlink_command cmd)
  7735. {
  7736. struct devlink_param_item *param_item;
  7737. param_item = devlink_param_find_by_id(param_list, param_id);
  7738. if (!param_item)
  7739. return -EINVAL;
  7740. if (!devlink_param_cmode_is_supported(param_item->param,
  7741. DEVLINK_PARAM_CMODE_DRIVERINIT))
  7742. return -EOPNOTSUPP;
  7743. if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
  7744. strcpy(param_item->driverinit_value.vstr, init_val.vstr);
  7745. else
  7746. param_item->driverinit_value = init_val;
  7747. param_item->driverinit_value_valid = true;
  7748. devlink_param_notify(devlink, port_index, param_item, cmd);
  7749. return 0;
  7750. }
  7751. /**
  7752. * devlink_param_driverinit_value_get - get configuration parameter
  7753. * value for driver initializing
  7754. *
  7755. * @devlink: devlink
  7756. * @param_id: parameter ID
  7757. * @init_val: value of parameter in driverinit configuration mode
  7758. *
  7759. * This function should be used by the driver to get driverinit
  7760. * configuration for initialization after reload command.
  7761. */
  7762. int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
  7763. union devlink_param_value *init_val)
  7764. {
  7765. if (!devlink_reload_supported(devlink->ops))
  7766. return -EOPNOTSUPP;
  7767. return __devlink_param_driverinit_value_get(&devlink->param_list,
  7768. param_id, init_val);
  7769. }
  7770. EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
  7771. /**
  7772. * devlink_param_driverinit_value_set - set value of configuration
  7773. * parameter for driverinit
  7774. * configuration mode
  7775. *
  7776. * @devlink: devlink
  7777. * @param_id: parameter ID
  7778. * @init_val: value of parameter to set for driverinit configuration mode
  7779. *
  7780. * This function should be used by the driver to set driverinit
  7781. * configuration mode default value.
  7782. */
  7783. int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
  7784. union devlink_param_value init_val)
  7785. {
  7786. return __devlink_param_driverinit_value_set(devlink, 0,
  7787. &devlink->param_list,
  7788. param_id, init_val,
  7789. DEVLINK_CMD_PARAM_NEW);
  7790. }
  7791. EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
  7792. /**
  7793. * devlink_port_param_driverinit_value_get - get configuration parameter
  7794. * value for driver initializing
  7795. *
  7796. * @devlink_port: devlink_port
  7797. * @param_id: parameter ID
  7798. * @init_val: value of parameter in driverinit configuration mode
  7799. *
  7800. * This function should be used by the driver to get driverinit
  7801. * configuration for initialization after reload command.
  7802. */
  7803. int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
  7804. u32 param_id,
  7805. union devlink_param_value *init_val)
  7806. {
  7807. struct devlink *devlink = devlink_port->devlink;
  7808. if (!devlink_reload_supported(devlink->ops))
  7809. return -EOPNOTSUPP;
  7810. return __devlink_param_driverinit_value_get(&devlink_port->param_list,
  7811. param_id, init_val);
  7812. }
  7813. EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
  7814. /**
  7815. * devlink_port_param_driverinit_value_set - set value of configuration
  7816. * parameter for driverinit
  7817. * configuration mode
  7818. *
  7819. * @devlink_port: devlink_port
  7820. * @param_id: parameter ID
  7821. * @init_val: value of parameter to set for driverinit configuration mode
  7822. *
  7823. * This function should be used by the driver to set driverinit
  7824. * configuration mode default value.
  7825. */
  7826. int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
  7827. u32 param_id,
  7828. union devlink_param_value init_val)
  7829. {
  7830. return __devlink_param_driverinit_value_set(devlink_port->devlink,
  7831. devlink_port->index,
  7832. &devlink_port->param_list,
  7833. param_id, init_val,
  7834. DEVLINK_CMD_PORT_PARAM_NEW);
  7835. }
  7836. EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
  7837. /**
  7838. * devlink_param_value_changed - notify devlink on a parameter's value
  7839. * change. Should be called by the driver
  7840. * right after the change.
  7841. *
  7842. * @devlink: devlink
  7843. * @param_id: parameter ID
  7844. *
  7845. * This function should be used by the driver to notify devlink on value
  7846. * change, excluding driverinit configuration mode.
  7847. * For driverinit configuration mode driver should use the function
  7848. */
  7849. void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
  7850. {
  7851. struct devlink_param_item *param_item;
  7852. param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
  7853. WARN_ON(!param_item);
  7854. devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
  7855. }
  7856. EXPORT_SYMBOL_GPL(devlink_param_value_changed);
  7857. /**
  7858. * devlink_port_param_value_changed - notify devlink on a parameter's value
  7859. * change. Should be called by the driver
  7860. * right after the change.
  7861. *
  7862. * @devlink_port: devlink_port
  7863. * @param_id: parameter ID
  7864. *
  7865. * This function should be used by the driver to notify devlink on value
  7866. * change, excluding driverinit configuration mode.
  7867. * For driverinit configuration mode driver should use the function
  7868. * devlink_port_param_driverinit_value_set() instead.
  7869. */
  7870. void devlink_port_param_value_changed(struct devlink_port *devlink_port,
  7871. u32 param_id)
  7872. {
  7873. struct devlink_param_item *param_item;
  7874. param_item = devlink_param_find_by_id(&devlink_port->param_list,
  7875. param_id);
  7876. WARN_ON(!param_item);
  7877. devlink_param_notify(devlink_port->devlink, devlink_port->index,
  7878. param_item, DEVLINK_CMD_PORT_PARAM_NEW);
  7879. }
  7880. EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
  7881. /**
  7882. * devlink_param_value_str_fill - Safely fill-up the string preventing
  7883. * from overflow of the preallocated buffer
  7884. *
  7885. * @dst_val: destination devlink_param_value
  7886. * @src: source buffer
  7887. */
  7888. void devlink_param_value_str_fill(union devlink_param_value *dst_val,
  7889. const char *src)
  7890. {
  7891. size_t len;
  7892. len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
  7893. WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
  7894. }
  7895. EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
  7896. /**
  7897. * devlink_region_create - create a new address region
  7898. *
  7899. * @devlink: devlink
  7900. * @ops: region operations and name
  7901. * @region_max_snapshots: Maximum supported number of snapshots for region
  7902. * @region_size: size of region
  7903. */
  7904. struct devlink_region *
  7905. devlink_region_create(struct devlink *devlink,
  7906. const struct devlink_region_ops *ops,
  7907. u32 region_max_snapshots, u64 region_size)
  7908. {
  7909. struct devlink_region *region;
  7910. int err = 0;
  7911. if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
  7912. return ERR_PTR(-EINVAL);
  7913. mutex_lock(&devlink->lock);
  7914. if (devlink_region_get_by_name(devlink, ops->name)) {
  7915. err = -EEXIST;
  7916. goto unlock;
  7917. }
  7918. region = kzalloc(sizeof(*region), GFP_KERNEL);
  7919. if (!region) {
  7920. err = -ENOMEM;
  7921. goto unlock;
  7922. }
  7923. region->devlink = devlink;
  7924. region->max_snapshots = region_max_snapshots;
  7925. region->ops = ops;
  7926. region->size = region_size;
  7927. INIT_LIST_HEAD(&region->snapshot_list);
  7928. list_add_tail(&region->list, &devlink->region_list);
  7929. devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
  7930. mutex_unlock(&devlink->lock);
  7931. return region;
  7932. unlock:
  7933. mutex_unlock(&devlink->lock);
  7934. return ERR_PTR(err);
  7935. }
  7936. EXPORT_SYMBOL_GPL(devlink_region_create);
  7937. /**
  7938. * devlink_port_region_create - create a new address region for a port
  7939. *
  7940. * @port: devlink port
  7941. * @ops: region operations and name
  7942. * @region_max_snapshots: Maximum supported number of snapshots for region
  7943. * @region_size: size of region
  7944. */
  7945. struct devlink_region *
  7946. devlink_port_region_create(struct devlink_port *port,
  7947. const struct devlink_port_region_ops *ops,
  7948. u32 region_max_snapshots, u64 region_size)
  7949. {
  7950. struct devlink *devlink = port->devlink;
  7951. struct devlink_region *region;
  7952. int err = 0;
  7953. if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
  7954. return ERR_PTR(-EINVAL);
  7955. mutex_lock(&devlink->lock);
  7956. if (devlink_port_region_get_by_name(port, ops->name)) {
  7957. err = -EEXIST;
  7958. goto unlock;
  7959. }
  7960. region = kzalloc(sizeof(*region), GFP_KERNEL);
  7961. if (!region) {
  7962. err = -ENOMEM;
  7963. goto unlock;
  7964. }
  7965. region->devlink = devlink;
  7966. region->port = port;
  7967. region->max_snapshots = region_max_snapshots;
  7968. region->port_ops = ops;
  7969. region->size = region_size;
  7970. INIT_LIST_HEAD(&region->snapshot_list);
  7971. list_add_tail(&region->list, &port->region_list);
  7972. devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
  7973. mutex_unlock(&devlink->lock);
  7974. return region;
  7975. unlock:
  7976. mutex_unlock(&devlink->lock);
  7977. return ERR_PTR(err);
  7978. }
  7979. EXPORT_SYMBOL_GPL(devlink_port_region_create);
  7980. /**
  7981. * devlink_region_destroy - destroy address region
  7982. *
  7983. * @region: devlink region to destroy
  7984. */
  7985. void devlink_region_destroy(struct devlink_region *region)
  7986. {
  7987. struct devlink *devlink = region->devlink;
  7988. struct devlink_snapshot *snapshot, *ts;
  7989. mutex_lock(&devlink->lock);
  7990. /* Free all snapshots of region */
  7991. list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
  7992. devlink_region_snapshot_del(region, snapshot);
  7993. list_del(&region->list);
  7994. devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
  7995. mutex_unlock(&devlink->lock);
  7996. kfree(region);
  7997. }
  7998. EXPORT_SYMBOL_GPL(devlink_region_destroy);
  7999. /**
  8000. * devlink_region_snapshot_id_get - get snapshot ID
  8001. *
  8002. * This callback should be called when adding a new snapshot,
  8003. * Driver should use the same id for multiple snapshots taken
  8004. * on multiple regions at the same time/by the same trigger.
  8005. *
  8006. * The caller of this function must use devlink_region_snapshot_id_put
  8007. * when finished creating regions using this id.
  8008. *
  8009. * Returns zero on success, or a negative error code on failure.
  8010. *
  8011. * @devlink: devlink
  8012. * @id: storage to return id
  8013. */
  8014. int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
  8015. {
  8016. int err;
  8017. mutex_lock(&devlink->lock);
  8018. err = __devlink_region_snapshot_id_get(devlink, id);
  8019. mutex_unlock(&devlink->lock);
  8020. return err;
  8021. }
  8022. EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
  8023. /**
  8024. * devlink_region_snapshot_id_put - put snapshot ID reference
  8025. *
  8026. * This should be called by a driver after finishing creating snapshots
  8027. * with an id. Doing so ensures that the ID can later be released in the
  8028. * event that all snapshots using it have been destroyed.
  8029. *
  8030. * @devlink: devlink
  8031. * @id: id to release reference on
  8032. */
  8033. void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
  8034. {
  8035. mutex_lock(&devlink->lock);
  8036. __devlink_snapshot_id_decrement(devlink, id);
  8037. mutex_unlock(&devlink->lock);
  8038. }
  8039. EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
  8040. /**
  8041. * devlink_region_snapshot_create - create a new snapshot
  8042. * This will add a new snapshot of a region. The snapshot
  8043. * will be stored on the region struct and can be accessed
  8044. * from devlink. This is useful for future analyses of snapshots.
  8045. * Multiple snapshots can be created on a region.
  8046. * The @snapshot_id should be obtained using the getter function.
  8047. *
  8048. * @region: devlink region of the snapshot
  8049. * @data: snapshot data
  8050. * @snapshot_id: snapshot id to be created
  8051. */
  8052. int devlink_region_snapshot_create(struct devlink_region *region,
  8053. u8 *data, u32 snapshot_id)
  8054. {
  8055. struct devlink *devlink = region->devlink;
  8056. int err;
  8057. mutex_lock(&devlink->lock);
  8058. err = __devlink_region_snapshot_create(region, data, snapshot_id);
  8059. mutex_unlock(&devlink->lock);
  8060. return err;
  8061. }
  8062. EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
  8063. #define DEVLINK_TRAP(_id, _type) \
  8064. { \
  8065. .type = DEVLINK_TRAP_TYPE_##_type, \
  8066. .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
  8067. .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
  8068. }
  8069. static const struct devlink_trap devlink_trap_generic[] = {
  8070. DEVLINK_TRAP(SMAC_MC, DROP),
  8071. DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
  8072. DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
  8073. DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
  8074. DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
  8075. DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
  8076. DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
  8077. DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
  8078. DEVLINK_TRAP(TAIL_DROP, DROP),
  8079. DEVLINK_TRAP(NON_IP_PACKET, DROP),
  8080. DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
  8081. DEVLINK_TRAP(DIP_LB, DROP),
  8082. DEVLINK_TRAP(SIP_MC, DROP),
  8083. DEVLINK_TRAP(SIP_LB, DROP),
  8084. DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
  8085. DEVLINK_TRAP(IPV4_SIP_BC, DROP),
  8086. DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
  8087. DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
  8088. DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
  8089. DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
  8090. DEVLINK_TRAP(RPF, EXCEPTION),
  8091. DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
  8092. DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
  8093. DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
  8094. DEVLINK_TRAP(NON_ROUTABLE, DROP),
  8095. DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
  8096. DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
  8097. DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
  8098. DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
  8099. DEVLINK_TRAP(STP, CONTROL),
  8100. DEVLINK_TRAP(LACP, CONTROL),
  8101. DEVLINK_TRAP(LLDP, CONTROL),
  8102. DEVLINK_TRAP(IGMP_QUERY, CONTROL),
  8103. DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
  8104. DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
  8105. DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
  8106. DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
  8107. DEVLINK_TRAP(MLD_QUERY, CONTROL),
  8108. DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
  8109. DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
  8110. DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
  8111. DEVLINK_TRAP(IPV4_DHCP, CONTROL),
  8112. DEVLINK_TRAP(IPV6_DHCP, CONTROL),
  8113. DEVLINK_TRAP(ARP_REQUEST, CONTROL),
  8114. DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
  8115. DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
  8116. DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
  8117. DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
  8118. DEVLINK_TRAP(IPV4_BFD, CONTROL),
  8119. DEVLINK_TRAP(IPV6_BFD, CONTROL),
  8120. DEVLINK_TRAP(IPV4_OSPF, CONTROL),
  8121. DEVLINK_TRAP(IPV6_OSPF, CONTROL),
  8122. DEVLINK_TRAP(IPV4_BGP, CONTROL),
  8123. DEVLINK_TRAP(IPV6_BGP, CONTROL),
  8124. DEVLINK_TRAP(IPV4_VRRP, CONTROL),
  8125. DEVLINK_TRAP(IPV6_VRRP, CONTROL),
  8126. DEVLINK_TRAP(IPV4_PIM, CONTROL),
  8127. DEVLINK_TRAP(IPV6_PIM, CONTROL),
  8128. DEVLINK_TRAP(UC_LB, CONTROL),
  8129. DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
  8130. DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
  8131. DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
  8132. DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
  8133. DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
  8134. DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
  8135. DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
  8136. DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
  8137. DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
  8138. DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
  8139. DEVLINK_TRAP(PTP_EVENT, CONTROL),
  8140. DEVLINK_TRAP(PTP_GENERAL, CONTROL),
  8141. DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
  8142. DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
  8143. DEVLINK_TRAP(EARLY_DROP, DROP),
  8144. DEVLINK_TRAP(VXLAN_PARSING, DROP),
  8145. DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
  8146. DEVLINK_TRAP(VLAN_PARSING, DROP),
  8147. DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
  8148. DEVLINK_TRAP(MPLS_PARSING, DROP),
  8149. DEVLINK_TRAP(ARP_PARSING, DROP),
  8150. DEVLINK_TRAP(IP_1_PARSING, DROP),
  8151. DEVLINK_TRAP(IP_N_PARSING, DROP),
  8152. DEVLINK_TRAP(GRE_PARSING, DROP),
  8153. DEVLINK_TRAP(UDP_PARSING, DROP),
  8154. DEVLINK_TRAP(TCP_PARSING, DROP),
  8155. DEVLINK_TRAP(IPSEC_PARSING, DROP),
  8156. DEVLINK_TRAP(SCTP_PARSING, DROP),
  8157. DEVLINK_TRAP(DCCP_PARSING, DROP),
  8158. DEVLINK_TRAP(GTP_PARSING, DROP),
  8159. DEVLINK_TRAP(ESP_PARSING, DROP),
  8160. };
  8161. #define DEVLINK_TRAP_GROUP(_id) \
  8162. { \
  8163. .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
  8164. .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
  8165. }
  8166. static const struct devlink_trap_group devlink_trap_group_generic[] = {
  8167. DEVLINK_TRAP_GROUP(L2_DROPS),
  8168. DEVLINK_TRAP_GROUP(L3_DROPS),
  8169. DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
  8170. DEVLINK_TRAP_GROUP(BUFFER_DROPS),
  8171. DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
  8172. DEVLINK_TRAP_GROUP(ACL_DROPS),
  8173. DEVLINK_TRAP_GROUP(STP),
  8174. DEVLINK_TRAP_GROUP(LACP),
  8175. DEVLINK_TRAP_GROUP(LLDP),
  8176. DEVLINK_TRAP_GROUP(MC_SNOOPING),
  8177. DEVLINK_TRAP_GROUP(DHCP),
  8178. DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
  8179. DEVLINK_TRAP_GROUP(BFD),
  8180. DEVLINK_TRAP_GROUP(OSPF),
  8181. DEVLINK_TRAP_GROUP(BGP),
  8182. DEVLINK_TRAP_GROUP(VRRP),
  8183. DEVLINK_TRAP_GROUP(PIM),
  8184. DEVLINK_TRAP_GROUP(UC_LB),
  8185. DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
  8186. DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
  8187. DEVLINK_TRAP_GROUP(IPV6),
  8188. DEVLINK_TRAP_GROUP(PTP_EVENT),
  8189. DEVLINK_TRAP_GROUP(PTP_GENERAL),
  8190. DEVLINK_TRAP_GROUP(ACL_SAMPLE),
  8191. DEVLINK_TRAP_GROUP(ACL_TRAP),
  8192. DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
  8193. };
  8194. static int devlink_trap_generic_verify(const struct devlink_trap *trap)
  8195. {
  8196. if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
  8197. return -EINVAL;
  8198. if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
  8199. return -EINVAL;
  8200. if (trap->type != devlink_trap_generic[trap->id].type)
  8201. return -EINVAL;
  8202. return 0;
  8203. }
  8204. static int devlink_trap_driver_verify(const struct devlink_trap *trap)
  8205. {
  8206. int i;
  8207. if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
  8208. return -EINVAL;
  8209. for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
  8210. if (!strcmp(trap->name, devlink_trap_generic[i].name))
  8211. return -EEXIST;
  8212. }
  8213. return 0;
  8214. }
  8215. static int devlink_trap_verify(const struct devlink_trap *trap)
  8216. {
  8217. if (!trap || !trap->name)
  8218. return -EINVAL;
  8219. if (trap->generic)
  8220. return devlink_trap_generic_verify(trap);
  8221. else
  8222. return devlink_trap_driver_verify(trap);
  8223. }
  8224. static int
  8225. devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
  8226. {
  8227. if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
  8228. return -EINVAL;
  8229. if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
  8230. return -EINVAL;
  8231. return 0;
  8232. }
  8233. static int
  8234. devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
  8235. {
  8236. int i;
  8237. if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
  8238. return -EINVAL;
  8239. for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
  8240. if (!strcmp(group->name, devlink_trap_group_generic[i].name))
  8241. return -EEXIST;
  8242. }
  8243. return 0;
  8244. }
  8245. static int devlink_trap_group_verify(const struct devlink_trap_group *group)
  8246. {
  8247. if (group->generic)
  8248. return devlink_trap_group_generic_verify(group);
  8249. else
  8250. return devlink_trap_group_driver_verify(group);
  8251. }
  8252. static void
  8253. devlink_trap_group_notify(struct devlink *devlink,
  8254. const struct devlink_trap_group_item *group_item,
  8255. enum devlink_command cmd)
  8256. {
  8257. struct sk_buff *msg;
  8258. int err;
  8259. WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
  8260. cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
  8261. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  8262. if (!msg)
  8263. return;
  8264. err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
  8265. 0);
  8266. if (err) {
  8267. nlmsg_free(msg);
  8268. return;
  8269. }
  8270. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  8271. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  8272. }
  8273. static int
  8274. devlink_trap_item_group_link(struct devlink *devlink,
  8275. struct devlink_trap_item *trap_item)
  8276. {
  8277. u16 group_id = trap_item->trap->init_group_id;
  8278. struct devlink_trap_group_item *group_item;
  8279. group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
  8280. if (WARN_ON_ONCE(!group_item))
  8281. return -EINVAL;
  8282. trap_item->group_item = group_item;
  8283. return 0;
  8284. }
  8285. static void devlink_trap_notify(struct devlink *devlink,
  8286. const struct devlink_trap_item *trap_item,
  8287. enum devlink_command cmd)
  8288. {
  8289. struct sk_buff *msg;
  8290. int err;
  8291. WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
  8292. cmd != DEVLINK_CMD_TRAP_DEL);
  8293. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  8294. if (!msg)
  8295. return;
  8296. err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
  8297. if (err) {
  8298. nlmsg_free(msg);
  8299. return;
  8300. }
  8301. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  8302. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  8303. }
  8304. static int
  8305. devlink_trap_register(struct devlink *devlink,
  8306. const struct devlink_trap *trap, void *priv)
  8307. {
  8308. struct devlink_trap_item *trap_item;
  8309. int err;
  8310. if (devlink_trap_item_lookup(devlink, trap->name))
  8311. return -EEXIST;
  8312. trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
  8313. if (!trap_item)
  8314. return -ENOMEM;
  8315. trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
  8316. if (!trap_item->stats) {
  8317. err = -ENOMEM;
  8318. goto err_stats_alloc;
  8319. }
  8320. trap_item->trap = trap;
  8321. trap_item->action = trap->init_action;
  8322. trap_item->priv = priv;
  8323. err = devlink_trap_item_group_link(devlink, trap_item);
  8324. if (err)
  8325. goto err_group_link;
  8326. err = devlink->ops->trap_init(devlink, trap, trap_item);
  8327. if (err)
  8328. goto err_trap_init;
  8329. list_add_tail(&trap_item->list, &devlink->trap_list);
  8330. devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
  8331. return 0;
  8332. err_trap_init:
  8333. err_group_link:
  8334. free_percpu(trap_item->stats);
  8335. err_stats_alloc:
  8336. kfree(trap_item);
  8337. return err;
  8338. }
  8339. static void devlink_trap_unregister(struct devlink *devlink,
  8340. const struct devlink_trap *trap)
  8341. {
  8342. struct devlink_trap_item *trap_item;
  8343. trap_item = devlink_trap_item_lookup(devlink, trap->name);
  8344. if (WARN_ON_ONCE(!trap_item))
  8345. return;
  8346. devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
  8347. list_del(&trap_item->list);
  8348. if (devlink->ops->trap_fini)
  8349. devlink->ops->trap_fini(devlink, trap, trap_item);
  8350. free_percpu(trap_item->stats);
  8351. kfree(trap_item);
  8352. }
  8353. static void devlink_trap_disable(struct devlink *devlink,
  8354. const struct devlink_trap *trap)
  8355. {
  8356. struct devlink_trap_item *trap_item;
  8357. trap_item = devlink_trap_item_lookup(devlink, trap->name);
  8358. if (WARN_ON_ONCE(!trap_item))
  8359. return;
  8360. devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
  8361. NULL);
  8362. trap_item->action = DEVLINK_TRAP_ACTION_DROP;
  8363. }
  8364. /**
  8365. * devlink_traps_register - Register packet traps with devlink.
  8366. * @devlink: devlink.
  8367. * @traps: Packet traps.
  8368. * @traps_count: Count of provided packet traps.
  8369. * @priv: Driver private information.
  8370. *
  8371. * Return: Non-zero value on failure.
  8372. */
  8373. int devlink_traps_register(struct devlink *devlink,
  8374. const struct devlink_trap *traps,
  8375. size_t traps_count, void *priv)
  8376. {
  8377. int i, err;
  8378. if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
  8379. return -EINVAL;
  8380. mutex_lock(&devlink->lock);
  8381. for (i = 0; i < traps_count; i++) {
  8382. const struct devlink_trap *trap = &traps[i];
  8383. err = devlink_trap_verify(trap);
  8384. if (err)
  8385. goto err_trap_verify;
  8386. err = devlink_trap_register(devlink, trap, priv);
  8387. if (err)
  8388. goto err_trap_register;
  8389. }
  8390. mutex_unlock(&devlink->lock);
  8391. return 0;
  8392. err_trap_register:
  8393. err_trap_verify:
  8394. for (i--; i >= 0; i--)
  8395. devlink_trap_unregister(devlink, &traps[i]);
  8396. mutex_unlock(&devlink->lock);
  8397. return err;
  8398. }
  8399. EXPORT_SYMBOL_GPL(devlink_traps_register);
  8400. /**
  8401. * devlink_traps_unregister - Unregister packet traps from devlink.
  8402. * @devlink: devlink.
  8403. * @traps: Packet traps.
  8404. * @traps_count: Count of provided packet traps.
  8405. */
  8406. void devlink_traps_unregister(struct devlink *devlink,
  8407. const struct devlink_trap *traps,
  8408. size_t traps_count)
  8409. {
  8410. int i;
  8411. mutex_lock(&devlink->lock);
  8412. /* Make sure we do not have any packets in-flight while unregistering
  8413. * traps by disabling all of them and waiting for a grace period.
  8414. */
  8415. for (i = traps_count - 1; i >= 0; i--)
  8416. devlink_trap_disable(devlink, &traps[i]);
  8417. synchronize_rcu();
  8418. for (i = traps_count - 1; i >= 0; i--)
  8419. devlink_trap_unregister(devlink, &traps[i]);
  8420. mutex_unlock(&devlink->lock);
  8421. }
  8422. EXPORT_SYMBOL_GPL(devlink_traps_unregister);
  8423. static void
  8424. devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
  8425. size_t skb_len)
  8426. {
  8427. struct devlink_stats *stats;
  8428. stats = this_cpu_ptr(trap_stats);
  8429. u64_stats_update_begin(&stats->syncp);
  8430. stats->rx_bytes += skb_len;
  8431. stats->rx_packets++;
  8432. u64_stats_update_end(&stats->syncp);
  8433. }
  8434. static void
  8435. devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
  8436. const struct devlink_trap_item *trap_item,
  8437. struct devlink_port *in_devlink_port,
  8438. const struct flow_action_cookie *fa_cookie)
  8439. {
  8440. metadata->trap_name = trap_item->trap->name;
  8441. metadata->trap_group_name = trap_item->group_item->group->name;
  8442. metadata->fa_cookie = fa_cookie;
  8443. metadata->trap_type = trap_item->trap->type;
  8444. spin_lock(&in_devlink_port->type_lock);
  8445. if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
  8446. metadata->input_dev = in_devlink_port->type_dev;
  8447. spin_unlock(&in_devlink_port->type_lock);
  8448. }
  8449. /**
  8450. * devlink_trap_report - Report trapped packet to drop monitor.
  8451. * @devlink: devlink.
  8452. * @skb: Trapped packet.
  8453. * @trap_ctx: Trap context.
  8454. * @in_devlink_port: Input devlink port.
  8455. * @fa_cookie: Flow action cookie. Could be NULL.
  8456. */
  8457. void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
  8458. void *trap_ctx, struct devlink_port *in_devlink_port,
  8459. const struct flow_action_cookie *fa_cookie)
  8460. {
  8461. struct devlink_trap_item *trap_item = trap_ctx;
  8462. devlink_trap_stats_update(trap_item->stats, skb->len);
  8463. devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
  8464. if (trace_devlink_trap_report_enabled()) {
  8465. struct devlink_trap_metadata metadata = {};
  8466. devlink_trap_report_metadata_set(&metadata, trap_item,
  8467. in_devlink_port, fa_cookie);
  8468. trace_devlink_trap_report(devlink, skb, &metadata);
  8469. }
  8470. }
  8471. EXPORT_SYMBOL_GPL(devlink_trap_report);
  8472. /**
  8473. * devlink_trap_ctx_priv - Trap context to driver private information.
  8474. * @trap_ctx: Trap context.
  8475. *
  8476. * Return: Driver private information passed during registration.
  8477. */
  8478. void *devlink_trap_ctx_priv(void *trap_ctx)
  8479. {
  8480. struct devlink_trap_item *trap_item = trap_ctx;
  8481. return trap_item->priv;
  8482. }
  8483. EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
  8484. static int
  8485. devlink_trap_group_item_policer_link(struct devlink *devlink,
  8486. struct devlink_trap_group_item *group_item)
  8487. {
  8488. u32 policer_id = group_item->group->init_policer_id;
  8489. struct devlink_trap_policer_item *policer_item;
  8490. if (policer_id == 0)
  8491. return 0;
  8492. policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
  8493. if (WARN_ON_ONCE(!policer_item))
  8494. return -EINVAL;
  8495. group_item->policer_item = policer_item;
  8496. return 0;
  8497. }
  8498. static int
  8499. devlink_trap_group_register(struct devlink *devlink,
  8500. const struct devlink_trap_group *group)
  8501. {
  8502. struct devlink_trap_group_item *group_item;
  8503. int err;
  8504. if (devlink_trap_group_item_lookup(devlink, group->name))
  8505. return -EEXIST;
  8506. group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
  8507. if (!group_item)
  8508. return -ENOMEM;
  8509. group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
  8510. if (!group_item->stats) {
  8511. err = -ENOMEM;
  8512. goto err_stats_alloc;
  8513. }
  8514. group_item->group = group;
  8515. err = devlink_trap_group_item_policer_link(devlink, group_item);
  8516. if (err)
  8517. goto err_policer_link;
  8518. if (devlink->ops->trap_group_init) {
  8519. err = devlink->ops->trap_group_init(devlink, group);
  8520. if (err)
  8521. goto err_group_init;
  8522. }
  8523. list_add_tail(&group_item->list, &devlink->trap_group_list);
  8524. devlink_trap_group_notify(devlink, group_item,
  8525. DEVLINK_CMD_TRAP_GROUP_NEW);
  8526. return 0;
  8527. err_group_init:
  8528. err_policer_link:
  8529. free_percpu(group_item->stats);
  8530. err_stats_alloc:
  8531. kfree(group_item);
  8532. return err;
  8533. }
  8534. static void
  8535. devlink_trap_group_unregister(struct devlink *devlink,
  8536. const struct devlink_trap_group *group)
  8537. {
  8538. struct devlink_trap_group_item *group_item;
  8539. group_item = devlink_trap_group_item_lookup(devlink, group->name);
  8540. if (WARN_ON_ONCE(!group_item))
  8541. return;
  8542. devlink_trap_group_notify(devlink, group_item,
  8543. DEVLINK_CMD_TRAP_GROUP_DEL);
  8544. list_del(&group_item->list);
  8545. free_percpu(group_item->stats);
  8546. kfree(group_item);
  8547. }
  8548. /**
  8549. * devlink_trap_groups_register - Register packet trap groups with devlink.
  8550. * @devlink: devlink.
  8551. * @groups: Packet trap groups.
  8552. * @groups_count: Count of provided packet trap groups.
  8553. *
  8554. * Return: Non-zero value on failure.
  8555. */
  8556. int devlink_trap_groups_register(struct devlink *devlink,
  8557. const struct devlink_trap_group *groups,
  8558. size_t groups_count)
  8559. {
  8560. int i, err;
  8561. mutex_lock(&devlink->lock);
  8562. for (i = 0; i < groups_count; i++) {
  8563. const struct devlink_trap_group *group = &groups[i];
  8564. err = devlink_trap_group_verify(group);
  8565. if (err)
  8566. goto err_trap_group_verify;
  8567. err = devlink_trap_group_register(devlink, group);
  8568. if (err)
  8569. goto err_trap_group_register;
  8570. }
  8571. mutex_unlock(&devlink->lock);
  8572. return 0;
  8573. err_trap_group_register:
  8574. err_trap_group_verify:
  8575. for (i--; i >= 0; i--)
  8576. devlink_trap_group_unregister(devlink, &groups[i]);
  8577. mutex_unlock(&devlink->lock);
  8578. return err;
  8579. }
  8580. EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
  8581. /**
  8582. * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
  8583. * @devlink: devlink.
  8584. * @groups: Packet trap groups.
  8585. * @groups_count: Count of provided packet trap groups.
  8586. */
  8587. void devlink_trap_groups_unregister(struct devlink *devlink,
  8588. const struct devlink_trap_group *groups,
  8589. size_t groups_count)
  8590. {
  8591. int i;
  8592. mutex_lock(&devlink->lock);
  8593. for (i = groups_count - 1; i >= 0; i--)
  8594. devlink_trap_group_unregister(devlink, &groups[i]);
  8595. mutex_unlock(&devlink->lock);
  8596. }
  8597. EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
  8598. static void
  8599. devlink_trap_policer_notify(struct devlink *devlink,
  8600. const struct devlink_trap_policer_item *policer_item,
  8601. enum devlink_command cmd)
  8602. {
  8603. struct sk_buff *msg;
  8604. int err;
  8605. WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
  8606. cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
  8607. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  8608. if (!msg)
  8609. return;
  8610. err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
  8611. 0, 0);
  8612. if (err) {
  8613. nlmsg_free(msg);
  8614. return;
  8615. }
  8616. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  8617. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  8618. }
  8619. static int
  8620. devlink_trap_policer_register(struct devlink *devlink,
  8621. const struct devlink_trap_policer *policer)
  8622. {
  8623. struct devlink_trap_policer_item *policer_item;
  8624. int err;
  8625. if (devlink_trap_policer_item_lookup(devlink, policer->id))
  8626. return -EEXIST;
  8627. policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
  8628. if (!policer_item)
  8629. return -ENOMEM;
  8630. policer_item->policer = policer;
  8631. policer_item->rate = policer->init_rate;
  8632. policer_item->burst = policer->init_burst;
  8633. if (devlink->ops->trap_policer_init) {
  8634. err = devlink->ops->trap_policer_init(devlink, policer);
  8635. if (err)
  8636. goto err_policer_init;
  8637. }
  8638. list_add_tail(&policer_item->list, &devlink->trap_policer_list);
  8639. devlink_trap_policer_notify(devlink, policer_item,
  8640. DEVLINK_CMD_TRAP_POLICER_NEW);
  8641. return 0;
  8642. err_policer_init:
  8643. kfree(policer_item);
  8644. return err;
  8645. }
  8646. static void
  8647. devlink_trap_policer_unregister(struct devlink *devlink,
  8648. const struct devlink_trap_policer *policer)
  8649. {
  8650. struct devlink_trap_policer_item *policer_item;
  8651. policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
  8652. if (WARN_ON_ONCE(!policer_item))
  8653. return;
  8654. devlink_trap_policer_notify(devlink, policer_item,
  8655. DEVLINK_CMD_TRAP_POLICER_DEL);
  8656. list_del(&policer_item->list);
  8657. if (devlink->ops->trap_policer_fini)
  8658. devlink->ops->trap_policer_fini(devlink, policer);
  8659. kfree(policer_item);
  8660. }
  8661. /**
  8662. * devlink_trap_policers_register - Register packet trap policers with devlink.
  8663. * @devlink: devlink.
  8664. * @policers: Packet trap policers.
  8665. * @policers_count: Count of provided packet trap policers.
  8666. *
  8667. * Return: Non-zero value on failure.
  8668. */
  8669. int
  8670. devlink_trap_policers_register(struct devlink *devlink,
  8671. const struct devlink_trap_policer *policers,
  8672. size_t policers_count)
  8673. {
  8674. int i, err;
  8675. mutex_lock(&devlink->lock);
  8676. for (i = 0; i < policers_count; i++) {
  8677. const struct devlink_trap_policer *policer = &policers[i];
  8678. if (WARN_ON(policer->id == 0 ||
  8679. policer->max_rate < policer->min_rate ||
  8680. policer->max_burst < policer->min_burst)) {
  8681. err = -EINVAL;
  8682. goto err_trap_policer_verify;
  8683. }
  8684. err = devlink_trap_policer_register(devlink, policer);
  8685. if (err)
  8686. goto err_trap_policer_register;
  8687. }
  8688. mutex_unlock(&devlink->lock);
  8689. return 0;
  8690. err_trap_policer_register:
  8691. err_trap_policer_verify:
  8692. for (i--; i >= 0; i--)
  8693. devlink_trap_policer_unregister(devlink, &policers[i]);
  8694. mutex_unlock(&devlink->lock);
  8695. return err;
  8696. }
  8697. EXPORT_SYMBOL_GPL(devlink_trap_policers_register);
  8698. /**
  8699. * devlink_trap_policers_unregister - Unregister packet trap policers from devlink.
  8700. * @devlink: devlink.
  8701. * @policers: Packet trap policers.
  8702. * @policers_count: Count of provided packet trap policers.
  8703. */
  8704. void
  8705. devlink_trap_policers_unregister(struct devlink *devlink,
  8706. const struct devlink_trap_policer *policers,
  8707. size_t policers_count)
  8708. {
  8709. int i;
  8710. mutex_lock(&devlink->lock);
  8711. for (i = policers_count - 1; i >= 0; i--)
  8712. devlink_trap_policer_unregister(devlink, &policers[i]);
  8713. mutex_unlock(&devlink->lock);
  8714. }
  8715. EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister);
  8716. static void __devlink_compat_running_version(struct devlink *devlink,
  8717. char *buf, size_t len)
  8718. {
  8719. const struct nlattr *nlattr;
  8720. struct devlink_info_req req;
  8721. struct sk_buff *msg;
  8722. int rem, err;
  8723. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  8724. if (!msg)
  8725. return;
  8726. req.msg = msg;
  8727. err = devlink->ops->info_get(devlink, &req, NULL);
  8728. if (err)
  8729. goto free_msg;
  8730. nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
  8731. const struct nlattr *kv;
  8732. int rem_kv;
  8733. if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
  8734. continue;
  8735. nla_for_each_nested(kv, nlattr, rem_kv) {
  8736. if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
  8737. continue;
  8738. strlcat(buf, nla_data(kv), len);
  8739. strlcat(buf, " ", len);
  8740. }
  8741. }
  8742. free_msg:
  8743. nlmsg_free(msg);
  8744. }
  8745. void devlink_compat_running_version(struct net_device *dev,
  8746. char *buf, size_t len)
  8747. {
  8748. struct devlink *devlink;
  8749. dev_hold(dev);
  8750. rtnl_unlock();
  8751. devlink = netdev_to_devlink(dev);
  8752. if (!devlink || !devlink->ops->info_get)
  8753. goto out;
  8754. mutex_lock(&devlink->lock);
  8755. __devlink_compat_running_version(devlink, buf, len);
  8756. mutex_unlock(&devlink->lock);
  8757. out:
  8758. rtnl_lock();
  8759. dev_put(dev);
  8760. }
  8761. int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
  8762. {
  8763. struct devlink_flash_update_params params = {};
  8764. struct devlink *devlink;
  8765. int ret;
  8766. dev_hold(dev);
  8767. rtnl_unlock();
  8768. devlink = netdev_to_devlink(dev);
  8769. if (!devlink || !devlink->ops->flash_update) {
  8770. ret = -EOPNOTSUPP;
  8771. goto out;
  8772. }
  8773. params.file_name = file_name;
  8774. mutex_lock(&devlink->lock);
  8775. ret = devlink->ops->flash_update(devlink, &params, NULL);
  8776. mutex_unlock(&devlink->lock);
  8777. out:
  8778. rtnl_lock();
  8779. dev_put(dev);
  8780. return ret;
  8781. }
  8782. int devlink_compat_phys_port_name_get(struct net_device *dev,
  8783. char *name, size_t len)
  8784. {
  8785. struct devlink_port *devlink_port;
  8786. /* RTNL mutex is held here which ensures that devlink_port
  8787. * instance cannot disappear in the middle. No need to take
  8788. * any devlink lock as only permanent values are accessed.
  8789. */
  8790. ASSERT_RTNL();
  8791. devlink_port = netdev_to_devlink_port(dev);
  8792. if (!devlink_port)
  8793. return -EOPNOTSUPP;
  8794. return __devlink_port_phys_port_name_get(devlink_port, name, len);
  8795. }
  8796. int devlink_compat_switch_id_get(struct net_device *dev,
  8797. struct netdev_phys_item_id *ppid)
  8798. {
  8799. struct devlink_port *devlink_port;
  8800. /* Caller must hold RTNL mutex or reference to dev, which ensures that
  8801. * devlink_port instance cannot disappear in the middle. No need to take
  8802. * any devlink lock as only permanent values are accessed.
  8803. */
  8804. devlink_port = netdev_to_devlink_port(dev);
  8805. if (!devlink_port || !devlink_port->switch_port)
  8806. return -EOPNOTSUPP;
  8807. memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
  8808. return 0;
  8809. }
  8810. static void __net_exit devlink_pernet_pre_exit(struct net *net)
  8811. {
  8812. struct devlink *devlink;
  8813. u32 actions_performed;
  8814. int err;
  8815. /* In case network namespace is getting destroyed, reload
  8816. * all devlink instances from this namespace into init_net.
  8817. */
  8818. mutex_lock(&devlink_mutex);
  8819. list_for_each_entry(devlink, &devlink_list, list) {
  8820. if (net_eq(devlink_net(devlink), net)) {
  8821. if (WARN_ON(!devlink_reload_supported(devlink->ops)))
  8822. continue;
  8823. err = devlink_reload(devlink, &init_net,
  8824. DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
  8825. DEVLINK_RELOAD_LIMIT_UNSPEC,
  8826. &actions_performed, NULL);
  8827. if (err && err != -EOPNOTSUPP)
  8828. pr_warn("Failed to reload devlink instance into init_net\n");
  8829. }
  8830. }
  8831. mutex_unlock(&devlink_mutex);
  8832. }
  8833. static struct pernet_operations devlink_pernet_ops __net_initdata = {
  8834. .pre_exit = devlink_pernet_pre_exit,
  8835. };
  8836. static int __init devlink_init(void)
  8837. {
  8838. int err;
  8839. err = genl_register_family(&devlink_nl_family);
  8840. if (err)
  8841. goto out;
  8842. err = register_pernet_subsys(&devlink_pernet_ops);
  8843. out:
  8844. WARN_ON(err);
  8845. return err;
  8846. }
  8847. subsys_initcall(devlink_init);