• Home
  • Raw
  • Download

Lines Matching +full:foo +full:- +full:over +full:- +full:udp

1 // SPDX-License-Identifier: GPL-2.0-only
8 #include <linux/udp.h>
16 #include <net/udp.h>
51 return sk->sk_user_data; in fou_from_sock()
56 /* Remove 'len' bytes from the packet (UDP header and in fou_recv_pull()
59 if (fou->family == AF_INET) in fou_recv_pull()
60 ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len); in fou_recv_pull()
62 ipv6_hdr(skb)->payload_len = in fou_recv_pull()
63 htons(ntohs(ipv6_hdr(skb)->payload_len) - len); in fou_recv_pull()
81 return -fou->protocol; in fou_udp_recv()
98 if (skb->remcsum_offload) in gue_remcsum()
136 switch (guehdr->version) { in gue_udp_recv()
145 switch (((struct iphdr *)guehdr)->version) { in gue_udp_recv()
159 return -prot; in gue_udp_recv()
166 optlen = guehdr->hlen << 2; in gue_udp_recv()
180 if (fou->family == AF_INET) in gue_udp_recv()
181 ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len); in gue_udp_recv()
183 ipv6_hdr(skb)->payload_len = in gue_udp_recv()
184 htons(ntohs(ipv6_hdr(skb)->payload_len) - len); in gue_udp_recv()
193 if (guehdr->flags & GUE_FLAG_PRIV) { in gue_udp_recv()
200 hdrlen, guehdr->proto_ctype, in gue_udp_recv()
201 !!(fou->flags & in gue_udp_recv()
212 if (unlikely(guehdr->control)) in gue_udp_recv()
215 proto_ctype = guehdr->proto_ctype; in gue_udp_recv()
222 return -proto_ctype; in gue_udp_recv()
233 u8 proto = fou_from_sock(sk)->protocol; in fou_gro_receive()
241 * treating the GRE tunnel header as though it is a UDP protocol in fou_gro_receive()
244 NAPI_GRO_CB(skb)->encap_mark = 0; in fou_gro_receive()
247 NAPI_GRO_CB(skb)->is_fou = 1; in fou_gro_receive()
250 offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; in fou_gro_receive()
252 if (!ops || !ops->callbacks.gro_receive) in fou_gro_receive()
255 pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); in fou_gro_receive()
267 u8 proto = fou_from_sock(sk)->protocol; in fou_gro_complete()
268 int err = -ENOSYS; in fou_gro_complete()
272 offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; in fou_gro_complete()
274 if (WARN_ON(!ops || !ops->callbacks.gro_complete)) in fou_gro_complete()
277 err = ops->callbacks.gro_complete(skb, nhoff); in fou_gro_complete()
296 if (skb->remcsum_offload) in gue_gro_remcsum()
299 if (!NAPI_GRO_CB(skb)->csum_valid) in gue_gro_remcsum()
305 skb->remcsum_offload = 1; in gue_gro_remcsum()
339 switch (guehdr->version) { in gue_gro_receive()
343 switch (((struct iphdr *)guehdr)->version) { in gue_gro_receive()
358 optlen = guehdr->hlen << 2; in gue_gro_receive()
367 if (unlikely(guehdr->control) || guehdr->version != 0 || in gue_gro_receive()
373 /* Adjust NAPI_GRO_CB(skb)->csum to account for guehdr, in gue_gro_receive()
380 if (guehdr->flags & GUE_FLAG_PRIV) { in gue_gro_receive()
388 !!(fou->flags & in gue_gro_receive()
405 if (!NAPI_GRO_CB(p)->same_flow) in gue_gro_receive()
408 guehdr2 = (struct guehdr *)(p->data + off); in gue_gro_receive()
413 if (guehdr->word != guehdr2->word) { in gue_gro_receive()
414 NAPI_GRO_CB(p)->same_flow = 0; in gue_gro_receive()
419 if (guehdr->hlen && memcmp(&guehdr[1], &guehdr2[1], in gue_gro_receive()
420 guehdr->hlen << 2)) { in gue_gro_receive()
421 NAPI_GRO_CB(p)->same_flow = 0; in gue_gro_receive()
426 proto = guehdr->proto_ctype; in gue_gro_receive()
433 * treating the GRE tunnel header as though it is a UDP protocol in gue_gro_receive()
436 NAPI_GRO_CB(skb)->encap_mark = 0; in gue_gro_receive()
439 NAPI_GRO_CB(skb)->is_fou = 1; in gue_gro_receive()
442 offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; in gue_gro_receive()
444 if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive)) in gue_gro_receive()
447 pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); in gue_gro_receive()
461 struct guehdr *guehdr = (struct guehdr *)(skb->data + nhoff); in gue_gro_complete()
465 int err = -ENOENT; in gue_gro_complete()
467 switch (guehdr->version) { in gue_gro_complete()
469 proto = guehdr->proto_ctype; in gue_gro_complete()
470 guehlen = sizeof(*guehdr) + (guehdr->hlen << 2); in gue_gro_complete()
473 switch (((struct iphdr *)guehdr)->version) { in gue_gro_complete()
489 offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; in gue_gro_complete()
491 if (WARN_ON(!ops || !ops->callbacks.gro_complete)) in gue_gro_complete()
494 err = ops->callbacks.gro_complete(skb, nhoff + guehlen); in gue_gro_complete()
505 struct sock *sk = fou->sock->sk; in fou_cfg_cmp()
506 struct udp_port_cfg *udp_cfg = &cfg->udp_config; in fou_cfg_cmp()
508 if (fou->family != udp_cfg->family || in fou_cfg_cmp()
509 fou->port != udp_cfg->local_udp_port || in fou_cfg_cmp()
510 sk->sk_dport != udp_cfg->peer_udp_port || in fou_cfg_cmp()
511 sk->sk_bound_dev_if != udp_cfg->bind_ifindex) in fou_cfg_cmp()
514 if (fou->family == AF_INET) { in fou_cfg_cmp()
515 if (sk->sk_rcv_saddr != udp_cfg->local_ip.s_addr || in fou_cfg_cmp()
516 sk->sk_daddr != udp_cfg->peer_ip.s_addr) in fou_cfg_cmp()
522 if (ipv6_addr_cmp(&sk->sk_v6_rcv_saddr, &udp_cfg->local_ip6) || in fou_cfg_cmp()
523 ipv6_addr_cmp(&sk->sk_v6_daddr, &udp_cfg->peer_ip6)) in fou_cfg_cmp()
539 mutex_lock(&fn->fou_lock); in fou_add_to_port_list()
540 list_for_each_entry(fout, &fn->fou_list, list) { in fou_add_to_port_list()
542 mutex_unlock(&fn->fou_lock); in fou_add_to_port_list()
543 return -EALREADY; in fou_add_to_port_list()
547 list_add(&fou->list, &fn->fou_list); in fou_add_to_port_list()
548 mutex_unlock(&fn->fou_lock); in fou_add_to_port_list()
555 struct socket *sock = fou->sock; in fou_release()
557 list_del(&fou->list); in fou_release()
572 /* Open UDP socket */ in fou_create()
573 err = udp_sock_create(net, &cfg->udp_config, &sock); in fou_create()
580 err = -ENOMEM; in fou_create()
584 sk = sock->sk; in fou_create()
586 fou->port = cfg->udp_config.local_udp_port; in fou_create()
587 fou->family = cfg->udp_config.family; in fou_create()
588 fou->flags = cfg->flags; in fou_create()
589 fou->type = cfg->type; in fou_create()
590 fou->sock = sock; in fou_create()
598 switch (cfg->type) { in fou_create()
603 fou->protocol = cfg->protocol; in fou_create()
611 err = -EINVAL; in fou_create()
617 sk->sk_allocation = GFP_ATOMIC; in fou_create()
639 int err = -EINVAL; in fou_destroy()
642 mutex_lock(&fn->fou_lock); in fou_destroy()
643 list_for_each_entry(fou, &fn->fou_list, list) { in fou_destroy()
650 mutex_unlock(&fn->fou_lock); in fou_destroy()
681 cfg->udp_config.family = AF_INET; in parse_nl_config()
683 if (info->attrs[FOU_ATTR_AF]) { in parse_nl_config()
684 u8 family = nla_get_u8(info->attrs[FOU_ATTR_AF]); in parse_nl_config()
690 cfg->udp_config.ipv6_v6only = 1; in parse_nl_config()
693 return -EAFNOSUPPORT; in parse_nl_config()
696 cfg->udp_config.family = family; in parse_nl_config()
699 if (info->attrs[FOU_ATTR_PORT]) { in parse_nl_config()
700 port = nla_get_be16(info->attrs[FOU_ATTR_PORT]); in parse_nl_config()
701 cfg->udp_config.local_udp_port = port; in parse_nl_config()
704 if (info->attrs[FOU_ATTR_IPPROTO]) in parse_nl_config()
705 cfg->protocol = nla_get_u8(info->attrs[FOU_ATTR_IPPROTO]); in parse_nl_config()
707 if (info->attrs[FOU_ATTR_TYPE]) in parse_nl_config()
708 cfg->type = nla_get_u8(info->attrs[FOU_ATTR_TYPE]); in parse_nl_config()
710 if (info->attrs[FOU_ATTR_REMCSUM_NOPARTIAL]) in parse_nl_config()
711 cfg->flags |= FOU_F_REMCSUM_NOPARTIAL; in parse_nl_config()
713 if (cfg->udp_config.family == AF_INET) { in parse_nl_config()
714 if (info->attrs[FOU_ATTR_LOCAL_V4]) { in parse_nl_config()
715 attr = info->attrs[FOU_ATTR_LOCAL_V4]; in parse_nl_config()
716 cfg->udp_config.local_ip.s_addr = nla_get_in_addr(attr); in parse_nl_config()
720 if (info->attrs[FOU_ATTR_PEER_V4]) { in parse_nl_config()
721 attr = info->attrs[FOU_ATTR_PEER_V4]; in parse_nl_config()
722 cfg->udp_config.peer_ip.s_addr = nla_get_in_addr(attr); in parse_nl_config()
727 if (info->attrs[FOU_ATTR_LOCAL_V6]) { in parse_nl_config()
728 attr = info->attrs[FOU_ATTR_LOCAL_V6]; in parse_nl_config()
729 cfg->udp_config.local_ip6 = nla_get_in6_addr(attr); in parse_nl_config()
733 if (info->attrs[FOU_ATTR_PEER_V6]) { in parse_nl_config()
734 attr = info->attrs[FOU_ATTR_PEER_V6]; in parse_nl_config()
735 cfg->udp_config.peer_ip6 = nla_get_in6_addr(attr); in parse_nl_config()
742 if (info->attrs[FOU_ATTR_PEER_PORT]) { in parse_nl_config()
743 port = nla_get_be16(info->attrs[FOU_ATTR_PEER_PORT]); in parse_nl_config()
744 cfg->udp_config.peer_udp_port = port; in parse_nl_config()
746 return -EINVAL; in parse_nl_config()
750 if (info->attrs[FOU_ATTR_IFINDEX]) { in parse_nl_config()
752 return -EINVAL; in parse_nl_config()
754 ifindex = nla_get_s32(info->attrs[FOU_ATTR_IFINDEX]); in parse_nl_config()
756 cfg->udp_config.bind_ifindex = ifindex; in parse_nl_config()
790 struct sock *sk = fou->sock->sk; in fou_fill_info()
792 if (nla_put_u8(msg, FOU_ATTR_AF, fou->sock->sk->sk_family) || in fou_fill_info()
793 nla_put_be16(msg, FOU_ATTR_PORT, fou->port) || in fou_fill_info()
794 nla_put_be16(msg, FOU_ATTR_PEER_PORT, sk->sk_dport) || in fou_fill_info()
795 nla_put_u8(msg, FOU_ATTR_IPPROTO, fou->protocol) || in fou_fill_info()
796 nla_put_u8(msg, FOU_ATTR_TYPE, fou->type) || in fou_fill_info()
797 nla_put_s32(msg, FOU_ATTR_IFINDEX, sk->sk_bound_dev_if)) in fou_fill_info()
798 return -1; in fou_fill_info()
800 if (fou->flags & FOU_F_REMCSUM_NOPARTIAL) in fou_fill_info()
802 return -1; in fou_fill_info()
804 if (fou->sock->sk->sk_family == AF_INET) { in fou_fill_info()
805 if (nla_put_in_addr(msg, FOU_ATTR_LOCAL_V4, sk->sk_rcv_saddr)) in fou_fill_info()
806 return -1; in fou_fill_info()
808 if (nla_put_in_addr(msg, FOU_ATTR_PEER_V4, sk->sk_daddr)) in fou_fill_info()
809 return -1; in fou_fill_info()
813 &sk->sk_v6_rcv_saddr)) in fou_fill_info()
814 return -1; in fou_fill_info()
816 if (nla_put_in6_addr(msg, FOU_ATTR_PEER_V6, &sk->sk_v6_daddr)) in fou_fill_info()
817 return -1; in fou_fill_info()
831 return -ENOMEM; in fou_dump_info()
841 return -EMSGSIZE; in fou_dump_info()
860 return -EINVAL; in fou_nl_cmd_get_port()
864 return -EINVAL; in fou_nl_cmd_get_port()
868 return -ENOMEM; in fou_nl_cmd_get_port()
870 ret = -ESRCH; in fou_nl_cmd_get_port()
871 mutex_lock(&fn->fou_lock); in fou_nl_cmd_get_port()
872 list_for_each_entry(fout, &fn->fou_list, list) { in fou_nl_cmd_get_port()
874 ret = fou_dump_info(fout, info->snd_portid, in fou_nl_cmd_get_port()
875 info->snd_seq, 0, msg, in fou_nl_cmd_get_port()
876 info->genlhdr->cmd); in fou_nl_cmd_get_port()
880 mutex_unlock(&fn->fou_lock); in fou_nl_cmd_get_port()
893 struct net *net = sock_net(skb->sk); in fou_nl_dump()
898 mutex_lock(&fn->fou_lock); in fou_nl_dump()
899 list_for_each_entry(fout, &fn->fou_list, list) { in fou_nl_dump()
900 if (idx++ < cb->args[0]) in fou_nl_dump()
902 ret = fou_dump_info(fout, NETLINK_CB(cb->skb).portid, in fou_nl_dump()
903 cb->nlh->nlmsg_seq, NLM_F_MULTI, in fou_nl_dump()
908 mutex_unlock(&fn->fou_lock); in fou_nl_dump()
910 cb->args[0] = idx; in fou_nl_dump()
911 return skb->len; in fou_nl_dump()
960 if (e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) { in gue_encap_hlen()
980 *sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev), in __fou_build_header()
996 if ((e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) && in __gue_build_header()
997 skb->ip_summed == CHECKSUM_PARTIAL) { in __gue_build_header()
1010 *sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev), in __gue_build_header()
1017 guehdr = (struct guehdr *)skb->data; in __gue_build_header()
1019 guehdr->control = 0; in __gue_build_header()
1020 guehdr->version = 0; in __gue_build_header()
1021 guehdr->hlen = optlen >> 2; in __gue_build_header()
1022 guehdr->flags = 0; in __gue_build_header()
1023 guehdr->proto_ctype = *protocol; in __gue_build_header()
1030 guehdr->flags |= GUE_FLAG_PRIV; in __gue_build_header()
1039 return -EINVAL; in __gue_build_header()
1041 csum_start -= hdrlen; in __gue_build_header()
1043 pd[1] = htons(csum_start + skb->csum_offset); in __gue_build_header()
1046 skb->ip_summed = CHECKSUM_NONE; in __gue_build_header()
1047 skb->encapsulation = 0; in __gue_build_header()
1072 uh->dest = e->dport; in fou_build_udp()
1073 uh->source = sport; in fou_build_udp()
1074 uh->len = htons(skb->len); in fou_build_udp()
1075 udp_set_csum(!(e->flags & TUNNEL_ENCAP_FLAG_CSUM), skb, in fou_build_udp()
1076 fl4->saddr, fl4->daddr, skb->len); in fou_build_udp()
1084 int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM ? SKB_GSO_UDP_TUNNEL_CSUM : in fou_build_header()
1101 int type = e->flags & TUNNEL_ENCAP_FLAG_CSUM ? SKB_GSO_UDP_TUNNEL_CSUM : in gue_build_header()
1119 if (ipprot && ipprot->err_handler) { in gue_err_proto_handler()
1120 if (!ipprot->err_handler(skb, info)) in gue_err_proto_handler()
1124 return -ENOENT; in gue_err_proto_handler()
1136 return -EINVAL; in gue_err()
1140 switch (guehdr->version) { in gue_err()
1145 skb_set_transport_header(skb, -(int)sizeof(struct icmphdr)); in gue_err()
1147 switch (((struct iphdr *)guehdr)->version) { in gue_err()
1157 ret = -EOPNOTSUPP; in gue_err()
1162 return -EOPNOTSUPP; in gue_err()
1165 if (guehdr->control) in gue_err()
1166 return -ENOENT; in gue_err()
1168 optlen = guehdr->hlen << 2; in gue_err()
1171 return -EINVAL; in gue_err()
1175 return -EINVAL; in gue_err()
1177 /* Handling exceptions for direct UDP encapsulation in GUE would lead to in gue_err()
1181 if (guehdr->proto_ctype == IPPROTO_UDP || in gue_err()
1182 guehdr->proto_ctype == IPPROTO_UDPLITE) in gue_err()
1183 return -EOPNOTSUPP; in gue_err()
1185 skb_set_transport_header(skb, -(int)sizeof(struct icmphdr)); in gue_err()
1186 ret = gue_err_proto_handler(guehdr->proto_ctype, skb, info); in gue_err()
1249 INIT_LIST_HEAD(&fn->fou_list); in fou_init_net()
1250 mutex_init(&fn->fou_lock); in fou_init_net()
1260 mutex_lock(&fn->fou_lock); in fou_exit_net()
1261 list_for_each_entry_safe(fou, next, &fn->fou_list, list) in fou_exit_net()
1263 mutex_unlock(&fn->fou_lock); in fou_exit_net()
1307 MODULE_DESCRIPTION("Foo over UDP");