topology_test.go 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393
  1. // Copyright 2019 the Kilo authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package mesh
  15. import (
  16. "net"
  17. "strings"
  18. "testing"
  19. "github.com/kylelemons/godebug/pretty"
  20. "github.com/squat/kilo/pkg/encapsulation"
  21. "github.com/squat/kilo/pkg/wireguard"
  22. "github.com/vishvananda/netlink"
  23. "golang.org/x/sys/unix"
  24. )
  25. func allowedIPs(ips ...string) string {
  26. return strings.Join(ips, ", ")
  27. }
  28. func setup(t *testing.T) (map[string]*Node, map[string]*Peer, []byte, uint32) {
  29. key := []byte("private")
  30. e1 := &net.IPNet{IP: net.ParseIP("10.1.0.1").To4(), Mask: net.CIDRMask(16, 32)}
  31. e2 := &net.IPNet{IP: net.ParseIP("10.1.0.2").To4(), Mask: net.CIDRMask(16, 32)}
  32. e3 := &net.IPNet{IP: net.ParseIP("10.1.0.3").To4(), Mask: net.CIDRMask(16, 32)}
  33. i1 := &net.IPNet{IP: net.ParseIP("192.168.0.1").To4(), Mask: net.CIDRMask(32, 32)}
  34. i2 := &net.IPNet{IP: net.ParseIP("192.168.0.2").To4(), Mask: net.CIDRMask(32, 32)}
  35. nodes := map[string]*Node{
  36. "a": {
  37. Name: "a",
  38. ExternalIP: e1,
  39. InternalIP: i1,
  40. Location: "1",
  41. Subnet: &net.IPNet{IP: net.ParseIP("10.2.1.0"), Mask: net.CIDRMask(24, 32)},
  42. Key: []byte("key1"),
  43. },
  44. "b": {
  45. Name: "b",
  46. ExternalIP: e2,
  47. InternalIP: i1,
  48. Location: "2",
  49. Subnet: &net.IPNet{IP: net.ParseIP("10.2.2.0"), Mask: net.CIDRMask(24, 32)},
  50. Key: []byte("key2"),
  51. },
  52. "c": {
  53. Name: "c",
  54. ExternalIP: e3,
  55. InternalIP: i2,
  56. // Same location a node b.
  57. Location: "2",
  58. Subnet: &net.IPNet{IP: net.ParseIP("10.2.3.0"), Mask: net.CIDRMask(24, 32)},
  59. Key: []byte("key3"),
  60. },
  61. }
  62. peers := map[string]*Peer{
  63. "a": {
  64. Name: "a",
  65. Peer: wireguard.Peer{
  66. AllowedIPs: []*net.IPNet{
  67. {IP: net.ParseIP("10.5.0.1"), Mask: net.CIDRMask(24, 32)},
  68. {IP: net.ParseIP("10.5.0.2"), Mask: net.CIDRMask(24, 32)},
  69. },
  70. PublicKey: []byte("key4"),
  71. },
  72. },
  73. "b": {
  74. Name: "b",
  75. Peer: wireguard.Peer{
  76. AllowedIPs: []*net.IPNet{
  77. {IP: net.ParseIP("10.5.0.3"), Mask: net.CIDRMask(24, 32)},
  78. },
  79. Endpoint: &wireguard.Endpoint{
  80. IP: net.ParseIP("192.168.0.1"),
  81. Port: DefaultKiloPort,
  82. },
  83. PublicKey: []byte("key5"),
  84. },
  85. },
  86. }
  87. return nodes, peers, key, DefaultKiloPort
  88. }
  89. func TestNewTopology(t *testing.T) {
  90. nodes, peers, key, port := setup(t)
  91. w1 := net.ParseIP("10.4.0.1").To4()
  92. w2 := net.ParseIP("10.4.0.2").To4()
  93. w3 := net.ParseIP("10.4.0.3").To4()
  94. for _, tc := range []struct {
  95. name string
  96. granularity Granularity
  97. hostname string
  98. result *Topology
  99. }{
  100. {
  101. name: "logical from a",
  102. granularity: LogicalGranularity,
  103. hostname: nodes["a"].Name,
  104. result: &Topology{
  105. hostname: nodes["a"].Name,
  106. leader: true,
  107. location: nodes["a"].Location,
  108. subnet: DefaultKiloSubnet,
  109. privateIP: nodes["a"].InternalIP,
  110. wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
  111. segments: []*segment{
  112. {
  113. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  114. endpoint: nodes["a"].ExternalIP.IP,
  115. key: nodes["a"].Key,
  116. location: nodes["a"].Location,
  117. cidrs: []*net.IPNet{nodes["a"].Subnet},
  118. hostnames: []string{"a"},
  119. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  120. wireGuardIP: w1,
  121. },
  122. {
  123. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  124. endpoint: nodes["b"].ExternalIP.IP,
  125. key: nodes["b"].Key,
  126. location: nodes["b"].Location,
  127. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  128. hostnames: []string{"b", "c"},
  129. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  130. wireGuardIP: w2,
  131. },
  132. },
  133. peers: []*Peer{peers["a"], peers["b"]},
  134. },
  135. },
  136. {
  137. name: "logical from b",
  138. granularity: LogicalGranularity,
  139. hostname: nodes["b"].Name,
  140. result: &Topology{
  141. hostname: nodes["b"].Name,
  142. leader: true,
  143. location: nodes["b"].Location,
  144. subnet: DefaultKiloSubnet,
  145. privateIP: nodes["b"].InternalIP,
  146. wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
  147. segments: []*segment{
  148. {
  149. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  150. endpoint: nodes["a"].ExternalIP.IP,
  151. key: nodes["a"].Key,
  152. location: nodes["a"].Location,
  153. cidrs: []*net.IPNet{nodes["a"].Subnet},
  154. hostnames: []string{"a"},
  155. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  156. wireGuardIP: w1,
  157. },
  158. {
  159. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  160. endpoint: nodes["b"].ExternalIP.IP,
  161. key: nodes["b"].Key,
  162. location: nodes["b"].Location,
  163. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  164. hostnames: []string{"b", "c"},
  165. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  166. wireGuardIP: w2,
  167. },
  168. },
  169. peers: []*Peer{peers["a"], peers["b"]},
  170. },
  171. },
  172. {
  173. name: "logical from c",
  174. granularity: LogicalGranularity,
  175. hostname: nodes["c"].Name,
  176. result: &Topology{
  177. hostname: nodes["c"].Name,
  178. leader: false,
  179. location: nodes["b"].Location,
  180. subnet: DefaultKiloSubnet,
  181. privateIP: nodes["c"].InternalIP,
  182. wireGuardCIDR: nil,
  183. segments: []*segment{
  184. {
  185. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  186. endpoint: nodes["a"].ExternalIP.IP,
  187. key: nodes["a"].Key,
  188. location: nodes["a"].Location,
  189. cidrs: []*net.IPNet{nodes["a"].Subnet},
  190. hostnames: []string{"a"},
  191. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  192. wireGuardIP: w1,
  193. },
  194. {
  195. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  196. endpoint: nodes["b"].ExternalIP.IP,
  197. key: nodes["b"].Key,
  198. location: nodes["b"].Location,
  199. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  200. hostnames: []string{"b", "c"},
  201. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  202. wireGuardIP: w2,
  203. },
  204. },
  205. peers: []*Peer{peers["a"], peers["b"]},
  206. },
  207. },
  208. {
  209. name: "full from a",
  210. granularity: FullGranularity,
  211. hostname: nodes["a"].Name,
  212. result: &Topology{
  213. hostname: nodes["a"].Name,
  214. leader: true,
  215. location: nodes["a"].Name,
  216. subnet: DefaultKiloSubnet,
  217. privateIP: nodes["a"].InternalIP,
  218. wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
  219. segments: []*segment{
  220. {
  221. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  222. endpoint: nodes["a"].ExternalIP.IP,
  223. key: nodes["a"].Key,
  224. location: nodes["a"].Name,
  225. cidrs: []*net.IPNet{nodes["a"].Subnet},
  226. hostnames: []string{"a"},
  227. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  228. wireGuardIP: w1,
  229. },
  230. {
  231. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  232. endpoint: nodes["b"].ExternalIP.IP,
  233. key: nodes["b"].Key,
  234. location: nodes["b"].Name,
  235. cidrs: []*net.IPNet{nodes["b"].Subnet},
  236. hostnames: []string{"b"},
  237. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  238. wireGuardIP: w2,
  239. },
  240. {
  241. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  242. endpoint: nodes["c"].ExternalIP.IP,
  243. key: nodes["c"].Key,
  244. location: nodes["c"].Name,
  245. cidrs: []*net.IPNet{nodes["c"].Subnet},
  246. hostnames: []string{"c"},
  247. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  248. wireGuardIP: w3,
  249. },
  250. },
  251. peers: []*Peer{peers["a"], peers["b"]},
  252. },
  253. },
  254. {
  255. name: "full from b",
  256. granularity: FullGranularity,
  257. hostname: nodes["b"].Name,
  258. result: &Topology{
  259. hostname: nodes["b"].Name,
  260. leader: true,
  261. location: nodes["b"].Name,
  262. subnet: DefaultKiloSubnet,
  263. privateIP: nodes["b"].InternalIP,
  264. wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
  265. segments: []*segment{
  266. {
  267. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  268. endpoint: nodes["a"].ExternalIP.IP,
  269. key: nodes["a"].Key,
  270. location: nodes["a"].Name,
  271. cidrs: []*net.IPNet{nodes["a"].Subnet},
  272. hostnames: []string{"a"},
  273. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  274. wireGuardIP: w1,
  275. },
  276. {
  277. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  278. endpoint: nodes["b"].ExternalIP.IP,
  279. key: nodes["b"].Key,
  280. location: nodes["b"].Name,
  281. cidrs: []*net.IPNet{nodes["b"].Subnet},
  282. hostnames: []string{"b"},
  283. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  284. wireGuardIP: w2,
  285. },
  286. {
  287. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  288. endpoint: nodes["c"].ExternalIP.IP,
  289. key: nodes["c"].Key,
  290. location: nodes["c"].Name,
  291. cidrs: []*net.IPNet{nodes["c"].Subnet},
  292. hostnames: []string{"c"},
  293. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  294. wireGuardIP: w3,
  295. },
  296. },
  297. peers: []*Peer{peers["a"], peers["b"]},
  298. },
  299. },
  300. {
  301. name: "full from c",
  302. granularity: FullGranularity,
  303. hostname: nodes["c"].Name,
  304. result: &Topology{
  305. hostname: nodes["c"].Name,
  306. leader: true,
  307. location: nodes["c"].Name,
  308. subnet: DefaultKiloSubnet,
  309. privateIP: nodes["c"].InternalIP,
  310. wireGuardCIDR: &net.IPNet{IP: w3, Mask: net.CIDRMask(16, 32)},
  311. segments: []*segment{
  312. {
  313. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  314. endpoint: nodes["a"].ExternalIP.IP,
  315. key: nodes["a"].Key,
  316. location: nodes["a"].Name,
  317. cidrs: []*net.IPNet{nodes["a"].Subnet},
  318. hostnames: []string{"a"},
  319. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  320. wireGuardIP: w1,
  321. },
  322. {
  323. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  324. endpoint: nodes["b"].ExternalIP.IP,
  325. key: nodes["b"].Key,
  326. location: nodes["b"].Name,
  327. cidrs: []*net.IPNet{nodes["b"].Subnet},
  328. hostnames: []string{"b"},
  329. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  330. wireGuardIP: w2,
  331. },
  332. {
  333. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  334. endpoint: nodes["c"].ExternalIP.IP,
  335. key: nodes["c"].Key,
  336. location: nodes["c"].Name,
  337. cidrs: []*net.IPNet{nodes["c"].Subnet},
  338. hostnames: []string{"c"},
  339. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  340. wireGuardIP: w3,
  341. },
  342. },
  343. peers: []*Peer{peers["a"], peers["b"]},
  344. },
  345. },
  346. } {
  347. tc.result.key = key
  348. tc.result.port = port
  349. topo, err := NewTopology(nodes, peers, tc.granularity, tc.hostname, port, key, DefaultKiloSubnet)
  350. if err != nil {
  351. t.Errorf("test case %q: failed to generate Topology: %v", tc.name, err)
  352. }
  353. if diff := pretty.Compare(topo, tc.result); diff != "" {
  354. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  355. }
  356. }
  357. }
  358. func mustTopo(t *testing.T, nodes map[string]*Node, peers map[string]*Peer, granularity Granularity, hostname string, port uint32, key []byte, subnet *net.IPNet) *Topology {
  359. topo, err := NewTopology(nodes, peers, granularity, hostname, port, key, subnet)
  360. if err != nil {
  361. t.Errorf("failed to generate Topology: %v", err)
  362. }
  363. return topo
  364. }
  365. func TestRoutes(t *testing.T) {
  366. nodes, peers, key, port := setup(t)
  367. kiloIface := 0
  368. privIface := 1
  369. pubIface := 2
  370. mustTopoForGranularityAndHost := func(granularity Granularity, hostname string) *Topology {
  371. return mustTopo(t, nodes, peers, granularity, hostname, port, key, DefaultKiloSubnet)
  372. }
  373. for _, tc := range []struct {
  374. name string
  375. local bool
  376. topology *Topology
  377. result []*netlink.Route
  378. }{
  379. {
  380. name: "logical from a",
  381. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name),
  382. result: []*netlink.Route{
  383. {
  384. Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].cidrs[0],
  385. Flags: int(netlink.FLAG_ONLINK),
  386. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  387. LinkIndex: kiloIface,
  388. Protocol: unix.RTPROT_STATIC,
  389. },
  390. {
  391. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  392. Flags: int(netlink.FLAG_ONLINK),
  393. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  394. LinkIndex: kiloIface,
  395. Protocol: unix.RTPROT_STATIC,
  396. },
  397. {
  398. Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].cidrs[1],
  399. Flags: int(netlink.FLAG_ONLINK),
  400. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  401. LinkIndex: kiloIface,
  402. Protocol: unix.RTPROT_STATIC,
  403. },
  404. {
  405. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  406. Flags: int(netlink.FLAG_ONLINK),
  407. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  408. LinkIndex: kiloIface,
  409. Protocol: unix.RTPROT_STATIC,
  410. },
  411. {
  412. Dst: peers["a"].AllowedIPs[0],
  413. LinkIndex: kiloIface,
  414. Protocol: unix.RTPROT_STATIC,
  415. },
  416. {
  417. Dst: peers["a"].AllowedIPs[1],
  418. LinkIndex: kiloIface,
  419. Protocol: unix.RTPROT_STATIC,
  420. },
  421. {
  422. Dst: peers["b"].AllowedIPs[0],
  423. LinkIndex: kiloIface,
  424. Protocol: unix.RTPROT_STATIC,
  425. },
  426. },
  427. },
  428. {
  429. name: "logical from b",
  430. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name),
  431. result: []*netlink.Route{
  432. {
  433. Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].cidrs[0],
  434. Flags: int(netlink.FLAG_ONLINK),
  435. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  436. LinkIndex: kiloIface,
  437. Protocol: unix.RTPROT_STATIC,
  438. },
  439. {
  440. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  441. Flags: int(netlink.FLAG_ONLINK),
  442. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  443. LinkIndex: kiloIface,
  444. Protocol: unix.RTPROT_STATIC,
  445. },
  446. {
  447. Dst: peers["a"].AllowedIPs[0],
  448. LinkIndex: kiloIface,
  449. Protocol: unix.RTPROT_STATIC,
  450. },
  451. {
  452. Dst: peers["a"].AllowedIPs[1],
  453. LinkIndex: kiloIface,
  454. Protocol: unix.RTPROT_STATIC,
  455. },
  456. {
  457. Dst: peers["b"].AllowedIPs[0],
  458. LinkIndex: kiloIface,
  459. Protocol: unix.RTPROT_STATIC,
  460. },
  461. },
  462. },
  463. {
  464. name: "logical from c",
  465. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name),
  466. result: []*netlink.Route{
  467. {
  468. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].wireGuardIP),
  469. Flags: int(netlink.FLAG_ONLINK),
  470. Gw: nodes["b"].InternalIP.IP,
  471. LinkIndex: privIface,
  472. Protocol: unix.RTPROT_STATIC,
  473. },
  474. {
  475. Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].cidrs[0],
  476. Flags: int(netlink.FLAG_ONLINK),
  477. Gw: nodes["b"].InternalIP.IP,
  478. LinkIndex: privIface,
  479. Protocol: unix.RTPROT_STATIC,
  480. },
  481. {
  482. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  483. Flags: int(netlink.FLAG_ONLINK),
  484. Gw: nodes["b"].InternalIP.IP,
  485. LinkIndex: privIface,
  486. Protocol: unix.RTPROT_STATIC,
  487. },
  488. {
  489. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[1].wireGuardIP),
  490. Flags: int(netlink.FLAG_ONLINK),
  491. Gw: nodes["b"].InternalIP.IP,
  492. LinkIndex: privIface,
  493. Protocol: unix.RTPROT_STATIC,
  494. },
  495. {
  496. Dst: peers["a"].AllowedIPs[0],
  497. Flags: int(netlink.FLAG_ONLINK),
  498. Gw: nodes["b"].InternalIP.IP,
  499. LinkIndex: privIface,
  500. Protocol: unix.RTPROT_STATIC,
  501. },
  502. {
  503. Dst: peers["a"].AllowedIPs[1],
  504. Flags: int(netlink.FLAG_ONLINK),
  505. Gw: nodes["b"].InternalIP.IP,
  506. LinkIndex: privIface,
  507. Protocol: unix.RTPROT_STATIC,
  508. },
  509. {
  510. Dst: peers["b"].AllowedIPs[0],
  511. Flags: int(netlink.FLAG_ONLINK),
  512. Gw: nodes["b"].InternalIP.IP,
  513. LinkIndex: privIface,
  514. Protocol: unix.RTPROT_STATIC,
  515. },
  516. },
  517. },
  518. {
  519. name: "full from a",
  520. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name),
  521. result: []*netlink.Route{
  522. {
  523. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].cidrs[0],
  524. Flags: int(netlink.FLAG_ONLINK),
  525. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  526. LinkIndex: kiloIface,
  527. Protocol: unix.RTPROT_STATIC,
  528. },
  529. {
  530. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  531. Flags: int(netlink.FLAG_ONLINK),
  532. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  533. LinkIndex: kiloIface,
  534. Protocol: unix.RTPROT_STATIC,
  535. },
  536. {
  537. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].cidrs[0],
  538. Flags: int(netlink.FLAG_ONLINK),
  539. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
  540. LinkIndex: kiloIface,
  541. Protocol: unix.RTPROT_STATIC,
  542. },
  543. {
  544. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  545. Flags: int(netlink.FLAG_ONLINK),
  546. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
  547. LinkIndex: kiloIface,
  548. Protocol: unix.RTPROT_STATIC,
  549. },
  550. {
  551. Dst: peers["a"].AllowedIPs[0],
  552. LinkIndex: kiloIface,
  553. Protocol: unix.RTPROT_STATIC,
  554. },
  555. {
  556. Dst: peers["a"].AllowedIPs[1],
  557. LinkIndex: kiloIface,
  558. Protocol: unix.RTPROT_STATIC,
  559. },
  560. {
  561. Dst: peers["b"].AllowedIPs[0],
  562. LinkIndex: kiloIface,
  563. Protocol: unix.RTPROT_STATIC,
  564. },
  565. },
  566. },
  567. {
  568. name: "full from b",
  569. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name),
  570. result: []*netlink.Route{
  571. {
  572. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].cidrs[0],
  573. Flags: int(netlink.FLAG_ONLINK),
  574. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  575. LinkIndex: kiloIface,
  576. Protocol: unix.RTPROT_STATIC,
  577. },
  578. {
  579. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  580. Flags: int(netlink.FLAG_ONLINK),
  581. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  582. LinkIndex: kiloIface,
  583. Protocol: unix.RTPROT_STATIC,
  584. },
  585. {
  586. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].cidrs[0],
  587. Flags: int(netlink.FLAG_ONLINK),
  588. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
  589. LinkIndex: kiloIface,
  590. Protocol: unix.RTPROT_STATIC,
  591. },
  592. {
  593. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  594. Flags: int(netlink.FLAG_ONLINK),
  595. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
  596. LinkIndex: kiloIface,
  597. Protocol: unix.RTPROT_STATIC,
  598. },
  599. {
  600. Dst: peers["a"].AllowedIPs[0],
  601. LinkIndex: kiloIface,
  602. Protocol: unix.RTPROT_STATIC,
  603. },
  604. {
  605. Dst: peers["a"].AllowedIPs[1],
  606. LinkIndex: kiloIface,
  607. Protocol: unix.RTPROT_STATIC,
  608. },
  609. {
  610. Dst: peers["b"].AllowedIPs[0],
  611. LinkIndex: kiloIface,
  612. Protocol: unix.RTPROT_STATIC,
  613. },
  614. },
  615. },
  616. {
  617. name: "full from c",
  618. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name),
  619. result: []*netlink.Route{
  620. {
  621. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].cidrs[0],
  622. Flags: int(netlink.FLAG_ONLINK),
  623. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
  624. LinkIndex: kiloIface,
  625. Protocol: unix.RTPROT_STATIC,
  626. },
  627. {
  628. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  629. Flags: int(netlink.FLAG_ONLINK),
  630. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
  631. LinkIndex: kiloIface,
  632. Protocol: unix.RTPROT_STATIC,
  633. },
  634. {
  635. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].cidrs[0],
  636. Flags: int(netlink.FLAG_ONLINK),
  637. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
  638. LinkIndex: kiloIface,
  639. Protocol: unix.RTPROT_STATIC,
  640. },
  641. {
  642. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  643. Flags: int(netlink.FLAG_ONLINK),
  644. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
  645. LinkIndex: kiloIface,
  646. Protocol: unix.RTPROT_STATIC,
  647. },
  648. {
  649. Dst: peers["a"].AllowedIPs[0],
  650. LinkIndex: kiloIface,
  651. Protocol: unix.RTPROT_STATIC,
  652. },
  653. {
  654. Dst: peers["a"].AllowedIPs[1],
  655. LinkIndex: kiloIface,
  656. Protocol: unix.RTPROT_STATIC,
  657. },
  658. {
  659. Dst: peers["b"].AllowedIPs[0],
  660. LinkIndex: kiloIface,
  661. Protocol: unix.RTPROT_STATIC,
  662. },
  663. },
  664. },
  665. {
  666. name: "logical from a local",
  667. local: true,
  668. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name),
  669. result: []*netlink.Route{
  670. {
  671. Dst: nodes["b"].Subnet,
  672. Flags: int(netlink.FLAG_ONLINK),
  673. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  674. LinkIndex: kiloIface,
  675. Protocol: unix.RTPROT_STATIC,
  676. },
  677. {
  678. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  679. Flags: int(netlink.FLAG_ONLINK),
  680. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  681. LinkIndex: kiloIface,
  682. Protocol: unix.RTPROT_STATIC,
  683. },
  684. {
  685. Dst: nodes["c"].Subnet,
  686. Flags: int(netlink.FLAG_ONLINK),
  687. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  688. LinkIndex: kiloIface,
  689. Protocol: unix.RTPROT_STATIC,
  690. },
  691. {
  692. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  693. Flags: int(netlink.FLAG_ONLINK),
  694. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  695. LinkIndex: kiloIface,
  696. Protocol: unix.RTPROT_STATIC,
  697. },
  698. {
  699. Dst: peers["a"].AllowedIPs[0],
  700. LinkIndex: kiloIface,
  701. Protocol: unix.RTPROT_STATIC,
  702. },
  703. {
  704. Dst: peers["a"].AllowedIPs[1],
  705. LinkIndex: kiloIface,
  706. Protocol: unix.RTPROT_STATIC,
  707. },
  708. {
  709. Dst: peers["b"].AllowedIPs[0],
  710. LinkIndex: kiloIface,
  711. Protocol: unix.RTPROT_STATIC,
  712. },
  713. },
  714. },
  715. {
  716. name: "logical from b local",
  717. local: true,
  718. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name),
  719. result: []*netlink.Route{
  720. {
  721. Dst: nodes["a"].Subnet,
  722. Flags: int(netlink.FLAG_ONLINK),
  723. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  724. LinkIndex: kiloIface,
  725. Protocol: unix.RTPROT_STATIC,
  726. },
  727. {
  728. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  729. Flags: int(netlink.FLAG_ONLINK),
  730. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  731. LinkIndex: kiloIface,
  732. Protocol: unix.RTPROT_STATIC,
  733. },
  734. {
  735. Dst: nodes["c"].Subnet,
  736. Flags: int(netlink.FLAG_ONLINK),
  737. Gw: nodes["c"].InternalIP.IP,
  738. LinkIndex: privIface,
  739. Protocol: unix.RTPROT_STATIC,
  740. },
  741. {
  742. Dst: peers["a"].AllowedIPs[0],
  743. LinkIndex: kiloIface,
  744. Protocol: unix.RTPROT_STATIC,
  745. },
  746. {
  747. Dst: peers["a"].AllowedIPs[1],
  748. LinkIndex: kiloIface,
  749. Protocol: unix.RTPROT_STATIC,
  750. },
  751. {
  752. Dst: peers["b"].AllowedIPs[0],
  753. LinkIndex: kiloIface,
  754. Protocol: unix.RTPROT_STATIC,
  755. },
  756. },
  757. },
  758. {
  759. name: "logical from c local",
  760. local: true,
  761. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name),
  762. result: []*netlink.Route{
  763. {
  764. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].wireGuardIP),
  765. Flags: int(netlink.FLAG_ONLINK),
  766. Gw: nodes["b"].InternalIP.IP,
  767. LinkIndex: privIface,
  768. Protocol: unix.RTPROT_STATIC,
  769. },
  770. {
  771. Dst: nodes["a"].Subnet,
  772. Flags: int(netlink.FLAG_ONLINK),
  773. Gw: nodes["b"].InternalIP.IP,
  774. LinkIndex: privIface,
  775. Protocol: unix.RTPROT_STATIC,
  776. },
  777. {
  778. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  779. Flags: int(netlink.FLAG_ONLINK),
  780. Gw: nodes["b"].InternalIP.IP,
  781. LinkIndex: privIface,
  782. Protocol: unix.RTPROT_STATIC,
  783. },
  784. {
  785. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[1].wireGuardIP),
  786. Flags: int(netlink.FLAG_ONLINK),
  787. Gw: nodes["b"].InternalIP.IP,
  788. LinkIndex: privIface,
  789. Protocol: unix.RTPROT_STATIC,
  790. },
  791. {
  792. Dst: nodes["b"].Subnet,
  793. Flags: int(netlink.FLAG_ONLINK),
  794. Gw: nodes["b"].InternalIP.IP,
  795. LinkIndex: privIface,
  796. Protocol: unix.RTPROT_STATIC,
  797. },
  798. {
  799. Dst: peers["a"].AllowedIPs[0],
  800. Flags: int(netlink.FLAG_ONLINK),
  801. Gw: nodes["b"].InternalIP.IP,
  802. LinkIndex: privIface,
  803. Protocol: unix.RTPROT_STATIC,
  804. },
  805. {
  806. Dst: peers["a"].AllowedIPs[1],
  807. Flags: int(netlink.FLAG_ONLINK),
  808. Gw: nodes["b"].InternalIP.IP,
  809. LinkIndex: privIface,
  810. Protocol: unix.RTPROT_STATIC,
  811. },
  812. {
  813. Dst: peers["b"].AllowedIPs[0],
  814. Flags: int(netlink.FLAG_ONLINK),
  815. Gw: nodes["b"].InternalIP.IP,
  816. LinkIndex: privIface,
  817. Protocol: unix.RTPROT_STATIC,
  818. },
  819. },
  820. },
  821. {
  822. name: "full from a local",
  823. local: true,
  824. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name),
  825. result: []*netlink.Route{
  826. {
  827. Dst: nodes["b"].Subnet,
  828. Flags: int(netlink.FLAG_ONLINK),
  829. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  830. LinkIndex: kiloIface,
  831. Protocol: unix.RTPROT_STATIC,
  832. },
  833. {
  834. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  835. Flags: int(netlink.FLAG_ONLINK),
  836. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  837. LinkIndex: kiloIface,
  838. Protocol: unix.RTPROT_STATIC,
  839. },
  840. {
  841. Dst: nodes["c"].Subnet,
  842. Flags: int(netlink.FLAG_ONLINK),
  843. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
  844. LinkIndex: kiloIface,
  845. Protocol: unix.RTPROT_STATIC,
  846. },
  847. {
  848. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  849. Flags: int(netlink.FLAG_ONLINK),
  850. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
  851. LinkIndex: kiloIface,
  852. Protocol: unix.RTPROT_STATIC,
  853. },
  854. {
  855. Dst: peers["a"].AllowedIPs[0],
  856. LinkIndex: kiloIface,
  857. Protocol: unix.RTPROT_STATIC,
  858. },
  859. {
  860. Dst: peers["a"].AllowedIPs[1],
  861. LinkIndex: kiloIface,
  862. Protocol: unix.RTPROT_STATIC,
  863. },
  864. {
  865. Dst: peers["b"].AllowedIPs[0],
  866. LinkIndex: kiloIface,
  867. Protocol: unix.RTPROT_STATIC,
  868. },
  869. },
  870. },
  871. {
  872. name: "full from b local",
  873. local: true,
  874. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name),
  875. result: []*netlink.Route{
  876. {
  877. Dst: nodes["a"].Subnet,
  878. Flags: int(netlink.FLAG_ONLINK),
  879. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  880. LinkIndex: kiloIface,
  881. Protocol: unix.RTPROT_STATIC,
  882. },
  883. {
  884. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  885. Flags: int(netlink.FLAG_ONLINK),
  886. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  887. LinkIndex: kiloIface,
  888. Protocol: unix.RTPROT_STATIC,
  889. },
  890. {
  891. Dst: nodes["c"].Subnet,
  892. Flags: int(netlink.FLAG_ONLINK),
  893. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
  894. LinkIndex: kiloIface,
  895. Protocol: unix.RTPROT_STATIC,
  896. },
  897. {
  898. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  899. Flags: int(netlink.FLAG_ONLINK),
  900. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
  901. LinkIndex: kiloIface,
  902. Protocol: unix.RTPROT_STATIC,
  903. },
  904. {
  905. Dst: peers["a"].AllowedIPs[0],
  906. LinkIndex: kiloIface,
  907. Protocol: unix.RTPROT_STATIC,
  908. },
  909. {
  910. Dst: peers["a"].AllowedIPs[1],
  911. LinkIndex: kiloIface,
  912. Protocol: unix.RTPROT_STATIC,
  913. },
  914. {
  915. Dst: peers["b"].AllowedIPs[0],
  916. LinkIndex: kiloIface,
  917. Protocol: unix.RTPROT_STATIC,
  918. },
  919. },
  920. },
  921. {
  922. name: "full from c local",
  923. local: true,
  924. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name),
  925. result: []*netlink.Route{
  926. {
  927. Dst: nodes["a"].Subnet,
  928. Flags: int(netlink.FLAG_ONLINK),
  929. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
  930. LinkIndex: kiloIface,
  931. Protocol: unix.RTPROT_STATIC,
  932. },
  933. {
  934. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  935. Flags: int(netlink.FLAG_ONLINK),
  936. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
  937. LinkIndex: kiloIface,
  938. Protocol: unix.RTPROT_STATIC,
  939. },
  940. {
  941. Dst: nodes["b"].Subnet,
  942. Flags: int(netlink.FLAG_ONLINK),
  943. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
  944. LinkIndex: kiloIface,
  945. Protocol: unix.RTPROT_STATIC,
  946. },
  947. {
  948. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  949. Flags: int(netlink.FLAG_ONLINK),
  950. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
  951. LinkIndex: kiloIface,
  952. Protocol: unix.RTPROT_STATIC,
  953. },
  954. {
  955. Dst: peers["a"].AllowedIPs[0],
  956. LinkIndex: kiloIface,
  957. Protocol: unix.RTPROT_STATIC,
  958. },
  959. {
  960. Dst: peers["a"].AllowedIPs[1],
  961. LinkIndex: kiloIface,
  962. Protocol: unix.RTPROT_STATIC,
  963. },
  964. {
  965. Dst: peers["b"].AllowedIPs[0],
  966. LinkIndex: kiloIface,
  967. Protocol: unix.RTPROT_STATIC,
  968. },
  969. },
  970. },
  971. } {
  972. routes := tc.topology.Routes(kiloIface, privIface, pubIface, tc.local, encapsulation.NewIPIP(encapsulation.Never))
  973. if diff := pretty.Compare(routes, tc.result); diff != "" {
  974. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  975. }
  976. }
  977. }
  978. func TestConf(t *testing.T) {
  979. nodes, peers, key, port := setup(t)
  980. for _, tc := range []struct {
  981. name string
  982. topology *Topology
  983. result string
  984. }{
  985. {
  986. name: "logical from a",
  987. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet),
  988. result: `[Interface]
  989. PrivateKey = private
  990. ListenPort = 51820
  991. [Peer]
  992. PublicKey = key2
  993. Endpoint = 10.1.0.2:51820
  994. AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
  995. [Peer]
  996. PublicKey = key4
  997. PersistentKeepalive = 0
  998. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  999. [Peer]
  1000. PublicKey = key5
  1001. Endpoint = 192.168.0.1:51820
  1002. PersistentKeepalive = 0
  1003. AllowedIPs = 10.5.0.3/24
  1004. `,
  1005. },
  1006. {
  1007. name: "logical from b",
  1008. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["b"].Name, port, key, DefaultKiloSubnet),
  1009. result: `[Interface]
  1010. PrivateKey = private
  1011. ListenPort = 51820
  1012. [Peer]
  1013. PublicKey = key1
  1014. Endpoint = 10.1.0.1:51820
  1015. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  1016. [Peer]
  1017. PublicKey = key4
  1018. PersistentKeepalive = 0
  1019. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  1020. [Peer]
  1021. PublicKey = key5
  1022. Endpoint = 192.168.0.1:51820
  1023. PersistentKeepalive = 0
  1024. AllowedIPs = 10.5.0.3/24
  1025. `,
  1026. },
  1027. {
  1028. name: "logical from c",
  1029. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["c"].Name, port, key, DefaultKiloSubnet),
  1030. result: `[Interface]
  1031. PrivateKey = private
  1032. ListenPort = 51820
  1033. [Peer]
  1034. PublicKey = key1
  1035. Endpoint = 10.1.0.1:51820
  1036. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  1037. [Peer]
  1038. PublicKey = key4
  1039. PersistentKeepalive = 0
  1040. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  1041. [Peer]
  1042. PublicKey = key5
  1043. Endpoint = 192.168.0.1:51820
  1044. PersistentKeepalive = 0
  1045. AllowedIPs = 10.5.0.3/24
  1046. `,
  1047. },
  1048. {
  1049. name: "full from a",
  1050. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet),
  1051. result: `[Interface]
  1052. PrivateKey = private
  1053. ListenPort = 51820
  1054. [Peer]
  1055. PublicKey = key2
  1056. Endpoint = 10.1.0.2:51820
  1057. AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.4.0.2/32
  1058. [Peer]
  1059. PublicKey = key3
  1060. Endpoint = 10.1.0.3:51820
  1061. AllowedIPs = 10.2.3.0/24, 192.168.0.2/32, 10.4.0.3/32
  1062. [Peer]
  1063. PublicKey = key4
  1064. PersistentKeepalive = 0
  1065. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  1066. [Peer]
  1067. PublicKey = key5
  1068. Endpoint = 192.168.0.1:51820
  1069. PersistentKeepalive = 0
  1070. AllowedIPs = 10.5.0.3/24
  1071. `,
  1072. },
  1073. {
  1074. name: "full from b",
  1075. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["b"].Name, port, key, DefaultKiloSubnet),
  1076. result: `[Interface]
  1077. PrivateKey = private
  1078. ListenPort = 51820
  1079. [Peer]
  1080. PublicKey = key1
  1081. Endpoint = 10.1.0.1:51820
  1082. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  1083. [Peer]
  1084. PublicKey = key3
  1085. Endpoint = 10.1.0.3:51820
  1086. AllowedIPs = 10.2.3.0/24, 192.168.0.2/32, 10.4.0.3/32
  1087. [Peer]
  1088. PublicKey = key4
  1089. PersistentKeepalive = 0
  1090. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  1091. [Peer]
  1092. PublicKey = key5
  1093. Endpoint = 192.168.0.1:51820
  1094. PersistentKeepalive = 0
  1095. AllowedIPs = 10.5.0.3/24
  1096. `,
  1097. },
  1098. {
  1099. name: "full from c",
  1100. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["c"].Name, port, key, DefaultKiloSubnet),
  1101. result: `[Interface]
  1102. PrivateKey = private
  1103. ListenPort = 51820
  1104. [Peer]
  1105. PublicKey = key1
  1106. Endpoint = 10.1.0.1:51820
  1107. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  1108. [Peer]
  1109. PublicKey = key2
  1110. Endpoint = 10.1.0.2:51820
  1111. AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.4.0.2/32
  1112. [Peer]
  1113. PublicKey = key4
  1114. PersistentKeepalive = 0
  1115. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  1116. [Peer]
  1117. PublicKey = key5
  1118. Endpoint = 192.168.0.1:51820
  1119. PersistentKeepalive = 0
  1120. AllowedIPs = 10.5.0.3/24
  1121. `,
  1122. },
  1123. } {
  1124. conf := tc.topology.Conf()
  1125. if !conf.Equal(wireguard.Parse([]byte(tc.result))) {
  1126. buf, err := conf.Bytes()
  1127. if err != nil {
  1128. t.Errorf("test case %q: failed to render conf: %v", tc.name, err)
  1129. }
  1130. t.Errorf("test case %q: expected %s got %s", tc.name, tc.result, string(buf))
  1131. }
  1132. }
  1133. }
  1134. func TestFindLeader(t *testing.T) {
  1135. ip, e1, err := net.ParseCIDR("10.0.0.1/32")
  1136. if err != nil {
  1137. t.Fatalf("failed to parse external IP CIDR: %v", err)
  1138. }
  1139. e1.IP = ip
  1140. ip, e2, err := net.ParseCIDR("8.8.8.8/32")
  1141. if err != nil {
  1142. t.Fatalf("failed to parse external IP CIDR: %v", err)
  1143. }
  1144. e2.IP = ip
  1145. nodes := []*Node{
  1146. {
  1147. Name: "a",
  1148. ExternalIP: e1,
  1149. },
  1150. {
  1151. Name: "b",
  1152. ExternalIP: e2,
  1153. },
  1154. {
  1155. Name: "c",
  1156. ExternalIP: e2,
  1157. },
  1158. {
  1159. Name: "d",
  1160. ExternalIP: e1,
  1161. Leader: true,
  1162. },
  1163. {
  1164. Name: "2",
  1165. ExternalIP: e2,
  1166. Leader: true,
  1167. },
  1168. }
  1169. for _, tc := range []struct {
  1170. name string
  1171. nodes []*Node
  1172. out int
  1173. }{
  1174. {
  1175. name: "nil",
  1176. nodes: nil,
  1177. out: 0,
  1178. },
  1179. {
  1180. name: "one",
  1181. nodes: []*Node{nodes[0]},
  1182. out: 0,
  1183. },
  1184. {
  1185. name: "non-leaders",
  1186. nodes: []*Node{nodes[0], nodes[1], nodes[2]},
  1187. out: 1,
  1188. },
  1189. {
  1190. name: "leaders",
  1191. nodes: []*Node{nodes[3], nodes[4]},
  1192. out: 1,
  1193. },
  1194. {
  1195. name: "public",
  1196. nodes: []*Node{nodes[1], nodes[2], nodes[4]},
  1197. out: 2,
  1198. },
  1199. {
  1200. name: "private",
  1201. nodes: []*Node{nodes[0], nodes[3]},
  1202. out: 1,
  1203. },
  1204. {
  1205. name: "all",
  1206. nodes: nodes,
  1207. out: 4,
  1208. },
  1209. } {
  1210. l := findLeader(tc.nodes)
  1211. if l != tc.out {
  1212. t.Errorf("test case %q: expected %d got %d", tc.name, tc.out, l)
  1213. }
  1214. }
  1215. }
  1216. func TestDeduplicatePeerIPs(t *testing.T) {
  1217. p1 := &Peer{
  1218. Name: "1",
  1219. Peer: wireguard.Peer{
  1220. PublicKey: []byte("key1"),
  1221. AllowedIPs: []*net.IPNet{
  1222. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  1223. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  1224. },
  1225. },
  1226. }
  1227. p2 := &Peer{
  1228. Name: "2",
  1229. Peer: wireguard.Peer{
  1230. PublicKey: []byte("key2"),
  1231. AllowedIPs: []*net.IPNet{
  1232. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  1233. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  1234. },
  1235. },
  1236. }
  1237. p3 := &Peer{
  1238. Name: "3",
  1239. Peer: wireguard.Peer{
  1240. PublicKey: []byte("key3"),
  1241. AllowedIPs: []*net.IPNet{
  1242. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  1243. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  1244. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  1245. },
  1246. },
  1247. }
  1248. p4 := &Peer{
  1249. Name: "4",
  1250. Peer: wireguard.Peer{
  1251. PublicKey: []byte("key4"),
  1252. AllowedIPs: []*net.IPNet{
  1253. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  1254. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  1255. },
  1256. },
  1257. }
  1258. for _, tc := range []struct {
  1259. name string
  1260. peers []*Peer
  1261. out []*Peer
  1262. }{
  1263. {
  1264. name: "nil",
  1265. peers: nil,
  1266. out: nil,
  1267. },
  1268. {
  1269. name: "simple dupe",
  1270. peers: []*Peer{p1, p2},
  1271. out: []*Peer{
  1272. p1,
  1273. {
  1274. Name: "2",
  1275. Peer: wireguard.Peer{
  1276. PublicKey: []byte("key2"),
  1277. AllowedIPs: []*net.IPNet{
  1278. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  1279. },
  1280. },
  1281. },
  1282. },
  1283. },
  1284. {
  1285. name: "simple dupe reversed",
  1286. peers: []*Peer{p2, p1},
  1287. out: []*Peer{
  1288. p2,
  1289. {
  1290. Name: "1",
  1291. Peer: wireguard.Peer{
  1292. PublicKey: []byte("key1"),
  1293. AllowedIPs: []*net.IPNet{
  1294. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  1295. },
  1296. },
  1297. },
  1298. },
  1299. },
  1300. {
  1301. name: "one duplicates all",
  1302. peers: []*Peer{p3, p2, p1, p4},
  1303. out: []*Peer{
  1304. p3,
  1305. {
  1306. Name: "2",
  1307. Peer: wireguard.Peer{
  1308. PublicKey: []byte("key2"),
  1309. },
  1310. },
  1311. {
  1312. Name: "1",
  1313. Peer: wireguard.Peer{
  1314. PublicKey: []byte("key1"),
  1315. },
  1316. },
  1317. {
  1318. Name: "4",
  1319. Peer: wireguard.Peer{
  1320. PublicKey: []byte("key4"),
  1321. },
  1322. },
  1323. },
  1324. },
  1325. {
  1326. name: "one duplicates itself",
  1327. peers: []*Peer{p4, p1},
  1328. out: []*Peer{
  1329. {
  1330. Name: "4",
  1331. Peer: wireguard.Peer{
  1332. PublicKey: []byte("key4"),
  1333. AllowedIPs: []*net.IPNet{
  1334. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  1335. },
  1336. },
  1337. },
  1338. {
  1339. Name: "1",
  1340. Peer: wireguard.Peer{
  1341. PublicKey: []byte("key1"),
  1342. AllowedIPs: []*net.IPNet{
  1343. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  1344. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  1345. },
  1346. },
  1347. },
  1348. },
  1349. },
  1350. } {
  1351. out := deduplicatePeerIPs(tc.peers)
  1352. if diff := pretty.Compare(out, tc.out); diff != "" {
  1353. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  1354. }
  1355. }
  1356. }