netlink_linux.go 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307
  1. package netlink
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "io"
  6. "math/rand"
  7. "net"
  8. "os"
  9. "sync/atomic"
  10. "syscall"
  11. "unsafe"
  12. )
  13. const (
  14. IFNAMSIZ = 16
  15. DEFAULT_CHANGE = 0xFFFFFFFF
  16. IFLA_INFO_KIND = 1
  17. IFLA_INFO_DATA = 2
  18. VETH_INFO_PEER = 1
  19. IFLA_MACVLAN_MODE = 1
  20. IFLA_VLAN_ID = 1
  21. IFLA_NET_NS_FD = 28
  22. IFLA_ADDRESS = 1
  23. IFLA_BRPORT_MODE = 4
  24. SIOC_BRADDBR = 0x89a0
  25. SIOC_BRDELBR = 0x89a1
  26. SIOC_BRADDIF = 0x89a2
  27. )
  28. const (
  29. MACVLAN_MODE_PRIVATE = 1 << iota
  30. MACVLAN_MODE_VEPA
  31. MACVLAN_MODE_BRIDGE
  32. MACVLAN_MODE_PASSTHRU
  33. )
  34. var nextSeqNr uint32
  35. type ifreqHwaddr struct {
  36. IfrnName [IFNAMSIZ]byte
  37. IfruHwaddr syscall.RawSockaddr
  38. }
  39. type ifreqIndex struct {
  40. IfrnName [IFNAMSIZ]byte
  41. IfruIndex int32
  42. }
  43. type ifreqFlags struct {
  44. IfrnName [IFNAMSIZ]byte
  45. Ifruflags uint16
  46. }
  47. var native binary.ByteOrder
  48. func init() {
  49. var x uint32 = 0x01020304
  50. if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
  51. native = binary.BigEndian
  52. } else {
  53. native = binary.LittleEndian
  54. }
  55. }
  56. func getIpFamily(ip net.IP) int {
  57. if len(ip) <= net.IPv4len {
  58. return syscall.AF_INET
  59. }
  60. if ip.To4() != nil {
  61. return syscall.AF_INET
  62. }
  63. return syscall.AF_INET6
  64. }
  65. type NetlinkRequestData interface {
  66. Len() int
  67. ToWireFormat() []byte
  68. }
  69. type IfInfomsg struct {
  70. syscall.IfInfomsg
  71. }
  72. func newIfInfomsg(family int) *IfInfomsg {
  73. return &IfInfomsg{
  74. IfInfomsg: syscall.IfInfomsg{
  75. Family: uint8(family),
  76. },
  77. }
  78. }
  79. func newIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
  80. msg := newIfInfomsg(family)
  81. parent.children = append(parent.children, msg)
  82. return msg
  83. }
  84. func (msg *IfInfomsg) ToWireFormat() []byte {
  85. length := syscall.SizeofIfInfomsg
  86. b := make([]byte, length)
  87. b[0] = msg.Family
  88. b[1] = 0
  89. native.PutUint16(b[2:4], msg.Type)
  90. native.PutUint32(b[4:8], uint32(msg.Index))
  91. native.PutUint32(b[8:12], msg.Flags)
  92. native.PutUint32(b[12:16], msg.Change)
  93. return b
  94. }
  95. func (msg *IfInfomsg) Len() int {
  96. return syscall.SizeofIfInfomsg
  97. }
  98. type IfAddrmsg struct {
  99. syscall.IfAddrmsg
  100. }
  101. func newIfAddrmsg(family int) *IfAddrmsg {
  102. return &IfAddrmsg{
  103. IfAddrmsg: syscall.IfAddrmsg{
  104. Family: uint8(family),
  105. },
  106. }
  107. }
  108. func (msg *IfAddrmsg) ToWireFormat() []byte {
  109. length := syscall.SizeofIfAddrmsg
  110. b := make([]byte, length)
  111. b[0] = msg.Family
  112. b[1] = msg.Prefixlen
  113. b[2] = msg.Flags
  114. b[3] = msg.Scope
  115. native.PutUint32(b[4:8], msg.Index)
  116. return b
  117. }
  118. func (msg *IfAddrmsg) Len() int {
  119. return syscall.SizeofIfAddrmsg
  120. }
  121. type RtMsg struct {
  122. syscall.RtMsg
  123. }
  124. func newRtMsg() *RtMsg {
  125. return &RtMsg{
  126. RtMsg: syscall.RtMsg{
  127. Table: syscall.RT_TABLE_MAIN,
  128. Scope: syscall.RT_SCOPE_UNIVERSE,
  129. Protocol: syscall.RTPROT_BOOT,
  130. Type: syscall.RTN_UNICAST,
  131. },
  132. }
  133. }
  134. func (msg *RtMsg) ToWireFormat() []byte {
  135. length := syscall.SizeofRtMsg
  136. b := make([]byte, length)
  137. b[0] = msg.Family
  138. b[1] = msg.Dst_len
  139. b[2] = msg.Src_len
  140. b[3] = msg.Tos
  141. b[4] = msg.Table
  142. b[5] = msg.Protocol
  143. b[6] = msg.Scope
  144. b[7] = msg.Type
  145. native.PutUint32(b[8:12], msg.Flags)
  146. return b
  147. }
  148. func (msg *RtMsg) Len() int {
  149. return syscall.SizeofRtMsg
  150. }
  151. func rtaAlignOf(attrlen int) int {
  152. return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1)
  153. }
  154. type RtAttr struct {
  155. syscall.RtAttr
  156. Data []byte
  157. children []NetlinkRequestData
  158. }
  159. func newRtAttr(attrType int, data []byte) *RtAttr {
  160. return &RtAttr{
  161. RtAttr: syscall.RtAttr{
  162. Type: uint16(attrType),
  163. },
  164. children: []NetlinkRequestData{},
  165. Data: data,
  166. }
  167. }
  168. func newRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
  169. attr := newRtAttr(attrType, data)
  170. parent.children = append(parent.children, attr)
  171. return attr
  172. }
  173. func (a *RtAttr) Len() int {
  174. if len(a.children) == 0 {
  175. return (syscall.SizeofRtAttr + len(a.Data))
  176. }
  177. l := 0
  178. for _, child := range a.children {
  179. l += child.Len()
  180. }
  181. l += syscall.SizeofRtAttr
  182. return rtaAlignOf(l + len(a.Data))
  183. }
  184. func (a *RtAttr) ToWireFormat() []byte {
  185. length := a.Len()
  186. buf := make([]byte, rtaAlignOf(length))
  187. if a.Data != nil {
  188. copy(buf[4:], a.Data)
  189. } else {
  190. next := 4
  191. for _, child := range a.children {
  192. childBuf := child.ToWireFormat()
  193. copy(buf[next:], childBuf)
  194. next += rtaAlignOf(len(childBuf))
  195. }
  196. }
  197. if l := uint16(length); l != 0 {
  198. native.PutUint16(buf[0:2], l)
  199. }
  200. native.PutUint16(buf[2:4], a.Type)
  201. return buf
  202. }
  203. func uint32Attr(t int, n uint32) *RtAttr {
  204. buf := make([]byte, 4)
  205. native.PutUint32(buf, n)
  206. return newRtAttr(t, buf)
  207. }
  208. type NetlinkRequest struct {
  209. syscall.NlMsghdr
  210. Data []NetlinkRequestData
  211. }
  212. func (rr *NetlinkRequest) ToWireFormat() []byte {
  213. length := rr.Len
  214. dataBytes := make([][]byte, len(rr.Data))
  215. for i, data := range rr.Data {
  216. dataBytes[i] = data.ToWireFormat()
  217. length += uint32(len(dataBytes[i]))
  218. }
  219. b := make([]byte, length)
  220. native.PutUint32(b[0:4], length)
  221. native.PutUint16(b[4:6], rr.Type)
  222. native.PutUint16(b[6:8], rr.Flags)
  223. native.PutUint32(b[8:12], rr.Seq)
  224. native.PutUint32(b[12:16], rr.Pid)
  225. next := 16
  226. for _, data := range dataBytes {
  227. copy(b[next:], data)
  228. next += len(data)
  229. }
  230. return b
  231. }
  232. func (rr *NetlinkRequest) AddData(data NetlinkRequestData) {
  233. if data != nil {
  234. rr.Data = append(rr.Data, data)
  235. }
  236. }
  237. func newNetlinkRequest(proto, flags int) *NetlinkRequest {
  238. return &NetlinkRequest{
  239. NlMsghdr: syscall.NlMsghdr{
  240. Len: uint32(syscall.NLMSG_HDRLEN),
  241. Type: uint16(proto),
  242. Flags: syscall.NLM_F_REQUEST | uint16(flags),
  243. Seq: atomic.AddUint32(&nextSeqNr, 1),
  244. },
  245. }
  246. }
  247. type NetlinkSocket struct {
  248. fd int
  249. lsa syscall.SockaddrNetlink
  250. }
  251. func getNetlinkSocket() (*NetlinkSocket, error) {
  252. fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_ROUTE)
  253. if err != nil {
  254. return nil, err
  255. }
  256. s := &NetlinkSocket{
  257. fd: fd,
  258. }
  259. s.lsa.Family = syscall.AF_NETLINK
  260. if err := syscall.Bind(fd, &s.lsa); err != nil {
  261. syscall.Close(fd)
  262. return nil, err
  263. }
  264. return s, nil
  265. }
  266. func (s *NetlinkSocket) Close() {
  267. syscall.Close(s.fd)
  268. }
  269. func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
  270. if err := syscall.Sendto(s.fd, request.ToWireFormat(), 0, &s.lsa); err != nil {
  271. return err
  272. }
  273. return nil
  274. }
  275. func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
  276. rb := make([]byte, syscall.Getpagesize())
  277. nr, _, err := syscall.Recvfrom(s.fd, rb, 0)
  278. if err != nil {
  279. return nil, err
  280. }
  281. if nr < syscall.NLMSG_HDRLEN {
  282. return nil, ErrShortResponse
  283. }
  284. rb = rb[:nr]
  285. return syscall.ParseNetlinkMessage(rb)
  286. }
  287. func (s *NetlinkSocket) GetPid() (uint32, error) {
  288. lsa, err := syscall.Getsockname(s.fd)
  289. if err != nil {
  290. return 0, err
  291. }
  292. switch v := lsa.(type) {
  293. case *syscall.SockaddrNetlink:
  294. return v.Pid, nil
  295. }
  296. return 0, ErrWrongSockType
  297. }
  298. func (s *NetlinkSocket) CheckMessage(m syscall.NetlinkMessage, seq, pid uint32) error {
  299. if m.Header.Seq != seq {
  300. return fmt.Errorf("netlink: invalid seq %d, expected %d", m.Header.Seq, seq)
  301. }
  302. if m.Header.Pid != pid {
  303. return fmt.Errorf("netlink: wrong pid %d, expected %d", m.Header.Pid, pid)
  304. }
  305. if m.Header.Type == syscall.NLMSG_DONE {
  306. return io.EOF
  307. }
  308. if m.Header.Type == syscall.NLMSG_ERROR {
  309. e := int32(native.Uint32(m.Data[0:4]))
  310. if e == 0 {
  311. return io.EOF
  312. }
  313. return syscall.Errno(-e)
  314. }
  315. return nil
  316. }
  317. func (s *NetlinkSocket) HandleAck(seq uint32) error {
  318. pid, err := s.GetPid()
  319. if err != nil {
  320. return err
  321. }
  322. outer:
  323. for {
  324. msgs, err := s.Receive()
  325. if err != nil {
  326. return err
  327. }
  328. for _, m := range msgs {
  329. if err := s.CheckMessage(m, seq, pid); err != nil {
  330. if err == io.EOF {
  331. break outer
  332. }
  333. return err
  334. }
  335. }
  336. }
  337. return nil
  338. }
  339. func zeroTerminated(s string) []byte {
  340. return []byte(s + "\000")
  341. }
  342. func nonZeroTerminated(s string) []byte {
  343. return []byte(s)
  344. }
  345. // Add a new network link of a specified type.
  346. // This is identical to running: ip link add $name type $linkType
  347. func NetworkLinkAdd(name string, linkType string) error {
  348. if name == "" || linkType == "" {
  349. return fmt.Errorf("Neither link name nor link type can be empty!")
  350. }
  351. s, err := getNetlinkSocket()
  352. if err != nil {
  353. return err
  354. }
  355. defer s.Close()
  356. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
  357. msg := newIfInfomsg(syscall.AF_UNSPEC)
  358. wb.AddData(msg)
  359. linkInfo := newRtAttr(syscall.IFLA_LINKINFO, nil)
  360. newRtAttrChild(linkInfo, IFLA_INFO_KIND, nonZeroTerminated(linkType))
  361. wb.AddData(linkInfo)
  362. nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name))
  363. wb.AddData(nameData)
  364. if err := s.Send(wb); err != nil {
  365. return err
  366. }
  367. return s.HandleAck(wb.Seq)
  368. }
  369. // Delete a network link.
  370. // This is identical to running: ip link del $name
  371. func NetworkLinkDel(name string) error {
  372. if name == "" {
  373. return fmt.Errorf("Network link name can not be empty!")
  374. }
  375. s, err := getNetlinkSocket()
  376. if err != nil {
  377. return err
  378. }
  379. defer s.Close()
  380. iface, err := net.InterfaceByName(name)
  381. if err != nil {
  382. return err
  383. }
  384. wb := newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK)
  385. msg := newIfInfomsg(syscall.AF_UNSPEC)
  386. msg.Index = int32(iface.Index)
  387. wb.AddData(msg)
  388. if err := s.Send(wb); err != nil {
  389. return err
  390. }
  391. return s.HandleAck(wb.Seq)
  392. }
  393. // Bring up a particular network interface.
  394. // This is identical to running: ip link set dev $name up
  395. func NetworkLinkUp(iface *net.Interface) error {
  396. s, err := getNetlinkSocket()
  397. if err != nil {
  398. return err
  399. }
  400. defer s.Close()
  401. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
  402. msg := newIfInfomsg(syscall.AF_UNSPEC)
  403. msg.Index = int32(iface.Index)
  404. msg.Flags = syscall.IFF_UP
  405. msg.Change = syscall.IFF_UP
  406. wb.AddData(msg)
  407. if err := s.Send(wb); err != nil {
  408. return err
  409. }
  410. return s.HandleAck(wb.Seq)
  411. }
  412. // Bring down a particular network interface.
  413. // This is identical to running: ip link set $name down
  414. func NetworkLinkDown(iface *net.Interface) error {
  415. s, err := getNetlinkSocket()
  416. if err != nil {
  417. return err
  418. }
  419. defer s.Close()
  420. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
  421. msg := newIfInfomsg(syscall.AF_UNSPEC)
  422. msg.Index = int32(iface.Index)
  423. msg.Flags = 0 & ^syscall.IFF_UP
  424. msg.Change = DEFAULT_CHANGE
  425. wb.AddData(msg)
  426. if err := s.Send(wb); err != nil {
  427. return err
  428. }
  429. return s.HandleAck(wb.Seq)
  430. }
  431. // Set link layer address ie. MAC Address.
  432. // This is identical to running: ip link set dev $name address $macaddress
  433. func NetworkSetMacAddress(iface *net.Interface, macaddr string) error {
  434. s, err := getNetlinkSocket()
  435. if err != nil {
  436. return err
  437. }
  438. defer s.Close()
  439. hwaddr, err := net.ParseMAC(macaddr)
  440. if err != nil {
  441. return err
  442. }
  443. var (
  444. MULTICAST byte = 0x1
  445. )
  446. if hwaddr[0]&0x1 == MULTICAST {
  447. return fmt.Errorf("Multicast MAC Address is not supported: %s", macaddr)
  448. }
  449. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  450. msg := newIfInfomsg(syscall.AF_UNSPEC)
  451. msg.Index = int32(iface.Index)
  452. msg.Change = DEFAULT_CHANGE
  453. wb.AddData(msg)
  454. macdata := make([]byte, 6)
  455. copy(macdata, hwaddr)
  456. data := newRtAttr(IFLA_ADDRESS, macdata)
  457. wb.AddData(data)
  458. if err := s.Send(wb); err != nil {
  459. return err
  460. }
  461. return s.HandleAck(wb.Seq)
  462. }
  463. // Set link Maximum Transmission Unit
  464. // This is identical to running: ip link set dev $name mtu $MTU
  465. // bridge is a bitch here https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=292088
  466. // https://bugzilla.redhat.com/show_bug.cgi?id=697021
  467. // There is a discussion about how to deal with ifcs joining bridge with MTU > 1500
  468. // Regular network nterfaces do seem to work though!
  469. func NetworkSetMTU(iface *net.Interface, mtu int) error {
  470. s, err := getNetlinkSocket()
  471. if err != nil {
  472. return err
  473. }
  474. defer s.Close()
  475. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  476. msg := newIfInfomsg(syscall.AF_UNSPEC)
  477. msg.Type = syscall.RTM_SETLINK
  478. msg.Flags = syscall.NLM_F_REQUEST
  479. msg.Index = int32(iface.Index)
  480. msg.Change = DEFAULT_CHANGE
  481. wb.AddData(msg)
  482. wb.AddData(uint32Attr(syscall.IFLA_MTU, uint32(mtu)))
  483. if err := s.Send(wb); err != nil {
  484. return err
  485. }
  486. return s.HandleAck(wb.Seq)
  487. }
  488. // Set link queue length
  489. // This is identical to running: ip link set dev $name txqueuelen $QLEN
  490. func NetworkSetTxQueueLen(iface *net.Interface, txQueueLen int) error {
  491. s, err := getNetlinkSocket()
  492. if err != nil {
  493. return err
  494. }
  495. defer s.Close()
  496. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  497. msg := newIfInfomsg(syscall.AF_UNSPEC)
  498. msg.Type = syscall.RTM_SETLINK
  499. msg.Flags = syscall.NLM_F_REQUEST
  500. msg.Index = int32(iface.Index)
  501. msg.Change = DEFAULT_CHANGE
  502. wb.AddData(msg)
  503. wb.AddData(uint32Attr(syscall.IFLA_TXQLEN, uint32(txQueueLen)))
  504. if err := s.Send(wb); err != nil {
  505. return err
  506. }
  507. return s.HandleAck(wb.Seq)
  508. }
  509. func networkMasterAction(iface *net.Interface, rtattr *RtAttr) error {
  510. s, err := getNetlinkSocket()
  511. if err != nil {
  512. return err
  513. }
  514. defer s.Close()
  515. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  516. msg := newIfInfomsg(syscall.AF_UNSPEC)
  517. msg.Type = syscall.RTM_SETLINK
  518. msg.Flags = syscall.NLM_F_REQUEST
  519. msg.Index = int32(iface.Index)
  520. msg.Change = DEFAULT_CHANGE
  521. wb.AddData(msg)
  522. wb.AddData(rtattr)
  523. if err := s.Send(wb); err != nil {
  524. return err
  525. }
  526. return s.HandleAck(wb.Seq)
  527. }
  528. // Add an interface to bridge.
  529. // This is identical to running: ip link set $name master $master
  530. func NetworkSetMaster(iface, master *net.Interface) error {
  531. data := uint32Attr(syscall.IFLA_MASTER, uint32(master.Index))
  532. return networkMasterAction(iface, data)
  533. }
  534. // Remove an interface from the bridge
  535. // This is is identical to to running: ip link $name set nomaster
  536. func NetworkSetNoMaster(iface *net.Interface) error {
  537. data := uint32Attr(syscall.IFLA_MASTER, 0)
  538. return networkMasterAction(iface, data)
  539. }
  540. func networkSetNsAction(iface *net.Interface, rtattr *RtAttr) error {
  541. s, err := getNetlinkSocket()
  542. if err != nil {
  543. return err
  544. }
  545. defer s.Close()
  546. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
  547. msg := newIfInfomsg(syscall.AF_UNSPEC)
  548. msg.Index = int32(iface.Index)
  549. wb.AddData(msg)
  550. wb.AddData(rtattr)
  551. if err := s.Send(wb); err != nil {
  552. return err
  553. }
  554. return s.HandleAck(wb.Seq)
  555. }
  556. // Move a particular network interface to a particular network namespace
  557. // specified by PID. This is identical to running: ip link set dev $name netns $pid
  558. func NetworkSetNsPid(iface *net.Interface, nspid int) error {
  559. data := uint32Attr(syscall.IFLA_NET_NS_PID, uint32(nspid))
  560. return networkSetNsAction(iface, data)
  561. }
  562. // Move a particular network interface to a particular mounted
  563. // network namespace specified by file descriptor.
  564. // This is idential to running: ip link set dev $name netns $fd
  565. func NetworkSetNsFd(iface *net.Interface, fd int) error {
  566. data := uint32Attr(IFLA_NET_NS_FD, uint32(fd))
  567. return networkSetNsAction(iface, data)
  568. }
  569. // Rename a particular interface to a different name
  570. // !!! Note that you can't rename an active interface. You need to bring it down before renaming it.
  571. // This is identical to running: ip link set dev ${oldName} name ${newName}
  572. func NetworkChangeName(iface *net.Interface, newName string) error {
  573. if len(newName) >= IFNAMSIZ {
  574. return fmt.Errorf("Interface name %s too long", newName)
  575. }
  576. s, err := getNetlinkSocket()
  577. if err != nil {
  578. return err
  579. }
  580. defer s.Close()
  581. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  582. msg := newIfInfomsg(syscall.AF_UNSPEC)
  583. msg.Index = int32(iface.Index)
  584. msg.Change = DEFAULT_CHANGE
  585. wb.AddData(msg)
  586. nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(newName))
  587. wb.AddData(nameData)
  588. if err := s.Send(wb); err != nil {
  589. return err
  590. }
  591. return s.HandleAck(wb.Seq)
  592. }
  593. // Add a new VETH pair link on the host
  594. // This is identical to running: ip link add name $name type veth peer name $peername
  595. func NetworkCreateVethPair(name1, name2 string, txQueueLen int) error {
  596. s, err := getNetlinkSocket()
  597. if err != nil {
  598. return err
  599. }
  600. defer s.Close()
  601. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
  602. msg := newIfInfomsg(syscall.AF_UNSPEC)
  603. wb.AddData(msg)
  604. nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name1))
  605. wb.AddData(nameData)
  606. txqLen := make([]byte, 4)
  607. native.PutUint32(txqLen, uint32(txQueueLen))
  608. txqData := newRtAttr(syscall.IFLA_TXQLEN, txqLen)
  609. wb.AddData(txqData)
  610. nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil)
  611. newRtAttrChild(nest1, IFLA_INFO_KIND, zeroTerminated("veth"))
  612. nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil)
  613. nest3 := newRtAttrChild(nest2, VETH_INFO_PEER, nil)
  614. newIfInfomsgChild(nest3, syscall.AF_UNSPEC)
  615. newRtAttrChild(nest3, syscall.IFLA_IFNAME, zeroTerminated(name2))
  616. txqLen2 := make([]byte, 4)
  617. native.PutUint32(txqLen2, uint32(txQueueLen))
  618. newRtAttrChild(nest3, syscall.IFLA_TXQLEN, txqLen2)
  619. wb.AddData(nest1)
  620. if err := s.Send(wb); err != nil {
  621. return err
  622. }
  623. if err := s.HandleAck(wb.Seq); err != nil {
  624. if os.IsExist(err) {
  625. return ErrInterfaceExists
  626. }
  627. return err
  628. }
  629. return nil
  630. }
  631. // Add a new VLAN interface with masterDev as its upper device
  632. // This is identical to running:
  633. // ip link add name $name link $masterdev type vlan id $id
  634. func NetworkLinkAddVlan(masterDev, vlanDev string, vlanId uint16) error {
  635. s, err := getNetlinkSocket()
  636. if err != nil {
  637. return err
  638. }
  639. defer s.Close()
  640. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
  641. masterDevIfc, err := net.InterfaceByName(masterDev)
  642. if err != nil {
  643. return err
  644. }
  645. msg := newIfInfomsg(syscall.AF_UNSPEC)
  646. wb.AddData(msg)
  647. nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil)
  648. newRtAttrChild(nest1, IFLA_INFO_KIND, nonZeroTerminated("vlan"))
  649. nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil)
  650. vlanData := make([]byte, 2)
  651. native.PutUint16(vlanData, vlanId)
  652. newRtAttrChild(nest2, IFLA_VLAN_ID, vlanData)
  653. wb.AddData(nest1)
  654. wb.AddData(uint32Attr(syscall.IFLA_LINK, uint32(masterDevIfc.Index)))
  655. wb.AddData(newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(vlanDev)))
  656. if err := s.Send(wb); err != nil {
  657. return err
  658. }
  659. return s.HandleAck(wb.Seq)
  660. }
  661. // MacVlan link has LowerDev, UpperDev and operates in Mode mode
  662. // This simplifies the code when creating MacVlan or MacVtap interface
  663. type MacVlanLink struct {
  664. MasterDev string
  665. SlaveDev string
  666. mode string
  667. }
  668. func (m MacVlanLink) Mode() uint32 {
  669. modeMap := map[string]uint32{
  670. "private": MACVLAN_MODE_PRIVATE,
  671. "vepa": MACVLAN_MODE_VEPA,
  672. "bridge": MACVLAN_MODE_BRIDGE,
  673. "passthru": MACVLAN_MODE_PASSTHRU,
  674. }
  675. return modeMap[m.mode]
  676. }
  677. // Add MAC VLAN network interface with masterDev as its upper device
  678. // This is identical to running:
  679. // ip link add name $name link $masterdev type macvlan mode $mode
  680. func networkLinkMacVlan(dev_type string, mcvln *MacVlanLink) error {
  681. s, err := getNetlinkSocket()
  682. if err != nil {
  683. return err
  684. }
  685. defer s.Close()
  686. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
  687. masterDevIfc, err := net.InterfaceByName(mcvln.MasterDev)
  688. if err != nil {
  689. return err
  690. }
  691. msg := newIfInfomsg(syscall.AF_UNSPEC)
  692. wb.AddData(msg)
  693. nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil)
  694. newRtAttrChild(nest1, IFLA_INFO_KIND, nonZeroTerminated(dev_type))
  695. nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil)
  696. macVlanData := make([]byte, 4)
  697. native.PutUint32(macVlanData, mcvln.Mode())
  698. newRtAttrChild(nest2, IFLA_MACVLAN_MODE, macVlanData)
  699. wb.AddData(nest1)
  700. wb.AddData(uint32Attr(syscall.IFLA_LINK, uint32(masterDevIfc.Index)))
  701. wb.AddData(newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(mcvln.SlaveDev)))
  702. if err := s.Send(wb); err != nil {
  703. return err
  704. }
  705. return s.HandleAck(wb.Seq)
  706. }
  707. func NetworkLinkAddMacVlan(masterDev, macVlanDev string, mode string) error {
  708. return networkLinkMacVlan("macvlan", &MacVlanLink{
  709. MasterDev: masterDev,
  710. SlaveDev: macVlanDev,
  711. mode: mode,
  712. })
  713. }
  714. func NetworkLinkAddMacVtap(masterDev, macVlanDev string, mode string) error {
  715. return networkLinkMacVlan("macvtap", &MacVlanLink{
  716. MasterDev: masterDev,
  717. SlaveDev: macVlanDev,
  718. mode: mode,
  719. })
  720. }
  721. func networkLinkIpAction(action, flags int, ifa IfAddr) error {
  722. s, err := getNetlinkSocket()
  723. if err != nil {
  724. return err
  725. }
  726. defer s.Close()
  727. family := getIpFamily(ifa.IP)
  728. wb := newNetlinkRequest(action, flags)
  729. msg := newIfAddrmsg(family)
  730. msg.Index = uint32(ifa.Iface.Index)
  731. prefixLen, _ := ifa.IPNet.Mask.Size()
  732. msg.Prefixlen = uint8(prefixLen)
  733. wb.AddData(msg)
  734. var ipData []byte
  735. if family == syscall.AF_INET {
  736. ipData = ifa.IP.To4()
  737. } else {
  738. ipData = ifa.IP.To16()
  739. }
  740. localData := newRtAttr(syscall.IFA_LOCAL, ipData)
  741. wb.AddData(localData)
  742. addrData := newRtAttr(syscall.IFA_ADDRESS, ipData)
  743. wb.AddData(addrData)
  744. if err := s.Send(wb); err != nil {
  745. return err
  746. }
  747. return s.HandleAck(wb.Seq)
  748. }
  749. // Delete an IP address from an interface. This is identical to:
  750. // ip addr del $ip/$ipNet dev $iface
  751. func NetworkLinkDelIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
  752. return networkLinkIpAction(
  753. syscall.RTM_DELADDR,
  754. syscall.NLM_F_ACK,
  755. IfAddr{iface, ip, ipNet},
  756. )
  757. }
  758. // Add an Ip address to an interface. This is identical to:
  759. // ip addr add $ip/$ipNet dev $iface
  760. func NetworkLinkAddIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
  761. return networkLinkIpAction(
  762. syscall.RTM_NEWADDR,
  763. syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK,
  764. IfAddr{iface, ip, ipNet},
  765. )
  766. }
  767. // Returns an array of IPNet for all the currently routed subnets on ipv4
  768. // This is similar to the first column of "ip route" output
  769. func NetworkGetRoutes() ([]Route, error) {
  770. s, err := getNetlinkSocket()
  771. if err != nil {
  772. return nil, err
  773. }
  774. defer s.Close()
  775. wb := newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP)
  776. msg := newIfInfomsg(syscall.AF_UNSPEC)
  777. wb.AddData(msg)
  778. if err := s.Send(wb); err != nil {
  779. return nil, err
  780. }
  781. pid, err := s.GetPid()
  782. if err != nil {
  783. return nil, err
  784. }
  785. res := make([]Route, 0)
  786. outer:
  787. for {
  788. msgs, err := s.Receive()
  789. if err != nil {
  790. return nil, err
  791. }
  792. for _, m := range msgs {
  793. if err := s.CheckMessage(m, wb.Seq, pid); err != nil {
  794. if err == io.EOF {
  795. break outer
  796. }
  797. return nil, err
  798. }
  799. if m.Header.Type != syscall.RTM_NEWROUTE {
  800. continue
  801. }
  802. var r Route
  803. msg := (*RtMsg)(unsafe.Pointer(&m.Data[0:syscall.SizeofRtMsg][0]))
  804. if msg.Flags&syscall.RTM_F_CLONED != 0 {
  805. // Ignore cloned routes
  806. continue
  807. }
  808. if msg.Table != syscall.RT_TABLE_MAIN {
  809. // Ignore non-main tables
  810. continue
  811. }
  812. if msg.Family != syscall.AF_INET {
  813. // Ignore non-ipv4 routes
  814. continue
  815. }
  816. if msg.Dst_len == 0 {
  817. // Default routes
  818. r.Default = true
  819. }
  820. attrs, err := syscall.ParseNetlinkRouteAttr(&m)
  821. if err != nil {
  822. return nil, err
  823. }
  824. for _, attr := range attrs {
  825. switch attr.Attr.Type {
  826. case syscall.RTA_DST:
  827. ip := attr.Value
  828. r.IPNet = &net.IPNet{
  829. IP: ip,
  830. Mask: net.CIDRMask(int(msg.Dst_len), 8*len(ip)),
  831. }
  832. case syscall.RTA_OIF:
  833. index := int(native.Uint32(attr.Value[0:4]))
  834. r.Iface, _ = net.InterfaceByIndex(index)
  835. }
  836. }
  837. if r.Default || r.IPNet != nil {
  838. res = append(res, r)
  839. }
  840. }
  841. }
  842. return res, nil
  843. }
  844. // Add a new route table entry.
  845. func AddRoute(destination, source, gateway, device string) error {
  846. if destination == "" && source == "" && gateway == "" {
  847. return fmt.Errorf("one of destination, source or gateway must not be blank")
  848. }
  849. s, err := getNetlinkSocket()
  850. if err != nil {
  851. return err
  852. }
  853. defer s.Close()
  854. wb := newNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
  855. msg := newRtMsg()
  856. currentFamily := -1
  857. var rtAttrs []*RtAttr
  858. if destination != "" {
  859. destIP, destNet, err := net.ParseCIDR(destination)
  860. if err != nil {
  861. return fmt.Errorf("destination CIDR %s couldn't be parsed", destination)
  862. }
  863. destFamily := getIpFamily(destIP)
  864. currentFamily = destFamily
  865. destLen, bits := destNet.Mask.Size()
  866. if destLen == 0 && bits == 0 {
  867. return fmt.Errorf("destination CIDR %s generated a non-canonical Mask", destination)
  868. }
  869. msg.Family = uint8(destFamily)
  870. msg.Dst_len = uint8(destLen)
  871. var destData []byte
  872. if destFamily == syscall.AF_INET {
  873. destData = destIP.To4()
  874. } else {
  875. destData = destIP.To16()
  876. }
  877. rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_DST, destData))
  878. }
  879. if source != "" {
  880. srcIP := net.ParseIP(source)
  881. if srcIP == nil {
  882. return fmt.Errorf("source IP %s couldn't be parsed", source)
  883. }
  884. srcFamily := getIpFamily(srcIP)
  885. if currentFamily != -1 && currentFamily != srcFamily {
  886. return fmt.Errorf("source and destination ip were not the same IP family")
  887. }
  888. currentFamily = srcFamily
  889. msg.Family = uint8(srcFamily)
  890. var srcData []byte
  891. if srcFamily == syscall.AF_INET {
  892. srcData = srcIP.To4()
  893. } else {
  894. srcData = srcIP.To16()
  895. }
  896. rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_PREFSRC, srcData))
  897. }
  898. if gateway != "" {
  899. gwIP := net.ParseIP(gateway)
  900. if gwIP == nil {
  901. return fmt.Errorf("gateway IP %s couldn't be parsed", gateway)
  902. }
  903. gwFamily := getIpFamily(gwIP)
  904. if currentFamily != -1 && currentFamily != gwFamily {
  905. return fmt.Errorf("gateway, source, and destination ip were not the same IP family")
  906. }
  907. msg.Family = uint8(gwFamily)
  908. var gwData []byte
  909. if gwFamily == syscall.AF_INET {
  910. gwData = gwIP.To4()
  911. } else {
  912. gwData = gwIP.To16()
  913. }
  914. rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_GATEWAY, gwData))
  915. }
  916. wb.AddData(msg)
  917. for _, attr := range rtAttrs {
  918. wb.AddData(attr)
  919. }
  920. iface, err := net.InterfaceByName(device)
  921. if err != nil {
  922. return err
  923. }
  924. wb.AddData(uint32Attr(syscall.RTA_OIF, uint32(iface.Index)))
  925. if err := s.Send(wb); err != nil {
  926. return err
  927. }
  928. return s.HandleAck(wb.Seq)
  929. }
  930. // Add a new default gateway. Identical to:
  931. // ip route add default via $ip
  932. func AddDefaultGw(ip, device string) error {
  933. return AddRoute("", "", ip, device)
  934. }
  935. // THIS CODE DOES NOT COMMUNICATE WITH KERNEL VIA RTNETLINK INTERFACE
  936. // IT IS HERE FOR BACKWARDS COMPATIBILITY WITH OLDER LINUX KERNELS
  937. // WHICH SHIP WITH OLDER NOT ENTIRELY FUNCTIONAL VERSION OF NETLINK
  938. func getIfSocket() (fd int, err error) {
  939. for _, socket := range []int{
  940. syscall.AF_INET,
  941. syscall.AF_PACKET,
  942. syscall.AF_INET6,
  943. } {
  944. if fd, err = syscall.Socket(socket, syscall.SOCK_DGRAM, 0); err == nil {
  945. break
  946. }
  947. }
  948. if err == nil {
  949. return fd, nil
  950. }
  951. return -1, err
  952. }
  953. // Create the actual bridge device. This is more backward-compatible than
  954. // netlink.NetworkLinkAdd and works on RHEL 6.
  955. func CreateBridge(name string, setMacAddr bool) error {
  956. if len(name) >= IFNAMSIZ {
  957. return fmt.Errorf("Interface name %s too long", name)
  958. }
  959. s, err := getIfSocket()
  960. if err != nil {
  961. return err
  962. }
  963. defer syscall.Close(s)
  964. nameBytePtr, err := syscall.BytePtrFromString(name)
  965. if err != nil {
  966. return err
  967. }
  968. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 {
  969. return err
  970. }
  971. if setMacAddr {
  972. return SetMacAddress(name, randMacAddr())
  973. }
  974. return nil
  975. }
  976. // Delete the actual bridge device.
  977. func DeleteBridge(name string) error {
  978. s, err := getIfSocket()
  979. if err != nil {
  980. return err
  981. }
  982. defer syscall.Close(s)
  983. nameBytePtr, err := syscall.BytePtrFromString(name)
  984. if err != nil {
  985. return err
  986. }
  987. var ifr ifreqFlags
  988. copy(ifr.IfrnName[:len(ifr.IfrnName)-1], []byte(name))
  989. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s),
  990. syscall.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifr))); err != 0 {
  991. return err
  992. }
  993. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s),
  994. SIOC_BRDELBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 {
  995. return err
  996. }
  997. return nil
  998. }
  999. // Add a slave to abridge device. This is more backward-compatible than
  1000. // netlink.NetworkSetMaster and works on RHEL 6.
  1001. func AddToBridge(iface, master *net.Interface) error {
  1002. if len(master.Name) >= IFNAMSIZ {
  1003. return fmt.Errorf("Interface name %s too long", master.Name)
  1004. }
  1005. s, err := getIfSocket()
  1006. if err != nil {
  1007. return err
  1008. }
  1009. defer syscall.Close(s)
  1010. ifr := ifreqIndex{}
  1011. copy(ifr.IfrnName[:len(ifr.IfrnName)-1], master.Name)
  1012. ifr.IfruIndex = int32(iface.Index)
  1013. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDIF, uintptr(unsafe.Pointer(&ifr))); err != 0 {
  1014. return err
  1015. }
  1016. return nil
  1017. }
  1018. func randMacAddr() string {
  1019. hw := make(net.HardwareAddr, 6)
  1020. for i := 0; i < 6; i++ {
  1021. hw[i] = byte(rand.Intn(255))
  1022. }
  1023. hw[0] &^= 0x1 // clear multicast bit
  1024. hw[0] |= 0x2 // set local assignment bit (IEEE802)
  1025. return hw.String()
  1026. }
  1027. func SetMacAddress(name, addr string) error {
  1028. if len(name) >= IFNAMSIZ {
  1029. return fmt.Errorf("Interface name %s too long", name)
  1030. }
  1031. hw, err := net.ParseMAC(addr)
  1032. if err != nil {
  1033. return err
  1034. }
  1035. s, err := getIfSocket()
  1036. if err != nil {
  1037. return err
  1038. }
  1039. defer syscall.Close(s)
  1040. ifr := ifreqHwaddr{}
  1041. ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
  1042. copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name)
  1043. for i := 0; i < 6; i++ {
  1044. ifr.IfruHwaddr.Data[i] = ifrDataByte(hw[i])
  1045. }
  1046. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 {
  1047. return err
  1048. }
  1049. return nil
  1050. }
  1051. func SetHairpinMode(iface *net.Interface, enabled bool) error {
  1052. s, err := getNetlinkSocket()
  1053. if err != nil {
  1054. return err
  1055. }
  1056. defer s.Close()
  1057. req := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  1058. msg := newIfInfomsg(syscall.AF_BRIDGE)
  1059. msg.Type = syscall.RTM_SETLINK
  1060. msg.Flags = syscall.NLM_F_REQUEST
  1061. msg.Index = int32(iface.Index)
  1062. msg.Change = DEFAULT_CHANGE
  1063. req.AddData(msg)
  1064. mode := []byte{0}
  1065. if enabled {
  1066. mode[0] = byte(1)
  1067. }
  1068. br := newRtAttr(syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED, nil)
  1069. newRtAttrChild(br, IFLA_BRPORT_MODE, mode)
  1070. req.AddData(br)
  1071. if err := s.Send(req); err != nil {
  1072. return err
  1073. }
  1074. return s.HandleAck(req.Seq)
  1075. }
  1076. func ChangeName(iface *net.Interface, newName string) error {
  1077. if len(newName) >= IFNAMSIZ {
  1078. return fmt.Errorf("Interface name %s too long", newName)
  1079. }
  1080. fd, err := getIfSocket()
  1081. if err != nil {
  1082. return err
  1083. }
  1084. defer syscall.Close(fd)
  1085. data := [IFNAMSIZ * 2]byte{}
  1086. // the "-1"s here are very important for ensuring we get proper null
  1087. // termination of our new C strings
  1088. copy(data[:IFNAMSIZ-1], iface.Name)
  1089. copy(data[IFNAMSIZ:IFNAMSIZ*2-1], newName)
  1090. if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.SIOCSIFNAME, uintptr(unsafe.Pointer(&data[0]))); errno != 0 {
  1091. return errno
  1092. }
  1093. return nil
  1094. }