link_linux.go 124 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213
  1. package netlink
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "io/ioutil"
  8. "net"
  9. "os"
  10. "strconv"
  11. "strings"
  12. "syscall"
  13. "unsafe"
  14. "github.com/vishvananda/netlink/nl"
  15. "github.com/vishvananda/netns"
  16. "golang.org/x/sys/unix"
  17. )
  18. const (
  19. SizeofLinkStats32 = 0x5c
  20. SizeofLinkStats64 = 0xb8
  21. )
  22. const (
  23. TUNTAP_MODE_TUN TuntapMode = unix.IFF_TUN
  24. TUNTAP_MODE_TAP TuntapMode = unix.IFF_TAP
  25. TUNTAP_DEFAULTS TuntapFlag = unix.IFF_TUN_EXCL | unix.IFF_ONE_QUEUE
  26. TUNTAP_VNET_HDR TuntapFlag = unix.IFF_VNET_HDR
  27. TUNTAP_TUN_EXCL TuntapFlag = unix.IFF_TUN_EXCL
  28. TUNTAP_NO_PI TuntapFlag = unix.IFF_NO_PI
  29. TUNTAP_ONE_QUEUE TuntapFlag = unix.IFF_ONE_QUEUE
  30. TUNTAP_MULTI_QUEUE TuntapFlag = unix.IFF_MULTI_QUEUE
  31. TUNTAP_MULTI_QUEUE_DEFAULTS TuntapFlag = TUNTAP_MULTI_QUEUE | TUNTAP_NO_PI
  32. )
  33. var StringToTuntapModeMap = map[string]TuntapMode{
  34. "tun": TUNTAP_MODE_TUN,
  35. "tap": TUNTAP_MODE_TAP,
  36. }
  37. func (ttm TuntapMode) String() string {
  38. switch ttm {
  39. case TUNTAP_MODE_TUN:
  40. return "tun"
  41. case TUNTAP_MODE_TAP:
  42. return "tap"
  43. }
  44. return "unknown"
  45. }
  46. const (
  47. VF_LINK_STATE_AUTO uint32 = 0
  48. VF_LINK_STATE_ENABLE uint32 = 1
  49. VF_LINK_STATE_DISABLE uint32 = 2
  50. )
  51. var macvlanModes = [...]uint32{
  52. 0,
  53. nl.MACVLAN_MODE_PRIVATE,
  54. nl.MACVLAN_MODE_VEPA,
  55. nl.MACVLAN_MODE_BRIDGE,
  56. nl.MACVLAN_MODE_PASSTHRU,
  57. nl.MACVLAN_MODE_SOURCE,
  58. }
  59. func ensureIndex(link *LinkAttrs) {
  60. if link != nil && link.Index == 0 {
  61. newlink, _ := LinkByName(link.Name)
  62. if newlink != nil {
  63. link.Index = newlink.Attrs().Index
  64. }
  65. }
  66. }
  67. func (h *Handle) ensureIndex(link *LinkAttrs) {
  68. if link != nil && link.Index == 0 {
  69. newlink, _ := h.LinkByName(link.Name)
  70. if newlink != nil {
  71. link.Index = newlink.Attrs().Index
  72. }
  73. }
  74. }
  75. func (h *Handle) LinkSetARPOff(link Link) error {
  76. base := link.Attrs()
  77. h.ensureIndex(base)
  78. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  79. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  80. msg.Change |= unix.IFF_NOARP
  81. msg.Flags |= unix.IFF_NOARP
  82. msg.Index = int32(base.Index)
  83. req.AddData(msg)
  84. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  85. return err
  86. }
  87. func LinkSetARPOff(link Link) error {
  88. return pkgHandle.LinkSetARPOff(link)
  89. }
  90. func (h *Handle) LinkSetARPOn(link Link) error {
  91. base := link.Attrs()
  92. h.ensureIndex(base)
  93. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  94. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  95. msg.Change |= unix.IFF_NOARP
  96. msg.Flags &= ^uint32(unix.IFF_NOARP)
  97. msg.Index = int32(base.Index)
  98. req.AddData(msg)
  99. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  100. return err
  101. }
  102. func LinkSetARPOn(link Link) error {
  103. return pkgHandle.LinkSetARPOn(link)
  104. }
  105. func (h *Handle) SetPromiscOn(link Link) error {
  106. base := link.Attrs()
  107. h.ensureIndex(base)
  108. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  109. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  110. msg.Change = unix.IFF_PROMISC
  111. msg.Flags = unix.IFF_PROMISC
  112. msg.Index = int32(base.Index)
  113. req.AddData(msg)
  114. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  115. return err
  116. }
  117. // LinkSetAllmulticastOn enables the reception of all hardware multicast packets for the link device.
  118. // Equivalent to: `ip link set $link allmulticast on`
  119. func LinkSetAllmulticastOn(link Link) error {
  120. return pkgHandle.LinkSetAllmulticastOn(link)
  121. }
  122. // LinkSetAllmulticastOn enables the reception of all hardware multicast packets for the link device.
  123. // Equivalent to: `ip link set $link allmulticast on`
  124. func (h *Handle) LinkSetAllmulticastOn(link Link) error {
  125. base := link.Attrs()
  126. h.ensureIndex(base)
  127. req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
  128. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  129. msg.Change = unix.IFF_ALLMULTI
  130. msg.Flags = unix.IFF_ALLMULTI
  131. msg.Index = int32(base.Index)
  132. req.AddData(msg)
  133. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  134. return err
  135. }
  136. // LinkSetAllmulticastOff disables the reception of all hardware multicast packets for the link device.
  137. // Equivalent to: `ip link set $link allmulticast off`
  138. func LinkSetAllmulticastOff(link Link) error {
  139. return pkgHandle.LinkSetAllmulticastOff(link)
  140. }
  141. // LinkSetAllmulticastOff disables the reception of all hardware multicast packets for the link device.
  142. // Equivalent to: `ip link set $link allmulticast off`
  143. func (h *Handle) LinkSetAllmulticastOff(link Link) error {
  144. base := link.Attrs()
  145. h.ensureIndex(base)
  146. req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
  147. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  148. msg.Change = unix.IFF_ALLMULTI
  149. msg.Index = int32(base.Index)
  150. req.AddData(msg)
  151. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  152. return err
  153. }
  154. // LinkSetMulticastOn enables the reception of multicast packets for the link device.
  155. // Equivalent to: `ip link set $link multicast on`
  156. func LinkSetMulticastOn(link Link) error {
  157. return pkgHandle.LinkSetMulticastOn(link)
  158. }
  159. // LinkSetMulticastOn enables the reception of multicast packets for the link device.
  160. // Equivalent to: `ip link set $link multicast on`
  161. func (h *Handle) LinkSetMulticastOn(link Link) error {
  162. base := link.Attrs()
  163. h.ensureIndex(base)
  164. req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
  165. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  166. msg.Change = unix.IFF_MULTICAST
  167. msg.Flags = unix.IFF_MULTICAST
  168. msg.Index = int32(base.Index)
  169. req.AddData(msg)
  170. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  171. return err
  172. }
  173. // LinkSetAllmulticastOff disables the reception of multicast packets for the link device.
  174. // Equivalent to: `ip link set $link multicast off`
  175. func LinkSetMulticastOff(link Link) error {
  176. return pkgHandle.LinkSetMulticastOff(link)
  177. }
  178. // LinkSetAllmulticastOff disables the reception of multicast packets for the link device.
  179. // Equivalent to: `ip link set $link multicast off`
  180. func (h *Handle) LinkSetMulticastOff(link Link) error {
  181. base := link.Attrs()
  182. h.ensureIndex(base)
  183. req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
  184. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  185. msg.Change = unix.IFF_MULTICAST
  186. msg.Index = int32(base.Index)
  187. req.AddData(msg)
  188. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  189. return err
  190. }
  191. func MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error {
  192. return pkgHandle.MacvlanMACAddrAdd(link, addr)
  193. }
  194. func (h *Handle) MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error {
  195. return h.macvlanMACAddrChange(link, []net.HardwareAddr{addr}, nl.MACVLAN_MACADDR_ADD)
  196. }
  197. func MacvlanMACAddrDel(link Link, addr net.HardwareAddr) error {
  198. return pkgHandle.MacvlanMACAddrDel(link, addr)
  199. }
  200. func (h *Handle) MacvlanMACAddrDel(link Link, addr net.HardwareAddr) error {
  201. return h.macvlanMACAddrChange(link, []net.HardwareAddr{addr}, nl.MACVLAN_MACADDR_DEL)
  202. }
  203. func MacvlanMACAddrFlush(link Link) error {
  204. return pkgHandle.MacvlanMACAddrFlush(link)
  205. }
  206. func (h *Handle) MacvlanMACAddrFlush(link Link) error {
  207. return h.macvlanMACAddrChange(link, nil, nl.MACVLAN_MACADDR_FLUSH)
  208. }
  209. func MacvlanMACAddrSet(link Link, addrs []net.HardwareAddr) error {
  210. return pkgHandle.MacvlanMACAddrSet(link, addrs)
  211. }
  212. func (h *Handle) MacvlanMACAddrSet(link Link, addrs []net.HardwareAddr) error {
  213. return h.macvlanMACAddrChange(link, addrs, nl.MACVLAN_MACADDR_SET)
  214. }
  215. func (h *Handle) macvlanMACAddrChange(link Link, addrs []net.HardwareAddr, mode uint32) error {
  216. base := link.Attrs()
  217. h.ensureIndex(base)
  218. req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
  219. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  220. msg.Index = int32(base.Index)
  221. req.AddData(msg)
  222. linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil)
  223. linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type()))
  224. inner := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  225. // IFLA_MACVLAN_MACADDR_MODE = mode
  226. b := make([]byte, 4)
  227. native.PutUint32(b, mode)
  228. inner.AddRtAttr(nl.IFLA_MACVLAN_MACADDR_MODE, b)
  229. // populate message with MAC addrs, if necessary
  230. switch mode {
  231. case nl.MACVLAN_MACADDR_ADD, nl.MACVLAN_MACADDR_DEL:
  232. if len(addrs) == 1 {
  233. inner.AddRtAttr(nl.IFLA_MACVLAN_MACADDR, []byte(addrs[0]))
  234. }
  235. case nl.MACVLAN_MACADDR_SET:
  236. mad := inner.AddRtAttr(nl.IFLA_MACVLAN_MACADDR_DATA, nil)
  237. for _, addr := range addrs {
  238. mad.AddRtAttr(nl.IFLA_MACVLAN_MACADDR, []byte(addr))
  239. }
  240. }
  241. req.AddData(linkInfo)
  242. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  243. return err
  244. }
  245. // LinkSetMacvlanMode sets the mode of a macvlan or macvtap link device.
  246. // Note that passthrough mode cannot be set to and from and will fail.
  247. // Equivalent to: `ip link set $link type (macvlan|macvtap) mode $mode
  248. func LinkSetMacvlanMode(link Link, mode MacvlanMode) error {
  249. return pkgHandle.LinkSetMacvlanMode(link, mode)
  250. }
  251. // LinkSetMacvlanMode sets the mode of the macvlan or macvtap link device.
  252. // Note that passthrough mode cannot be set to and from and will fail.
  253. // Equivalent to: `ip link set $link type (macvlan|macvtap) mode $mode
  254. func (h *Handle) LinkSetMacvlanMode(link Link, mode MacvlanMode) error {
  255. base := link.Attrs()
  256. h.ensureIndex(base)
  257. req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
  258. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  259. msg.Index = int32(base.Index)
  260. req.AddData(msg)
  261. linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil)
  262. linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type()))
  263. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  264. data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[mode]))
  265. req.AddData(linkInfo)
  266. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  267. return err
  268. }
  269. func BridgeSetMcastSnoop(link Link, on bool) error {
  270. return pkgHandle.BridgeSetMcastSnoop(link, on)
  271. }
  272. func (h *Handle) BridgeSetMcastSnoop(link Link, on bool) error {
  273. bridge := link.(*Bridge)
  274. bridge.MulticastSnooping = &on
  275. return h.linkModify(bridge, unix.NLM_F_ACK)
  276. }
  277. func BridgeSetVlanFiltering(link Link, on bool) error {
  278. return pkgHandle.BridgeSetVlanFiltering(link, on)
  279. }
  280. func (h *Handle) BridgeSetVlanFiltering(link Link, on bool) error {
  281. bridge := link.(*Bridge)
  282. bridge.VlanFiltering = &on
  283. return h.linkModify(bridge, unix.NLM_F_ACK)
  284. }
  285. func BridgeSetVlanDefaultPVID(link Link, pvid uint16) error {
  286. return pkgHandle.BridgeSetVlanDefaultPVID(link, pvid)
  287. }
  288. func (h *Handle) BridgeSetVlanDefaultPVID(link Link, pvid uint16) error {
  289. bridge := link.(*Bridge)
  290. bridge.VlanDefaultPVID = &pvid
  291. return h.linkModify(bridge, unix.NLM_F_ACK)
  292. }
  293. func SetPromiscOn(link Link) error {
  294. return pkgHandle.SetPromiscOn(link)
  295. }
  296. func (h *Handle) SetPromiscOff(link Link) error {
  297. base := link.Attrs()
  298. h.ensureIndex(base)
  299. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  300. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  301. msg.Change = unix.IFF_PROMISC
  302. msg.Index = int32(base.Index)
  303. req.AddData(msg)
  304. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  305. return err
  306. }
  307. func SetPromiscOff(link Link) error {
  308. return pkgHandle.SetPromiscOff(link)
  309. }
  310. // LinkSetUp enables the link device.
  311. // Equivalent to: `ip link set $link up`
  312. func LinkSetUp(link Link) error {
  313. return pkgHandle.LinkSetUp(link)
  314. }
  315. // LinkSetUp enables the link device.
  316. // Equivalent to: `ip link set $link up`
  317. func (h *Handle) LinkSetUp(link Link) error {
  318. base := link.Attrs()
  319. h.ensureIndex(base)
  320. req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
  321. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  322. msg.Change = unix.IFF_UP
  323. msg.Flags = unix.IFF_UP
  324. msg.Index = int32(base.Index)
  325. req.AddData(msg)
  326. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  327. return err
  328. }
  329. // LinkSetDown disables link device.
  330. // Equivalent to: `ip link set $link down`
  331. func LinkSetDown(link Link) error {
  332. return pkgHandle.LinkSetDown(link)
  333. }
  334. // LinkSetDown disables link device.
  335. // Equivalent to: `ip link set $link down`
  336. func (h *Handle) LinkSetDown(link Link) error {
  337. base := link.Attrs()
  338. h.ensureIndex(base)
  339. req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
  340. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  341. msg.Change = unix.IFF_UP
  342. msg.Index = int32(base.Index)
  343. req.AddData(msg)
  344. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  345. return err
  346. }
  347. // LinkSetMTU sets the mtu of the link device.
  348. // Equivalent to: `ip link set $link mtu $mtu`
  349. func LinkSetMTU(link Link, mtu int) error {
  350. return pkgHandle.LinkSetMTU(link, mtu)
  351. }
  352. // LinkSetMTU sets the mtu of the link device.
  353. // Equivalent to: `ip link set $link mtu $mtu`
  354. func (h *Handle) LinkSetMTU(link Link, mtu int) error {
  355. base := link.Attrs()
  356. h.ensureIndex(base)
  357. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  358. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  359. msg.Index = int32(base.Index)
  360. req.AddData(msg)
  361. b := make([]byte, 4)
  362. native.PutUint32(b, uint32(mtu))
  363. data := nl.NewRtAttr(unix.IFLA_MTU, b)
  364. req.AddData(data)
  365. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  366. return err
  367. }
  368. // LinkSetName sets the name of the link device.
  369. // Equivalent to: `ip link set $link name $name`
  370. func LinkSetName(link Link, name string) error {
  371. return pkgHandle.LinkSetName(link, name)
  372. }
  373. // LinkSetName sets the name of the link device.
  374. // Equivalent to: `ip link set $link name $name`
  375. func (h *Handle) LinkSetName(link Link, name string) error {
  376. base := link.Attrs()
  377. h.ensureIndex(base)
  378. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  379. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  380. msg.Index = int32(base.Index)
  381. req.AddData(msg)
  382. data := nl.NewRtAttr(unix.IFLA_IFNAME, []byte(name))
  383. req.AddData(data)
  384. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  385. return err
  386. }
  387. // LinkSetAlias sets the alias of the link device.
  388. // Equivalent to: `ip link set dev $link alias $name`
  389. func LinkSetAlias(link Link, name string) error {
  390. return pkgHandle.LinkSetAlias(link, name)
  391. }
  392. // LinkSetAlias sets the alias of the link device.
  393. // Equivalent to: `ip link set dev $link alias $name`
  394. func (h *Handle) LinkSetAlias(link Link, name string) error {
  395. base := link.Attrs()
  396. h.ensureIndex(base)
  397. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  398. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  399. msg.Index = int32(base.Index)
  400. req.AddData(msg)
  401. data := nl.NewRtAttr(unix.IFLA_IFALIAS, []byte(name))
  402. req.AddData(data)
  403. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  404. return err
  405. }
  406. // LinkAddAltName adds a new alternative name for the link device.
  407. // Equivalent to: `ip link property add $link altname $name`
  408. func LinkAddAltName(link Link, name string) error {
  409. return pkgHandle.LinkAddAltName(link, name)
  410. }
  411. // LinkAddAltName adds a new alternative name for the link device.
  412. // Equivalent to: `ip link property add $link altname $name`
  413. func (h *Handle) LinkAddAltName(link Link, name string) error {
  414. base := link.Attrs()
  415. h.ensureIndex(base)
  416. req := h.newNetlinkRequest(unix.RTM_NEWLINKPROP, unix.NLM_F_ACK)
  417. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  418. msg.Index = int32(base.Index)
  419. req.AddData(msg)
  420. data := nl.NewRtAttr(unix.IFLA_PROP_LIST|unix.NLA_F_NESTED, nil)
  421. data.AddRtAttr(unix.IFLA_ALT_IFNAME, []byte(name))
  422. req.AddData(data)
  423. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  424. return err
  425. }
  426. // LinkDelAltName delete an alternative name for the link device.
  427. // Equivalent to: `ip link property del $link altname $name`
  428. func LinkDelAltName(link Link, name string) error {
  429. return pkgHandle.LinkDelAltName(link, name)
  430. }
  431. // LinkDelAltName delete an alternative name for the link device.
  432. // Equivalent to: `ip link property del $link altname $name`
  433. func (h *Handle) LinkDelAltName(link Link, name string) error {
  434. base := link.Attrs()
  435. h.ensureIndex(base)
  436. req := h.newNetlinkRequest(unix.RTM_DELLINKPROP, unix.NLM_F_ACK)
  437. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  438. msg.Index = int32(base.Index)
  439. req.AddData(msg)
  440. data := nl.NewRtAttr(unix.IFLA_PROP_LIST|unix.NLA_F_NESTED, nil)
  441. data.AddRtAttr(unix.IFLA_ALT_IFNAME, []byte(name))
  442. req.AddData(data)
  443. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  444. return err
  445. }
  446. // LinkSetHardwareAddr sets the hardware address of the link device.
  447. // Equivalent to: `ip link set $link address $hwaddr`
  448. func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
  449. return pkgHandle.LinkSetHardwareAddr(link, hwaddr)
  450. }
  451. // LinkSetHardwareAddr sets the hardware address of the link device.
  452. // Equivalent to: `ip link set $link address $hwaddr`
  453. func (h *Handle) LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
  454. base := link.Attrs()
  455. h.ensureIndex(base)
  456. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  457. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  458. msg.Index = int32(base.Index)
  459. req.AddData(msg)
  460. data := nl.NewRtAttr(unix.IFLA_ADDRESS, []byte(hwaddr))
  461. req.AddData(data)
  462. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  463. return err
  464. }
  465. // LinkSetVfHardwareAddr sets the hardware address of a vf for the link.
  466. // Equivalent to: `ip link set $link vf $vf mac $hwaddr`
  467. func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
  468. return pkgHandle.LinkSetVfHardwareAddr(link, vf, hwaddr)
  469. }
  470. // LinkSetVfHardwareAddr sets the hardware address of a vf for the link.
  471. // Equivalent to: `ip link set $link vf $vf mac $hwaddr`
  472. func (h *Handle) LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
  473. base := link.Attrs()
  474. h.ensureIndex(base)
  475. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  476. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  477. msg.Index = int32(base.Index)
  478. req.AddData(msg)
  479. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  480. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  481. vfmsg := nl.VfMac{
  482. Vf: uint32(vf),
  483. }
  484. copy(vfmsg.Mac[:], []byte(hwaddr))
  485. info.AddRtAttr(nl.IFLA_VF_MAC, vfmsg.Serialize())
  486. req.AddData(data)
  487. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  488. return err
  489. }
  490. // LinkSetVfVlan sets the vlan of a vf for the link.
  491. // Equivalent to: `ip link set $link vf $vf vlan $vlan`
  492. func LinkSetVfVlan(link Link, vf, vlan int) error {
  493. return pkgHandle.LinkSetVfVlan(link, vf, vlan)
  494. }
  495. // LinkSetVfVlan sets the vlan of a vf for the link.
  496. // Equivalent to: `ip link set $link vf $vf vlan $vlan`
  497. func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
  498. base := link.Attrs()
  499. h.ensureIndex(base)
  500. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  501. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  502. msg.Index = int32(base.Index)
  503. req.AddData(msg)
  504. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  505. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  506. vfmsg := nl.VfVlan{
  507. Vf: uint32(vf),
  508. Vlan: uint32(vlan),
  509. }
  510. info.AddRtAttr(nl.IFLA_VF_VLAN, vfmsg.Serialize())
  511. req.AddData(data)
  512. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  513. return err
  514. }
  515. // LinkSetVfVlanQos sets the vlan and qos priority of a vf for the link.
  516. // Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos`
  517. func LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
  518. return pkgHandle.LinkSetVfVlanQos(link, vf, vlan, qos)
  519. }
  520. // LinkSetVfVlanQos sets the vlan and qos priority of a vf for the link.
  521. // Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos`
  522. func (h *Handle) LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
  523. base := link.Attrs()
  524. h.ensureIndex(base)
  525. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  526. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  527. msg.Index = int32(base.Index)
  528. req.AddData(msg)
  529. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  530. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  531. vfmsg := nl.VfVlan{
  532. Vf: uint32(vf),
  533. Vlan: uint32(vlan),
  534. Qos: uint32(qos),
  535. }
  536. info.AddRtAttr(nl.IFLA_VF_VLAN, vfmsg.Serialize())
  537. req.AddData(data)
  538. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  539. return err
  540. }
  541. // LinkSetVfVlanQosProto sets the vlan, qos and protocol of a vf for the link.
  542. // Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos proto $proto`
  543. func LinkSetVfVlanQosProto(link Link, vf, vlan, qos, proto int) error {
  544. return pkgHandle.LinkSetVfVlanQosProto(link, vf, vlan, qos, proto)
  545. }
  546. // LinkSetVfVlanQosProto sets the vlan, qos and protocol of a vf for the link.
  547. // Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos proto $proto`
  548. func (h *Handle) LinkSetVfVlanQosProto(link Link, vf, vlan, qos, proto int) error {
  549. base := link.Attrs()
  550. h.ensureIndex(base)
  551. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  552. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  553. msg.Index = int32(base.Index)
  554. req.AddData(msg)
  555. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  556. vfInfo := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  557. vfVlanList := vfInfo.AddRtAttr(nl.IFLA_VF_VLAN_LIST, nil)
  558. vfmsg := nl.VfVlanInfo{
  559. VfVlan: nl.VfVlan{
  560. Vf: uint32(vf),
  561. Vlan: uint32(vlan),
  562. Qos: uint32(qos),
  563. },
  564. VlanProto: (uint16(proto)>>8)&0xFF | (uint16(proto)&0xFF)<<8,
  565. }
  566. vfVlanList.AddRtAttr(nl.IFLA_VF_VLAN_INFO, vfmsg.Serialize())
  567. req.AddData(data)
  568. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  569. return err
  570. }
  571. // LinkSetVfTxRate sets the tx rate of a vf for the link.
  572. // Equivalent to: `ip link set $link vf $vf rate $rate`
  573. func LinkSetVfTxRate(link Link, vf, rate int) error {
  574. return pkgHandle.LinkSetVfTxRate(link, vf, rate)
  575. }
  576. // LinkSetVfTxRate sets the tx rate of a vf for the link.
  577. // Equivalent to: `ip link set $link vf $vf rate $rate`
  578. func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
  579. base := link.Attrs()
  580. h.ensureIndex(base)
  581. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  582. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  583. msg.Index = int32(base.Index)
  584. req.AddData(msg)
  585. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  586. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  587. vfmsg := nl.VfTxRate{
  588. Vf: uint32(vf),
  589. Rate: uint32(rate),
  590. }
  591. info.AddRtAttr(nl.IFLA_VF_TX_RATE, vfmsg.Serialize())
  592. req.AddData(data)
  593. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  594. return err
  595. }
  596. // LinkSetVfRate sets the min and max tx rate of a vf for the link.
  597. // Equivalent to: `ip link set $link vf $vf min_tx_rate $min_rate max_tx_rate $max_rate`
  598. func LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
  599. return pkgHandle.LinkSetVfRate(link, vf, minRate, maxRate)
  600. }
  601. // LinkSetVfRate sets the min and max tx rate of a vf for the link.
  602. // Equivalent to: `ip link set $link vf $vf min_tx_rate $min_rate max_tx_rate $max_rate`
  603. func (h *Handle) LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
  604. base := link.Attrs()
  605. h.ensureIndex(base)
  606. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  607. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  608. msg.Index = int32(base.Index)
  609. req.AddData(msg)
  610. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  611. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  612. vfmsg := nl.VfRate{
  613. Vf: uint32(vf),
  614. MinTxRate: uint32(minRate),
  615. MaxTxRate: uint32(maxRate),
  616. }
  617. info.AddRtAttr(nl.IFLA_VF_RATE, vfmsg.Serialize())
  618. req.AddData(data)
  619. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  620. return err
  621. }
  622. // LinkSetVfState enables/disables virtual link state on a vf.
  623. // Equivalent to: `ip link set $link vf $vf state $state`
  624. func LinkSetVfState(link Link, vf int, state uint32) error {
  625. return pkgHandle.LinkSetVfState(link, vf, state)
  626. }
  627. // LinkSetVfState enables/disables virtual link state on a vf.
  628. // Equivalent to: `ip link set $link vf $vf state $state`
  629. func (h *Handle) LinkSetVfState(link Link, vf int, state uint32) error {
  630. base := link.Attrs()
  631. h.ensureIndex(base)
  632. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  633. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  634. msg.Index = int32(base.Index)
  635. req.AddData(msg)
  636. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  637. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  638. vfmsg := nl.VfLinkState{
  639. Vf: uint32(vf),
  640. LinkState: state,
  641. }
  642. info.AddRtAttr(nl.IFLA_VF_LINK_STATE, vfmsg.Serialize())
  643. req.AddData(data)
  644. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  645. return err
  646. }
  647. // LinkSetVfSpoofchk enables/disables spoof check on a vf for the link.
  648. // Equivalent to: `ip link set $link vf $vf spoofchk $check`
  649. func LinkSetVfSpoofchk(link Link, vf int, check bool) error {
  650. return pkgHandle.LinkSetVfSpoofchk(link, vf, check)
  651. }
  652. // LinkSetVfSpoofchk enables/disables spoof check on a vf for the link.
  653. // Equivalent to: `ip link set $link vf $vf spoofchk $check`
  654. func (h *Handle) LinkSetVfSpoofchk(link Link, vf int, check bool) error {
  655. var setting uint32
  656. base := link.Attrs()
  657. h.ensureIndex(base)
  658. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  659. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  660. msg.Index = int32(base.Index)
  661. req.AddData(msg)
  662. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  663. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  664. if check {
  665. setting = 1
  666. }
  667. vfmsg := nl.VfSpoofchk{
  668. Vf: uint32(vf),
  669. Setting: setting,
  670. }
  671. info.AddRtAttr(nl.IFLA_VF_SPOOFCHK, vfmsg.Serialize())
  672. req.AddData(data)
  673. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  674. return err
  675. }
  676. // LinkSetVfTrust enables/disables trust state on a vf for the link.
  677. // Equivalent to: `ip link set $link vf $vf trust $state`
  678. func LinkSetVfTrust(link Link, vf int, state bool) error {
  679. return pkgHandle.LinkSetVfTrust(link, vf, state)
  680. }
  681. // LinkSetVfTrust enables/disables trust state on a vf for the link.
  682. // Equivalent to: `ip link set $link vf $vf trust $state`
  683. func (h *Handle) LinkSetVfTrust(link Link, vf int, state bool) error {
  684. var setting uint32
  685. base := link.Attrs()
  686. h.ensureIndex(base)
  687. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  688. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  689. msg.Index = int32(base.Index)
  690. req.AddData(msg)
  691. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  692. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  693. if state {
  694. setting = 1
  695. }
  696. vfmsg := nl.VfTrust{
  697. Vf: uint32(vf),
  698. Setting: setting,
  699. }
  700. info.AddRtAttr(nl.IFLA_VF_TRUST, vfmsg.Serialize())
  701. req.AddData(data)
  702. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  703. return err
  704. }
  705. // LinkSetVfNodeGUID sets the node GUID of a vf for the link.
  706. // Equivalent to: `ip link set dev $link vf $vf node_guid $nodeguid`
  707. func LinkSetVfNodeGUID(link Link, vf int, nodeguid net.HardwareAddr) error {
  708. return pkgHandle.LinkSetVfGUID(link, vf, nodeguid, nl.IFLA_VF_IB_NODE_GUID)
  709. }
  710. // LinkSetVfPortGUID sets the port GUID of a vf for the link.
  711. // Equivalent to: `ip link set dev $link vf $vf port_guid $portguid`
  712. func LinkSetVfPortGUID(link Link, vf int, portguid net.HardwareAddr) error {
  713. return pkgHandle.LinkSetVfGUID(link, vf, portguid, nl.IFLA_VF_IB_PORT_GUID)
  714. }
  715. // LinkSetVfGUID sets the node or port GUID of a vf for the link.
  716. func (h *Handle) LinkSetVfGUID(link Link, vf int, vfGuid net.HardwareAddr, guidType int) error {
  717. var err error
  718. var guid uint64
  719. buf := bytes.NewBuffer(vfGuid)
  720. err = binary.Read(buf, binary.BigEndian, &guid)
  721. if err != nil {
  722. return err
  723. }
  724. base := link.Attrs()
  725. h.ensureIndex(base)
  726. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  727. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  728. msg.Index = int32(base.Index)
  729. req.AddData(msg)
  730. data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
  731. info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
  732. vfmsg := nl.VfGUID{
  733. Vf: uint32(vf),
  734. GUID: guid,
  735. }
  736. info.AddRtAttr(guidType, vfmsg.Serialize())
  737. req.AddData(data)
  738. _, err = req.Execute(unix.NETLINK_ROUTE, 0)
  739. return err
  740. }
  741. // LinkSetMaster sets the master of the link device.
  742. // Equivalent to: `ip link set $link master $master`
  743. func LinkSetMaster(link Link, master Link) error {
  744. return pkgHandle.LinkSetMaster(link, master)
  745. }
  746. // LinkSetMaster sets the master of the link device.
  747. // Equivalent to: `ip link set $link master $master`
  748. func (h *Handle) LinkSetMaster(link Link, master Link) error {
  749. index := 0
  750. if master != nil {
  751. masterBase := master.Attrs()
  752. h.ensureIndex(masterBase)
  753. index = masterBase.Index
  754. }
  755. if index <= 0 {
  756. return fmt.Errorf("Device does not exist")
  757. }
  758. return h.LinkSetMasterByIndex(link, index)
  759. }
  760. // LinkSetNoMaster removes the master of the link device.
  761. // Equivalent to: `ip link set $link nomaster`
  762. func LinkSetNoMaster(link Link) error {
  763. return pkgHandle.LinkSetNoMaster(link)
  764. }
  765. // LinkSetNoMaster removes the master of the link device.
  766. // Equivalent to: `ip link set $link nomaster`
  767. func (h *Handle) LinkSetNoMaster(link Link) error {
  768. return h.LinkSetMasterByIndex(link, 0)
  769. }
  770. // LinkSetMasterByIndex sets the master of the link device.
  771. // Equivalent to: `ip link set $link master $master`
  772. func LinkSetMasterByIndex(link Link, masterIndex int) error {
  773. return pkgHandle.LinkSetMasterByIndex(link, masterIndex)
  774. }
  775. // LinkSetMasterByIndex sets the master of the link device.
  776. // Equivalent to: `ip link set $link master $master`
  777. func (h *Handle) LinkSetMasterByIndex(link Link, masterIndex int) error {
  778. base := link.Attrs()
  779. h.ensureIndex(base)
  780. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  781. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  782. msg.Index = int32(base.Index)
  783. req.AddData(msg)
  784. b := make([]byte, 4)
  785. native.PutUint32(b, uint32(masterIndex))
  786. data := nl.NewRtAttr(unix.IFLA_MASTER, b)
  787. req.AddData(data)
  788. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  789. return err
  790. }
  791. // LinkSetNsPid puts the device into a new network namespace. The
  792. // pid must be a pid of a running process.
  793. // Equivalent to: `ip link set $link netns $pid`
  794. func LinkSetNsPid(link Link, nspid int) error {
  795. return pkgHandle.LinkSetNsPid(link, nspid)
  796. }
  797. // LinkSetNsPid puts the device into a new network namespace. The
  798. // pid must be a pid of a running process.
  799. // Equivalent to: `ip link set $link netns $pid`
  800. func (h *Handle) LinkSetNsPid(link Link, nspid int) error {
  801. base := link.Attrs()
  802. h.ensureIndex(base)
  803. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  804. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  805. msg.Index = int32(base.Index)
  806. req.AddData(msg)
  807. b := make([]byte, 4)
  808. native.PutUint32(b, uint32(nspid))
  809. data := nl.NewRtAttr(unix.IFLA_NET_NS_PID, b)
  810. req.AddData(data)
  811. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  812. return err
  813. }
  814. // LinkSetNsFd puts the device into a new network namespace. The
  815. // fd must be an open file descriptor to a network namespace.
  816. // Similar to: `ip link set $link netns $ns`
  817. func LinkSetNsFd(link Link, fd int) error {
  818. return pkgHandle.LinkSetNsFd(link, fd)
  819. }
  820. // LinkSetNsFd puts the device into a new network namespace. The
  821. // fd must be an open file descriptor to a network namespace.
  822. // Similar to: `ip link set $link netns $ns`
  823. func (h *Handle) LinkSetNsFd(link Link, fd int) error {
  824. base := link.Attrs()
  825. h.ensureIndex(base)
  826. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  827. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  828. msg.Index = int32(base.Index)
  829. req.AddData(msg)
  830. b := make([]byte, 4)
  831. native.PutUint32(b, uint32(fd))
  832. data := nl.NewRtAttr(unix.IFLA_NET_NS_FD, b)
  833. req.AddData(data)
  834. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  835. return err
  836. }
  837. // LinkSetXdpFd adds a bpf function to the driver. The fd must be a bpf
  838. // program loaded with bpf(type=BPF_PROG_TYPE_XDP)
  839. func LinkSetXdpFd(link Link, fd int) error {
  840. return LinkSetXdpFdWithFlags(link, fd, 0)
  841. }
  842. // LinkSetXdpFdWithFlags adds a bpf function to the driver with the given
  843. // options. The fd must be a bpf program loaded with bpf(type=BPF_PROG_TYPE_XDP)
  844. func LinkSetXdpFdWithFlags(link Link, fd, flags int) error {
  845. base := link.Attrs()
  846. ensureIndex(base)
  847. req := nl.NewNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  848. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  849. msg.Index = int32(base.Index)
  850. req.AddData(msg)
  851. addXdpAttrs(&LinkXdp{Fd: fd, Flags: uint32(flags)}, req)
  852. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  853. return err
  854. }
  855. // LinkSetGSOMaxSegs sets the GSO maximum segment count of the link device.
  856. // Equivalent to: `ip link set $link gso_max_segs $maxSegs`
  857. func LinkSetGSOMaxSegs(link Link, maxSegs int) error {
  858. return pkgHandle.LinkSetGSOMaxSegs(link, maxSegs)
  859. }
  860. // LinkSetGSOMaxSegs sets the GSO maximum segment count of the link device.
  861. // Equivalent to: `ip link set $link gso_max_segs $maxSegs`
  862. func (h *Handle) LinkSetGSOMaxSegs(link Link, maxSize int) error {
  863. base := link.Attrs()
  864. h.ensureIndex(base)
  865. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  866. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  867. msg.Index = int32(base.Index)
  868. req.AddData(msg)
  869. b := make([]byte, 4)
  870. native.PutUint32(b, uint32(maxSize))
  871. data := nl.NewRtAttr(unix.IFLA_GSO_MAX_SEGS, b)
  872. req.AddData(data)
  873. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  874. return err
  875. }
  876. // LinkSetGSOMaxSize sets the IPv6 GSO maximum size of the link device.
  877. // Equivalent to: `ip link set $link gso_max_size $maxSize`
  878. func LinkSetGSOMaxSize(link Link, maxSize int) error {
  879. return pkgHandle.LinkSetGSOMaxSize(link, maxSize)
  880. }
  881. // LinkSetGSOMaxSize sets the IPv6 GSO maximum size of the link device.
  882. // Equivalent to: `ip link set $link gso_max_size $maxSize`
  883. func (h *Handle) LinkSetGSOMaxSize(link Link, maxSize int) error {
  884. base := link.Attrs()
  885. h.ensureIndex(base)
  886. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  887. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  888. msg.Index = int32(base.Index)
  889. req.AddData(msg)
  890. b := make([]byte, 4)
  891. native.PutUint32(b, uint32(maxSize))
  892. data := nl.NewRtAttr(unix.IFLA_GSO_MAX_SIZE, b)
  893. req.AddData(data)
  894. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  895. return err
  896. }
  897. // LinkSetGROMaxSize sets the IPv6 GRO maximum size of the link device.
  898. // Equivalent to: `ip link set $link gro_max_size $maxSize`
  899. func LinkSetGROMaxSize(link Link, maxSize int) error {
  900. return pkgHandle.LinkSetGROMaxSize(link, maxSize)
  901. }
  902. // LinkSetGROMaxSize sets the IPv6 GRO maximum size of the link device.
  903. // Equivalent to: `ip link set $link gro_max_size $maxSize`
  904. func (h *Handle) LinkSetGROMaxSize(link Link, maxSize int) error {
  905. base := link.Attrs()
  906. h.ensureIndex(base)
  907. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  908. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  909. msg.Index = int32(base.Index)
  910. req.AddData(msg)
  911. b := make([]byte, 4)
  912. native.PutUint32(b, uint32(maxSize))
  913. data := nl.NewRtAttr(unix.IFLA_GRO_MAX_SIZE, b)
  914. req.AddData(data)
  915. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  916. return err
  917. }
  918. // LinkSetGSOIPv4MaxSize sets the IPv4 GSO maximum size of the link device.
  919. // Equivalent to: `ip link set $link gso_ipv4_max_size $maxSize`
  920. func LinkSetGSOIPv4MaxSize(link Link, maxSize int) error {
  921. return pkgHandle.LinkSetGSOIPv4MaxSize(link, maxSize)
  922. }
  923. // LinkSetGSOIPv4MaxSize sets the IPv4 GSO maximum size of the link device.
  924. // Equivalent to: `ip link set $link gso_ipv4_max_size $maxSize`
  925. func (h *Handle) LinkSetGSOIPv4MaxSize(link Link, maxSize int) error {
  926. base := link.Attrs()
  927. h.ensureIndex(base)
  928. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  929. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  930. msg.Index = int32(base.Index)
  931. req.AddData(msg)
  932. b := make([]byte, 4)
  933. native.PutUint32(b, uint32(maxSize))
  934. data := nl.NewRtAttr(unix.IFLA_GSO_IPV4_MAX_SIZE, b)
  935. req.AddData(data)
  936. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  937. return err
  938. }
  939. // LinkSetGROIPv4MaxSize sets the IPv4 GRO maximum size of the link device.
  940. // Equivalent to: `ip link set $link gro_ipv4_max_size $maxSize`
  941. func LinkSetGROIPv4MaxSize(link Link, maxSize int) error {
  942. return pkgHandle.LinkSetGROIPv4MaxSize(link, maxSize)
  943. }
  944. // LinkSetGROIPv4MaxSize sets the IPv4 GRO maximum size of the link device.
  945. // Equivalent to: `ip link set $link gro_ipv4_max_size $maxSize`
  946. func (h *Handle) LinkSetGROIPv4MaxSize(link Link, maxSize int) error {
  947. base := link.Attrs()
  948. h.ensureIndex(base)
  949. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  950. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  951. msg.Index = int32(base.Index)
  952. req.AddData(msg)
  953. b := make([]byte, 4)
  954. native.PutUint32(b, uint32(maxSize))
  955. data := nl.NewRtAttr(unix.IFLA_GRO_IPV4_MAX_SIZE, b)
  956. req.AddData(data)
  957. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  958. return err
  959. }
  960. func boolAttr(val bool) []byte {
  961. var v uint8
  962. if val {
  963. v = 1
  964. }
  965. return nl.Uint8Attr(v)
  966. }
  967. type vxlanPortRange struct {
  968. Lo, Hi uint16
  969. }
  970. func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
  971. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  972. if vxlan.FlowBased {
  973. vxlan.VxlanId = 0
  974. }
  975. data.AddRtAttr(nl.IFLA_VXLAN_ID, nl.Uint32Attr(uint32(vxlan.VxlanId)))
  976. if vxlan.VtepDevIndex != 0 {
  977. data.AddRtAttr(nl.IFLA_VXLAN_LINK, nl.Uint32Attr(uint32(vxlan.VtepDevIndex)))
  978. }
  979. if vxlan.SrcAddr != nil {
  980. ip := vxlan.SrcAddr.To4()
  981. if ip != nil {
  982. data.AddRtAttr(nl.IFLA_VXLAN_LOCAL, []byte(ip))
  983. } else {
  984. ip = vxlan.SrcAddr.To16()
  985. if ip != nil {
  986. data.AddRtAttr(nl.IFLA_VXLAN_LOCAL6, []byte(ip))
  987. }
  988. }
  989. }
  990. if vxlan.Group != nil {
  991. group := vxlan.Group.To4()
  992. if group != nil {
  993. data.AddRtAttr(nl.IFLA_VXLAN_GROUP, []byte(group))
  994. } else {
  995. group = vxlan.Group.To16()
  996. if group != nil {
  997. data.AddRtAttr(nl.IFLA_VXLAN_GROUP6, []byte(group))
  998. }
  999. }
  1000. }
  1001. data.AddRtAttr(nl.IFLA_VXLAN_TTL, nl.Uint8Attr(uint8(vxlan.TTL)))
  1002. data.AddRtAttr(nl.IFLA_VXLAN_TOS, nl.Uint8Attr(uint8(vxlan.TOS)))
  1003. data.AddRtAttr(nl.IFLA_VXLAN_LEARNING, boolAttr(vxlan.Learning))
  1004. data.AddRtAttr(nl.IFLA_VXLAN_PROXY, boolAttr(vxlan.Proxy))
  1005. data.AddRtAttr(nl.IFLA_VXLAN_RSC, boolAttr(vxlan.RSC))
  1006. data.AddRtAttr(nl.IFLA_VXLAN_L2MISS, boolAttr(vxlan.L2miss))
  1007. data.AddRtAttr(nl.IFLA_VXLAN_L3MISS, boolAttr(vxlan.L3miss))
  1008. data.AddRtAttr(nl.IFLA_VXLAN_UDP_ZERO_CSUM6_TX, boolAttr(vxlan.UDP6ZeroCSumTx))
  1009. data.AddRtAttr(nl.IFLA_VXLAN_UDP_ZERO_CSUM6_RX, boolAttr(vxlan.UDP6ZeroCSumRx))
  1010. if vxlan.UDPCSum {
  1011. data.AddRtAttr(nl.IFLA_VXLAN_UDP_CSUM, boolAttr(vxlan.UDPCSum))
  1012. }
  1013. if vxlan.GBP {
  1014. data.AddRtAttr(nl.IFLA_VXLAN_GBP, []byte{})
  1015. }
  1016. if vxlan.FlowBased {
  1017. data.AddRtAttr(nl.IFLA_VXLAN_FLOWBASED, boolAttr(vxlan.FlowBased))
  1018. }
  1019. if vxlan.NoAge {
  1020. data.AddRtAttr(nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(0))
  1021. } else if vxlan.Age > 0 {
  1022. data.AddRtAttr(nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(uint32(vxlan.Age)))
  1023. }
  1024. if vxlan.Limit > 0 {
  1025. data.AddRtAttr(nl.IFLA_VXLAN_LIMIT, nl.Uint32Attr(uint32(vxlan.Limit)))
  1026. }
  1027. if vxlan.Port > 0 {
  1028. data.AddRtAttr(nl.IFLA_VXLAN_PORT, htons(uint16(vxlan.Port)))
  1029. }
  1030. if vxlan.PortLow > 0 || vxlan.PortHigh > 0 {
  1031. pr := vxlanPortRange{uint16(vxlan.PortLow), uint16(vxlan.PortHigh)}
  1032. buf := new(bytes.Buffer)
  1033. binary.Write(buf, binary.BigEndian, &pr)
  1034. data.AddRtAttr(nl.IFLA_VXLAN_PORT_RANGE, buf.Bytes())
  1035. }
  1036. }
  1037. func addBondAttrs(bond *Bond, linkInfo *nl.RtAttr) {
  1038. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  1039. if bond.Mode >= 0 {
  1040. data.AddRtAttr(nl.IFLA_BOND_MODE, nl.Uint8Attr(uint8(bond.Mode)))
  1041. }
  1042. if bond.ActiveSlave >= 0 {
  1043. data.AddRtAttr(nl.IFLA_BOND_ACTIVE_SLAVE, nl.Uint32Attr(uint32(bond.ActiveSlave)))
  1044. }
  1045. if bond.Miimon >= 0 {
  1046. data.AddRtAttr(nl.IFLA_BOND_MIIMON, nl.Uint32Attr(uint32(bond.Miimon)))
  1047. }
  1048. if bond.UpDelay >= 0 {
  1049. data.AddRtAttr(nl.IFLA_BOND_UPDELAY, nl.Uint32Attr(uint32(bond.UpDelay)))
  1050. }
  1051. if bond.DownDelay >= 0 {
  1052. data.AddRtAttr(nl.IFLA_BOND_DOWNDELAY, nl.Uint32Attr(uint32(bond.DownDelay)))
  1053. }
  1054. if bond.UseCarrier >= 0 {
  1055. data.AddRtAttr(nl.IFLA_BOND_USE_CARRIER, nl.Uint8Attr(uint8(bond.UseCarrier)))
  1056. }
  1057. if bond.ArpInterval >= 0 {
  1058. data.AddRtAttr(nl.IFLA_BOND_ARP_INTERVAL, nl.Uint32Attr(uint32(bond.ArpInterval)))
  1059. }
  1060. if bond.ArpIpTargets != nil {
  1061. msg := data.AddRtAttr(nl.IFLA_BOND_ARP_IP_TARGET, nil)
  1062. for i := range bond.ArpIpTargets {
  1063. ip := bond.ArpIpTargets[i].To4()
  1064. if ip != nil {
  1065. msg.AddRtAttr(i, []byte(ip))
  1066. continue
  1067. }
  1068. ip = bond.ArpIpTargets[i].To16()
  1069. if ip != nil {
  1070. msg.AddRtAttr(i, []byte(ip))
  1071. }
  1072. }
  1073. }
  1074. if bond.ArpValidate >= 0 {
  1075. data.AddRtAttr(nl.IFLA_BOND_ARP_VALIDATE, nl.Uint32Attr(uint32(bond.ArpValidate)))
  1076. }
  1077. if bond.ArpAllTargets >= 0 {
  1078. data.AddRtAttr(nl.IFLA_BOND_ARP_ALL_TARGETS, nl.Uint32Attr(uint32(bond.ArpAllTargets)))
  1079. }
  1080. if bond.Primary >= 0 {
  1081. data.AddRtAttr(nl.IFLA_BOND_PRIMARY, nl.Uint32Attr(uint32(bond.Primary)))
  1082. }
  1083. if bond.PrimaryReselect >= 0 {
  1084. data.AddRtAttr(nl.IFLA_BOND_PRIMARY_RESELECT, nl.Uint8Attr(uint8(bond.PrimaryReselect)))
  1085. }
  1086. if bond.FailOverMac >= 0 {
  1087. data.AddRtAttr(nl.IFLA_BOND_FAIL_OVER_MAC, nl.Uint8Attr(uint8(bond.FailOverMac)))
  1088. }
  1089. if bond.XmitHashPolicy >= 0 {
  1090. data.AddRtAttr(nl.IFLA_BOND_XMIT_HASH_POLICY, nl.Uint8Attr(uint8(bond.XmitHashPolicy)))
  1091. }
  1092. if bond.ResendIgmp >= 0 {
  1093. data.AddRtAttr(nl.IFLA_BOND_RESEND_IGMP, nl.Uint32Attr(uint32(bond.ResendIgmp)))
  1094. }
  1095. if bond.NumPeerNotif >= 0 {
  1096. data.AddRtAttr(nl.IFLA_BOND_NUM_PEER_NOTIF, nl.Uint8Attr(uint8(bond.NumPeerNotif)))
  1097. }
  1098. if bond.AllSlavesActive >= 0 {
  1099. data.AddRtAttr(nl.IFLA_BOND_ALL_SLAVES_ACTIVE, nl.Uint8Attr(uint8(bond.AllSlavesActive)))
  1100. }
  1101. if bond.MinLinks >= 0 {
  1102. data.AddRtAttr(nl.IFLA_BOND_MIN_LINKS, nl.Uint32Attr(uint32(bond.MinLinks)))
  1103. }
  1104. if bond.LpInterval >= 0 {
  1105. data.AddRtAttr(nl.IFLA_BOND_LP_INTERVAL, nl.Uint32Attr(uint32(bond.LpInterval)))
  1106. }
  1107. if bond.PacketsPerSlave >= 0 {
  1108. data.AddRtAttr(nl.IFLA_BOND_PACKETS_PER_SLAVE, nl.Uint32Attr(uint32(bond.PacketsPerSlave)))
  1109. }
  1110. if bond.LacpRate >= 0 {
  1111. data.AddRtAttr(nl.IFLA_BOND_AD_LACP_RATE, nl.Uint8Attr(uint8(bond.LacpRate)))
  1112. }
  1113. if bond.AdSelect >= 0 {
  1114. data.AddRtAttr(nl.IFLA_BOND_AD_SELECT, nl.Uint8Attr(uint8(bond.AdSelect)))
  1115. }
  1116. if bond.AdActorSysPrio >= 0 {
  1117. data.AddRtAttr(nl.IFLA_BOND_AD_ACTOR_SYS_PRIO, nl.Uint16Attr(uint16(bond.AdActorSysPrio)))
  1118. }
  1119. if bond.AdUserPortKey >= 0 {
  1120. data.AddRtAttr(nl.IFLA_BOND_AD_USER_PORT_KEY, nl.Uint16Attr(uint16(bond.AdUserPortKey)))
  1121. }
  1122. if bond.AdActorSystem != nil {
  1123. data.AddRtAttr(nl.IFLA_BOND_AD_ACTOR_SYSTEM, []byte(bond.AdActorSystem))
  1124. }
  1125. if bond.TlbDynamicLb >= 0 {
  1126. data.AddRtAttr(nl.IFLA_BOND_TLB_DYNAMIC_LB, nl.Uint8Attr(uint8(bond.TlbDynamicLb)))
  1127. }
  1128. }
  1129. func cleanupFds(fds []*os.File) {
  1130. for _, f := range fds {
  1131. f.Close()
  1132. }
  1133. }
  1134. // LinkAdd adds a new link device. The type and features of the device
  1135. // are taken from the parameters in the link object.
  1136. // Equivalent to: `ip link add $link`
  1137. func LinkAdd(link Link) error {
  1138. return pkgHandle.LinkAdd(link)
  1139. }
  1140. // LinkAdd adds a new link device. The type and features of the device
  1141. // are taken from the parameters in the link object.
  1142. // Equivalent to: `ip link add $link`
  1143. func (h *Handle) LinkAdd(link Link) error {
  1144. return h.linkModify(link, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
  1145. }
  1146. func LinkModify(link Link) error {
  1147. return pkgHandle.LinkModify(link)
  1148. }
  1149. func (h *Handle) LinkModify(link Link) error {
  1150. return h.linkModify(link, unix.NLM_F_REQUEST|unix.NLM_F_ACK)
  1151. }
  1152. func (h *Handle) linkModify(link Link, flags int) error {
  1153. // TODO: support extra data for macvlan
  1154. base := link.Attrs()
  1155. // if tuntap, then the name can be empty, OS will provide a name
  1156. tuntap, isTuntap := link.(*Tuntap)
  1157. if base.Name == "" && !isTuntap {
  1158. return fmt.Errorf("LinkAttrs.Name cannot be empty")
  1159. }
  1160. if isTuntap {
  1161. if tuntap.Mode < unix.IFF_TUN || tuntap.Mode > unix.IFF_TAP {
  1162. return fmt.Errorf("Tuntap.Mode %v unknown", tuntap.Mode)
  1163. }
  1164. queues := tuntap.Queues
  1165. var fds []*os.File
  1166. var req ifReq
  1167. copy(req.Name[:15], base.Name)
  1168. req.Flags = uint16(tuntap.Flags)
  1169. if queues == 0 { //Legacy compatibility
  1170. queues = 1
  1171. if tuntap.Flags == 0 {
  1172. req.Flags = uint16(TUNTAP_DEFAULTS)
  1173. }
  1174. } else {
  1175. // For best peformance set Flags to TUNTAP_MULTI_QUEUE_DEFAULTS | TUNTAP_VNET_HDR
  1176. // when a) KVM has support for this ABI and
  1177. // b) the value of the flag is queryable using the TUNGETIFF ioctl
  1178. if tuntap.Flags == 0 {
  1179. req.Flags = uint16(TUNTAP_MULTI_QUEUE_DEFAULTS)
  1180. }
  1181. }
  1182. req.Flags |= uint16(tuntap.Mode)
  1183. const TUN = "/dev/net/tun"
  1184. for i := 0; i < queues; i++ {
  1185. localReq := req
  1186. fd, err := unix.Open(TUN, os.O_RDWR|syscall.O_CLOEXEC, 0)
  1187. if err != nil {
  1188. cleanupFds(fds)
  1189. return err
  1190. }
  1191. _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(unix.TUNSETIFF), uintptr(unsafe.Pointer(&localReq)))
  1192. if errno != 0 {
  1193. // close the new fd
  1194. unix.Close(fd)
  1195. // and the already opened ones
  1196. cleanupFds(fds)
  1197. return fmt.Errorf("Tuntap IOCTL TUNSETIFF failed [%d], errno %v", i, errno)
  1198. }
  1199. _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TUNSETOWNER, uintptr(tuntap.Owner))
  1200. if errno != 0 {
  1201. cleanupFds(fds)
  1202. return fmt.Errorf("Tuntap IOCTL TUNSETOWNER failed [%d], errno %v", i, errno)
  1203. }
  1204. _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TUNSETGROUP, uintptr(tuntap.Group))
  1205. if errno != 0 {
  1206. cleanupFds(fds)
  1207. return fmt.Errorf("Tuntap IOCTL TUNSETGROUP failed [%d], errno %v", i, errno)
  1208. }
  1209. // Set the tun device to non-blocking before use. The below comment
  1210. // taken from:
  1211. //
  1212. // https://github.com/mistsys/tuntap/commit/161418c25003bbee77d085a34af64d189df62bea
  1213. //
  1214. // Note there is a complication because in go, if a device node is
  1215. // opened, go sets it to use nonblocking I/O. However a /dev/net/tun
  1216. // doesn't work with epoll until after the TUNSETIFF ioctl has been
  1217. // done. So we open the unix fd directly, do the ioctl, then put the
  1218. // fd in nonblocking mode, an then finally wrap it in a os.File,
  1219. // which will see the nonblocking mode and add the fd to the
  1220. // pollable set, so later on when we Read() from it blocked the
  1221. // calling thread in the kernel.
  1222. //
  1223. // See
  1224. // https://github.com/golang/go/issues/30426
  1225. // which got exposed in go 1.13 by the fix to
  1226. // https://github.com/golang/go/issues/30624
  1227. err = unix.SetNonblock(fd, true)
  1228. if err != nil {
  1229. cleanupFds(fds)
  1230. return fmt.Errorf("Tuntap set to non-blocking failed [%d], err %v", i, err)
  1231. }
  1232. // create the file from the file descriptor and store it
  1233. file := os.NewFile(uintptr(fd), TUN)
  1234. fds = append(fds, file)
  1235. // 1) we only care for the name of the first tap in the multi queue set
  1236. // 2) if the original name was empty, the localReq has now the actual name
  1237. //
  1238. // In addition:
  1239. // This ensures that the link name is always identical to what the kernel returns.
  1240. // Not only in case of an empty name, but also when using name templates.
  1241. // e.g. when the provided name is "tap%d", the kernel replaces %d with the next available number.
  1242. if i == 0 {
  1243. link.Attrs().Name = strings.Trim(string(localReq.Name[:]), "\x00")
  1244. }
  1245. }
  1246. control := func(file *os.File, f func(fd uintptr)) error {
  1247. name := file.Name()
  1248. conn, err := file.SyscallConn()
  1249. if err != nil {
  1250. return fmt.Errorf("SyscallConn() failed on %s: %v", name, err)
  1251. }
  1252. if err := conn.Control(f); err != nil {
  1253. return fmt.Errorf("Failed to get file descriptor for %s: %v", name, err)
  1254. }
  1255. return nil
  1256. }
  1257. // only persist interface if NonPersist is NOT set
  1258. if !tuntap.NonPersist {
  1259. var errno syscall.Errno
  1260. if err := control(fds[0], func(fd uintptr) {
  1261. _, _, errno = unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TUNSETPERSIST), 1)
  1262. }); err != nil {
  1263. return err
  1264. }
  1265. if errno != 0 {
  1266. cleanupFds(fds)
  1267. return fmt.Errorf("Tuntap IOCTL TUNSETPERSIST failed, errno %v", errno)
  1268. }
  1269. }
  1270. h.ensureIndex(base)
  1271. // can't set master during create, so set it afterwards
  1272. if base.MasterIndex != 0 {
  1273. // TODO: verify MasterIndex is actually a bridge?
  1274. err := h.LinkSetMasterByIndex(link, base.MasterIndex)
  1275. if err != nil {
  1276. // un-persist (e.g. allow the interface to be removed) the tuntap
  1277. // should not hurt if not set prior, condition might be not needed
  1278. if !tuntap.NonPersist {
  1279. // ignore error
  1280. _ = control(fds[0], func(fd uintptr) {
  1281. _, _, _ = unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TUNSETPERSIST), 0)
  1282. })
  1283. }
  1284. cleanupFds(fds)
  1285. return err
  1286. }
  1287. }
  1288. if tuntap.Queues == 0 {
  1289. cleanupFds(fds)
  1290. } else {
  1291. tuntap.Fds = fds
  1292. }
  1293. return nil
  1294. }
  1295. req := h.newNetlinkRequest(unix.RTM_NEWLINK, flags)
  1296. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  1297. // TODO: make it shorter
  1298. if base.Flags&net.FlagUp != 0 {
  1299. msg.Change = unix.IFF_UP
  1300. msg.Flags = unix.IFF_UP
  1301. }
  1302. if base.Flags&net.FlagBroadcast != 0 {
  1303. msg.Change |= unix.IFF_BROADCAST
  1304. msg.Flags |= unix.IFF_BROADCAST
  1305. }
  1306. if base.Flags&net.FlagLoopback != 0 {
  1307. msg.Change |= unix.IFF_LOOPBACK
  1308. msg.Flags |= unix.IFF_LOOPBACK
  1309. }
  1310. if base.Flags&net.FlagPointToPoint != 0 {
  1311. msg.Change |= unix.IFF_POINTOPOINT
  1312. msg.Flags |= unix.IFF_POINTOPOINT
  1313. }
  1314. if base.Flags&net.FlagMulticast != 0 {
  1315. msg.Change |= unix.IFF_MULTICAST
  1316. msg.Flags |= unix.IFF_MULTICAST
  1317. }
  1318. if base.Index != 0 {
  1319. msg.Index = int32(base.Index)
  1320. }
  1321. req.AddData(msg)
  1322. if base.ParentIndex != 0 {
  1323. b := make([]byte, 4)
  1324. native.PutUint32(b, uint32(base.ParentIndex))
  1325. data := nl.NewRtAttr(unix.IFLA_LINK, b)
  1326. req.AddData(data)
  1327. } else if link.Type() == "ipvlan" || link.Type() == "ipoib" {
  1328. return fmt.Errorf("Can't create %s link without ParentIndex", link.Type())
  1329. }
  1330. nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(base.Name))
  1331. req.AddData(nameData)
  1332. if base.Alias != "" {
  1333. alias := nl.NewRtAttr(unix.IFLA_IFALIAS, []byte(base.Alias))
  1334. req.AddData(alias)
  1335. }
  1336. if base.MTU > 0 {
  1337. mtu := nl.NewRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU)))
  1338. req.AddData(mtu)
  1339. }
  1340. if base.TxQLen >= 0 {
  1341. qlen := nl.NewRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen)))
  1342. req.AddData(qlen)
  1343. }
  1344. if base.HardwareAddr != nil {
  1345. hwaddr := nl.NewRtAttr(unix.IFLA_ADDRESS, []byte(base.HardwareAddr))
  1346. req.AddData(hwaddr)
  1347. }
  1348. if base.NumTxQueues > 0 {
  1349. txqueues := nl.NewRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(uint32(base.NumTxQueues)))
  1350. req.AddData(txqueues)
  1351. }
  1352. if base.NumRxQueues > 0 {
  1353. rxqueues := nl.NewRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(uint32(base.NumRxQueues)))
  1354. req.AddData(rxqueues)
  1355. }
  1356. if base.GSOMaxSegs > 0 {
  1357. gsoAttr := nl.NewRtAttr(unix.IFLA_GSO_MAX_SEGS, nl.Uint32Attr(base.GSOMaxSegs))
  1358. req.AddData(gsoAttr)
  1359. }
  1360. if base.GSOMaxSize > 0 {
  1361. gsoAttr := nl.NewRtAttr(unix.IFLA_GSO_MAX_SIZE, nl.Uint32Attr(base.GSOMaxSize))
  1362. req.AddData(gsoAttr)
  1363. }
  1364. if base.GROMaxSize > 0 {
  1365. groAttr := nl.NewRtAttr(unix.IFLA_GRO_MAX_SIZE, nl.Uint32Attr(base.GROMaxSize))
  1366. req.AddData(groAttr)
  1367. }
  1368. if base.GSOIPv4MaxSize > 0 {
  1369. gsoAttr := nl.NewRtAttr(unix.IFLA_GSO_IPV4_MAX_SIZE, nl.Uint32Attr(base.GSOIPv4MaxSize))
  1370. req.AddData(gsoAttr)
  1371. }
  1372. if base.GROIPv4MaxSize > 0 {
  1373. groAttr := nl.NewRtAttr(unix.IFLA_GRO_IPV4_MAX_SIZE, nl.Uint32Attr(base.GROIPv4MaxSize))
  1374. req.AddData(groAttr)
  1375. }
  1376. if base.Group > 0 {
  1377. groupAttr := nl.NewRtAttr(unix.IFLA_GROUP, nl.Uint32Attr(base.Group))
  1378. req.AddData(groupAttr)
  1379. }
  1380. if base.Namespace != nil {
  1381. var attr *nl.RtAttr
  1382. switch ns := base.Namespace.(type) {
  1383. case NsPid:
  1384. val := nl.Uint32Attr(uint32(ns))
  1385. attr = nl.NewRtAttr(unix.IFLA_NET_NS_PID, val)
  1386. case NsFd:
  1387. val := nl.Uint32Attr(uint32(ns))
  1388. attr = nl.NewRtAttr(unix.IFLA_NET_NS_FD, val)
  1389. }
  1390. req.AddData(attr)
  1391. }
  1392. if base.Xdp != nil {
  1393. addXdpAttrs(base.Xdp, req)
  1394. }
  1395. linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil)
  1396. linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type()))
  1397. switch link := link.(type) {
  1398. case *Vlan:
  1399. b := make([]byte, 2)
  1400. native.PutUint16(b, uint16(link.VlanId))
  1401. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  1402. data.AddRtAttr(nl.IFLA_VLAN_ID, b)
  1403. var vlanFlags uint32
  1404. var vlanFlagsMask uint32
  1405. if link.ReorderHdr != nil {
  1406. vlanFlagsMask |= nl.VLAN_FLAG_REORDER_HDR
  1407. if *link.ReorderHdr {
  1408. vlanFlags |= nl.VLAN_FLAG_REORDER_HDR
  1409. } else {
  1410. vlanFlags &= ^uint32(nl.VLAN_FLAG_REORDER_HDR)
  1411. }
  1412. }
  1413. if link.Gvrp != nil {
  1414. vlanFlagsMask |= nl.VLAN_FLAG_GVRP
  1415. if *link.Gvrp {
  1416. vlanFlags |= nl.VLAN_FLAG_GVRP
  1417. } else {
  1418. vlanFlags &= ^uint32(nl.VLAN_FLAG_GVRP)
  1419. }
  1420. }
  1421. if link.Mvrp != nil {
  1422. vlanFlagsMask |= nl.VLAN_FLAG_MVRP
  1423. if *link.Mvrp {
  1424. vlanFlags |= nl.VLAN_FLAG_MVRP
  1425. } else {
  1426. vlanFlags &= ^uint32(nl.VLAN_FLAG_MVRP)
  1427. }
  1428. }
  1429. if link.LooseBinding != nil {
  1430. vlanFlagsMask |= nl.VLAN_FLAG_LOOSE_BINDING
  1431. if *link.LooseBinding {
  1432. vlanFlags |= nl.VLAN_FLAG_LOOSE_BINDING
  1433. } else {
  1434. vlanFlags &= ^uint32(nl.VLAN_FLAG_LOOSE_BINDING)
  1435. }
  1436. }
  1437. if link.BridgeBinding != nil {
  1438. vlanFlagsMask |= nl.VLAN_FLAG_BRIDGE_BINDING
  1439. if *link.BridgeBinding {
  1440. vlanFlags |= nl.VLAN_FLAG_BRIDGE_BINDING
  1441. } else {
  1442. vlanFlags &= ^uint32(nl.VLAN_FLAG_BRIDGE_BINDING)
  1443. }
  1444. }
  1445. buf := &bytes.Buffer{}
  1446. buf.Write(nl.Uint32Attr(vlanFlags))
  1447. buf.Write(nl.Uint32Attr(vlanFlagsMask))
  1448. data.AddRtAttr(nl.IFLA_VLAN_FLAGS, buf.Bytes())
  1449. if link.IngressQosMap != nil {
  1450. ingressMap := data.AddRtAttr(nl.IFLA_VLAN_INGRESS_QOS, nil)
  1451. for from, to := range link.IngressQosMap {
  1452. buf := &bytes.Buffer{}
  1453. buf.Write(nl.Uint32Attr(from))
  1454. buf.Write(nl.Uint32Attr(to))
  1455. ingressMap.AddRtAttr(nl.IFLA_VLAN_QOS_MAPPING, buf.Bytes())
  1456. }
  1457. }
  1458. if link.EgressQosMap != nil {
  1459. egressMap := data.AddRtAttr(nl.IFLA_VLAN_EGRESS_QOS, nil)
  1460. for from, to := range link.EgressQosMap {
  1461. buf := &bytes.Buffer{}
  1462. buf.Write(nl.Uint32Attr(from))
  1463. buf.Write(nl.Uint32Attr(to))
  1464. egressMap.AddRtAttr(nl.IFLA_VLAN_QOS_MAPPING, buf.Bytes())
  1465. }
  1466. }
  1467. if link.VlanProtocol != VLAN_PROTOCOL_UNKNOWN {
  1468. data.AddRtAttr(nl.IFLA_VLAN_PROTOCOL, htons(uint16(link.VlanProtocol)))
  1469. }
  1470. case *Netkit:
  1471. if err := addNetkitAttrs(link, linkInfo, flags); err != nil {
  1472. return err
  1473. }
  1474. case *Veth:
  1475. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  1476. peer := data.AddRtAttr(nl.VETH_INFO_PEER, nil)
  1477. nl.NewIfInfomsgChild(peer, unix.AF_UNSPEC)
  1478. peer.AddRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(link.PeerName))
  1479. if link.PeerTxQLen >= 0 {
  1480. peer.AddRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(link.PeerTxQLen)))
  1481. } else if base.TxQLen >= 0 {
  1482. peer.AddRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen)))
  1483. }
  1484. if link.PeerNumTxQueues > 0 {
  1485. peer.AddRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(link.PeerNumTxQueues))
  1486. } else if base.NumTxQueues > 0 {
  1487. peer.AddRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(uint32(base.NumTxQueues)))
  1488. }
  1489. if link.PeerNumRxQueues > 0 {
  1490. peer.AddRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(link.PeerNumRxQueues))
  1491. } else if base.NumRxQueues > 0 {
  1492. peer.AddRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(uint32(base.NumRxQueues)))
  1493. }
  1494. if link.PeerMTU > 0 {
  1495. peer.AddRtAttr(unix.IFLA_MTU, nl.Uint32Attr(link.PeerMTU))
  1496. } else if base.MTU > 0 {
  1497. peer.AddRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU)))
  1498. }
  1499. if link.PeerHardwareAddr != nil {
  1500. peer.AddRtAttr(unix.IFLA_ADDRESS, []byte(link.PeerHardwareAddr))
  1501. }
  1502. if link.PeerNamespace != nil {
  1503. switch ns := link.PeerNamespace.(type) {
  1504. case NsPid:
  1505. val := nl.Uint32Attr(uint32(ns))
  1506. peer.AddRtAttr(unix.IFLA_NET_NS_PID, val)
  1507. case NsFd:
  1508. val := nl.Uint32Attr(uint32(ns))
  1509. peer.AddRtAttr(unix.IFLA_NET_NS_FD, val)
  1510. }
  1511. }
  1512. case *Vxlan:
  1513. addVxlanAttrs(link, linkInfo)
  1514. case *Bond:
  1515. addBondAttrs(link, linkInfo)
  1516. case *IPVlan:
  1517. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  1518. data.AddRtAttr(nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(link.Mode)))
  1519. data.AddRtAttr(nl.IFLA_IPVLAN_FLAG, nl.Uint16Attr(uint16(link.Flag)))
  1520. case *IPVtap:
  1521. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  1522. data.AddRtAttr(nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(link.Mode)))
  1523. data.AddRtAttr(nl.IFLA_IPVLAN_FLAG, nl.Uint16Attr(uint16(link.Flag)))
  1524. case *Macvlan:
  1525. addMacvlanAttrs(link, linkInfo)
  1526. case *Macvtap:
  1527. addMacvtapAttrs(link, linkInfo)
  1528. case *Geneve:
  1529. addGeneveAttrs(link, linkInfo)
  1530. case *Gretap:
  1531. addGretapAttrs(link, linkInfo)
  1532. case *Iptun:
  1533. addIptunAttrs(link, linkInfo)
  1534. case *Ip6tnl:
  1535. addIp6tnlAttrs(link, linkInfo)
  1536. case *Sittun:
  1537. addSittunAttrs(link, linkInfo)
  1538. case *Gretun:
  1539. addGretunAttrs(link, linkInfo)
  1540. case *Vti:
  1541. addVtiAttrs(link, linkInfo)
  1542. case *Vrf:
  1543. addVrfAttrs(link, linkInfo)
  1544. case *Bridge:
  1545. addBridgeAttrs(link, linkInfo)
  1546. case *GTP:
  1547. addGTPAttrs(link, linkInfo)
  1548. case *Xfrmi:
  1549. addXfrmiAttrs(link, linkInfo)
  1550. case *IPoIB:
  1551. addIPoIBAttrs(link, linkInfo)
  1552. case *BareUDP:
  1553. addBareUDPAttrs(link, linkInfo)
  1554. }
  1555. req.AddData(linkInfo)
  1556. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  1557. if err != nil {
  1558. return err
  1559. }
  1560. h.ensureIndex(base)
  1561. // can't set master during create, so set it afterwards
  1562. if base.MasterIndex != 0 {
  1563. // TODO: verify MasterIndex is actually a bridge?
  1564. return h.LinkSetMasterByIndex(link, base.MasterIndex)
  1565. }
  1566. return nil
  1567. }
  1568. // LinkDel deletes link device. Either Index or Name must be set in
  1569. // the link object for it to be deleted. The other values are ignored.
  1570. // Equivalent to: `ip link del $link`
  1571. func LinkDel(link Link) error {
  1572. return pkgHandle.LinkDel(link)
  1573. }
  1574. // LinkDel deletes link device. Either Index or Name must be set in
  1575. // the link object for it to be deleted. The other values are ignored.
  1576. // Equivalent to: `ip link del $link`
  1577. func (h *Handle) LinkDel(link Link) error {
  1578. base := link.Attrs()
  1579. h.ensureIndex(base)
  1580. req := h.newNetlinkRequest(unix.RTM_DELLINK, unix.NLM_F_ACK)
  1581. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  1582. msg.Index = int32(base.Index)
  1583. req.AddData(msg)
  1584. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  1585. return err
  1586. }
  1587. func (h *Handle) linkByNameDump(name string) (Link, error) {
  1588. links, executeErr := h.LinkList()
  1589. if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
  1590. return nil, executeErr
  1591. }
  1592. for _, link := range links {
  1593. if link.Attrs().Name == name {
  1594. return link, executeErr
  1595. }
  1596. // support finding interfaces also via altnames
  1597. for _, altName := range link.Attrs().AltNames {
  1598. if altName == name {
  1599. return link, executeErr
  1600. }
  1601. }
  1602. }
  1603. return nil, LinkNotFoundError{fmt.Errorf("Link %s not found", name)}
  1604. }
  1605. func (h *Handle) linkByAliasDump(alias string) (Link, error) {
  1606. links, executeErr := h.LinkList()
  1607. if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
  1608. return nil, executeErr
  1609. }
  1610. for _, link := range links {
  1611. if link.Attrs().Alias == alias {
  1612. return link, executeErr
  1613. }
  1614. }
  1615. return nil, LinkNotFoundError{fmt.Errorf("Link alias %s not found", alias)}
  1616. }
  1617. // LinkByName finds a link by name and returns a pointer to the object.
  1618. //
  1619. // If the kernel doesn't support IFLA_IFNAME, this method will fall back to
  1620. // filtering a dump of all link names. In this case, if the returned error is
  1621. // [ErrDumpInterrupted] the result may be missing or outdated.
  1622. func LinkByName(name string) (Link, error) {
  1623. return pkgHandle.LinkByName(name)
  1624. }
  1625. // LinkByName finds a link by name and returns a pointer to the object.
  1626. //
  1627. // If the kernel doesn't support IFLA_IFNAME, this method will fall back to
  1628. // filtering a dump of all link names. In this case, if the returned error is
  1629. // [ErrDumpInterrupted] the result may be missing or outdated.
  1630. func (h *Handle) LinkByName(name string) (Link, error) {
  1631. if h.lookupByDump {
  1632. return h.linkByNameDump(name)
  1633. }
  1634. req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK)
  1635. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  1636. req.AddData(msg)
  1637. attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF))
  1638. req.AddData(attr)
  1639. nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(name))
  1640. if len(name) > 15 {
  1641. nameData = nl.NewRtAttr(unix.IFLA_ALT_IFNAME, nl.ZeroTerminated(name))
  1642. }
  1643. req.AddData(nameData)
  1644. link, err := execGetLink(req)
  1645. if err == unix.EINVAL {
  1646. // older kernels don't support looking up via IFLA_IFNAME
  1647. // so fall back to dumping all links
  1648. h.lookupByDump = true
  1649. return h.linkByNameDump(name)
  1650. }
  1651. return link, err
  1652. }
  1653. // LinkByAlias finds a link by its alias and returns a pointer to the object.
  1654. // If there are multiple links with the alias it returns the first one
  1655. //
  1656. // If the kernel doesn't support IFLA_IFALIAS, this method will fall back to
  1657. // filtering a dump of all link names. In this case, if the returned error is
  1658. // [ErrDumpInterrupted] the result may be missing or outdated.
  1659. func LinkByAlias(alias string) (Link, error) {
  1660. return pkgHandle.LinkByAlias(alias)
  1661. }
  1662. // LinkByAlias finds a link by its alias and returns a pointer to the object.
  1663. // If there are multiple links with the alias it returns the first one
  1664. //
  1665. // If the kernel doesn't support IFLA_IFALIAS, this method will fall back to
  1666. // filtering a dump of all link names. In this case, if the returned error is
  1667. // [ErrDumpInterrupted] the result may be missing or outdated.
  1668. func (h *Handle) LinkByAlias(alias string) (Link, error) {
  1669. if h.lookupByDump {
  1670. return h.linkByAliasDump(alias)
  1671. }
  1672. req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK)
  1673. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  1674. req.AddData(msg)
  1675. attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF))
  1676. req.AddData(attr)
  1677. nameData := nl.NewRtAttr(unix.IFLA_IFALIAS, nl.ZeroTerminated(alias))
  1678. req.AddData(nameData)
  1679. link, err := execGetLink(req)
  1680. if err == unix.EINVAL {
  1681. // older kernels don't support looking up via IFLA_IFALIAS
  1682. // so fall back to dumping all links
  1683. h.lookupByDump = true
  1684. return h.linkByAliasDump(alias)
  1685. }
  1686. return link, err
  1687. }
  1688. // LinkByIndex finds a link by index and returns a pointer to the object.
  1689. func LinkByIndex(index int) (Link, error) {
  1690. return pkgHandle.LinkByIndex(index)
  1691. }
  1692. // LinkByIndex finds a link by index and returns a pointer to the object.
  1693. func (h *Handle) LinkByIndex(index int) (Link, error) {
  1694. req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK)
  1695. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  1696. msg.Index = int32(index)
  1697. req.AddData(msg)
  1698. attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF))
  1699. req.AddData(attr)
  1700. return execGetLink(req)
  1701. }
  1702. func execGetLink(req *nl.NetlinkRequest) (Link, error) {
  1703. msgs, err := req.Execute(unix.NETLINK_ROUTE, 0)
  1704. if err != nil {
  1705. if errno, ok := err.(syscall.Errno); ok {
  1706. if errno == unix.ENODEV {
  1707. return nil, LinkNotFoundError{fmt.Errorf("Link not found")}
  1708. }
  1709. }
  1710. return nil, err
  1711. }
  1712. switch {
  1713. case len(msgs) == 0:
  1714. return nil, LinkNotFoundError{fmt.Errorf("Link not found")}
  1715. case len(msgs) == 1:
  1716. return LinkDeserialize(nil, msgs[0])
  1717. default:
  1718. return nil, fmt.Errorf("More than one link found")
  1719. }
  1720. }
  1721. // LinkDeserialize deserializes a raw message received from netlink into
  1722. // a link object.
  1723. func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
  1724. msg := nl.DeserializeIfInfomsg(m)
  1725. attrs, err := nl.ParseRouteAttr(m[msg.Len():])
  1726. if err != nil {
  1727. return nil, err
  1728. }
  1729. base := NewLinkAttrs()
  1730. base.Index = int(msg.Index)
  1731. base.RawFlags = msg.Flags
  1732. base.Flags = linkFlags(msg.Flags)
  1733. base.EncapType = msg.EncapType()
  1734. base.NetNsID = -1
  1735. if msg.Flags&unix.IFF_ALLMULTI != 0 {
  1736. base.Allmulti = 1
  1737. }
  1738. if msg.Flags&unix.IFF_MULTICAST != 0 {
  1739. base.Multi = 1
  1740. }
  1741. var (
  1742. link Link
  1743. stats32 *LinkStatistics32
  1744. stats64 *LinkStatistics64
  1745. linkType string
  1746. linkSlave LinkSlave
  1747. slaveType string
  1748. )
  1749. for _, attr := range attrs {
  1750. switch attr.Attr.Type {
  1751. case unix.IFLA_LINKINFO:
  1752. infos, err := nl.ParseRouteAttr(attr.Value)
  1753. if err != nil {
  1754. return nil, err
  1755. }
  1756. for _, info := range infos {
  1757. switch info.Attr.Type {
  1758. case nl.IFLA_INFO_KIND:
  1759. linkType = string(info.Value[:len(info.Value)-1])
  1760. switch linkType {
  1761. case "dummy":
  1762. link = &Dummy{}
  1763. case "ifb":
  1764. link = &Ifb{}
  1765. case "bridge":
  1766. link = &Bridge{}
  1767. case "vlan":
  1768. link = &Vlan{}
  1769. case "netkit":
  1770. link = &Netkit{}
  1771. case "veth":
  1772. link = &Veth{}
  1773. case "wireguard":
  1774. link = &Wireguard{}
  1775. case "vxlan":
  1776. link = &Vxlan{}
  1777. case "bond":
  1778. link = &Bond{}
  1779. case "ipvlan":
  1780. link = &IPVlan{}
  1781. case "ipvtap":
  1782. link = &IPVtap{}
  1783. case "macvlan":
  1784. link = &Macvlan{}
  1785. case "macvtap":
  1786. link = &Macvtap{}
  1787. case "geneve":
  1788. link = &Geneve{}
  1789. case "gretap":
  1790. link = &Gretap{}
  1791. case "ip6gretap":
  1792. link = &Gretap{}
  1793. case "ipip":
  1794. link = &Iptun{}
  1795. case "ip6tnl":
  1796. link = &Ip6tnl{}
  1797. case "sit":
  1798. link = &Sittun{}
  1799. case "gre":
  1800. link = &Gretun{}
  1801. case "ip6gre":
  1802. link = &Gretun{}
  1803. case "vti", "vti6":
  1804. link = &Vti{}
  1805. case "vrf":
  1806. link = &Vrf{}
  1807. case "gtp":
  1808. link = &GTP{}
  1809. case "xfrm":
  1810. link = &Xfrmi{}
  1811. case "tun":
  1812. link = &Tuntap{}
  1813. case "ipoib":
  1814. link = &IPoIB{}
  1815. case "can":
  1816. link = &Can{}
  1817. case "bareudp":
  1818. link = &BareUDP{}
  1819. default:
  1820. link = &GenericLink{LinkType: linkType}
  1821. }
  1822. case nl.IFLA_INFO_DATA:
  1823. data, err := nl.ParseRouteAttr(info.Value)
  1824. if err != nil {
  1825. return nil, err
  1826. }
  1827. switch linkType {
  1828. case "netkit":
  1829. parseNetkitData(link, data)
  1830. case "vlan":
  1831. parseVlanData(link, data)
  1832. case "vxlan":
  1833. parseVxlanData(link, data)
  1834. case "bond":
  1835. parseBondData(link, data)
  1836. case "ipvlan":
  1837. parseIPVlanData(link, data)
  1838. case "ipvtap":
  1839. parseIPVtapData(link, data)
  1840. case "macvlan":
  1841. parseMacvlanData(link, data)
  1842. case "macvtap":
  1843. parseMacvtapData(link, data)
  1844. case "geneve":
  1845. parseGeneveData(link, data)
  1846. case "gretap":
  1847. parseGretapData(link, data)
  1848. case "ip6gretap":
  1849. parseGretapData(link, data)
  1850. case "ipip":
  1851. parseIptunData(link, data)
  1852. case "ip6tnl":
  1853. parseIp6tnlData(link, data)
  1854. case "sit":
  1855. parseSittunData(link, data)
  1856. case "gre":
  1857. parseGretunData(link, data)
  1858. case "ip6gre":
  1859. parseGretunData(link, data)
  1860. case "vti", "vti6":
  1861. parseVtiData(link, data)
  1862. case "vrf":
  1863. parseVrfData(link, data)
  1864. case "bridge":
  1865. parseBridgeData(link, data)
  1866. case "gtp":
  1867. parseGTPData(link, data)
  1868. case "xfrm":
  1869. parseXfrmiData(link, data)
  1870. case "tun":
  1871. parseTuntapData(link, data)
  1872. case "ipoib":
  1873. parseIPoIBData(link, data)
  1874. case "can":
  1875. parseCanData(link, data)
  1876. case "bareudp":
  1877. parseBareUDPData(link, data)
  1878. }
  1879. case nl.IFLA_INFO_SLAVE_KIND:
  1880. slaveType = string(info.Value[:len(info.Value)-1])
  1881. switch slaveType {
  1882. case "bond":
  1883. linkSlave = &BondSlave{}
  1884. case "vrf":
  1885. linkSlave = &VrfSlave{}
  1886. }
  1887. case nl.IFLA_INFO_SLAVE_DATA:
  1888. switch slaveType {
  1889. case "bond":
  1890. data, err := nl.ParseRouteAttr(info.Value)
  1891. if err != nil {
  1892. return nil, err
  1893. }
  1894. parseBondSlaveData(linkSlave, data)
  1895. case "vrf":
  1896. data, err := nl.ParseRouteAttr(info.Value)
  1897. if err != nil {
  1898. return nil, err
  1899. }
  1900. parseVrfSlaveData(linkSlave, data)
  1901. }
  1902. }
  1903. }
  1904. case unix.IFLA_ADDRESS:
  1905. var nonzero bool
  1906. for _, b := range attr.Value {
  1907. if b != 0 {
  1908. nonzero = true
  1909. }
  1910. }
  1911. if nonzero {
  1912. base.HardwareAddr = attr.Value[:]
  1913. }
  1914. case unix.IFLA_IFNAME:
  1915. base.Name = string(attr.Value[:len(attr.Value)-1])
  1916. case unix.IFLA_MTU:
  1917. base.MTU = int(native.Uint32(attr.Value[0:4]))
  1918. case unix.IFLA_PROMISCUITY:
  1919. base.Promisc = int(native.Uint32(attr.Value[0:4]))
  1920. case unix.IFLA_LINK:
  1921. base.ParentIndex = int(native.Uint32(attr.Value[0:4]))
  1922. case unix.IFLA_MASTER:
  1923. base.MasterIndex = int(native.Uint32(attr.Value[0:4]))
  1924. case unix.IFLA_TXQLEN:
  1925. base.TxQLen = int(native.Uint32(attr.Value[0:4]))
  1926. case unix.IFLA_IFALIAS:
  1927. base.Alias = string(attr.Value[:len(attr.Value)-1])
  1928. case unix.IFLA_STATS:
  1929. stats32 = new(LinkStatistics32)
  1930. if err := binary.Read(bytes.NewBuffer(attr.Value[:]), nl.NativeEndian(), stats32); err != nil {
  1931. return nil, err
  1932. }
  1933. case unix.IFLA_STATS64:
  1934. stats64 = new(LinkStatistics64)
  1935. if err := binary.Read(bytes.NewBuffer(attr.Value[:]), nl.NativeEndian(), stats64); err != nil {
  1936. return nil, err
  1937. }
  1938. case unix.IFLA_XDP:
  1939. xdp, err := parseLinkXdp(attr.Value[:])
  1940. if err != nil {
  1941. return nil, err
  1942. }
  1943. base.Xdp = xdp
  1944. case unix.IFLA_PROTINFO | unix.NLA_F_NESTED:
  1945. if hdr != nil && hdr.Type == unix.RTM_NEWLINK &&
  1946. msg.Family == unix.AF_BRIDGE {
  1947. attrs, err := nl.ParseRouteAttr(attr.Value[:])
  1948. if err != nil {
  1949. return nil, err
  1950. }
  1951. protinfo := parseProtinfo(attrs)
  1952. base.Protinfo = &protinfo
  1953. }
  1954. case unix.IFLA_PROP_LIST | unix.NLA_F_NESTED:
  1955. attrs, err := nl.ParseRouteAttr(attr.Value[:])
  1956. if err != nil {
  1957. return nil, err
  1958. }
  1959. base.AltNames = []string{}
  1960. for _, attr := range attrs {
  1961. if attr.Attr.Type == unix.IFLA_ALT_IFNAME {
  1962. base.AltNames = append(base.AltNames, nl.BytesToString(attr.Value))
  1963. }
  1964. }
  1965. case unix.IFLA_OPERSTATE:
  1966. base.OperState = LinkOperState(uint8(attr.Value[0]))
  1967. case unix.IFLA_PHYS_SWITCH_ID:
  1968. base.PhysSwitchID = int(native.Uint32(attr.Value[0:4]))
  1969. case unix.IFLA_LINK_NETNSID:
  1970. base.NetNsID = int(native.Uint32(attr.Value[0:4]))
  1971. case unix.IFLA_TSO_MAX_SEGS:
  1972. base.TSOMaxSegs = native.Uint32(attr.Value[0:4])
  1973. case unix.IFLA_TSO_MAX_SIZE:
  1974. base.TSOMaxSize = native.Uint32(attr.Value[0:4])
  1975. case unix.IFLA_GSO_MAX_SEGS:
  1976. base.GSOMaxSegs = native.Uint32(attr.Value[0:4])
  1977. case unix.IFLA_GSO_MAX_SIZE:
  1978. base.GSOMaxSize = native.Uint32(attr.Value[0:4])
  1979. case unix.IFLA_GRO_MAX_SIZE:
  1980. base.GROMaxSize = native.Uint32(attr.Value[0:4])
  1981. case unix.IFLA_GSO_IPV4_MAX_SIZE:
  1982. base.GSOIPv4MaxSize = native.Uint32(attr.Value[0:4])
  1983. case unix.IFLA_GRO_IPV4_MAX_SIZE:
  1984. base.GROIPv4MaxSize = native.Uint32(attr.Value[0:4])
  1985. case unix.IFLA_VFINFO_LIST:
  1986. data, err := nl.ParseRouteAttr(attr.Value)
  1987. if err != nil {
  1988. return nil, err
  1989. }
  1990. vfs, err := parseVfInfoList(data)
  1991. if err != nil {
  1992. return nil, err
  1993. }
  1994. base.Vfs = vfs
  1995. case unix.IFLA_NUM_TX_QUEUES:
  1996. base.NumTxQueues = int(native.Uint32(attr.Value[0:4]))
  1997. case unix.IFLA_NUM_RX_QUEUES:
  1998. base.NumRxQueues = int(native.Uint32(attr.Value[0:4]))
  1999. case unix.IFLA_GROUP:
  2000. base.Group = native.Uint32(attr.Value[0:4])
  2001. case unix.IFLA_PERM_ADDRESS:
  2002. for _, b := range attr.Value {
  2003. if b != 0 {
  2004. base.PermHWAddr = attr.Value[:]
  2005. break
  2006. }
  2007. }
  2008. case unix.IFLA_PARENT_DEV_NAME:
  2009. base.ParentDev = string(attr.Value[:len(attr.Value)-1])
  2010. case unix.IFLA_PARENT_DEV_BUS_NAME:
  2011. base.ParentDevBus = string(attr.Value[:len(attr.Value)-1])
  2012. }
  2013. }
  2014. if stats64 != nil {
  2015. base.Statistics = (*LinkStatistics)(stats64)
  2016. } else if stats32 != nil {
  2017. base.Statistics = (*LinkStatistics)(stats32.to64())
  2018. }
  2019. // Links that don't have IFLA_INFO_KIND are hardware devices
  2020. if link == nil {
  2021. link = &Device{}
  2022. }
  2023. *link.Attrs() = base
  2024. link.Attrs().Slave = linkSlave
  2025. // If the tuntap attributes are not updated by netlink due to
  2026. // an older driver, use sysfs
  2027. if link != nil && linkType == "tun" {
  2028. tuntap := link.(*Tuntap)
  2029. if tuntap.Mode == 0 {
  2030. ifname := tuntap.Attrs().Name
  2031. if flags, err := readSysPropAsInt64(ifname, "tun_flags"); err == nil {
  2032. if flags&unix.IFF_TUN != 0 {
  2033. tuntap.Mode = unix.IFF_TUN
  2034. } else if flags&unix.IFF_TAP != 0 {
  2035. tuntap.Mode = unix.IFF_TAP
  2036. }
  2037. tuntap.NonPersist = false
  2038. if flags&unix.IFF_PERSIST == 0 {
  2039. tuntap.NonPersist = true
  2040. }
  2041. }
  2042. // The sysfs interface for owner/group returns -1 for root user, instead of returning 0.
  2043. // So explicitly check for negative value, before assigning the owner uid/gid.
  2044. if owner, err := readSysPropAsInt64(ifname, "owner"); err == nil && owner > 0 {
  2045. tuntap.Owner = uint32(owner)
  2046. }
  2047. if group, err := readSysPropAsInt64(ifname, "group"); err == nil && group > 0 {
  2048. tuntap.Group = uint32(group)
  2049. }
  2050. }
  2051. }
  2052. return link, nil
  2053. }
  2054. func readSysPropAsInt64(ifname, prop string) (int64, error) {
  2055. fname := fmt.Sprintf("/sys/class/net/%s/%s", ifname, prop)
  2056. contents, err := ioutil.ReadFile(fname)
  2057. if err != nil {
  2058. return 0, err
  2059. }
  2060. num, err := strconv.ParseInt(strings.TrimSpace(string(contents)), 0, 64)
  2061. if err == nil {
  2062. return num, nil
  2063. }
  2064. return 0, err
  2065. }
  2066. // LinkList gets a list of link devices.
  2067. // Equivalent to: `ip link show`
  2068. func LinkList() ([]Link, error) {
  2069. return pkgHandle.LinkList()
  2070. }
  2071. // LinkList gets a list of link devices.
  2072. // Equivalent to: `ip link show`
  2073. //
  2074. // If the returned error is [ErrDumpInterrupted], results may be inconsistent
  2075. // or incomplete.
  2076. func (h *Handle) LinkList() ([]Link, error) {
  2077. // NOTE(vish): This duplicates functionality in net/iface_linux.go, but we need
  2078. // to get the message ourselves to parse link type.
  2079. req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
  2080. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  2081. req.AddData(msg)
  2082. attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF))
  2083. req.AddData(attr)
  2084. msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
  2085. if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
  2086. return nil, executeErr
  2087. }
  2088. var res []Link
  2089. for _, m := range msgs {
  2090. link, err := LinkDeserialize(nil, m)
  2091. if err != nil {
  2092. return nil, err
  2093. }
  2094. res = append(res, link)
  2095. }
  2096. return res, executeErr
  2097. }
  2098. // LinkUpdate is used to pass information back from LinkSubscribe()
  2099. type LinkUpdate struct {
  2100. nl.IfInfomsg
  2101. Header unix.NlMsghdr
  2102. Link
  2103. }
  2104. // LinkSubscribe takes a chan down which notifications will be sent
  2105. // when links change. Close the 'done' chan to stop subscription.
  2106. func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error {
  2107. return linkSubscribeAt(netns.None(), netns.None(), ch, done, nil, false, 0, nil, false)
  2108. }
  2109. // LinkSubscribeAt works like LinkSubscribe plus it allows the caller
  2110. // to choose the network namespace in which to subscribe (ns).
  2111. func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error {
  2112. return linkSubscribeAt(ns, netns.None(), ch, done, nil, false, 0, nil, false)
  2113. }
  2114. // LinkSubscribeOptions contains a set of options to use with
  2115. // LinkSubscribeWithOptions.
  2116. type LinkSubscribeOptions struct {
  2117. Namespace *netns.NsHandle
  2118. ErrorCallback func(error)
  2119. ListExisting bool
  2120. ReceiveBufferSize int
  2121. ReceiveBufferForceSize bool
  2122. ReceiveTimeout *unix.Timeval
  2123. }
  2124. // LinkSubscribeWithOptions work like LinkSubscribe but enable to
  2125. // provide additional options to modify the behavior. Currently, the
  2126. // namespace can be provided as well as an error callback.
  2127. //
  2128. // When options.ListExisting is true, options.ErrorCallback may be
  2129. // called with [ErrDumpInterrupted] to indicate that results from
  2130. // the initial dump of links may be inconsistent or incomplete.
  2131. func LinkSubscribeWithOptions(ch chan<- LinkUpdate, done <-chan struct{}, options LinkSubscribeOptions) error {
  2132. if options.Namespace == nil {
  2133. none := netns.None()
  2134. options.Namespace = &none
  2135. }
  2136. return linkSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting,
  2137. options.ReceiveBufferSize, options.ReceiveTimeout, options.ReceiveBufferForceSize)
  2138. }
  2139. func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}, cberr func(error), listExisting bool,
  2140. rcvbuf int, rcvTimeout *unix.Timeval, rcvbufForce bool) error {
  2141. s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_LINK)
  2142. if err != nil {
  2143. return err
  2144. }
  2145. if rcvTimeout != nil {
  2146. if err := s.SetReceiveTimeout(rcvTimeout); err != nil {
  2147. return err
  2148. }
  2149. }
  2150. if rcvbuf != 0 {
  2151. err = s.SetReceiveBufferSize(rcvbuf, rcvbufForce)
  2152. if err != nil {
  2153. return err
  2154. }
  2155. }
  2156. if done != nil {
  2157. go func() {
  2158. <-done
  2159. s.Close()
  2160. }()
  2161. }
  2162. if listExisting {
  2163. req := pkgHandle.newNetlinkRequest(unix.RTM_GETLINK,
  2164. unix.NLM_F_DUMP)
  2165. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  2166. req.AddData(msg)
  2167. if err := s.Send(req); err != nil {
  2168. return err
  2169. }
  2170. }
  2171. go func() {
  2172. defer close(ch)
  2173. for {
  2174. msgs, from, err := s.Receive()
  2175. if err != nil {
  2176. if cberr != nil {
  2177. cberr(fmt.Errorf("Receive failed: %v",
  2178. err))
  2179. }
  2180. return
  2181. }
  2182. if from.Pid != nl.PidKernel {
  2183. if cberr != nil {
  2184. cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
  2185. }
  2186. continue
  2187. }
  2188. for _, m := range msgs {
  2189. if m.Header.Flags&unix.NLM_F_DUMP_INTR != 0 && cberr != nil {
  2190. cberr(ErrDumpInterrupted)
  2191. }
  2192. if m.Header.Type == unix.NLMSG_DONE {
  2193. continue
  2194. }
  2195. if m.Header.Type == unix.NLMSG_ERROR {
  2196. error := int32(native.Uint32(m.Data[0:4]))
  2197. if error == 0 {
  2198. continue
  2199. }
  2200. if cberr != nil {
  2201. cberr(fmt.Errorf("error message: %v",
  2202. syscall.Errno(-error)))
  2203. }
  2204. continue
  2205. }
  2206. ifmsg := nl.DeserializeIfInfomsg(m.Data)
  2207. header := unix.NlMsghdr(m.Header)
  2208. link, err := LinkDeserialize(&header, m.Data)
  2209. if err != nil {
  2210. if cberr != nil {
  2211. cberr(err)
  2212. }
  2213. continue
  2214. }
  2215. ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: header, Link: link}
  2216. }
  2217. }
  2218. }()
  2219. return nil
  2220. }
  2221. func LinkSetHairpin(link Link, mode bool) error {
  2222. return pkgHandle.LinkSetHairpin(link, mode)
  2223. }
  2224. func (h *Handle) LinkSetHairpin(link Link, mode bool) error {
  2225. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_MODE)
  2226. }
  2227. func LinkSetGuard(link Link, mode bool) error {
  2228. return pkgHandle.LinkSetGuard(link, mode)
  2229. }
  2230. func (h *Handle) LinkSetGuard(link Link, mode bool) error {
  2231. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_GUARD)
  2232. }
  2233. // LinkSetBRSlaveGroupFwdMask set the group_fwd_mask of a bridge slave interface
  2234. func LinkSetBRSlaveGroupFwdMask(link Link, mask uint16) error {
  2235. return pkgHandle.LinkSetBRSlaveGroupFwdMask(link, mask)
  2236. }
  2237. // LinkSetBRSlaveGroupFwdMask set the group_fwd_mask of a bridge slave interface
  2238. func (h *Handle) LinkSetBRSlaveGroupFwdMask(link Link, mask uint16) error {
  2239. return h.setProtinfoAttrRawVal(link, nl.Uint16Attr(mask), nl.IFLA_BRPORT_GROUP_FWD_MASK)
  2240. }
  2241. func LinkSetFastLeave(link Link, mode bool) error {
  2242. return pkgHandle.LinkSetFastLeave(link, mode)
  2243. }
  2244. func (h *Handle) LinkSetFastLeave(link Link, mode bool) error {
  2245. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_FAST_LEAVE)
  2246. }
  2247. func LinkSetLearning(link Link, mode bool) error {
  2248. return pkgHandle.LinkSetLearning(link, mode)
  2249. }
  2250. func (h *Handle) LinkSetLearning(link Link, mode bool) error {
  2251. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_LEARNING)
  2252. }
  2253. func LinkSetVlanTunnel(link Link, mode bool) error {
  2254. return pkgHandle.LinkSetVlanTunnel(link, mode)
  2255. }
  2256. func (h *Handle) LinkSetVlanTunnel(link Link, mode bool) error {
  2257. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_VLAN_TUNNEL)
  2258. }
  2259. func LinkSetRootBlock(link Link, mode bool) error {
  2260. return pkgHandle.LinkSetRootBlock(link, mode)
  2261. }
  2262. func (h *Handle) LinkSetRootBlock(link Link, mode bool) error {
  2263. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROTECT)
  2264. }
  2265. func LinkSetFlood(link Link, mode bool) error {
  2266. return pkgHandle.LinkSetFlood(link, mode)
  2267. }
  2268. func (h *Handle) LinkSetFlood(link Link, mode bool) error {
  2269. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_UNICAST_FLOOD)
  2270. }
  2271. func LinkSetIsolated(link Link, mode bool) error {
  2272. return pkgHandle.LinkSetIsolated(link, mode)
  2273. }
  2274. func (h *Handle) LinkSetIsolated(link Link, mode bool) error {
  2275. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_ISOLATED)
  2276. }
  2277. func LinkSetBrProxyArp(link Link, mode bool) error {
  2278. return pkgHandle.LinkSetBrProxyArp(link, mode)
  2279. }
  2280. func (h *Handle) LinkSetBrProxyArp(link Link, mode bool) error {
  2281. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP)
  2282. }
  2283. func LinkSetBrProxyArpWiFi(link Link, mode bool) error {
  2284. return pkgHandle.LinkSetBrProxyArpWiFi(link, mode)
  2285. }
  2286. func (h *Handle) LinkSetBrProxyArpWiFi(link Link, mode bool) error {
  2287. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP_WIFI)
  2288. }
  2289. func LinkSetBrNeighSuppress(link Link, mode bool) error {
  2290. return pkgHandle.LinkSetBrNeighSuppress(link, mode)
  2291. }
  2292. func (h *Handle) LinkSetBrNeighSuppress(link Link, mode bool) error {
  2293. return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_NEIGH_SUPPRESS)
  2294. }
  2295. func (h *Handle) setProtinfoAttrRawVal(link Link, val []byte, attr int) error {
  2296. base := link.Attrs()
  2297. h.ensureIndex(base)
  2298. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  2299. msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
  2300. msg.Index = int32(base.Index)
  2301. req.AddData(msg)
  2302. br := nl.NewRtAttr(unix.IFLA_PROTINFO|unix.NLA_F_NESTED, nil)
  2303. br.AddRtAttr(attr, val)
  2304. req.AddData(br)
  2305. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  2306. if err != nil {
  2307. return err
  2308. }
  2309. return nil
  2310. }
  2311. func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
  2312. return h.setProtinfoAttrRawVal(link, boolToByte(mode), attr)
  2313. }
  2314. // LinkSetTxQLen sets the transaction queue length for the link.
  2315. // Equivalent to: `ip link set $link txqlen $qlen`
  2316. func LinkSetTxQLen(link Link, qlen int) error {
  2317. return pkgHandle.LinkSetTxQLen(link, qlen)
  2318. }
  2319. // LinkSetTxQLen sets the transaction queue length for the link.
  2320. // Equivalent to: `ip link set $link txqlen $qlen`
  2321. func (h *Handle) LinkSetTxQLen(link Link, qlen int) error {
  2322. base := link.Attrs()
  2323. h.ensureIndex(base)
  2324. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  2325. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  2326. msg.Index = int32(base.Index)
  2327. req.AddData(msg)
  2328. b := make([]byte, 4)
  2329. native.PutUint32(b, uint32(qlen))
  2330. data := nl.NewRtAttr(unix.IFLA_TXQLEN, b)
  2331. req.AddData(data)
  2332. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  2333. return err
  2334. }
  2335. // LinkSetGroup sets the link group id which can be used to perform mass actions
  2336. // with iproute2 as well use it as a reference in nft filters.
  2337. // Equivalent to: `ip link set $link group $id`
  2338. func LinkSetGroup(link Link, group int) error {
  2339. return pkgHandle.LinkSetGroup(link, group)
  2340. }
  2341. // LinkSetGroup sets the link group id which can be used to perform mass actions
  2342. // with iproute2 as well use it as a reference in nft filters.
  2343. // Equivalent to: `ip link set $link group $id`
  2344. func (h *Handle) LinkSetGroup(link Link, group int) error {
  2345. base := link.Attrs()
  2346. h.ensureIndex(base)
  2347. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  2348. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  2349. msg.Index = int32(base.Index)
  2350. req.AddData(msg)
  2351. b := make([]byte, 4)
  2352. native.PutUint32(b, uint32(group))
  2353. data := nl.NewRtAttr(unix.IFLA_GROUP, b)
  2354. req.AddData(data)
  2355. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  2356. return err
  2357. }
  2358. // LinkSetIP6AddrGenMode sets the IPv6 address generation mode of the link device.
  2359. // Equivalent to: `ip link set $link addrgenmode $mode`
  2360. func LinkSetIP6AddrGenMode(link Link, mode int) error {
  2361. return pkgHandle.LinkSetIP6AddrGenMode(link, mode)
  2362. }
  2363. // LinkSetIP6AddrGenMode sets the IPv6 address generation mode of the link device.
  2364. // Equivalent to: `ip link set $link addrgenmode $mode`
  2365. func (h *Handle) LinkSetIP6AddrGenMode(link Link, mode int) error {
  2366. base := link.Attrs()
  2367. h.ensureIndex(base)
  2368. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  2369. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  2370. msg.Index = int32(base.Index)
  2371. req.AddData(msg)
  2372. b := make([]byte, 1)
  2373. b[0] = uint8(mode)
  2374. data := nl.NewRtAttr(unix.IFLA_INET6_ADDR_GEN_MODE, b)
  2375. af := nl.NewRtAttr(unix.AF_INET6, data.Serialize())
  2376. spec := nl.NewRtAttr(unix.IFLA_AF_SPEC, af.Serialize())
  2377. req.AddData(spec)
  2378. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  2379. return err
  2380. }
  2381. func addNetkitAttrs(nk *Netkit, linkInfo *nl.RtAttr, flag int) error {
  2382. if nk.Mode != NETKIT_MODE_L2 && (nk.LinkAttrs.HardwareAddr != nil || nk.peerLinkAttrs.HardwareAddr != nil) {
  2383. return fmt.Errorf("netkit only allows setting Ethernet in L2 mode")
  2384. }
  2385. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  2386. // Kernel will return error if trying to change the mode of an existing netkit device
  2387. data.AddRtAttr(nl.IFLA_NETKIT_MODE, nl.Uint32Attr(uint32(nk.Mode)))
  2388. data.AddRtAttr(nl.IFLA_NETKIT_POLICY, nl.Uint32Attr(uint32(nk.Policy)))
  2389. data.AddRtAttr(nl.IFLA_NETKIT_PEER_POLICY, nl.Uint32Attr(uint32(nk.PeerPolicy)))
  2390. data.AddRtAttr(nl.IFLA_NETKIT_SCRUB, nl.Uint32Attr(uint32(nk.Scrub)))
  2391. data.AddRtAttr(nl.IFLA_NETKIT_PEER_SCRUB, nl.Uint32Attr(uint32(nk.PeerScrub)))
  2392. if (flag & unix.NLM_F_EXCL) == 0 {
  2393. // Modifying peer link attributes will not take effect
  2394. return nil
  2395. }
  2396. peer := data.AddRtAttr(nl.IFLA_NETKIT_PEER_INFO, nil)
  2397. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  2398. if nk.peerLinkAttrs.Flags&net.FlagUp != 0 {
  2399. msg.Change = unix.IFF_UP
  2400. msg.Flags = unix.IFF_UP
  2401. }
  2402. if nk.peerLinkAttrs.Index != 0 {
  2403. msg.Index = int32(nk.peerLinkAttrs.Index)
  2404. }
  2405. peer.AddChild(msg)
  2406. if nk.peerLinkAttrs.Name != "" {
  2407. peer.AddRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(nk.peerLinkAttrs.Name))
  2408. }
  2409. if nk.peerLinkAttrs.MTU > 0 {
  2410. peer.AddRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(nk.peerLinkAttrs.MTU)))
  2411. }
  2412. if nk.peerLinkAttrs.GSOMaxSegs > 0 {
  2413. peer.AddRtAttr(unix.IFLA_GSO_MAX_SEGS, nl.Uint32Attr(nk.peerLinkAttrs.GSOMaxSegs))
  2414. }
  2415. if nk.peerLinkAttrs.GSOMaxSize > 0 {
  2416. peer.AddRtAttr(unix.IFLA_GSO_MAX_SIZE, nl.Uint32Attr(nk.peerLinkAttrs.GSOMaxSize))
  2417. }
  2418. if nk.peerLinkAttrs.GSOIPv4MaxSize > 0 {
  2419. peer.AddRtAttr(unix.IFLA_GSO_IPV4_MAX_SIZE, nl.Uint32Attr(nk.peerLinkAttrs.GSOIPv4MaxSize))
  2420. }
  2421. if nk.peerLinkAttrs.GROIPv4MaxSize > 0 {
  2422. peer.AddRtAttr(unix.IFLA_GRO_IPV4_MAX_SIZE, nl.Uint32Attr(nk.peerLinkAttrs.GROIPv4MaxSize))
  2423. }
  2424. if nk.peerLinkAttrs.Namespace != nil {
  2425. switch ns := nk.peerLinkAttrs.Namespace.(type) {
  2426. case NsPid:
  2427. peer.AddRtAttr(unix.IFLA_NET_NS_PID, nl.Uint32Attr(uint32(ns)))
  2428. case NsFd:
  2429. peer.AddRtAttr(unix.IFLA_NET_NS_FD, nl.Uint32Attr(uint32(ns)))
  2430. }
  2431. }
  2432. if nk.peerLinkAttrs.HardwareAddr != nil {
  2433. peer.AddRtAttr(unix.IFLA_ADDRESS, []byte(nk.peerLinkAttrs.HardwareAddr))
  2434. }
  2435. return nil
  2436. }
  2437. func parseNetkitData(link Link, data []syscall.NetlinkRouteAttr) {
  2438. netkit := link.(*Netkit)
  2439. for _, datum := range data {
  2440. switch datum.Attr.Type {
  2441. case nl.IFLA_NETKIT_PRIMARY:
  2442. isPrimary := datum.Value[0:1][0]
  2443. if isPrimary != 0 {
  2444. netkit.isPrimary = true
  2445. }
  2446. case nl.IFLA_NETKIT_MODE:
  2447. netkit.Mode = NetkitMode(native.Uint32(datum.Value[0:4]))
  2448. case nl.IFLA_NETKIT_POLICY:
  2449. netkit.Policy = NetkitPolicy(native.Uint32(datum.Value[0:4]))
  2450. case nl.IFLA_NETKIT_PEER_POLICY:
  2451. netkit.PeerPolicy = NetkitPolicy(native.Uint32(datum.Value[0:4]))
  2452. case nl.IFLA_NETKIT_SCRUB:
  2453. netkit.supportsScrub = true
  2454. netkit.Scrub = NetkitScrub(native.Uint32(datum.Value[0:4]))
  2455. case nl.IFLA_NETKIT_PEER_SCRUB:
  2456. netkit.supportsScrub = true
  2457. netkit.PeerScrub = NetkitScrub(native.Uint32(datum.Value[0:4]))
  2458. }
  2459. }
  2460. }
  2461. func parseVlanQosMap(data []byte) map[uint32]uint32 {
  2462. values, err := nl.ParseRouteAttr(data)
  2463. if err != nil {
  2464. return nil
  2465. }
  2466. qosMap := make(map[uint32]uint32)
  2467. for _, value := range values {
  2468. switch value.Attr.Type {
  2469. case nl.IFLA_VLAN_QOS_MAPPING:
  2470. from := native.Uint32(value.Value[:4])
  2471. to := native.Uint32(value.Value[4:])
  2472. qosMap[from] = to
  2473. }
  2474. }
  2475. return qosMap
  2476. }
  2477. func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) {
  2478. vlan := link.(*Vlan)
  2479. for _, datum := range data {
  2480. switch datum.Attr.Type {
  2481. case nl.IFLA_VLAN_ID:
  2482. vlan.VlanId = int(native.Uint16(datum.Value[0:2]))
  2483. case nl.IFLA_VLAN_FLAGS:
  2484. flags := native.Uint32(datum.Value[0:4])
  2485. trueVal := true
  2486. falseVal := false
  2487. if flags&nl.VLAN_FLAG_REORDER_HDR != 0 {
  2488. vlan.ReorderHdr = &trueVal
  2489. } else {
  2490. vlan.ReorderHdr = &falseVal
  2491. }
  2492. if flags&nl.VLAN_FLAG_GVRP != 0 {
  2493. vlan.Gvrp = &trueVal
  2494. } else {
  2495. vlan.Gvrp = &falseVal
  2496. }
  2497. if flags&nl.VLAN_FLAG_LOOSE_BINDING != 0 {
  2498. vlan.LooseBinding = &trueVal
  2499. } else {
  2500. vlan.LooseBinding = &falseVal
  2501. }
  2502. if flags&nl.VLAN_FLAG_MVRP != 0 {
  2503. vlan.Mvrp = &trueVal
  2504. } else {
  2505. vlan.Mvrp = &falseVal
  2506. }
  2507. if flags&nl.VLAN_FLAG_BRIDGE_BINDING != 0 {
  2508. vlan.BridgeBinding = &trueVal
  2509. } else {
  2510. vlan.BridgeBinding = &falseVal
  2511. }
  2512. case nl.IFLA_VLAN_EGRESS_QOS:
  2513. vlan.EgressQosMap = parseVlanQosMap(datum.Value)
  2514. case nl.IFLA_VLAN_INGRESS_QOS:
  2515. vlan.IngressQosMap = parseVlanQosMap(datum.Value)
  2516. case nl.IFLA_VLAN_PROTOCOL:
  2517. vlan.VlanProtocol = VlanProtocol(int(ntohs(datum.Value[0:2])))
  2518. }
  2519. }
  2520. }
  2521. func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) {
  2522. vxlan := link.(*Vxlan)
  2523. for _, datum := range data {
  2524. // NOTE(vish): Apparently some messages can be sent with no value.
  2525. // We special case GBP here to not change existing
  2526. // functionality. It appears that GBP sends a datum.Value
  2527. // of null.
  2528. if len(datum.Value) == 0 && datum.Attr.Type != nl.IFLA_VXLAN_GBP {
  2529. continue
  2530. }
  2531. switch datum.Attr.Type {
  2532. case nl.IFLA_VXLAN_ID:
  2533. vxlan.VxlanId = int(native.Uint32(datum.Value[0:4]))
  2534. case nl.IFLA_VXLAN_LINK:
  2535. vxlan.VtepDevIndex = int(native.Uint32(datum.Value[0:4]))
  2536. case nl.IFLA_VXLAN_LOCAL:
  2537. vxlan.SrcAddr = net.IP(datum.Value[0:4])
  2538. case nl.IFLA_VXLAN_LOCAL6:
  2539. vxlan.SrcAddr = net.IP(datum.Value[0:16])
  2540. case nl.IFLA_VXLAN_GROUP:
  2541. vxlan.Group = net.IP(datum.Value[0:4])
  2542. case nl.IFLA_VXLAN_GROUP6:
  2543. vxlan.Group = net.IP(datum.Value[0:16])
  2544. case nl.IFLA_VXLAN_TTL:
  2545. vxlan.TTL = int(datum.Value[0])
  2546. case nl.IFLA_VXLAN_TOS:
  2547. vxlan.TOS = int(datum.Value[0])
  2548. case nl.IFLA_VXLAN_LEARNING:
  2549. vxlan.Learning = int8(datum.Value[0]) != 0
  2550. case nl.IFLA_VXLAN_PROXY:
  2551. vxlan.Proxy = int8(datum.Value[0]) != 0
  2552. case nl.IFLA_VXLAN_RSC:
  2553. vxlan.RSC = int8(datum.Value[0]) != 0
  2554. case nl.IFLA_VXLAN_L2MISS:
  2555. vxlan.L2miss = int8(datum.Value[0]) != 0
  2556. case nl.IFLA_VXLAN_L3MISS:
  2557. vxlan.L3miss = int8(datum.Value[0]) != 0
  2558. case nl.IFLA_VXLAN_UDP_CSUM:
  2559. vxlan.UDPCSum = int8(datum.Value[0]) != 0
  2560. case nl.IFLA_VXLAN_UDP_ZERO_CSUM6_TX:
  2561. vxlan.UDP6ZeroCSumTx = int8(datum.Value[0]) != 0
  2562. case nl.IFLA_VXLAN_UDP_ZERO_CSUM6_RX:
  2563. vxlan.UDP6ZeroCSumRx = int8(datum.Value[0]) != 0
  2564. case nl.IFLA_VXLAN_GBP:
  2565. vxlan.GBP = true
  2566. case nl.IFLA_VXLAN_FLOWBASED:
  2567. vxlan.FlowBased = int8(datum.Value[0]) != 0
  2568. case nl.IFLA_VXLAN_AGEING:
  2569. vxlan.Age = int(native.Uint32(datum.Value[0:4]))
  2570. vxlan.NoAge = vxlan.Age == 0
  2571. case nl.IFLA_VXLAN_LIMIT:
  2572. vxlan.Limit = int(native.Uint32(datum.Value[0:4]))
  2573. case nl.IFLA_VXLAN_PORT:
  2574. vxlan.Port = int(ntohs(datum.Value[0:2]))
  2575. case nl.IFLA_VXLAN_PORT_RANGE:
  2576. buf := bytes.NewBuffer(datum.Value[0:4])
  2577. var pr vxlanPortRange
  2578. if binary.Read(buf, binary.BigEndian, &pr) == nil {
  2579. vxlan.PortLow = int(pr.Lo)
  2580. vxlan.PortHigh = int(pr.Hi)
  2581. }
  2582. }
  2583. }
  2584. }
  2585. func parseBondData(link Link, data []syscall.NetlinkRouteAttr) {
  2586. bond := link.(*Bond)
  2587. for i := range data {
  2588. switch data[i].Attr.Type {
  2589. case nl.IFLA_BOND_MODE:
  2590. bond.Mode = BondMode(data[i].Value[0])
  2591. case nl.IFLA_BOND_ACTIVE_SLAVE:
  2592. bond.ActiveSlave = int(native.Uint32(data[i].Value[0:4]))
  2593. case nl.IFLA_BOND_MIIMON:
  2594. bond.Miimon = int(native.Uint32(data[i].Value[0:4]))
  2595. case nl.IFLA_BOND_UPDELAY:
  2596. bond.UpDelay = int(native.Uint32(data[i].Value[0:4]))
  2597. case nl.IFLA_BOND_DOWNDELAY:
  2598. bond.DownDelay = int(native.Uint32(data[i].Value[0:4]))
  2599. case nl.IFLA_BOND_USE_CARRIER:
  2600. bond.UseCarrier = int(data[i].Value[0])
  2601. case nl.IFLA_BOND_ARP_INTERVAL:
  2602. bond.ArpInterval = int(native.Uint32(data[i].Value[0:4]))
  2603. case nl.IFLA_BOND_ARP_IP_TARGET:
  2604. bond.ArpIpTargets = parseBondArpIpTargets(data[i].Value)
  2605. case nl.IFLA_BOND_ARP_VALIDATE:
  2606. bond.ArpValidate = BondArpValidate(native.Uint32(data[i].Value[0:4]))
  2607. case nl.IFLA_BOND_ARP_ALL_TARGETS:
  2608. bond.ArpAllTargets = BondArpAllTargets(native.Uint32(data[i].Value[0:4]))
  2609. case nl.IFLA_BOND_PRIMARY:
  2610. bond.Primary = int(native.Uint32(data[i].Value[0:4]))
  2611. case nl.IFLA_BOND_PRIMARY_RESELECT:
  2612. bond.PrimaryReselect = BondPrimaryReselect(data[i].Value[0])
  2613. case nl.IFLA_BOND_FAIL_OVER_MAC:
  2614. bond.FailOverMac = BondFailOverMac(data[i].Value[0])
  2615. case nl.IFLA_BOND_XMIT_HASH_POLICY:
  2616. bond.XmitHashPolicy = BondXmitHashPolicy(data[i].Value[0])
  2617. case nl.IFLA_BOND_RESEND_IGMP:
  2618. bond.ResendIgmp = int(native.Uint32(data[i].Value[0:4]))
  2619. case nl.IFLA_BOND_NUM_PEER_NOTIF:
  2620. bond.NumPeerNotif = int(data[i].Value[0])
  2621. case nl.IFLA_BOND_ALL_SLAVES_ACTIVE:
  2622. bond.AllSlavesActive = int(data[i].Value[0])
  2623. case nl.IFLA_BOND_MIN_LINKS:
  2624. bond.MinLinks = int(native.Uint32(data[i].Value[0:4]))
  2625. case nl.IFLA_BOND_LP_INTERVAL:
  2626. bond.LpInterval = int(native.Uint32(data[i].Value[0:4]))
  2627. case nl.IFLA_BOND_PACKETS_PER_SLAVE:
  2628. bond.PacketsPerSlave = int(native.Uint32(data[i].Value[0:4]))
  2629. case nl.IFLA_BOND_AD_LACP_RATE:
  2630. bond.LacpRate = BondLacpRate(data[i].Value[0])
  2631. case nl.IFLA_BOND_AD_SELECT:
  2632. bond.AdSelect = BondAdSelect(data[i].Value[0])
  2633. case nl.IFLA_BOND_AD_INFO:
  2634. // TODO: implement
  2635. case nl.IFLA_BOND_AD_ACTOR_SYS_PRIO:
  2636. bond.AdActorSysPrio = int(native.Uint16(data[i].Value[0:2]))
  2637. case nl.IFLA_BOND_AD_USER_PORT_KEY:
  2638. bond.AdUserPortKey = int(native.Uint16(data[i].Value[0:2]))
  2639. case nl.IFLA_BOND_AD_ACTOR_SYSTEM:
  2640. bond.AdActorSystem = net.HardwareAddr(data[i].Value[0:6])
  2641. case nl.IFLA_BOND_TLB_DYNAMIC_LB:
  2642. bond.TlbDynamicLb = int(data[i].Value[0])
  2643. }
  2644. }
  2645. }
  2646. func parseBondArpIpTargets(value []byte) []net.IP {
  2647. data, err := nl.ParseRouteAttr(value)
  2648. if err != nil {
  2649. return nil
  2650. }
  2651. targets := []net.IP{}
  2652. for i := range data {
  2653. target := net.IP(data[i].Value)
  2654. if ip := target.To4(); ip != nil {
  2655. targets = append(targets, ip)
  2656. continue
  2657. }
  2658. if ip := target.To16(); ip != nil {
  2659. targets = append(targets, ip)
  2660. }
  2661. }
  2662. return targets
  2663. }
  2664. func addBondSlaveAttrs(bondSlave *BondSlave, linkInfo *nl.RtAttr) {
  2665. data := linkInfo.AddRtAttr(nl.IFLA_INFO_SLAVE_DATA, nil)
  2666. data.AddRtAttr(nl.IFLA_BOND_SLAVE_STATE, nl.Uint8Attr(uint8(bondSlave.State)))
  2667. data.AddRtAttr(nl.IFLA_BOND_SLAVE_MII_STATUS, nl.Uint8Attr(uint8(bondSlave.MiiStatus)))
  2668. data.AddRtAttr(nl.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, nl.Uint32Attr(bondSlave.LinkFailureCount))
  2669. data.AddRtAttr(nl.IFLA_BOND_SLAVE_QUEUE_ID, nl.Uint16Attr(bondSlave.QueueId))
  2670. data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, nl.Uint16Attr(bondSlave.AggregatorId))
  2671. data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE, nl.Uint8Attr(bondSlave.AdActorOperPortState))
  2672. data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, nl.Uint16Attr(bondSlave.AdPartnerOperPortState))
  2673. if mac := bondSlave.PermHardwareAddr; mac != nil {
  2674. data.AddRtAttr(nl.IFLA_BOND_SLAVE_PERM_HWADDR, []byte(mac))
  2675. }
  2676. }
  2677. func parseBondSlaveData(slave LinkSlave, data []syscall.NetlinkRouteAttr) {
  2678. bondSlave := slave.(*BondSlave)
  2679. for i := range data {
  2680. switch data[i].Attr.Type {
  2681. case nl.IFLA_BOND_SLAVE_STATE:
  2682. bondSlave.State = BondSlaveState(data[i].Value[0])
  2683. case nl.IFLA_BOND_SLAVE_MII_STATUS:
  2684. bondSlave.MiiStatus = BondSlaveMiiStatus(data[i].Value[0])
  2685. case nl.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT:
  2686. bondSlave.LinkFailureCount = native.Uint32(data[i].Value[0:4])
  2687. case nl.IFLA_BOND_SLAVE_PERM_HWADDR:
  2688. bondSlave.PermHardwareAddr = net.HardwareAddr(data[i].Value[0:6])
  2689. case nl.IFLA_BOND_SLAVE_QUEUE_ID:
  2690. bondSlave.QueueId = native.Uint16(data[i].Value[0:2])
  2691. case nl.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID:
  2692. bondSlave.AggregatorId = native.Uint16(data[i].Value[0:2])
  2693. case nl.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE:
  2694. bondSlave.AdActorOperPortState = uint8(data[i].Value[0])
  2695. case nl.IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE:
  2696. bondSlave.AdPartnerOperPortState = native.Uint16(data[i].Value[0:2])
  2697. }
  2698. }
  2699. }
  2700. func parseVrfSlaveData(slave LinkSlave, data []syscall.NetlinkRouteAttr) {
  2701. vrfSlave := slave.(*VrfSlave)
  2702. for i := range data {
  2703. switch data[i].Attr.Type {
  2704. case nl.IFLA_BOND_SLAVE_STATE:
  2705. vrfSlave.Table = native.Uint32(data[i].Value[0:4])
  2706. }
  2707. }
  2708. }
  2709. func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) {
  2710. ipv := link.(*IPVlan)
  2711. for _, datum := range data {
  2712. switch datum.Attr.Type {
  2713. case nl.IFLA_IPVLAN_MODE:
  2714. ipv.Mode = IPVlanMode(native.Uint32(datum.Value[0:4]))
  2715. case nl.IFLA_IPVLAN_FLAG:
  2716. ipv.Flag = IPVlanFlag(native.Uint32(datum.Value[0:4]))
  2717. }
  2718. }
  2719. }
  2720. func parseIPVtapData(link Link, data []syscall.NetlinkRouteAttr) {
  2721. ipv := link.(*IPVtap)
  2722. for _, datum := range data {
  2723. switch datum.Attr.Type {
  2724. case nl.IFLA_IPVLAN_MODE:
  2725. ipv.Mode = IPVlanMode(native.Uint32(datum.Value[0:4]))
  2726. case nl.IFLA_IPVLAN_FLAG:
  2727. ipv.Flag = IPVlanFlag(native.Uint32(datum.Value[0:4]))
  2728. }
  2729. }
  2730. }
  2731. func addMacvtapAttrs(macvtap *Macvtap, linkInfo *nl.RtAttr) {
  2732. addMacvlanAttrs(&macvtap.Macvlan, linkInfo)
  2733. }
  2734. func parseMacvtapData(link Link, data []syscall.NetlinkRouteAttr) {
  2735. macv := link.(*Macvtap)
  2736. parseMacvlanData(&macv.Macvlan, data)
  2737. }
  2738. func addMacvlanAttrs(macvlan *Macvlan, linkInfo *nl.RtAttr) {
  2739. var data *nl.RtAttr
  2740. if macvlan.Mode != MACVLAN_MODE_DEFAULT || macvlan.BCQueueLen > 0 {
  2741. data = linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  2742. }
  2743. if macvlan.Mode != MACVLAN_MODE_DEFAULT {
  2744. data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macvlan.Mode]))
  2745. }
  2746. if macvlan.BCQueueLen > 0 {
  2747. data.AddRtAttr(nl.IFLA_MACVLAN_BC_QUEUE_LEN, nl.Uint32Attr(macvlan.BCQueueLen))
  2748. }
  2749. }
  2750. func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) {
  2751. macv := link.(*Macvlan)
  2752. for _, datum := range data {
  2753. switch datum.Attr.Type {
  2754. case nl.IFLA_MACVLAN_MODE:
  2755. switch native.Uint32(datum.Value[0:4]) {
  2756. case nl.MACVLAN_MODE_PRIVATE:
  2757. macv.Mode = MACVLAN_MODE_PRIVATE
  2758. case nl.MACVLAN_MODE_VEPA:
  2759. macv.Mode = MACVLAN_MODE_VEPA
  2760. case nl.MACVLAN_MODE_BRIDGE:
  2761. macv.Mode = MACVLAN_MODE_BRIDGE
  2762. case nl.MACVLAN_MODE_PASSTHRU:
  2763. macv.Mode = MACVLAN_MODE_PASSTHRU
  2764. case nl.MACVLAN_MODE_SOURCE:
  2765. macv.Mode = MACVLAN_MODE_SOURCE
  2766. }
  2767. case nl.IFLA_MACVLAN_MACADDR_COUNT:
  2768. macv.MACAddrs = make([]net.HardwareAddr, 0, int(native.Uint32(datum.Value[0:4])))
  2769. case nl.IFLA_MACVLAN_MACADDR_DATA:
  2770. macs, err := nl.ParseRouteAttr(datum.Value[:])
  2771. if err != nil {
  2772. panic(fmt.Sprintf("failed to ParseRouteAttr for IFLA_MACVLAN_MACADDR_DATA: %v", err))
  2773. }
  2774. for _, macDatum := range macs {
  2775. macv.MACAddrs = append(macv.MACAddrs, net.HardwareAddr(macDatum.Value[0:6]))
  2776. }
  2777. case nl.IFLA_MACVLAN_BC_QUEUE_LEN:
  2778. macv.BCQueueLen = native.Uint32(datum.Value[0:4])
  2779. case nl.IFLA_MACVLAN_BC_QUEUE_LEN_USED:
  2780. macv.UsedBCQueueLen = native.Uint32(datum.Value[0:4])
  2781. }
  2782. }
  2783. }
  2784. func linkFlags(rawFlags uint32) net.Flags {
  2785. var f net.Flags
  2786. if rawFlags&unix.IFF_UP != 0 {
  2787. f |= net.FlagUp
  2788. }
  2789. if rawFlags&unix.IFF_BROADCAST != 0 {
  2790. f |= net.FlagBroadcast
  2791. }
  2792. if rawFlags&unix.IFF_LOOPBACK != 0 {
  2793. f |= net.FlagLoopback
  2794. }
  2795. if rawFlags&unix.IFF_POINTOPOINT != 0 {
  2796. f |= net.FlagPointToPoint
  2797. }
  2798. if rawFlags&unix.IFF_MULTICAST != 0 {
  2799. f |= net.FlagMulticast
  2800. }
  2801. if rawFlags&unix.IFF_RUNNING != 0 {
  2802. f |= net.FlagRunning
  2803. }
  2804. return f
  2805. }
  2806. type genevePortRange struct {
  2807. Lo, Hi uint16
  2808. }
  2809. func addGeneveAttrs(geneve *Geneve, linkInfo *nl.RtAttr) {
  2810. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  2811. if geneve.InnerProtoInherit {
  2812. data.AddRtAttr(nl.IFLA_GENEVE_INNER_PROTO_INHERIT, []byte{})
  2813. }
  2814. if geneve.FlowBased {
  2815. geneve.ID = 0
  2816. data.AddRtAttr(nl.IFLA_GENEVE_COLLECT_METADATA, []byte{})
  2817. }
  2818. if ip := geneve.Remote; ip != nil {
  2819. if ip4 := ip.To4(); ip4 != nil {
  2820. data.AddRtAttr(nl.IFLA_GENEVE_REMOTE, ip.To4())
  2821. } else {
  2822. data.AddRtAttr(nl.IFLA_GENEVE_REMOTE6, []byte(ip))
  2823. }
  2824. }
  2825. if geneve.ID != 0 {
  2826. data.AddRtAttr(nl.IFLA_GENEVE_ID, nl.Uint32Attr(geneve.ID))
  2827. }
  2828. if geneve.Dport != 0 {
  2829. data.AddRtAttr(nl.IFLA_GENEVE_PORT, htons(geneve.Dport))
  2830. }
  2831. if geneve.Ttl != 0 {
  2832. data.AddRtAttr(nl.IFLA_GENEVE_TTL, nl.Uint8Attr(geneve.Ttl))
  2833. }
  2834. if geneve.Tos != 0 {
  2835. data.AddRtAttr(nl.IFLA_GENEVE_TOS, nl.Uint8Attr(geneve.Tos))
  2836. }
  2837. if geneve.PortLow > 0 || geneve.PortHigh > 0 {
  2838. pr := genevePortRange{uint16(geneve.PortLow), uint16(geneve.PortHigh)}
  2839. buf := new(bytes.Buffer)
  2840. binary.Write(buf, binary.BigEndian, &pr)
  2841. data.AddRtAttr(nl.IFLA_GENEVE_PORT_RANGE, buf.Bytes())
  2842. }
  2843. data.AddRtAttr(nl.IFLA_GENEVE_DF, nl.Uint8Attr(uint8(geneve.Df)))
  2844. }
  2845. func parseGeneveData(link Link, data []syscall.NetlinkRouteAttr) {
  2846. geneve := link.(*Geneve)
  2847. for _, datum := range data {
  2848. switch datum.Attr.Type {
  2849. case nl.IFLA_GENEVE_ID:
  2850. geneve.ID = native.Uint32(datum.Value[0:4])
  2851. case nl.IFLA_GENEVE_REMOTE, nl.IFLA_GENEVE_REMOTE6:
  2852. geneve.Remote = datum.Value
  2853. case nl.IFLA_GENEVE_PORT:
  2854. geneve.Dport = ntohs(datum.Value[0:2])
  2855. case nl.IFLA_GENEVE_TTL:
  2856. geneve.Ttl = uint8(datum.Value[0])
  2857. case nl.IFLA_GENEVE_TOS:
  2858. geneve.Tos = uint8(datum.Value[0])
  2859. case nl.IFLA_GENEVE_COLLECT_METADATA:
  2860. geneve.FlowBased = true
  2861. case nl.IFLA_GENEVE_INNER_PROTO_INHERIT:
  2862. geneve.InnerProtoInherit = true
  2863. case nl.IFLA_GENEVE_PORT_RANGE:
  2864. buf := bytes.NewBuffer(datum.Value[0:4])
  2865. var pr genevePortRange
  2866. if binary.Read(buf, binary.BigEndian, &pr) == nil {
  2867. geneve.PortLow = int(pr.Lo)
  2868. geneve.PortHigh = int(pr.Hi)
  2869. }
  2870. }
  2871. }
  2872. }
  2873. func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
  2874. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  2875. if gretap.FlowBased {
  2876. // In flow based mode, no other attributes need to be configured
  2877. data.AddRtAttr(nl.IFLA_GRE_COLLECT_METADATA, []byte{})
  2878. return
  2879. }
  2880. if ip := gretap.Local; ip != nil {
  2881. if ip.To4() != nil {
  2882. ip = ip.To4()
  2883. }
  2884. data.AddRtAttr(nl.IFLA_GRE_LOCAL, []byte(ip))
  2885. }
  2886. if ip := gretap.Remote; ip != nil {
  2887. if ip.To4() != nil {
  2888. ip = ip.To4()
  2889. }
  2890. data.AddRtAttr(nl.IFLA_GRE_REMOTE, []byte(ip))
  2891. }
  2892. if gretap.IKey != 0 {
  2893. data.AddRtAttr(nl.IFLA_GRE_IKEY, htonl(gretap.IKey))
  2894. gretap.IFlags |= uint16(nl.GRE_KEY)
  2895. }
  2896. if gretap.OKey != 0 {
  2897. data.AddRtAttr(nl.IFLA_GRE_OKEY, htonl(gretap.OKey))
  2898. gretap.OFlags |= uint16(nl.GRE_KEY)
  2899. }
  2900. data.AddRtAttr(nl.IFLA_GRE_IFLAGS, htons(gretap.IFlags))
  2901. data.AddRtAttr(nl.IFLA_GRE_OFLAGS, htons(gretap.OFlags))
  2902. if gretap.Link != 0 {
  2903. data.AddRtAttr(nl.IFLA_GRE_LINK, nl.Uint32Attr(gretap.Link))
  2904. }
  2905. data.AddRtAttr(nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gretap.PMtuDisc))
  2906. data.AddRtAttr(nl.IFLA_GRE_TTL, nl.Uint8Attr(gretap.Ttl))
  2907. data.AddRtAttr(nl.IFLA_GRE_TOS, nl.Uint8Attr(gretap.Tos))
  2908. data.AddRtAttr(nl.IFLA_GRE_ENCAP_TYPE, nl.Uint16Attr(gretap.EncapType))
  2909. data.AddRtAttr(nl.IFLA_GRE_ENCAP_FLAGS, nl.Uint16Attr(gretap.EncapFlags))
  2910. data.AddRtAttr(nl.IFLA_GRE_ENCAP_SPORT, htons(gretap.EncapSport))
  2911. data.AddRtAttr(nl.IFLA_GRE_ENCAP_DPORT, htons(gretap.EncapDport))
  2912. }
  2913. func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
  2914. gre := link.(*Gretap)
  2915. for _, datum := range data {
  2916. switch datum.Attr.Type {
  2917. case nl.IFLA_GRE_OKEY:
  2918. gre.IKey = ntohl(datum.Value[0:4])
  2919. case nl.IFLA_GRE_IKEY:
  2920. gre.OKey = ntohl(datum.Value[0:4])
  2921. case nl.IFLA_GRE_LOCAL:
  2922. gre.Local = net.IP(datum.Value)
  2923. case nl.IFLA_GRE_REMOTE:
  2924. gre.Remote = net.IP(datum.Value)
  2925. case nl.IFLA_GRE_ENCAP_SPORT:
  2926. gre.EncapSport = ntohs(datum.Value[0:2])
  2927. case nl.IFLA_GRE_ENCAP_DPORT:
  2928. gre.EncapDport = ntohs(datum.Value[0:2])
  2929. case nl.IFLA_GRE_IFLAGS:
  2930. gre.IFlags = ntohs(datum.Value[0:2])
  2931. case nl.IFLA_GRE_OFLAGS:
  2932. gre.OFlags = ntohs(datum.Value[0:2])
  2933. case nl.IFLA_GRE_TTL:
  2934. gre.Ttl = uint8(datum.Value[0])
  2935. case nl.IFLA_GRE_TOS:
  2936. gre.Tos = uint8(datum.Value[0])
  2937. case nl.IFLA_GRE_PMTUDISC:
  2938. gre.PMtuDisc = uint8(datum.Value[0])
  2939. case nl.IFLA_GRE_ENCAP_TYPE:
  2940. gre.EncapType = native.Uint16(datum.Value[0:2])
  2941. case nl.IFLA_GRE_ENCAP_FLAGS:
  2942. gre.EncapFlags = native.Uint16(datum.Value[0:2])
  2943. case nl.IFLA_GRE_COLLECT_METADATA:
  2944. gre.FlowBased = true
  2945. }
  2946. }
  2947. }
  2948. func addGretunAttrs(gre *Gretun, linkInfo *nl.RtAttr) {
  2949. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  2950. if gre.FlowBased {
  2951. // In flow based mode, no other attributes need to be configured
  2952. data.AddRtAttr(nl.IFLA_GRE_COLLECT_METADATA, []byte{})
  2953. return
  2954. }
  2955. if ip := gre.Local; ip != nil {
  2956. if ip.To4() != nil {
  2957. ip = ip.To4()
  2958. }
  2959. data.AddRtAttr(nl.IFLA_GRE_LOCAL, []byte(ip))
  2960. }
  2961. if ip := gre.Remote; ip != nil {
  2962. if ip.To4() != nil {
  2963. ip = ip.To4()
  2964. }
  2965. data.AddRtAttr(nl.IFLA_GRE_REMOTE, []byte(ip))
  2966. }
  2967. if gre.IKey != 0 {
  2968. data.AddRtAttr(nl.IFLA_GRE_IKEY, htonl(gre.IKey))
  2969. gre.IFlags |= uint16(nl.GRE_KEY)
  2970. }
  2971. if gre.OKey != 0 {
  2972. data.AddRtAttr(nl.IFLA_GRE_OKEY, htonl(gre.OKey))
  2973. gre.OFlags |= uint16(nl.GRE_KEY)
  2974. }
  2975. data.AddRtAttr(nl.IFLA_GRE_IFLAGS, htons(gre.IFlags))
  2976. data.AddRtAttr(nl.IFLA_GRE_OFLAGS, htons(gre.OFlags))
  2977. if gre.Link != 0 {
  2978. data.AddRtAttr(nl.IFLA_GRE_LINK, nl.Uint32Attr(gre.Link))
  2979. }
  2980. data.AddRtAttr(nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gre.PMtuDisc))
  2981. data.AddRtAttr(nl.IFLA_GRE_TTL, nl.Uint8Attr(gre.Ttl))
  2982. data.AddRtAttr(nl.IFLA_GRE_TOS, nl.Uint8Attr(gre.Tos))
  2983. data.AddRtAttr(nl.IFLA_GRE_ENCAP_TYPE, nl.Uint16Attr(gre.EncapType))
  2984. data.AddRtAttr(nl.IFLA_GRE_ENCAP_FLAGS, nl.Uint16Attr(gre.EncapFlags))
  2985. data.AddRtAttr(nl.IFLA_GRE_ENCAP_SPORT, htons(gre.EncapSport))
  2986. data.AddRtAttr(nl.IFLA_GRE_ENCAP_DPORT, htons(gre.EncapDport))
  2987. }
  2988. func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) {
  2989. gre := link.(*Gretun)
  2990. for _, datum := range data {
  2991. switch datum.Attr.Type {
  2992. case nl.IFLA_GRE_IKEY:
  2993. gre.IKey = ntohl(datum.Value[0:4])
  2994. case nl.IFLA_GRE_OKEY:
  2995. gre.OKey = ntohl(datum.Value[0:4])
  2996. case nl.IFLA_GRE_LOCAL:
  2997. gre.Local = net.IP(datum.Value)
  2998. case nl.IFLA_GRE_REMOTE:
  2999. gre.Remote = net.IP(datum.Value)
  3000. case nl.IFLA_GRE_IFLAGS:
  3001. gre.IFlags = ntohs(datum.Value[0:2])
  3002. case nl.IFLA_GRE_OFLAGS:
  3003. gre.OFlags = ntohs(datum.Value[0:2])
  3004. case nl.IFLA_GRE_TTL:
  3005. gre.Ttl = uint8(datum.Value[0])
  3006. case nl.IFLA_GRE_TOS:
  3007. gre.Tos = uint8(datum.Value[0])
  3008. case nl.IFLA_GRE_PMTUDISC:
  3009. gre.PMtuDisc = uint8(datum.Value[0])
  3010. case nl.IFLA_GRE_ENCAP_TYPE:
  3011. gre.EncapType = native.Uint16(datum.Value[0:2])
  3012. case nl.IFLA_GRE_ENCAP_FLAGS:
  3013. gre.EncapFlags = native.Uint16(datum.Value[0:2])
  3014. case nl.IFLA_GRE_ENCAP_SPORT:
  3015. gre.EncapSport = ntohs(datum.Value[0:2])
  3016. case nl.IFLA_GRE_ENCAP_DPORT:
  3017. gre.EncapDport = ntohs(datum.Value[0:2])
  3018. case nl.IFLA_GRE_COLLECT_METADATA:
  3019. gre.FlowBased = true
  3020. }
  3021. }
  3022. }
  3023. func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) {
  3024. attrs := nl.NewRtAttr(unix.IFLA_XDP|unix.NLA_F_NESTED, nil)
  3025. b := make([]byte, 4)
  3026. native.PutUint32(b, uint32(xdp.Fd))
  3027. attrs.AddRtAttr(nl.IFLA_XDP_FD, b)
  3028. if xdp.Flags != 0 {
  3029. b := make([]byte, 4)
  3030. native.PutUint32(b, xdp.Flags)
  3031. attrs.AddRtAttr(nl.IFLA_XDP_FLAGS, b)
  3032. }
  3033. req.AddData(attrs)
  3034. }
  3035. func parseLinkXdp(data []byte) (*LinkXdp, error) {
  3036. attrs, err := nl.ParseRouteAttr(data)
  3037. if err != nil {
  3038. return nil, err
  3039. }
  3040. xdp := &LinkXdp{}
  3041. for _, attr := range attrs {
  3042. switch attr.Attr.Type {
  3043. case nl.IFLA_XDP_FD:
  3044. xdp.Fd = int(native.Uint32(attr.Value[0:4]))
  3045. case nl.IFLA_XDP_ATTACHED:
  3046. xdp.AttachMode = uint32(attr.Value[0])
  3047. xdp.Attached = xdp.AttachMode != 0
  3048. case nl.IFLA_XDP_FLAGS:
  3049. xdp.Flags = native.Uint32(attr.Value[0:4])
  3050. case nl.IFLA_XDP_PROG_ID:
  3051. xdp.ProgId = native.Uint32(attr.Value[0:4])
  3052. }
  3053. }
  3054. return xdp, nil
  3055. }
  3056. func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) {
  3057. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3058. if iptun.FlowBased {
  3059. // In flow based mode, no other attributes need to be configured
  3060. data.AddRtAttr(nl.IFLA_IPTUN_COLLECT_METADATA, []byte{})
  3061. return
  3062. }
  3063. ip := iptun.Local.To4()
  3064. if ip != nil {
  3065. data.AddRtAttr(nl.IFLA_IPTUN_LOCAL, []byte(ip))
  3066. }
  3067. ip = iptun.Remote.To4()
  3068. if ip != nil {
  3069. data.AddRtAttr(nl.IFLA_IPTUN_REMOTE, []byte(ip))
  3070. }
  3071. if iptun.Link != 0 {
  3072. data.AddRtAttr(nl.IFLA_IPTUN_LINK, nl.Uint32Attr(iptun.Link))
  3073. }
  3074. data.AddRtAttr(nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(iptun.PMtuDisc))
  3075. data.AddRtAttr(nl.IFLA_IPTUN_TTL, nl.Uint8Attr(iptun.Ttl))
  3076. data.AddRtAttr(nl.IFLA_IPTUN_TOS, nl.Uint8Attr(iptun.Tos))
  3077. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(iptun.EncapType))
  3078. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(iptun.EncapFlags))
  3079. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_SPORT, htons(iptun.EncapSport))
  3080. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_DPORT, htons(iptun.EncapDport))
  3081. data.AddRtAttr(nl.IFLA_IPTUN_PROTO, nl.Uint8Attr(iptun.Proto))
  3082. }
  3083. func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
  3084. iptun := link.(*Iptun)
  3085. for _, datum := range data {
  3086. switch datum.Attr.Type {
  3087. case nl.IFLA_IPTUN_LOCAL:
  3088. iptun.Local = net.IP(datum.Value[0:4])
  3089. case nl.IFLA_IPTUN_REMOTE:
  3090. iptun.Remote = net.IP(datum.Value[0:4])
  3091. case nl.IFLA_IPTUN_TTL:
  3092. iptun.Ttl = uint8(datum.Value[0])
  3093. case nl.IFLA_IPTUN_TOS:
  3094. iptun.Tos = uint8(datum.Value[0])
  3095. case nl.IFLA_IPTUN_PMTUDISC:
  3096. iptun.PMtuDisc = uint8(datum.Value[0])
  3097. case nl.IFLA_IPTUN_ENCAP_SPORT:
  3098. iptun.EncapSport = ntohs(datum.Value[0:2])
  3099. case nl.IFLA_IPTUN_ENCAP_DPORT:
  3100. iptun.EncapDport = ntohs(datum.Value[0:2])
  3101. case nl.IFLA_IPTUN_ENCAP_TYPE:
  3102. iptun.EncapType = native.Uint16(datum.Value[0:2])
  3103. case nl.IFLA_IPTUN_ENCAP_FLAGS:
  3104. iptun.EncapFlags = native.Uint16(datum.Value[0:2])
  3105. case nl.IFLA_IPTUN_COLLECT_METADATA:
  3106. iptun.FlowBased = true
  3107. case nl.IFLA_IPTUN_PROTO:
  3108. iptun.Proto = datum.Value[0]
  3109. }
  3110. }
  3111. }
  3112. func addIp6tnlAttrs(ip6tnl *Ip6tnl, linkInfo *nl.RtAttr) {
  3113. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3114. if ip6tnl.FlowBased {
  3115. // In flow based mode, no other attributes need to be configured
  3116. data.AddRtAttr(nl.IFLA_IPTUN_COLLECT_METADATA, []byte{})
  3117. return
  3118. }
  3119. if ip6tnl.Link != 0 {
  3120. data.AddRtAttr(nl.IFLA_IPTUN_LINK, nl.Uint32Attr(ip6tnl.Link))
  3121. }
  3122. ip := ip6tnl.Local.To16()
  3123. if ip != nil {
  3124. data.AddRtAttr(nl.IFLA_IPTUN_LOCAL, []byte(ip))
  3125. }
  3126. ip = ip6tnl.Remote.To16()
  3127. if ip != nil {
  3128. data.AddRtAttr(nl.IFLA_IPTUN_REMOTE, []byte(ip))
  3129. }
  3130. data.AddRtAttr(nl.IFLA_IPTUN_TTL, nl.Uint8Attr(ip6tnl.Ttl))
  3131. data.AddRtAttr(nl.IFLA_IPTUN_TOS, nl.Uint8Attr(ip6tnl.Tos))
  3132. data.AddRtAttr(nl.IFLA_IPTUN_FLAGS, nl.Uint32Attr(ip6tnl.Flags))
  3133. data.AddRtAttr(nl.IFLA_IPTUN_PROTO, nl.Uint8Attr(ip6tnl.Proto))
  3134. data.AddRtAttr(nl.IFLA_IPTUN_FLOWINFO, nl.Uint32Attr(ip6tnl.FlowInfo))
  3135. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_LIMIT, nl.Uint8Attr(ip6tnl.EncapLimit))
  3136. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(ip6tnl.EncapType))
  3137. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(ip6tnl.EncapFlags))
  3138. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_SPORT, htons(ip6tnl.EncapSport))
  3139. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_DPORT, htons(ip6tnl.EncapDport))
  3140. }
  3141. func parseIp6tnlData(link Link, data []syscall.NetlinkRouteAttr) {
  3142. ip6tnl := link.(*Ip6tnl)
  3143. for _, datum := range data {
  3144. switch datum.Attr.Type {
  3145. case nl.IFLA_IPTUN_LOCAL:
  3146. ip6tnl.Local = net.IP(datum.Value[:16])
  3147. case nl.IFLA_IPTUN_REMOTE:
  3148. ip6tnl.Remote = net.IP(datum.Value[:16])
  3149. case nl.IFLA_IPTUN_TTL:
  3150. ip6tnl.Ttl = datum.Value[0]
  3151. case nl.IFLA_IPTUN_TOS:
  3152. ip6tnl.Tos = datum.Value[0]
  3153. case nl.IFLA_IPTUN_FLAGS:
  3154. ip6tnl.Flags = native.Uint32(datum.Value[:4])
  3155. case nl.IFLA_IPTUN_PROTO:
  3156. ip6tnl.Proto = datum.Value[0]
  3157. case nl.IFLA_IPTUN_FLOWINFO:
  3158. ip6tnl.FlowInfo = native.Uint32(datum.Value[:4])
  3159. case nl.IFLA_IPTUN_ENCAP_LIMIT:
  3160. ip6tnl.EncapLimit = datum.Value[0]
  3161. case nl.IFLA_IPTUN_ENCAP_TYPE:
  3162. ip6tnl.EncapType = native.Uint16(datum.Value[0:2])
  3163. case nl.IFLA_IPTUN_ENCAP_FLAGS:
  3164. ip6tnl.EncapFlags = native.Uint16(datum.Value[0:2])
  3165. case nl.IFLA_IPTUN_ENCAP_SPORT:
  3166. ip6tnl.EncapSport = ntohs(datum.Value[0:2])
  3167. case nl.IFLA_IPTUN_ENCAP_DPORT:
  3168. ip6tnl.EncapDport = ntohs(datum.Value[0:2])
  3169. case nl.IFLA_IPTUN_COLLECT_METADATA:
  3170. ip6tnl.FlowBased = true
  3171. }
  3172. }
  3173. }
  3174. func addSittunAttrs(sittun *Sittun, linkInfo *nl.RtAttr) {
  3175. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3176. if sittun.Link != 0 {
  3177. data.AddRtAttr(nl.IFLA_IPTUN_LINK, nl.Uint32Attr(sittun.Link))
  3178. }
  3179. ip := sittun.Local.To4()
  3180. if ip != nil {
  3181. data.AddRtAttr(nl.IFLA_IPTUN_LOCAL, []byte(ip))
  3182. }
  3183. ip = sittun.Remote.To4()
  3184. if ip != nil {
  3185. data.AddRtAttr(nl.IFLA_IPTUN_REMOTE, []byte(ip))
  3186. }
  3187. if sittun.Ttl > 0 {
  3188. // Would otherwise fail on 3.10 kernel
  3189. data.AddRtAttr(nl.IFLA_IPTUN_TTL, nl.Uint8Attr(sittun.Ttl))
  3190. }
  3191. data.AddRtAttr(nl.IFLA_IPTUN_PROTO, nl.Uint8Attr(sittun.Proto))
  3192. data.AddRtAttr(nl.IFLA_IPTUN_TOS, nl.Uint8Attr(sittun.Tos))
  3193. data.AddRtAttr(nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(sittun.PMtuDisc))
  3194. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_LIMIT, nl.Uint8Attr(sittun.EncapLimit))
  3195. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(sittun.EncapType))
  3196. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(sittun.EncapFlags))
  3197. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_SPORT, htons(sittun.EncapSport))
  3198. data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_DPORT, htons(sittun.EncapDport))
  3199. }
  3200. func parseSittunData(link Link, data []syscall.NetlinkRouteAttr) {
  3201. sittun := link.(*Sittun)
  3202. for _, datum := range data {
  3203. switch datum.Attr.Type {
  3204. case nl.IFLA_IPTUN_LOCAL:
  3205. sittun.Local = net.IP(datum.Value[0:4])
  3206. case nl.IFLA_IPTUN_REMOTE:
  3207. sittun.Remote = net.IP(datum.Value[0:4])
  3208. case nl.IFLA_IPTUN_TTL:
  3209. sittun.Ttl = datum.Value[0]
  3210. case nl.IFLA_IPTUN_TOS:
  3211. sittun.Tos = datum.Value[0]
  3212. case nl.IFLA_IPTUN_PMTUDISC:
  3213. sittun.PMtuDisc = datum.Value[0]
  3214. case nl.IFLA_IPTUN_PROTO:
  3215. sittun.Proto = datum.Value[0]
  3216. case nl.IFLA_IPTUN_ENCAP_TYPE:
  3217. sittun.EncapType = native.Uint16(datum.Value[0:2])
  3218. case nl.IFLA_IPTUN_ENCAP_FLAGS:
  3219. sittun.EncapFlags = native.Uint16(datum.Value[0:2])
  3220. case nl.IFLA_IPTUN_ENCAP_SPORT:
  3221. sittun.EncapSport = ntohs(datum.Value[0:2])
  3222. case nl.IFLA_IPTUN_ENCAP_DPORT:
  3223. sittun.EncapDport = ntohs(datum.Value[0:2])
  3224. }
  3225. }
  3226. }
  3227. func addVtiAttrs(vti *Vti, linkInfo *nl.RtAttr) {
  3228. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3229. family := FAMILY_V4
  3230. if vti.Local.To4() == nil {
  3231. family = FAMILY_V6
  3232. }
  3233. var ip net.IP
  3234. if family == FAMILY_V4 {
  3235. ip = vti.Local.To4()
  3236. } else {
  3237. ip = vti.Local
  3238. }
  3239. if ip != nil {
  3240. data.AddRtAttr(nl.IFLA_VTI_LOCAL, []byte(ip))
  3241. }
  3242. if family == FAMILY_V4 {
  3243. ip = vti.Remote.To4()
  3244. } else {
  3245. ip = vti.Remote
  3246. }
  3247. if ip != nil {
  3248. data.AddRtAttr(nl.IFLA_VTI_REMOTE, []byte(ip))
  3249. }
  3250. if vti.Link != 0 {
  3251. data.AddRtAttr(nl.IFLA_VTI_LINK, nl.Uint32Attr(vti.Link))
  3252. }
  3253. data.AddRtAttr(nl.IFLA_VTI_IKEY, htonl(vti.IKey))
  3254. data.AddRtAttr(nl.IFLA_VTI_OKEY, htonl(vti.OKey))
  3255. }
  3256. func parseVtiData(link Link, data []syscall.NetlinkRouteAttr) {
  3257. vti := link.(*Vti)
  3258. for _, datum := range data {
  3259. switch datum.Attr.Type {
  3260. case nl.IFLA_VTI_LOCAL:
  3261. vti.Local = net.IP(datum.Value)
  3262. case nl.IFLA_VTI_REMOTE:
  3263. vti.Remote = net.IP(datum.Value)
  3264. case nl.IFLA_VTI_IKEY:
  3265. vti.IKey = ntohl(datum.Value[0:4])
  3266. case nl.IFLA_VTI_OKEY:
  3267. vti.OKey = ntohl(datum.Value[0:4])
  3268. }
  3269. }
  3270. }
  3271. func addVrfAttrs(vrf *Vrf, linkInfo *nl.RtAttr) {
  3272. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3273. b := make([]byte, 4)
  3274. native.PutUint32(b, uint32(vrf.Table))
  3275. data.AddRtAttr(nl.IFLA_VRF_TABLE, b)
  3276. }
  3277. func parseVrfData(link Link, data []syscall.NetlinkRouteAttr) {
  3278. vrf := link.(*Vrf)
  3279. for _, datum := range data {
  3280. switch datum.Attr.Type {
  3281. case nl.IFLA_VRF_TABLE:
  3282. vrf.Table = native.Uint32(datum.Value[0:4])
  3283. }
  3284. }
  3285. }
  3286. func addBridgeAttrs(bridge *Bridge, linkInfo *nl.RtAttr) {
  3287. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3288. if bridge.MulticastSnooping != nil {
  3289. data.AddRtAttr(nl.IFLA_BR_MCAST_SNOOPING, boolToByte(*bridge.MulticastSnooping))
  3290. }
  3291. if bridge.AgeingTime != nil {
  3292. data.AddRtAttr(nl.IFLA_BR_AGEING_TIME, nl.Uint32Attr(*bridge.AgeingTime))
  3293. }
  3294. if bridge.HelloTime != nil {
  3295. data.AddRtAttr(nl.IFLA_BR_HELLO_TIME, nl.Uint32Attr(*bridge.HelloTime))
  3296. }
  3297. if bridge.VlanFiltering != nil {
  3298. data.AddRtAttr(nl.IFLA_BR_VLAN_FILTERING, boolToByte(*bridge.VlanFiltering))
  3299. }
  3300. if bridge.VlanDefaultPVID != nil {
  3301. data.AddRtAttr(nl.IFLA_BR_VLAN_DEFAULT_PVID, nl.Uint16Attr(*bridge.VlanDefaultPVID))
  3302. }
  3303. if bridge.GroupFwdMask != nil {
  3304. data.AddRtAttr(nl.IFLA_BR_GROUP_FWD_MASK, nl.Uint16Attr(*bridge.GroupFwdMask))
  3305. }
  3306. }
  3307. func parseBridgeData(bridge Link, data []syscall.NetlinkRouteAttr) {
  3308. br := bridge.(*Bridge)
  3309. for _, datum := range data {
  3310. switch datum.Attr.Type {
  3311. case nl.IFLA_BR_AGEING_TIME:
  3312. ageingTime := native.Uint32(datum.Value[0:4])
  3313. br.AgeingTime = &ageingTime
  3314. case nl.IFLA_BR_HELLO_TIME:
  3315. helloTime := native.Uint32(datum.Value[0:4])
  3316. br.HelloTime = &helloTime
  3317. case nl.IFLA_BR_MCAST_SNOOPING:
  3318. mcastSnooping := datum.Value[0] == 1
  3319. br.MulticastSnooping = &mcastSnooping
  3320. case nl.IFLA_BR_VLAN_FILTERING:
  3321. vlanFiltering := datum.Value[0] == 1
  3322. br.VlanFiltering = &vlanFiltering
  3323. case nl.IFLA_BR_VLAN_DEFAULT_PVID:
  3324. vlanDefaultPVID := native.Uint16(datum.Value[0:2])
  3325. br.VlanDefaultPVID = &vlanDefaultPVID
  3326. case nl.IFLA_BR_GROUP_FWD_MASK:
  3327. mask := native.Uint16(datum.Value[0:2])
  3328. br.GroupFwdMask = &mask
  3329. }
  3330. }
  3331. }
  3332. func addGTPAttrs(gtp *GTP, linkInfo *nl.RtAttr) {
  3333. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3334. data.AddRtAttr(nl.IFLA_GTP_FD0, nl.Uint32Attr(uint32(gtp.FD0)))
  3335. data.AddRtAttr(nl.IFLA_GTP_FD1, nl.Uint32Attr(uint32(gtp.FD1)))
  3336. data.AddRtAttr(nl.IFLA_GTP_PDP_HASHSIZE, nl.Uint32Attr(131072))
  3337. if gtp.Role != nl.GTP_ROLE_GGSN {
  3338. data.AddRtAttr(nl.IFLA_GTP_ROLE, nl.Uint32Attr(uint32(gtp.Role)))
  3339. }
  3340. }
  3341. func parseGTPData(link Link, data []syscall.NetlinkRouteAttr) {
  3342. gtp := link.(*GTP)
  3343. for _, datum := range data {
  3344. switch datum.Attr.Type {
  3345. case nl.IFLA_GTP_FD0:
  3346. gtp.FD0 = int(native.Uint32(datum.Value))
  3347. case nl.IFLA_GTP_FD1:
  3348. gtp.FD1 = int(native.Uint32(datum.Value))
  3349. case nl.IFLA_GTP_PDP_HASHSIZE:
  3350. gtp.PDPHashsize = int(native.Uint32(datum.Value))
  3351. case nl.IFLA_GTP_ROLE:
  3352. gtp.Role = int(native.Uint32(datum.Value))
  3353. }
  3354. }
  3355. }
  3356. func parseVfInfoList(data []syscall.NetlinkRouteAttr) ([]VfInfo, error) {
  3357. var vfs []VfInfo
  3358. for i, element := range data {
  3359. if element.Attr.Type != nl.IFLA_VF_INFO {
  3360. return nil, fmt.Errorf("Incorrect element type in vf info list: %d", element.Attr.Type)
  3361. }
  3362. vfAttrs, err := nl.ParseRouteAttr(element.Value)
  3363. if err != nil {
  3364. return nil, err
  3365. }
  3366. vf, err := parseVfInfo(vfAttrs, i)
  3367. if err != nil {
  3368. return nil, err
  3369. }
  3370. vfs = append(vfs, vf)
  3371. }
  3372. return vfs, nil
  3373. }
  3374. func parseVfInfo(data []syscall.NetlinkRouteAttr, id int) (VfInfo, error) {
  3375. vf := VfInfo{ID: id}
  3376. for _, element := range data {
  3377. switch element.Attr.Type {
  3378. case nl.IFLA_VF_MAC:
  3379. mac := nl.DeserializeVfMac(element.Value[:])
  3380. vf.Mac = mac.Mac[:6]
  3381. case nl.IFLA_VF_VLAN:
  3382. vl := nl.DeserializeVfVlan(element.Value[:])
  3383. vf.Vlan = int(vl.Vlan)
  3384. vf.Qos = int(vl.Qos)
  3385. case nl.IFLA_VF_VLAN_LIST:
  3386. vfVlanInfoList, err := nl.DeserializeVfVlanList(element.Value[:])
  3387. if err != nil {
  3388. return vf, err
  3389. }
  3390. vf.VlanProto = int(vfVlanInfoList[0].VlanProto)
  3391. case nl.IFLA_VF_TX_RATE:
  3392. txr := nl.DeserializeVfTxRate(element.Value[:])
  3393. vf.TxRate = int(txr.Rate)
  3394. case nl.IFLA_VF_SPOOFCHK:
  3395. sp := nl.DeserializeVfSpoofchk(element.Value[:])
  3396. vf.Spoofchk = sp.Setting != 0
  3397. case nl.IFLA_VF_LINK_STATE:
  3398. ls := nl.DeserializeVfLinkState(element.Value[:])
  3399. vf.LinkState = ls.LinkState
  3400. case nl.IFLA_VF_RATE:
  3401. vfr := nl.DeserializeVfRate(element.Value[:])
  3402. vf.MaxTxRate = vfr.MaxTxRate
  3403. vf.MinTxRate = vfr.MinTxRate
  3404. case nl.IFLA_VF_STATS:
  3405. vfstats := nl.DeserializeVfStats(element.Value[:])
  3406. vf.RxPackets = vfstats.RxPackets
  3407. vf.TxPackets = vfstats.TxPackets
  3408. vf.RxBytes = vfstats.RxBytes
  3409. vf.TxBytes = vfstats.TxBytes
  3410. vf.Multicast = vfstats.Multicast
  3411. vf.Broadcast = vfstats.Broadcast
  3412. vf.RxDropped = vfstats.RxDropped
  3413. vf.TxDropped = vfstats.TxDropped
  3414. case nl.IFLA_VF_RSS_QUERY_EN:
  3415. result := nl.DeserializeVfRssQueryEn(element.Value)
  3416. vf.RssQuery = result.Setting
  3417. case nl.IFLA_VF_TRUST:
  3418. result := nl.DeserializeVfTrust(element.Value)
  3419. vf.Trust = result.Setting
  3420. }
  3421. }
  3422. return vf, nil
  3423. }
  3424. func addXfrmiAttrs(xfrmi *Xfrmi, linkInfo *nl.RtAttr) {
  3425. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3426. data.AddRtAttr(nl.IFLA_XFRM_LINK, nl.Uint32Attr(uint32(xfrmi.ParentIndex)))
  3427. if xfrmi.Ifid != 0 {
  3428. data.AddRtAttr(nl.IFLA_XFRM_IF_ID, nl.Uint32Attr(xfrmi.Ifid))
  3429. }
  3430. }
  3431. func parseXfrmiData(link Link, data []syscall.NetlinkRouteAttr) {
  3432. xfrmi := link.(*Xfrmi)
  3433. for _, datum := range data {
  3434. switch datum.Attr.Type {
  3435. case nl.IFLA_XFRM_LINK:
  3436. xfrmi.ParentIndex = int(native.Uint32(datum.Value))
  3437. case nl.IFLA_XFRM_IF_ID:
  3438. xfrmi.Ifid = native.Uint32(datum.Value)
  3439. }
  3440. }
  3441. }
  3442. func ioctlBondSlave(cmd uintptr, link Link, master *Bond) error {
  3443. fd, err := getSocketUDP()
  3444. if err != nil {
  3445. return err
  3446. }
  3447. defer syscall.Close(fd)
  3448. ifreq := newIocltSlaveReq(link.Attrs().Name, master.Attrs().Name)
  3449. _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), cmd, uintptr(unsafe.Pointer(ifreq)))
  3450. if errno != 0 {
  3451. return fmt.Errorf("errno=%v", errno)
  3452. }
  3453. return nil
  3454. }
  3455. // LinkSetBondSlaveActive sets specified slave to ACTIVE in an `active-backup` bond link via ioctl interface.
  3456. //
  3457. // Multiple calls keeps the status unchanged(shown in the unit test).
  3458. func LinkSetBondSlaveActive(link Link, master *Bond) error {
  3459. err := ioctlBondSlave(unix.SIOCBONDCHANGEACTIVE, link, master)
  3460. if err != nil {
  3461. return fmt.Errorf("Failed to set slave %q active in %q, %v", link.Attrs().Name, master.Attrs().Name, err)
  3462. }
  3463. return nil
  3464. }
  3465. // LinkSetBondSlave add slave to bond link via ioctl interface.
  3466. func LinkSetBondSlave(link Link, master *Bond) error {
  3467. err := ioctlBondSlave(unix.SIOCBONDENSLAVE, link, master)
  3468. if err != nil {
  3469. return fmt.Errorf("Failed to enslave %q to %q, %v", link.Attrs().Name, master.Attrs().Name, err)
  3470. }
  3471. return nil
  3472. }
  3473. // LinkSetBondSlave removes specified slave from bond link via ioctl interface.
  3474. func LinkDelBondSlave(link Link, master *Bond) error {
  3475. err := ioctlBondSlave(unix.SIOCBONDRELEASE, link, master)
  3476. if err != nil {
  3477. return fmt.Errorf("Failed to del slave %q from %q, %v", link.Attrs().Name, master.Attrs().Name, err)
  3478. }
  3479. return nil
  3480. }
  3481. // LinkSetBondSlaveQueueId modify bond slave queue-id.
  3482. func (h *Handle) LinkSetBondSlaveQueueId(link Link, queueId uint16) error {
  3483. base := link.Attrs()
  3484. h.ensureIndex(base)
  3485. req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
  3486. msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
  3487. msg.Index = int32(base.Index)
  3488. req.AddData(msg)
  3489. linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil)
  3490. data := linkInfo.AddRtAttr(nl.IFLA_INFO_SLAVE_DATA, nil)
  3491. data.AddRtAttr(nl.IFLA_BOND_SLAVE_QUEUE_ID, nl.Uint16Attr(queueId))
  3492. req.AddData(linkInfo)
  3493. _, err := req.Execute(unix.NETLINK_ROUTE, 0)
  3494. return err
  3495. }
  3496. // LinkSetBondSlaveQueueId modify bond slave queue-id.
  3497. func LinkSetBondSlaveQueueId(link Link, queueId uint16) error {
  3498. return pkgHandle.LinkSetBondSlaveQueueId(link, queueId)
  3499. }
  3500. func vethStatsSerialize(stats ethtoolStats) ([]byte, error) {
  3501. statsSize := int(unsafe.Sizeof(stats)) + int(stats.nStats)*int(unsafe.Sizeof(uint64(0)))
  3502. b := make([]byte, 0, statsSize)
  3503. buf := bytes.NewBuffer(b)
  3504. err := binary.Write(buf, nl.NativeEndian(), stats)
  3505. return buf.Bytes()[:statsSize], err
  3506. }
  3507. type vethEthtoolStats struct {
  3508. Cmd uint32
  3509. NStats uint32
  3510. Peer uint64
  3511. // Newer kernels have XDP stats in here, but we only care
  3512. // to extract the peer ifindex here.
  3513. }
  3514. func vethStatsDeserialize(b []byte) (vethEthtoolStats, error) {
  3515. var stats = vethEthtoolStats{}
  3516. err := binary.Read(bytes.NewReader(b), nl.NativeEndian(), &stats)
  3517. return stats, err
  3518. }
  3519. // VethPeerIndex get veth peer index.
  3520. func VethPeerIndex(link *Veth) (int, error) {
  3521. fd, err := getSocketUDP()
  3522. if err != nil {
  3523. return -1, err
  3524. }
  3525. defer syscall.Close(fd)
  3526. ifreq, sSet := newIocltStringSetReq(link.Name)
  3527. _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq)))
  3528. if errno != 0 {
  3529. return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno)
  3530. }
  3531. stats := ethtoolStats{
  3532. cmd: ETHTOOL_GSTATS,
  3533. nStats: sSet.data[0],
  3534. }
  3535. buffer, err := vethStatsSerialize(stats)
  3536. if err != nil {
  3537. return -1, err
  3538. }
  3539. ifreq.Data = uintptr(unsafe.Pointer(&buffer[0]))
  3540. _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq)))
  3541. if errno != 0 {
  3542. return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno)
  3543. }
  3544. vstats, err := vethStatsDeserialize(buffer)
  3545. if err != nil {
  3546. return -1, err
  3547. }
  3548. return int(vstats.Peer), nil
  3549. }
  3550. func parseTuntapData(link Link, data []syscall.NetlinkRouteAttr) {
  3551. tuntap := link.(*Tuntap)
  3552. for _, datum := range data {
  3553. switch datum.Attr.Type {
  3554. case nl.IFLA_TUN_OWNER:
  3555. tuntap.Owner = native.Uint32(datum.Value)
  3556. case nl.IFLA_TUN_GROUP:
  3557. tuntap.Group = native.Uint32(datum.Value)
  3558. case nl.IFLA_TUN_TYPE:
  3559. tuntap.Mode = TuntapMode(uint8(datum.Value[0]))
  3560. case nl.IFLA_TUN_PI:
  3561. if datum.Value[0] == 0 {
  3562. tuntap.Flags |= TUNTAP_NO_PI
  3563. }
  3564. case nl.IFLA_TUN_VNET_HDR:
  3565. if datum.Value[0] == 1 {
  3566. tuntap.Flags |= TUNTAP_VNET_HDR
  3567. }
  3568. case nl.IFLA_TUN_PERSIST:
  3569. tuntap.NonPersist = false
  3570. if uint8(datum.Value[0]) == 0 {
  3571. tuntap.NonPersist = true
  3572. }
  3573. case nl.IFLA_TUN_MULTI_QUEUE:
  3574. if datum.Value[0] == 1 {
  3575. tuntap.Flags |= TUNTAP_MULTI_QUEUE
  3576. }
  3577. case nl.IFLA_TUN_NUM_QUEUES:
  3578. tuntap.Queues = int(native.Uint32(datum.Value))
  3579. case nl.IFLA_TUN_NUM_DISABLED_QUEUES:
  3580. tuntap.DisabledQueues = int(native.Uint32(datum.Value))
  3581. }
  3582. }
  3583. }
  3584. func parseIPoIBData(link Link, data []syscall.NetlinkRouteAttr) {
  3585. ipoib := link.(*IPoIB)
  3586. for _, datum := range data {
  3587. switch datum.Attr.Type {
  3588. case nl.IFLA_IPOIB_PKEY:
  3589. ipoib.Pkey = uint16(native.Uint16(datum.Value))
  3590. case nl.IFLA_IPOIB_MODE:
  3591. ipoib.Mode = IPoIBMode(native.Uint16(datum.Value))
  3592. case nl.IFLA_IPOIB_UMCAST:
  3593. ipoib.Umcast = uint16(native.Uint16(datum.Value))
  3594. }
  3595. }
  3596. }
  3597. func parseCanData(link Link, data []syscall.NetlinkRouteAttr) {
  3598. can := link.(*Can)
  3599. for _, datum := range data {
  3600. switch datum.Attr.Type {
  3601. case nl.IFLA_CAN_BITTIMING:
  3602. can.BitRate = native.Uint32(datum.Value)
  3603. can.SamplePoint = native.Uint32(datum.Value[4:])
  3604. can.TimeQuanta = native.Uint32(datum.Value[8:])
  3605. can.PropagationSegment = native.Uint32(datum.Value[12:])
  3606. can.PhaseSegment1 = native.Uint32(datum.Value[16:])
  3607. can.PhaseSegment2 = native.Uint32(datum.Value[20:])
  3608. can.SyncJumpWidth = native.Uint32(datum.Value[24:])
  3609. can.BitRatePreScaler = native.Uint32(datum.Value[28:])
  3610. case nl.IFLA_CAN_BITTIMING_CONST:
  3611. can.Name = string(datum.Value[:16])
  3612. can.TimeSegment1Min = native.Uint32(datum.Value[16:])
  3613. can.TimeSegment1Max = native.Uint32(datum.Value[20:])
  3614. can.TimeSegment2Min = native.Uint32(datum.Value[24:])
  3615. can.TimeSegment2Max = native.Uint32(datum.Value[28:])
  3616. can.SyncJumpWidthMax = native.Uint32(datum.Value[32:])
  3617. can.BitRatePreScalerMin = native.Uint32(datum.Value[36:])
  3618. can.BitRatePreScalerMax = native.Uint32(datum.Value[40:])
  3619. can.BitRatePreScalerInc = native.Uint32(datum.Value[44:])
  3620. case nl.IFLA_CAN_CLOCK:
  3621. can.ClockFrequency = native.Uint32(datum.Value)
  3622. case nl.IFLA_CAN_STATE:
  3623. can.State = native.Uint32(datum.Value)
  3624. case nl.IFLA_CAN_CTRLMODE:
  3625. can.Mask = native.Uint32(datum.Value)
  3626. can.Flags = native.Uint32(datum.Value[4:])
  3627. case nl.IFLA_CAN_BERR_COUNTER:
  3628. can.TxError = native.Uint16(datum.Value)
  3629. can.RxError = native.Uint16(datum.Value[2:])
  3630. case nl.IFLA_CAN_RESTART_MS:
  3631. can.RestartMs = native.Uint32(datum.Value)
  3632. case nl.IFLA_CAN_DATA_BITTIMING_CONST:
  3633. case nl.IFLA_CAN_RESTART:
  3634. case nl.IFLA_CAN_DATA_BITTIMING:
  3635. case nl.IFLA_CAN_TERMINATION:
  3636. case nl.IFLA_CAN_TERMINATION_CONST:
  3637. case nl.IFLA_CAN_BITRATE_CONST:
  3638. case nl.IFLA_CAN_DATA_BITRATE_CONST:
  3639. case nl.IFLA_CAN_BITRATE_MAX:
  3640. }
  3641. }
  3642. }
  3643. func addIPoIBAttrs(ipoib *IPoIB, linkInfo *nl.RtAttr) {
  3644. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3645. data.AddRtAttr(nl.IFLA_IPOIB_PKEY, nl.Uint16Attr(uint16(ipoib.Pkey)))
  3646. data.AddRtAttr(nl.IFLA_IPOIB_MODE, nl.Uint16Attr(uint16(ipoib.Mode)))
  3647. data.AddRtAttr(nl.IFLA_IPOIB_UMCAST, nl.Uint16Attr(uint16(ipoib.Umcast)))
  3648. }
  3649. func addBareUDPAttrs(bareudp *BareUDP, linkInfo *nl.RtAttr) {
  3650. data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
  3651. data.AddRtAttr(nl.IFLA_BAREUDP_PORT, nl.Uint16Attr(nl.Swap16(bareudp.Port)))
  3652. data.AddRtAttr(nl.IFLA_BAREUDP_ETHERTYPE, nl.Uint16Attr(nl.Swap16(bareudp.EtherType)))
  3653. if bareudp.SrcPortMin != 0 {
  3654. data.AddRtAttr(nl.IFLA_BAREUDP_SRCPORT_MIN, nl.Uint16Attr(bareudp.SrcPortMin))
  3655. }
  3656. if bareudp.MultiProto {
  3657. data.AddRtAttr(nl.IFLA_BAREUDP_MULTIPROTO_MODE, []byte{})
  3658. }
  3659. }
  3660. func parseBareUDPData(link Link, data []syscall.NetlinkRouteAttr) {
  3661. bareudp := link.(*BareUDP)
  3662. for _, attr := range data {
  3663. switch attr.Attr.Type {
  3664. case nl.IFLA_BAREUDP_PORT:
  3665. bareudp.Port = binary.BigEndian.Uint16(attr.Value)
  3666. case nl.IFLA_BAREUDP_ETHERTYPE:
  3667. bareudp.EtherType = binary.BigEndian.Uint16(attr.Value)
  3668. case nl.IFLA_BAREUDP_SRCPORT_MIN:
  3669. bareudp.SrcPortMin = native.Uint16(attr.Value)
  3670. case nl.IFLA_BAREUDP_MULTIPROTO_MODE:
  3671. bareudp.MultiProto = true
  3672. }
  3673. }
  3674. }