netlink_linux.go 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. package netlink
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "io"
  6. "math/rand"
  7. "net"
  8. "sync/atomic"
  9. "syscall"
  10. "unsafe"
  11. )
  12. const (
  13. IFNAMSIZ = 16
  14. DEFAULT_CHANGE = 0xFFFFFFFF
  15. IFLA_INFO_KIND = 1
  16. IFLA_INFO_DATA = 2
  17. VETH_INFO_PEER = 1
  18. IFLA_NET_NS_FD = 28
  19. SIOC_BRADDBR = 0x89a0
  20. SIOC_BRDELBR = 0x89a1
  21. SIOC_BRADDIF = 0x89a2
  22. )
  23. var nextSeqNr uint32
  24. type ifreqHwaddr struct {
  25. IfrnName [IFNAMSIZ]byte
  26. IfruHwaddr syscall.RawSockaddr
  27. }
  28. type ifreqIndex struct {
  29. IfrnName [IFNAMSIZ]byte
  30. IfruIndex int32
  31. }
  32. type ifreqFlags struct {
  33. IfrnName [IFNAMSIZ]byte
  34. Ifruflags uint16
  35. }
  36. var native binary.ByteOrder
  37. func init() {
  38. var x uint32 = 0x01020304
  39. if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
  40. native = binary.BigEndian
  41. } else {
  42. native = binary.LittleEndian
  43. }
  44. }
  45. func getIpFamily(ip net.IP) int {
  46. if len(ip) <= net.IPv4len {
  47. return syscall.AF_INET
  48. }
  49. if ip.To4() != nil {
  50. return syscall.AF_INET
  51. }
  52. return syscall.AF_INET6
  53. }
  54. type NetlinkRequestData interface {
  55. Len() int
  56. ToWireFormat() []byte
  57. }
  58. type IfInfomsg struct {
  59. syscall.IfInfomsg
  60. }
  61. func newIfInfomsg(family int) *IfInfomsg {
  62. return &IfInfomsg{
  63. IfInfomsg: syscall.IfInfomsg{
  64. Family: uint8(family),
  65. },
  66. }
  67. }
  68. func newIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
  69. msg := newIfInfomsg(family)
  70. parent.children = append(parent.children, msg)
  71. return msg
  72. }
  73. func (msg *IfInfomsg) ToWireFormat() []byte {
  74. length := syscall.SizeofIfInfomsg
  75. b := make([]byte, length)
  76. b[0] = msg.Family
  77. b[1] = 0
  78. native.PutUint16(b[2:4], msg.Type)
  79. native.PutUint32(b[4:8], uint32(msg.Index))
  80. native.PutUint32(b[8:12], msg.Flags)
  81. native.PutUint32(b[12:16], msg.Change)
  82. return b
  83. }
  84. func (msg *IfInfomsg) Len() int {
  85. return syscall.SizeofIfInfomsg
  86. }
  87. type IfAddrmsg struct {
  88. syscall.IfAddrmsg
  89. }
  90. func newIfAddrmsg(family int) *IfAddrmsg {
  91. return &IfAddrmsg{
  92. IfAddrmsg: syscall.IfAddrmsg{
  93. Family: uint8(family),
  94. },
  95. }
  96. }
  97. func (msg *IfAddrmsg) ToWireFormat() []byte {
  98. length := syscall.SizeofIfAddrmsg
  99. b := make([]byte, length)
  100. b[0] = msg.Family
  101. b[1] = msg.Prefixlen
  102. b[2] = msg.Flags
  103. b[3] = msg.Scope
  104. native.PutUint32(b[4:8], msg.Index)
  105. return b
  106. }
  107. func (msg *IfAddrmsg) Len() int {
  108. return syscall.SizeofIfAddrmsg
  109. }
  110. type RtMsg struct {
  111. syscall.RtMsg
  112. }
  113. func newRtMsg() *RtMsg {
  114. return &RtMsg{
  115. RtMsg: syscall.RtMsg{
  116. Table: syscall.RT_TABLE_MAIN,
  117. Scope: syscall.RT_SCOPE_UNIVERSE,
  118. Protocol: syscall.RTPROT_BOOT,
  119. Type: syscall.RTN_UNICAST,
  120. },
  121. }
  122. }
  123. func (msg *RtMsg) ToWireFormat() []byte {
  124. length := syscall.SizeofRtMsg
  125. b := make([]byte, length)
  126. b[0] = msg.Family
  127. b[1] = msg.Dst_len
  128. b[2] = msg.Src_len
  129. b[3] = msg.Tos
  130. b[4] = msg.Table
  131. b[5] = msg.Protocol
  132. b[6] = msg.Scope
  133. b[7] = msg.Type
  134. native.PutUint32(b[8:12], msg.Flags)
  135. return b
  136. }
  137. func (msg *RtMsg) Len() int {
  138. return syscall.SizeofRtMsg
  139. }
  140. func rtaAlignOf(attrlen int) int {
  141. return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1)
  142. }
  143. type RtAttr struct {
  144. syscall.RtAttr
  145. Data []byte
  146. children []NetlinkRequestData
  147. }
  148. func newRtAttr(attrType int, data []byte) *RtAttr {
  149. return &RtAttr{
  150. RtAttr: syscall.RtAttr{
  151. Type: uint16(attrType),
  152. },
  153. children: []NetlinkRequestData{},
  154. Data: data,
  155. }
  156. }
  157. func newRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
  158. attr := newRtAttr(attrType, data)
  159. parent.children = append(parent.children, attr)
  160. return attr
  161. }
  162. func (a *RtAttr) Len() int {
  163. if len(a.children) == 0 {
  164. return (syscall.SizeofRtAttr + len(a.Data))
  165. }
  166. l := 0
  167. for _, child := range a.children {
  168. l += child.Len()
  169. }
  170. l += syscall.SizeofRtAttr
  171. return rtaAlignOf(l + len(a.Data))
  172. }
  173. func (a *RtAttr) ToWireFormat() []byte {
  174. length := a.Len()
  175. buf := make([]byte, rtaAlignOf(length))
  176. if a.Data != nil {
  177. copy(buf[4:], a.Data)
  178. } else {
  179. next := 4
  180. for _, child := range a.children {
  181. childBuf := child.ToWireFormat()
  182. copy(buf[next:], childBuf)
  183. next += rtaAlignOf(len(childBuf))
  184. }
  185. }
  186. if l := uint16(length); l != 0 {
  187. native.PutUint16(buf[0:2], l)
  188. }
  189. native.PutUint16(buf[2:4], a.Type)
  190. return buf
  191. }
  192. func uint32Attr(t int, n uint32) *RtAttr {
  193. buf := make([]byte, 4)
  194. native.PutUint32(buf, n)
  195. return newRtAttr(t, buf)
  196. }
  197. type NetlinkRequest struct {
  198. syscall.NlMsghdr
  199. Data []NetlinkRequestData
  200. }
  201. func (rr *NetlinkRequest) ToWireFormat() []byte {
  202. length := rr.Len
  203. dataBytes := make([][]byte, len(rr.Data))
  204. for i, data := range rr.Data {
  205. dataBytes[i] = data.ToWireFormat()
  206. length += uint32(len(dataBytes[i]))
  207. }
  208. b := make([]byte, length)
  209. native.PutUint32(b[0:4], length)
  210. native.PutUint16(b[4:6], rr.Type)
  211. native.PutUint16(b[6:8], rr.Flags)
  212. native.PutUint32(b[8:12], rr.Seq)
  213. native.PutUint32(b[12:16], rr.Pid)
  214. next := 16
  215. for _, data := range dataBytes {
  216. copy(b[next:], data)
  217. next += len(data)
  218. }
  219. return b
  220. }
  221. func (rr *NetlinkRequest) AddData(data NetlinkRequestData) {
  222. if data != nil {
  223. rr.Data = append(rr.Data, data)
  224. }
  225. }
  226. func newNetlinkRequest(proto, flags int) *NetlinkRequest {
  227. return &NetlinkRequest{
  228. NlMsghdr: syscall.NlMsghdr{
  229. Len: uint32(syscall.NLMSG_HDRLEN),
  230. Type: uint16(proto),
  231. Flags: syscall.NLM_F_REQUEST | uint16(flags),
  232. Seq: atomic.AddUint32(&nextSeqNr, 1),
  233. },
  234. }
  235. }
  236. type NetlinkSocket struct {
  237. fd int
  238. lsa syscall.SockaddrNetlink
  239. }
  240. func getNetlinkSocket() (*NetlinkSocket, error) {
  241. fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_ROUTE)
  242. if err != nil {
  243. return nil, err
  244. }
  245. s := &NetlinkSocket{
  246. fd: fd,
  247. }
  248. s.lsa.Family = syscall.AF_NETLINK
  249. if err := syscall.Bind(fd, &s.lsa); err != nil {
  250. syscall.Close(fd)
  251. return nil, err
  252. }
  253. return s, nil
  254. }
  255. func (s *NetlinkSocket) Close() {
  256. syscall.Close(s.fd)
  257. }
  258. func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
  259. if err := syscall.Sendto(s.fd, request.ToWireFormat(), 0, &s.lsa); err != nil {
  260. return err
  261. }
  262. return nil
  263. }
  264. func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
  265. rb := make([]byte, syscall.Getpagesize())
  266. nr, _, err := syscall.Recvfrom(s.fd, rb, 0)
  267. if err != nil {
  268. return nil, err
  269. }
  270. if nr < syscall.NLMSG_HDRLEN {
  271. return nil, ErrShortResponse
  272. }
  273. rb = rb[:nr]
  274. return syscall.ParseNetlinkMessage(rb)
  275. }
  276. func (s *NetlinkSocket) GetPid() (uint32, error) {
  277. lsa, err := syscall.Getsockname(s.fd)
  278. if err != nil {
  279. return 0, err
  280. }
  281. switch v := lsa.(type) {
  282. case *syscall.SockaddrNetlink:
  283. return v.Pid, nil
  284. }
  285. return 0, ErrWrongSockType
  286. }
  287. func (s *NetlinkSocket) CheckMessage(m syscall.NetlinkMessage, seq, pid uint32) error {
  288. if m.Header.Seq != seq {
  289. return fmt.Errorf("netlink: invalid seq %d, expected %d", m.Header.Seq, seq)
  290. }
  291. if m.Header.Pid != pid {
  292. return fmt.Errorf("netlink: wrong pid %d, expected %d", m.Header.Pid, pid)
  293. }
  294. if m.Header.Type == syscall.NLMSG_DONE {
  295. return io.EOF
  296. }
  297. if m.Header.Type == syscall.NLMSG_ERROR {
  298. e := int32(native.Uint32(m.Data[0:4]))
  299. if e == 0 {
  300. return io.EOF
  301. }
  302. return syscall.Errno(-e)
  303. }
  304. return nil
  305. }
  306. func (s *NetlinkSocket) HandleAck(seq uint32) error {
  307. pid, err := s.GetPid()
  308. if err != nil {
  309. return err
  310. }
  311. outer:
  312. for {
  313. msgs, err := s.Receive()
  314. if err != nil {
  315. return err
  316. }
  317. for _, m := range msgs {
  318. if err := s.CheckMessage(m, seq, pid); err != nil {
  319. if err == io.EOF {
  320. break outer
  321. }
  322. return err
  323. }
  324. }
  325. }
  326. return nil
  327. }
  328. // Add a new route table entry.
  329. func AddRoute(destination, source, gateway, device string) error {
  330. if destination == "" && source == "" && gateway == "" {
  331. return fmt.Errorf("one of destination, source or gateway must not be blank")
  332. }
  333. s, err := getNetlinkSocket()
  334. if err != nil {
  335. return err
  336. }
  337. defer s.Close()
  338. wb := newNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
  339. msg := newRtMsg()
  340. currentFamily := -1
  341. var rtAttrs []*RtAttr
  342. if destination != "" {
  343. destIP, destNet, err := net.ParseCIDR(destination)
  344. if err != nil {
  345. return fmt.Errorf("destination CIDR %s couldn't be parsed", destination)
  346. }
  347. destFamily := getIpFamily(destIP)
  348. currentFamily = destFamily
  349. destLen, bits := destNet.Mask.Size()
  350. if destLen == 0 && bits == 0 {
  351. return fmt.Errorf("destination CIDR %s generated a non-canonical Mask", destination)
  352. }
  353. msg.Family = uint8(destFamily)
  354. msg.Dst_len = uint8(destLen)
  355. var destData []byte
  356. if destFamily == syscall.AF_INET {
  357. destData = destIP.To4()
  358. } else {
  359. destData = destIP.To16()
  360. }
  361. rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_DST, destData))
  362. }
  363. if source != "" {
  364. srcIP, srcNet, err := net.ParseCIDR(source)
  365. if err != nil {
  366. return fmt.Errorf("source CIDR %s couldn't be parsed", source)
  367. }
  368. srcFamily := getIpFamily(srcIP)
  369. if currentFamily != -1 && currentFamily != srcFamily {
  370. return fmt.Errorf("source and destination ip were not the same IP family")
  371. }
  372. currentFamily = srcFamily
  373. srcLen, bits := srcNet.Mask.Size()
  374. if srcLen == 0 && bits == 0 {
  375. return fmt.Errorf("source CIDR %s generated a non-canonical Mask", source)
  376. }
  377. msg.Family = uint8(srcFamily)
  378. msg.Src_len = uint8(srcLen)
  379. var srcData []byte
  380. if srcFamily == syscall.AF_INET {
  381. srcData = srcIP.To4()
  382. } else {
  383. srcData = srcIP.To16()
  384. }
  385. rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_SRC, srcData))
  386. }
  387. if gateway != "" {
  388. gwIP := net.ParseIP(gateway)
  389. if gwIP == nil {
  390. return fmt.Errorf("gateway IP %s couldn't be parsed", gateway)
  391. }
  392. gwFamily := getIpFamily(gwIP)
  393. if currentFamily != -1 && currentFamily != gwFamily {
  394. return fmt.Errorf("gateway, source, and destination ip were not the same IP family")
  395. }
  396. msg.Family = uint8(gwFamily)
  397. var gwData []byte
  398. if gwFamily == syscall.AF_INET {
  399. gwData = gwIP.To4()
  400. } else {
  401. gwData = gwIP.To16()
  402. }
  403. rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_GATEWAY, gwData))
  404. }
  405. wb.AddData(msg)
  406. for _, attr := range rtAttrs {
  407. wb.AddData(attr)
  408. }
  409. iface, err := net.InterfaceByName(device)
  410. if err != nil {
  411. return err
  412. }
  413. wb.AddData(uint32Attr(syscall.RTA_OIF, uint32(iface.Index)))
  414. if err := s.Send(wb); err != nil {
  415. return err
  416. }
  417. return s.HandleAck(wb.Seq)
  418. }
  419. // Add a new default gateway. Identical to:
  420. // ip route add default via $ip
  421. func AddDefaultGw(ip, device string) error {
  422. return AddRoute("", "", ip, device)
  423. }
  424. // Bring up a particular network interface
  425. func NetworkLinkUp(iface *net.Interface) error {
  426. s, err := getNetlinkSocket()
  427. if err != nil {
  428. return err
  429. }
  430. defer s.Close()
  431. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
  432. msg := newIfInfomsg(syscall.AF_UNSPEC)
  433. msg.Change = syscall.IFF_UP
  434. msg.Flags = syscall.IFF_UP
  435. msg.Index = int32(iface.Index)
  436. wb.AddData(msg)
  437. if err := s.Send(wb); err != nil {
  438. return err
  439. }
  440. return s.HandleAck(wb.Seq)
  441. }
  442. func NetworkLinkDown(iface *net.Interface) error {
  443. s, err := getNetlinkSocket()
  444. if err != nil {
  445. return err
  446. }
  447. defer s.Close()
  448. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
  449. msg := newIfInfomsg(syscall.AF_UNSPEC)
  450. msg.Change = syscall.IFF_UP
  451. msg.Flags = 0 & ^syscall.IFF_UP
  452. msg.Index = int32(iface.Index)
  453. wb.AddData(msg)
  454. if err := s.Send(wb); err != nil {
  455. return err
  456. }
  457. return s.HandleAck(wb.Seq)
  458. }
  459. func NetworkSetMTU(iface *net.Interface, mtu int) error {
  460. s, err := getNetlinkSocket()
  461. if err != nil {
  462. return err
  463. }
  464. defer s.Close()
  465. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  466. msg := newIfInfomsg(syscall.AF_UNSPEC)
  467. msg.Type = syscall.RTM_SETLINK
  468. msg.Flags = syscall.NLM_F_REQUEST
  469. msg.Index = int32(iface.Index)
  470. msg.Change = DEFAULT_CHANGE
  471. wb.AddData(msg)
  472. wb.AddData(uint32Attr(syscall.IFLA_MTU, uint32(mtu)))
  473. if err := s.Send(wb); err != nil {
  474. return err
  475. }
  476. return s.HandleAck(wb.Seq)
  477. }
  478. // same as ip link set $name master $master
  479. func NetworkSetMaster(iface, master *net.Interface) error {
  480. s, err := getNetlinkSocket()
  481. if err != nil {
  482. return err
  483. }
  484. defer s.Close()
  485. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  486. msg := newIfInfomsg(syscall.AF_UNSPEC)
  487. msg.Type = syscall.RTM_SETLINK
  488. msg.Flags = syscall.NLM_F_REQUEST
  489. msg.Index = int32(iface.Index)
  490. msg.Change = DEFAULT_CHANGE
  491. wb.AddData(msg)
  492. wb.AddData(uint32Attr(syscall.IFLA_MASTER, uint32(master.Index)))
  493. if err := s.Send(wb); err != nil {
  494. return err
  495. }
  496. return s.HandleAck(wb.Seq)
  497. }
  498. func NetworkSetNsPid(iface *net.Interface, nspid int) error {
  499. s, err := getNetlinkSocket()
  500. if err != nil {
  501. return err
  502. }
  503. defer s.Close()
  504. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  505. msg := newIfInfomsg(syscall.AF_UNSPEC)
  506. msg.Type = syscall.RTM_SETLINK
  507. msg.Flags = syscall.NLM_F_REQUEST
  508. msg.Index = int32(iface.Index)
  509. msg.Change = DEFAULT_CHANGE
  510. wb.AddData(msg)
  511. wb.AddData(uint32Attr(syscall.IFLA_NET_NS_PID, uint32(nspid)))
  512. if err := s.Send(wb); err != nil {
  513. return err
  514. }
  515. return s.HandleAck(wb.Seq)
  516. }
  517. func NetworkSetNsFd(iface *net.Interface, fd int) error {
  518. s, err := getNetlinkSocket()
  519. if err != nil {
  520. return err
  521. }
  522. defer s.Close()
  523. wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
  524. msg := newIfInfomsg(syscall.AF_UNSPEC)
  525. msg.Type = syscall.RTM_SETLINK
  526. msg.Flags = syscall.NLM_F_REQUEST
  527. msg.Index = int32(iface.Index)
  528. msg.Change = DEFAULT_CHANGE
  529. wb.AddData(msg)
  530. wb.AddData(uint32Attr(IFLA_NET_NS_FD, uint32(fd)))
  531. if err := s.Send(wb); err != nil {
  532. return err
  533. }
  534. return s.HandleAck(wb.Seq)
  535. }
  536. func networkLinkIpAction(action, flags int, ifa IfAddr) error {
  537. s, err := getNetlinkSocket()
  538. if err != nil {
  539. return err
  540. }
  541. defer s.Close()
  542. family := getIpFamily(ifa.IP)
  543. wb := newNetlinkRequest(action, flags)
  544. msg := newIfAddrmsg(family)
  545. msg.Index = uint32(ifa.Iface.Index)
  546. prefixLen, _ := ifa.IPNet.Mask.Size()
  547. msg.Prefixlen = uint8(prefixLen)
  548. wb.AddData(msg)
  549. var ipData []byte
  550. if family == syscall.AF_INET {
  551. ipData = ifa.IP.To4()
  552. } else {
  553. ipData = ifa.IP.To16()
  554. }
  555. localData := newRtAttr(syscall.IFA_LOCAL, ipData)
  556. wb.AddData(localData)
  557. addrData := newRtAttr(syscall.IFA_ADDRESS, ipData)
  558. wb.AddData(addrData)
  559. if err := s.Send(wb); err != nil {
  560. return err
  561. }
  562. return s.HandleAck(wb.Seq)
  563. }
  564. // Delete an IP address from an interface. This is identical to:
  565. // ip addr del $ip/$ipNet dev $iface
  566. func NetworkLinkDelIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
  567. return networkLinkIpAction(
  568. syscall.RTM_DELADDR,
  569. syscall.NLM_F_ACK,
  570. IfAddr{iface, ip, ipNet},
  571. )
  572. }
  573. // Add an Ip address to an interface. This is identical to:
  574. // ip addr add $ip/$ipNet dev $iface
  575. func NetworkLinkAddIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
  576. return networkLinkIpAction(
  577. syscall.RTM_NEWADDR,
  578. syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK,
  579. IfAddr{iface, ip, ipNet},
  580. )
  581. }
  582. func zeroTerminated(s string) []byte {
  583. return []byte(s + "\000")
  584. }
  585. func nonZeroTerminated(s string) []byte {
  586. return []byte(s)
  587. }
  588. // Add a new network link of a specified type. This is identical to
  589. // running: ip add link $name type $linkType
  590. func NetworkLinkAdd(name string, linkType string) error {
  591. if name == "" || linkType == "" {
  592. return fmt.Errorf("Neither link name nor link type can be empty!")
  593. }
  594. s, err := getNetlinkSocket()
  595. if err != nil {
  596. return err
  597. }
  598. defer s.Close()
  599. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
  600. msg := newIfInfomsg(syscall.AF_UNSPEC)
  601. wb.AddData(msg)
  602. linkInfo := newRtAttr(syscall.IFLA_LINKINFO, nil)
  603. newRtAttrChild(linkInfo, IFLA_INFO_KIND, nonZeroTerminated(linkType))
  604. wb.AddData(linkInfo)
  605. nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name))
  606. wb.AddData(nameData)
  607. if err := s.Send(wb); err != nil {
  608. return err
  609. }
  610. return s.HandleAck(wb.Seq)
  611. }
  612. // Delete a network link. This is identical to
  613. // running: ip link del $name
  614. func NetworkLinkDel(name string) error {
  615. if name == "" {
  616. return fmt.Errorf("Network link name can not be empty!")
  617. }
  618. s, err := getNetlinkSocket()
  619. if err != nil {
  620. return err
  621. }
  622. defer s.Close()
  623. iface, err := net.InterfaceByName(name)
  624. if err != nil {
  625. return err
  626. }
  627. wb := newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK)
  628. msg := newIfInfomsg(syscall.AF_UNSPEC)
  629. msg.Index = int32(iface.Index)
  630. wb.AddData(msg)
  631. if err := s.Send(wb); err != nil {
  632. return err
  633. }
  634. return s.HandleAck(wb.Seq)
  635. }
  636. // Returns an array of IPNet for all the currently routed subnets on ipv4
  637. // This is similar to the first column of "ip route" output
  638. func NetworkGetRoutes() ([]Route, error) {
  639. s, err := getNetlinkSocket()
  640. if err != nil {
  641. return nil, err
  642. }
  643. defer s.Close()
  644. wb := newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP)
  645. msg := newIfInfomsg(syscall.AF_UNSPEC)
  646. wb.AddData(msg)
  647. if err := s.Send(wb); err != nil {
  648. return nil, err
  649. }
  650. pid, err := s.GetPid()
  651. if err != nil {
  652. return nil, err
  653. }
  654. res := make([]Route, 0)
  655. outer:
  656. for {
  657. msgs, err := s.Receive()
  658. if err != nil {
  659. return nil, err
  660. }
  661. for _, m := range msgs {
  662. if err := s.CheckMessage(m, wb.Seq, pid); err != nil {
  663. if err == io.EOF {
  664. break outer
  665. }
  666. return nil, err
  667. }
  668. if m.Header.Type != syscall.RTM_NEWROUTE {
  669. continue
  670. }
  671. var r Route
  672. msg := (*RtMsg)(unsafe.Pointer(&m.Data[0:syscall.SizeofRtMsg][0]))
  673. if msg.Flags&syscall.RTM_F_CLONED != 0 {
  674. // Ignore cloned routes
  675. continue
  676. }
  677. if msg.Table != syscall.RT_TABLE_MAIN {
  678. // Ignore non-main tables
  679. continue
  680. }
  681. if msg.Family != syscall.AF_INET {
  682. // Ignore non-ipv4 routes
  683. continue
  684. }
  685. if msg.Dst_len == 0 {
  686. // Default routes
  687. r.Default = true
  688. }
  689. attrs, err := syscall.ParseNetlinkRouteAttr(&m)
  690. if err != nil {
  691. return nil, err
  692. }
  693. for _, attr := range attrs {
  694. switch attr.Attr.Type {
  695. case syscall.RTA_DST:
  696. ip := attr.Value
  697. r.IPNet = &net.IPNet{
  698. IP: ip,
  699. Mask: net.CIDRMask(int(msg.Dst_len), 8*len(ip)),
  700. }
  701. case syscall.RTA_OIF:
  702. index := int(native.Uint32(attr.Value[0:4]))
  703. r.Iface, _ = net.InterfaceByIndex(index)
  704. }
  705. }
  706. if r.Default || r.IPNet != nil {
  707. res = append(res, r)
  708. }
  709. }
  710. }
  711. return res, nil
  712. }
  713. func getIfSocket() (fd int, err error) {
  714. for _, socket := range []int{
  715. syscall.AF_INET,
  716. syscall.AF_PACKET,
  717. syscall.AF_INET6,
  718. } {
  719. if fd, err = syscall.Socket(socket, syscall.SOCK_DGRAM, 0); err == nil {
  720. break
  721. }
  722. }
  723. if err == nil {
  724. return fd, nil
  725. }
  726. return -1, err
  727. }
  728. func NetworkChangeName(iface *net.Interface, newName string) error {
  729. if len(newName) >= IFNAMSIZ {
  730. return fmt.Errorf("Interface name %s too long", newName)
  731. }
  732. fd, err := getIfSocket()
  733. if err != nil {
  734. return err
  735. }
  736. defer syscall.Close(fd)
  737. data := [IFNAMSIZ * 2]byte{}
  738. // the "-1"s here are very important for ensuring we get proper null
  739. // termination of our new C strings
  740. copy(data[:IFNAMSIZ-1], iface.Name)
  741. copy(data[IFNAMSIZ:IFNAMSIZ*2-1], newName)
  742. if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.SIOCSIFNAME, uintptr(unsafe.Pointer(&data[0]))); errno != 0 {
  743. return errno
  744. }
  745. return nil
  746. }
  747. func NetworkCreateVethPair(name1, name2 string) error {
  748. s, err := getNetlinkSocket()
  749. if err != nil {
  750. return err
  751. }
  752. defer s.Close()
  753. wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
  754. msg := newIfInfomsg(syscall.AF_UNSPEC)
  755. wb.AddData(msg)
  756. nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name1))
  757. wb.AddData(nameData)
  758. nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil)
  759. newRtAttrChild(nest1, IFLA_INFO_KIND, zeroTerminated("veth"))
  760. nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil)
  761. nest3 := newRtAttrChild(nest2, VETH_INFO_PEER, nil)
  762. newIfInfomsgChild(nest3, syscall.AF_UNSPEC)
  763. newRtAttrChild(nest3, syscall.IFLA_IFNAME, zeroTerminated(name2))
  764. wb.AddData(nest1)
  765. if err := s.Send(wb); err != nil {
  766. return err
  767. }
  768. return s.HandleAck(wb.Seq)
  769. }
  770. // Create the actual bridge device. This is more backward-compatible than
  771. // netlink.NetworkLinkAdd and works on RHEL 6.
  772. func CreateBridge(name string, setMacAddr bool) error {
  773. if len(name) >= IFNAMSIZ {
  774. return fmt.Errorf("Interface name %s too long", name)
  775. }
  776. s, err := getIfSocket()
  777. if err != nil {
  778. return err
  779. }
  780. defer syscall.Close(s)
  781. nameBytePtr, err := syscall.BytePtrFromString(name)
  782. if err != nil {
  783. return err
  784. }
  785. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 {
  786. return err
  787. }
  788. if setMacAddr {
  789. return NetworkSetMacAddress(name, randMacAddr())
  790. }
  791. return nil
  792. }
  793. // Delete the actual bridge device.
  794. func DeleteBridge(name string) error {
  795. s, err := getIfSocket()
  796. if err != nil {
  797. return err
  798. }
  799. defer syscall.Close(s)
  800. nameBytePtr, err := syscall.BytePtrFromString(name)
  801. if err != nil {
  802. return err
  803. }
  804. var ifr ifreqFlags
  805. copy(ifr.IfrnName[:len(ifr.IfrnName)-1], []byte(name))
  806. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s),
  807. syscall.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifr))); err != 0 {
  808. return err
  809. }
  810. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s),
  811. SIOC_BRDELBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 {
  812. return err
  813. }
  814. return nil
  815. }
  816. // Add a slave to abridge device. This is more backward-compatible than
  817. // netlink.NetworkSetMaster and works on RHEL 6.
  818. func AddToBridge(iface, master *net.Interface) error {
  819. if len(master.Name) >= IFNAMSIZ {
  820. return fmt.Errorf("Interface name %s too long", master.Name)
  821. }
  822. s, err := getIfSocket()
  823. if err != nil {
  824. return err
  825. }
  826. defer syscall.Close(s)
  827. ifr := ifreqIndex{}
  828. copy(ifr.IfrnName[:len(ifr.IfrnName)-1], master.Name)
  829. ifr.IfruIndex = int32(iface.Index)
  830. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDIF, uintptr(unsafe.Pointer(&ifr))); err != 0 {
  831. return err
  832. }
  833. return nil
  834. }
  835. func randMacAddr() string {
  836. hw := make(net.HardwareAddr, 6)
  837. for i := 0; i < 6; i++ {
  838. hw[i] = byte(rand.Intn(255))
  839. }
  840. hw[0] &^= 0x1 // clear multicast bit
  841. hw[0] |= 0x2 // set local assignment bit (IEEE802)
  842. return hw.String()
  843. }
  844. func NetworkSetMacAddress(name, addr string) error {
  845. if len(name) >= IFNAMSIZ {
  846. return fmt.Errorf("Interface name %s too long", name)
  847. }
  848. hw, err := net.ParseMAC(addr)
  849. if err != nil {
  850. return err
  851. }
  852. s, err := getIfSocket()
  853. if err != nil {
  854. return err
  855. }
  856. defer syscall.Close(s)
  857. ifr := ifreqHwaddr{}
  858. ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
  859. copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name)
  860. for i := 0; i < 6; i++ {
  861. ifr.IfruHwaddr.Data[i] = ifrDataByte(hw[i])
  862. }
  863. if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 {
  864. return err
  865. }
  866. return nil
  867. }