1 Star 0 Fork 48

flying-eagle/lwip

forked from src-openEuler/lwip 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0002-adapt-lstack.patch 172.89 KB
一键复制 编辑 原始数据 按行查看 历史
jinag12 提交于 2024-02-06 10:45 . adapt lwip-2.2.0
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563
From 388525230f809bfa61fe31921b54ebfb6aae57ec Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng12@huawei.com>
Date: Fri, 31 Dec 2021 17:32:49 +0800
Subject: [PATCH] adapt lstack
---
src/Makefile | 5 +-
src/api/api_lib.c | 2 +
src/api/api_msg.c | 46 +++
src/api/dir.mk | 2 +-
src/api/perf.c | 182 ++++++++++++
src/api/posix_api.c | 156 ++++++++++
src/api/sockets.c | 558 ++++++++++++++++++++++++++++++++++-
src/api/sys_arch.c | 379 ++++++++++++++++++++++++
src/api/tcpip.c | 34 ++-
src/core/dir.mk | 8 +-
src/core/init.c | 4 +-
src/core/ip.c | 2 +-
src/core/ipv4/ip4.c | 14 +
src/core/ipv6/ip6.c | 10 +
src/core/mem.c | 6 +-
src/core/memp.c | 4 +
src/core/netif.c | 8 +-
src/core/pbuf.c | 4 +
src/core/stats.c | 13 +-
src/core/tcp.c | 196 +++++++++++-
src/core/tcp_in.c | 101 ++++++-
src/core/tcp_out.c | 25 +-
src/core/timeouts.c | 18 +-
src/core/udp.c | 15 +
src/include/arch/cc.h | 80 ++++-
src/include/arch/perf.h | 155 ++++++++++
src/include/arch/sys_arch.h | 92 +++++-
src/include/eventpoll.h | 72 +++++
src/include/hlist.h | 233 +++++++++++++++
src/include/list.h | 110 +++++++
src/include/lwip/api.h | 35 +++
src/include/lwip/debug.h | 1 +
src/include/lwip/def.h | 15 +
src/include/lwip/ip.h | 8 +-
src/include/lwip/memp.h | 17 ++
src/include/lwip/netif.h | 4 +-
src/include/lwip/opt.h | 62 +++-
src/include/lwip/priv/memp_std.h | 7 +
src/include/lwip/priv/sockets_priv.h | 49 +--
src/include/lwip/priv/tcp_priv.h | 162 +++++++++-
src/include/lwip/prot/ip4.h | 15 +
src/include/lwip/sockets.h | 67 ++++-
src/include/lwip/stats.h | 4 +-
src/include/lwip/tcp.h | 94 +++++-
src/include/lwip/tcpip.h | 2 +-
src/include/lwip/timeouts.h | 4 +
src/include/lwiplog.h | 81 +++++
src/include/lwipopts.h | 253 ++++++++++++----
src/include/lwipsock.h | 155 ++++++++++
src/include/memp_def.h | 66 +++++
src/include/posix_api.h | 88 ++++++
src/include/reg_sock.h | 62 ++++
src/netif/dir.mk | 2 +-
53 files changed, 3581 insertions(+), 206 deletions(-)
create mode 100644 src/api/perf.c
create mode 100644 src/api/posix_api.c
create mode 100644 src/api/sys_arch.c
create mode 100644 src/include/arch/perf.h
create mode 100644 src/include/eventpoll.h
create mode 100644 src/include/hlist.h
create mode 100644 src/include/list.h
create mode 100644 src/include/lwiplog.h
create mode 100644 src/include/lwipsock.h
create mode 100644 src/include/memp_def.h
create mode 100644 src/include/posix_api.h
create mode 100644 src/include/reg_sock.h
diff --git a/src/Makefile b/src/Makefile
index 3ecf8d2..1676a71 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@ LWIP_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
ROOT_DIR := $(dir $(abspath $(LWIP_DIR)))
LWIP_INC = $(LWIP_DIR)/include
-#DPDK_INCLUDE_FILE ?= /usr/include/dpdk
+DPDK_INCLUDE_FILE ?= /usr/include/dpdk
SEC_FLAGS = -fstack-protector-strong -Werror -Wall -Wl,-z,relro,-z,now -Wl,-z,noexecstack -Wtrampolines -fPIC
@@ -10,7 +10,8 @@ CC = gcc
AR = ar
OPTIMIZATION = -O3
INC = -I$(LWIP_DIR) \
- -I$(LWIP_INC)
+ -I$(LWIP_INC) \
+ -I$(DPDK_INCLUDE_FILE)
CFLAGS = -g $(OPTIMIZATION) $(INC) $(SEC_FLAGS)
ARFLAGS = crDP
diff --git a/src/api/api_lib.c b/src/api/api_lib.c
index 60678f8..4cdb965 100644
--- a/src/api/api_lib.c
+++ b/src/api/api_lib.c
@@ -1061,7 +1061,9 @@ netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u1
/* For locking the core: this _can_ be delayed on low memory/low send buffer,
but if it is, this is done inside api_msg.c:do_write(), so we can use the
non-blocking version here. */
+ PERF_START(PERF_LAYER_TCP, PERF_POINT_TCP_DATA_SEND);
err = netconn_apimsg(lwip_netconn_do_write, &API_MSG_VAR_REF(msg));
+ PERF_STOP_INCREASE_COUNT("lwip_netconn_do_write", PERF_LAYER_TCP);
if (err == ERR_OK) {
if (bytes_written != NULL) {
*bytes_written = API_MSG_VAR_REF(msg).msg.w.offset;
diff --git a/src/api/api_msg.c b/src/api/api_msg.c
index 8092be9..d8d6339 100644
--- a/src/api/api_msg.c
+++ b/src/api/api_msg.c
@@ -54,6 +54,11 @@
#include "lwip/mld6.h"
#include "lwip/priv/tcpip_priv.h"
+#if USE_LIBOS
+#include "lwip/sockets.h"
+#include "lwipsock.h"
+#endif
+
#include <string.h>
/* netconns are polled once per second (e.g. continue write on memory error) */
@@ -455,6 +460,14 @@ err_tcp(void *arg, err_t err)
old_state = conn->state;
conn->state = NETCONN_NONE;
+#if USE_LIBOS
+ if (CONN_TYPE_IS_HOST(conn)) {
+ LWIP_DEBUGF(API_MSG_DEBUG,
+ ("linux localhost connection already success, ignore lwip err_tcp fd=%d\n", conn->socket));
+ return;
+ }
+#endif /* USE_LIBOS */
+
SYS_ARCH_UNPROTECT(lev);
/* Notify the user layer about a connection error. Used to signal select. */
@@ -598,6 +611,10 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
}
+#if USE_LIBOS
+ LWIP_DEBUGF(API_MSG_DEBUG, ("libos incoming connection established\n"));
+ SET_CONN_TYPE_LIBOS(newconn);
+#endif
return ERR_OK;
}
#endif /* LWIP_TCP */
@@ -1316,6 +1333,31 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
return ERR_VAL;
}
+#if USE_LIBOS
+ if (CONN_TYPE_IS_HOST(conn)) {
+ LWIP_DEBUGF(API_MSG_DEBUG,
+ ("libos outgoing connection abort fd=%d\n", conn->socket));
+ return ERR_ABRT;
+ }
+
+ LWIP_DEBUGF(API_MSG_DEBUG, ("libos outgoing connection established\n"));
+ if (CONN_TYPE_HAS_INPRG(conn) && CONN_TYPE_HAS_HOST(conn)) {
+ int s = conn->socket;
+ struct lwip_sock *sock = get_socket_without_errno(s);
+
+ if (!!sock && !!sock->epoll_data) {
+ struct epoll_event ee = {0};
+ ee.data.fd = s;
+ ee.events |= EPOLLIN | EPOLLOUT | EPOLLERR;
+ posix_api->epoll_ctl_fn(sock->epoll_data->fd, EPOLL_CTL_DEL, s, &ee);
+ posix_api->shutdown_fn(s, SHUT_RDWR);
+ LWIP_DEBUGF(API_MSG_DEBUG,
+ ("linux outgoing connection abort fd=%d\n", s));
+ }
+ }
+ SET_CONN_TYPE_LIBOS(conn);
+#endif
+
LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect",
(conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn));
@@ -1339,6 +1381,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
if (was_blocking) {
sys_sem_signal(op_completed_sem);
}
+
return ERR_OK;
}
#endif /* LWIP_TCP */
@@ -1373,6 +1416,7 @@ lwip_netconn_do_connect(void *m)
#endif /* LWIP_UDP */
#if LWIP_TCP
case NETCONN_TCP:
+ PERF_START(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_SEND);
/* Prevent connect while doing any other action. */
if (msg->conn->state == NETCONN_CONNECT) {
err = ERR_ALREADY;
@@ -1390,6 +1434,7 @@ lwip_netconn_do_connect(void *m)
err = ERR_INPROGRESS;
} else {
msg->conn->current_msg = msg;
+ PERF_STOP_INCREASE_COUNT("lwip_netconn_do_connect", PERF_LAYER_TCP);
/* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()),
when the connection is established! */
#if LWIP_TCPIP_CORE_LOCKING
@@ -1403,6 +1448,7 @@ lwip_netconn_do_connect(void *m)
}
}
}
+ PERF_STOP_INCREASE_COUNT("lwip_netconn_do_connect", PERF_LAYER_TCP);
break;
#endif /* LWIP_TCP */
default:
diff --git a/src/api/dir.mk b/src/api/dir.mk
index 72142ab..afbf863 100644
--- a/src/api/dir.mk
+++ b/src/api/dir.mk
@@ -1,3 +1,3 @@
-SRC = api_lib.c api_msg.c err.c netbuf.c netdb.c netifapi.c sockets.c tcpip.c
+SRC = api_lib.c api_msg.c err.c netbuf.c netdb.c netifapi.c sockets.c tcpip.c perf.c posix_api.c sys_arch.c
$(eval $(call register_dir, api, $(SRC)))
diff --git a/src/api/perf.c b/src/api/perf.c
new file mode 100644
index 0000000..1c2a273
--- /dev/null
+++ b/src/api/perf.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#include "arch/perf.h"
+
+#include <signal.h>
+
+#include <lwip/stats.h>
+
+#if LWIP_RECORD_PERF
+
+#define SIG_FUNC_NUM 3
+
+#define SIG_STATS_DISPLAY 38
+#define SIG_PERF_BEGIN 39
+#define SIG_PERF_END 40
+
+typedef void (*pSignalFunc) (int);
+static void signal_stats_display(int s);
+static void signal_perf_begin(int s);
+static void signal_perf_end(int s);
+
+uint32_t g_record_perf;
+__thread uint64_t g_timeTaken[PERF_POINT_END];
+__thread int g_perfPoint[PERF_LAYER_END];
+__thread struct timespec tvStart[PERF_LAYER_END];
+volatile uint64_t g_perfMaxtime[PERF_POINT_END];
+volatile uint64_t g_astPacketCnt[PERF_POINT_END];
+volatile uint64_t g_astPacketProcTime[PERF_POINT_END];
+
+char *g_ppLayerName[PERF_POINT_END] = {
+ "IP_RECV",
+ "TCP_DATA_RECV",
+ "UDP_PARTIAL",
+ "TCP_SYN_RECV",
+ "TCP_SYN_ACK_SEND",
+ "TCP_ACK_RECV",
+ "TCP_SYN_SEND",
+ "TCP_SYN_ACK_RECV",
+ "TCP_ACK_SEND",
+ "TCP_DATA_SEND",
+ "IP_SEND"
+};
+
+static int gsig_arr[SIG_FUNC_NUM] = {
+ SIG_STATS_DISPLAY,
+ SIG_PERF_BEGIN,
+ SIG_PERF_END
+};
+
+static pSignalFunc g_Funcs[SIG_FUNC_NUM] = {
+ signal_stats_display,
+ signal_perf_begin,
+ signal_perf_end,
+};
+
+static void print_perf_data_and_reset()
+{
+ int i;
+ printf("\n********* PERF DATA START*************\n");
+ for (i = 0; i < PERF_POINT_END; i++) {
+ printf("%-20s Total: PacketProcTime: %-15"PRIu64", Maxtime: %-15"PRIu64", packetCnt: %-15"PRIu64"\n",
+ g_ppLayerName[i], __sync_fetch_and_or(&g_astPacketProcTime[i], 0),
+ __sync_fetch_and_or(&g_perfMaxtime[i], 0),
+ __sync_fetch_and_or(&g_astPacketCnt[i], 0));
+
+ if (__sync_fetch_and_or(&g_astPacketProcTime[i], 0) && __sync_fetch_and_or(&g_astPacketCnt[i], 0)) {
+ printf("%-20s Average: PacketProcTime: %-15lf, MaxTime: %-15"PRIu64"\n", g_ppLayerName[i],
+ (double)__sync_fetch_and_or(&g_astPacketProcTime[i], 0) / (double)__sync_fetch_and_or(&g_astPacketCnt[i], 0),
+ __sync_or_and_fetch(&g_perfMaxtime[i], 0));
+ }
+
+ __sync_fetch_and_and (&g_astPacketProcTime[i], 0);
+ __sync_fetch_and_and (&g_astPacketCnt[i], 0);
+ __sync_fetch_and_and (&g_perfMaxtime[i], 0);
+ }
+ printf("\n********* PERF DATA END*************\n");
+}
+
+static void signal_stats_display(int s)
+{
+ struct sigaction s_test;
+ printf("Received signal %d, stats display.\n", s);
+ stats_display();
+ s_test.sa_handler = (void *) signal_stats_display;
+ if (sigemptyset(&s_test.sa_mask) != 0) {
+ printf("sigemptyset failed.\n");
+ }
+ s_test.sa_flags = SA_RESETHAND;
+ if (sigaction(s, &s_test, NULL) != 0) {
+ printf("Could not register %d signal handler.\n", s);
+ }
+}
+
+static void signal_perf_begin(int s)
+{
+ struct sigaction s_test;
+ printf("Received signal %d, perf_begin.\n", s);
+ g_record_perf = 1;
+ s_test.sa_handler = (void *) signal_perf_begin;
+ if (sigemptyset(&s_test.sa_mask) != 0) {
+ printf("sigemptyset failed.\n");
+ }
+ s_test.sa_flags = SA_RESETHAND;
+ if (sigaction(s, &s_test, NULL) != 0) {
+ printf("Could not register %d signal handler.\n", s);
+ }
+}
+
+static void signal_perf_end(int s)
+{
+ struct sigaction s_test;
+ printf("Received signal %d, perf_end\n", s);
+ g_record_perf = 0;
+ print_perf_data_and_reset();
+ s_test.sa_handler = (void *) signal_perf_end;
+ if (sigemptyset(&s_test.sa_mask) != 0) {
+ printf("sigemptyset failed.\n");
+ }
+ s_test.sa_flags = SA_RESETHAND;
+ if (sigaction(s, &s_test, NULL) != 0) {
+ printf("Could not register %d signal handler.\n", s);
+ }
+}
+
+int check_layer_point(int layer, int point)
+{
+ if (point == g_perfPoint[layer]) {
+ return 1;
+ }
+ return 0;
+}
+
+int perf_init(void)
+{
+ int i;
+ struct sigaction s_test;
+ for (i = 0; i < SIG_FUNC_NUM; i++) {
+ s_test.sa_handler = (void *) g_Funcs[i];
+ if (sigemptyset(&s_test.sa_mask) != 0) {
+ printf("sigemptyset failed.\n");
+ return 1;
+ }
+
+ s_test.sa_flags = SA_RESETHAND;
+ if (sigaction(gsig_arr[i], &s_test, NULL) != 0) {
+ printf("Could not register %d signal handler.\n", gsig_arr[i]);
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif
diff --git a/src/api/posix_api.c b/src/api/posix_api.c
new file mode 100644
index 0000000..a917cea
--- /dev/null
+++ b/src/api/posix_api.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+
+#include "lwip/err.h"
+#include "lwipsock.h"
+
+posix_api_t *posix_api;
+posix_api_t posix_api_val;
+
+static int chld_is_epfd(int fd)
+{
+ return 0;
+}
+
+static struct lwip_sock *chld_get_socket(int fd)
+{
+ return NULL;
+}
+
+void posix_api_fork(void)
+{
+ /* lstack helper api */
+ posix_api->is_chld = 1;
+ posix_api->is_epfd = chld_is_epfd;
+ posix_api->get_socket = chld_get_socket;
+}
+
+static int chose_dlsym_handle(void *__restrict* khandle)
+{
+ void *dlhandle;
+ int (*gazelle_epoll_create)(int size);
+ dlhandle = dlopen ("liblstack.so", RTLD_LAZY);
+ if (dlhandle == NULL) {
+ return ERR_IF;
+ }
+
+ gazelle_epoll_create = dlsym(dlhandle, "epoll_create");
+ if (gazelle_epoll_create == NULL) {
+ return ERR_MEM;
+ }
+
+ dlclose(dlhandle);
+
+ *khandle = RTLD_NEXT;
+ if (dlsym(*khandle, "epoll_create") == gazelle_epoll_create) {
+ RTE_LOG(ERR, EAL, "posix api use RTLD_DEFAULT\n");
+ *khandle = RTLD_DEFAULT;
+ } else {
+ RTE_LOG(ERR, EAL, "posix api use RTLD_NEXT\n");
+ }
+
+ return ERR_OK;
+}
+
+int posix_api_init(void)
+{
+/* the symbol we use here won't be NULL, so we don't need dlerror()
+ to test error */
+#define CHECK_DLSYM_RET_RETURN(ret) do { \
+ if ((ret) == NULL) \
+ goto err_out; \
+ } while (0)
+
+ posix_api = &posix_api_val;
+
+ void *__restrict handle;
+ int ret = chose_dlsym_handle(&handle);
+ if (ret != ERR_OK) {
+ return ret;
+ }
+
+ /* glibc standard api */
+ CHECK_DLSYM_RET_RETURN(posix_api->socket_fn = dlsym(handle, "socket"));
+ CHECK_DLSYM_RET_RETURN(posix_api->accept_fn = dlsym(handle, "accept"));
+ CHECK_DLSYM_RET_RETURN(posix_api->accept4_fn = dlsym(handle, "accept4"));
+ CHECK_DLSYM_RET_RETURN(posix_api->bind_fn = dlsym(handle, "bind"));
+ CHECK_DLSYM_RET_RETURN(posix_api->listen_fn = dlsym(handle, "listen"));
+ CHECK_DLSYM_RET_RETURN(posix_api->connect_fn = dlsym(handle, "connect"));
+ CHECK_DLSYM_RET_RETURN(posix_api->setsockopt_fn = dlsym(handle, "setsockopt"));
+ CHECK_DLSYM_RET_RETURN(posix_api->getsockopt_fn = dlsym(handle, "getsockopt"));
+ CHECK_DLSYM_RET_RETURN(posix_api->getpeername_fn = dlsym(handle, "getpeername"));
+ CHECK_DLSYM_RET_RETURN(posix_api->getsockname_fn = dlsym(handle, "getsockname"));
+ CHECK_DLSYM_RET_RETURN(posix_api->shutdown_fn = dlsym(handle, "shutdown"));
+ CHECK_DLSYM_RET_RETURN(posix_api->close_fn = dlsym(handle, "close"));
+ CHECK_DLSYM_RET_RETURN(posix_api->read_fn = dlsym(handle, "read"));
+ CHECK_DLSYM_RET_RETURN(posix_api->write_fn = dlsym(handle, "write"));
+ CHECK_DLSYM_RET_RETURN(posix_api->recv_fn = dlsym(handle, "recv"));
+ CHECK_DLSYM_RET_RETURN(posix_api->send_fn = dlsym(handle, "send"));
+ CHECK_DLSYM_RET_RETURN(posix_api->recv_msg = dlsym(handle, "recvmsg"));
+ CHECK_DLSYM_RET_RETURN(posix_api->send_msg = dlsym(handle, "sendmsg"));
+ CHECK_DLSYM_RET_RETURN(posix_api->recv_from = dlsym(handle, "recvfrom"));
+ CHECK_DLSYM_RET_RETURN(posix_api->send_to = dlsym(handle, "sendto"));
+ CHECK_DLSYM_RET_RETURN(posix_api->fcntl_fn = dlsym(handle, "fcntl"));
+ CHECK_DLSYM_RET_RETURN(posix_api->fcntl64_fn = dlsym(handle, "fcntl64"));
+ CHECK_DLSYM_RET_RETURN(posix_api->pipe_fn = dlsym(handle, "pipe"));
+ CHECK_DLSYM_RET_RETURN(posix_api->epoll_create_fn = dlsym(handle, "epoll_create"));
+ CHECK_DLSYM_RET_RETURN(posix_api->epoll_ctl_fn = dlsym(handle, "epoll_ctl"));
+ CHECK_DLSYM_RET_RETURN(posix_api->epoll_wait_fn = dlsym(handle, "epoll_wait"));
+ CHECK_DLSYM_RET_RETURN(posix_api->fork_fn = dlsym(handle, "fork"));
+ CHECK_DLSYM_RET_RETURN(posix_api->eventfd_fn = dlsym(handle, "eventfd"));
+ CHECK_DLSYM_RET_RETURN(posix_api->sigaction_fn = dlsym(handle, "sigaction"));
+ CHECK_DLSYM_RET_RETURN(posix_api->poll_fn = dlsym(handle, "poll"));
+ CHECK_DLSYM_RET_RETURN(posix_api->ioctl_fn = dlsym(handle, "ioctl"));
+
+ /* lstack helper api */
+ posix_api->get_socket = get_socket;
+ posix_api->is_epfd = lwip_is_epfd;
+ posix_api->epoll_close_fn = lwip_epoll_close;
+
+ /* support fork */
+ posix_api->is_chld = 0;
+ return ERR_OK;
+
+err_out:
+ return ERR_MEM;
+#undef CHECK_DLSYM_RET_RETURN
+}
diff --git a/src/api/sockets.c b/src/api/sockets.c
index b911194..8df741d 100644
--- a/src/api/sockets.c
+++ b/src/api/sockets.c
@@ -62,8 +62,21 @@
#include <stdarg.h>
#endif
+#if USE_LIBOS
+#include <stdarg.h>
+#include "lwipsock.h"
+#endif
+
#include <string.h>
+#if USE_LIBOS
+enum KERNEL_LWIP_PATH {
+ PATH_KERNEL = 0,
+ PATH_LWIP,
+ PATH_ERR,
+};
+#endif
+
#ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME
#endif
@@ -92,6 +105,7 @@
/* Address length safe read and write */
#if LWIP_SOCKET_HAVE_SA_LEN
+
#if LWIP_IPV4
#define IP4ADDR_SOCKADDR_SET_LEN(sin) \
(sin)->sin_len = sizeof(struct sockaddr_in)
@@ -130,12 +144,20 @@
#endif /* LWIP_SOCKET_HAVE_SA_LEN */
#if LWIP_IPV4
+#if USE_LIBOS
+#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \
+ (sin)->sin_family = AF_INET; \
+ (sin)->sin_port = lwip_htons((port)); \
+ inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \
+ memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0)
+#else
#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \
IP4ADDR_SOCKADDR_SET_LEN(sin); \
(sin)->sin_family = AF_INET; \
(sin)->sin_port = lwip_htons((port)); \
inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \
memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0)
+#endif /* USE_LIBOS */
#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \
inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \
(port) = lwip_ntohs((sin)->sin_port); }while(0)
@@ -301,7 +323,12 @@ static void lwip_socket_drop_registered_mld6_memberships(int s);
#endif /* LWIP_IPV6_MLD */
/** The global array of available sockets */
+#if USE_LIBOS
+uint32_t sockets_num;
+struct lwip_sock *sockets;
+#else
static struct lwip_sock sockets[NUM_SOCKETS];
+#endif /* USE_LIBOS */
#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
#if LWIP_TCPIP_CORE_LOCKING
@@ -324,7 +351,7 @@ static struct lwip_select_cb *select_cb_list;
/* Forward declaration of some functions */
#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
-static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
+void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
#define DEFAULT_SOCKET_EVENTCB event_callback
static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent);
#else
@@ -450,7 +477,13 @@ static struct lwip_sock *
tryget_socket_unconn_nouse(int fd)
{
int s = fd - LWIP_SOCKET_OFFSET;
- if ((s < 0) || (s >= NUM_SOCKETS)) {
+
+#if USE_LIBOS
+ if ((s < 0) || (s >= sockets_num))
+#else
+ if ((s < 0) || (s >= NUM_SOCKETS))
+#endif /* USE_LIBOS */
+ {
LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd));
return NULL;
}
@@ -514,8 +547,13 @@ tryget_socket(int fd)
* @param fd externally used socket index
* @return struct lwip_sock for the socket or NULL if not found
*/
+#if USE_LIBOS
+struct lwip_sock *
+get_socket(int fd)
+#else
static struct lwip_sock *
get_socket(int fd)
+#endif /* USE_LIBOS */
{
struct lwip_sock *sock = tryget_socket(fd);
if (!sock) {
@@ -528,6 +566,24 @@ get_socket(int fd)
return sock;
}
+#if USE_LIBOS
+/**
+ * Map a externally used socket index to the internal socket representation.
+ *
+ * @param s externally used socket index
+ * @return struct lwip_sock for the socket or NULL if not found without
+ * checking.
+ */
+struct lwip_sock *
+get_socket_by_fd(int fd)
+{
+ if ((fd < LWIP_SOCKET_OFFSET) || (fd >= sockets_num + LWIP_SOCKET_OFFSET)) {
+ return NULL;
+ }
+ return &sockets[fd - LWIP_SOCKET_OFFSET];
+}
+#endif /* USE_LIBOS */
+
/**
* Allocate a new socket for a given netconn.
*
@@ -543,6 +599,62 @@ alloc_socket(struct netconn *newconn, int accepted)
SYS_ARCH_DECL_PROTECT(lev);
LWIP_UNUSED_ARG(accepted);
+#if USE_LIBOS
+ int type, protocol = 0, domain = AF_INET;
+ switch (NETCONNTYPE_GROUP(newconn->type)) {
+ case NETCONN_RAW:
+ type = SOCK_RAW;
+ break;
+ case NETCONN_UDPLITE:
+ case NETCONN_UDP:
+ type = SOCK_DGRAM;
+ break;
+ case NETCONN_TCP:
+ type = SOCK_STREAM;
+ break;
+ default:
+ type = -1;
+ break;
+ }
+
+ SYS_ARCH_PROTECT(lev);
+ i = posix_api->socket_fn(domain, type, protocol);
+ if (i == -1) {
+ goto err;
+ }
+
+ if ((i < LWIP_SOCKET_OFFSET) || (i >= sockets_num + LWIP_SOCKET_OFFSET)) {
+ goto err;
+ }
+
+ if (!sockets[i].conn && (sockets[i].select_waiting == 0)) {
+ /*initialize state as NETCONN_HOST | NETCONN_LIBOS,
+ *if connection accepted and alloc_socket called, it can be only NETCONN_LIBOS*/
+ if (accepted)
+ SET_CONN_TYPE_LIBOS(newconn);
+ else
+ SET_CONN_TYPE_LIBOS_OR_HOST(newconn);
+ sockets[i].conn = newconn;
+ /* The socket is not yet known to anyone, so no need to protect
+ after having marked it as used. */
+ SYS_ARCH_UNPROTECT(lev);
+ sockets[i].lastdata.pbuf = NULL;
+ sockets[i].rcvevent = 0;
+ /* TCP sendbuf is empty, but the socket is not yet writable until connected
+ * (unless it has been created by accept()). */
+ sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
+ sockets[i].errevent = 0;
+ sockets[i].epoll_data = NULL;
+ init_list_node_null(&sockets[i].list);
+ return i + LWIP_SOCKET_OFFSET;
+ }
+
+err:
+ posix_api->close_fn(i);
+ SYS_ARCH_UNPROTECT(lev);
+ return -1;
+#else /* USE_LIBOS */
+
/* allocate a new socket identifier */
for (i = 0; i < NUM_SOCKETS; ++i) {
/* Protect socket array */
@@ -574,6 +686,8 @@ alloc_socket(struct netconn *newconn, int accepted)
SYS_ARCH_UNPROTECT(lev);
}
return -1;
+
+#endif /* USE_LIBOS */
}
/** Free a socket (under lock)
@@ -668,10 +782,43 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
SYS_ARCH_DECL_PROTECT(lev);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
+#if USE_LIBOS
+ int sys_errno = 0;
+
+ sock = posix_api->get_socket(s);
+ /*AF_UNIX case*/
+ if (!sock) {
+ if (rearm_accept_fd(s) < 0) {
+ LWIP_DEBUGF(SOCKETS_DEBUG,
+ ("failed to rearm accept fd=%d errno=%d\n", s, errno));
+ }
+ return posix_api->accept_fn(s, addr, addrlen);
+ }
+
+ /*for AF_INET, we may try both linux and lwip*/
+ if (!CONN_TYPE_HAS_LIBOS_AND_HOST(sock->conn)) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("conn->type has libos and host bits"));
+ set_errno(EINVAL);
+ return -1;
+ }
+
+ if (rearm_accept_fd(s) < 0) {
+ LWIP_DEBUGF(SOCKETS_DEBUG,
+ ("failed to rearm accept fd=%d errno=%d\n", s, errno));
+ }
+
+ /* raise accept syscall in palce */
+ newsock = posix_api->accept_fn(s, addr, addrlen);
+ if (newsock >= 0) {
+ return newsock;
+ }
+ sys_errno = errno;
+#else
sock = get_socket(s);
if (!sock) {
return -1;
}
+#endif
/* wait for a new connection */
err = netconn_accept(sock->conn, &newconn);
@@ -685,6 +832,9 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
set_errno(err_to_errno(err));
}
done_socket(sock);
+#if USE_LIBOS
+ set_errno(sys_errno);
+#endif /* USE_LIBOS */
return -1;
}
LWIP_ASSERT("newconn != NULL", newconn != NULL);
@@ -696,7 +846,11 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
done_socket(sock);
return -1;
}
+#if USE_LIBOS
+ LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < sockets_num + LWIP_SOCKET_OFFSET));
+#else
LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET));
+#endif /* USE_LIBOS */
nsock = &sockets[newsock - LWIP_SOCKET_OFFSET];
/* See event_callback: If data comes in right away after an accept, even
@@ -734,9 +888,11 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
}
IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port);
+#if !USE_LIBOS
if (*addrlen > IPADDR_SOCKADDR_GET_LEN(&tempaddr)) {
*addrlen = IPADDR_SOCKADDR_GET_LEN(&tempaddr);
}
+#endif /* USE_LIBOS */
MEMCPY(addr, &tempaddr, *addrlen);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
@@ -759,11 +915,24 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
ip_addr_t local_addr;
u16_t local_port;
err_t err;
-
+#if USE_LIBOS
+ sock = posix_api->get_socket(s);
+ /*AF_UNIX case*/
+ if (!sock) {
+ return posix_api->bind_fn(s, name, namelen);
+ }
+ /*for AF_INET, we may try both linux and lwip*/
+ if (!CONN_TYPE_HAS_LIBOS_AND_HOST(sock->conn)) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("conn->type has libos and host bits"));
+ set_errno(EINVAL);
+ return -1;
+ }
+#else
sock = get_socket(s);
if (!sock) {
return -1;
}
+#endif
if (!SOCK_ADDR_TYPE_MATCH(name, sock)) {
/* sockaddr does not match socket type (IPv4/IPv6) */
@@ -783,6 +952,18 @@ lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port));
+#if USE_LIBOS
+ /* Supports kernel NIC IP address. */
+ int ret = posix_api->bind_fn(s, name, namelen);
+ if (ret < 0) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("bind syscall failed\n"));
+ /* bind must succeed on both linux and libos */
+ if (!is_host_ipv4(local_addr.addr)) {
+ return ret;
+ }
+ }
+#endif /* USE_LIBOS */
+
#if LWIP_IPV4 && LWIP_IPV6
/* Dual-stack: Unmap IPv4 mapped IPv6 addresses */
if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) {
@@ -815,10 +996,29 @@ lwip_close(int s)
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
+#if USE_LIBOS
+ int ret;
+ if (posix_api->is_epfd(s)) {
+ return posix_api->epoll_close_fn(s);
+ }
+
+ ret = posix_api->close_fn(s);
+ if (ret < 0)
+ return ret;
+ if (posix_api->is_chld == 0)
+ clean_host_fd(s);
+
+ sock = posix_api->get_socket(s);
+ /*AF_UNIX case*/
+ if (!sock) {
+ return ret;
+ }
+#else
sock = get_socket(s);
if (!sock) {
return -1;
}
+#endif /* USE_LIBOS */
if (sock->conn != NULL) {
is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP;
@@ -842,6 +1042,13 @@ lwip_close(int s)
return -1;
}
+#if USE_LIBOS
+ sock->epoll = LIBOS_EPOLLNONE;
+ sock->events = 0;
+ sock->epoll_data = NULL;
+ list_del_node_null(&sock->list);
+#endif
+
free_socket(sock, is_tcp);
set_errno(0);
return 0;
@@ -853,10 +1060,28 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
struct lwip_sock *sock;
err_t err;
+#if USE_LIBOS
+ int ret;
+
+ sock = posix_api->get_socket(s);
+ if (!sock) {
+ return posix_api->connect_fn(s, name, namelen);
+ }
+
+ /* raise connect syscall in place */
+ ADD_CONN_TYPE_INPRG(sock->conn);
+ ret = posix_api->connect_fn(s, name, namelen);
+ if (!ret) {
+ SET_CONN_TYPE_HOST(sock->conn);
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("linux connect succeed fd=%d\n", s));
+ return ret;
+ }
+#else
sock = get_socket(s);
if (!sock) {
return -1;
}
+#endif
if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) {
/* sockaddr does not match socket type (IPv4/IPv6) */
@@ -901,6 +1126,11 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
return -1;
}
+#if USE_LIBOS
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("libos connect succeed fd=%d\n",s));
+ SET_CONN_TYPE_LIBOS(sock->conn);
+#endif /* USE_LIBOS */
+
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));
set_errno(0);
done_socket(sock);
@@ -923,10 +1153,29 @@ lwip_listen(int s, int backlog)
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
+#if USE_LIBOS
+ int ret;
+
+ sock = posix_api->get_socket(s);
+ /*AF_UNIX case*/
+ if (!sock) {
+ return posix_api->listen_fn(s, backlog);
+ }
+ /*for AF_INET, we may try both linux and lwip*/
+ if (!CONN_TYPE_HAS_LIBOS_AND_HOST(sock->conn)) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("conn->type has libos and host bits"));
+ set_errno(EADDRINUSE);
+ return -1;
+ }
+
+ if ((ret = posix_api->listen_fn(s, backlog)) == -1)
+ return ret;
+#else
sock = get_socket(s);
if (!sock) {
return -1;
}
+#endif
/* limit the "backlog" parameter to fit in an u8_t */
backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff);
@@ -958,6 +1207,9 @@ static ssize_t
lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
{
u8_t apiflags = NETCONN_NOAUTORCVD;
+#if USE_LIBOS
+ apiflags = 0;
+#endif
ssize_t recvd = 0;
ssize_t recv_left = (len <= SSIZE_MAX) ? (ssize_t)len : SSIZE_MAX;
@@ -977,6 +1229,13 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
/* Check if there is data left from the last recv operation. */
if (sock->lastdata.pbuf) {
p = sock->lastdata.pbuf;
+#if USE_LIBOS
+ if ((flags & MSG_PEEK) == 0) {
+ if ((NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP)) {
+ del_epoll_event(sock->conn, EPOLLIN);
+ }
+ }
+#endif
} else {
/* No data was left from the previous operation, so we try to get
some from the network. */
@@ -1047,10 +1306,22 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
/* @todo: do we need to support peeking more than one pbuf? */
} while ((recv_left > 0) && !(flags & MSG_PEEK));
lwip_recv_tcp_done:
- if ((recvd > 0) && !(flags & MSG_PEEK)) {
- /* ensure window update after copying all data */
- netconn_tcp_recvd(sock->conn, (size_t)recvd);
+#if USE_LIBOS
+ if (apiflags & NETCONN_NOAUTORCVD)
+#endif
+ {
+ if ((recvd > 0) && !(flags & MSG_PEEK)) {
+ /* ensure window update after copying all data */
+ netconn_tcp_recvd(sock->conn, (size_t)recvd);
+ }
}
+#if USE_LIBOS
+ if ((flags & MSG_PEEK) == 0) {
+ if (((NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP)) && sock->lastdata.pbuf) {
+ add_epoll_event(sock->conn, EPOLLIN);
+ }
+ }
+#endif
set_errno(0);
return recvd;
}
@@ -1079,11 +1350,13 @@ lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port,
#endif /* LWIP_IPV4 && LWIP_IPV6 */
IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port);
+#if !USE_LIBOS
if (*fromlen < IPADDR_SOCKADDR_GET_LEN(&saddr)) {
truncated = 1;
} else if (*fromlen > IPADDR_SOCKADDR_GET_LEN(&saddr)) {
*fromlen = IPADDR_SOCKADDR_GET_LEN(&saddr);
}
+#endif
MEMCPY(from, &saddr, *fromlen);
return truncated;
}
@@ -1233,6 +1506,43 @@ lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16
return ERR_OK;
}
+#if USE_LIBOS
+static inline enum KERNEL_LWIP_PATH select_path(int s)
+{
+ struct lwip_sock *sock;
+
+ sock = posix_api->get_socket(s);
+ /*AF_UNIX case*/
+ if (!sock) {
+ if (rearm_host_fd(s) < 0) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("failed to rearm fd=%d errno=%d\n", s, errno));
+ }
+ return PATH_KERNEL;
+ }
+
+ if (CONN_TYPE_HAS_INPRG(sock->conn)) {
+ set_errno(EWOULDBLOCK);
+ return PATH_ERR;
+ }
+
+ /*for AF_INET, we can try erther linux or lwip*/
+ if (CONN_TYPE_IS_HOST(sock->conn)) {
+ if (rearm_host_fd(s) < 0) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("failed to rearm read fd=%d errno=%d\n", s, errno));
+ }
+ return PATH_KERNEL;
+ }
+
+ if (!CONN_TYPE_IS_LIBOS(sock->conn)) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("conn->type is not libos bit type=%x", netconn_type(sock->conn)));
+ set_errno(EINVAL);
+ return PATH_ERR;
+ }
+
+ return PATH_LWIP;
+}
+#endif
+
ssize_t
lwip_recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
@@ -1240,6 +1550,15 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
struct lwip_sock *sock;
ssize_t ret;
+#if USE_LIBOS
+ enum KERNEL_LWIP_PATH path = select_path(s);
+ if (path == PATH_ERR) {
+ return -1;
+ } else if (path == PATH_KERNEL) {
+ return posix_api->recv_from(s, mem, len, flags, from, fromlen);
+ }
+#endif
+
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags));
sock = get_socket(s);
if (!sock) {
@@ -1289,6 +1608,14 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
ssize_t
lwip_read(int s, void *mem, size_t len)
{
+#if USE_LIBOS
+ enum KERNEL_LWIP_PATH path = select_path(s);
+ if (path == PATH_ERR) {
+ return -1;
+ } else if (path == PATH_KERNEL) {
+ return posix_api->read_fn(s, mem, len);
+ }
+#endif
return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
}
@@ -1322,6 +1649,15 @@ lwip_recvmsg(int s, struct msghdr *message, int flags)
msg_iovlen_t i;
ssize_t buflen;
+#if USE_LIBOS
+ enum KERNEL_LWIP_PATH path = select_path(s);
+ if (path == PATH_ERR) {
+ return -1;
+ } else if (path == PATH_KERNEL) {
+ return posix_api->recv_msg(s, message, flags);
+ }
+#endif
+
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags));
LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;);
LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK|MSG_DONTWAIT)) == 0,
@@ -1466,6 +1802,15 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags)
#endif
err_t err = ERR_OK;
+#if USE_LIBOS
+ enum KERNEL_LWIP_PATH path = select_path(s);
+ if (path == PATH_ERR) {
+ return -1;
+ } else if (path == PATH_KERNEL) {
+ return posix_api->send_msg(s, msg, flags);
+ }
+#endif
+
sock = get_socket(s);
if (!sock) {
return -1;
@@ -1629,6 +1974,15 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
u16_t remote_port;
struct netbuf buf;
+#if USE_LIBOS
+ enum KERNEL_LWIP_PATH path = select_path(s);
+ if (path == PATH_ERR) {
+ return -1;
+ } else if (path == PATH_KERNEL) {
+ return posix_api->send_to(s, data, size, flags, to, tolen);
+ }
+#endif
+
sock = get_socket(s);
if (!sock) {
return -1;
@@ -1727,6 +2081,11 @@ lwip_socket(int domain, int type, int protocol)
LWIP_UNUSED_ARG(domain); /* @todo: check this */
+#if USE_LIBOS
+ if ((domain != AF_INET && domain != AF_UNSPEC) || posix_api->is_chld)
+ return posix_api->socket_fn(domain, type, protocol);
+#endif
+
/* create a netconn */
switch (type) {
case SOCK_RAW:
@@ -1783,6 +2142,14 @@ lwip_socket(int domain, int type, int protocol)
ssize_t
lwip_write(int s, const void *data, size_t size)
{
+#if USE_LIBOS
+ enum KERNEL_LWIP_PATH path = select_path(s);
+ if (path == PATH_ERR) {
+ return -1;
+ } else if (path == PATH_KERNEL) {
+ return posix_api->write_fn(s, data, size);
+ }
+#endif
return lwip_send(s, data, size, 0);
}
@@ -2518,7 +2885,7 @@ lwip_poll_should_wake(const struct lwip_select_cb *scb, int fd, int has_recveven
* NETCONN_EVT_ERROR
* This requirement will be asserted in select_check_waiters()
*/
-static void
+void
event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
{
int s, check_waiters;
@@ -2567,23 +2934,38 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
if (sock->rcvevent > 1) {
check_waiters = 0;
}
+#if USE_LIBOS
+ add_epoll_event(conn, EPOLLIN);
+#endif
break;
case NETCONN_EVT_RCVMINUS:
sock->rcvevent--;
check_waiters = 0;
+#if USE_LIBOS
+ del_epoll_event(conn, EPOLLIN);
+#endif
break;
case NETCONN_EVT_SENDPLUS:
if (sock->sendevent) {
check_waiters = 0;
}
sock->sendevent = 1;
+#if USE_LIBOS
+ add_epoll_event(conn, EPOLLOUT);
+#endif
break;
case NETCONN_EVT_SENDMINUS:
sock->sendevent = 0;
check_waiters = 0;
+#if USE_LIBOS
+ del_epoll_event(conn, EPOLLOUT);
+#endif
break;
case NETCONN_EVT_ERROR:
sock->errevent = 1;
+#if USE_LIBOS
+ add_epoll_event(conn, EPOLLERR);
+#endif
break;
default:
LWIP_ASSERT("unknown event", 0);
@@ -2778,9 +3160,11 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
ip_addr_debug_print_val(SOCKETS_DEBUG, naddr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port));
+#if !USE_LIBOS
if (*namelen > IPADDR_SOCKADDR_GET_LEN(&saddr)) {
*namelen = IPADDR_SOCKADDR_GET_LEN(&saddr);
}
+#endif
MEMCPY(name, &saddr, *namelen);
set_errno(0);
@@ -2791,12 +3175,41 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
int
lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
{
+#if USE_LIBOS
+ struct lwip_sock *sock;
+
+ sock = posix_api->get_socket(s);
+ if (!sock) {
+ return posix_api->getpeername_fn(s, name, namelen);
+ }
+ /*for AF_INET, if has only host type bit, just call linux api,
+ *if has libos and host type bits, it's a not connected fd, call
+ *linux api and return -1(errno == ENOTCONN) is also ok*/
+ if (CONN_TYPE_HAS_HOST(sock->conn)) {
+ return posix_api->getpeername_fn(s, name, namelen);
+ }
+#endif
+
return lwip_getaddrname(s, name, namelen, 0);
}
int
lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
{
+#if USE_LIBOS
+ struct lwip_sock *sock;
+
+ sock = posix_api->get_socket(s);
+ if (!sock) {
+ return posix_api->getsockname_fn(s, name, namelen);
+ }
+ /*for AF_INET, if has only host type bit, just call linux api,
+ *if has libos and host type bits, also call linux api*/
+ if (CONN_TYPE_HAS_HOST(sock->conn)) {
+ return posix_api->getsockname_fn(s, name, namelen);
+ }
+#endif
+
return lwip_getaddrname(s, name, namelen, 1);
}
@@ -2804,15 +3217,28 @@ int
lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
{
int err;
- struct lwip_sock *sock = get_socket(s);
#if !LWIP_TCPIP_CORE_LOCKING
err_t cberr;
LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
#endif /* !LWIP_TCPIP_CORE_LOCKING */
+#if USE_LIBOS
+ struct lwip_sock *sock = posix_api->get_socket(s);
+
+ if (!sock) {
+ return posix_api->getsockopt_fn(s, level, optname, optval, optlen);
+ }
+ /*for AF_INET, we return linux result? */
+ if (CONN_TYPE_HAS_HOST(sock->conn)) {
+ return posix_api->getsockopt_fn(s, level, optname, optval, optlen);
+ }
+#else
+ struct lwip_sock *sock = get_socket(s);
+
if (!sock) {
return -1;
}
+#endif /* USE_LIBOS */
if ((NULL == optval) || (NULL == optlen)) {
set_errno(EFAULT);
@@ -3250,15 +3676,30 @@ int
lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
{
int err = 0;
- struct lwip_sock *sock = get_socket(s);
#if !LWIP_TCPIP_CORE_LOCKING
err_t cberr;
LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
#endif /* !LWIP_TCPIP_CORE_LOCKING */
+#if USE_LIBOS
+ struct lwip_sock *sock = posix_api->get_socket(s);
+
+ if (!sock) {
+ return posix_api->setsockopt_fn(s, level, optname, optval, optlen);
+ }
+ /*for AF_INET, we may try both linux and lwip*/
+ if (CONN_TYPE_HAS_HOST(sock->conn)) {
+ if (posix_api->setsockopt_fn(s, level, optname, optval, optlen) < 0) {
+ return -1;
+ }
+ }
+#else
+ struct lwip_sock *sock = get_socket(s);
+
if (!sock) {
return -1;
}
+#endif /* USE_LIBOS */
if (NULL == optval) {
set_errno(EFAULT);
@@ -3372,6 +3813,7 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_
case SO_KEEPALIVE:
#if SO_REUSE
case SO_REUSEADDR:
+ case SO_REUSEPORT:
#endif /* SO_REUSE */
if ((optname == SO_BROADCAST) &&
(NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) {
@@ -3784,6 +4226,29 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_
return err;
}
+#if USE_LIBOS
+int
+lwip_ioctl(int s, long cmd, ...)
+{
+ struct lwip_sock *sock = posix_api->get_socket(s);
+ u8_t val;
+
+ int ret = -1;
+ void *argp;
+ va_list ap;
+
+ va_start(ap, cmd);
+ argp = va_arg(ap, void *);
+ va_end(ap);
+
+ if (!sock) {
+ return posix_api->ioctl_fn(s, cmd, argp);
+ }
+ if (CONN_TYPE_HAS_HOST(sock->conn)) {
+ if ((ret = posix_api->ioctl_fn(s, cmd, argp)) == -1)
+ return ret;
+ }
+#else
int
lwip_ioctl(int s, long cmd, void *argp)
{
@@ -3796,6 +4261,7 @@ lwip_ioctl(int s, long cmd, void *argp)
if (!sock) {
return -1;
}
+#endif /* USE_LIBOS */
switch (cmd) {
#if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE
@@ -3878,6 +4344,26 @@ lwip_ioctl(int s, long cmd, void *argp)
* the flag O_NONBLOCK is implemented for F_SETFL.
*/
int
+#if USE_LIBOS
+lwip_fcntl(int s, int cmd, ...)
+{
+ struct lwip_sock *sock = posix_api->get_socket(s);
+ int val, ret = -1;
+ int op_mode = 0;
+ va_list ap;
+
+ va_start(ap, cmd);
+ val = va_arg(ap, int);
+ va_end(ap);
+
+ if (!sock) {
+ return posix_api->fcntl_fn(s, cmd, val);
+ }
+ if (CONN_TYPE_HAS_HOST(sock->conn)) {
+ if ((ret = posix_api->fcntl_fn(s, cmd, val)) == -1)
+ return ret;
+ }
+#else /* USE_LIBOS */
lwip_fcntl(int s, int cmd, int val)
{
struct lwip_sock *sock = get_socket(s);
@@ -3887,6 +4373,7 @@ lwip_fcntl(int s, int cmd, int val)
if (!sock) {
return -1;
}
+#endif /* USE_LIBOS */
switch (cmd) {
case F_GETFL:
@@ -4202,4 +4689,50 @@ lwip_socket_drop_registered_mld6_memberships(int s)
}
#endif /* LWIP_IPV6_MLD */
+#if USE_LIBOS
+void lwip_sock_init(void)
+{
+ if (sockets_num == 0) {
+ sockets_num = NUM_SOCKETS;
+ sockets = calloc(sockets_num, sizeof(struct lwip_sock));
+ LWIP_ASSERT("sockets != NULL", sockets != NULL);
+ memset(sockets, 0, sockets_num * sizeof(struct lwip_sock));
+ }
+ return;
+}
+
+//modify from lwip_close
+void lwip_exit(void)
+{
+ int i, is_tcp;
+ struct lwip_sock *sock;
+
+ if (memp_pools[MEMP_SYS_MBOX] == NULL) {
+ return;
+ }
+
+ for (i = 0; i < sockets_num; i++) {
+ sock = &sockets[i];
+ if (!sock->conn)
+ continue;
+#if LWIP_IGMP
+ /* drop all possibly joined IGMP memberships */
+ lwip_socket_drop_registered_memberships(i);
+#endif /* LWIP_IGMP */
+ /*
+ * process is exiting, call netconn_delete to
+ * close tcp connection, and ignore the return value
+ */
+ is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP;
+ netconn_delete(sock->conn);
+ free_socket(sock, is_tcp);
+ }
+
+ free(sockets);
+ sockets = NULL;
+ sockets_num = 0;
+}
+
+#endif /* USE_LIBOS */
+
#endif /* LWIP_SOCKET */
diff --git a/src/api/sys_arch.c b/src/api/sys_arch.c
new file mode 100644
index 0000000..55561b1
--- /dev/null
+++ b/src/api/sys_arch.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#define _GNU_SOURCE
+#include <pthread.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <rte_memzone.h>
+#include <rte_ring.h>
+
+#include "lwip/err.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/opt.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+#include "arch/sys_arch.h"
+
+struct sys_mutex {
+ volatile unsigned int m;
+};
+
+struct sys_mutex lstack_mutex;
+
+struct sys_sem lstack_sem;
+
+#define MAX_THREAD_NAME 64
+#define MBOX_NAME_PREFIX "_mbox_0x"
+#define MAX_MBOX_NAME_LEN (sizeof(MBOX_NAME_PREFIX) + 32) // log(UINT64_MAX) < 32
+
+struct sys_thread {
+ struct sys_thread *next;
+ char name[MAX_THREAD_NAME];
+ lwip_thread_fn fn;
+ void *arg;
+ int stacksize;
+ int prio;
+ pthread_t tid;
+};
+
+
+struct sys_mem_stats {
+ uint32_t tot_len;
+};
+
+static PER_THREAD struct sys_mem_stats hugepage_stats;
+
+static PER_THREAD uint64_t cycles_per_ms __attribute__((aligned(64)));
+static PER_THREAD uint64_t sys_start_ms __attribute__((aligned(64)));
+
+/*
+ * Mailbox
+ * */
+static int mbox_wait_func(void)
+{
+#if LWIP_TIMERS
+ sys_timer_run();
+#endif /* LWIP_TIMER */
+ return eth_dev_poll();
+}
+
+err_t sys_mbox_new(struct sys_mbox **mb, int size)
+{
+ int ret;
+ struct sys_mbox *mbox;
+
+ mbox = (struct sys_mbox *)memp_malloc(MEMP_SYS_MBOX);
+ if (mbox == NULL) {
+ return ERR_MEM;
+ }
+
+ mbox->flags = RING_F_SP_ENQ | RING_F_SC_DEQ;
+
+ ret = snprintf(mbox->name, sizeof(mbox->name), MBOX_NAME_PREFIX"%"PRIXPTR, (uintptr_t)mbox);
+ if (ret < 0) {
+ memp_free(MEMP_SYS_MBOX, mbox);
+ return ERR_VAL;
+ }
+
+ mbox->size = size;
+ mbox->socket_id = rte_socket_id();
+ mbox->ring = rte_ring_create(mbox->name, mbox->size, mbox->socket_id, mbox->flags);
+ if (!mbox->ring) {
+ RTE_LOG(ERR, EAL, "cannot create rte_ring for mbox\n");
+ memp_free(MEMP_SYS_MBOX, mbox);
+ return ERR_MEM;
+ }
+ mbox->wait_fn = mbox_wait_func;
+ *mb = mbox;
+
+ return ERR_OK;
+}
+
+void sys_mbox_free(struct sys_mbox **mb)
+{
+ struct sys_mbox *mbox = *mb;
+ rte_ring_free(mbox->ring);
+ memp_free(MEMP_SYS_MBOX, mbox);
+}
+
+err_t sys_mbox_trypost(struct sys_mbox **mb, void *msg)
+{
+ unsigned int n;
+ struct sys_mbox *mbox = *mb;
+
+ n = rte_ring_sp_enqueue_bulk(mbox->ring, &msg, 1, NULL);
+ if (!n)
+ return ERR_BUF;
+ return ERR_OK;
+}
+
+void sys_mbox_post(struct sys_mbox **mb, void *msg)
+{
+ struct sys_mbox *mbox = *mb;
+
+ /* NOTE: sys_mbox_post is used on mbox defined in src/api/tcpip.c.
+ * If the ring size of mbox is greater than MEMP_NUM_TCPIP_MSG_API,
+ * enqueue failure will never happen.
+ * */
+ if (!rte_ring_sp_enqueue_bulk(mbox->ring, &msg, 1, NULL)) {
+ LWIP_ASSERT("It is failed to post msg into mbox", 0);
+ }
+}
+
+err_t sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
+{
+ return sys_mbox_trypost(q, msg);
+}
+
+uint32_t sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
+{
+ unsigned int n;
+ struct sys_mbox *mbox = *mb;
+
+ n = rte_ring_sc_dequeue_bulk(mbox->ring, msg, 1, NULL);
+ if (!n) {
+ *msg = NULL;
+ return SYS_MBOX_EMPTY;
+ }
+
+ return 0;
+}
+
+uint32_t sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, uint32_t timeout)
+{
+ unsigned int n;
+ uint32_t poll_ts = 0;
+ uint32_t time_needed = 0;
+ struct sys_mbox *mbox = *mb;
+
+ n = rte_ring_sc_dequeue_bulk(mbox->ring, msg, 1, NULL);
+
+ if (timeout > 0)
+ poll_ts = sys_now();
+
+ while (!n) {
+ if (timeout > 0) {
+ time_needed = sys_now() - poll_ts;
+ if (time_needed >= timeout) {
+ return SYS_ARCH_TIMEOUT;
+ }
+ }
+
+ (void)mbox->wait_fn();
+
+ n = rte_ring_sc_dequeue_bulk(mbox->ring, msg, 1, NULL);
+ }
+
+ return time_needed;
+}
+
+int sys_mbox_empty(struct sys_mbox *mb)
+{
+ return rte_ring_count(mb->ring) == 0;
+}
+
+/*
+ * Threads
+ * */
+sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
+{
+ int err;
+ pthread_t tid;
+ struct sys_thread *thread;
+
+ thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
+ if (thread == NULL) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: malloc sys_thread failed\n"));
+ rte_exit(EXIT_FAILURE, "malloc sys_thread failed\n");
+ }
+
+ err = pthread_create(&tid, NULL, (void*(*)(void *))function, arg);
+ if (err > 0) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create failed\n"));
+ rte_exit(EXIT_FAILURE, "pthread_create failed\n");
+ }
+
+ err = pthread_setname_np(tid, name);
+ if (err > 0) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_setname_np failed\n"));
+ }
+ thread->tid = tid;
+ thread->stacksize = stacksize;
+ thread->prio = prio;
+
+ return thread;
+}
+
+/*
+ * Semaphore
+ * */
+err_t sys_sem_new(struct sys_sem **sem, uint8_t count)
+{
+ *sem = (struct sys_sem *)memp_malloc(MEMP_SYS_SEM);
+ if ((*sem) == NULL) {
+ return ERR_MEM;
+ }
+ (*sem)->c = 0;
+ (*sem)->wait_fn = mbox_wait_func;
+ return ERR_OK;
+}
+
+void sys_sem_signal(struct sys_sem **s)
+{
+ struct sys_sem *sem = NULL;
+ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
+ sem = *s;
+ ++(sem->c);
+}
+
+static uint32_t cond_wait(struct sys_sem *sem, uint32_t timeout)
+{
+ uint32_t used_ms = 0;
+ uint32_t poll_ts;
+
+ if (timeout == 0) {
+ (void)sem->wait_fn();
+ return 0;
+ }
+
+ poll_ts = sys_now();
+
+ while (used_ms < timeout) {
+ if (sem->c > 0)
+ return timeout - used_ms;
+
+ (void)sem->wait_fn();
+ used_ms = sys_now() - poll_ts;
+ }
+
+ return SYS_ARCH_TIMEOUT;
+}
+
+uint32_t sys_arch_sem_wait(struct sys_sem **s, uint32_t timeout)
+{
+ uint32_t time_needed = 0;
+ struct sys_sem *sem = NULL;
+ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
+ sem = *s;
+
+ while (sem->c <= 0) {
+ if (timeout > 0) {
+ time_needed = cond_wait(sem, timeout);
+
+ if (time_needed == SYS_ARCH_TIMEOUT) {
+ return SYS_ARCH_TIMEOUT;
+ }
+ } else {
+ cond_wait(sem, 0);
+ }
+ }
+
+ sem->c--;
+ return time_needed;
+}
+
+void sys_sem_free(struct sys_sem **s)
+{
+ if ((s != NULL) && (*s != SYS_SEM_NULL))
+ memp_free(MEMP_SYS_SEM, *s);
+}
+
+/*
+ * Mutex
+ * */
+err_t sys_mutex_new(struct sys_mutex **mutex)
+{
+ return ERR_OK;
+}
+
+void sys_mutex_lock(struct sys_mutex **mutex)
+{
+}
+
+void sys_mutex_unlock(struct sys_mutex **mutex)
+{
+}
+
+void sys_mutex_free(struct sys_mutex **mutex)
+{
+}
+
+/* Timer from DPDK */
+void sys_calibrate_tsc(void)
+{
+#define MS_PER_SEC 1E3
+ uint64_t freq = rte_get_tsc_hz();
+
+ cycles_per_ms = (freq + MS_PER_SEC - 1) / MS_PER_SEC;
+ sys_start_ms = rte_rdtsc() / cycles_per_ms;
+}
+
+uint32_t sys_now(void)
+{
+ uint64_t cur_ms = rte_rdtsc() / cycles_per_ms;
+ return (uint32_t)(cur_ms - sys_start_ms);
+}
+
+/*
+ * Critical section
+ * */
+sys_prot_t sys_arch_protect(void)
+{
+ return 0;
+}
+
+void sys_arch_unprotect(sys_prot_t pval)
+{
+}
+
+/*
+ * Hugepage memory manager
+ * */
+uint8_t *sys_hugepage_malloc(const char *name, uint32_t size)
+{
+ const struct rte_memzone *mz;
+
+ mz = rte_memzone_reserve(name, size, rte_socket_id(), 0);
+ if (mz == NULL) {
+ rte_exit(EXIT_FAILURE, "failed to reserver memory for mempool[%s]\n", name);
+ return NULL;
+ }
+
+ memset(mz->addr, 0, mz->len);
+ hugepage_stats.tot_len += mz->len;
+
+ return (uint8_t*)mz->addr;
+}
diff --git a/src/api/tcpip.c b/src/api/tcpip.c
index 3aecbd4..05adfe0 100644
--- a/src/api/tcpip.c
+++ b/src/api/tcpip.c
@@ -56,13 +56,13 @@
#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
/* global variables */
-static tcpip_init_done_fn tcpip_init_done;
-static void *tcpip_init_done_arg;
-static sys_mbox_t tcpip_mbox;
+static PER_THREAD tcpip_init_done_fn tcpip_init_done;
+static PER_THREAD void *tcpip_init_done_arg;
+static PER_THREAD sys_mbox_t tcpip_mbox;
#if LWIP_TCPIP_CORE_LOCKING
/** The global semaphore to lock the stack. */
-sys_mutex_t lock_tcpip_core;
+PER_THREAD sys_mutex_t lock_tcpip_core;
#endif /* LWIP_TCPIP_CORE_LOCKING */
static void tcpip_thread_handle_msg(struct tcpip_msg *msg);
@@ -123,8 +123,13 @@ again:
*
* @param arg unused argument
*/
+#if USE_LIBOS
+__attribute__((unused)) static void
+tcpip_thread(void *arg)
+#else
static void
tcpip_thread(void *arg)
+#endif /* USE_LIBOS */
{
struct tcpip_msg *msg;
LWIP_UNUSED_ARG(arg);
@@ -247,6 +252,9 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
#if LWIP_TCPIP_CORE_LOCKING_INPUT
err_t ret;
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp));
+#if USE_LIBOS && LWIP_TIMERS
+ sys_timer_run();
+#endif
LOCK_TCPIP_CORE();
ret = input_fn(p, inp);
UNLOCK_TCPIP_CORE();
@@ -326,6 +334,9 @@ tcpip_callback(tcpip_callback_fn function, void *ctx)
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
+#if USE_LIBOS && LWIP_TIMER
+ sys_timer_run();
+#endif
sys_mbox_post(&tcpip_mbox, msg);
return ERR_OK;
}
@@ -362,6 +373,9 @@ tcpip_try_callback(tcpip_callback_fn function, void *ctx)
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
+#if USE_LIBOS && LWIP_TIMER
+ sys_timer_run();
+#endif
if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) {
memp_free(MEMP_TCPIP_MSG_API, msg);
return ERR_MEM;
@@ -443,6 +457,9 @@ tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
{
#if LWIP_TCPIP_CORE_LOCKING
LWIP_UNUSED_ARG(sem);
+#if USE_LIBOS && LWIP_TIMERS
+ sys_timer_run();
+#endif
LOCK_TCPIP_CORE();
fn(apimsg);
UNLOCK_TCPIP_CORE();
@@ -480,6 +497,9 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
#if LWIP_TCPIP_CORE_LOCKING
err_t err;
LOCK_TCPIP_CORE();
+#if USE_LIBOS && LWIP_TIMERS
+ sys_timer_run();
+#endif
err = fn(call);
UNLOCK_TCPIP_CORE();
return err;
@@ -542,6 +562,10 @@ tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
msg->type = TCPIP_MSG_CALLBACK_STATIC;
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
+
+#if USE_LIBOS && LWIP_TIMER
+ sys_timer_run();
+#endif
return (struct tcpip_callback_msg *)msg;
}
@@ -662,7 +686,9 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg)
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
+#if !USE_LIBOS
sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
+#endif
}
/**
diff --git a/src/core/dir.mk b/src/core/dir.mk
index e5a055b..ebc01a5 100644
--- a/src/core/dir.mk
+++ b/src/core/dir.mk
@@ -1,6 +1,6 @@
-SRC = inet_chksum.c init.c ip.c mem.c memp.c netif.c pbuf.c \
- raw.c stats.c tcp.c tcp_in.c tcp_out.c timeouts.c udp.c \
- ipv4/etharp.c ipv4/icmp.c ipv4/ip4_addr.c ipv4/ip4.c \
- ipv4/ip4_frag.c
+SRC = def.c inet_chksum.c init.c ip.c mem.c memp.c netif.c pbuf.c \
+ raw.c tcp.c tcp_in.c tcp_out.c timeouts.c udp.c stats.c\
+ ipv4/icmp.c ipv4/ip4_addr.c ipv4/ip4_frag.c ipv4/etharp.c \
+ ipv4/ip4.c
$(eval $(call register_dir, core, $(SRC)))
diff --git a/src/core/init.c b/src/core/init.c
index 0013a89..5b60ed8 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -349,9 +349,7 @@ lwip_init(void)
/* Modules initialization */
stats_init();
-#if !NO_SYS
- sys_init();
-#endif /* !NO_SYS */
+
mem_init();
memp_init();
pbuf_init();
diff --git a/src/core/ip.c b/src/core/ip.c
index 18514cf..0d39d2d 100644
--- a/src/core/ip.c
+++ b/src/core/ip.c
@@ -61,7 +61,7 @@
#include "lwip/ip.h"
/** Global data for both IPv4 and IPv6 */
-struct ip_globals ip_data;
+PER_THREAD struct ip_globals ip_data;
#if LWIP_IPV4 && LWIP_IPV6
diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c
index e044bff..ef7771f 100644
--- a/src/core/ipv4/ip4.c
+++ b/src/core/ipv4/ip4.c
@@ -282,7 +282,9 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
{
struct netif *netif;
+#ifndef LWIP_PERF
PERF_START;
+#endif
LWIP_UNUSED_ARG(inp);
if (!ip4_canforward(p)) {
@@ -378,7 +380,9 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
MIB2_STATS_INC(mib2.ipforwdatagrams);
IP_STATS_INC(ip.xmit);
+#ifndef LWIP_PERF
PERF_STOP("ip4_forward");
+#endif
/* don't fragment if interface has mtu set to 0 [loopif] */
if (netif->mtu && (p->tot_len > netif->mtu)) {
if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
@@ -472,6 +476,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
LWIP_ASSERT_CORE_LOCKED();
+ PERF_START(PERF_LAYER_IP, PERF_POINT_IP_RECV);
+
IP_STATS_INC(ip.recv);
MIB2_STATS_INC(mib2.ipinreceives);
@@ -734,13 +740,19 @@ ip4_input(struct pbuf *p, struct netif *inp)
case IP_PROTO_UDPLITE:
#endif /* LWIP_UDPLITE */
MIB2_STATS_INC(mib2.ipindelivers);
+ PERF_PAUSE(PERF_LAYER_IP);
udp_input(p, inp);
+ PERF_RESUME(PERF_LAYER_IP, PERF_POINT_IP_RECV);
break;
#endif /* LWIP_UDP */
#if LWIP_TCP
case IP_PROTO_TCP:
MIB2_STATS_INC(mib2.ipindelivers);
+ PERF_PAUSE(PERF_LAYER_IP);
+ PERF_START(PERF_LAYER_TCP, PERF_POINT_TCP_RECV);
tcp_input(p, inp);
+ PERF_STOP_INCREASE_COUNT("tcp_input", PERF_LAYER_TCP);
+ PERF_RESUME(PERF_LAYER_IP, PERF_POINT_IP_RECV);
break;
#endif /* LWIP_TCP */
#if LWIP_ICMP
@@ -789,6 +801,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
ip4_addr_set_any(ip4_current_src_addr());
ip4_addr_set_any(ip4_current_dest_addr());
+ PERF_STOP_INCREASE_COUNT("ip4_input", PERF_LAYER_IP);
+
return ERR_OK;
}
diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c
index 90e90dd..fad4f40 100644
--- a/src/core/ipv6/ip6.c
+++ b/src/core/ipv6/ip6.c
@@ -522,6 +522,8 @@ ip6_input(struct pbuf *p, struct netif *inp)
LWIP_ASSERT_CORE_LOCKED();
+ PERF_START(PERF_LAYER_IP, PERF_POINT_IP_RECV);
+
IP6_STATS_INC(ip6.recv);
/* identify the IP header */
@@ -1069,12 +1071,18 @@ options_done:
#if LWIP_UDPLITE
case IP6_NEXTH_UDPLITE:
#endif /* LWIP_UDPLITE */
+ PERF_PAUSE(PERF_LAYER_IP);
udp_input(p, inp);
+ PERF_RESUME(PERF_LAYER_IP, PERF_POINT_IP_RECV);
break;
#endif /* LWIP_UDP */
#if LWIP_TCP
case IP6_NEXTH_TCP:
+ PERF_PAUSE(PERF_LAYER_IP);
+ PERF_START(PERF_LAYER_TCP, PERF_POINT_TCP_RECV);
tcp_input(p, inp);
+ PERF_STOP_INCREASE_COUNT("tcp_input", PERF_LAYER_TCP);
+ PERF_RESUME(PERF_LAYER_IP, PERF_POINT_IP_RECV);
break;
#endif /* LWIP_TCP */
#if LWIP_ICMP6
@@ -1115,6 +1123,8 @@ ip6_input_cleanup:
ip6_addr_set_zero(ip6_current_src_addr());
ip6_addr_set_zero(ip6_current_dest_addr());
+ PERF_STOP_INCREASE_COUNT("ip6_input", PERF_LAYER_IP);
+
return ERR_OK;
}
diff --git a/src/core/mem.c b/src/core/mem.c
index 8566edc..3522825 100644
--- a/src/core/mem.c
+++ b/src/core/mem.c
@@ -381,9 +381,9 @@ LWIP_DECLARE_MEMORY_ALIGNED(ram_heap, MEM_SIZE_ALIGNED + (2U * SIZEOF_STRUCT_MEM
#endif /* LWIP_RAM_HEAP_POINTER */
/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */
-static u8_t *ram;
+static PER_THREAD u8_t *ram;
/** the last entry, always unused! */
-static struct mem *ram_end;
+static PER_THREAD struct mem *ram_end;
/** concurrent access protection */
#if !NO_SYS
@@ -418,7 +418,7 @@ static volatile u8_t mem_free_count;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
/** pointer to the lowest free block, this is used for faster search */
-static struct mem * LWIP_MEM_LFREE_VOLATILE lfree;
+static PER_THREAD struct mem * LWIP_MEM_LFREE_VOLATILE lfree;
#if MEM_SANITY_CHECK
static void mem_sanity(void);
diff --git a/src/core/memp.c b/src/core/memp.c
index 352ce5a..454ba32 100644
--- a/src/core/memp.c
+++ b/src/core/memp.c
@@ -78,10 +78,14 @@
#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)
#include "lwip/priv/memp_std.h"
+#if USE_LIBOS
+PER_THREAD struct memp_desc* memp_pools[MEMP_MAX] = {NULL};
+#else
const struct memp_desc *const memp_pools[MEMP_MAX] = {
#define LWIP_MEMPOOL(name,num,size,desc) &memp_ ## name,
#include "lwip/priv/memp_std.h"
};
+#endif /* USE_LIBOS */
#ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME
diff --git a/src/core/netif.c b/src/core/netif.c
index d3a0677..ded3561 100644
--- a/src/core/netif.c
+++ b/src/core/netif.c
@@ -110,12 +110,12 @@ static netif_ext_callback_t *ext_callback;
#endif
#if !LWIP_SINGLE_NETIF
-struct netif *netif_list;
+PER_THREAD struct netif *netif_list;
#endif /* !LWIP_SINGLE_NETIF */
-struct netif *netif_default;
+PER_THREAD struct netif *netif_default;
#define netif_index_to_num(index) ((index) - 1)
-static u8_t netif_num;
+static PER_THREAD u8_t netif_num;
#if LWIP_NUM_NETIF_CLIENT_DATA > 0
static u8_t netif_client_id;
@@ -141,7 +141,7 @@ static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const i
#endif
-static struct netif loop_netif;
+static PER_THREAD struct netif loop_netif;
#if LWIP_TESTMODE
struct netif* netif_get_loopif(void)
diff --git a/src/core/pbuf.c b/src/core/pbuf.c
index 1fb64d4..201ddf3 100644
--- a/src/core/pbuf.c
+++ b/src/core/pbuf.c
@@ -739,7 +739,9 @@ pbuf_free(struct pbuf *p)
}
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p));
+#ifndef LWIP_PERF
PERF_START;
+#endif
count = 0;
/* de-allocate all consecutive pbufs from the head of the chain that
@@ -796,7 +798,9 @@ pbuf_free(struct pbuf *p)
p = NULL;
}
}
+#ifndef LWIP_PERF
PERF_STOP("pbuf_free");
+#endif
/* return number of de-allocated pbufs */
return count;
}
diff --git a/src/core/stats.c b/src/core/stats.c
index 95445ec..ce6a929 100644
--- a/src/core/stats.c
+++ b/src/core/stats.c
@@ -47,7 +47,7 @@
#include <string.h>
-struct stats_ lwip_stats;
+PER_THREAD struct stats_ lwip_stats;
void
stats_init(void)
@@ -59,6 +59,17 @@ stats_init(void)
#endif /* LWIP_DEBUG */
}
+int get_mib2_stats(char *buf)
+{
+ int len = 0;
+#if MIB2_STATS
+ len = (long)&((struct stats_mib2 *)0)->udpindatagrams;
+ /* we just need the ip&tcp, others not needed. */
+ memcpy(buf, &lwip_stats.mib2, len);
+#endif
+ return len;
+}
+
#if LWIP_STATS_DISPLAY
void
stats_display_proto(struct stats_proto *proto, const char *name)
diff --git a/src/core/tcp.c b/src/core/tcp.c
index ea95ffe..24d035c 100644
--- a/src/core/tcp.c
+++ b/src/core/tcp.c
@@ -113,6 +113,7 @@
#include "lwip/nd6.h"
#include <string.h>
+#include <pthread.h>
#ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME
@@ -157,36 +158,50 @@ static const char *const tcp_state_str[] = {
/* last local TCP port */
static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START;
+static pthread_mutex_t g_tcp_port_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Incremented every coarse grained timer shot (typically every 500 ms). */
-u32_t tcp_ticks;
-static const u8_t tcp_backoff[13] =
+PER_THREAD u32_t tcp_ticks;
+static PER_THREAD const u8_t tcp_backoff[13] =
{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
/* Times per slowtmr hits */
-static const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
+static PER_THREAD const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
/* The TCP PCB lists. */
/** List of all TCP PCBs bound but not yet (connected || listening) */
-struct tcp_pcb *tcp_bound_pcbs;
+PER_THREAD struct tcp_pcb *tcp_bound_pcbs;
/** List of all TCP PCBs in LISTEN state */
-union tcp_listen_pcbs_t tcp_listen_pcbs;
+PER_THREAD union tcp_listen_pcbs_t tcp_listen_pcbs;
/** List of all TCP PCBs that are in a state in which
* they accept or send data. */
-struct tcp_pcb *tcp_active_pcbs;
+PER_THREAD struct tcp_pcb *tcp_active_pcbs;
/** List of all TCP PCBs in TIME-WAIT state */
-struct tcp_pcb *tcp_tw_pcbs;
+PER_THREAD struct tcp_pcb *tcp_tw_pcbs;
/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */
-struct tcp_pcb **const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
- &tcp_active_pcbs, &tcp_tw_pcbs
-};
+PER_THREAD struct tcp_pcb ** tcp_pcb_lists[NUM_TCP_PCB_LISTS] = {NULL, NULL, NULL, NULL};
+
+#if TCP_PCB_HASH
+#define INIT_TCP_HTABLE(ht_ptr) \
+ do { \
+ int _i; \
+ (ht_ptr)->size = TCP_HTABLE_SIZE; \
+ for (_i = 0; _i < TCP_HTABLE_SIZE; ++_i) { \
+ if (sys_mutex_new(&(ht_ptr)->array[_i].mutex) != ERR_OK) \
+ LWIP_ASSERT("failed to create ht->array[].mutex", 0);\
+ INIT_HLIST_HEAD(&(ht_ptr)->array[_i].chain); \
+ }\
+ } while (0)
+
+PER_THREAD struct tcp_hash_table *tcp_active_htable; /* key: lport/fport/lip/fip */
+#endif
-u8_t tcp_active_pcbs_changed;
+PER_THREAD u8_t tcp_active_pcbs_changed;
/** Timer counter to handle calling slow-timer from tcp_tmr() */
-static u8_t tcp_timer;
-static u8_t tcp_timer_ctr;
+static PER_THREAD u8_t tcp_timer;
+static PER_THREAD u8_t tcp_timer_ctr;
static u16_t tcp_new_port(void);
static err_t tcp_close_shutdown_fin(struct tcp_pcb *pcb);
@@ -200,9 +215,20 @@ static void tcp_ext_arg_invoke_callbacks_destroyed(struct tcp_pcb_ext_args *ext_
void
tcp_init(void)
{
+ tcp_pcb_lists[0] = &tcp_listen_pcbs.pcbs;
+ tcp_pcb_lists[1] = &tcp_bound_pcbs;
+ tcp_pcb_lists[2] = &tcp_active_pcbs;
+ tcp_pcb_lists[3] = &tcp_tw_pcbs;
+
#ifdef LWIP_RAND
tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
#endif /* LWIP_RAND */
+
+#if TCP_PCB_HASH
+ tcp_active_htable = (struct tcp_hash_table*)mem_malloc(sizeof(struct tcp_hash_table));
+ LWIP_ASSERT("malloc tcp_active_htable mem failed.", tcp_active_htable != NULL);
+ INIT_TCP_HTABLE(tcp_active_htable);
+#endif
}
/** Free a tcp pcb */
@@ -361,6 +387,9 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
pcb->local_port, pcb->remote_port);
tcp_pcb_purge(pcb);
+#if TCP_PCB_HASH
+ TCP_RMV_ACTIVE_HASH(pcb);
+#endif
TCP_RMV_ACTIVE(pcb);
/* Deallocate the pcb since we already sent a RST for it */
if (tcp_input_pcb == pcb) {
@@ -395,6 +424,9 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
tcp_free_listen(pcb);
break;
case SYN_SENT:
+#if TCP_PCB_HASH
+ TCP_PCB_REMOVE_ACTIVE_HASH(pcb);
+#endif
TCP_PCB_REMOVE_ACTIVE(pcb);
tcp_free(pcb);
MIB2_STATS_INC(mib2.tcpattemptfails);
@@ -494,6 +526,7 @@ tcp_close(struct tcp_pcb *pcb)
/* Set a flag not to receive any more data... */
tcp_set_flags(pcb, TF_RXCLOSED);
}
+
/* ... and close */
return tcp_close_shutdown(pcb, 1);
}
@@ -599,6 +632,9 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
} else {
send_rst = reset;
local_port = pcb->local_port;
+#if TCP_PCB_HASH
+ TCP_PCB_REMOVE_ACTIVE_HASH(pcb);
+#endif
TCP_PCB_REMOVE_ACTIVE(pcb);
}
if (pcb->unacked != NULL) {
@@ -880,6 +916,11 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err)
}
}
#endif /* SO_REUSE */
+
+#if USE_LIBOS
+ vdev_reg_done(REG_RING_TCP_LISTEN, pcb);
+#endif
+
lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
if (lpcb == NULL) {
res = ERR_MEM;
@@ -1018,6 +1059,7 @@ tcp_new_port(void)
u16_t n = 0;
struct tcp_pcb *pcb;
+ pthread_mutex_lock(&g_tcp_port_mutex);
again:
tcp_port++;
if (tcp_port == TCP_LOCAL_PORT_RANGE_END) {
@@ -1035,6 +1077,8 @@ again:
}
}
}
+ pthread_mutex_unlock(&g_tcp_port_mutex);
+
return tcp_port;
}
@@ -1145,6 +1189,10 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
#endif /* SO_REUSE */
}
+#if USE_LIBOS
+ vdev_reg_done(REG_RING_TCP_CONNECT, pcb);
+#endif
+
iss = tcp_next_iss(pcb);
pcb->rcv_nxt = 0;
pcb->snd_nxt = iss;
@@ -1177,6 +1225,9 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
if (old_local_port != 0) {
TCP_RMV(&tcp_bound_pcbs, pcb);
}
+#if TCP_PCB_HASH
+ TCP_REG_ACTIVE_HASH(pcb);
+#endif
TCP_REG_ACTIVE(pcb);
MIB2_STATS_INC(mib2.tcpactiveopens);
@@ -1392,11 +1443,26 @@ tcp_slowtmr_start:
if (prev != NULL) {
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
prev->next = pcb->next;
+#if USE_LIBOS
+ if (pcb->next)
+ pcb->next->prev = prev;
+ //dont set next NULL, it will be used below
+ pcb->prev = NULL;
+#endif
} else {
/* This PCB was the first. */
LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
tcp_active_pcbs = pcb->next;
+#if USE_LIBOS
+ if (pcb->next)
+ pcb->next->prev = NULL;
+ //dont set next NULL, it will be used below
+ pcb->prev = NULL;
+#endif
}
+#if TCP_PCB_HASH
+ TCP_RMV_ACTIVE_HASH(pcb);
+#endif
if (pcb_reset) {
tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
@@ -1407,6 +1473,9 @@ tcp_slowtmr_start:
last_state = pcb->state;
pcb2 = pcb;
pcb = pcb->next;
+#if USE_LIBOS
+ pcb2->next = NULL;
+#endif
tcp_free(pcb2);
tcp_active_pcbs_changed = 0;
@@ -1458,13 +1527,28 @@ tcp_slowtmr_start:
if (prev != NULL) {
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
prev->next = pcb->next;
+#if USE_LIBOS
+ if (pcb->next)
+ pcb->next->prev = prev;
+ //dont set next NULL, it will be used below
+ pcb->prev = NULL;
+#endif
} else {
/* This PCB was the first. */
LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
tcp_tw_pcbs = pcb->next;
+#if USE_LIBOS
+ if (pcb->next)
+ pcb->next->prev = NULL;
+ //dont set next NULL, it will be used below
+ pcb->prev = NULL;
+#endif
}
pcb2 = pcb;
pcb = pcb->next;
+#if USE_LIBOS
+ pcb2->next = NULL;
+#endif
tcp_free(pcb2);
} else {
prev = pcb;
@@ -2216,6 +2300,14 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
}
+#if TCP_PCB_HASH
+void
+tcp_pcb_remove_hash(struct tcp_hash_table *htb, struct tcp_pcb *pcb)
+{
+ TCP_RMV_HASH(htb, pcb);
+}
+#endif /* TCP_PCB_HASH */
+
/**
* Calculates a new initial sequence number for new connections.
*
@@ -2390,6 +2482,84 @@ tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t
return ERR_VAL;
}
+uint32_t tcp_get_conn_num(void)
+{
+ struct tcp_pcb *pcb = NULL;
+ struct tcp_pcb_listen *pcbl = NULL;
+ uint32_t conn_num = 0;
+
+ for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+ conn_num++;
+ }
+
+ for (pcbl = tcp_listen_pcbs.listen_pcbs; pcbl != NULL; pcbl = pcbl->next) {
+ conn_num++;
+ }
+
+ for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+ conn_num++;
+ }
+
+ return conn_num;
+}
+
+void tcp_get_conn(char *buf, int32_t len, uint32_t *conn_num)
+{
+ int tmp_len = 0;
+ char *tmp_buf = buf;
+ struct tcp_pcb_dp tdp;
+ struct tcp_pcb *pcb = NULL;
+ struct tcp_pcb_listen *pcbl = NULL;
+
+#define COPY_TDP(b, l) \
+ do { \
+ if (l + sizeof(tdp) <= len) { \
+ memcpy(b, &tdp, sizeof(tdp)); \
+ b += sizeof(tdp); \
+ l += sizeof(tdp); \
+ *conn_num += 1; \
+ } else \
+ return; \
+ } while(0);
+
+ *conn_num = 0;
+
+ for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+ tdp.state = ACTIVE_LIST;
+ tdp.lip = pcb->local_ip.addr;
+ tdp.rip = pcb->remote_ip.addr;
+ tdp.l_port = pcb->local_port;
+ tdp.r_port = pcb->remote_port;
+ tdp.s_next = pcb->snd_queuelen;
+ /* lwip not cache rcv buf. Set it to 0. */
+ tdp.r_next = 0;
+ tdp.tcp_sub_state = pcb->state;
+ COPY_TDP(tmp_buf, tmp_len);
+ }
+
+ for (pcbl = tcp_listen_pcbs.listen_pcbs; pcbl != NULL; pcbl = pcbl->next) {
+ tdp.state = LISTEN_LIST;
+ tdp.lip = pcbl->local_ip.addr;
+ tdp.rip = pcbl->remote_ip.addr;
+ tdp.l_port = pcbl->local_port;
+ tdp.tcp_sub_state = pcbl->state;
+ COPY_TDP(tmp_buf, tmp_len);
+ }
+
+ for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+ tdp.state = TIME_WAIT_LIST;
+ tdp.lip = pcb->local_ip.addr;
+ tdp.rip = pcb->remote_ip.addr;
+ tdp.l_port = pcb->local_port;
+ tdp.r_port = pcb->remote_port;
+ tdp.s_next = pcb->snd_queuelen;
+ /* lwip not cache rcv buf. Set it to 0. */
+ tdp.r_next = 0;
+ tdp.tcp_sub_state = pcb->state;
+ COPY_TDP(tmp_buf, tmp_len);
+ }
+}
+
#if TCP_QUEUE_OOSEQ
/* Free all ooseq pbufs (and possibly reset SACK state) */
void
diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c
index c7a1f7b..48ee11d 100644
--- a/src/core/tcp_in.c
+++ b/src/core/tcp_in.c
@@ -71,21 +71,22 @@
/* These variables are global to all functions involved in the input
processing of TCP segments. They are set by the tcp_input()
function. */
-static struct tcp_seg inseg;
-static struct tcp_hdr *tcphdr;
-static u16_t tcphdr_optlen;
-static u16_t tcphdr_opt1len;
-static u8_t *tcphdr_opt2;
-static u16_t tcp_optidx;
-static u32_t seqno, ackno;
-static tcpwnd_size_t recv_acked;
-static u16_t tcplen;
-static u8_t flags;
-
-static u8_t recv_flags;
-static struct pbuf *recv_data;
-
-struct tcp_pcb *tcp_input_pcb;
+static PER_THREAD struct tcp_seg inseg;
+static PER_THREAD struct tcp_hdr *tcphdr;
+static PER_THREAD u16_t tcphdr_optlen;
+static PER_THREAD u16_t tcphdr_opt1len;
+static PER_THREAD u8_t *tcphdr_opt2;
+static PER_THREAD u16_t tcp_optidx;
+static PER_THREAD u32_t seqno;
+static PER_THREAD u32_t ackno;
+static PER_THREAD tcpwnd_size_t recv_acked;
+static PER_THREAD u16_t tcplen;
+static PER_THREAD u8_t flags;
+
+static PER_THREAD u8_t recv_flags;
+static PER_THREAD struct pbuf *recv_data;
+
+PER_THREAD struct tcp_pcb *tcp_input_pcb;
/* Forward declarations. */
static err_t tcp_process(struct tcp_pcb *pcb);
@@ -126,11 +127,20 @@ tcp_input(struct pbuf *p, struct netif *inp)
u8_t hdrlen_bytes;
err_t err;
+#if TCP_PCB_HASH
+ u32_t idx;
+ struct hlist_head *head;
+ struct hlist_node *node;
+ pcb = NULL;
+#endif
+
LWIP_UNUSED_ARG(inp);
LWIP_ASSERT_CORE_LOCKED();
LWIP_ASSERT("tcp_input: invalid pbuf", p != NULL);
+#ifndef LWIP_PERF
PERF_START;
+#endif
TCP_STATS_INC(tcp.recv);
MIB2_STATS_INC(mib2.tcpinsegs);
@@ -247,7 +257,15 @@ tcp_input(struct pbuf *p, struct netif *inp)
for an active connection. */
prev = NULL;
+#if TCP_PCB_HASH
+ idx = TUPLE4_HASH_FN( ip_current_dest_addr()->addr, tcphdr->dest,
+ ip_current_src_addr()->addr, tcphdr->src) &
+ (tcp_active_htable->size - 1);
+ head = &tcp_active_htable->array[idx].chain;
+ tcppcb_hlist_for_each(pcb, node, head) {
+#else
for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+#endif
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
@@ -263,6 +281,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
pcb->local_port == tcphdr->dest &&
ip_addr_eq(&pcb->remote_ip, ip_current_src_addr()) &&
ip_addr_eq(&pcb->local_ip, ip_current_dest_addr())) {
+#if !TCP_PCB_HASH
/* Move this PCB to the front of the list so that subsequent
lookups will be faster (we exploit locality in TCP segment
arrivals). */
@@ -275,9 +294,14 @@ tcp_input(struct pbuf *p, struct netif *inp)
TCP_STATS_INC(tcp.cachehit);
}
LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
+#endif
break;
}
+#if TCP_PCB_HASH
+ pcb = NULL;
+#else
prev = pcb;
+#endif
}
if (pcb == NULL) {
@@ -363,8 +387,15 @@ tcp_input(struct pbuf *p, struct netif *inp)
arrivals). */
if (prev != NULL) {
((struct tcp_pcb_listen *)prev)->next = lpcb->next;
+#if USE_LIBOS
+ if (lpcb->next)
+ lpcb->next->prev = (struct tcp_pcb_listen *)prev;
+#endif
/* our successor is the remainder of the listening list */
lpcb->next = tcp_listen_pcbs.listen_pcbs;
+#if USE_LIBOS
+ lpcb->prev = NULL;
+#endif
/* put this listening pcb at the head of the listening list */
tcp_listen_pcbs.listen_pcbs = lpcb;
} else {
@@ -445,6 +476,9 @@ tcp_input(struct pbuf *p, struct netif *inp)
application that the connection is dead before we
deallocate the PCB. */
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST);
+#if TCP_PCB_HASH
+ tcp_pcb_remove_hash(tcp_active_htable, pcb);
+#endif
tcp_pcb_remove(&tcp_active_pcbs, pcb);
tcp_free(pcb);
} else {
@@ -550,7 +584,19 @@ tcp_input(struct pbuf *p, struct netif *inp)
goto aborted;
}
/* Try to send something out. */
+#if LWIP_RECORD_PERF
+ if (check_layer_point(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_ACK_RECV)) {
+ PERF_PAUSE(PERF_LAYER_TCP);
+ PERF_START(PERF_LAYER_TCP, PERF_POINT_TCP_ACK_SEND);
+ }
+#endif
tcp_output(pcb);
+#if LWIP_RECORD_PERF
+ if (check_layer_point(PERF_LAYER_TCP, PERF_POINT_TCP_ACK_SEND)) {
+ PERF_STOP_INCREASE_COUNT("tcp_in", PERF_LAYER_TCP);
+ PERF_RESUME(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_ACK_RECV);
+ }
+#endif
#if TCP_INPUT_DEBUG
#if TCP_DEBUG
tcp_debug_print_state(pcb->state);
@@ -583,7 +629,9 @@ aborted:
}
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
+#ifndef LWIP_PERF
PERF_STOP("tcp_input");
+#endif
return;
dropped:
TCP_STATS_INC(tcp.drop);
@@ -610,6 +658,9 @@ tcp_input_delayed_close(struct tcp_pcb *pcb)
ensure the application doesn't continue using the PCB. */
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
}
+#if TCP_PCB_HASH
+ tcp_pcb_remove_hash(tcp_active_htable, pcb);
+#endif
tcp_pcb_remove(&tcp_active_pcbs, pcb);
tcp_free(pcb);
return 1;
@@ -649,6 +700,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
tcp_rst_netif(ip_data.current_input_netif, ackno, seqno + tcplen, ip_current_dest_addr(),
ip_current_src_addr(), tcphdr->dest, tcphdr->src);
} else if (flags & TCP_SYN) {
+ PERF_UPDATE_POINT(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_RECV);
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
#if TCP_LISTEN_BACKLOG
if (pcb->accepts_pending >= pcb->backlog) {
@@ -698,6 +750,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
npcb->netif_idx = pcb->netif_idx;
/* Register the new PCB so that we can begin receiving segments
for it. */
+#if TCP_PCB_HASH
+ TCP_REG_ACTIVE_HASH(npcb);
+#endif
TCP_REG_ACTIVE(npcb);
/* Parse any options in the SYN. */
@@ -718,13 +773,18 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
}
#endif
+ PERF_PAUSE(PERF_LAYER_TCP);
+ PERF_START(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_ACK_SEND);
/* Send a SYN|ACK together with the MSS option. */
rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
if (rc != ERR_OK) {
tcp_abandon(npcb, 0);
+ PERF_RESUME(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_RECV);
return;
}
tcp_output(npcb);
+ PERF_STOP_INCREASE_COUNT("tcp_output", PERF_LAYER_TCP);
+ PERF_RESUME(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_RECV);
}
return;
}
@@ -868,6 +928,7 @@ tcp_process(struct tcp_pcb *pcb)
/* received SYN ACK with expected sequence number? */
if ((flags & TCP_ACK) && (flags & TCP_SYN)
&& (ackno == pcb->lastack + 1)) {
+ PERF_UPDATE_POINT(PERF_LAYER_TCP, PERF_POINT_TCP_SYN_ACK_RECV);
pcb->rcv_nxt = seqno + 1;
pcb->rcv_ann_right_edge = pcb->rcv_nxt;
pcb->lastack = ackno;
@@ -940,6 +1001,7 @@ tcp_process(struct tcp_pcb *pcb)
/* expected ACK number? */
if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
pcb->state = ESTABLISHED;
+ PERF_UPDATE_POINT(PERF_LAYER_TCP, PERF_POINT_TCP_ACK_RECV);
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
if (pcb->listener == NULL) {
@@ -1007,6 +1069,9 @@ tcp_process(struct tcp_pcb *pcb)
("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_ack_now(pcb);
tcp_pcb_purge(pcb);
+#if TCP_PCB_HASH
+ TCP_RMV_ACTIVE_HASH(pcb);
+#endif
TCP_RMV_ACTIVE(pcb);
pcb->state = TIME_WAIT;
TCP_REG(&tcp_tw_pcbs, pcb);
@@ -1025,6 +1090,9 @@ tcp_process(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_ack_now(pcb);
tcp_pcb_purge(pcb);
+#if TCP_PCB_HASH
+ TCP_RMV_ACTIVE_HASH(pcb);
+#endif
TCP_RMV_ACTIVE(pcb);
pcb->state = TIME_WAIT;
TCP_REG(&tcp_tw_pcbs, pcb);
@@ -1035,6 +1103,9 @@ tcp_process(struct tcp_pcb *pcb)
if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_pcb_purge(pcb);
+#if TCP_PCB_HASH
+ TCP_RMV_ACTIVE_HASH(pcb);
+#endif
TCP_RMV_ACTIVE(pcb);
pcb->state = TIME_WAIT;
TCP_REG(&tcp_tw_pcbs, pcb);
diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c
index 64579ee..74b22b0 100644
--- a/src/core/tcp_out.c
+++ b/src/core/tcp_out.c
@@ -274,7 +274,7 @@ tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
return p;
}
#else /* TCP_OVERSIZE */
-#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
+#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_POOL)
#endif /* TCP_OVERSIZE */
#if TCP_CHECKSUM_ON_COPY
@@ -643,7 +643,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
((struct pbuf_rom *)p2)->payload = (const u8_t *)arg + pos;
/* Second, allocate a pbuf for the headers. */
- if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
+ if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_POOL)) == NULL) {
/* If allocation fails, we have to deallocate the data pbuf as
* well. */
pbuf_free(p2);
@@ -1461,6 +1461,11 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
err_t err;
u16_t len;
u32_t *opts;
+
+#if LWIP_RECORD_PERF
+ int tmpPoint;
+#endif
+
#if TCP_CHECKSUM_ON_COPY
int seg_chksum_was_swapped = 0;
#endif
@@ -1607,6 +1612,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
#endif /* CHECKSUM_GEN_TCP */
TCP_STATS_INC(tcp.xmit);
+ PERF_PAUSE_RETURN_POINT(PERF_LAYER_TCP, tmpPoint);
+ PERF_START(PERF_LAYER_IP, PERF_POINT_IP_SEND);
+
NETIF_SET_HINTS(netif, &(pcb->netif_hints));
err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
pcb->tos, IP_PROTO_TCP, netif);
@@ -1621,6 +1629,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
}
#endif
+ PERF_STOP_INCREASE_COUNT("ip_out", PERF_LAYER_IP);
+ PERF_RESUME(PERF_LAYER_TCP, tmpPoint);
+
return err;
}
@@ -2090,6 +2101,10 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
u8_t optlen, optflags = 0;
u8_t num_sacks = 0;
+#if LWIP_RECORD_PERF
+ int tmpPoint;
+#endif
+
LWIP_ASSERT("tcp_send_empty_ack: invalid pcb", pcb != NULL);
#if LWIP_TCP_TIMESTAMPS
@@ -2106,6 +2121,9 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
}
#endif
+ PERF_PAUSE_RETURN_POINT(PERF_LAYER_TCP, tmpPoint);
+ PERF_START(PERF_LAYER_IP, PERF_POINT_IP_SEND);
+
p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt));
if (p == NULL) {
/* let tcp_fasttmr retry sending this ACK */
@@ -2130,6 +2148,9 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
}
+ PERF_STOP_INCREASE_COUNT("ip_out", PERF_LAYER_IP);
+ PERF_RESUME(PERF_LAYER_TCP, tmpPoint);
+
return err;
}
diff --git a/src/core/timeouts.c b/src/core/timeouts.c
index 91657eb..477369f 100644
--- a/src/core/timeouts.c
+++ b/src/core/timeouts.c
@@ -119,9 +119,9 @@ const int lwip_num_cyclic_timers = LWIP_ARRAYSIZE(lwip_cyclic_timers);
#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM
/** The one and only timeout list */
-static struct sys_timeo *next_timeout;
+static PER_THREAD struct sys_timeo *next_timeout;
-static u32_t current_timeout_due_time;
+static PER_THREAD u32_t current_timeout_due_time;
#if LWIP_TESTMODE
struct sys_timeo**
@@ -133,7 +133,7 @@ sys_timeouts_get_next_timeout(void)
#if LWIP_TCP
/** global variable that shows if the tcp timer is currently scheduled or not */
-static int tcpip_tcp_timer_active;
+static PER_THREAD int tcpip_tcp_timer_active;
/**
* Timer callback function that calls tcp_tmr() and reschedules itself.
@@ -442,6 +442,18 @@ sys_timeouts_sleeptime(void)
}
}
+#if USE_LIBOS
+void sys_timer_run(void)
+{
+ u32_t sleeptime;
+
+ sleeptime = sys_timeouts_sleeptime();
+ if (sleeptime == 0) {
+ sys_check_timeouts();
+ }
+}
+#endif /* USE_LIBOS */
+
#else /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */
/* Satisfy the TCP code which calls this function */
void
diff --git a/src/core/udp.c b/src/core/udp.c
index 23c2be2..24fc174 100644
--- a/src/core/udp.c
+++ b/src/core/udp.c
@@ -207,7 +207,11 @@ udp_input(struct pbuf *p, struct netif *inp)
LWIP_ASSERT("udp_input: invalid pbuf", p != NULL);
LWIP_ASSERT("udp_input: invalid netif", inp != NULL);
+#if LWIP_RECORD_PERF
+ PERF_START(PERF_LAYER_UDP, PERF_POINT_UDP);
+#else
PERF_START;
+#endif
UDP_STATS_INC(udp.recv);
@@ -428,7 +432,12 @@ udp_input(struct pbuf *p, struct netif *inp)
pbuf_free(p);
}
end:
+#if LWIP_RECORD_PERF
+ PERF_STOP_INCREASE_COUNT("udp_input", PERF_LAYER_UDP);
+#else
PERF_STOP("udp_input");
+#endif
+
return;
#if CHECKSUM_CHECK_UDP
chkerr:
@@ -438,7 +447,13 @@ chkerr:
UDP_STATS_INC(udp.drop);
MIB2_STATS_INC(mib2.udpinerrors);
pbuf_free(p);
+
+#if LWIP_RECORD_PERF
+ PERF_STOP_INCREASE_COUNT("udp_input", PERF_LAYER_UDP);
+#else
PERF_STOP("udp_input");
+#endif
+
#endif /* CHECKSUM_CHECK_UDP */
}
diff --git a/src/include/arch/cc.h b/src/include/arch/cc.h
index 52b76f9..33c24b4 100644
--- a/src/include/arch/cc.h
+++ b/src/include/arch/cc.h
@@ -1,7 +1,81 @@
-#ifndef LWIP_CC_H
-#define LWIP_CC_H
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+#ifndef LWIP_ARCH_CC_H
+#define LWIP_ARCH_CC_H
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
-#endif /* LWIP_CC_H */
+#include "lwiplog.h"
+#define LWIP_NOASSERT
+
+#define LWIP_ERRNO_STDINCLUDE 1
+#define MEMP_MEMORY_BASE_PLACEHOLDER 0
+#define MEMZONE_NAMESIZE 32
+
+#define LWIP_RAND() ((uint32_t)rand())
+
+extern uint8_t *sys_hugepage_malloc(const char *name, uint32_t size);
+
+#define LWIP_DECLARE_MEMP_BASE_ALIGNED(name, __size)\
+PER_THREAD uint8_t *memp_memory_##name##_base; \
+void alloc_memp_##name##_base(void) \
+{ \
+ memp_ ## name.desc = memp_desc_ ## name; \
+ memp_ ## name.stats = &memp_stat ## name; \
+ memp_ ## name.size = memp_size ## name; \
+ memp_ ## name.num = memp_num ## name; \
+ memp_ ## name.tab = &memp_tab_ ## name; \
+ memp_pools[MEMP_##name] = &memp_ ## name; \
+ \
+ char mpname[MEMZONE_NAMESIZE] = {0}; \
+ snprintf(mpname, MEMZONE_NAMESIZE, "%ld_%s", gettid(), #name); \
+ memp_memory_##name##_base = \
+ sys_hugepage_malloc(mpname, LWIP_MEM_ALIGN_BUFFER(__size)); \
+ memp_pools[MEMP_##name]->base = memp_memory_##name##_base; \
+}
+
+#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) \
+PER_THREAD uint8_t *variable_name; \
+void alloc_memory_##variable_name(void) \
+{ \
+ char mpname[MEMZONE_NAMESIZE] = {0}; \
+ snprintf(mpname, MEMZONE_NAMESIZE, "%ld_%s", gettid(), #variable_name); \
+ (variable_name) = \
+ sys_hugepage_malloc(mpname, LWIP_MEM_ALIGN_BUFFER(size)); \
+}
+
+#endif /* LWIP_ARCH_CC_H */
diff --git a/src/include/arch/perf.h b/src/include/arch/perf.h
new file mode 100644
index 0000000..e505da7
--- /dev/null
+++ b/src/include/arch/perf.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef LWIP_ARCH_PERF_H
+#define LWIP_ARCH_PERF_H
+
+#include <time.h>
+
+#include "lwip/debug.h"
+
+#if LWIP_RECORD_PERF
+enum PERF_POINT {
+ PERF_POINT_IP_RECV,
+ PERF_POINT_TCP_RECV,
+ PERF_POINT_UDP,
+ PERF_POINT_TCP_SYN_RECV,
+ PERF_POINT_TCP_SYN_ACK_SEND,
+ PERF_POINT_TCP_ACK_RECV,
+ PERF_POINT_TCP_SYN_SEND,
+ PERF_POINT_TCP_SYN_ACK_RECV,
+ PERF_POINT_TCP_ACK_SEND,
+ PERF_POINT_TCP_DATA_SEND,
+ PERF_POINT_IP_SEND,
+ PERF_POINT_END
+};
+
+enum PERF_LAYER {
+ PERF_LAYER_IP,
+ PERF_LAYER_TCP,
+ PERF_LAYER_UDP,
+ PERF_LAYER_END
+};
+
+extern uint32_t g_record_perf;
+
+extern __thread uint64_t g_timeTaken[PERF_POINT_END];
+extern __thread int g_perfPoint[PERF_LAYER_END];
+extern __thread struct timespec tvStart[PERF_LAYER_END];
+
+extern char *g_ppLayerName[PERF_POINT_END];
+extern volatile uint64_t g_perfMaxtime[PERF_POINT_END];
+extern volatile uint64_t g_astPacketCnt[PERF_POINT_END];
+extern volatile uint64_t g_astPacketProcTime[PERF_POINT_END];
+
+#define PERF_START(layer, point) do {\
+ g_perfPoint[(layer)] = (point);\
+ LWIP_DEBUGF(PERF_OUTPUT_DEBUG, ("set point %d:%s\n", layer, g_ppLayerName[g_perfPoint[(layer)]]));\
+ clock_gettime(CLOCK_MONOTONIC, &tvStart[(layer)]);\
+ g_timeTaken[(point)] = 0;\
+} while (0)
+
+#define PERF_UPDATE_POINT(layer, point) do {\
+ LWIP_DEBUGF(PERF_OUTPUT_DEBUG, ("old point %d:%s\n", layer, g_ppLayerName[g_perfPoint[(layer)]]));\
+ g_timeTaken[(point)] = g_timeTaken[g_perfPoint[(layer)]];\
+ g_timeTaken[g_perfPoint[(layer)]] = 0;\
+ g_perfPoint[(layer)] = (point);\
+ LWIP_DEBUGF(PERF_OUTPUT_DEBUG, ("new point %d:%s\n", layer, g_ppLayerName[g_perfPoint[(layer)]]));\
+} while (0)
+
+#define PERF_PAUSE(layer) do {\
+ struct timespec tvEnd;\
+ clock_gettime(CLOCK_MONOTONIC, &tvEnd);\
+ LWIP_DEBUGF(PERF_OUTPUT_DEBUG, ("perf pause layer%d\n", layer));\
+ g_timeTaken[g_perfPoint[(layer)]] += ((tvEnd.tv_sec - tvStart[(layer)].tv_sec) \
+ * (1000000000UL) + (tvEnd.tv_nsec - tvStart[(layer)].tv_nsec));\
+} while (0)
+
+#define PERF_PAUSE_RETURN_POINT(layer, pause_point) do {\
+ struct timespec tvEnd;\
+ clock_gettime(CLOCK_MONOTONIC, &tvEnd);\
+ g_timeTaken[g_perfPoint[(layer)]] += ((tvEnd.tv_sec - tvStart[(layer)].tv_sec) \
+ * (1000000000UL) + (tvEnd.tv_nsec - tvStart[(layer)].tv_nsec));\
+ LWIP_DEBUGF(PERF_OUTPUT_DEBUG, ("perf pause point %d:%s\n", layer, g_ppLayerName[g_perfPoint[(layer)]]));\
+ (pause_point) = g_perfPoint[(layer)];\
+} while (0)
+
+
+#define PERF_RESUME(layer, point) do {\
+ LWIP_DEBUGF(PERF_OUTPUT_DEBUG, ("perf resule point %d:%s\n", layer, g_ppLayerName[point]));\
+ clock_gettime(CLOCK_MONOTONIC, &tvStart[(layer)]);\
+ g_perfPoint[(layer)] = (point);\
+} while (0)
+
+
+/* x is a prompt */
+#define PERF_STOP_INCREASE_COUNT(x, layer) do {\
+ if (g_record_perf)\
+ {\
+ struct timespec tvEnd;\
+ int i = 2;\
+ uint32_t oldValue = 0;\
+ clock_gettime(CLOCK_MONOTONIC, &tvEnd);\
+ g_timeTaken[g_perfPoint[(layer)]] += ((tvEnd.tv_sec - tvStart[(layer)].tv_sec) \
+ * (1000000000UL) + (tvEnd.tv_nsec - tvStart[(layer)].tv_nsec));\
+ while (i && !oldValue)\
+ {\
+ oldValue = __sync_or_and_fetch(&g_perfMaxtime[g_perfPoint[(layer)]], 0);\
+ if (oldValue >= g_timeTaken[g_perfPoint[(layer)]])\
+ {\
+ break;\
+ }\
+ oldValue = __sync_val_compare_and_swap(&g_perfMaxtime[g_perfPoint[(layer)]],\
+ oldValue, g_timeTaken[g_perfPoint[(layer)]]);\
+ i--;\
+ }\
+ __sync_fetch_and_add(&g_astPacketCnt[g_perfPoint[(layer)]], 1);\
+ __sync_fetch_and_add(&g_astPacketProcTime[g_perfPoint[(layer)]], g_timeTaken[g_perfPoint[(layer)]]);\
+ LWIP_DEBUGF(PERF_OUTPUT_DEBUG, ("Time for %s is: %ld\n",\
+ g_ppLayerName[g_perfPoint[(layer)]], g_timeTaken[g_perfPoint[(layer)]]));\
+ }\
+} while (0)
+
+
+int check_layer_point(int layer, int point);
+int perf_init();
+
+#else
+#define PERF_START(layer, point) do { } while (0)
+#define PERF_UPDATE_POINT(layer, point) do { } while (0)
+#define PERF_PAUSE(layer) do { } while (0)
+#define PERF_PAUSE_RETURN_POINT(layer, pause_point) do { } while (0)
+#define PERF_RESUME(layer, point) do { } while (0)
+#define PERF_STOP_INCREASE_COUNT(x, layer) do { } while (0)
+#endif
+
+#endif /* LWIP_ARCH_PERF_H */
diff --git a/src/include/arch/sys_arch.h b/src/include/arch/sys_arch.h
index 3f555ee..b8a0d28 100644
--- a/src/include/arch/sys_arch.h
+++ b/src/include/arch/sys_arch.h
@@ -1,7 +1,93 @@
-#ifndef LWIP_SYS_ARCH_H
-#define LWIP_SYS_ARCH_H
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+#ifndef LWIP_ARCH_SYS_ARCH_H
+#define LWIP_ARCH_SYS_ARCH_H
+#include <rte_cycles.h>
+#include <rte_debug.h>
-#endif /* LWIP_SYS_ARCH_H */
+#define SYS_MBOX_NULL NULL
+#define SYS_SEM_NULL NULL
+typedef uint32_t sys_prot_t;
+struct sys_sem {
+ volatile unsigned int c;
+ int (*wait_fn)(void);
+};
+
+#define MBOX_NAME_LEN 64
+struct sys_mbox {
+ struct rte_ring *ring;
+ char name[MBOX_NAME_LEN];
+ int size;
+ int socket_id;
+ unsigned flags;
+ int (*wait_fn)(void);
+};
+
+typedef struct sys_sem *sys_sem_t;
+#define sys_sem_valid(sem) (((sem) != NULL) && (*(sem) != NULL))
+#define sys_sem_valid_val(sem) ((sem) != NULL)
+#define sys_sem_set_invalid(sem) do { if ((sem) != NULL) { *(sem) = NULL; }} while(0)
+#define sys_sem_set_invalid_val(sem) do { (sem) = NULL; } while(0)
+
+struct sys_mutex;
+typedef struct sys_mutex *sys_mutex_t;
+#define sys_mutex_valid(mutex) sys_sem_valid(mutex)
+#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
+
+typedef struct sys_mbox *sys_mbox_t;
+#define sys_mbox_valid(mbox) sys_sem_valid(mbox)
+#define sys_mbox_valid_val(mbox) sys_sem_valid_val(mbox)
+#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
+#define sys_mbox_set_invalid_val(mbox) sys_sem_set_invalid_val(mbox)
+int sys_mbox_empty(struct sys_mbox *);
+
+struct sys_thread;
+typedef struct sys_thread *sys_thread_t;
+
+extern int eth_dev_poll(void);
+
+void sys_calibrate_tsc(void);
+uint32_t sys_now(void);
+__attribute__((always_inline)) inline int update_timeout(int timeout, uint32_t poll_ts)
+{
+ uint32_t used_ms = sys_now() - poll_ts;
+ if (timeout > 0 && used_ms < timeout) {
+ return timeout;
+ } else {
+ return 0;
+ }
+}
+
+#endif /* LWIP_ARCH_SYS_ARCH_H */
diff --git a/src/include/eventpoll.h b/src/include/eventpoll.h
new file mode 100644
index 0000000..01f8d64
--- /dev/null
+++ b/src/include/eventpoll.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef __EVENTPOLL_H__
+#define __EVENTPOLL_H__
+
+#include <sys/epoll.h>
+
+#include "lwip/api.h"
+#include "list.h"
+
+#define MAX_EPOLLFDS 32
+
+#define LIBOS_EPOLLNONE (0x0)
+#define LIBOS_BADEP (NULL)
+
+struct event_queue {
+ struct list_node events;
+ /* total number of sockets have events */
+ int num_events;
+};
+
+struct event_array {
+ sys_mbox_t mbox;
+ volatile int num_events;
+ struct epoll_event events[0];
+};
+
+struct libos_epoll {
+ struct event_queue *libos_queue;
+ struct event_array *host_queue;
+ int num_hostfds;
+ int hints;
+ int fd; /* self fd */
+ int efd; /* eventfd */
+};
+
+extern int add_epoll_event(struct netconn*, uint32_t);
+extern int del_epoll_event(struct netconn*, uint32_t);
+extern int lwip_epoll_close(int);
+extern int lwip_is_epfd(int);
+
+#endif /* __EVENTPOLL_H__ */
diff --git a/src/include/hlist.h b/src/include/hlist.h
new file mode 100644
index 0000000..7059488
--- /dev/null
+++ b/src/include/hlist.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef __HLIST_H__
+#define __HLIST_H__
+
+#include "list.h"
+
+//#if TCP_PCB_HASH
+struct hlist_node {
+ /**
+ * @pprev: point the previous node's next pointer
+ */
+ struct hlist_node *next;
+ struct hlist_node **pprev;
+};
+
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_tail {
+ struct hlist_node *end;
+};
+
+struct hlist_ctl {
+ struct hlist_head head;
+ struct hlist_tail tail;
+};
+
+#define INIT_HLIST_CTRL(ptr) {(ptr)->head.first = NULL; (ptr)->tail.end = NULL;}
+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+#define INIT_HLIST_NODE(ptr) {(ptr)->next = NULL; (ptr)->pprev = NULL;}
+#define hlist_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * hlist_for_each_entry - iterate over list of given type
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_node to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(tpos, pos, head, member) \
+ for (pos = (head)->first; \
+ pos && ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
+ pos = (pos)->next)
+
+/**
+ * next must be != NULL
+ * add n node before next node
+ *
+ * @n: new node
+ * @next: node in the hlist
+ */
+static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next)
+{
+ n->pprev = next->pprev;
+ n->next = next;
+ next->pprev = &n->next;
+ *(n->pprev) = n;
+}
+
+static inline int hlist_empty(const struct hlist_head *h)
+{
+ return !h->first;
+}
+
+static inline int hlist_unhashed(const struct hlist_node *h)
+{
+ return !h->pprev;
+}
+
+static inline void hlist_del_init(struct hlist_node *n)
+{
+ struct hlist_node *next = n->next;
+ struct hlist_node **pprev = n->pprev;
+
+ if (pprev == NULL) {
+ return;
+ }
+
+ *pprev = next;
+ if (next != NULL) {
+ next->pprev = pprev;
+ }
+
+ n->next = NULL;
+ n->pprev = NULL;
+}
+
+static inline void hlist_ctl_del(struct hlist_ctl *ctl, struct hlist_node *n)
+{
+ if (ctl->head.first == ctl->tail.end) {
+ ctl->head.first = NULL;
+ ctl->tail.end = NULL;
+ return;
+ }
+
+ if (ctl->tail.end == n) {
+ ctl->tail.end = (struct hlist_node *)n->pprev;
+ }
+
+ hlist_del_init(n);
+}
+
+static inline struct hlist_node *hlist_pop_tail(struct hlist_ctl *ctl)
+{
+ if (hlist_empty(&ctl->head)) {
+ return NULL;
+ }
+
+ if (ctl->head.first == ctl->tail.end) {
+ struct hlist_node *ret = ctl->tail.end;
+ ctl->tail.end = NULL;
+ ctl->head.first = NULL;
+ return ret;
+ }
+
+ struct hlist_node *temp = ctl->tail.end;
+
+ struct hlist_node **ptailPrev = ctl->tail.end->pprev;
+ *ptailPrev = NULL;
+
+ ctl->tail.end = (struct hlist_node *)ptailPrev;
+ temp->pprev = NULL;
+ return temp;
+}
+
+static inline void hlist_add_after(struct hlist_node *n, struct hlist_node *next)
+{
+ next->next = n->next;
+ n->next = next;
+ next->pprev = &n->next;
+ if (next->next) {
+ next->next->pprev = &next->next;
+ }
+}
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+ struct hlist_node *first = h->first;
+
+ n->next = first;
+ if (first != NULL) {
+ first->pprev = &n->next;
+ }
+
+ h->first = n;
+ n->pprev = &h->first;
+}
+
+static inline struct hlist_node *hlist_pop_head(struct hlist_ctl *ctl)
+{
+ if (hlist_empty(&ctl->head)) {
+ return NULL;
+ }
+
+ struct hlist_node *temp = ctl->head.first;
+ hlist_ctl_del(ctl, temp);
+ return temp;
+}
+
+static inline void hlist_ctl_add_tail(struct hlist_ctl *ctl, struct hlist_node *node)
+{
+ if (hlist_empty(&ctl->head)) {
+ hlist_add_head(node, &ctl->head);
+ ctl->tail.end = ctl->head.first;
+ return;
+ }
+
+ ctl->tail.end->next = node;
+
+ node->pprev = &(ctl->tail.end->next);
+ node->next = NULL;
+ ctl->tail.end = node;
+}
+
+static inline void hlist_ctl_add_head(struct hlist_node *node, struct hlist_ctl *ctl)
+{
+ hlist_add_head(node, &ctl->head);
+ if (ctl->tail.end == NULL) {
+ ctl->tail.end = ctl->head.first;
+ }
+}
+
+static inline void hlist_ctl_add_before(struct hlist_node *n, struct hlist_node *next, struct hlist_ctl *ctl)
+{
+ hlist_add_before(n, next);
+ if (next == ctl->head.first) {
+ ctl->head.first = n;
+ }
+}
+
+static inline void hlist_ctl_add_after(struct hlist_node *n, struct hlist_node *next, struct hlist_ctl *ctl)
+{
+ hlist_add_after(n, next);
+ if (n == ctl->tail.end) {
+ ctl->tail.end = next;
+ }
+}
+//#endif /* TCP_PCB_HASH */
+
+#endif /* __HLIST_H__ */
diff --git a/src/include/list.h b/src/include/list.h
new file mode 100644
index 0000000..11f94c2
--- /dev/null
+++ b/src/include/list.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef __LIST_H__
+#define __LIST_H__
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+struct list_node {
+ struct list_node *prev;
+ struct list_node *next;
+};
+
+static inline void init_list_node_null(struct list_node *n)
+{
+ n->prev = NULL;
+ n->next = NULL;
+}
+
+static inline void init_list_node(struct list_node *n)
+{
+ n->prev = n;
+ n->next = n;
+}
+
+static inline void list_add_node(struct list_node *h, struct list_node *n)
+{
+ n->next = h;
+ n->prev = h->prev;
+ h->prev->next = n;
+ h->prev = n;
+}
+
+static inline void list_del_node(struct list_node *n)
+{
+ struct list_node *prev = n->prev;
+ struct list_node *next = n->next;
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void list_del_node_init(struct list_node *n)
+{
+ list_del_node(n);
+ init_list_node(n);
+}
+
+static inline void list_del_node_null(struct list_node *n)
+{
+ if ((n->next) && (n->prev)) {
+ list_del_node(n);
+ }
+ init_list_node_null(n);
+}
+
+static inline int list_is_null(const struct list_node *n)
+{
+ return (n->prev == NULL) && (n->next == NULL);
+}
+
+static inline int list_is_empty(const struct list_node *h)
+{
+ return h == h->next;
+}
+
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = (pos)->next; pos != (head); pos = n, n = (pos)->next)
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type,member));})
+#endif /* container_of */
+
+#endif /* __LIST_H__ */
diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h
index be8c22a..55fc413 100644
--- a/src/include/lwip/api.h
+++ b/src/include/lwip/api.h
@@ -140,8 +140,43 @@ enum netconn_type {
/** Raw connection IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
, NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */
#endif /* LWIP_IPV6 */
+
+#if USE_LIBOS
+ /*here must bigger than 0xff, because (type & 0xff) is for lwip inner use*/
+ , NETCONN_LIBOS = 0x100
+ , NETCONN_HOST = 0x200
+ , NETCONN_INPRG = 0x400
+ , NETCONN_STACK = NETCONN_LIBOS | NETCONN_HOST | NETCONN_INPRG
+#endif /* USE_LIBOS */
};
+#ifdef USE_LIBOS
+#define SET_CONN_TYPE_LIBOS_OR_HOST(conn) do { \
+ conn->type &= ~(NETCONN_STACK); \
+ conn->type |= (NETCONN_LIBOS | NETCONN_HOST); } while (0)
+#define SET_CONN_TYPE_LIBOS(conn) do { \
+ conn->type &= ~(NETCONN_STACK); \
+ conn->type |= NETCONN_LIBOS; } while (0)
+#define SET_CONN_TYPE_HOST(conn) do { \
+ conn->type &= ~(NETCONN_STACK); \
+ conn->type |= NETCONN_HOST; } while (0)
+#define ADD_CONN_TYPE_INPRG(conn) do { \
+ conn->type |= NETCONN_INPRG; } while(0)
+#define CONN_TYPE_HAS_LIBOS_AND_HOST(conn) ((conn->type & (NETCONN_LIBOS | NETCONN_HOST)) == (NETCONN_LIBOS | NETCONN_HOST))
+#define CONN_TYPE_HAS_LIBOS(conn) (conn->type & NETCONN_LIBOS)
+#define CONN_TYPE_HAS_HOST(conn) (conn->type & NETCONN_HOST)
+#define CONN_TYPE_HAS_INPRG(conn) (!!(conn->type & NETCONN_INPRG))
+#define CONN_TYPE_IS_LIBOS(conn) (!!(NETCONN_LIBOS == (conn->type & NETCONN_STACK)))
+#define CONN_TYPE_IS_HOST(conn) (!!(NETCONN_HOST == (conn->type & NETCONN_STACK)))
+#else
+#define SET_CONN_TYPE_LIBOS_OR_HOST(conn) do {} while (0)
+#define SET_CONN_TYPE_LIBOS(conn) do {} while (0)
+#define SET_CONN_TYPE_HOST(conn) do {} while (0)
+#define CONN_TYPE_HAS_LIBOS_AND_HOST(conn) (0)
+#define CONN_TYPE_HAS_LIBOS(conn) (0)
+#define CONN_TYPE_HAS_HOST(conn) (0)
+#endif /* USE_LIBOS */
+
/** Current state of the netconn. Non-TCP netconns are always
* in state NETCONN_NONE! */
enum netconn_state {
diff --git a/src/include/lwip/debug.h b/src/include/lwip/debug.h
index 0ec7e76..4986973 100644
--- a/src/include/lwip/debug.h
+++ b/src/include/lwip/debug.h
@@ -146,6 +146,7 @@
#define LWIP_DEBUGF(debug, message) do { \
if (LWIP_DEBUG_ENABLED(debug)) { \
+ LWIP_PLATFORM_LOG(debug, STRIP_BRACES(ESC_ARGS message)); \
LWIP_PLATFORM_DIAG(message); \
if ((debug) & LWIP_DBG_HALT) { \
while(1); \
diff --git a/src/include/lwip/def.h b/src/include/lwip/def.h
index d6bf763..cfc59e2 100644
--- a/src/include/lwip/def.h
+++ b/src/include/lwip/def.h
@@ -116,6 +116,21 @@ u32_t lwip_htonl(u32_t x);
/* Provide usual function names as macros for users, but this can be turned off */
#ifndef LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
+
+/* avoid conflicts with netinet/in.h */
+#ifdef htons
+#undef htons
+#endif
+#ifdef ntohs
+#undef ntohs
+#endif
+#ifdef htonl
+#undef htonl
+#endif
+#ifdef ntohl
+#undef ntohl
+#endif
+
#define htons(x) lwip_htons(x)
#define ntohs(x) lwip_ntohs(x)
#define htonl(x) lwip_htonl(x)
diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h
index 668d831..db031ba 100644
--- a/src/include/lwip/ip.h
+++ b/src/include/lwip/ip.h
@@ -107,9 +107,15 @@ struct ip_pcb {
/*
* Option flags per-socket. These are the same like SO_XXX in sockets.h
*/
+#if USE_LIBOS
+#define SOF_REUSEADDR 0x02U /* allow local address reuse */
+#define SOF_KEEPALIVE 0x09U /* keep connections alive */
+#define SOF_BROADCAST 0x06U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+#else
#define SOF_REUSEADDR 0x04U /* allow local address reuse */
#define SOF_KEEPALIVE 0x08U /* keep connections alive */
#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+#endif /* USE_LIBOS */
/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */
#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE)
@@ -136,7 +142,7 @@ struct ip_globals
/** Destination IP address of current_header */
ip_addr_t current_iphdr_dest;
};
-extern struct ip_globals ip_data;
+extern PER_THREAD struct ip_globals ip_data;
/** Get the interface that accepted the current packet.
diff --git a/src/include/lwip/memp.h b/src/include/lwip/memp.h
index 1630b26..64d8f31 100644
--- a/src/include/lwip/memp.h
+++ b/src/include/lwip/memp.h
@@ -58,7 +58,11 @@ typedef enum {
#include "lwip/priv/memp_priv.h"
#include "lwip/stats.h"
+#if USE_LIBOS
+extern PER_THREAD struct memp_desc* memp_pools[MEMP_MAX];
+#else
extern const struct memp_desc* const memp_pools[MEMP_MAX];
+#endif /* USE_LIBOS */
/**
* @ingroup mempool
@@ -92,6 +96,18 @@ extern const struct memp_desc* const memp_pools[MEMP_MAX];
* To relocate a pool, declare it as extern in cc.h. Example for GCC:
* extern u8_t \_\_attribute\_\_((section(".onchip_mem"))) memp_memory_my_private_pool_base[];
*/
+#if USE_LIBOS
+#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \
+ PER_THREAD struct memp_desc memp_ ## name = {0}; \
+ PER_THREAD char memp_desc_ ## name[] = desc; \
+ PER_THREAD struct stats_mem memp_stat ## name = {0}; \
+ PER_THREAD u16_t memp_size ## name = size; \
+ PER_THREAD u16_t memp_num ## name = num; \
+ PER_THREAD struct memp *memp_tab_ ## name = NULL; \
+ LWIP_DECLARE_MEMP_BASE_ALIGNED(name, ((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size))));
+
+#else /* USE_LIBOS */
+
#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \
LWIP_DECLARE_MEMORY_ALIGNED(memp_memory_ ## name ## _base, ((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))); \
\
@@ -108,6 +124,7 @@ extern const struct memp_desc* const memp_pools[MEMP_MAX];
&memp_tab_ ## name \
};
+#endif /* USE_LIBOS */
#endif /* MEMP_MEM_MALLOC */
/**
diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h
index 0cde2c2..1e6dc46 100644
--- a/src/include/lwip/netif.h
+++ b/src/include/lwip/netif.h
@@ -420,11 +420,11 @@ struct netif {
#define NETIF_FOREACH(netif) if (((netif) = netif_default) != NULL)
#else /* LWIP_SINGLE_NETIF */
/** The list of network interfaces. */
-extern struct netif *netif_list;
+extern PER_THREAD struct netif *netif_list;
#define NETIF_FOREACH(netif) for ((netif) = netif_list; (netif) != NULL; (netif) = (netif)->next)
#endif /* LWIP_SINGLE_NETIF */
/** The default network interface. */
-extern struct netif *netif_default;
+extern PER_THREAD struct netif *netif_default;
void netif_init(void);
diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h
index c27dd03..b738460 100644
--- a/src/include/lwip/opt.h
+++ b/src/include/lwip/opt.h
@@ -525,6 +525,22 @@
#define MEMP_NUM_NETCONN 4
#endif
+/**
+ * MEMP_NUM_SYS_SEM: the number of struct sys_sems.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#if !defined MEMP_NUM_SYS_SEM || defined __DOXYGEN__
+#define MEMP_NUM_SYS_SEM 128
+#endif
+
+/**
+ * MEMP_NUM_SYS_MBOX: the number of struct sys_sems.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#if !defined MEMP_NUM_SYS_MBOX || defined __DOXYGEN__
+#define MEMP_NUM_SYS_MBOX 128
+#endif
+
/**
* MEMP_NUM_SELECT_CB: the number of struct lwip_select_cb.
* (Only needed if you have LWIP_MPU_COMPATIBLE==1 and use the socket API.
@@ -2294,7 +2310,7 @@
* MIB2_STATS==1: Stats for SNMP MIB2.
*/
#if !defined MIB2_STATS || defined __DOXYGEN__
-#define MIB2_STATS 0
+#define MIB2_STATS 1
#endif
#else
@@ -3484,6 +3500,10 @@
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#endif
+#ifndef PERF_OUTPUT_DEBUG
+ #define PERF_OUTPUT_DEBUG LWIP_DBG_OFF
+#endif
+
/**
* TCP_RST_DEBUG: Enable debugging for TCP with the RST message.
*/
@@ -3571,6 +3591,46 @@
#define LWIP_TESTMODE 0
#endif
+/**
+ * EPOLL_DEBUG: Enable debugging in epoll.c.
+ */
+#if !defined EPOLL_DEBUG || defined __DOXYGEN__ && USE_LIBOS
+#define EPOLL_DEBUG LWIP_DBG_OFF
+#endif
+/**
+ * @}
+ */
+
+/**
+ * ETHDEV_DEBUG: Enable debugging in ethdev.c.
+ */
+#if !defined ETHDEV_DEBUG || defined __DOXYGEN__ && USE_LIBOS
+#define ETHDEV_DEBUG LWIP_DBG_OFF
+#endif
+/**
+ * @}
+ */
+
+/**
+ * ETHDEV_DEBUG: Enable debugging in ethdev.c.
+ */
+#if !defined SYSCALL_DEBUG || defined __DOXYGEN__ && USE_LIBOS
+#define SYSCALL_DEBUG LWIP_DBG_OFF
+#endif
+/**
+ * @}
+ */
+
+/**
+ * CONTROL_DEBUG: Enable debugging in control_plane.c.
+ */
+#if !defined CONTROL_DEBUG || defined __DOXYGEN__ && USE_LIBOS
+#define CONTROL_DEBUG LWIP_DBG_ON
+#endif
+/**
+ * @}
+ */
+
/*
--------------------------------------------------
---------- Performance tracking options ----------
diff --git a/src/include/lwip/priv/memp_std.h b/src/include/lwip/priv/memp_std.h
index 669ad4d..395ac0c 100644
--- a/src/include/lwip/priv/memp_std.h
+++ b/src/include/lwip/priv/memp_std.h
@@ -122,6 +122,13 @@ LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group),
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+#if USE_LIBOS
+#if !LWIP_NETCONN_SEM_PER_THREAD
+LWIP_MEMPOOL(SYS_SEM, MEMP_NUM_SYS_SEM, sizeof(struct sys_sem), "SYS_SEM")
+#endif
+
+LWIP_MEMPOOL(SYS_MBOX, MEMP_NUM_SYS_MBOX, sizeof(struct sys_mbox), "SYS_MBOX")
+#endif /* USE_LIBOS */
/*
* A list of pools of pbuf's used by LWIP.
*
diff --git a/src/include/lwip/priv/sockets_priv.h b/src/include/lwip/priv/sockets_priv.h
index c604734..f438206 100644
--- a/src/include/lwip/priv/sockets_priv.h
+++ b/src/include/lwip/priv/sockets_priv.h
@@ -45,56 +45,17 @@
#include "lwip/sockets.h"
#include "lwip/sys.h"
+/* move some definitions to the lwipsock.h for libnet to use, and
+ * at the same time avoid conflict between lwip/sockets.h and sys/socket.h
+ */
+#include "lwipsock.h"
+
#ifdef __cplusplus
extern "C" {
#endif
#define NUM_SOCKETS MEMP_NUM_NETCONN
-/** This is overridable for the rare case where more than 255 threads
- * select on the same socket...
- */
-#ifndef SELWAIT_T
-#define SELWAIT_T u8_t
-#endif
-
-union lwip_sock_lastdata {
- struct netbuf *netbuf;
- struct pbuf *pbuf;
-};
-
-/** Contains all internal pointers and states used for a socket */
-struct lwip_sock {
- /** sockets currently are built on netconns, each socket has one netconn */
- struct netconn *conn;
- /** data that was left from the previous read */
- union lwip_sock_lastdata lastdata;
-#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
- /** number of times data was received, set by event_callback(),
- tested by the receive and select functions */
- s16_t rcvevent;
- /** number of times data was ACKed (free send buffer), set by event_callback(),
- tested by select */
- u16_t sendevent;
- /** error happened for this socket, set by event_callback(), tested by select */
- u16_t errevent;
- /** counter of how many threads are waiting for this socket using select */
- SELWAIT_T select_waiting;
-#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
-#if LWIP_NETCONN_FULLDUPLEX
- /* counter of how many threads are using a struct lwip_sock (not the 'int') */
- u8_t fd_used;
- /* status of pending close/delete actions */
- u8_t fd_free_pending;
-#define LWIP_SOCK_FD_FREE_TCP 1
-#define LWIP_SOCK_FD_FREE_FREE 2
-#endif
-};
-
-#ifndef set_errno
-#define set_errno(err) do { if (err) { errno = (err); } } while(0)
-#endif
-
#if !LWIP_TCPIP_CORE_LOCKING
/** Maximum optlen used by setsockopt/getsockopt */
#define LWIP_SETGETSOCKOPT_MAXOPTLEN LWIP_MAX(16, sizeof(struct ifreq))
diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h
index a8e87e5..b1380b6 100644
--- a/src/include/lwip/priv/tcp_priv.h
+++ b/src/include/lwip/priv/tcp_priv.h
@@ -320,25 +320,42 @@ struct tcp_seg {
#endif /* LWIP_WND_SCALE */
/* Global variables: */
-extern struct tcp_pcb *tcp_input_pcb;
-extern u32_t tcp_ticks;
-extern u8_t tcp_active_pcbs_changed;
+extern PER_THREAD struct tcp_pcb *tcp_input_pcb;
+extern PER_THREAD u32_t tcp_ticks;
+extern PER_THREAD u8_t tcp_active_pcbs_changed;
/* The TCP PCB lists. */
union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
struct tcp_pcb_listen *listen_pcbs;
struct tcp_pcb *pcbs;
};
-extern struct tcp_pcb *tcp_bound_pcbs;
-extern union tcp_listen_pcbs_t tcp_listen_pcbs;
-extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
+extern PER_THREAD struct tcp_pcb *tcp_bound_pcbs;
+extern PER_THREAD union tcp_listen_pcbs_t tcp_listen_pcbs;
+extern PER_THREAD struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
state in which they accept or send
data. */
-extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */
+extern PER_THREAD struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */
#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3
#define NUM_TCP_PCB_LISTS 4
-extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
+extern PER_THREAD struct tcp_pcb ** tcp_pcb_lists[NUM_TCP_PCB_LISTS];
+
+#if USE_LIBOS
+#include "reg_sock.h"
+static inline int vdev_reg_done(enum reg_ring_type reg_type, const struct tcp_pcb *pcb)
+{
+ LWIP_ASSERT("Invalid parameter", pcb != NULL);
+
+ struct libnet_quintuple qtuple;
+ qtuple.protocol = 0;
+ qtuple.src_ip = pcb->local_ip.addr;
+ qtuple.src_port = lwip_htons(pcb->local_port);
+ qtuple.dst_ip = pcb->remote_ip.addr;
+ qtuple.dst_port = lwip_htons(pcb->remote_port);
+
+ return vdev_reg_xmit(reg_type, &qtuple);
+}
+#endif
/* Axioms about the above lists:
1) Every TCP PCB that is not CLOSED is in one of the lists.
@@ -352,6 +369,54 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
#define TCP_DEBUG_PCB_LISTS 0
#endif
#if TCP_DEBUG_PCB_LISTS
+#if USE_LIBOS
+#define TCP_REG(pcbs, npcb) do {\
+ struct tcp_pcb *tcp_tmp_pcb; \
+ LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \
+ for (tcp_tmp_pcb = *(pcbs); \
+ tcp_tmp_pcb != NULL; \
+ tcp_tmp_pcb = tcp_tmp_pcb->next) { \
+ LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \
+ } \
+ LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \
+ if (*pcbs) \
+ (*pcbs)->prev = npcb; \
+ (npcb)->prev = NULL; \
+ (npcb)->next = *(pcbs); \
+ LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \
+ *(pcbs) = (npcb); \
+ LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
+ tcp_timer_needed(); \
+ } while(0)
+#define TCP_RMV(pcbs, npcb) do { \
+ if (pcb->state == LISTEN) \
+ vdev_reg_done(REG_RING_TCP_LISTEN_CLOSE, npcb); \
+ else \
+ vdev_reg_done(REG_RING_TCP_CONNECT_CLOSE, npcb);\
+ struct tcp_pcb *tcp_tmp_pcb; \
+ LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \
+ LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \
+ if(*(pcbs) == (npcb)) { \
+ *(pcbs) = (*pcbs)->next; \
+ if (*pcbs) \
+ (*pcbs)->prev = NULL; \
+ } else { \
+ struct tcp_pcb *prev, *next; \
+ prev = npcb->prev; \
+ next = npcb->next; \
+ if (prev) \
+ prev->next = next; \
+ if (next) \
+ next->prev = prev; \
+ } \
+ } \
+ (npcb)->prev = NULL; \
+ (npcb)->next = NULL; \
+ LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
+ LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \
+ } while(0)
+
+#else /* USE_LIBOS */
#define TCP_REG(pcbs, npcb) do {\
struct tcp_pcb *tcp_tmp_pcb; \
LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %"U16_F"\n", (void *)(npcb), (npcb)->local_port)); \
@@ -384,8 +449,65 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \
} while(0)
+#endif /* USE_LIBOS */
#else /* LWIP_DEBUG */
+#if TCP_PCB_HASH
+#define TCP_REG_HASH(pcbs, npcb) \
+ do { \
+ u32_t idx; \
+ struct hlist_head *hd; \
+ struct tcp_hash_table *htb = pcbs; \
+ idx = TUPLE4_HASH_FN((npcb)->local_ip.addr, (npcb)->local_port, \
+ (npcb)->remote_ip.addr, (npcb)->remote_port) & \
+ (htb->size - 1); \
+ hd = &htb->array[idx].chain; \
+ hlist_add_head(&(npcb)->tcp_node, hd); \
+ tcp_timer_needed(); \
+ } while (0)
+
+#define TCP_RMV_HASH(pcbs, npcb) \
+ do { \
+ hlist_del_init(&(npcb)->tcp_node); \
+ } while (0)
+#endif /* TCP_PCB_HASH */
+
+#if USE_LIBOS
+#define TCP_REG(pcbs, npcb) \
+ do { \
+ if (*pcbs) \
+ (*pcbs)->prev = npcb; \
+ (npcb)->prev = NULL; \
+ (npcb)->next = *pcbs; \
+ *(pcbs) = (npcb); \
+ tcp_timer_needed(); \
+ } while (0)
+
+#define TCP_RMV(pcbs, npcb) \
+ do { \
+ if (pcb->state == LISTEN) \
+ vdev_reg_done(REG_RING_TCP_LISTEN_CLOSE, npcb); \
+ else \
+ vdev_reg_done(REG_RING_TCP_CONNECT_CLOSE, npcb);\
+ if(*(pcbs) == (npcb)) { \
+ (*(pcbs)) = (*pcbs)->next; \
+ if (*pcbs) \
+ (*pcbs)->prev = NULL; \
+ } \
+ else { \
+ struct tcp_pcb *prev, *next; \
+ prev = npcb->prev; \
+ next = npcb->next; \
+ if (prev) \
+ prev->next = next; \
+ if (next) \
+ next->prev = prev; \
+ } \
+ (npcb)->prev = NULL; \
+ (npcb)->next = NULL; \
+ } while(0)
+
+#else /* USE_LIBOS */
#define TCP_REG(pcbs, npcb) \
do { \
(npcb)->next = *pcbs; \
@@ -412,8 +534,32 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
(npcb)->next = NULL; \
} while(0)
+#endif /* USE_LIBOS */
#endif /* LWIP_DEBUG */
+
+#if TCP_PCB_HASH
+#define TCP_REG_ACTIVE_HASH(npcb) \
+ do { \
+ TCP_REG_HASH(tcp_active_htable, npcb); \
+ tcp_active_pcbs_changed = 1; \
+ } while (0)
+
+#define TCP_RMV_ACTIVE_HASH(npcb) \
+ do { \
+ TCP_RMV_HASH(tcp_active_htable, npcb); \
+ tcp_active_pcbs_changed = 1; \
+ } while (0)
+
+#define TCP_PCB_REMOVE_ACTIVE_HASH(pcb) \
+ do { \
+ tcp_pcb_remove_hash(tcp_active_htable, pcb); \
+ tcp_active_pcbs_changed = 1; \
+ } while (0)
+
+void tcp_pcb_remove_hash(struct tcp_hash_table *htb, struct tcp_pcb *pcb);
+#endif /* TCP_PCB_HASH */
+
#define TCP_REG_ACTIVE(npcb) \
do { \
TCP_REG(&tcp_active_pcbs, npcb); \
diff --git a/src/include/lwip/prot/ip4.h b/src/include/lwip/prot/ip4.h
index 9347461..c9ad89c 100644
--- a/src/include/lwip/prot/ip4.h
+++ b/src/include/lwip/prot/ip4.h
@@ -81,6 +81,21 @@ struct ip_hdr {
PACK_STRUCT_FIELD(u16_t _id);
/* fragment offset field */
PACK_STRUCT_FIELD(u16_t _offset);
+
+/* avoid conflicts with netinet/ip.h */
+#ifdef IP_RF
+#undef IP_RF
+#endif
+#ifdef IP_DF
+#undef IP_DF
+#endif
+#ifdef IP_MF
+#undef IP_MF
+#endif
+#ifdef IP_OFFMASK
+#undef IP_OFFMASK
+#endif
+
#define IP_RF 0x8000U /* reserved fragment flag */
#define IP_DF 0x4000U /* don't fragment flag */
#define IP_MF 0x2000U /* more fragments flag */
diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h
index b6f3d52..c8f0fab 100644
--- a/src/include/lwip/sockets.h
+++ b/src/include/lwip/sockets.h
@@ -64,6 +64,11 @@ extern "C" {
/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
to prevent this code from redefining it. */
+#if USE_LIBOS
+#define SA_FAMILY_T_DEFINED
+ typedef u16_t sa_family_t;
+#endif
+
#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
typedef u8_t sa_family_t;
#endif
@@ -76,7 +81,9 @@ typedef u16_t in_port_t;
#if LWIP_IPV4
/* members are in network byte order */
struct sockaddr_in {
+#if !USE_LIBOS
u8_t sin_len;
+#endif
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
@@ -97,7 +104,9 @@ struct sockaddr_in6 {
#endif /* LWIP_IPV6 */
struct sockaddr {
+#if !USE_LIBOS
u8_t sa_len;
+#endif
sa_family_t sa_family;
char sa_data[14];
};
@@ -198,6 +207,9 @@ struct ifreq {
#define SOCK_DGRAM 2
#define SOCK_RAW 3
+#if USE_LIBOS
+#include <asm/socket.h>
+#else
/*
* Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
*/
@@ -229,6 +241,12 @@ struct ifreq {
#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
#define SO_BINDTODEVICE 0x100b /* bind to device */
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define SOL_SOCKET 0xfff /* options for socket level */
+#endif /* USE_LIBOS */
+
/*
* Structure used for manipulating linger option.
*/
@@ -237,11 +255,6 @@ struct linger {
int l_linger; /* linger time in seconds */
};
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xfff /* options for socket level */
-
#define AF_UNSPEC 0
#define AF_INET 2
@@ -285,11 +298,20 @@ struct linger {
/*
* Options for level IPPROTO_TCP
*/
+#if USE_LIBOS
+/* come from netinet/tcp.h */
+#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
+#define TCP_KEEPALIVE 0x24 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
+#define TCP_KEEPIDLE 0x04 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
+#define TCP_KEEPINTVL 0x05 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
+#define TCP_KEEPCNT 0x06 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
+#else /* USE_LIBOS */
#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
+#endif /* USE_LIBOS */
#endif /* LWIP_TCP */
#if LWIP_IPV6
@@ -492,12 +514,30 @@ typedef struct fd_set
unsigned char fd_bits [(FD_SETSIZE+7)/8];
} fd_set;
-#elif FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN)
+#elif FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN) && !USE_LIBOS
#error "external FD_SETSIZE too small for number of sockets"
#else
#define LWIP_SELECT_MAXNFDS FD_SETSIZE
#endif /* FD_SET */
+#if USE_LIBOS
+#if !defined(POLLIN) && !defined(POLLOUT)
+/* come from bits/poll.h */
+#define POLLIN 0x001
+#define POLLOUT 0x004
+#define POLLERR 0x008
+#define POLLNVAL 0x020
+/* Below values are unimplemented */
+#define POLLRDNORM 0x040
+#define POLLRDBAND 0x080
+#define POLLPRI 0x002
+#define POLLWRNORM 0x100
+#define POLLWRBAND 0x200
+#define POLLHUP 0x010
+#endif
+#endif /* USE_LIBOS */
+
+#if LWIP_SOCKET_POLL
/* poll-related defines and types */
/* @todo: find a better way to guard the definition of these defines and types if already defined */
#if !defined(POLLIN) && !defined(POLLOUT)
@@ -520,6 +560,7 @@ struct pollfd
short revents;
};
#endif
+#endif /* LWIP_SOCKET_POLL */
/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
* by your system, set this to 0 and include <sys/time.h> in cc.h */
@@ -622,8 +663,15 @@ int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptse
#if LWIP_SOCKET_POLL
int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
#endif
+
+#if USE_LIBOS
+int lwip_ioctl(int s, long cmd, ...);
+int lwip_fcntl(int s, int cmd, ...);
+#else
int lwip_ioctl(int s, long cmd, void *argp);
int lwip_fcntl(int s, int cmd, int val);
+#endif /* USE_LIBOS */
+
const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size);
int lwip_inet_pton(int af, const char *src, void *dst);
@@ -689,10 +737,17 @@ int lwip_inet_pton(int af, const char *src, void *dst);
#define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt)
/** @ingroup socket */
#define close(s) lwip_close(s)
+
+#if USE_LIBOS
+#define fcntl(s,cmd...) lwip_fcntl(s,cmd)
+#define ioctl(s,cmd...) lwip_ioctl(s,cmd)
+#else
/** @ingroup socket */
#define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val)
/** @ingroup socket */
#define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp)
+#endif /* USE_LIBOS */
+
#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
#endif /* LWIP_COMPAT_SOCKETS != 2 */
diff --git a/src/include/lwip/stats.h b/src/include/lwip/stats.h
index b570dba..4470531 100644
--- a/src/include/lwip/stats.h
+++ b/src/include/lwip/stats.h
@@ -301,7 +301,7 @@ struct stats_ {
};
/** Global variable containing lwIP internal statistics. Add this to your debugger's watchlist. */
-extern struct stats_ lwip_stats;
+extern PER_THREAD struct stats_ lwip_stats;
/** Init statistics */
void stats_init(void);
@@ -467,6 +467,8 @@ void stats_init(void);
#define MIB2_STATS_INC(x)
#endif
+int get_mib2_stats(char *buf);
+
/* Display of statistics */
#if LWIP_STATS_DISPLAY
void stats_display(void);
diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h
index 3991fd6..8248753 100644
--- a/src/include/lwip/tcp.h
+++ b/src/include/lwip/tcp.h
@@ -51,6 +51,11 @@
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
+#if TCP_PCB_HASH
+#include "lwip/sys.h"
+#include "hlist.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -209,15 +214,27 @@ typedef u16_t tcpflags_t;
/**
* members common to struct tcp_pcb and struct tcp_listen_pcb
*/
+#if USE_LIBOS
#define TCP_PCB_COMMON(type) \
type *next; /* for the linked list */ \
+ type *prev; /* for the linked list */ \
void *callback_arg; \
TCP_PCB_EXTARGS \
enum tcp_state state; /* TCP state */ \
u8_t prio; \
/* ports are in host byte order */ \
u16_t local_port
-
+
+#else /* USE_LIBOS */
+#define TCP_PCB_COMMON(type) \
+ type *next; /* for the linked list */ \
+ void *callback_arg; \
+ TCP_PCB_EXTARGS \
+ enum tcp_state state; /* TCP state */ \
+ u8_t prio; \
+ /* ports are in host byte order */ \
+ u16_t local_port
+#endif /* USE_LIBOS */
/** the TCP protocol control block for listening pcbs */
struct tcp_pcb_listen {
@@ -244,6 +261,9 @@ struct tcp_pcb {
IP_PCB;
/** protocol specific PCB members */
TCP_PCB_COMMON(struct tcp_pcb);
+#if TCP_PCB_HASH
+ struct hlist_node tcp_node;
+#endif
/* ports are in host byte order */
u16_t remote_port;
@@ -388,6 +408,58 @@ struct tcp_pcb {
#endif
};
+#if TCP_PCB_HASH
+#define TCP_HTABLE_SIZE MEMP_NUM_NETCONN*12
+
+struct tcp_hashbucket
+{
+ sys_mutex_t mutex;
+ struct hlist_head chain;
+};
+
+struct tcp_hash_table
+{
+ u32_t size;
+ struct tcp_hashbucket array[TCP_HTABLE_SIZE];
+};
+
+extern PER_THREAD struct tcp_hash_table *tcp_active_htable; /* key: lport/fport/lip/fip */
+
+#define JHASH_INITVAL 0xdeadbeef
+
+static inline unsigned int rol32(unsigned int word, unsigned int shift)
+{
+ return (word << shift) | (word >> (32 - shift));
+}
+
+#define __jhash_final(a, b, c) \
+{ \
+ c ^= b; c -= rol32(b, 14); \
+ a ^= c; a -= rol32(c, 11); \
+ b ^= a; b -= rol32(a, 25); \
+ c ^= b; c -= rol32(b, 16); \
+ a ^= c; a -= rol32(c, 4); \
+ b ^= a; b -= rol32(a, 14); \
+ c ^= b; c -= rol32(b, 24); \
+}
+
+static inline unsigned int jhash_3words(unsigned int a, unsigned int b, unsigned int c)
+{
+ a += JHASH_INITVAL;
+ b += JHASH_INITVAL;;
+
+ __jhash_final(a, b, c);
+
+ return c;
+}
+
+#define TUPLE4_HASH_FN(laddr, lport, faddr, fport) jhash_3words(laddr, faddr,lport|(fport<<16))
+
+#define tcppcb_hlist_for_each(tcppcb, node, list) \
+ hlist_for_each_entry(tcppcb, node, list, tcp_node)
+
+#endif /* TCP_PCB_HASH */
+
#if LWIP_EVENT_API
enum lwip_event {
@@ -481,6 +553,26 @@ err_t tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_add
#define tcp_dbg_get_tcp_state(pcb) ((pcb)->state)
+enum tcp_list_state {
+ ACTIVE_LIST,
+ LISTEN_LIST,
+ TIME_WAIT_LIST,
+};
+
+struct tcp_pcb_dp {
+ uint32_t state;
+ uint32_t lip;
+ uint32_t rip;
+ uint16_t l_port;
+ uint16_t r_port;
+ uint32_t r_next;
+ uint32_t s_next;
+ uint32_t tcp_sub_state;
+};
+
+void tcp_get_conn(char *buf, int32_t len, uint32_t *conn_num);
+uint32_t tcp_get_conn_num(void);
+
/* for compatibility with older implementation */
#define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6)
diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h
index 30ce4fe..76e99c1 100644
--- a/src/include/lwip/tcpip.h
+++ b/src/include/lwip/tcpip.h
@@ -51,7 +51,7 @@ extern "C" {
#if LWIP_TCPIP_CORE_LOCKING
/** The global semaphore to lock the stack. */
-extern sys_mutex_t lock_tcpip_core;
+extern PER_THREAD sys_mutex_t lock_tcpip_core;
#if !defined LOCK_TCPIP_CORE || defined __DOXYGEN__
/** Lock lwIP core mutex (needs @ref LWIP_TCPIP_CORE_LOCKING 1) */
#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core)
diff --git a/src/include/lwip/timeouts.h b/src/include/lwip/timeouts.h
index b601f9e..b451554 100644
--- a/src/include/lwip/timeouts.h
+++ b/src/include/lwip/timeouts.h
@@ -119,6 +119,10 @@ struct sys_timeo** sys_timeouts_get_next_timeout(void);
void lwip_cyclic_timer(void *arg);
#endif
+#if USE_LIBOS
+void sys_timer_run(void);
+#endif /* USE_LIBOS */
+
#endif /* LWIP_TIMERS */
#ifdef __cplusplus
diff --git a/src/include/lwiplog.h b/src/include/lwiplog.h
new file mode 100644
index 0000000..363e516
--- /dev/null
+++ b/src/include/lwiplog.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef __LWIPLOG_H__
+#define __LWIPLOG_H__
+
+#include <stdio.h>
+#include <sys/syscall.h>
+
+#include <rte_log.h>
+
+#include "lwipopts.h"
+
+#define gettid() syscall(__NR_gettid)
+
+#if USE_DPDK_LOG
+
+#define LWIP_LOG_WARN LWIP_DBG_LEVEL_WARNING
+#define LWIP_LOG_ERROR LWIP_DBG_LEVEL_SERIOUS
+#define LWIP_LOG_FATAL LWIP_DBG_LEVEL_SEVERE
+
+#define LWIP_PLATFORM_LOG(level, fmt, ...) \
+do { \
+ if ((level) & LWIP_LOG_FATAL) { \
+ RTE_LOG(ERR, EAL, fmt, ##__VA_ARGS__); \
+ abort(); \
+ } else if ((level) & LWIP_LOG_ERROR) { \
+ RTE_LOG(ERR, EAL, fmt, ##__VA_ARGS__); \
+ } else if ((level) & LWIP_LOG_WARN) { \
+ RTE_LOG(WARNING, EAL, fmt, ##__VA_ARGS__); \
+ } else { \
+ RTE_LOG(INFO, EAL, fmt, ##__VA_ARGS__); \
+ } \
+} while(0)
+
+
+#define LWIP_PLATFORM_DIAG(x)
+
+#define ESC_ARGS(...) __VA_ARGS__
+#define STRIP_BRACES(args) args
+
+#define LWIP_PLATFORM_ASSERT(x) \
+do { LWIP_PLATFORM_LOG(LWIP_LOG_FATAL, "Assertion \"%s\" failed at line %d in %s\n", \
+ x, __LINE__, __FILE__); abort();} while(0)
+
+#else
+
+#define LWIP_PLATFORM_LOG(debug, message)
+
+#endif /* USE_DPDK_LOG */
+
+#endif /* __LWIPLOG_H__ */
diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h
index 4ab26f2..8893a5f 100644
--- a/src/include/lwipopts.h
+++ b/src/include/lwipopts.h
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
@@ -11,70 +11,193 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * derived from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
- *
- * Author: Simon Goldschmidt
+ *
+ * Author: Huawei Technologies
*
*/
-#ifndef LWIP_HDR_LWIPOPTS_H__
-#define LWIP_HDR_LWIPOPTS_H__
-
-/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
-#define NO_SYS 1
-#define LWIP_NETCONN 0
-#define LWIP_SOCKET 0
-#define SYS_LIGHTWEIGHT_PROT 0
-
-#define LWIP_IPV6 1
-#define IPV6_FRAG_COPYHEADER 1
-#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
-
-/* Enable some protocols to test them */
-#define LWIP_DHCP 1
-#define LWIP_AUTOIP 1
-
-#define LWIP_IGMP 1
-#define LWIP_DNS 1
-
-#define LWIP_ALTCP 1
-
-/* Turn off checksum verification of fuzzed data */
-#define CHECKSUM_CHECK_IP 0
-#define CHECKSUM_CHECK_UDP 0
-#define CHECKSUM_CHECK_TCP 0
-#define CHECKSUM_CHECK_ICMP 0
-#define CHECKSUM_CHECK_ICMP6 0
-
-/* Minimal changes to opt.h required for tcp unit tests: */
-#define MEM_SIZE 16000
-#define TCP_SND_QUEUELEN 40
-#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN
-#define TCP_OVERSIZE 1
-#define TCP_SND_BUF (12 * TCP_MSS)
-#define TCP_WND (10 * TCP_MSS)
-#define LWIP_WND_SCALE 1
-#define TCP_RCV_SCALE 2
-#define PBUF_POOL_SIZE 400 /* pbuf tests need ~200KByte */
-
-/* Minimal changes to opt.h required for etharp unit tests: */
-#define ETHARP_SUPPORT_STATIC_ENTRIES 1
-
-#define LWIP_NUM_NETIF_CLIENT_DATA 1
-#define LWIP_SNMP 1
-#define MIB2_STATS 1
-#define LWIP_MDNS_RESPONDER 1
-
-#endif /* LWIP_HDR_LWIPOPTS_H__ */
+
+#ifndef __LWIPOPTS_H__
+#define __LWIPOPTS_H__
+
+#define LWIP_TCPIP_CORE_LOCKING 1
+
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+
+#define LWIP_TCP 1
+
+#define LWIP_SO_SENTIMEO 0
+
+#define LIP_SO_LINGER 0
+
+#define MEMP_USE_CUSTOM_POOLS 0
+#define MEM_USE_POOLS 0
+
+#define PER_TCP_PCB_BUFFER (16 * 128)
+
+#define MAX_CLIENTS (20000)
+
+#define RESERVED_CLIENTS (2000)
+
+#define MEMP_NUM_TCP_PCB (MAX_CLIENTS + RESERVED_CLIENTS)
+
+/* we use PBUF_POOL instead of PBUF_RAM in tcp_write, so reduce PBUF_RAM size,
+ * and do NOT let PBUF_POOL_BUFSIZE less then TCP_MSS
+*/
+#define MEM_SIZE (((PER_TCP_PCB_BUFFER + 128) * MEMP_NUM_TCP_SEG) >> 2)
+
+#define MEMP_NUM_TCP_PCB_LISTEN 3000
+
+#define MEMP_NUM_TCP_SEG (128 * 128 * 2)
+
+#define MEMP_NUM_NETCONN (MAX_CLIENTS + RESERVED_CLIENTS)
+
+#define MEMP_NUM_SYS_SEM (MAX_CLIENTS + RESERVED_CLIENTS)
+
+#define MEMP_NUM_SYS_MBOX (MAX_CLIENTS + RESERVED_CLIENTS)
+
+#define PBUF_POOL_SIZE (MAX_CLIENTS * 2)
+
+#define MEMP_MEM_MALLOC 0
+
+#define LWIP_ARP 1
+
+#define ETHARP_SUPPORT_STATIC_ENTRIES 1
+
+#define LWIP_IPV4 1
+
+#define IP_FORWARD 0
+
+#define IP_REASSEMBLY 1
+
+#define LWIP_UDP 0
+
+#define LWIP_TCP 1
+
+#define IP_HLEN 20
+
+#define TCP_HLEN 20
+
+#define FRAME_MTU 1500
+
+#define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN)
+
+#define TCP_WND (40 * TCP_MSS)
+
+#define TCP_SND_BUF (5 * TCP_MSS)
+
+#define TCP_SND_QUEUELEN (8191)
+
+#define TCP_SNDLOWAT (TCP_SND_BUF / 5)
+
+#define TCP_SNDQUEUELOWAT (TCP_SND_QUEUELEN / 5)
+
+#define TCP_LISTEN_BACKLOG 1
+
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+
+#define TCP_OVERSIZE 0
+
+#define LWIP_NETIF_API 1
+
+#define DEFAULT_TCP_RECVMBOX_SIZE 128
+
+#define DEFAULT_ACCEPTMBOX_SIZE 1024
+
+#define LWIP_NETCONN 1
+
+#define LWIP_TCPIP_TIMEOUT 0
+
+#define LWIP_SOCKET 1
+
+#define LWIP_TCP_KEEPALIVE 1
+
+#define LWIP_STATS 1
+
+#define LWIP_STATS_DISPLAY 1
+
+#define CHECKSUM_GEN_IP 1 /* master switch */
+
+#define CHECKSUM_GEN_TCP 1 /* master switch */
+
+#define CHECKSUM_CHECK_IP 1 /* master switch */
+
+#define CHECKSUM_CHECK_TCP 1 /* master switch */
+
+#define LWIP_TIMEVAL_PRIVATE 0
+
+#define USE_LIBOS 1
+
+#define LWIP_DEBUG 1
+
+#define LWIP_PERF 1
+
+#define LWIP_RECORD_PERF 0
+
+#define LWIP_SOCKET_POLL 0
+
+#define USE_LIBOS_ZC_RING 0
+
+#define SO_REUSE 1
+
+#define SIOCSHIWAT 1
+
+#define O_NONBLOCK 04000 /* same as define in bits/fcntl-linux.h */
+
+#define O_NDELAY O_NONBLOCK
+
+#define FIONBIO 0x5421 /* same as define in asm-generic/ioctls.h */
+
+#define LWIP_SUPPORT_CUSTOM_PBUF 1
+
+#define MEM_LIBC_MALLOC 0
+
+#define LWIP_TIMERS 1
+
+#define TCPIP_MBOX_SIZE (MEMP_NUM_TCPIP_MSG_API)
+
+#define TCP_PCB_HASH 1
+
+#define USE_DPDK_LOG 1
+
+#define LWIP_EPOOL_WAIT_MAX_EVENTS 30
+
+#define ARP_TABLE_SIZE 512
+
+/*
+ ---------------------------------------
+ ------- Syscall thread options --------
+ ---------------------------------------
+*/
+#define USE_SYSCALL_THREAD 1
+
+#define MAX_BLOCKING_ACCEPT_FD (100)
+
+#define MAX_BLOCKING_CONNECT_FD (100)
+
+#define MAX_BLOCKING_EPOLL_FD (100)
+
+#define MAX_SYSCALL_EVENTS (MAX_BLOCKING_ACCEPT_FD + MAX_BLOCKING_CONNECT_FD + MAX_BLOCKING_EPOLL_FD)
+
+#define MAX_HOST_FD (MAX_CLIENTS + RESERVED_CLIENTS)
+
+#if USE_LIBOS
+#define PER_THREAD __thread
+#else
+#define PER_THREAD
+#endif
+
+#endif /* __LWIPOPTS_H__ */
diff --git a/src/include/lwipsock.h b/src/include/lwipsock.h
new file mode 100644
index 0000000..dbc67b9
--- /dev/null
+++ b/src/include/lwipsock.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef __LWIPSOCK_H__
+#define __LWIPSOCK_H__
+
+#include "lwip/opt.h"
+#include "lwip/api.h"
+
+#include "posix_api.h"
+#include "eventpoll.h"
+
+/* move some definitions to the lwipsock.h for libnet to use, and
+ * at the same time avoid conflict between lwip/sockets.h and sys/socket.h
+ */
+
+/* --------------------------------------------------
+ * the following definition is copied from lwip/priv/tcpip_priv.h
+ * --------------------------------------------------
+ */
+
+/** This is overridable for the rare case where more than 255 threads
+ * select on the same socket...
+ */
+#ifndef SELWAIT_T
+#define SELWAIT_T u8_t
+#endif
+
+union lwip_sock_lastdata {
+ struct netbuf *netbuf;
+ struct pbuf *pbuf;
+};
+
+/** Contains all internal pointers and states used for a socket */
+struct lwip_sock {
+ /** sockets currently are built on netconns, each socket has one netconn */
+ struct netconn *conn;
+ /** data that was left from the previous read */
+ union lwip_sock_lastdata lastdata;
+#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
+ /** number of times data was received, set by event_callback(),
+ tested by the receive and select functions */
+ s16_t rcvevent;
+ /** number of times data was ACKed (free send buffer), set by event_callback(),
+ tested by select */
+ u16_t sendevent;
+ /** error happened for this socket, set by event_callback(), tested by select */
+ u16_t errevent;
+ /** counter of how many threads are waiting for this socket using select */
+ SELWAIT_T select_waiting;
+#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
+#if LWIP_NETCONN_FULLDUPLEX
+ /* counter of how many threads are using a struct lwip_sock (not the 'int') */
+ u8_t fd_used;
+ /* status of pending close/delete actions */
+ u8_t fd_free_pending;
+#define LWIP_SOCK_FD_FREE_TCP 1
+#define LWIP_SOCK_FD_FREE_FREE 2
+#endif
+
+#if USE_LIBOS
+ struct list_node list;
+ /* registered events */
+ uint32_t epoll;
+ /* available events */
+ uint32_t events;
+ epoll_data_t ep_data;
+ /* libos_epoll pointer in use */
+ struct libos_epoll *epoll_data;
+#endif
+};
+
+#ifndef set_errno
+#define set_errno(err) do { if (err) { errno = (err); } } while(0)
+#endif
+
+
+/* --------------------------------------------------
+ * --------------- LIBNET references ----------------
+ * --------------------------------------------------
+ */
+#if USE_LIBOS
+extern uint32_t sockets_num;
+extern struct lwip_sock *sockets;
+/**
+ * Map a externally used socket index to the internal socket representation.
+ *
+ * @param s externally used socket index
+ * @return struct lwip_sock for the socket or NULL if not found
+ */
+static inline struct lwip_sock *
+get_socket_without_errno(int s)
+{
+ struct lwip_sock *sock = NULL;
+
+ s -= LWIP_SOCKET_OFFSET;
+
+ if ((s < 0) || (s >= sockets_num)) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s + LWIP_SOCKET_OFFSET));
+ return NULL;
+ }
+
+ sock = &sockets[s];
+
+ if (!sock->conn) {
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s + LWIP_SOCKET_OFFSET));
+ return NULL;
+ }
+
+ return sock;
+}
+#endif /* USE_LIBOS */
+
+struct lwip_sock *get_socket(int s);
+struct lwip_sock *get_socket_by_fd(int s);
+void lwip_sock_init(void);
+void lwip_exit(void);
+
+extern int is_host_ipv4(uint32_t ipv4);
+extern int rearm_host_fd(int fd);
+extern int rearm_accept_fd(int fd);
+extern void unarm_host_fd(int fd);
+extern void clean_host_fd(int fd);
+extern int arm_host_fd(struct libos_epoll *ep, int op, int fd, struct epoll_event *event);
+
+#endif /* __LWIPSOCK_H__ */
diff --git a/src/include/memp_def.h b/src/include/memp_def.h
new file mode 100644
index 0000000..082f685
--- /dev/null
+++ b/src/include/memp_def.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef __MEMP_DEF_H__
+#define __MEMP_DEF_H__
+
+#include "lwip/opt.h"
+#include "arch/cc.h"
+
+#define LWIP_MEMPOOL_BASE_DECLARE(name) \
+ extern void alloc_memp_##name##_base(void);
+
+#define LWIP_MEM_MEMORY_DECLARE(name) \
+ extern void alloc_memory_##name(void);
+
+#define LWIP_MEMPOOL_BASE_INIT(name) \
+ alloc_memp_##name##_base();
+
+#define LWIP_MEM_MEMORY_INIT(name) \
+ alloc_memory_##name();
+
+#define LWIP_MEMPOOL(name, num, size, desc) LWIP_MEMPOOL_BASE_DECLARE(name)
+#include <lwip/priv/memp_std.h>
+#undef LWIP_MEMPOOL
+
+static inline void hugepage_init(void)
+{
+#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_BASE_INIT(name)
+#include "lwip/priv/memp_std.h"
+
+#if !MEM_LIBC_MALLOC
+ LWIP_MEM_MEMORY_DECLARE(ram_heap)
+ LWIP_MEM_MEMORY_INIT(ram_heap)
+#endif /* MEM_LIBC_MALLOC */
+}
+
+#endif /* __MEMP_DEF_H__ */
diff --git a/src/include/posix_api.h b/src/include/posix_api.h
new file mode 100644
index 0000000..8aa8516
--- /dev/null
+++ b/src/include/posix_api.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef __POSIX_API_H__
+#define __POSIX_API_H__
+
+#include <signal.h>
+#include <poll.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+
+typedef struct {
+ void *handle;
+ int (*socket_fn)(int domain, int type, int protocol);
+ int (*accept_fn)(int s, struct sockaddr*, socklen_t*);
+ int (*accept4_fn)(int s, struct sockaddr *addr, socklen_t *addrlen, int flags);
+ int (*bind_fn)(int s, const struct sockaddr*, socklen_t);
+ int (*listen_fn)(int s, int backlog);
+ int (*connect_fn)(int s, const struct sockaddr *name, socklen_t namelen);
+ int (*getpeername_fn)(int s, struct sockaddr *name, socklen_t *namelen);
+ int (*getsockname_fn)(int s, struct sockaddr *name, socklen_t *namelen);
+ int (*setsockopt_fn)(int s, int level, int optname, const void *optval, socklen_t optlen);
+ int (*getsockopt_fn)(int s, int level, int optname, void *optval, socklen_t *optlen);
+ int (*shutdown_fn)(int s, int how);
+ int (*close_fn)(int fd);
+ pid_t (*fork_fn)(void);
+ ssize_t (*read_fn)(int fd, void *mem, size_t len);
+ ssize_t (*write_fn)(int fd, const void *data, size_t len);
+ ssize_t (*recv_fn)(int sockfd, void *buf, size_t len, int flags);
+ ssize_t (*send_fn)(int sockfd, const void *buf, size_t len, int flags);
+ ssize_t (*recv_msg)(int sockfd, const struct msghdr *msg, int flags);
+ ssize_t (*send_msg)(int sockfd, const struct msghdr *msg, int flags);
+ ssize_t (*recv_from)(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
+ ssize_t (*send_to)(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr,
+ socklen_t addrlen);
+ int (*fcntl_fn)(int fd, int cmd, ...);
+ int (*fcntl64_fn)(int fd, int cmd, ...);
+ int (*pipe_fn)(int pipefd[2]);
+ int (*epoll_create_fn)(int size);
+ int (*epoll_ctl_fn)(int epfd, int op, int fd, struct epoll_event *event);
+ int (*epoll_wait_fn)(int epfd, struct epoll_event *events, int maxevents, int timeout);
+ int (*epoll_close_fn)(int epfd);
+ int (*eventfd_fn)(unsigned int initval, int flags);
+ int (*is_epfd)(int fd);
+ struct lwip_sock* (*get_socket)(int fd);
+ int (*sigaction_fn)(int signum, const struct sigaction *act, struct sigaction *oldact);
+ int (*poll_fn)(struct pollfd *fds, nfds_t nfds, int timeout);
+ int (*ioctl_fn)(int fd, int cmd, ...);
+
+ int is_chld;
+} posix_api_t;
+
+posix_api_t *posix_api;
+
+int posix_api_init(void);
+void posix_api_free(void);
+void posix_api_fork(void);
+
+#endif /* __POSIX_API_H__ */
diff --git a/src/include/reg_sock.h b/src/include/reg_sock.h
new file mode 100644
index 0000000..76d4c48
--- /dev/null
+++ b/src/include/reg_sock.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Huawei Technologies
+ *
+ */
+
+#ifndef __REG_SOCK_H__
+#define __REG_SOCK_H__
+
+enum reg_ring_type {
+ REG_RING_TCP_LISTEN = 0,
+ REG_RING_TCP_LISTEN_CLOSE,
+ REG_RING_TCP_CONNECT,
+ REG_RING_TCP_CONNECT_CLOSE,
+ RING_REG_MAX,
+};
+
+struct libnet_quintuple {
+ uint32_t protocol;
+ /* net byte order */
+ uint16_t src_port;
+ uint16_t dst_port;
+ uint32_t src_ip;
+ uint32_t dst_ip;
+};
+
+struct reg_ring_msg {
+ enum reg_ring_type type;
+
+ uint32_t tid;
+ struct libnet_quintuple qtuple;
+};
+
+extern int vdev_reg_xmit(enum reg_ring_type type, struct libnet_quintuple *qtuple);
+
+#endif /* __REG_SOCK_H__ */
\ No newline at end of file
diff --git a/src/netif/dir.mk b/src/netif/dir.mk
index 233c79a..f585d5e 100644
--- a/src/netif/dir.mk
+++ b/src/netif/dir.mk
@@ -1,3 +1,3 @@
-SRC = ethernet.c
+SRC = ethernet.c
$(eval $(call register_dir, netif, $(SRC)))
--
1.8.3.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/flying-eagle12138/lwip.git
git@gitee.com:flying-eagle12138/lwip.git
flying-eagle12138
lwip
lwip
master

搜索帮助