fou_core.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/module.h>
  3. #include <linux/errno.h>
  4. #include <linux/socket.h>
  5. #include <linux/skbuff.h>
  6. #include <linux/ip.h>
  7. #include <linux/icmp.h>
  8. #include <linux/udp.h>
  9. #include <linux/types.h>
  10. #include <linux/kernel.h>
  11. #include <net/genetlink.h>
  12. #include <net/gro.h>
  13. #include <net/gue.h>
  14. #include <net/fou.h>
  15. #include <net/ip.h>
  16. #include <net/protocol.h>
  17. #include <net/udp.h>
  18. #include <net/udp_tunnel.h>
  19. #include <uapi/linux/fou.h>
  20. #include <uapi/linux/genetlink.h>
  21. #include "fou_nl.h"
  22. struct fou {
  23. struct socket *sock;
  24. u8 protocol;
  25. u8 flags;
  26. __be16 port;
  27. u8 family;
  28. u16 type;
  29. struct list_head list;
  30. struct rcu_head rcu;
  31. };
  32. #define FOU_F_REMCSUM_NOPARTIAL BIT(0)
  33. struct fou_cfg {
  34. u16 type;
  35. u8 protocol;
  36. u8 flags;
  37. struct udp_port_cfg udp_config;
  38. };
  39. static unsigned int fou_net_id;
  40. struct fou_net {
  41. struct list_head fou_list;
  42. struct mutex fou_lock;
  43. };
  44. static inline struct fou *fou_from_sock(struct sock *sk)
  45. {
  46. return rcu_dereference_sk_user_data(sk);
  47. }
  48. static int fou_recv_pull(struct sk_buff *skb, struct fou *fou, size_t len)
  49. {
  50. /* Remove 'len' bytes from the packet (UDP header and
  51. * FOU header if present).
  52. */
  53. if (fou->family == AF_INET)
  54. ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len);
  55. else
  56. ipv6_hdr(skb)->payload_len =
  57. htons(ntohs(ipv6_hdr(skb)->payload_len) - len);
  58. __skb_pull(skb, len);
  59. skb_postpull_rcsum(skb, udp_hdr(skb), len);
  60. skb_reset_transport_header(skb);
  61. return iptunnel_pull_offloads(skb);
  62. }
  63. static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
  64. {
  65. struct fou *fou = fou_from_sock(sk);
  66. if (!fou)
  67. return 1;
  68. if (fou_recv_pull(skb, fou, sizeof(struct udphdr)))
  69. goto drop;
  70. return -fou->protocol;
  71. drop:
  72. kfree_skb(skb);
  73. return 0;
  74. }
  75. static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
  76. void *data, size_t hdrlen, u8 ipproto,
  77. bool nopartial)
  78. {
  79. __be16 *pd = data;
  80. size_t start = ntohs(pd[0]);
  81. size_t offset = ntohs(pd[1]);
  82. size_t plen = sizeof(struct udphdr) + hdrlen +
  83. max_t(size_t, offset + sizeof(u16), start);
  84. if (skb->remcsum_offload)
  85. return guehdr;
  86. if (!pskb_may_pull(skb, plen))
  87. return NULL;
  88. guehdr = (struct guehdr *)&udp_hdr(skb)[1];
  89. skb_remcsum_process(skb, (void *)guehdr + hdrlen,
  90. start, offset, nopartial);
  91. return guehdr;
  92. }
  93. static int gue_control_message(struct sk_buff *skb, struct guehdr *guehdr)
  94. {
  95. /* No support yet */
  96. kfree_skb(skb);
  97. return 0;
  98. }
  99. static int gue_udp_recv(struct sock *sk, struct sk_buff *skb)
  100. {
  101. struct fou *fou = fou_from_sock(sk);
  102. size_t len, optlen, hdrlen;
  103. struct guehdr *guehdr;
  104. void *data;
  105. u16 doffset = 0;
  106. u8 proto_ctype;
  107. if (!fou)
  108. return 1;
  109. len = sizeof(struct udphdr) + sizeof(struct guehdr);
  110. if (!pskb_may_pull(skb, len))
  111. goto drop;
  112. guehdr = (struct guehdr *)&udp_hdr(skb)[1];
  113. switch (guehdr->version) {
  114. case 0: /* Full GUE header present */
  115. break;
  116. case 1: {
  117. /* Direct encapsulation of IPv4 or IPv6 */
  118. int prot;
  119. switch (((struct iphdr *)guehdr)->version) {
  120. case 4:
  121. prot = IPPROTO_IPIP;
  122. break;
  123. case 6:
  124. prot = IPPROTO_IPV6;
  125. break;
  126. default:
  127. goto drop;
  128. }
  129. if (fou_recv_pull(skb, fou, sizeof(struct udphdr)))
  130. goto drop;
  131. return -prot;
  132. }
  133. default: /* Undefined version */
  134. goto drop;
  135. }
  136. optlen = guehdr->hlen << 2;
  137. len += optlen;
  138. if (!pskb_may_pull(skb, len))
  139. goto drop;
  140. /* guehdr may change after pull */
  141. guehdr = (struct guehdr *)&udp_hdr(skb)[1];
  142. if (validate_gue_flags(guehdr, optlen))
  143. goto drop;
  144. hdrlen = sizeof(struct guehdr) + optlen;
  145. if (fou->family == AF_INET)
  146. ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len);
  147. else
  148. ipv6_hdr(skb)->payload_len =
  149. htons(ntohs(ipv6_hdr(skb)->payload_len) - len);
  150. /* Pull csum through the guehdr now . This can be used if
  151. * there is a remote checksum offload.
  152. */
  153. skb_postpull_rcsum(skb, udp_hdr(skb), len);
  154. data = &guehdr[1];
  155. if (guehdr->flags & GUE_FLAG_PRIV) {
  156. __be32 flags = *(__be32 *)(data + doffset);
  157. doffset += GUE_LEN_PRIV;
  158. if (flags & GUE_PFLAG_REMCSUM) {
  159. guehdr = gue_remcsum(skb, guehdr, data + doffset,
  160. hdrlen, guehdr->proto_ctype,
  161. !!(fou->flags &
  162. FOU_F_REMCSUM_NOPARTIAL));
  163. if (!guehdr)
  164. goto drop;
  165. data = &guehdr[1];
  166. doffset += GUE_PLEN_REMCSUM;
  167. }
  168. }
  169. if (unlikely(guehdr->control))
  170. return gue_control_message(skb, guehdr);
  171. proto_ctype = guehdr->proto_ctype;
  172. if (unlikely(!proto_ctype))
  173. goto drop;
  174. __skb_pull(skb, sizeof(struct udphdr) + hdrlen);
  175. skb_reset_transport_header(skb);
  176. if (iptunnel_pull_offloads(skb))
  177. goto drop;
  178. return -proto_ctype;
  179. drop:
  180. kfree_skb(skb);
  181. return 0;
  182. }
  183. static const struct net_offload *fou_gro_ops(const struct sock *sk,
  184. int proto)
  185. {
  186. const struct net_offload __rcu **offloads;
  187. /* FOU doesn't allow IPv4 on IPv6 sockets. */
  188. offloads = sk->sk_family == AF_INET6 ? inet6_offloads : inet_offloads;
  189. return rcu_dereference(offloads[proto]);
  190. }
  191. static struct sk_buff *fou_gro_receive(struct sock *sk,
  192. struct list_head *head,
  193. struct sk_buff *skb)
  194. {
  195. struct fou *fou = fou_from_sock(sk);
  196. const struct net_offload *ops;
  197. struct sk_buff *pp = NULL;
  198. if (!fou)
  199. goto out;
  200. /* We can clear the encap_mark for FOU as we are essentially doing
  201. * one of two possible things. We are either adding an L4 tunnel
  202. * header to the outer L3 tunnel header, or we are simply
  203. * treating the GRE tunnel header as though it is a UDP protocol
  204. * specific header such as VXLAN or GENEVE.
  205. */
  206. NAPI_GRO_CB(skb)->encap_mark = 0;
  207. /* Flag this frame as already having an outer encap header */
  208. NAPI_GRO_CB(skb)->is_fou = 1;
  209. ops = fou_gro_ops(sk, fou->protocol);
  210. if (!ops || !ops->callbacks.gro_receive)
  211. goto out;
  212. pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
  213. out:
  214. return pp;
  215. }
  216. static int fou_gro_complete(struct sock *sk, struct sk_buff *skb,
  217. int nhoff)
  218. {
  219. struct fou *fou = fou_from_sock(sk);
  220. const struct net_offload *ops;
  221. int err;
  222. if (!fou) {
  223. err = -ENOENT;
  224. goto out;
  225. }
  226. ops = fou_gro_ops(sk, fou->protocol);
  227. if (WARN_ON(!ops || !ops->callbacks.gro_complete)) {
  228. err = -ENOSYS;
  229. goto out;
  230. }
  231. err = ops->callbacks.gro_complete(skb, nhoff);
  232. skb_set_inner_mac_header(skb, nhoff);
  233. out:
  234. return err;
  235. }
  236. static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
  237. struct guehdr *guehdr, void *data,
  238. size_t hdrlen, struct gro_remcsum *grc,
  239. bool nopartial)
  240. {
  241. __be16 *pd = data;
  242. size_t start = ntohs(pd[0]);
  243. size_t offset = ntohs(pd[1]);
  244. if (skb->remcsum_offload)
  245. return guehdr;
  246. if (!NAPI_GRO_CB(skb)->csum_valid)
  247. return NULL;
  248. guehdr = skb_gro_remcsum_process(skb, (void *)guehdr, off, hdrlen,
  249. start, offset, grc, nopartial);
  250. skb->remcsum_offload = 1;
  251. return guehdr;
  252. }
  253. static struct sk_buff *gue_gro_receive(struct sock *sk,
  254. struct list_head *head,
  255. struct sk_buff *skb)
  256. {
  257. const struct net_offload *ops;
  258. struct sk_buff *pp = NULL;
  259. struct sk_buff *p;
  260. struct guehdr *guehdr;
  261. size_t len, optlen, hdrlen, off;
  262. void *data;
  263. u16 doffset = 0;
  264. int flush = 1;
  265. struct fou *fou = fou_from_sock(sk);
  266. struct gro_remcsum grc;
  267. u8 proto;
  268. skb_gro_remcsum_init(&grc);
  269. if (!fou)
  270. goto out;
  271. off = skb_gro_offset(skb);
  272. len = off + sizeof(*guehdr);
  273. guehdr = skb_gro_header(skb, len, off);
  274. if (unlikely(!guehdr))
  275. goto out;
  276. switch (guehdr->version) {
  277. case 0:
  278. break;
  279. case 1:
  280. switch (((struct iphdr *)guehdr)->version) {
  281. case 4:
  282. proto = IPPROTO_IPIP;
  283. break;
  284. case 6:
  285. proto = IPPROTO_IPV6;
  286. break;
  287. default:
  288. goto out;
  289. }
  290. goto next_proto;
  291. default:
  292. goto out;
  293. }
  294. optlen = guehdr->hlen << 2;
  295. len += optlen;
  296. if (!skb_gro_may_pull(skb, len)) {
  297. guehdr = skb_gro_header_slow(skb, len, off);
  298. if (unlikely(!guehdr))
  299. goto out;
  300. }
  301. if (unlikely(guehdr->control) || guehdr->version != 0 ||
  302. validate_gue_flags(guehdr, optlen))
  303. goto out;
  304. hdrlen = sizeof(*guehdr) + optlen;
  305. /* Adjust NAPI_GRO_CB(skb)->csum to account for guehdr,
  306. * this is needed if there is a remote checkcsum offload.
  307. */
  308. skb_gro_postpull_rcsum(skb, guehdr, hdrlen);
  309. data = &guehdr[1];
  310. if (guehdr->flags & GUE_FLAG_PRIV) {
  311. __be32 flags = *(__be32 *)(data + doffset);
  312. doffset += GUE_LEN_PRIV;
  313. if (flags & GUE_PFLAG_REMCSUM) {
  314. guehdr = gue_gro_remcsum(skb, off, guehdr,
  315. data + doffset, hdrlen, &grc,
  316. !!(fou->flags &
  317. FOU_F_REMCSUM_NOPARTIAL));
  318. if (!guehdr)
  319. goto out;
  320. data = &guehdr[1];
  321. doffset += GUE_PLEN_REMCSUM;
  322. }
  323. }
  324. skb_gro_pull(skb, hdrlen);
  325. list_for_each_entry(p, head, list) {
  326. const struct guehdr *guehdr2;
  327. if (!NAPI_GRO_CB(p)->same_flow)
  328. continue;
  329. guehdr2 = (struct guehdr *)(p->data + off);
  330. /* Compare base GUE header to be equal (covers
  331. * hlen, version, proto_ctype, and flags.
  332. */
  333. if (guehdr->word != guehdr2->word) {
  334. NAPI_GRO_CB(p)->same_flow = 0;
  335. continue;
  336. }
  337. /* Compare optional fields are the same. */
  338. if (guehdr->hlen && memcmp(&guehdr[1], &guehdr2[1],
  339. guehdr->hlen << 2)) {
  340. NAPI_GRO_CB(p)->same_flow = 0;
  341. continue;
  342. }
  343. }
  344. proto = guehdr->proto_ctype;
  345. next_proto:
  346. /* We can clear the encap_mark for GUE as we are essentially doing
  347. * one of two possible things. We are either adding an L4 tunnel
  348. * header to the outer L3 tunnel header, or we are simply
  349. * treating the GRE tunnel header as though it is a UDP protocol
  350. * specific header such as VXLAN or GENEVE.
  351. */
  352. NAPI_GRO_CB(skb)->encap_mark = 0;
  353. /* Flag this frame as already having an outer encap header */
  354. NAPI_GRO_CB(skb)->is_fou = 1;
  355. ops = fou_gro_ops(sk, proto);
  356. if (!ops || !ops->callbacks.gro_receive)
  357. goto out;
  358. pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
  359. flush = 0;
  360. out:
  361. skb_gro_flush_final_remcsum(skb, pp, flush, &grc);
  362. return pp;
  363. }
  364. static int gue_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
  365. {
  366. struct guehdr *guehdr = (struct guehdr *)(skb->data + nhoff);
  367. const struct net_offload *ops;
  368. unsigned int guehlen = 0;
  369. u8 proto;
  370. int err = -ENOENT;
  371. switch (guehdr->version) {
  372. case 0:
  373. proto = guehdr->proto_ctype;
  374. guehlen = sizeof(*guehdr) + (guehdr->hlen << 2);
  375. break;
  376. case 1:
  377. switch (((struct iphdr *)guehdr)->version) {
  378. case 4:
  379. proto = IPPROTO_IPIP;
  380. break;
  381. case 6:
  382. proto = IPPROTO_IPV6;
  383. break;
  384. default:
  385. return err;
  386. }
  387. break;
  388. default:
  389. return err;
  390. }
  391. ops = fou_gro_ops(sk, proto);
  392. if (WARN_ON(!ops || !ops->callbacks.gro_complete))
  393. goto out;
  394. err = ops->callbacks.gro_complete(skb, nhoff + guehlen);
  395. skb_set_inner_mac_header(skb, nhoff + guehlen);
  396. out:
  397. return err;
  398. }
  399. static bool fou_cfg_cmp(struct fou *fou, struct fou_cfg *cfg)
  400. {
  401. struct sock *sk = fou->sock->sk;
  402. struct udp_port_cfg *udp_cfg = &cfg->udp_config;
  403. if (fou->family != udp_cfg->family ||
  404. fou->port != udp_cfg->local_udp_port ||
  405. sk->sk_dport != udp_cfg->peer_udp_port ||
  406. sk->sk_bound_dev_if != udp_cfg->bind_ifindex)
  407. return false;
  408. if (fou->family == AF_INET) {
  409. if (sk->sk_rcv_saddr != udp_cfg->local_ip.s_addr ||
  410. sk->sk_daddr != udp_cfg->peer_ip.s_addr)
  411. return false;
  412. else
  413. return true;
  414. #if IS_ENABLED(CONFIG_IPV6)
  415. } else {
  416. if (ipv6_addr_cmp(&sk->sk_v6_rcv_saddr, &udp_cfg->local_ip6) ||
  417. ipv6_addr_cmp(&sk->sk_v6_daddr, &udp_cfg->peer_ip6))
  418. return false;
  419. else
  420. return true;
  421. #endif
  422. }
  423. return false;
  424. }
  425. static int fou_add_to_port_list(struct net *net, struct fou *fou,
  426. struct fou_cfg *cfg)
  427. {
  428. struct fou_net *fn = net_generic(net, fou_net_id);
  429. struct fou *fout;
  430. mutex_lock(&fn->fou_lock);
  431. list_for_each_entry(fout, &fn->fou_list, list) {
  432. if (fou_cfg_cmp(fout, cfg)) {
  433. mutex_unlock(&fn->fou_lock);
  434. return -EALREADY;
  435. }
  436. }
  437. list_add(&fou->list, &fn->fou_list);
  438. mutex_unlock(&fn->fou_lock);
  439. return 0;
  440. }
  441. static void fou_release(struct fou *fou)
  442. {
  443. struct socket *sock = fou->sock;
  444. list_del(&fou->list);
  445. udp_tunnel_sock_release(sock);
  446. kfree_rcu(fou, rcu);
  447. }
  448. static int fou_create(struct net *net, struct fou_cfg *cfg,
  449. struct socket **sockp)
  450. {
  451. struct socket *sock = NULL;
  452. struct fou *fou = NULL;
  453. struct sock *sk;
  454. struct udp_tunnel_sock_cfg tunnel_cfg;
  455. int err;
  456. /* Open UDP socket */
  457. err = udp_sock_create(net, &cfg->udp_config, &sock);
  458. if (err < 0)
  459. goto error;
  460. /* Allocate FOU port structure */
  461. fou = kzalloc_obj(*fou);
  462. if (!fou) {
  463. err = -ENOMEM;
  464. goto error;
  465. }
  466. sk = sock->sk;
  467. fou->port = cfg->udp_config.local_udp_port;
  468. fou->family = cfg->udp_config.family;
  469. fou->flags = cfg->flags;
  470. fou->type = cfg->type;
  471. fou->sock = sock;
  472. memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
  473. tunnel_cfg.encap_type = 1;
  474. tunnel_cfg.sk_user_data = fou;
  475. tunnel_cfg.encap_destroy = NULL;
  476. /* Initial for fou type */
  477. switch (cfg->type) {
  478. case FOU_ENCAP_DIRECT:
  479. tunnel_cfg.encap_rcv = fou_udp_recv;
  480. tunnel_cfg.gro_receive = fou_gro_receive;
  481. tunnel_cfg.gro_complete = fou_gro_complete;
  482. fou->protocol = cfg->protocol;
  483. break;
  484. case FOU_ENCAP_GUE:
  485. tunnel_cfg.encap_rcv = gue_udp_recv;
  486. tunnel_cfg.gro_receive = gue_gro_receive;
  487. tunnel_cfg.gro_complete = gue_gro_complete;
  488. break;
  489. default:
  490. err = -EINVAL;
  491. goto error;
  492. }
  493. setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
  494. sk->sk_allocation = GFP_ATOMIC;
  495. err = fou_add_to_port_list(net, fou, cfg);
  496. if (err)
  497. goto error;
  498. if (sockp)
  499. *sockp = sock;
  500. return 0;
  501. error:
  502. kfree(fou);
  503. if (sock)
  504. udp_tunnel_sock_release(sock);
  505. return err;
  506. }
  507. static int fou_destroy(struct net *net, struct fou_cfg *cfg)
  508. {
  509. struct fou_net *fn = net_generic(net, fou_net_id);
  510. int err = -EINVAL;
  511. struct fou *fou;
  512. mutex_lock(&fn->fou_lock);
  513. list_for_each_entry(fou, &fn->fou_list, list) {
  514. if (fou_cfg_cmp(fou, cfg)) {
  515. fou_release(fou);
  516. err = 0;
  517. break;
  518. }
  519. }
  520. mutex_unlock(&fn->fou_lock);
  521. return err;
  522. }
  523. static struct genl_family fou_nl_family;
  524. static int parse_nl_config(struct genl_info *info,
  525. struct fou_cfg *cfg)
  526. {
  527. bool has_local = false, has_peer = false;
  528. struct nlattr *attr;
  529. int ifindex;
  530. __be16 port;
  531. memset(cfg, 0, sizeof(*cfg));
  532. cfg->udp_config.family = AF_INET;
  533. if (info->attrs[FOU_ATTR_AF]) {
  534. u8 family = nla_get_u8(info->attrs[FOU_ATTR_AF]);
  535. switch (family) {
  536. case AF_INET:
  537. break;
  538. case AF_INET6:
  539. cfg->udp_config.ipv6_v6only = 1;
  540. break;
  541. default:
  542. return -EAFNOSUPPORT;
  543. }
  544. cfg->udp_config.family = family;
  545. }
  546. if (info->attrs[FOU_ATTR_PORT]) {
  547. port = nla_get_be16(info->attrs[FOU_ATTR_PORT]);
  548. cfg->udp_config.local_udp_port = port;
  549. }
  550. if (info->attrs[FOU_ATTR_IPPROTO])
  551. cfg->protocol = nla_get_u8(info->attrs[FOU_ATTR_IPPROTO]);
  552. if (info->attrs[FOU_ATTR_TYPE])
  553. cfg->type = nla_get_u8(info->attrs[FOU_ATTR_TYPE]);
  554. if (info->attrs[FOU_ATTR_REMCSUM_NOPARTIAL])
  555. cfg->flags |= FOU_F_REMCSUM_NOPARTIAL;
  556. if (cfg->udp_config.family == AF_INET) {
  557. if (info->attrs[FOU_ATTR_LOCAL_V4]) {
  558. attr = info->attrs[FOU_ATTR_LOCAL_V4];
  559. cfg->udp_config.local_ip.s_addr = nla_get_in_addr(attr);
  560. has_local = true;
  561. }
  562. if (info->attrs[FOU_ATTR_PEER_V4]) {
  563. attr = info->attrs[FOU_ATTR_PEER_V4];
  564. cfg->udp_config.peer_ip.s_addr = nla_get_in_addr(attr);
  565. has_peer = true;
  566. }
  567. #if IS_ENABLED(CONFIG_IPV6)
  568. } else {
  569. if (info->attrs[FOU_ATTR_LOCAL_V6]) {
  570. attr = info->attrs[FOU_ATTR_LOCAL_V6];
  571. cfg->udp_config.local_ip6 = nla_get_in6_addr(attr);
  572. has_local = true;
  573. }
  574. if (info->attrs[FOU_ATTR_PEER_V6]) {
  575. attr = info->attrs[FOU_ATTR_PEER_V6];
  576. cfg->udp_config.peer_ip6 = nla_get_in6_addr(attr);
  577. has_peer = true;
  578. }
  579. #endif
  580. }
  581. if (has_peer) {
  582. if (info->attrs[FOU_ATTR_PEER_PORT]) {
  583. port = nla_get_be16(info->attrs[FOU_ATTR_PEER_PORT]);
  584. cfg->udp_config.peer_udp_port = port;
  585. } else {
  586. return -EINVAL;
  587. }
  588. }
  589. if (info->attrs[FOU_ATTR_IFINDEX]) {
  590. if (!has_local)
  591. return -EINVAL;
  592. ifindex = nla_get_s32(info->attrs[FOU_ATTR_IFINDEX]);
  593. cfg->udp_config.bind_ifindex = ifindex;
  594. }
  595. return 0;
  596. }
  597. int fou_nl_add_doit(struct sk_buff *skb, struct genl_info *info)
  598. {
  599. struct net *net = genl_info_net(info);
  600. struct fou_cfg cfg;
  601. int err;
  602. err = parse_nl_config(info, &cfg);
  603. if (err)
  604. return err;
  605. return fou_create(net, &cfg, NULL);
  606. }
  607. int fou_nl_del_doit(struct sk_buff *skb, struct genl_info *info)
  608. {
  609. struct net *net = genl_info_net(info);
  610. struct fou_cfg cfg;
  611. int err;
  612. err = parse_nl_config(info, &cfg);
  613. if (err)
  614. return err;
  615. return fou_destroy(net, &cfg);
  616. }
  617. static int fou_fill_info(struct fou *fou, struct sk_buff *msg)
  618. {
  619. struct sock *sk = fou->sock->sk;
  620. if (nla_put_u8(msg, FOU_ATTR_AF, fou->sock->sk->sk_family) ||
  621. nla_put_be16(msg, FOU_ATTR_PORT, fou->port) ||
  622. nla_put_be16(msg, FOU_ATTR_PEER_PORT, sk->sk_dport) ||
  623. nla_put_u8(msg, FOU_ATTR_IPPROTO, fou->protocol) ||
  624. nla_put_u8(msg, FOU_ATTR_TYPE, fou->type) ||
  625. nla_put_s32(msg, FOU_ATTR_IFINDEX, sk->sk_bound_dev_if))
  626. return -1;
  627. if (fou->flags & FOU_F_REMCSUM_NOPARTIAL)
  628. if (nla_put_flag(msg, FOU_ATTR_REMCSUM_NOPARTIAL))
  629. return -1;
  630. if (fou->sock->sk->sk_family == AF_INET) {
  631. if (nla_put_in_addr(msg, FOU_ATTR_LOCAL_V4, sk->sk_rcv_saddr))
  632. return -1;
  633. if (nla_put_in_addr(msg, FOU_ATTR_PEER_V4, sk->sk_daddr))
  634. return -1;
  635. #if IS_ENABLED(CONFIG_IPV6)
  636. } else {
  637. if (nla_put_in6_addr(msg, FOU_ATTR_LOCAL_V6,
  638. &sk->sk_v6_rcv_saddr))
  639. return -1;
  640. if (nla_put_in6_addr(msg, FOU_ATTR_PEER_V6, &sk->sk_v6_daddr))
  641. return -1;
  642. #endif
  643. }
  644. return 0;
  645. }
  646. static int fou_dump_info(struct fou *fou, u32 portid, u32 seq,
  647. u32 flags, struct sk_buff *skb, u8 cmd)
  648. {
  649. void *hdr;
  650. hdr = genlmsg_put(skb, portid, seq, &fou_nl_family, flags, cmd);
  651. if (!hdr)
  652. return -ENOMEM;
  653. if (fou_fill_info(fou, skb) < 0)
  654. goto nla_put_failure;
  655. genlmsg_end(skb, hdr);
  656. return 0;
  657. nla_put_failure:
  658. genlmsg_cancel(skb, hdr);
  659. return -EMSGSIZE;
  660. }
  661. int fou_nl_get_doit(struct sk_buff *skb, struct genl_info *info)
  662. {
  663. struct net *net = genl_info_net(info);
  664. struct fou_net *fn = net_generic(net, fou_net_id);
  665. struct sk_buff *msg;
  666. struct fou_cfg cfg;
  667. struct fou *fout;
  668. __be16 port;
  669. u8 family;
  670. int ret;
  671. ret = parse_nl_config(info, &cfg);
  672. if (ret)
  673. return ret;
  674. port = cfg.udp_config.local_udp_port;
  675. if (port == 0)
  676. return -EINVAL;
  677. family = cfg.udp_config.family;
  678. if (family != AF_INET && family != AF_INET6)
  679. return -EINVAL;
  680. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  681. if (!msg)
  682. return -ENOMEM;
  683. ret = -ESRCH;
  684. mutex_lock(&fn->fou_lock);
  685. list_for_each_entry(fout, &fn->fou_list, list) {
  686. if (fou_cfg_cmp(fout, &cfg)) {
  687. ret = fou_dump_info(fout, info->snd_portid,
  688. info->snd_seq, 0, msg,
  689. info->genlhdr->cmd);
  690. break;
  691. }
  692. }
  693. mutex_unlock(&fn->fou_lock);
  694. if (ret < 0)
  695. goto out_free;
  696. return genlmsg_reply(msg, info);
  697. out_free:
  698. nlmsg_free(msg);
  699. return ret;
  700. }
  701. int fou_nl_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
  702. {
  703. struct net *net = sock_net(skb->sk);
  704. struct fou_net *fn = net_generic(net, fou_net_id);
  705. struct fou *fout;
  706. int idx = 0, ret;
  707. mutex_lock(&fn->fou_lock);
  708. list_for_each_entry(fout, &fn->fou_list, list) {
  709. if (idx++ < cb->args[0])
  710. continue;
  711. ret = fou_dump_info(fout, NETLINK_CB(cb->skb).portid,
  712. cb->nlh->nlmsg_seq, NLM_F_MULTI,
  713. skb, FOU_CMD_GET);
  714. if (ret)
  715. break;
  716. }
  717. mutex_unlock(&fn->fou_lock);
  718. cb->args[0] = idx;
  719. return skb->len;
  720. }
  721. static struct genl_family fou_nl_family __ro_after_init = {
  722. .hdrsize = 0,
  723. .name = FOU_GENL_NAME,
  724. .version = FOU_GENL_VERSION,
  725. .maxattr = FOU_ATTR_MAX,
  726. .policy = fou_nl_policy,
  727. .netnsok = true,
  728. .module = THIS_MODULE,
  729. .small_ops = fou_nl_ops,
  730. .n_small_ops = ARRAY_SIZE(fou_nl_ops),
  731. .resv_start_op = FOU_CMD_GET + 1,
  732. };
  733. size_t fou_encap_hlen(struct ip_tunnel_encap *e)
  734. {
  735. return sizeof(struct udphdr);
  736. }
  737. EXPORT_SYMBOL(fou_encap_hlen);
  738. size_t gue_encap_hlen(struct ip_tunnel_encap *e)
  739. {
  740. size_t len;
  741. bool need_priv = false;
  742. len = sizeof(struct udphdr) + sizeof(struct guehdr);
  743. if (e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) {
  744. len += GUE_PLEN_REMCSUM;
  745. need_priv = true;
  746. }
  747. len += need_priv ? GUE_LEN_PRIV : 0;
  748. return len;
  749. }
  750. EXPORT_SYMBOL(gue_encap_hlen);
  751. int __fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
  752. u8 *protocol, __be16 *sport, int type)
  753. {
  754. int err;
  755. err = iptunnel_handle_offloads(skb, type);
  756. if (err)
  757. return err;
  758. *sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
  759. skb, 0, 0, false);
  760. return 0;
  761. }
  762. EXPORT_SYMBOL(__fou_build_header);
  763. int __gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
  764. u8 *protocol, __be16 *sport, int type)
  765. {
  766. struct guehdr *guehdr;
  767. size_t hdrlen, optlen = 0;
  768. void *data;
  769. bool need_priv = false;
  770. int err;
  771. if ((e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) &&
  772. skb->ip_summed == CHECKSUM_PARTIAL) {
  773. optlen += GUE_PLEN_REMCSUM;
  774. type |= SKB_GSO_TUNNEL_REMCSUM;
  775. need_priv = true;
  776. }
  777. optlen += need_priv ? GUE_LEN_PRIV : 0;
  778. err = iptunnel_handle_offloads(skb, type);
  779. if (err)
  780. return err;
  781. /* Get source port (based on flow hash) before skb_push */
  782. *sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
  783. skb, 0, 0, false);
  784. hdrlen = sizeof(struct guehdr) + optlen;
  785. skb_push(skb, hdrlen);
  786. guehdr = (struct guehdr *)skb->data;
  787. guehdr->control = 0;
  788. guehdr->version = 0;
  789. guehdr->hlen = optlen >> 2;
  790. guehdr->flags = 0;
  791. guehdr->proto_ctype = *protocol;
  792. data = &guehdr[1];
  793. if (need_priv) {
  794. __be32 *flags = data;
  795. guehdr->flags |= GUE_FLAG_PRIV;
  796. *flags = 0;
  797. data += GUE_LEN_PRIV;
  798. if (type & SKB_GSO_TUNNEL_REMCSUM) {
  799. u16 csum_start = skb_checksum_start_offset(skb);
  800. __be16 *pd = data;
  801. if (csum_start < hdrlen)
  802. return -EINVAL;
  803. csum_start -= hdrlen;
  804. pd[0] = htons(csum_start);
  805. pd[1] = htons(csum_start + skb->csum_offset);
  806. if (!skb_is_gso(skb)) {
  807. skb->ip_summed = CHECKSUM_NONE;
  808. skb->encapsulation = 0;
  809. }
  810. *flags |= GUE_PFLAG_REMCSUM;
  811. data += GUE_PLEN_REMCSUM;
  812. }
  813. }
  814. return 0;
  815. }
  816. EXPORT_SYMBOL(__gue_build_header);
  817. #ifdef CONFIG_NET_FOU_IP_TUNNELS
  818. static void fou_build_udp(struct sk_buff *skb, struct ip_tunnel_encap *e,
  819. struct flowi4 *fl4, u8 *protocol, __be16 sport)
  820. {
  821. struct udphdr *uh;
  822. skb_push(skb, sizeof(struct udphdr));
  823. skb_reset_transport_header(skb);
  824. uh = udp_hdr(skb);
  825. uh->dest = e->dport;
  826. uh->source = sport;
  827. uh->len = htons(skb->len);
  828. udp_set_csum(!(e->flags & TUNNEL_ENCAP_FLAG_CSUM), skb,
  829. fl4->saddr, fl4->daddr, skb->len);
  830. *protocol = IPPROTO_UDP;
  831. }
  832. static int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
  833. u8 *protocol, struct flowi4 *fl4)
  834. {
  835. int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM ? SKB_GSO_UDP_TUNNEL_CSUM :
  836. SKB_GSO_UDP_TUNNEL;
  837. __be16 sport;
  838. int err;
  839. err = __fou_build_header(skb, e, protocol, &sport, type);
  840. if (err)
  841. return err;
  842. fou_build_udp(skb, e, fl4, protocol, sport);
  843. return 0;
  844. }
  845. static int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
  846. u8 *protocol, struct flowi4 *fl4)
  847. {
  848. int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM ? SKB_GSO_UDP_TUNNEL_CSUM :
  849. SKB_GSO_UDP_TUNNEL;
  850. __be16 sport;
  851. int err;
  852. err = __gue_build_header(skb, e, protocol, &sport, type);
  853. if (err)
  854. return err;
  855. fou_build_udp(skb, e, fl4, protocol, sport);
  856. return 0;
  857. }
  858. static int gue_err_proto_handler(int proto, struct sk_buff *skb, u32 info)
  859. {
  860. const struct net_protocol *ipprot = rcu_dereference(inet_protos[proto]);
  861. if (ipprot && ipprot->err_handler) {
  862. if (!ipprot->err_handler(skb, info))
  863. return 0;
  864. }
  865. return -ENOENT;
  866. }
  867. static int gue_err(struct sk_buff *skb, u32 info)
  868. {
  869. int transport_offset = skb_transport_offset(skb);
  870. struct guehdr *guehdr;
  871. size_t len, optlen;
  872. int ret;
  873. len = sizeof(struct udphdr) + sizeof(struct guehdr);
  874. if (!pskb_may_pull(skb, transport_offset + len))
  875. return -EINVAL;
  876. guehdr = (struct guehdr *)&udp_hdr(skb)[1];
  877. switch (guehdr->version) {
  878. case 0: /* Full GUE header present */
  879. break;
  880. case 1: {
  881. /* Direct encapsulation of IPv4 or IPv6 */
  882. skb_set_transport_header(skb, -(int)sizeof(struct icmphdr));
  883. switch (((struct iphdr *)guehdr)->version) {
  884. case 4:
  885. ret = gue_err_proto_handler(IPPROTO_IPIP, skb, info);
  886. goto out;
  887. #if IS_ENABLED(CONFIG_IPV6)
  888. case 6:
  889. ret = gue_err_proto_handler(IPPROTO_IPV6, skb, info);
  890. goto out;
  891. #endif
  892. default:
  893. ret = -EOPNOTSUPP;
  894. goto out;
  895. }
  896. }
  897. default: /* Undefined version */
  898. return -EOPNOTSUPP;
  899. }
  900. if (guehdr->control)
  901. return -ENOENT;
  902. optlen = guehdr->hlen << 2;
  903. if (!pskb_may_pull(skb, transport_offset + len + optlen))
  904. return -EINVAL;
  905. guehdr = (struct guehdr *)&udp_hdr(skb)[1];
  906. if (validate_gue_flags(guehdr, optlen))
  907. return -EINVAL;
  908. /* Handling exceptions for direct UDP encapsulation in GUE would lead to
  909. * recursion. Besides, this kind of encapsulation can't even be
  910. * configured currently. Discard this.
  911. */
  912. if (guehdr->proto_ctype == IPPROTO_UDP ||
  913. guehdr->proto_ctype == IPPROTO_UDPLITE)
  914. return -EOPNOTSUPP;
  915. skb_set_transport_header(skb, -(int)sizeof(struct icmphdr));
  916. ret = gue_err_proto_handler(guehdr->proto_ctype, skb, info);
  917. out:
  918. skb_set_transport_header(skb, transport_offset);
  919. return ret;
  920. }
  921. static const struct ip_tunnel_encap_ops fou_iptun_ops = {
  922. .encap_hlen = fou_encap_hlen,
  923. .build_header = fou_build_header,
  924. .err_handler = gue_err,
  925. };
  926. static const struct ip_tunnel_encap_ops gue_iptun_ops = {
  927. .encap_hlen = gue_encap_hlen,
  928. .build_header = gue_build_header,
  929. .err_handler = gue_err,
  930. };
  931. static int ip_tunnel_encap_add_fou_ops(void)
  932. {
  933. int ret;
  934. ret = ip_tunnel_encap_add_ops(&fou_iptun_ops, TUNNEL_ENCAP_FOU);
  935. if (ret < 0) {
  936. pr_err("can't add fou ops\n");
  937. return ret;
  938. }
  939. ret = ip_tunnel_encap_add_ops(&gue_iptun_ops, TUNNEL_ENCAP_GUE);
  940. if (ret < 0) {
  941. pr_err("can't add gue ops\n");
  942. ip_tunnel_encap_del_ops(&fou_iptun_ops, TUNNEL_ENCAP_FOU);
  943. return ret;
  944. }
  945. return 0;
  946. }
  947. static void ip_tunnel_encap_del_fou_ops(void)
  948. {
  949. ip_tunnel_encap_del_ops(&fou_iptun_ops, TUNNEL_ENCAP_FOU);
  950. ip_tunnel_encap_del_ops(&gue_iptun_ops, TUNNEL_ENCAP_GUE);
  951. }
  952. #else
  953. static int ip_tunnel_encap_add_fou_ops(void)
  954. {
  955. return 0;
  956. }
  957. static void ip_tunnel_encap_del_fou_ops(void)
  958. {
  959. }
  960. #endif
  961. static __net_init int fou_init_net(struct net *net)
  962. {
  963. struct fou_net *fn = net_generic(net, fou_net_id);
  964. INIT_LIST_HEAD(&fn->fou_list);
  965. mutex_init(&fn->fou_lock);
  966. return 0;
  967. }
  968. static __net_exit void fou_exit_net(struct net *net)
  969. {
  970. struct fou_net *fn = net_generic(net, fou_net_id);
  971. struct fou *fou, *next;
  972. /* Close all the FOU sockets */
  973. mutex_lock(&fn->fou_lock);
  974. list_for_each_entry_safe(fou, next, &fn->fou_list, list)
  975. fou_release(fou);
  976. mutex_unlock(&fn->fou_lock);
  977. }
  978. static struct pernet_operations fou_net_ops = {
  979. .init = fou_init_net,
  980. .exit = fou_exit_net,
  981. .id = &fou_net_id,
  982. .size = sizeof(struct fou_net),
  983. };
  984. static int __init fou_init(void)
  985. {
  986. int ret;
  987. ret = register_pernet_device(&fou_net_ops);
  988. if (ret)
  989. goto exit;
  990. ret = genl_register_family(&fou_nl_family);
  991. if (ret < 0)
  992. goto unregister;
  993. ret = register_fou_bpf();
  994. if (ret < 0)
  995. goto kfunc_failed;
  996. ret = ip_tunnel_encap_add_fou_ops();
  997. if (ret == 0)
  998. return 0;
  999. kfunc_failed:
  1000. genl_unregister_family(&fou_nl_family);
  1001. unregister:
  1002. unregister_pernet_device(&fou_net_ops);
  1003. exit:
  1004. return ret;
  1005. }
  1006. static void __exit fou_fini(void)
  1007. {
  1008. ip_tunnel_encap_del_fou_ops();
  1009. genl_unregister_family(&fou_nl_family);
  1010. unregister_pernet_device(&fou_net_ops);
  1011. }
  1012. module_init(fou_init);
  1013. module_exit(fou_fini);
  1014. MODULE_AUTHOR("Tom Herbert <therbert@google.com>");
  1015. MODULE_LICENSE("GPL");
  1016. MODULE_DESCRIPTION("Foo over UDP");