fou.c 21 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. #include <linux/module.h>
  2. #include <linux/errno.h>
  3. #include <linux/socket.h>
  4. #include <linux/skbuff.h>
  5. #include <linux/ip.h>
  6. #include <linux/udp.h>
  7. #include <linux/types.h>
  8. #include <linux/kernel.h>
  9. #include <net/genetlink.h>
  10. #include <net/gue.h>
  11. #include <net/ip.h>
  12. #include <net/protocol.h>
  13. #include <net/udp.h>
  14. #include <net/udp_tunnel.h>
  15. #include <net/xfrm.h>
  16. #include <uapi/linux/fou.h>
  17. #include <uapi/linux/genetlink.h>
  18. struct fou {
  19. struct socket *sock;
  20. u8 protocol;
  21. u8 flags;
  22. __be16 port;
  23. u16 type;
  24. struct list_head list;
  25. struct rcu_head rcu;
  26. };
  27. #define FOU_F_REMCSUM_NOPARTIAL BIT(0)
  28. struct fou_cfg {
  29. u16 type;
  30. u8 protocol;
  31. u8 flags;
  32. struct udp_port_cfg udp_config;
  33. };
  34. static unsigned int fou_net_id;
  35. struct fou_net {
  36. struct list_head fou_list;
  37. struct mutex fou_lock;
  38. };
  39. static inline struct fou *fou_from_sock(struct sock *sk)
  40. {
  41. return sk->sk_user_data;
  42. }
  43. static int fou_recv_pull(struct sk_buff *skb, size_t len)
  44. {
  45. struct iphdr *iph = ip_hdr(skb);
  46. /* Remove 'len' bytes from the packet (UDP header and
  47. * FOU header if present).
  48. */
  49. iph->tot_len = htons(ntohs(iph->tot_len) - len);
  50. __skb_pull(skb, len);
  51. skb_postpull_rcsum(skb, udp_hdr(skb), len);
  52. skb_reset_transport_header(skb);
  53. return iptunnel_pull_offloads(skb);
  54. }
  55. static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
  56. {
  57. struct fou *fou = fou_from_sock(sk);
  58. if (!fou)
  59. return 1;
  60. if (fou_recv_pull(skb, sizeof(struct udphdr)))
  61. goto drop;
  62. return -fou->protocol;
  63. drop:
  64. kfree_skb(skb);
  65. return 0;
  66. }
  67. static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
  68. void *data, size_t hdrlen, u8 ipproto,
  69. bool nopartial)
  70. {
  71. __be16 *pd = data;
  72. size_t start = ntohs(pd[0]);
  73. size_t offset = ntohs(pd[1]);
  74. size_t plen = sizeof(struct udphdr) + hdrlen +
  75. max_t(size_t, offset + sizeof(u16), start);
  76. if (skb->remcsum_offload)
  77. return guehdr;
  78. if (!pskb_may_pull(skb, plen))
  79. return NULL;
  80. guehdr = (struct guehdr *)&udp_hdr(skb)[1];
  81. skb_remcsum_process(skb, (void *)guehdr + hdrlen,
  82. start, offset, nopartial);
  83. return guehdr;
  84. }
  85. static int gue_control_message(struct sk_buff *skb, struct guehdr *guehdr)
  86. {
  87. /* No support yet */
  88. kfree_skb(skb);
  89. return 0;
  90. }
  91. static int gue_udp_recv(struct sock *sk, struct sk_buff *skb)
  92. {
  93. struct fou *fou = fou_from_sock(sk);
  94. size_t len, optlen, hdrlen;
  95. struct guehdr *guehdr;
  96. void *data;
  97. u16 doffset = 0;
  98. if (!fou)
  99. return 1;
  100. len = sizeof(struct udphdr) + sizeof(struct guehdr);
  101. if (!pskb_may_pull(skb, len))
  102. goto drop;
  103. guehdr = (struct guehdr *)&udp_hdr(skb)[1];
  104. optlen = guehdr->hlen << 2;
  105. len += optlen;
  106. if (!pskb_may_pull(skb, len))
  107. goto drop;
  108. /* guehdr may change after pull */
  109. guehdr = (struct guehdr *)&udp_hdr(skb)[1];
  110. hdrlen = sizeof(struct guehdr) + optlen;
  111. if (guehdr->version != 0 || validate_gue_flags(guehdr, optlen))
  112. goto drop;
  113. hdrlen = sizeof(struct guehdr) + optlen;
  114. ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len);
  115. /* Pull csum through the guehdr now . This can be used if
  116. * there is a remote checksum offload.
  117. */
  118. skb_postpull_rcsum(skb, udp_hdr(skb), len);
  119. data = &guehdr[1];
  120. if (guehdr->flags & GUE_FLAG_PRIV) {
  121. __be32 flags = *(__be32 *)(data + doffset);
  122. doffset += GUE_LEN_PRIV;
  123. if (flags & GUE_PFLAG_REMCSUM) {
  124. guehdr = gue_remcsum(skb, guehdr, data + doffset,
  125. hdrlen, guehdr->proto_ctype,
  126. !!(fou->flags &
  127. FOU_F_REMCSUM_NOPARTIAL));
  128. if (!guehdr)
  129. goto drop;
  130. data = &guehdr[1];
  131. doffset += GUE_PLEN_REMCSUM;
  132. }
  133. }
  134. if (unlikely(guehdr->control))
  135. return gue_control_message(skb, guehdr);
  136. __skb_pull(skb, sizeof(struct udphdr) + hdrlen);
  137. skb_reset_transport_header(skb);
  138. if (iptunnel_pull_offloads(skb))
  139. goto drop;
  140. return -guehdr->proto_ctype;
  141. drop:
  142. kfree_skb(skb);
  143. return 0;
  144. }
  145. static struct sk_buff **fou_gro_receive(struct sock *sk,
  146. struct sk_buff **head,
  147. struct sk_buff *skb)
  148. {
  149. const struct net_offload *ops;
  150. struct sk_buff **pp = NULL;
  151. u8 proto = fou_from_sock(sk)->protocol;
  152. const struct net_offload **offloads;
  153. /* We can clear the encap_mark for FOU as we are essentially doing
  154. * one of two possible things. We are either adding an L4 tunnel
  155. * header to the outer L3 tunnel header, or we are are simply
  156. * treating the GRE tunnel header as though it is a UDP protocol
  157. * specific header such as VXLAN or GENEVE.
  158. */
  159. NAPI_GRO_CB(skb)->encap_mark = 0;
  160. /* Flag this frame as already having an outer encap header */
  161. NAPI_GRO_CB(skb)->is_fou = 1;
  162. rcu_read_lock();
  163. offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
  164. ops = rcu_dereference(offloads[proto]);
  165. if (!ops || !ops->callbacks.gro_receive)
  166. goto out_unlock;
  167. pp = ops->callbacks.gro_receive(head, skb);
  168. out_unlock:
  169. rcu_read_unlock();
  170. return pp;
  171. }
  172. static int fou_gro_complete(struct sock *sk, struct sk_buff *skb,
  173. int nhoff)
  174. {
  175. const struct net_offload *ops;
  176. u8 proto = fou_from_sock(sk)->protocol;
  177. int err = -ENOSYS;
  178. const struct net_offload **offloads;
  179. udp_tunnel_gro_complete(skb, nhoff);
  180. rcu_read_lock();
  181. offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
  182. ops = rcu_dereference(offloads[proto]);
  183. if (WARN_ON(!ops || !ops->callbacks.gro_complete))
  184. goto out_unlock;
  185. err = ops->callbacks.gro_complete(skb, nhoff);
  186. out_unlock:
  187. rcu_read_unlock();
  188. return err;
  189. }
  190. static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
  191. struct guehdr *guehdr, void *data,
  192. size_t hdrlen, struct gro_remcsum *grc,
  193. bool nopartial)
  194. {
  195. __be16 *pd = data;
  196. size_t start = ntohs(pd[0]);
  197. size_t offset = ntohs(pd[1]);
  198. if (skb->remcsum_offload)
  199. return guehdr;
  200. if (!NAPI_GRO_CB(skb)->csum_valid)
  201. return NULL;
  202. guehdr = skb_gro_remcsum_process(skb, (void *)guehdr, off, hdrlen,
  203. start, offset, grc, nopartial);
  204. skb->remcsum_offload = 1;
  205. return guehdr;
  206. }
  207. static struct sk_buff **gue_gro_receive(struct sock *sk,
  208. struct sk_buff **head,
  209. struct sk_buff *skb)
  210. {
  211. const struct net_offload **offloads;
  212. const struct net_offload *ops;
  213. struct sk_buff **pp = NULL;
  214. struct sk_buff *p;
  215. struct guehdr *guehdr;
  216. size_t len, optlen, hdrlen, off;
  217. void *data;
  218. u16 doffset = 0;
  219. int flush = 1;
  220. struct fou *fou = fou_from_sock(sk);
  221. struct gro_remcsum grc;
  222. skb_gro_remcsum_init(&grc);
  223. off = skb_gro_offset(skb);
  224. len = off + sizeof(*guehdr);
  225. guehdr = skb_gro_header_fast(skb, off);
  226. if (skb_gro_header_hard(skb, len)) {
  227. guehdr = skb_gro_header_slow(skb, len, off);
  228. if (unlikely(!guehdr))
  229. goto out;
  230. }
  231. optlen = guehdr->hlen << 2;
  232. len += optlen;
  233. if (skb_gro_header_hard(skb, len)) {
  234. guehdr = skb_gro_header_slow(skb, len, off);
  235. if (unlikely(!guehdr))
  236. goto out;
  237. }
  238. if (unlikely(guehdr->control) || guehdr->version != 0 ||
  239. validate_gue_flags(guehdr, optlen))
  240. goto out;
  241. hdrlen = sizeof(*guehdr) + optlen;
  242. /* Adjust NAPI_GRO_CB(skb)->csum to account for guehdr,
  243. * this is needed if there is a remote checkcsum offload.
  244. */
  245. skb_gro_postpull_rcsum(skb, guehdr, hdrlen);
  246. data = &guehdr[1];
  247. if (guehdr->flags & GUE_FLAG_PRIV) {
  248. __be32 flags = *(__be32 *)(data + doffset);
  249. doffset += GUE_LEN_PRIV;
  250. if (flags & GUE_PFLAG_REMCSUM) {
  251. guehdr = gue_gro_remcsum(skb, off, guehdr,
  252. data + doffset, hdrlen, &grc,
  253. !!(fou->flags &
  254. FOU_F_REMCSUM_NOPARTIAL));
  255. if (!guehdr)
  256. goto out;
  257. data = &guehdr[1];
  258. doffset += GUE_PLEN_REMCSUM;
  259. }
  260. }
  261. skb_gro_pull(skb, hdrlen);
  262. for (p = *head; p; p = p->next) {
  263. const struct guehdr *guehdr2;
  264. if (!NAPI_GRO_CB(p)->same_flow)
  265. continue;
  266. guehdr2 = (struct guehdr *)(p->data + off);
  267. /* Compare base GUE header to be equal (covers
  268. * hlen, version, proto_ctype, and flags.
  269. */
  270. if (guehdr->word != guehdr2->word) {
  271. NAPI_GRO_CB(p)->same_flow = 0;
  272. continue;
  273. }
  274. /* Compare optional fields are the same. */
  275. if (guehdr->hlen && memcmp(&guehdr[1], &guehdr2[1],
  276. guehdr->hlen << 2)) {
  277. NAPI_GRO_CB(p)->same_flow = 0;
  278. continue;
  279. }
  280. }
  281. /* We can clear the encap_mark for GUE as we are essentially doing
  282. * one of two possible things. We are either adding an L4 tunnel
  283. * header to the outer L3 tunnel header, or we are are simply
  284. * treating the GRE tunnel header as though it is a UDP protocol
  285. * specific header such as VXLAN or GENEVE.
  286. */
  287. NAPI_GRO_CB(skb)->encap_mark = 0;
  288. /* Flag this frame as already having an outer encap header */
  289. NAPI_GRO_CB(skb)->is_fou = 1;
  290. rcu_read_lock();
  291. offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
  292. ops = rcu_dereference(offloads[guehdr->proto_ctype]);
  293. if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive))
  294. goto out_unlock;
  295. pp = ops->callbacks.gro_receive(head, skb);
  296. flush = 0;
  297. out_unlock:
  298. rcu_read_unlock();
  299. out:
  300. NAPI_GRO_CB(skb)->flush |= flush;
  301. skb_gro_remcsum_cleanup(skb, &grc);
  302. return pp;
  303. }
  304. static int gue_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
  305. {
  306. const struct net_offload **offloads;
  307. struct guehdr *guehdr = (struct guehdr *)(skb->data + nhoff);
  308. const struct net_offload *ops;
  309. unsigned int guehlen;
  310. u8 proto;
  311. int err = -ENOENT;
  312. proto = guehdr->proto_ctype;
  313. guehlen = sizeof(*guehdr) + (guehdr->hlen << 2);
  314. rcu_read_lock();
  315. offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
  316. ops = rcu_dereference(offloads[proto]);
  317. if (WARN_ON(!ops || !ops->callbacks.gro_complete))
  318. goto out_unlock;
  319. err = ops->callbacks.gro_complete(skb, nhoff + guehlen);
  320. out_unlock:
  321. rcu_read_unlock();
  322. return err;
  323. }
  324. static int fou_add_to_port_list(struct net *net, struct fou *fou)
  325. {
  326. struct fou_net *fn = net_generic(net, fou_net_id);
  327. struct fou *fout;
  328. mutex_lock(&fn->fou_lock);
  329. list_for_each_entry(fout, &fn->fou_list, list) {
  330. if (fou->port == fout->port) {
  331. mutex_unlock(&fn->fou_lock);
  332. return -EALREADY;
  333. }
  334. }
  335. list_add(&fou->list, &fn->fou_list);
  336. mutex_unlock(&fn->fou_lock);
  337. return 0;
  338. }
  339. static void fou_release(struct fou *fou)
  340. {
  341. struct socket *sock = fou->sock;
  342. list_del(&fou->list);
  343. udp_tunnel_sock_release(sock);
  344. kfree_rcu(fou, rcu);
  345. }
  346. static int fou_encap_init(struct sock *sk, struct fou *fou, struct fou_cfg *cfg)
  347. {
  348. udp_sk(sk)->encap_rcv = fou_udp_recv;
  349. udp_sk(sk)->gro_receive = fou_gro_receive;
  350. udp_sk(sk)->gro_complete = fou_gro_complete;
  351. fou_from_sock(sk)->protocol = cfg->protocol;
  352. return 0;
  353. }
  354. static int gue_encap_init(struct sock *sk, struct fou *fou, struct fou_cfg *cfg)
  355. {
  356. udp_sk(sk)->encap_rcv = gue_udp_recv;
  357. udp_sk(sk)->gro_receive = gue_gro_receive;
  358. udp_sk(sk)->gro_complete = gue_gro_complete;
  359. return 0;
  360. }
  361. static int fou_create(struct net *net, struct fou_cfg *cfg,
  362. struct socket **sockp)
  363. {
  364. struct socket *sock = NULL;
  365. struct fou *fou = NULL;
  366. struct sock *sk;
  367. int err;
  368. /* Open UDP socket */
  369. err = udp_sock_create(net, &cfg->udp_config, &sock);
  370. if (err < 0)
  371. goto error;
  372. /* Allocate FOU port structure */
  373. fou = kzalloc(sizeof(*fou), GFP_KERNEL);
  374. if (!fou) {
  375. err = -ENOMEM;
  376. goto error;
  377. }
  378. sk = sock->sk;
  379. fou->flags = cfg->flags;
  380. fou->port = cfg->udp_config.local_udp_port;
  381. /* Initial for fou type */
  382. switch (cfg->type) {
  383. case FOU_ENCAP_DIRECT:
  384. err = fou_encap_init(sk, fou, cfg);
  385. if (err)
  386. goto error;
  387. break;
  388. case FOU_ENCAP_GUE:
  389. err = gue_encap_init(sk, fou, cfg);
  390. if (err)
  391. goto error;
  392. break;
  393. default:
  394. err = -EINVAL;
  395. goto error;
  396. }
  397. fou->type = cfg->type;
  398. udp_sk(sk)->encap_type = 1;
  399. udp_encap_enable();
  400. sk->sk_user_data = fou;
  401. fou->sock = sock;
  402. inet_inc_convert_csum(sk);
  403. sk->sk_allocation = GFP_ATOMIC;
  404. err = fou_add_to_port_list(net, fou);
  405. if (err)
  406. goto error;
  407. if (sockp)
  408. *sockp = sock;
  409. return 0;
  410. error:
  411. kfree(fou);
  412. if (sock)
  413. udp_tunnel_sock_release(sock);
  414. return err;
  415. }
  416. static int fou_destroy(struct net *net, struct fou_cfg *cfg)
  417. {
  418. struct fou_net *fn = net_generic(net, fou_net_id);
  419. __be16 port = cfg->udp_config.local_udp_port;
  420. int err = -EINVAL;
  421. struct fou *fou;
  422. mutex_lock(&fn->fou_lock);
  423. list_for_each_entry(fou, &fn->fou_list, list) {
  424. if (fou->port == port) {
  425. fou_release(fou);
  426. err = 0;
  427. break;
  428. }
  429. }
  430. mutex_unlock(&fn->fou_lock);
  431. return err;
  432. }
  433. static struct genl_family fou_nl_family = {
  434. .id = GENL_ID_GENERATE,
  435. .hdrsize = 0,
  436. .name = FOU_GENL_NAME,
  437. .version = FOU_GENL_VERSION,
  438. .maxattr = FOU_ATTR_MAX,
  439. .netnsok = true,
  440. };
  441. static struct nla_policy fou_nl_policy[FOU_ATTR_MAX + 1] = {
  442. [FOU_ATTR_PORT] = { .type = NLA_U16, },
  443. [FOU_ATTR_AF] = { .type = NLA_U8, },
  444. [FOU_ATTR_IPPROTO] = { .type = NLA_U8, },
  445. [FOU_ATTR_TYPE] = { .type = NLA_U8, },
  446. [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG, },
  447. };
  448. static int parse_nl_config(struct genl_info *info,
  449. struct fou_cfg *cfg)
  450. {
  451. memset(cfg, 0, sizeof(*cfg));
  452. cfg->udp_config.family = AF_INET;
  453. if (info->attrs[FOU_ATTR_AF]) {
  454. u8 family = nla_get_u8(info->attrs[FOU_ATTR_AF]);
  455. if (family != AF_INET)
  456. return -EINVAL;
  457. cfg->udp_config.family = family;
  458. }
  459. if (info->attrs[FOU_ATTR_PORT]) {
  460. __be16 port = nla_get_be16(info->attrs[FOU_ATTR_PORT]);
  461. cfg->udp_config.local_udp_port = port;
  462. }
  463. if (info->attrs[FOU_ATTR_IPPROTO])
  464. cfg->protocol = nla_get_u8(info->attrs[FOU_ATTR_IPPROTO]);
  465. if (info->attrs[FOU_ATTR_TYPE])
  466. cfg->type = nla_get_u8(info->attrs[FOU_ATTR_TYPE]);
  467. if (info->attrs[FOU_ATTR_REMCSUM_NOPARTIAL])
  468. cfg->flags |= FOU_F_REMCSUM_NOPARTIAL;
  469. return 0;
  470. }
  471. static int fou_nl_cmd_add_port(struct sk_buff *skb, struct genl_info *info)
  472. {
  473. struct net *net = genl_info_net(info);
  474. struct fou_cfg cfg;
  475. int err;
  476. err = parse_nl_config(info, &cfg);
  477. if (err)
  478. return err;
  479. return fou_create(net, &cfg, NULL);
  480. }
  481. static int fou_nl_cmd_rm_port(struct sk_buff *skb, struct genl_info *info)
  482. {
  483. struct net *net = genl_info_net(info);
  484. struct fou_cfg cfg;
  485. int err;
  486. err = parse_nl_config(info, &cfg);
  487. if (err)
  488. return err;
  489. return fou_destroy(net, &cfg);
  490. }
  491. static int fou_fill_info(struct fou *fou, struct sk_buff *msg)
  492. {
  493. if (nla_put_u8(msg, FOU_ATTR_AF, fou->sock->sk->sk_family) ||
  494. nla_put_be16(msg, FOU_ATTR_PORT, fou->port) ||
  495. nla_put_u8(msg, FOU_ATTR_IPPROTO, fou->protocol) ||
  496. nla_put_u8(msg, FOU_ATTR_TYPE, fou->type))
  497. return -1;
  498. if (fou->flags & FOU_F_REMCSUM_NOPARTIAL)
  499. if (nla_put_flag(msg, FOU_ATTR_REMCSUM_NOPARTIAL))
  500. return -1;
  501. return 0;
  502. }
  503. static int fou_dump_info(struct fou *fou, u32 portid, u32 seq,
  504. u32 flags, struct sk_buff *skb, u8 cmd)
  505. {
  506. void *hdr;
  507. hdr = genlmsg_put(skb, portid, seq, &fou_nl_family, flags, cmd);
  508. if (!hdr)
  509. return -ENOMEM;
  510. if (fou_fill_info(fou, skb) < 0)
  511. goto nla_put_failure;
  512. genlmsg_end(skb, hdr);
  513. return 0;
  514. nla_put_failure:
  515. genlmsg_cancel(skb, hdr);
  516. return -EMSGSIZE;
  517. }
  518. static int fou_nl_cmd_get_port(struct sk_buff *skb, struct genl_info *info)
  519. {
  520. struct net *net = genl_info_net(info);
  521. struct fou_net *fn = net_generic(net, fou_net_id);
  522. struct sk_buff *msg;
  523. struct fou_cfg cfg;
  524. struct fou *fout;
  525. __be16 port;
  526. int ret;
  527. ret = parse_nl_config(info, &cfg);
  528. if (ret)
  529. return ret;
  530. port = cfg.udp_config.local_udp_port;
  531. if (port == 0)
  532. return -EINVAL;
  533. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  534. if (!msg)
  535. return -ENOMEM;
  536. ret = -ESRCH;
  537. mutex_lock(&fn->fou_lock);
  538. list_for_each_entry(fout, &fn->fou_list, list) {
  539. if (port == fout->port) {
  540. ret = fou_dump_info(fout, info->snd_portid,
  541. info->snd_seq, 0, msg,
  542. info->genlhdr->cmd);
  543. break;
  544. }
  545. }
  546. mutex_unlock(&fn->fou_lock);
  547. if (ret < 0)
  548. goto out_free;
  549. return genlmsg_reply(msg, info);
  550. out_free:
  551. nlmsg_free(msg);
  552. return ret;
  553. }
  554. static int fou_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
  555. {
  556. struct net *net = sock_net(skb->sk);
  557. struct fou_net *fn = net_generic(net, fou_net_id);
  558. struct fou *fout;
  559. int idx = 0, ret;
  560. mutex_lock(&fn->fou_lock);
  561. list_for_each_entry(fout, &fn->fou_list, list) {
  562. if (idx++ < cb->args[0])
  563. continue;
  564. ret = fou_dump_info(fout, NETLINK_CB(cb->skb).portid,
  565. cb->nlh->nlmsg_seq, NLM_F_MULTI,
  566. skb, FOU_CMD_GET);
  567. if (ret)
  568. break;
  569. }
  570. mutex_unlock(&fn->fou_lock);
  571. cb->args[0] = idx;
  572. return skb->len;
  573. }
  574. static const struct genl_ops fou_nl_ops[] = {
  575. {
  576. .cmd = FOU_CMD_ADD,
  577. .doit = fou_nl_cmd_add_port,
  578. .policy = fou_nl_policy,
  579. .flags = GENL_ADMIN_PERM,
  580. },
  581. {
  582. .cmd = FOU_CMD_DEL,
  583. .doit = fou_nl_cmd_rm_port,
  584. .policy = fou_nl_policy,
  585. .flags = GENL_ADMIN_PERM,
  586. },
  587. {
  588. .cmd = FOU_CMD_GET,
  589. .doit = fou_nl_cmd_get_port,
  590. .dumpit = fou_nl_dump,
  591. .policy = fou_nl_policy,
  592. },
  593. };
  594. size_t fou_encap_hlen(struct ip_tunnel_encap *e)
  595. {
  596. return sizeof(struct udphdr);
  597. }
  598. EXPORT_SYMBOL(fou_encap_hlen);
  599. size_t gue_encap_hlen(struct ip_tunnel_encap *e)
  600. {
  601. size_t len;
  602. bool need_priv = false;
  603. len = sizeof(struct udphdr) + sizeof(struct guehdr);
  604. if (e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) {
  605. len += GUE_PLEN_REMCSUM;
  606. need_priv = true;
  607. }
  608. len += need_priv ? GUE_LEN_PRIV : 0;
  609. return len;
  610. }
  611. EXPORT_SYMBOL(gue_encap_hlen);
  612. static void fou_build_udp(struct sk_buff *skb, struct ip_tunnel_encap *e,
  613. struct flowi4 *fl4, u8 *protocol, __be16 sport)
  614. {
  615. struct udphdr *uh;
  616. skb_push(skb, sizeof(struct udphdr));
  617. skb_reset_transport_header(skb);
  618. uh = udp_hdr(skb);
  619. uh->dest = e->dport;
  620. uh->source = sport;
  621. uh->len = htons(skb->len);
  622. udp_set_csum(!(e->flags & TUNNEL_ENCAP_FLAG_CSUM), skb,
  623. fl4->saddr, fl4->daddr, skb->len);
  624. *protocol = IPPROTO_UDP;
  625. }
  626. int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
  627. u8 *protocol, struct flowi4 *fl4)
  628. {
  629. int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM ? SKB_GSO_UDP_TUNNEL_CSUM :
  630. SKB_GSO_UDP_TUNNEL;
  631. __be16 sport;
  632. skb = iptunnel_handle_offloads(skb, type);
  633. if (IS_ERR(skb))
  634. return PTR_ERR(skb);
  635. sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
  636. skb, 0, 0, false);
  637. fou_build_udp(skb, e, fl4, protocol, sport);
  638. return 0;
  639. }
  640. EXPORT_SYMBOL(fou_build_header);
  641. int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
  642. u8 *protocol, struct flowi4 *fl4)
  643. {
  644. int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM ? SKB_GSO_UDP_TUNNEL_CSUM :
  645. SKB_GSO_UDP_TUNNEL;
  646. struct guehdr *guehdr;
  647. size_t hdrlen, optlen = 0;
  648. __be16 sport;
  649. void *data;
  650. bool need_priv = false;
  651. if ((e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) &&
  652. skb->ip_summed == CHECKSUM_PARTIAL) {
  653. optlen += GUE_PLEN_REMCSUM;
  654. type |= SKB_GSO_TUNNEL_REMCSUM;
  655. need_priv = true;
  656. }
  657. optlen += need_priv ? GUE_LEN_PRIV : 0;
  658. skb = iptunnel_handle_offloads(skb, type);
  659. if (IS_ERR(skb))
  660. return PTR_ERR(skb);
  661. /* Get source port (based on flow hash) before skb_push */
  662. sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
  663. skb, 0, 0, false);
  664. hdrlen = sizeof(struct guehdr) + optlen;
  665. skb_push(skb, hdrlen);
  666. guehdr = (struct guehdr *)skb->data;
  667. guehdr->control = 0;
  668. guehdr->version = 0;
  669. guehdr->hlen = optlen >> 2;
  670. guehdr->flags = 0;
  671. guehdr->proto_ctype = *protocol;
  672. data = &guehdr[1];
  673. if (need_priv) {
  674. __be32 *flags = data;
  675. guehdr->flags |= GUE_FLAG_PRIV;
  676. *flags = 0;
  677. data += GUE_LEN_PRIV;
  678. if (type & SKB_GSO_TUNNEL_REMCSUM) {
  679. u16 csum_start = skb_checksum_start_offset(skb);
  680. __be16 *pd = data;
  681. if (csum_start < hdrlen)
  682. return -EINVAL;
  683. csum_start -= hdrlen;
  684. pd[0] = htons(csum_start);
  685. pd[1] = htons(csum_start + skb->csum_offset);
  686. if (!skb_is_gso(skb)) {
  687. skb->ip_summed = CHECKSUM_NONE;
  688. skb->encapsulation = 0;
  689. }
  690. *flags |= GUE_PFLAG_REMCSUM;
  691. data += GUE_PLEN_REMCSUM;
  692. }
  693. }
  694. fou_build_udp(skb, e, fl4, protocol, sport);
  695. return 0;
  696. }
  697. EXPORT_SYMBOL(gue_build_header);
  698. #ifdef CONFIG_NET_FOU_IP_TUNNELS
  699. static const struct ip_tunnel_encap_ops fou_iptun_ops = {
  700. .encap_hlen = fou_encap_hlen,
  701. .build_header = fou_build_header,
  702. };
  703. static const struct ip_tunnel_encap_ops gue_iptun_ops = {
  704. .encap_hlen = gue_encap_hlen,
  705. .build_header = gue_build_header,
  706. };
  707. static int ip_tunnel_encap_add_fou_ops(void)
  708. {
  709. int ret;
  710. ret = ip_tunnel_encap_add_ops(&fou_iptun_ops, TUNNEL_ENCAP_FOU);
  711. if (ret < 0) {
  712. pr_err("can't add fou ops\n");
  713. return ret;
  714. }
  715. ret = ip_tunnel_encap_add_ops(&gue_iptun_ops, TUNNEL_ENCAP_GUE);
  716. if (ret < 0) {
  717. pr_err("can't add gue ops\n");
  718. ip_tunnel_encap_del_ops(&fou_iptun_ops, TUNNEL_ENCAP_FOU);
  719. return ret;
  720. }
  721. return 0;
  722. }
  723. static void ip_tunnel_encap_del_fou_ops(void)
  724. {
  725. ip_tunnel_encap_del_ops(&fou_iptun_ops, TUNNEL_ENCAP_FOU);
  726. ip_tunnel_encap_del_ops(&gue_iptun_ops, TUNNEL_ENCAP_GUE);
  727. }
  728. #else
  729. static int ip_tunnel_encap_add_fou_ops(void)
  730. {
  731. return 0;
  732. }
  733. static void ip_tunnel_encap_del_fou_ops(void)
  734. {
  735. }
  736. #endif
  737. static __net_init int fou_init_net(struct net *net)
  738. {
  739. struct fou_net *fn = net_generic(net, fou_net_id);
  740. INIT_LIST_HEAD(&fn->fou_list);
  741. mutex_init(&fn->fou_lock);
  742. return 0;
  743. }
  744. static __net_exit void fou_exit_net(struct net *net)
  745. {
  746. struct fou_net *fn = net_generic(net, fou_net_id);
  747. struct fou *fou, *next;
  748. /* Close all the FOU sockets */
  749. mutex_lock(&fn->fou_lock);
  750. list_for_each_entry_safe(fou, next, &fn->fou_list, list)
  751. fou_release(fou);
  752. mutex_unlock(&fn->fou_lock);
  753. }
  754. static struct pernet_operations fou_net_ops = {
  755. .init = fou_init_net,
  756. .exit = fou_exit_net,
  757. .id = &fou_net_id,
  758. .size = sizeof(struct fou_net),
  759. };
  760. static int __init fou_init(void)
  761. {
  762. int ret;
  763. ret = register_pernet_device(&fou_net_ops);
  764. if (ret)
  765. goto exit;
  766. ret = genl_register_family_with_ops(&fou_nl_family,
  767. fou_nl_ops);
  768. if (ret < 0)
  769. goto unregister;
  770. ret = ip_tunnel_encap_add_fou_ops();
  771. if (ret == 0)
  772. return 0;
  773. genl_unregister_family(&fou_nl_family);
  774. unregister:
  775. unregister_pernet_device(&fou_net_ops);
  776. exit:
  777. return ret;
  778. }
  779. static void __exit fou_fini(void)
  780. {
  781. ip_tunnel_encap_del_fou_ops();
  782. genl_unregister_family(&fou_nl_family);
  783. unregister_pernet_device(&fou_net_ops);
  784. }
  785. module_init(fou_init);
  786. module_exit(fou_fini);
  787. MODULE_AUTHOR("Tom Herbert <therbert@google.com>");
  788. MODULE_LICENSE("GPL");