ila_xlat.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/jhash.h>
  3. #include <linux/netfilter.h>
  4. #include <linux/rcupdate.h>
  5. #include <linux/rhashtable.h>
  6. #include <linux/vmalloc.h>
  7. #include <net/genetlink.h>
  8. #include <net/netns/generic.h>
  9. #include <uapi/linux/genetlink.h>
  10. #include "ila.h"
  11. struct ila_xlat_params {
  12. struct ila_params ip;
  13. int ifindex;
  14. };
  15. struct ila_map {
  16. struct ila_xlat_params xp;
  17. struct rhash_head node;
  18. struct ila_map __rcu *next;
  19. struct rcu_head rcu;
  20. };
  21. #define MAX_LOCKS 1024
  22. #define LOCKS_PER_CPU 10
  23. static int alloc_ila_locks(struct ila_net *ilan)
  24. {
  25. return alloc_bucket_spinlocks(&ilan->xlat.locks, &ilan->xlat.locks_mask,
  26. MAX_LOCKS, LOCKS_PER_CPU,
  27. GFP_KERNEL);
  28. }
  29. static u32 hashrnd __read_mostly;
  30. static __always_inline void __ila_hash_secret_init(void)
  31. {
  32. net_get_random_once(&hashrnd, sizeof(hashrnd));
  33. }
  34. static inline u32 ila_locator_hash(struct ila_locator loc)
  35. {
  36. u32 *v = (u32 *)loc.v32;
  37. __ila_hash_secret_init();
  38. return jhash_2words(v[0], v[1], hashrnd);
  39. }
  40. static inline spinlock_t *ila_get_lock(struct ila_net *ilan,
  41. struct ila_locator loc)
  42. {
  43. return &ilan->xlat.locks[ila_locator_hash(loc) & ilan->xlat.locks_mask];
  44. }
  45. static inline int ila_cmp_wildcards(struct ila_map *ila,
  46. struct ila_addr *iaddr, int ifindex)
  47. {
  48. return (ila->xp.ifindex && ila->xp.ifindex != ifindex);
  49. }
  50. static inline int ila_cmp_params(struct ila_map *ila,
  51. struct ila_xlat_params *xp)
  52. {
  53. return (ila->xp.ifindex != xp->ifindex);
  54. }
  55. static int ila_cmpfn(struct rhashtable_compare_arg *arg,
  56. const void *obj)
  57. {
  58. const struct ila_map *ila = obj;
  59. return (ila->xp.ip.locator_match.v64 != *(__be64 *)arg->key);
  60. }
  61. static inline int ila_order(struct ila_map *ila)
  62. {
  63. int score = 0;
  64. if (ila->xp.ifindex)
  65. score += 1 << 1;
  66. return score;
  67. }
  68. static const struct rhashtable_params rht_params = {
  69. .nelem_hint = 1024,
  70. .head_offset = offsetof(struct ila_map, node),
  71. .key_offset = offsetof(struct ila_map, xp.ip.locator_match),
  72. .key_len = sizeof(u64), /* identifier */
  73. .max_size = 1048576,
  74. .min_size = 256,
  75. .automatic_shrinking = true,
  76. .obj_cmpfn = ila_cmpfn,
  77. };
  78. static int parse_nl_config(struct genl_info *info,
  79. struct ila_xlat_params *xp)
  80. {
  81. memset(xp, 0, sizeof(*xp));
  82. if (info->attrs[ILA_ATTR_LOCATOR])
  83. xp->ip.locator.v64 = (__force __be64)nla_get_u64(
  84. info->attrs[ILA_ATTR_LOCATOR]);
  85. if (info->attrs[ILA_ATTR_LOCATOR_MATCH])
  86. xp->ip.locator_match.v64 = (__force __be64)nla_get_u64(
  87. info->attrs[ILA_ATTR_LOCATOR_MATCH]);
  88. if (info->attrs[ILA_ATTR_CSUM_MODE])
  89. xp->ip.csum_mode = nla_get_u8(info->attrs[ILA_ATTR_CSUM_MODE]);
  90. else
  91. xp->ip.csum_mode = ILA_CSUM_NO_ACTION;
  92. if (info->attrs[ILA_ATTR_IDENT_TYPE])
  93. xp->ip.ident_type = nla_get_u8(
  94. info->attrs[ILA_ATTR_IDENT_TYPE]);
  95. else
  96. xp->ip.ident_type = ILA_ATYPE_USE_FORMAT;
  97. if (info->attrs[ILA_ATTR_IFINDEX])
  98. xp->ifindex = nla_get_s32(info->attrs[ILA_ATTR_IFINDEX]);
  99. return 0;
  100. }
  101. /* Must be called with rcu readlock */
  102. static inline struct ila_map *ila_lookup_wildcards(struct ila_addr *iaddr,
  103. int ifindex,
  104. struct ila_net *ilan)
  105. {
  106. struct ila_map *ila;
  107. ila = rhashtable_lookup_fast(&ilan->xlat.rhash_table, &iaddr->loc,
  108. rht_params);
  109. while (ila) {
  110. if (!ila_cmp_wildcards(ila, iaddr, ifindex))
  111. return ila;
  112. ila = rcu_access_pointer(ila->next);
  113. }
  114. return NULL;
  115. }
  116. /* Must be called with rcu readlock */
  117. static inline struct ila_map *ila_lookup_by_params(struct ila_xlat_params *xp,
  118. struct ila_net *ilan)
  119. {
  120. struct ila_map *ila;
  121. ila = rhashtable_lookup_fast(&ilan->xlat.rhash_table,
  122. &xp->ip.locator_match,
  123. rht_params);
  124. while (ila) {
  125. if (!ila_cmp_params(ila, xp))
  126. return ila;
  127. ila = rcu_access_pointer(ila->next);
  128. }
  129. return NULL;
  130. }
  131. static inline void ila_release(struct ila_map *ila)
  132. {
  133. kfree_rcu(ila, rcu);
  134. }
  135. static void ila_free_node(struct ila_map *ila)
  136. {
  137. struct ila_map *next;
  138. /* Assume rcu_readlock held */
  139. while (ila) {
  140. next = rcu_access_pointer(ila->next);
  141. ila_release(ila);
  142. ila = next;
  143. }
  144. }
  145. static void ila_free_cb(void *ptr, void *arg)
  146. {
  147. ila_free_node((struct ila_map *)ptr);
  148. }
  149. static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila);
  150. static unsigned int
  151. ila_nf_input(void *priv,
  152. struct sk_buff *skb,
  153. const struct nf_hook_state *state)
  154. {
  155. ila_xlat_addr(skb, false);
  156. return NF_ACCEPT;
  157. }
  158. static const struct nf_hook_ops ila_nf_hook_ops[] = {
  159. {
  160. .hook = ila_nf_input,
  161. .pf = NFPROTO_IPV6,
  162. .hooknum = NF_INET_PRE_ROUTING,
  163. .priority = -1,
  164. },
  165. };
  166. static DEFINE_MUTEX(ila_mutex);
  167. static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp)
  168. {
  169. struct ila_net *ilan = net_generic(net, ila_net_id);
  170. struct ila_map *ila, *head;
  171. spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match);
  172. int err = 0, order;
  173. if (!READ_ONCE(ilan->xlat.hooks_registered)) {
  174. /* We defer registering net hooks in the namespace until the
  175. * first mapping is added.
  176. */
  177. mutex_lock(&ila_mutex);
  178. if (!ilan->xlat.hooks_registered) {
  179. err = nf_register_net_hooks(net, ila_nf_hook_ops,
  180. ARRAY_SIZE(ila_nf_hook_ops));
  181. if (!err)
  182. WRITE_ONCE(ilan->xlat.hooks_registered, true);
  183. }
  184. mutex_unlock(&ila_mutex);
  185. if (err)
  186. return err;
  187. }
  188. ila = kzalloc(sizeof(*ila), GFP_KERNEL);
  189. if (!ila)
  190. return -ENOMEM;
  191. ila_init_saved_csum(&xp->ip);
  192. ila->xp = *xp;
  193. order = ila_order(ila);
  194. spin_lock(lock);
  195. head = rhashtable_lookup_fast(&ilan->xlat.rhash_table,
  196. &xp->ip.locator_match,
  197. rht_params);
  198. if (!head) {
  199. /* New entry for the rhash_table */
  200. err = rhashtable_lookup_insert_fast(&ilan->xlat.rhash_table,
  201. &ila->node, rht_params);
  202. } else {
  203. struct ila_map *tila = head, *prev = NULL;
  204. do {
  205. if (!ila_cmp_params(tila, xp)) {
  206. err = -EEXIST;
  207. goto out;
  208. }
  209. if (order > ila_order(tila))
  210. break;
  211. prev = tila;
  212. tila = rcu_dereference_protected(tila->next,
  213. lockdep_is_held(lock));
  214. } while (tila);
  215. if (prev) {
  216. /* Insert in sub list of head */
  217. RCU_INIT_POINTER(ila->next, tila);
  218. rcu_assign_pointer(prev->next, ila);
  219. } else {
  220. /* Make this ila new head */
  221. RCU_INIT_POINTER(ila->next, head);
  222. err = rhashtable_replace_fast(&ilan->xlat.rhash_table,
  223. &head->node,
  224. &ila->node, rht_params);
  225. if (err)
  226. goto out;
  227. }
  228. }
  229. out:
  230. spin_unlock(lock);
  231. if (err)
  232. kfree(ila);
  233. return err;
  234. }
  235. static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp)
  236. {
  237. struct ila_net *ilan = net_generic(net, ila_net_id);
  238. struct ila_map *ila, *head, *prev;
  239. spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match);
  240. int err = -ENOENT;
  241. spin_lock(lock);
  242. head = rhashtable_lookup_fast(&ilan->xlat.rhash_table,
  243. &xp->ip.locator_match, rht_params);
  244. ila = head;
  245. prev = NULL;
  246. while (ila) {
  247. if (ila_cmp_params(ila, xp)) {
  248. prev = ila;
  249. ila = rcu_dereference_protected(ila->next,
  250. lockdep_is_held(lock));
  251. continue;
  252. }
  253. err = 0;
  254. if (prev) {
  255. /* Not head, just delete from list */
  256. rcu_assign_pointer(prev->next, ila->next);
  257. } else {
  258. /* It is the head. If there is something in the
  259. * sublist we need to make a new head.
  260. */
  261. head = rcu_dereference_protected(ila->next,
  262. lockdep_is_held(lock));
  263. if (head) {
  264. /* Put first entry in the sublist into the
  265. * table
  266. */
  267. err = rhashtable_replace_fast(
  268. &ilan->xlat.rhash_table, &ila->node,
  269. &head->node, rht_params);
  270. if (err)
  271. goto out;
  272. } else {
  273. /* Entry no longer used */
  274. err = rhashtable_remove_fast(
  275. &ilan->xlat.rhash_table,
  276. &ila->node, rht_params);
  277. }
  278. }
  279. ila_release(ila);
  280. break;
  281. }
  282. out:
  283. spin_unlock(lock);
  284. return err;
  285. }
  286. int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info)
  287. {
  288. struct net *net = genl_info_net(info);
  289. struct ila_xlat_params p;
  290. int err;
  291. err = parse_nl_config(info, &p);
  292. if (err)
  293. return err;
  294. return ila_add_mapping(net, &p);
  295. }
  296. int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info)
  297. {
  298. struct net *net = genl_info_net(info);
  299. struct ila_xlat_params xp;
  300. int err;
  301. err = parse_nl_config(info, &xp);
  302. if (err)
  303. return err;
  304. ila_del_mapping(net, &xp);
  305. return 0;
  306. }
  307. static inline spinlock_t *lock_from_ila_map(struct ila_net *ilan,
  308. struct ila_map *ila)
  309. {
  310. return ila_get_lock(ilan, ila->xp.ip.locator_match);
  311. }
  312. int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info)
  313. {
  314. struct net *net = genl_info_net(info);
  315. struct ila_net *ilan = net_generic(net, ila_net_id);
  316. struct rhashtable_iter iter;
  317. struct ila_map *ila;
  318. spinlock_t *lock;
  319. int ret = 0;
  320. rhashtable_walk_enter(&ilan->xlat.rhash_table, &iter);
  321. rhashtable_walk_start(&iter);
  322. for (;;) {
  323. ila = rhashtable_walk_next(&iter);
  324. if (IS_ERR(ila)) {
  325. if (PTR_ERR(ila) == -EAGAIN)
  326. continue;
  327. ret = PTR_ERR(ila);
  328. goto done;
  329. } else if (!ila) {
  330. break;
  331. }
  332. lock = lock_from_ila_map(ilan, ila);
  333. spin_lock(lock);
  334. ret = rhashtable_remove_fast(&ilan->xlat.rhash_table,
  335. &ila->node, rht_params);
  336. if (!ret)
  337. ila_free_node(ila);
  338. spin_unlock(lock);
  339. if (ret)
  340. break;
  341. }
  342. done:
  343. rhashtable_walk_stop(&iter);
  344. rhashtable_walk_exit(&iter);
  345. return ret;
  346. }
  347. static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg)
  348. {
  349. if (nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR,
  350. (__force u64)ila->xp.ip.locator.v64,
  351. ILA_ATTR_PAD) ||
  352. nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR_MATCH,
  353. (__force u64)ila->xp.ip.locator_match.v64,
  354. ILA_ATTR_PAD) ||
  355. nla_put_s32(msg, ILA_ATTR_IFINDEX, ila->xp.ifindex) ||
  356. nla_put_u8(msg, ILA_ATTR_CSUM_MODE, ila->xp.ip.csum_mode) ||
  357. nla_put_u8(msg, ILA_ATTR_IDENT_TYPE, ila->xp.ip.ident_type))
  358. return -1;
  359. return 0;
  360. }
  361. static int ila_dump_info(struct ila_map *ila,
  362. u32 portid, u32 seq, u32 flags,
  363. struct sk_buff *skb, u8 cmd)
  364. {
  365. void *hdr;
  366. hdr = genlmsg_put(skb, portid, seq, &ila_nl_family, flags, cmd);
  367. if (!hdr)
  368. return -ENOMEM;
  369. if (ila_fill_info(ila, skb) < 0)
  370. goto nla_put_failure;
  371. genlmsg_end(skb, hdr);
  372. return 0;
  373. nla_put_failure:
  374. genlmsg_cancel(skb, hdr);
  375. return -EMSGSIZE;
  376. }
  377. int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
  378. {
  379. struct net *net = genl_info_net(info);
  380. struct ila_net *ilan = net_generic(net, ila_net_id);
  381. struct sk_buff *msg;
  382. struct ila_xlat_params xp;
  383. struct ila_map *ila;
  384. int ret;
  385. ret = parse_nl_config(info, &xp);
  386. if (ret)
  387. return ret;
  388. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  389. if (!msg)
  390. return -ENOMEM;
  391. rcu_read_lock();
  392. ret = -ESRCH;
  393. ila = ila_lookup_by_params(&xp, ilan);
  394. if (ila) {
  395. ret = ila_dump_info(ila,
  396. info->snd_portid,
  397. info->snd_seq, 0, msg,
  398. info->genlhdr->cmd);
  399. }
  400. rcu_read_unlock();
  401. if (ret < 0)
  402. goto out_free;
  403. return genlmsg_reply(msg, info);
  404. out_free:
  405. nlmsg_free(msg);
  406. return ret;
  407. }
  408. struct ila_dump_iter {
  409. struct rhashtable_iter rhiter;
  410. int skip;
  411. };
  412. int ila_xlat_nl_dump_start(struct netlink_callback *cb)
  413. {
  414. struct net *net = sock_net(cb->skb->sk);
  415. struct ila_net *ilan = net_generic(net, ila_net_id);
  416. struct ila_dump_iter *iter;
  417. iter = kmalloc(sizeof(*iter), GFP_KERNEL);
  418. if (!iter)
  419. return -ENOMEM;
  420. rhashtable_walk_enter(&ilan->xlat.rhash_table, &iter->rhiter);
  421. iter->skip = 0;
  422. cb->args[0] = (long)iter;
  423. return 0;
  424. }
  425. int ila_xlat_nl_dump_done(struct netlink_callback *cb)
  426. {
  427. struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0];
  428. rhashtable_walk_exit(&iter->rhiter);
  429. kfree(iter);
  430. return 0;
  431. }
  432. int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
  433. {
  434. struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0];
  435. struct rhashtable_iter *rhiter = &iter->rhiter;
  436. int skip = iter->skip;
  437. struct ila_map *ila;
  438. int ret;
  439. rhashtable_walk_start(rhiter);
  440. /* Get first entry */
  441. ila = rhashtable_walk_peek(rhiter);
  442. if (ila && !IS_ERR(ila) && skip) {
  443. /* Skip over visited entries */
  444. while (ila && skip) {
  445. /* Skip over any ila entries in this list that we
  446. * have already dumped.
  447. */
  448. ila = rcu_access_pointer(ila->next);
  449. skip--;
  450. }
  451. }
  452. skip = 0;
  453. for (;;) {
  454. if (IS_ERR(ila)) {
  455. ret = PTR_ERR(ila);
  456. if (ret == -EAGAIN) {
  457. /* Table has changed and iter has reset. Return
  458. * -EAGAIN to the application even if we have
  459. * written data to the skb. The application
  460. * needs to deal with this.
  461. */
  462. goto out_ret;
  463. } else {
  464. break;
  465. }
  466. } else if (!ila) {
  467. ret = 0;
  468. break;
  469. }
  470. while (ila) {
  471. ret = ila_dump_info(ila, NETLINK_CB(cb->skb).portid,
  472. cb->nlh->nlmsg_seq, NLM_F_MULTI,
  473. skb, ILA_CMD_GET);
  474. if (ret)
  475. goto out;
  476. skip++;
  477. ila = rcu_access_pointer(ila->next);
  478. }
  479. skip = 0;
  480. ila = rhashtable_walk_next(rhiter);
  481. }
  482. out:
  483. iter->skip = skip;
  484. ret = (skb->len ? : ret);
  485. out_ret:
  486. rhashtable_walk_stop(rhiter);
  487. return ret;
  488. }
  489. int ila_xlat_init_net(struct net *net)
  490. {
  491. struct ila_net *ilan = net_generic(net, ila_net_id);
  492. int err;
  493. err = alloc_ila_locks(ilan);
  494. if (err)
  495. return err;
  496. err = rhashtable_init(&ilan->xlat.rhash_table, &rht_params);
  497. if (err) {
  498. free_bucket_spinlocks(ilan->xlat.locks);
  499. return err;
  500. }
  501. return 0;
  502. }
  503. void ila_xlat_pre_exit_net(struct net *net)
  504. {
  505. struct ila_net *ilan = net_generic(net, ila_net_id);
  506. if (ilan->xlat.hooks_registered)
  507. nf_unregister_net_hooks(net, ila_nf_hook_ops,
  508. ARRAY_SIZE(ila_nf_hook_ops));
  509. }
  510. void ila_xlat_exit_net(struct net *net)
  511. {
  512. struct ila_net *ilan = net_generic(net, ila_net_id);
  513. rhashtable_free_and_destroy(&ilan->xlat.rhash_table, ila_free_cb, NULL);
  514. free_bucket_spinlocks(ilan->xlat.locks);
  515. }
  516. static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila)
  517. {
  518. struct ila_map *ila;
  519. struct ipv6hdr *ip6h = ipv6_hdr(skb);
  520. struct net *net = dev_net(skb->dev);
  521. struct ila_net *ilan = net_generic(net, ila_net_id);
  522. struct ila_addr *iaddr = ila_a2i(&ip6h->daddr);
  523. /* Assumes skb contains a valid IPv6 header that is pulled */
  524. /* No check here that ILA type in the mapping matches what is in the
  525. * address. We assume that whatever sender gaves us can be translated.
  526. * The checksum mode however is relevant.
  527. */
  528. rcu_read_lock();
  529. ila = ila_lookup_wildcards(iaddr, skb->dev->ifindex, ilan);
  530. if (ila)
  531. ila_update_ipv6_locator(skb, &ila->xp.ip, sir2ila);
  532. rcu_read_unlock();
  533. return 0;
  534. }