link_linux.go 100 KB

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