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>
7 #include <linux/icmp.h>
9 #include <linux/types.h>
10 #include <linux/kernel.h>
11 #include <net/genetlink.h>
16 #include <net/protocol.h>
18 #include <net/udp_tunnel.h>
19 #include <uapi/linux/fou.h>
20 #include <uapi/linux/genetlink.h>
29 struct list_head list
;
33 #define FOU_F_REMCSUM_NOPARTIAL BIT(0)
39 struct udp_port_cfg udp_config
;
42 static unsigned int fou_net_id
;
45 struct list_head fou_list
;
46 struct mutex fou_lock
;
49 static inline struct fou
*fou_from_sock(struct sock
*sk
)
51 return sk
->sk_user_data
;
54 static int fou_recv_pull(struct sk_buff
*skb
, struct fou
*fou
, size_t len
)
56 /* Remove 'len' bytes from the packet (UDP header and
57 * FOU header if present).
59 if (fou
->family
== AF_INET
)
60 ip_hdr(skb
)->tot_len
= htons(ntohs(ip_hdr(skb
)->tot_len
) - len
);
62 ipv6_hdr(skb
)->payload_len
=
63 htons(ntohs(ipv6_hdr(skb
)->payload_len
) - len
);
66 skb_postpull_rcsum(skb
, udp_hdr(skb
), len
);
67 skb_reset_transport_header(skb
);
68 return iptunnel_pull_offloads(skb
);
71 static int fou_udp_recv(struct sock
*sk
, struct sk_buff
*skb
)
73 struct fou
*fou
= fou_from_sock(sk
);
78 if (fou_recv_pull(skb
, fou
, sizeof(struct udphdr
)))
81 return -fou
->protocol
;
88 static struct guehdr
*gue_remcsum(struct sk_buff
*skb
, struct guehdr
*guehdr
,
89 void *data
, size_t hdrlen
, u8 ipproto
,
93 size_t start
= ntohs(pd
[0]);
94 size_t offset
= ntohs(pd
[1]);
95 size_t plen
= sizeof(struct udphdr
) + hdrlen
+
96 max_t(size_t, offset
+ sizeof(u16
), start
);
98 if (skb
->remcsum_offload
)
101 if (!pskb_may_pull(skb
, plen
))
103 guehdr
= (struct guehdr
*)&udp_hdr(skb
)[1];
105 skb_remcsum_process(skb
, (void *)guehdr
+ hdrlen
,
106 start
, offset
, nopartial
);
111 static int gue_control_message(struct sk_buff
*skb
, struct guehdr
*guehdr
)
118 static int gue_udp_recv(struct sock
*sk
, struct sk_buff
*skb
)
120 struct fou
*fou
= fou_from_sock(sk
);
121 size_t len
, optlen
, hdrlen
;
122 struct guehdr
*guehdr
;
130 len
= sizeof(struct udphdr
) + sizeof(struct guehdr
);
131 if (!pskb_may_pull(skb
, len
))
134 guehdr
= (struct guehdr
*)&udp_hdr(skb
)[1];
136 switch (guehdr
->version
) {
137 case 0: /* Full GUE header present */
141 /* Direct encapsulation of IPv4 or IPv6 */
145 switch (((struct iphdr
*)guehdr
)->version
) {
156 if (fou_recv_pull(skb
, fou
, sizeof(struct udphdr
)))
162 default: /* Undefined version */
166 optlen
= guehdr
->hlen
<< 2;
169 if (!pskb_may_pull(skb
, len
))
172 /* guehdr may change after pull */
173 guehdr
= (struct guehdr
*)&udp_hdr(skb
)[1];
175 if (validate_gue_flags(guehdr
, optlen
))
178 hdrlen
= sizeof(struct guehdr
) + optlen
;
180 if (fou
->family
== AF_INET
)
181 ip_hdr(skb
)->tot_len
= htons(ntohs(ip_hdr(skb
)->tot_len
) - len
);
183 ipv6_hdr(skb
)->payload_len
=
184 htons(ntohs(ipv6_hdr(skb
)->payload_len
) - len
);
186 /* Pull csum through the guehdr now . This can be used if
187 * there is a remote checksum offload.
189 skb_postpull_rcsum(skb
, udp_hdr(skb
), len
);
193 if (guehdr
->flags
& GUE_FLAG_PRIV
) {
194 __be32 flags
= *(__be32
*)(data
+ doffset
);
196 doffset
+= GUE_LEN_PRIV
;
198 if (flags
& GUE_PFLAG_REMCSUM
) {
199 guehdr
= gue_remcsum(skb
, guehdr
, data
+ doffset
,
200 hdrlen
, guehdr
->proto_ctype
,
202 FOU_F_REMCSUM_NOPARTIAL
));
208 doffset
+= GUE_PLEN_REMCSUM
;
212 if (unlikely(guehdr
->control
))
213 return gue_control_message(skb
, guehdr
);
215 proto_ctype
= guehdr
->proto_ctype
;
216 __skb_pull(skb
, sizeof(struct udphdr
) + hdrlen
);
217 skb_reset_transport_header(skb
);
219 if (iptunnel_pull_offloads(skb
))
229 static struct sk_buff
*fou_gro_receive(struct sock
*sk
,
230 struct list_head
*head
,
233 const struct net_offload __rcu
**offloads
;
234 u8 proto
= fou_from_sock(sk
)->protocol
;
235 const struct net_offload
*ops
;
236 struct sk_buff
*pp
= NULL
;
238 /* We can clear the encap_mark for FOU as we are essentially doing
239 * one of two possible things. We are either adding an L4 tunnel
240 * header to the outer L3 tunnel header, or we are simply
241 * treating the GRE tunnel header as though it is a UDP protocol
242 * specific header such as VXLAN or GENEVE.
244 NAPI_GRO_CB(skb
)->encap_mark
= 0;
246 /* Flag this frame as already having an outer encap header */
247 NAPI_GRO_CB(skb
)->is_fou
= 1;
249 offloads
= NAPI_GRO_CB(skb
)->is_ipv6
? inet6_offloads
: inet_offloads
;
250 ops
= rcu_dereference(offloads
[proto
]);
251 if (!ops
|| !ops
->callbacks
.gro_receive
)
254 pp
= call_gro_receive(ops
->callbacks
.gro_receive
, head
, skb
);
260 static int fou_gro_complete(struct sock
*sk
, struct sk_buff
*skb
,
263 const struct net_offload __rcu
**offloads
;
264 u8 proto
= fou_from_sock(sk
)->protocol
;
265 const struct net_offload
*ops
;
268 offloads
= NAPI_GRO_CB(skb
)->is_ipv6
? inet6_offloads
: inet_offloads
;
269 ops
= rcu_dereference(offloads
[proto
]);
270 if (WARN_ON(!ops
|| !ops
->callbacks
.gro_complete
))
273 err
= ops
->callbacks
.gro_complete(skb
, nhoff
);
275 skb_set_inner_mac_header(skb
, nhoff
);
281 static struct guehdr
*gue_gro_remcsum(struct sk_buff
*skb
, unsigned int off
,
282 struct guehdr
*guehdr
, void *data
,
283 size_t hdrlen
, struct gro_remcsum
*grc
,
287 size_t start
= ntohs(pd
[0]);
288 size_t offset
= ntohs(pd
[1]);
290 if (skb
->remcsum_offload
)
293 if (!NAPI_GRO_CB(skb
)->csum_valid
)
296 guehdr
= skb_gro_remcsum_process(skb
, (void *)guehdr
, off
, hdrlen
,
297 start
, offset
, grc
, nopartial
);
299 skb
->remcsum_offload
= 1;
304 static struct sk_buff
*gue_gro_receive(struct sock
*sk
,
305 struct list_head
*head
,
308 const struct net_offload __rcu
**offloads
;
309 const struct net_offload
*ops
;
310 struct sk_buff
*pp
= NULL
;
312 struct guehdr
*guehdr
;
313 size_t len
, optlen
, hdrlen
, off
;
317 struct fou
*fou
= fou_from_sock(sk
);
318 struct gro_remcsum grc
;
321 skb_gro_remcsum_init(&grc
);
323 off
= skb_gro_offset(skb
);
324 len
= off
+ sizeof(*guehdr
);
326 guehdr
= skb_gro_header_fast(skb
, off
);
327 if (skb_gro_header_hard(skb
, len
)) {
328 guehdr
= skb_gro_header_slow(skb
, len
, off
);
329 if (unlikely(!guehdr
))
333 switch (guehdr
->version
) {
337 switch (((struct iphdr
*)guehdr
)->version
) {
339 proto
= IPPROTO_IPIP
;
342 proto
= IPPROTO_IPV6
;
352 optlen
= guehdr
->hlen
<< 2;
355 if (skb_gro_header_hard(skb
, len
)) {
356 guehdr
= skb_gro_header_slow(skb
, len
, off
);
357 if (unlikely(!guehdr
))
361 if (unlikely(guehdr
->control
) || guehdr
->version
!= 0 ||
362 validate_gue_flags(guehdr
, optlen
))
365 hdrlen
= sizeof(*guehdr
) + optlen
;
367 /* Adjust NAPI_GRO_CB(skb)->csum to account for guehdr,
368 * this is needed if there is a remote checkcsum offload.
370 skb_gro_postpull_rcsum(skb
, guehdr
, hdrlen
);
374 if (guehdr
->flags
& GUE_FLAG_PRIV
) {
375 __be32 flags
= *(__be32
*)(data
+ doffset
);
377 doffset
+= GUE_LEN_PRIV
;
379 if (flags
& GUE_PFLAG_REMCSUM
) {
380 guehdr
= gue_gro_remcsum(skb
, off
, guehdr
,
381 data
+ doffset
, hdrlen
, &grc
,
383 FOU_F_REMCSUM_NOPARTIAL
));
390 doffset
+= GUE_PLEN_REMCSUM
;
394 skb_gro_pull(skb
, hdrlen
);
396 list_for_each_entry(p
, head
, list
) {
397 const struct guehdr
*guehdr2
;
399 if (!NAPI_GRO_CB(p
)->same_flow
)
402 guehdr2
= (struct guehdr
*)(p
->data
+ off
);
404 /* Compare base GUE header to be equal (covers
405 * hlen, version, proto_ctype, and flags.
407 if (guehdr
->word
!= guehdr2
->word
) {
408 NAPI_GRO_CB(p
)->same_flow
= 0;
412 /* Compare optional fields are the same. */
413 if (guehdr
->hlen
&& memcmp(&guehdr
[1], &guehdr2
[1],
414 guehdr
->hlen
<< 2)) {
415 NAPI_GRO_CB(p
)->same_flow
= 0;
420 proto
= guehdr
->proto_ctype
;
424 /* We can clear the encap_mark for GUE as we are essentially doing
425 * one of two possible things. We are either adding an L4 tunnel
426 * header to the outer L3 tunnel header, or we are simply
427 * treating the GRE tunnel header as though it is a UDP protocol
428 * specific header such as VXLAN or GENEVE.
430 NAPI_GRO_CB(skb
)->encap_mark
= 0;
432 /* Flag this frame as already having an outer encap header */
433 NAPI_GRO_CB(skb
)->is_fou
= 1;
435 offloads
= NAPI_GRO_CB(skb
)->is_ipv6
? inet6_offloads
: inet_offloads
;
436 ops
= rcu_dereference(offloads
[proto
]);
437 if (WARN_ON_ONCE(!ops
|| !ops
->callbacks
.gro_receive
))
440 pp
= call_gro_receive(ops
->callbacks
.gro_receive
, head
, skb
);
444 skb_gro_flush_final_remcsum(skb
, pp
, flush
, &grc
);
449 static int gue_gro_complete(struct sock
*sk
, struct sk_buff
*skb
, int nhoff
)
451 struct guehdr
*guehdr
= (struct guehdr
*)(skb
->data
+ nhoff
);
452 const struct net_offload __rcu
**offloads
;
453 const struct net_offload
*ops
;
454 unsigned int guehlen
= 0;
458 switch (guehdr
->version
) {
460 proto
= guehdr
->proto_ctype
;
461 guehlen
= sizeof(*guehdr
) + (guehdr
->hlen
<< 2);
464 switch (((struct iphdr
*)guehdr
)->version
) {
466 proto
= IPPROTO_IPIP
;
469 proto
= IPPROTO_IPV6
;
479 offloads
= NAPI_GRO_CB(skb
)->is_ipv6
? inet6_offloads
: inet_offloads
;
480 ops
= rcu_dereference(offloads
[proto
]);
481 if (WARN_ON(!ops
|| !ops
->callbacks
.gro_complete
))
484 err
= ops
->callbacks
.gro_complete(skb
, nhoff
+ guehlen
);
486 skb_set_inner_mac_header(skb
, nhoff
+ guehlen
);
492 static bool fou_cfg_cmp(struct fou
*fou
, struct fou_cfg
*cfg
)
494 struct sock
*sk
= fou
->sock
->sk
;
495 struct udp_port_cfg
*udp_cfg
= &cfg
->udp_config
;
497 if (fou
->family
!= udp_cfg
->family
||
498 fou
->port
!= udp_cfg
->local_udp_port
||
499 sk
->sk_dport
!= udp_cfg
->peer_udp_port
||
500 sk
->sk_bound_dev_if
!= udp_cfg
->bind_ifindex
)
503 if (fou
->family
== AF_INET
) {
504 if (sk
->sk_rcv_saddr
!= udp_cfg
->local_ip
.s_addr
||
505 sk
->sk_daddr
!= udp_cfg
->peer_ip
.s_addr
)
509 #if IS_ENABLED(CONFIG_IPV6)
511 if (ipv6_addr_cmp(&sk
->sk_v6_rcv_saddr
, &udp_cfg
->local_ip6
) ||
512 ipv6_addr_cmp(&sk
->sk_v6_daddr
, &udp_cfg
->peer_ip6
))
522 static int fou_add_to_port_list(struct net
*net
, struct fou
*fou
,
525 struct fou_net
*fn
= net_generic(net
, fou_net_id
);
528 mutex_lock(&fn
->fou_lock
);
529 list_for_each_entry(fout
, &fn
->fou_list
, list
) {
530 if (fou_cfg_cmp(fout
, cfg
)) {
531 mutex_unlock(&fn
->fou_lock
);
536 list_add(&fou
->list
, &fn
->fou_list
);
537 mutex_unlock(&fn
->fou_lock
);
542 static void fou_release(struct fou
*fou
)
544 struct socket
*sock
= fou
->sock
;
546 list_del(&fou
->list
);
547 udp_tunnel_sock_release(sock
);
552 static int fou_create(struct net
*net
, struct fou_cfg
*cfg
,
553 struct socket
**sockp
)
555 struct socket
*sock
= NULL
;
556 struct fou
*fou
= NULL
;
558 struct udp_tunnel_sock_cfg tunnel_cfg
;
561 /* Open UDP socket */
562 err
= udp_sock_create(net
, &cfg
->udp_config
, &sock
);
566 /* Allocate FOU port structure */
567 fou
= kzalloc(sizeof(*fou
), GFP_KERNEL
);
575 fou
->port
= cfg
->udp_config
.local_udp_port
;
576 fou
->family
= cfg
->udp_config
.family
;
577 fou
->flags
= cfg
->flags
;
578 fou
->type
= cfg
->type
;
581 memset(&tunnel_cfg
, 0, sizeof(tunnel_cfg
));
582 tunnel_cfg
.encap_type
= 1;
583 tunnel_cfg
.sk_user_data
= fou
;
584 tunnel_cfg
.encap_destroy
= NULL
;
586 /* Initial for fou type */
588 case FOU_ENCAP_DIRECT
:
589 tunnel_cfg
.encap_rcv
= fou_udp_recv
;
590 tunnel_cfg
.gro_receive
= fou_gro_receive
;
591 tunnel_cfg
.gro_complete
= fou_gro_complete
;
592 fou
->protocol
= cfg
->protocol
;
595 tunnel_cfg
.encap_rcv
= gue_udp_recv
;
596 tunnel_cfg
.gro_receive
= gue_gro_receive
;
597 tunnel_cfg
.gro_complete
= gue_gro_complete
;
604 setup_udp_tunnel_sock(net
, sock
, &tunnel_cfg
);
606 sk
->sk_allocation
= GFP_ATOMIC
;
608 err
= fou_add_to_port_list(net
, fou
, cfg
);
620 udp_tunnel_sock_release(sock
);
625 static int fou_destroy(struct net
*net
, struct fou_cfg
*cfg
)
627 struct fou_net
*fn
= net_generic(net
, fou_net_id
);
631 mutex_lock(&fn
->fou_lock
);
632 list_for_each_entry(fou
, &fn
->fou_list
, list
) {
633 if (fou_cfg_cmp(fou
, cfg
)) {
639 mutex_unlock(&fn
->fou_lock
);
644 static struct genl_family fou_nl_family
;
646 static const struct nla_policy fou_nl_policy
[FOU_ATTR_MAX
+ 1] = {
647 [FOU_ATTR_PORT
] = { .type
= NLA_U16
, },
648 [FOU_ATTR_AF
] = { .type
= NLA_U8
, },
649 [FOU_ATTR_IPPROTO
] = { .type
= NLA_U8
, },
650 [FOU_ATTR_TYPE
] = { .type
= NLA_U8
, },
651 [FOU_ATTR_REMCSUM_NOPARTIAL
] = { .type
= NLA_FLAG
, },
652 [FOU_ATTR_LOCAL_V4
] = { .type
= NLA_U32
, },
653 [FOU_ATTR_PEER_V4
] = { .type
= NLA_U32
, },
654 [FOU_ATTR_LOCAL_V6
] = { .len
= sizeof(struct in6_addr
), },
655 [FOU_ATTR_PEER_V6
] = { .len
= sizeof(struct in6_addr
), },
656 [FOU_ATTR_PEER_PORT
] = { .type
= NLA_U16
, },
657 [FOU_ATTR_IFINDEX
] = { .type
= NLA_S32
, },
660 static int parse_nl_config(struct genl_info
*info
,
663 bool has_local
= false, has_peer
= false;
668 memset(cfg
, 0, sizeof(*cfg
));
670 cfg
->udp_config
.family
= AF_INET
;
672 if (info
->attrs
[FOU_ATTR_AF
]) {
673 u8 family
= nla_get_u8(info
->attrs
[FOU_ATTR_AF
]);
679 cfg
->udp_config
.ipv6_v6only
= 1;
682 return -EAFNOSUPPORT
;
685 cfg
->udp_config
.family
= family
;
688 if (info
->attrs
[FOU_ATTR_PORT
]) {
689 port
= nla_get_be16(info
->attrs
[FOU_ATTR_PORT
]);
690 cfg
->udp_config
.local_udp_port
= port
;
693 if (info
->attrs
[FOU_ATTR_IPPROTO
])
694 cfg
->protocol
= nla_get_u8(info
->attrs
[FOU_ATTR_IPPROTO
]);
696 if (info
->attrs
[FOU_ATTR_TYPE
])
697 cfg
->type
= nla_get_u8(info
->attrs
[FOU_ATTR_TYPE
]);
699 if (info
->attrs
[FOU_ATTR_REMCSUM_NOPARTIAL
])
700 cfg
->flags
|= FOU_F_REMCSUM_NOPARTIAL
;
702 if (cfg
->udp_config
.family
== AF_INET
) {
703 if (info
->attrs
[FOU_ATTR_LOCAL_V4
]) {
704 attr
= info
->attrs
[FOU_ATTR_LOCAL_V4
];
705 cfg
->udp_config
.local_ip
.s_addr
= nla_get_in_addr(attr
);
709 if (info
->attrs
[FOU_ATTR_PEER_V4
]) {
710 attr
= info
->attrs
[FOU_ATTR_PEER_V4
];
711 cfg
->udp_config
.peer_ip
.s_addr
= nla_get_in_addr(attr
);
714 #if IS_ENABLED(CONFIG_IPV6)
716 if (info
->attrs
[FOU_ATTR_LOCAL_V6
]) {
717 attr
= info
->attrs
[FOU_ATTR_LOCAL_V6
];
718 cfg
->udp_config
.local_ip6
= nla_get_in6_addr(attr
);
722 if (info
->attrs
[FOU_ATTR_PEER_V6
]) {
723 attr
= info
->attrs
[FOU_ATTR_PEER_V6
];
724 cfg
->udp_config
.peer_ip6
= nla_get_in6_addr(attr
);
731 if (info
->attrs
[FOU_ATTR_PEER_PORT
]) {
732 port
= nla_get_be16(info
->attrs
[FOU_ATTR_PEER_PORT
]);
733 cfg
->udp_config
.peer_udp_port
= port
;
739 if (info
->attrs
[FOU_ATTR_IFINDEX
]) {
743 ifindex
= nla_get_s32(info
->attrs
[FOU_ATTR_IFINDEX
]);
745 cfg
->udp_config
.bind_ifindex
= ifindex
;
751 static int fou_nl_cmd_add_port(struct sk_buff
*skb
, struct genl_info
*info
)
753 struct net
*net
= genl_info_net(info
);
757 err
= parse_nl_config(info
, &cfg
);
761 return fou_create(net
, &cfg
, NULL
);
764 static int fou_nl_cmd_rm_port(struct sk_buff
*skb
, struct genl_info
*info
)
766 struct net
*net
= genl_info_net(info
);
770 err
= parse_nl_config(info
, &cfg
);
774 return fou_destroy(net
, &cfg
);
777 static int fou_fill_info(struct fou
*fou
, struct sk_buff
*msg
)
779 struct sock
*sk
= fou
->sock
->sk
;
781 if (nla_put_u8(msg
, FOU_ATTR_AF
, fou
->sock
->sk
->sk_family
) ||
782 nla_put_be16(msg
, FOU_ATTR_PORT
, fou
->port
) ||
783 nla_put_be16(msg
, FOU_ATTR_PEER_PORT
, sk
->sk_dport
) ||
784 nla_put_u8(msg
, FOU_ATTR_IPPROTO
, fou
->protocol
) ||
785 nla_put_u8(msg
, FOU_ATTR_TYPE
, fou
->type
) ||
786 nla_put_s32(msg
, FOU_ATTR_IFINDEX
, sk
->sk_bound_dev_if
))
789 if (fou
->flags
& FOU_F_REMCSUM_NOPARTIAL
)
790 if (nla_put_flag(msg
, FOU_ATTR_REMCSUM_NOPARTIAL
))
793 if (fou
->sock
->sk
->sk_family
== AF_INET
) {
794 if (nla_put_in_addr(msg
, FOU_ATTR_LOCAL_V4
, sk
->sk_rcv_saddr
))
797 if (nla_put_in_addr(msg
, FOU_ATTR_PEER_V4
, sk
->sk_daddr
))
799 #if IS_ENABLED(CONFIG_IPV6)
801 if (nla_put_in6_addr(msg
, FOU_ATTR_LOCAL_V6
,
802 &sk
->sk_v6_rcv_saddr
))
805 if (nla_put_in6_addr(msg
, FOU_ATTR_PEER_V6
, &sk
->sk_v6_daddr
))
813 static int fou_dump_info(struct fou
*fou
, u32 portid
, u32 seq
,
814 u32 flags
, struct sk_buff
*skb
, u8 cmd
)
818 hdr
= genlmsg_put(skb
, portid
, seq
, &fou_nl_family
, flags
, cmd
);
822 if (fou_fill_info(fou
, skb
) < 0)
823 goto nla_put_failure
;
825 genlmsg_end(skb
, hdr
);
829 genlmsg_cancel(skb
, hdr
);
833 static int fou_nl_cmd_get_port(struct sk_buff
*skb
, struct genl_info
*info
)
835 struct net
*net
= genl_info_net(info
);
836 struct fou_net
*fn
= net_generic(net
, fou_net_id
);
844 ret
= parse_nl_config(info
, &cfg
);
847 port
= cfg
.udp_config
.local_udp_port
;
851 family
= cfg
.udp_config
.family
;
852 if (family
!= AF_INET
&& family
!= AF_INET6
)
855 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
860 mutex_lock(&fn
->fou_lock
);
861 list_for_each_entry(fout
, &fn
->fou_list
, list
) {
862 if (fou_cfg_cmp(fout
, &cfg
)) {
863 ret
= fou_dump_info(fout
, info
->snd_portid
,
864 info
->snd_seq
, 0, msg
,
869 mutex_unlock(&fn
->fou_lock
);
873 return genlmsg_reply(msg
, info
);
880 static int fou_nl_dump(struct sk_buff
*skb
, struct netlink_callback
*cb
)
882 struct net
*net
= sock_net(skb
->sk
);
883 struct fou_net
*fn
= net_generic(net
, fou_net_id
);
887 mutex_lock(&fn
->fou_lock
);
888 list_for_each_entry(fout
, &fn
->fou_list
, list
) {
889 if (idx
++ < cb
->args
[0])
891 ret
= fou_dump_info(fout
, NETLINK_CB(cb
->skb
).portid
,
892 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
897 mutex_unlock(&fn
->fou_lock
);
903 static const struct genl_small_ops fou_nl_ops
[] = {
906 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
907 .doit
= fou_nl_cmd_add_port
,
908 .flags
= GENL_ADMIN_PERM
,
912 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
913 .doit
= fou_nl_cmd_rm_port
,
914 .flags
= GENL_ADMIN_PERM
,
918 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
919 .doit
= fou_nl_cmd_get_port
,
920 .dumpit
= fou_nl_dump
,
924 static struct genl_family fou_nl_family __ro_after_init
= {
926 .name
= FOU_GENL_NAME
,
927 .version
= FOU_GENL_VERSION
,
928 .maxattr
= FOU_ATTR_MAX
,
929 .policy
= fou_nl_policy
,
931 .module
= THIS_MODULE
,
932 .small_ops
= fou_nl_ops
,
933 .n_small_ops
= ARRAY_SIZE(fou_nl_ops
),
936 size_t fou_encap_hlen(struct ip_tunnel_encap
*e
)
938 return sizeof(struct udphdr
);
940 EXPORT_SYMBOL(fou_encap_hlen
);
942 size_t gue_encap_hlen(struct ip_tunnel_encap
*e
)
945 bool need_priv
= false;
947 len
= sizeof(struct udphdr
) + sizeof(struct guehdr
);
949 if (e
->flags
& TUNNEL_ENCAP_FLAG_REMCSUM
) {
950 len
+= GUE_PLEN_REMCSUM
;
954 len
+= need_priv
? GUE_LEN_PRIV
: 0;
958 EXPORT_SYMBOL(gue_encap_hlen
);
960 int __fou_build_header(struct sk_buff
*skb
, struct ip_tunnel_encap
*e
,
961 u8
*protocol
, __be16
*sport
, int type
)
965 err
= iptunnel_handle_offloads(skb
, type
);
969 *sport
= e
->sport
? : udp_flow_src_port(dev_net(skb
->dev
),
974 EXPORT_SYMBOL(__fou_build_header
);
976 int __gue_build_header(struct sk_buff
*skb
, struct ip_tunnel_encap
*e
,
977 u8
*protocol
, __be16
*sport
, int type
)
979 struct guehdr
*guehdr
;
980 size_t hdrlen
, optlen
= 0;
982 bool need_priv
= false;
985 if ((e
->flags
& TUNNEL_ENCAP_FLAG_REMCSUM
) &&
986 skb
->ip_summed
== CHECKSUM_PARTIAL
) {
987 optlen
+= GUE_PLEN_REMCSUM
;
988 type
|= SKB_GSO_TUNNEL_REMCSUM
;
992 optlen
+= need_priv
? GUE_LEN_PRIV
: 0;
994 err
= iptunnel_handle_offloads(skb
, type
);
998 /* Get source port (based on flow hash) before skb_push */
999 *sport
= e
->sport
? : udp_flow_src_port(dev_net(skb
->dev
),
1002 hdrlen
= sizeof(struct guehdr
) + optlen
;
1004 skb_push(skb
, hdrlen
);
1006 guehdr
= (struct guehdr
*)skb
->data
;
1008 guehdr
->control
= 0;
1009 guehdr
->version
= 0;
1010 guehdr
->hlen
= optlen
>> 2;
1012 guehdr
->proto_ctype
= *protocol
;
1017 __be32
*flags
= data
;
1019 guehdr
->flags
|= GUE_FLAG_PRIV
;
1021 data
+= GUE_LEN_PRIV
;
1023 if (type
& SKB_GSO_TUNNEL_REMCSUM
) {
1024 u16 csum_start
= skb_checksum_start_offset(skb
);
1027 if (csum_start
< hdrlen
)
1030 csum_start
-= hdrlen
;
1031 pd
[0] = htons(csum_start
);
1032 pd
[1] = htons(csum_start
+ skb
->csum_offset
);
1034 if (!skb_is_gso(skb
)) {
1035 skb
->ip_summed
= CHECKSUM_NONE
;
1036 skb
->encapsulation
= 0;
1039 *flags
|= GUE_PFLAG_REMCSUM
;
1040 data
+= GUE_PLEN_REMCSUM
;
1047 EXPORT_SYMBOL(__gue_build_header
);
1049 #ifdef CONFIG_NET_FOU_IP_TUNNELS
1051 static void fou_build_udp(struct sk_buff
*skb
, struct ip_tunnel_encap
*e
,
1052 struct flowi4
*fl4
, u8
*protocol
, __be16 sport
)
1056 skb_push(skb
, sizeof(struct udphdr
));
1057 skb_reset_transport_header(skb
);
1061 uh
->dest
= e
->dport
;
1063 uh
->len
= htons(skb
->len
);
1064 udp_set_csum(!(e
->flags
& TUNNEL_ENCAP_FLAG_CSUM
), skb
,
1065 fl4
->saddr
, fl4
->daddr
, skb
->len
);
1067 *protocol
= IPPROTO_UDP
;
1070 static int fou_build_header(struct sk_buff
*skb
, struct ip_tunnel_encap
*e
,
1071 u8
*protocol
, struct flowi4
*fl4
)
1073 int type
= e
->flags
& TUNNEL_ENCAP_FLAG_CSUM
? SKB_GSO_UDP_TUNNEL_CSUM
:
1078 err
= __fou_build_header(skb
, e
, protocol
, &sport
, type
);
1082 fou_build_udp(skb
, e
, fl4
, protocol
, sport
);
1087 static int gue_build_header(struct sk_buff
*skb
, struct ip_tunnel_encap
*e
,
1088 u8
*protocol
, struct flowi4
*fl4
)
1090 int type
= e
->flags
& TUNNEL_ENCAP_FLAG_CSUM
? SKB_GSO_UDP_TUNNEL_CSUM
:
1095 err
= __gue_build_header(skb
, e
, protocol
, &sport
, type
);
1099 fou_build_udp(skb
, e
, fl4
, protocol
, sport
);
1104 static int gue_err_proto_handler(int proto
, struct sk_buff
*skb
, u32 info
)
1106 const struct net_protocol
*ipprot
= rcu_dereference(inet_protos
[proto
]);
1108 if (ipprot
&& ipprot
->err_handler
) {
1109 if (!ipprot
->err_handler(skb
, info
))
1116 static int gue_err(struct sk_buff
*skb
, u32 info
)
1118 int transport_offset
= skb_transport_offset(skb
);
1119 struct guehdr
*guehdr
;
1123 len
= sizeof(struct udphdr
) + sizeof(struct guehdr
);
1124 if (!pskb_may_pull(skb
, transport_offset
+ len
))
1127 guehdr
= (struct guehdr
*)&udp_hdr(skb
)[1];
1129 switch (guehdr
->version
) {
1130 case 0: /* Full GUE header present */
1133 /* Direct encapsulation of IPv4 or IPv6 */
1134 skb_set_transport_header(skb
, -(int)sizeof(struct icmphdr
));
1136 switch (((struct iphdr
*)guehdr
)->version
) {
1138 ret
= gue_err_proto_handler(IPPROTO_IPIP
, skb
, info
);
1140 #if IS_ENABLED(CONFIG_IPV6)
1142 ret
= gue_err_proto_handler(IPPROTO_IPV6
, skb
, info
);
1150 default: /* Undefined version */
1154 if (guehdr
->control
)
1157 optlen
= guehdr
->hlen
<< 2;
1159 if (!pskb_may_pull(skb
, transport_offset
+ len
+ optlen
))
1162 guehdr
= (struct guehdr
*)&udp_hdr(skb
)[1];
1163 if (validate_gue_flags(guehdr
, optlen
))
1166 /* Handling exceptions for direct UDP encapsulation in GUE would lead to
1167 * recursion. Besides, this kind of encapsulation can't even be
1168 * configured currently. Discard this.
1170 if (guehdr
->proto_ctype
== IPPROTO_UDP
||
1171 guehdr
->proto_ctype
== IPPROTO_UDPLITE
)
1174 skb_set_transport_header(skb
, -(int)sizeof(struct icmphdr
));
1175 ret
= gue_err_proto_handler(guehdr
->proto_ctype
, skb
, info
);
1178 skb_set_transport_header(skb
, transport_offset
);
1183 static const struct ip_tunnel_encap_ops fou_iptun_ops
= {
1184 .encap_hlen
= fou_encap_hlen
,
1185 .build_header
= fou_build_header
,
1186 .err_handler
= gue_err
,
1189 static const struct ip_tunnel_encap_ops gue_iptun_ops
= {
1190 .encap_hlen
= gue_encap_hlen
,
1191 .build_header
= gue_build_header
,
1192 .err_handler
= gue_err
,
1195 static int ip_tunnel_encap_add_fou_ops(void)
1199 ret
= ip_tunnel_encap_add_ops(&fou_iptun_ops
, TUNNEL_ENCAP_FOU
);
1201 pr_err("can't add fou ops\n");
1205 ret
= ip_tunnel_encap_add_ops(&gue_iptun_ops
, TUNNEL_ENCAP_GUE
);
1207 pr_err("can't add gue ops\n");
1208 ip_tunnel_encap_del_ops(&fou_iptun_ops
, TUNNEL_ENCAP_FOU
);
1215 static void ip_tunnel_encap_del_fou_ops(void)
1217 ip_tunnel_encap_del_ops(&fou_iptun_ops
, TUNNEL_ENCAP_FOU
);
1218 ip_tunnel_encap_del_ops(&gue_iptun_ops
, TUNNEL_ENCAP_GUE
);
1223 static int ip_tunnel_encap_add_fou_ops(void)
1228 static void ip_tunnel_encap_del_fou_ops(void)
1234 static __net_init
int fou_init_net(struct net
*net
)
1236 struct fou_net
*fn
= net_generic(net
, fou_net_id
);
1238 INIT_LIST_HEAD(&fn
->fou_list
);
1239 mutex_init(&fn
->fou_lock
);
1243 static __net_exit
void fou_exit_net(struct net
*net
)
1245 struct fou_net
*fn
= net_generic(net
, fou_net_id
);
1246 struct fou
*fou
, *next
;
1248 /* Close all the FOU sockets */
1249 mutex_lock(&fn
->fou_lock
);
1250 list_for_each_entry_safe(fou
, next
, &fn
->fou_list
, list
)
1252 mutex_unlock(&fn
->fou_lock
);
1255 static struct pernet_operations fou_net_ops
= {
1256 .init
= fou_init_net
,
1257 .exit
= fou_exit_net
,
1259 .size
= sizeof(struct fou_net
),
1262 static int __init
fou_init(void)
1266 ret
= register_pernet_device(&fou_net_ops
);
1270 ret
= genl_register_family(&fou_nl_family
);
1274 ret
= ip_tunnel_encap_add_fou_ops();
1278 genl_unregister_family(&fou_nl_family
);
1280 unregister_pernet_device(&fou_net_ops
);
1285 static void __exit
fou_fini(void)
1287 ip_tunnel_encap_del_fou_ops();
1288 genl_unregister_family(&fou_nl_family
);
1289 unregister_pernet_device(&fou_net_ops
);
1292 module_init(fou_init
);
1293 module_exit(fou_fini
);
1294 MODULE_AUTHOR("Tom Herbert <therbert@google.com>");
1295 MODULE_LICENSE("GPL");
1296 MODULE_DESCRIPTION("Foo over UDP");