netlink_linux_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. package netlink
  2. import (
  3. "net"
  4. "strings"
  5. "syscall"
  6. "testing"
  7. )
  8. type testLink struct {
  9. name string
  10. linkType string
  11. }
  12. func addLink(t *testing.T, name string, linkType string) {
  13. if err := NetworkLinkAdd(name, linkType); err != nil {
  14. t.Fatalf("Unable to create %s link: %s", name, err)
  15. }
  16. }
  17. func readLink(t *testing.T, name string) *net.Interface {
  18. iface, err := net.InterfaceByName(name)
  19. if err != nil {
  20. t.Fatalf("Could not find %s interface: %s", name, err)
  21. }
  22. return iface
  23. }
  24. func deleteLink(t *testing.T, name string) {
  25. if err := NetworkLinkDel(name); err != nil {
  26. t.Fatalf("Unable to delete %s link: %s", name, err)
  27. }
  28. }
  29. func upLink(t *testing.T, name string) {
  30. iface := readLink(t, name)
  31. if err := NetworkLinkUp(iface); err != nil {
  32. t.Fatalf("Could not bring UP %#v interface: %s", iface, err)
  33. }
  34. }
  35. func downLink(t *testing.T, name string) {
  36. iface := readLink(t, name)
  37. if err := NetworkLinkDown(iface); err != nil {
  38. t.Fatalf("Could not bring DOWN %#v interface: %s", iface, err)
  39. }
  40. }
  41. func ipAssigned(iface *net.Interface, ip net.IP) bool {
  42. addrs, _ := iface.Addrs()
  43. for _, addr := range addrs {
  44. args := strings.SplitN(addr.String(), "/", 2)
  45. if args[0] == ip.String() {
  46. return true
  47. }
  48. }
  49. return false
  50. }
  51. func TestNetworkLinkAddDel(t *testing.T) {
  52. if testing.Short() {
  53. return
  54. }
  55. testLinks := []testLink{
  56. {"tstEth", "dummy"},
  57. {"tstBr", "bridge"},
  58. }
  59. for _, tl := range testLinks {
  60. addLink(t, tl.name, tl.linkType)
  61. defer deleteLink(t, tl.name)
  62. readLink(t, tl.name)
  63. }
  64. }
  65. func TestNetworkLinkUpDown(t *testing.T) {
  66. if testing.Short() {
  67. return
  68. }
  69. tl := testLink{name: "tstEth", linkType: "dummy"}
  70. addLink(t, tl.name, tl.linkType)
  71. defer deleteLink(t, tl.name)
  72. upLink(t, tl.name)
  73. ifcAfterUp := readLink(t, tl.name)
  74. if (ifcAfterUp.Flags & syscall.IFF_UP) != syscall.IFF_UP {
  75. t.Fatalf("Could not bring UP %#v initerface", tl)
  76. }
  77. downLink(t, tl.name)
  78. ifcAfterDown := readLink(t, tl.name)
  79. if (ifcAfterDown.Flags & syscall.IFF_UP) == syscall.IFF_UP {
  80. t.Fatalf("Could not bring DOWN %#v initerface", tl)
  81. }
  82. }
  83. func TestNetworkSetMacAddress(t *testing.T) {
  84. if testing.Short() {
  85. return
  86. }
  87. tl := testLink{name: "tstEth", linkType: "dummy"}
  88. macaddr := "22:ce:e0:99:63:6f"
  89. addLink(t, tl.name, tl.linkType)
  90. defer deleteLink(t, tl.name)
  91. ifcBeforeSet := readLink(t, tl.name)
  92. if err := NetworkSetMacAddress(ifcBeforeSet, macaddr); err != nil {
  93. t.Fatalf("Could not set %s MAC address on %#v interface: %s", macaddr, tl, err)
  94. }
  95. ifcAfterSet := readLink(t, tl.name)
  96. if ifcAfterSet.HardwareAddr.String() != macaddr {
  97. t.Fatalf("Could not set %s MAC address on %#v interface", macaddr, tl)
  98. }
  99. }
  100. func TestNetworkSetMTU(t *testing.T) {
  101. if testing.Short() {
  102. return
  103. }
  104. tl := testLink{name: "tstEth", linkType: "dummy"}
  105. mtu := 1400
  106. addLink(t, tl.name, tl.linkType)
  107. defer deleteLink(t, tl.name)
  108. ifcBeforeSet := readLink(t, tl.name)
  109. if err := NetworkSetMTU(ifcBeforeSet, mtu); err != nil {
  110. t.Fatalf("Could not set %d MTU on %#v interface: %s", mtu, tl, err)
  111. }
  112. ifcAfterSet := readLink(t, tl.name)
  113. if ifcAfterSet.MTU != mtu {
  114. t.Fatalf("Could not set %d MTU on %#v interface", mtu, tl)
  115. }
  116. }
  117. func TestNetworkSetMasterNoMaster(t *testing.T) {
  118. if testing.Short() {
  119. return
  120. }
  121. master := testLink{"tstBr", "bridge"}
  122. slave := testLink{"tstEth", "dummy"}
  123. testLinks := []testLink{master, slave}
  124. for _, tl := range testLinks {
  125. addLink(t, tl.name, tl.linkType)
  126. defer deleteLink(t, tl.name)
  127. upLink(t, tl.name)
  128. }
  129. masterIfc := readLink(t, master.name)
  130. slaveIfc := readLink(t, slave.name)
  131. if err := NetworkSetMaster(slaveIfc, masterIfc); err != nil {
  132. t.Fatalf("Could not set %#v to be the master of %#v: %s", master, slave, err)
  133. }
  134. // Trying to figure out a way to test which will not break on RHEL6.
  135. // We could check for existence of /sys/class/net/tstEth/upper_tstBr
  136. // which should point to the ../tstBr which is the UPPER device i.e. network bridge
  137. if err := NetworkSetNoMaster(slaveIfc); err != nil {
  138. t.Fatalf("Could not UNset %#v master of %#v: %s", master, slave, err)
  139. }
  140. }
  141. func TestNetworkChangeName(t *testing.T) {
  142. if testing.Short() {
  143. return
  144. }
  145. tl := testLink{"tstEth", "dummy"}
  146. newName := "newTst"
  147. addLink(t, tl.name, tl.linkType)
  148. linkIfc := readLink(t, tl.name)
  149. if err := NetworkChangeName(linkIfc, newName); err != nil {
  150. deleteLink(t, tl.name)
  151. t.Fatalf("Could not change %#v interface name to %s: %s", tl, newName, err)
  152. }
  153. readLink(t, newName)
  154. deleteLink(t, newName)
  155. }
  156. func TestNetworkLinkAddVlan(t *testing.T) {
  157. if testing.Short() {
  158. return
  159. }
  160. tl := struct {
  161. name string
  162. id uint16
  163. }{
  164. name: "tstVlan",
  165. id: 32,
  166. }
  167. masterLink := testLink{"tstEth", "dummy"}
  168. addLink(t, masterLink.name, masterLink.linkType)
  169. defer deleteLink(t, masterLink.name)
  170. if err := NetworkLinkAddVlan(masterLink.name, tl.name, tl.id); err != nil {
  171. t.Fatalf("Unable to create %#v VLAN interface: %s", tl, err)
  172. }
  173. readLink(t, tl.name)
  174. }
  175. func TestNetworkLinkAddMacVlan(t *testing.T) {
  176. if testing.Short() {
  177. return
  178. }
  179. tl := struct {
  180. name string
  181. mode string
  182. }{
  183. name: "tstVlan",
  184. mode: "private",
  185. }
  186. masterLink := testLink{"tstEth", "dummy"}
  187. addLink(t, masterLink.name, masterLink.linkType)
  188. defer deleteLink(t, masterLink.name)
  189. if err := NetworkLinkAddMacVlan(masterLink.name, tl.name, tl.mode); err != nil {
  190. t.Fatalf("Unable to create %#v MAC VLAN interface: %s", tl, err)
  191. }
  192. readLink(t, tl.name)
  193. }
  194. func TestAddDelNetworkIp(t *testing.T) {
  195. if testing.Short() {
  196. return
  197. }
  198. ifaceName := "lo"
  199. ip := net.ParseIP("127.0.1.1")
  200. mask := net.IPv4Mask(255, 255, 255, 255)
  201. ipNet := &net.IPNet{IP: ip, Mask: mask}
  202. iface, err := net.InterfaceByName(ifaceName)
  203. if err != nil {
  204. t.Skip("No 'lo' interface; skipping tests")
  205. }
  206. if err := NetworkLinkAddIp(iface, ip, ipNet); err != nil {
  207. t.Fatalf("Could not add IP address %s to interface %#v: %s", ip.String(), iface, err)
  208. }
  209. if !ipAssigned(iface, ip) {
  210. t.Fatalf("Could not locate address '%s' in lo address list.", ip.String())
  211. }
  212. if err := NetworkLinkDelIp(iface, ip, ipNet); err != nil {
  213. t.Fatalf("Could not delete IP address %s from interface %#v: %s", ip.String(), iface, err)
  214. }
  215. if ipAssigned(iface, ip) {
  216. t.Fatalf("Located address '%s' in lo address list after removal.", ip.String())
  217. }
  218. }
  219. func TestCreateVethPair(t *testing.T) {
  220. if testing.Short() {
  221. return
  222. }
  223. var (
  224. name1 = "veth1"
  225. name2 = "veth2"
  226. )
  227. if err := NetworkCreateVethPair(name1, name2, 0); err != nil {
  228. t.Fatalf("Could not create veth pair %s %s: %s", name1, name2, err)
  229. }
  230. defer NetworkLinkDel(name1)
  231. readLink(t, name1)
  232. readLink(t, name2)
  233. }
  234. //
  235. // netlink package tests which do not use RTNETLINK
  236. //
  237. func TestCreateBridgeWithMac(t *testing.T) {
  238. if testing.Short() {
  239. return
  240. }
  241. name := "testbridge"
  242. if err := CreateBridge(name, true); err != nil {
  243. t.Fatal(err)
  244. }
  245. if _, err := net.InterfaceByName(name); err != nil {
  246. t.Fatal(err)
  247. }
  248. // cleanup and tests
  249. if err := DeleteBridge(name); err != nil {
  250. t.Fatal(err)
  251. }
  252. if _, err := net.InterfaceByName(name); err == nil {
  253. t.Fatalf("expected error getting interface because %s bridge was deleted", name)
  254. }
  255. }
  256. func TestSetMacAddress(t *testing.T) {
  257. if testing.Short() {
  258. return
  259. }
  260. name := "testmac"
  261. mac := randMacAddr()
  262. if err := NetworkLinkAdd(name, "bridge"); err != nil {
  263. t.Fatal(err)
  264. }
  265. defer NetworkLinkDel(name)
  266. if err := SetMacAddress(name, mac); err != nil {
  267. t.Fatal(err)
  268. }
  269. iface, err := net.InterfaceByName(name)
  270. if err != nil {
  271. t.Fatal(err)
  272. }
  273. if iface.HardwareAddr.String() != mac {
  274. t.Fatalf("mac address %q does not match %q", iface.HardwareAddr, mac)
  275. }
  276. }