routes_test.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  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. "testing"
  17. "github.com/kylelemons/godebug/pretty"
  18. "github.com/vishvananda/netlink"
  19. "golang.org/x/sys/unix"
  20. "github.com/squat/kilo/pkg/encapsulation"
  21. )
  22. func TestRoutes(t *testing.T) {
  23. nodes, peers, key, port := setup(t)
  24. kiloIface := 0
  25. privIface := 1
  26. tunlIface := 2
  27. mustTopoForGranularityAndHost := func(granularity Granularity, hostname string) *Topology {
  28. return mustTopo(t, nodes, peers, granularity, hostname, port, key, DefaultKiloSubnet, 0)
  29. }
  30. for _, tc := range []struct {
  31. name string
  32. local bool
  33. topology *Topology
  34. strategy encapsulation.Strategy
  35. routes []*netlink.Route
  36. rules []*netlink.Rule
  37. }{
  38. {
  39. name: "logical from a",
  40. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name),
  41. strategy: encapsulation.Never,
  42. routes: []*netlink.Route{
  43. {
  44. Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].cidrs[0],
  45. Flags: int(netlink.FLAG_ONLINK),
  46. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  47. LinkIndex: kiloIface,
  48. Protocol: unix.RTPROT_STATIC,
  49. },
  50. {
  51. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  52. Flags: int(netlink.FLAG_ONLINK),
  53. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  54. LinkIndex: kiloIface,
  55. Protocol: unix.RTPROT_STATIC,
  56. },
  57. {
  58. Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].cidrs[1],
  59. Flags: int(netlink.FLAG_ONLINK),
  60. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  61. LinkIndex: kiloIface,
  62. Protocol: unix.RTPROT_STATIC,
  63. },
  64. {
  65. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  66. Flags: int(netlink.FLAG_ONLINK),
  67. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  68. LinkIndex: kiloIface,
  69. Protocol: unix.RTPROT_STATIC,
  70. },
  71. {
  72. Dst: peers["a"].AllowedIPs[0],
  73. LinkIndex: kiloIface,
  74. Protocol: unix.RTPROT_STATIC,
  75. },
  76. {
  77. Dst: peers["a"].AllowedIPs[1],
  78. LinkIndex: kiloIface,
  79. Protocol: unix.RTPROT_STATIC,
  80. },
  81. {
  82. Dst: peers["b"].AllowedIPs[0],
  83. LinkIndex: kiloIface,
  84. Protocol: unix.RTPROT_STATIC,
  85. },
  86. },
  87. },
  88. {
  89. name: "logical from b",
  90. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name),
  91. strategy: encapsulation.Never,
  92. routes: []*netlink.Route{
  93. {
  94. Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].cidrs[0],
  95. Flags: int(netlink.FLAG_ONLINK),
  96. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  97. LinkIndex: kiloIface,
  98. Protocol: unix.RTPROT_STATIC,
  99. },
  100. {
  101. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  102. Flags: int(netlink.FLAG_ONLINK),
  103. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  104. LinkIndex: kiloIface,
  105. Protocol: unix.RTPROT_STATIC,
  106. },
  107. {
  108. Dst: peers["a"].AllowedIPs[0],
  109. LinkIndex: kiloIface,
  110. Protocol: unix.RTPROT_STATIC,
  111. },
  112. {
  113. Dst: peers["a"].AllowedIPs[1],
  114. LinkIndex: kiloIface,
  115. Protocol: unix.RTPROT_STATIC,
  116. },
  117. {
  118. Dst: peers["b"].AllowedIPs[0],
  119. LinkIndex: kiloIface,
  120. Protocol: unix.RTPROT_STATIC,
  121. },
  122. },
  123. },
  124. {
  125. name: "logical from c",
  126. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name),
  127. strategy: encapsulation.Never,
  128. routes: []*netlink.Route{
  129. {
  130. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].wireGuardIP),
  131. Flags: int(netlink.FLAG_ONLINK),
  132. Gw: nodes["b"].InternalIP.IP,
  133. LinkIndex: privIface,
  134. Protocol: unix.RTPROT_STATIC,
  135. },
  136. {
  137. Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].cidrs[0],
  138. Flags: int(netlink.FLAG_ONLINK),
  139. Gw: nodes["b"].InternalIP.IP,
  140. LinkIndex: privIface,
  141. Protocol: unix.RTPROT_STATIC,
  142. },
  143. {
  144. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  145. Flags: int(netlink.FLAG_ONLINK),
  146. Gw: nodes["b"].InternalIP.IP,
  147. LinkIndex: privIface,
  148. Protocol: unix.RTPROT_STATIC,
  149. },
  150. {
  151. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[1].wireGuardIP),
  152. Flags: int(netlink.FLAG_ONLINK),
  153. Gw: nodes["b"].InternalIP.IP,
  154. LinkIndex: privIface,
  155. Protocol: unix.RTPROT_STATIC,
  156. },
  157. {
  158. Dst: peers["a"].AllowedIPs[0],
  159. Flags: int(netlink.FLAG_ONLINK),
  160. Gw: nodes["b"].InternalIP.IP,
  161. LinkIndex: privIface,
  162. Protocol: unix.RTPROT_STATIC,
  163. },
  164. {
  165. Dst: peers["a"].AllowedIPs[1],
  166. Flags: int(netlink.FLAG_ONLINK),
  167. Gw: nodes["b"].InternalIP.IP,
  168. LinkIndex: privIface,
  169. Protocol: unix.RTPROT_STATIC,
  170. },
  171. {
  172. Dst: peers["b"].AllowedIPs[0],
  173. Flags: int(netlink.FLAG_ONLINK),
  174. Gw: nodes["b"].InternalIP.IP,
  175. LinkIndex: privIface,
  176. Protocol: unix.RTPROT_STATIC,
  177. },
  178. },
  179. },
  180. {
  181. name: "full from a",
  182. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name),
  183. strategy: encapsulation.Never,
  184. routes: []*netlink.Route{
  185. {
  186. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].cidrs[0],
  187. Flags: int(netlink.FLAG_ONLINK),
  188. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  189. LinkIndex: kiloIface,
  190. Protocol: unix.RTPROT_STATIC,
  191. },
  192. {
  193. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  194. Flags: int(netlink.FLAG_ONLINK),
  195. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  196. LinkIndex: kiloIface,
  197. Protocol: unix.RTPROT_STATIC,
  198. },
  199. {
  200. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].cidrs[0],
  201. Flags: int(netlink.FLAG_ONLINK),
  202. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
  203. LinkIndex: kiloIface,
  204. Protocol: unix.RTPROT_STATIC,
  205. },
  206. {
  207. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  208. Flags: int(netlink.FLAG_ONLINK),
  209. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
  210. LinkIndex: kiloIface,
  211. Protocol: unix.RTPROT_STATIC,
  212. },
  213. {
  214. Dst: peers["a"].AllowedIPs[0],
  215. LinkIndex: kiloIface,
  216. Protocol: unix.RTPROT_STATIC,
  217. },
  218. {
  219. Dst: peers["a"].AllowedIPs[1],
  220. LinkIndex: kiloIface,
  221. Protocol: unix.RTPROT_STATIC,
  222. },
  223. {
  224. Dst: peers["b"].AllowedIPs[0],
  225. LinkIndex: kiloIface,
  226. Protocol: unix.RTPROT_STATIC,
  227. },
  228. },
  229. },
  230. {
  231. name: "full from b",
  232. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name),
  233. strategy: encapsulation.Never,
  234. routes: []*netlink.Route{
  235. {
  236. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].cidrs[0],
  237. Flags: int(netlink.FLAG_ONLINK),
  238. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  239. LinkIndex: kiloIface,
  240. Protocol: unix.RTPROT_STATIC,
  241. },
  242. {
  243. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  244. Flags: int(netlink.FLAG_ONLINK),
  245. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  246. LinkIndex: kiloIface,
  247. Protocol: unix.RTPROT_STATIC,
  248. },
  249. {
  250. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].cidrs[0],
  251. Flags: int(netlink.FLAG_ONLINK),
  252. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
  253. LinkIndex: kiloIface,
  254. Protocol: unix.RTPROT_STATIC,
  255. },
  256. {
  257. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  258. Flags: int(netlink.FLAG_ONLINK),
  259. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
  260. LinkIndex: kiloIface,
  261. Protocol: unix.RTPROT_STATIC,
  262. },
  263. {
  264. Dst: peers["a"].AllowedIPs[0],
  265. LinkIndex: kiloIface,
  266. Protocol: unix.RTPROT_STATIC,
  267. },
  268. {
  269. Dst: peers["a"].AllowedIPs[1],
  270. LinkIndex: kiloIface,
  271. Protocol: unix.RTPROT_STATIC,
  272. },
  273. {
  274. Dst: peers["b"].AllowedIPs[0],
  275. LinkIndex: kiloIface,
  276. Protocol: unix.RTPROT_STATIC,
  277. },
  278. },
  279. },
  280. {
  281. name: "full from c",
  282. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name),
  283. strategy: encapsulation.Never,
  284. routes: []*netlink.Route{
  285. {
  286. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].cidrs[0],
  287. Flags: int(netlink.FLAG_ONLINK),
  288. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
  289. LinkIndex: kiloIface,
  290. Protocol: unix.RTPROT_STATIC,
  291. },
  292. {
  293. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  294. Flags: int(netlink.FLAG_ONLINK),
  295. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
  296. LinkIndex: kiloIface,
  297. Protocol: unix.RTPROT_STATIC,
  298. },
  299. {
  300. Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].cidrs[0],
  301. Flags: int(netlink.FLAG_ONLINK),
  302. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
  303. LinkIndex: kiloIface,
  304. Protocol: unix.RTPROT_STATIC,
  305. },
  306. {
  307. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  308. Flags: int(netlink.FLAG_ONLINK),
  309. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
  310. LinkIndex: kiloIface,
  311. Protocol: unix.RTPROT_STATIC,
  312. },
  313. {
  314. Dst: peers["a"].AllowedIPs[0],
  315. LinkIndex: kiloIface,
  316. Protocol: unix.RTPROT_STATIC,
  317. },
  318. {
  319. Dst: peers["a"].AllowedIPs[1],
  320. LinkIndex: kiloIface,
  321. Protocol: unix.RTPROT_STATIC,
  322. },
  323. {
  324. Dst: peers["b"].AllowedIPs[0],
  325. LinkIndex: kiloIface,
  326. Protocol: unix.RTPROT_STATIC,
  327. },
  328. },
  329. },
  330. {
  331. name: "logical from a local",
  332. local: true,
  333. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name),
  334. strategy: encapsulation.Never,
  335. routes: []*netlink.Route{
  336. {
  337. Dst: nodes["b"].Subnet,
  338. Flags: int(netlink.FLAG_ONLINK),
  339. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  340. LinkIndex: kiloIface,
  341. Protocol: unix.RTPROT_STATIC,
  342. },
  343. {
  344. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  345. Flags: int(netlink.FLAG_ONLINK),
  346. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  347. LinkIndex: kiloIface,
  348. Protocol: unix.RTPROT_STATIC,
  349. },
  350. {
  351. Dst: nodes["c"].Subnet,
  352. Flags: int(netlink.FLAG_ONLINK),
  353. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  354. LinkIndex: kiloIface,
  355. Protocol: unix.RTPROT_STATIC,
  356. },
  357. {
  358. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  359. Flags: int(netlink.FLAG_ONLINK),
  360. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  361. LinkIndex: kiloIface,
  362. Protocol: unix.RTPROT_STATIC,
  363. },
  364. {
  365. Dst: peers["a"].AllowedIPs[0],
  366. LinkIndex: kiloIface,
  367. Protocol: unix.RTPROT_STATIC,
  368. },
  369. {
  370. Dst: peers["a"].AllowedIPs[1],
  371. LinkIndex: kiloIface,
  372. Protocol: unix.RTPROT_STATIC,
  373. },
  374. {
  375. Dst: peers["b"].AllowedIPs[0],
  376. LinkIndex: kiloIface,
  377. Protocol: unix.RTPROT_STATIC,
  378. },
  379. },
  380. },
  381. {
  382. name: "logical from a local always",
  383. local: true,
  384. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name),
  385. strategy: encapsulation.Always,
  386. routes: []*netlink.Route{
  387. {
  388. Dst: nodes["b"].Subnet,
  389. Flags: int(netlink.FLAG_ONLINK),
  390. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  391. LinkIndex: kiloIface,
  392. Protocol: unix.RTPROT_STATIC,
  393. },
  394. {
  395. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  396. Flags: int(netlink.FLAG_ONLINK),
  397. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  398. LinkIndex: kiloIface,
  399. Protocol: unix.RTPROT_STATIC,
  400. },
  401. {
  402. Dst: nodes["c"].Subnet,
  403. Flags: int(netlink.FLAG_ONLINK),
  404. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  405. LinkIndex: kiloIface,
  406. Protocol: unix.RTPROT_STATIC,
  407. },
  408. {
  409. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  410. Flags: int(netlink.FLAG_ONLINK),
  411. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  412. LinkIndex: kiloIface,
  413. Protocol: unix.RTPROT_STATIC,
  414. },
  415. {
  416. Dst: peers["a"].AllowedIPs[0],
  417. LinkIndex: kiloIface,
  418. Protocol: unix.RTPROT_STATIC,
  419. },
  420. {
  421. Dst: peers["a"].AllowedIPs[1],
  422. LinkIndex: kiloIface,
  423. Protocol: unix.RTPROT_STATIC,
  424. },
  425. {
  426. Dst: peers["b"].AllowedIPs[0],
  427. LinkIndex: kiloIface,
  428. Protocol: unix.RTPROT_STATIC,
  429. },
  430. },
  431. },
  432. {
  433. name: "logical from b local",
  434. local: true,
  435. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name),
  436. strategy: encapsulation.Never,
  437. routes: []*netlink.Route{
  438. {
  439. Dst: nodes["a"].Subnet,
  440. Flags: int(netlink.FLAG_ONLINK),
  441. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  442. LinkIndex: kiloIface,
  443. Protocol: unix.RTPROT_STATIC,
  444. },
  445. {
  446. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  447. Flags: int(netlink.FLAG_ONLINK),
  448. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  449. LinkIndex: kiloIface,
  450. Protocol: unix.RTPROT_STATIC,
  451. },
  452. {
  453. Dst: nodes["c"].Subnet,
  454. Flags: int(netlink.FLAG_ONLINK),
  455. Gw: nodes["c"].InternalIP.IP,
  456. LinkIndex: privIface,
  457. Protocol: unix.RTPROT_STATIC,
  458. },
  459. {
  460. Dst: peers["a"].AllowedIPs[0],
  461. LinkIndex: kiloIface,
  462. Protocol: unix.RTPROT_STATIC,
  463. },
  464. {
  465. Dst: peers["a"].AllowedIPs[1],
  466. LinkIndex: kiloIface,
  467. Protocol: unix.RTPROT_STATIC,
  468. },
  469. {
  470. Dst: peers["b"].AllowedIPs[0],
  471. LinkIndex: kiloIface,
  472. Protocol: unix.RTPROT_STATIC,
  473. },
  474. },
  475. },
  476. {
  477. name: "logical from b local always",
  478. local: true,
  479. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name),
  480. strategy: encapsulation.Always,
  481. routes: []*netlink.Route{
  482. {
  483. Dst: nodes["a"].Subnet,
  484. Flags: int(netlink.FLAG_ONLINK),
  485. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  486. LinkIndex: kiloIface,
  487. Protocol: unix.RTPROT_STATIC,
  488. },
  489. {
  490. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  491. Flags: int(netlink.FLAG_ONLINK),
  492. Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  493. LinkIndex: kiloIface,
  494. Protocol: unix.RTPROT_STATIC,
  495. },
  496. {
  497. Dst: nodes["c"].Subnet,
  498. Flags: int(netlink.FLAG_ONLINK),
  499. Gw: nodes["c"].InternalIP.IP,
  500. LinkIndex: tunlIface,
  501. Protocol: unix.RTPROT_STATIC,
  502. },
  503. {
  504. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  505. Flags: int(netlink.FLAG_ONLINK),
  506. Gw: nodes["c"].InternalIP.IP,
  507. LinkIndex: tunlIface,
  508. Protocol: unix.RTPROT_STATIC,
  509. Table: kiloTableIndex,
  510. },
  511. {
  512. Dst: peers["a"].AllowedIPs[0],
  513. LinkIndex: kiloIface,
  514. Protocol: unix.RTPROT_STATIC,
  515. },
  516. {
  517. Dst: peers["a"].AllowedIPs[1],
  518. LinkIndex: kiloIface,
  519. Protocol: unix.RTPROT_STATIC,
  520. },
  521. {
  522. Dst: peers["b"].AllowedIPs[0],
  523. LinkIndex: kiloIface,
  524. Protocol: unix.RTPROT_STATIC,
  525. },
  526. },
  527. rules: []*netlink.Rule{
  528. defaultRule(&netlink.Rule{
  529. Src: nodes["b"].Subnet,
  530. Dst: nodes["c"].InternalIP,
  531. Table: kiloTableIndex,
  532. }),
  533. defaultRule(&netlink.Rule{
  534. Dst: nodes["c"].InternalIP,
  535. IifName: DefaultKiloInterface,
  536. Table: kiloTableIndex,
  537. }),
  538. },
  539. },
  540. {
  541. name: "logical from c local",
  542. local: true,
  543. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name),
  544. strategy: encapsulation.Never,
  545. routes: []*netlink.Route{
  546. {
  547. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].wireGuardIP),
  548. Flags: int(netlink.FLAG_ONLINK),
  549. Gw: nodes["b"].InternalIP.IP,
  550. LinkIndex: privIface,
  551. Protocol: unix.RTPROT_STATIC,
  552. },
  553. {
  554. Dst: nodes["a"].Subnet,
  555. Flags: int(netlink.FLAG_ONLINK),
  556. Gw: nodes["b"].InternalIP.IP,
  557. LinkIndex: privIface,
  558. Protocol: unix.RTPROT_STATIC,
  559. },
  560. {
  561. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  562. Flags: int(netlink.FLAG_ONLINK),
  563. Gw: nodes["b"].InternalIP.IP,
  564. LinkIndex: privIface,
  565. Protocol: unix.RTPROT_STATIC,
  566. },
  567. {
  568. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[1].wireGuardIP),
  569. Flags: int(netlink.FLAG_ONLINK),
  570. Gw: nodes["b"].InternalIP.IP,
  571. LinkIndex: privIface,
  572. Protocol: unix.RTPROT_STATIC,
  573. },
  574. {
  575. Dst: nodes["b"].Subnet,
  576. Flags: int(netlink.FLAG_ONLINK),
  577. Gw: nodes["b"].InternalIP.IP,
  578. LinkIndex: privIface,
  579. Protocol: unix.RTPROT_STATIC,
  580. },
  581. {
  582. Dst: peers["a"].AllowedIPs[0],
  583. Flags: int(netlink.FLAG_ONLINK),
  584. Gw: nodes["b"].InternalIP.IP,
  585. LinkIndex: privIface,
  586. Protocol: unix.RTPROT_STATIC,
  587. },
  588. {
  589. Dst: peers["a"].AllowedIPs[1],
  590. Flags: int(netlink.FLAG_ONLINK),
  591. Gw: nodes["b"].InternalIP.IP,
  592. LinkIndex: privIface,
  593. Protocol: unix.RTPROT_STATIC,
  594. },
  595. {
  596. Dst: peers["b"].AllowedIPs[0],
  597. Flags: int(netlink.FLAG_ONLINK),
  598. Gw: nodes["b"].InternalIP.IP,
  599. LinkIndex: privIface,
  600. Protocol: unix.RTPROT_STATIC,
  601. },
  602. },
  603. },
  604. {
  605. name: "logical from c local always",
  606. local: true,
  607. topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name),
  608. strategy: encapsulation.Always,
  609. routes: []*netlink.Route{
  610. {
  611. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].wireGuardIP),
  612. Flags: int(netlink.FLAG_ONLINK),
  613. Gw: nodes["b"].InternalIP.IP,
  614. LinkIndex: tunlIface,
  615. Protocol: unix.RTPROT_STATIC,
  616. },
  617. {
  618. Dst: nodes["a"].Subnet,
  619. Flags: int(netlink.FLAG_ONLINK),
  620. Gw: nodes["b"].InternalIP.IP,
  621. LinkIndex: tunlIface,
  622. Protocol: unix.RTPROT_STATIC,
  623. },
  624. {
  625. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  626. Flags: int(netlink.FLAG_ONLINK),
  627. Gw: nodes["b"].InternalIP.IP,
  628. LinkIndex: tunlIface,
  629. Protocol: unix.RTPROT_STATIC,
  630. },
  631. {
  632. Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[1].wireGuardIP),
  633. Flags: int(netlink.FLAG_ONLINK),
  634. Gw: nodes["b"].InternalIP.IP,
  635. LinkIndex: tunlIface,
  636. Protocol: unix.RTPROT_STATIC,
  637. },
  638. {
  639. Dst: nodes["b"].Subnet,
  640. Flags: int(netlink.FLAG_ONLINK),
  641. Gw: nodes["b"].InternalIP.IP,
  642. LinkIndex: tunlIface,
  643. Protocol: unix.RTPROT_STATIC,
  644. },
  645. {
  646. Dst: nodes["b"].InternalIP,
  647. Flags: int(netlink.FLAG_ONLINK),
  648. Gw: nodes["b"].InternalIP.IP,
  649. LinkIndex: tunlIface,
  650. Protocol: unix.RTPROT_STATIC,
  651. Table: kiloTableIndex,
  652. },
  653. {
  654. Dst: peers["a"].AllowedIPs[0],
  655. Flags: int(netlink.FLAG_ONLINK),
  656. Gw: nodes["b"].InternalIP.IP,
  657. LinkIndex: tunlIface,
  658. Protocol: unix.RTPROT_STATIC,
  659. },
  660. {
  661. Dst: peers["a"].AllowedIPs[1],
  662. Flags: int(netlink.FLAG_ONLINK),
  663. Gw: nodes["b"].InternalIP.IP,
  664. LinkIndex: tunlIface,
  665. Protocol: unix.RTPROT_STATIC,
  666. },
  667. {
  668. Dst: peers["b"].AllowedIPs[0],
  669. Flags: int(netlink.FLAG_ONLINK),
  670. Gw: nodes["b"].InternalIP.IP,
  671. LinkIndex: tunlIface,
  672. Protocol: unix.RTPROT_STATIC,
  673. },
  674. },
  675. rules: []*netlink.Rule{
  676. defaultRule(&netlink.Rule{
  677. Src: nodes["c"].Subnet,
  678. Dst: nodes["b"].InternalIP,
  679. Table: kiloTableIndex,
  680. }),
  681. },
  682. },
  683. {
  684. name: "full from a local",
  685. local: true,
  686. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name),
  687. strategy: encapsulation.Never,
  688. routes: []*netlink.Route{
  689. {
  690. Dst: nodes["b"].Subnet,
  691. Flags: int(netlink.FLAG_ONLINK),
  692. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  693. LinkIndex: kiloIface,
  694. Protocol: unix.RTPROT_STATIC,
  695. },
  696. {
  697. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  698. Flags: int(netlink.FLAG_ONLINK),
  699. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
  700. LinkIndex: kiloIface,
  701. Protocol: unix.RTPROT_STATIC,
  702. },
  703. {
  704. Dst: nodes["c"].Subnet,
  705. Flags: int(netlink.FLAG_ONLINK),
  706. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
  707. LinkIndex: kiloIface,
  708. Protocol: unix.RTPROT_STATIC,
  709. },
  710. {
  711. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  712. Flags: int(netlink.FLAG_ONLINK),
  713. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
  714. LinkIndex: kiloIface,
  715. Protocol: unix.RTPROT_STATIC,
  716. },
  717. {
  718. Dst: peers["a"].AllowedIPs[0],
  719. LinkIndex: kiloIface,
  720. Protocol: unix.RTPROT_STATIC,
  721. },
  722. {
  723. Dst: peers["a"].AllowedIPs[1],
  724. LinkIndex: kiloIface,
  725. Protocol: unix.RTPROT_STATIC,
  726. },
  727. {
  728. Dst: peers["b"].AllowedIPs[0],
  729. LinkIndex: kiloIface,
  730. Protocol: unix.RTPROT_STATIC,
  731. },
  732. },
  733. },
  734. {
  735. name: "full from b local",
  736. local: true,
  737. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name),
  738. strategy: encapsulation.Never,
  739. routes: []*netlink.Route{
  740. {
  741. Dst: nodes["a"].Subnet,
  742. Flags: int(netlink.FLAG_ONLINK),
  743. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  744. LinkIndex: kiloIface,
  745. Protocol: unix.RTPROT_STATIC,
  746. },
  747. {
  748. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  749. Flags: int(netlink.FLAG_ONLINK),
  750. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
  751. LinkIndex: kiloIface,
  752. Protocol: unix.RTPROT_STATIC,
  753. },
  754. {
  755. Dst: nodes["c"].Subnet,
  756. Flags: int(netlink.FLAG_ONLINK),
  757. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
  758. LinkIndex: kiloIface,
  759. Protocol: unix.RTPROT_STATIC,
  760. },
  761. {
  762. Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
  763. Flags: int(netlink.FLAG_ONLINK),
  764. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
  765. LinkIndex: kiloIface,
  766. Protocol: unix.RTPROT_STATIC,
  767. },
  768. {
  769. Dst: peers["a"].AllowedIPs[0],
  770. LinkIndex: kiloIface,
  771. Protocol: unix.RTPROT_STATIC,
  772. },
  773. {
  774. Dst: peers["a"].AllowedIPs[1],
  775. LinkIndex: kiloIface,
  776. Protocol: unix.RTPROT_STATIC,
  777. },
  778. {
  779. Dst: peers["b"].AllowedIPs[0],
  780. LinkIndex: kiloIface,
  781. Protocol: unix.RTPROT_STATIC,
  782. },
  783. },
  784. },
  785. {
  786. name: "full from c local",
  787. local: true,
  788. topology: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name),
  789. strategy: encapsulation.Never,
  790. routes: []*netlink.Route{
  791. {
  792. Dst: nodes["a"].Subnet,
  793. Flags: int(netlink.FLAG_ONLINK),
  794. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
  795. LinkIndex: kiloIface,
  796. Protocol: unix.RTPROT_STATIC,
  797. },
  798. {
  799. Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
  800. Flags: int(netlink.FLAG_ONLINK),
  801. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
  802. LinkIndex: kiloIface,
  803. Protocol: unix.RTPROT_STATIC,
  804. },
  805. {
  806. Dst: nodes["b"].Subnet,
  807. Flags: int(netlink.FLAG_ONLINK),
  808. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
  809. LinkIndex: kiloIface,
  810. Protocol: unix.RTPROT_STATIC,
  811. },
  812. {
  813. Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
  814. Flags: int(netlink.FLAG_ONLINK),
  815. Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
  816. LinkIndex: kiloIface,
  817. Protocol: unix.RTPROT_STATIC,
  818. },
  819. {
  820. Dst: peers["a"].AllowedIPs[0],
  821. LinkIndex: kiloIface,
  822. Protocol: unix.RTPROT_STATIC,
  823. },
  824. {
  825. Dst: peers["a"].AllowedIPs[1],
  826. LinkIndex: kiloIface,
  827. Protocol: unix.RTPROT_STATIC,
  828. },
  829. {
  830. Dst: peers["b"].AllowedIPs[0],
  831. LinkIndex: kiloIface,
  832. Protocol: unix.RTPROT_STATIC,
  833. },
  834. },
  835. },
  836. } {
  837. routes, rules := tc.topology.Routes(DefaultKiloInterface, kiloIface, privIface, tunlIface, tc.local, encapsulation.NewIPIP(tc.strategy))
  838. if diff := pretty.Compare(routes, tc.routes); diff != "" {
  839. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  840. }
  841. if diff := pretty.Compare(rules, tc.rules); diff != "" {
  842. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  843. }
  844. }
  845. }