aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/compat/udp_tunnel
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2017-04-07 22:50:00 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2017-04-09 05:20:27 +0200
commit09106ec02cdaec979e6178730e7c5e112ea6d368 (patch)
tree09bb6ed2768b39dfa79278d52d61edf8da8403bd /src/compat/udp_tunnel
parentdata: alloca is actually as dangerous as they say (diff)
downloadwireguard-monolithic-historical-09106ec02cdaec979e6178730e7c5e112ea6d368.tar.xz
wireguard-monolithic-historical-09106ec02cdaec979e6178730e7c5e112ea6d368.zip
compat: support 3.16
Diffstat (limited to 'src/compat/udp_tunnel')
-rw-r--r--src/compat/udp_tunnel/include/net/udp_tunnel.h94
-rw-r--r--src/compat/udp_tunnel/udp_tunnel.c232
-rw-r--r--src/compat/udp_tunnel/udp_tunnel_partial_compat.h215
3 files changed, 541 insertions, 0 deletions
diff --git a/src/compat/udp_tunnel/include/net/udp_tunnel.h b/src/compat/udp_tunnel/include/net/udp_tunnel.h
new file mode 100644
index 0000000..b80f1f5
--- /dev/null
+++ b/src/compat/udp_tunnel/include/net/udp_tunnel.h
@@ -0,0 +1,94 @@
+#ifndef __NET_UDP_TUNNEL_H
+#define __NET_UDP_TUNNEL_H
+
+#include <net/ip_tunnels.h>
+#include <net/udp.h>
+
+#if IS_ENABLED(CONFIG_IPV6)
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#endif
+
+struct udp_port_cfg {
+ u8 family;
+
+ /* Used only for kernel-created sockets */
+ union {
+ struct in_addr local_ip;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr local_ip6;
+#endif
+ };
+
+ union {
+ struct in_addr peer_ip;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr peer_ip6;
+#endif
+ };
+
+ __be16 local_udp_port;
+ __be16 peer_udp_port;
+ unsigned int use_udp_checksums:1,
+ use_udp6_tx_checksums:1,
+ use_udp6_rx_checksums:1,
+ ipv6_v6only:1;
+};
+
+int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
+ struct socket **sockp);
+
+#if IS_ENABLED(CONFIG_IPV6)
+int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
+ struct socket **sockp);
+#else
+static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
+ struct socket **sockp)
+{
+ return 0;
+}
+#endif
+
+static inline int udp_sock_create(struct net *net,
+ struct udp_port_cfg *cfg,
+ struct socket **sockp)
+{
+ if (cfg->family == AF_INET)
+ return udp_sock_create4(net, cfg, sockp);
+
+ if (cfg->family == AF_INET6)
+ return udp_sock_create6(net, cfg, sockp);
+
+ return -EPFNOSUPPORT;
+}
+
+typedef int (*udp_tunnel_encap_rcv_t)(struct sock *sk, struct sk_buff *skb);
+
+struct udp_tunnel_sock_cfg {
+ void *sk_user_data;
+ __u8 encap_type;
+ udp_tunnel_encap_rcv_t encap_rcv;
+};
+
+/* Setup the given (UDP) sock to receive UDP encapsulated packets */
+void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+ struct udp_tunnel_sock_cfg *sock_cfg);
+
+/* Transmit the skb using UDP encapsulation. */
+void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
+ __be32 src, __be32 dst, __u8 tos, __u8 ttl,
+ __be16 df, __be16 src_port, __be16 dst_port,
+ bool xnet, bool nocheck);
+
+#if IS_ENABLED(CONFIG_IPV6)
+int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
+ struct sk_buff *skb,
+ struct net_device *dev, struct in6_addr *saddr,
+ struct in6_addr *daddr,
+ __u8 prio, __u8 ttl, __be32 label,
+ __be16 src_port, __be16 dst_port, bool nocheck);
+#endif
+
+void udp_tunnel_sock_release(struct socket *sock);
+
+#endif
diff --git a/src/compat/udp_tunnel/udp_tunnel.c b/src/compat/udp_tunnel/udp_tunnel.c
new file mode 100644
index 0000000..35e54e0
--- /dev/null
+++ b/src/compat/udp_tunnel/udp_tunnel.c
@@ -0,0 +1,232 @@
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/socket.h>
+#include <linux/udp.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <net/net_namespace.h>
+#include <net/inet_common.h>
+#include <net/udp.h>
+#include <net/udp_tunnel.h>
+
+/* This is global so, uh, only one real call site... This is the kind of horrific hack you'd expect to see in compat code. */
+static udp_tunnel_encap_rcv_t encap_rcv = NULL;
+static void our_sk_data_ready(struct sock *sk)
+{
+ struct sk_buff *skb;
+ while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ skb_orphan(skb);
+ sk_mem_reclaim(sk);
+ encap_rcv(sk, skb);
+ }
+}
+
+int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
+ struct socket **sockp)
+{
+ int err;
+ struct socket *sock = NULL;
+ struct sockaddr_in udp_addr;
+
+ err = __sock_create(net, AF_INET, SOCK_DGRAM, 0, &sock, 1);
+ if (err < 0)
+ goto error;
+
+ udp_addr.sin_family = AF_INET;
+ udp_addr.sin_addr = cfg->local_ip;
+ udp_addr.sin_port = cfg->local_udp_port;
+ err = kernel_bind(sock, (struct sockaddr *)&udp_addr,
+ sizeof(udp_addr));
+ if (err < 0)
+ goto error;
+
+ if (cfg->peer_udp_port) {
+ udp_addr.sin_family = AF_INET;
+ udp_addr.sin_addr = cfg->peer_ip;
+ udp_addr.sin_port = cfg->peer_udp_port;
+ err = kernel_connect(sock, (struct sockaddr *)&udp_addr,
+ sizeof(udp_addr), 0);
+ if (err < 0)
+ goto error;
+ }
+
+ sock->sk->sk_no_check_tx = !cfg->use_udp_checksums;
+
+ *sockp = sock;
+ return 0;
+
+error:
+ if (sock) {
+ kernel_sock_shutdown(sock, SHUT_RDWR);
+ sock_release(sock);
+ }
+ *sockp = NULL;
+ return err;
+}
+EXPORT_SYMBOL(udp_sock_create4);
+
+void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+ struct udp_tunnel_sock_cfg *cfg)
+{
+ inet_sk(sock->sk)->mc_loop = 0;
+ encap_rcv = cfg->encap_rcv;
+ rcu_assign_sk_user_data(sock->sk, cfg->sk_user_data);
+ sock->sk->sk_data_ready = our_sk_data_ready;
+}
+EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
+
+static void fake_destructor(struct sk_buff *skb)
+{
+}
+
+void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
+ __be32 src, __be32 dst, __u8 tos, __u8 ttl,
+ __be16 df, __be16 src_port, __be16 dst_port,
+ bool xnet, bool nocheck)
+{
+ struct udphdr *uh;
+
+ __skb_push(skb, sizeof(*uh));
+ skb_reset_transport_header(skb);
+ uh = udp_hdr(skb);
+
+ uh->dest = dst_port;
+ uh->source = src_port;
+ uh->len = htons(skb->len);
+
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+
+ udp_set_csum(nocheck, skb, src, dst, skb->len);
+
+ if (!skb->sk) {
+ skb->sk = sk;
+ skb->destructor = fake_destructor;
+ }
+
+ iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, xnet);
+}
+EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
+
+void udp_tunnel_sock_release(struct socket *sock)
+{
+ rcu_assign_sk_user_data(sock->sk, NULL);
+ kernel_sock_shutdown(sock, SHUT_RDWR);
+ sock_release(sock);
+}
+EXPORT_SYMBOL_GPL(udp_tunnel_sock_release);
+
+#if IS_ENABLED(CONFIG_IPV6)
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/socket.h>
+#include <linux/udp.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/in6.h>
+#include <net/udp.h>
+#include <net/udp_tunnel.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+#include <net/ip6_tunnel.h>
+#include <net/ip6_checksum.h>
+
+int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
+ struct socket **sockp)
+{
+ struct sockaddr_in6 udp6_addr;
+ int err;
+ struct socket *sock = NULL;
+
+ err = __sock_create(net, AF_INET6, SOCK_DGRAM, 0, &sock, 1);
+ if (err < 0)
+ goto error;
+
+ if (cfg->ipv6_v6only) {
+ int val = 1;
+
+ err = kernel_setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+ (char *) &val, sizeof(val));
+ if (err < 0)
+ goto error;
+ }
+
+ udp6_addr.sin6_family = AF_INET6;
+ memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
+ sizeof(udp6_addr.sin6_addr));
+ udp6_addr.sin6_port = cfg->local_udp_port;
+ err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
+ sizeof(udp6_addr));
+ if (err < 0)
+ goto error;
+
+ if (cfg->peer_udp_port) {
+ udp6_addr.sin6_family = AF_INET6;
+ memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6,
+ sizeof(udp6_addr.sin6_addr));
+ udp6_addr.sin6_port = cfg->peer_udp_port;
+ err = kernel_connect(sock,
+ (struct sockaddr *)&udp6_addr,
+ sizeof(udp6_addr), 0);
+ }
+ if (err < 0)
+ goto error;
+
+ udp_set_no_check6_tx(sock->sk, !cfg->use_udp6_tx_checksums);
+ udp_set_no_check6_rx(sock->sk, !cfg->use_udp6_rx_checksums);
+
+ *sockp = sock;
+ return 0;
+
+error:
+ if (sock) {
+ kernel_sock_shutdown(sock, SHUT_RDWR);
+ sock_release(sock);
+ }
+ *sockp = NULL;
+ return err;
+}
+EXPORT_SYMBOL_GPL(udp_sock_create6);
+
+int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
+ struct sk_buff *skb,
+ struct net_device *dev, struct in6_addr *saddr,
+ struct in6_addr *daddr,
+ __u8 prio, __u8 ttl, __be32 label,
+ __be16 src_port, __be16 dst_port, bool nocheck)
+{
+ struct udphdr *uh;
+ struct ipv6hdr *ip6h;
+
+ __skb_push(skb, sizeof(*uh));
+ skb_reset_transport_header(skb);
+ uh = udp_hdr(skb);
+
+ uh->dest = dst_port;
+ uh->source = src_port;
+
+ uh->len = htons(skb->len);
+
+ skb_dst_set(skb, dst);
+
+ udp6_set_csum(nocheck, skb, saddr, daddr, skb->len);
+
+ __skb_push(skb, sizeof(*ip6h));
+ skb_reset_network_header(skb);
+ ip6h = ipv6_hdr(skb);
+ ip6_flow_hdr(ip6h, prio, label);
+ ip6h->payload_len = htons(skb->len);
+ ip6h->nexthdr = IPPROTO_UDP;
+ ip6h->hop_limit = ttl;
+ ip6h->daddr = *daddr;
+ ip6h->saddr = *saddr;
+
+ if (!skb->sk) {
+ skb->sk = sk;
+ skb->destructor = fake_destructor;
+ }
+
+ ip6tunnel_xmit(skb, dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
+#endif
diff --git a/src/compat/udp_tunnel/udp_tunnel_partial_compat.h b/src/compat/udp_tunnel/udp_tunnel_partial_compat.h
new file mode 100644
index 0000000..53ee6c3
--- /dev/null
+++ b/src/compat/udp_tunnel/udp_tunnel_partial_compat.h
@@ -0,0 +1,215 @@
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
+#define udp_sock_create4 udp_sock_create
+#define udp_sock_create6 udp_sock_create
+#include <linux/socket.h>
+#include <linux/if.h>
+#include <linux/in.h>
+#include <net/ip_tunnels.h>
+#include <net/udp.h>
+#include <net/inet_common.h>
+#if IS_ENABLED(CONFIG_IPV6)
+#include <linux/in6.h>
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#include <net/ip6_checksum.h>
+#include <net/ip6_tunnel.h>
+#endif
+static inline void fake_destructor(struct sk_buff *skb)
+{
+}
+typedef int (*udp_tunnel_encap_rcv_t)(struct sock *sk, struct sk_buff *skb);
+struct udp_tunnel_sock_cfg {
+ void *sk_user_data;
+ __u8 encap_type;
+ udp_tunnel_encap_rcv_t encap_rcv;
+};
+/* This is global so, uh, only one real call site... This is the kind of horrific hack you'd expect to see in compat code. */
+static udp_tunnel_encap_rcv_t encap_rcv = NULL;
+static void our_sk_data_ready(struct sock *sk)
+{
+ struct sk_buff *skb;
+ while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ skb_orphan(skb);
+ sk_mem_reclaim(sk);
+ encap_rcv(sk, skb);
+ }
+}
+static inline void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+ struct udp_tunnel_sock_cfg *cfg)
+{
+ struct sock *sk = sock->sk;
+ inet_sk(sk)->mc_loop = 0;
+ encap_rcv = cfg->encap_rcv;
+ rcu_assign_sk_user_data(sk, cfg->sk_user_data);
+ sk->sk_data_ready = our_sk_data_ready;
+}
+static inline void udp_tunnel_sock_release(struct socket *sock)
+{
+ rcu_assign_sk_user_data(sock->sk, NULL);
+ kernel_sock_shutdown(sock, SHUT_RDWR);
+ sk_release_kernel(sock->sk);
+}
+static inline int udp_tunnel_xmit_skb(struct socket *sock, struct rtable *rt,
+ struct sk_buff *skb, __be32 src, __be32 dst,
+ __u8 tos, __u8 ttl, __be16 df, __be16 src_port,
+ __be16 dst_port, bool xnet)
+{
+ struct udphdr *uh;
+ __skb_push(skb, sizeof(*uh));
+ skb_reset_transport_header(skb);
+ uh = udp_hdr(skb);
+ uh->dest = dst_port;
+ uh->source = src_port;
+ uh->len = htons(skb->len);
+ udp_set_csum(sock->sk->sk_no_check_tx, skb, src, dst, skb->len);
+ return iptunnel_xmit(sock->sk, rt, skb, src, dst, IPPROTO_UDP,
+ tos, ttl, df, xnet);
+}
+#if IS_ENABLED(CONFIG_IPV6)
+static inline int udp_tunnel6_xmit_skb(struct socket *sock, struct dst_entry *dst,
+ struct sk_buff *skb, struct net_device *dev,
+ struct in6_addr *saddr, struct in6_addr *daddr,
+ __u8 prio, __u8 ttl, __be16 src_port,
+ __be16 dst_port)
+{
+ struct udphdr *uh;
+ struct ipv6hdr *ip6h;
+ struct sock *sk = sock->sk;
+ __skb_push(skb, sizeof(*uh));
+ skb_reset_transport_header(skb);
+ uh = udp_hdr(skb);
+ uh->dest = dst_port;
+ uh->source = src_port;
+ uh->len = htons(skb->len);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED
+ | IPSKB_REROUTED);
+ skb_dst_set(skb, dst);
+ udp6_set_csum(udp_get_no_check6_tx(sk), skb, &inet6_sk(sk)->saddr,
+ &sk->sk_v6_daddr, skb->len);
+ __skb_push(skb, sizeof(*ip6h));
+ skb_reset_network_header(skb);
+ ip6h = ipv6_hdr(skb);
+ ip6_flow_hdr(ip6h, prio, htonl(0));
+ ip6h->payload_len = htons(skb->len);
+ ip6h->nexthdr = IPPROTO_UDP;
+ ip6h->hop_limit = ttl;
+ ip6h->daddr = *daddr;
+ ip6h->saddr = *saddr;
+ ip6tunnel_xmit(skb, dev);
+ return 0;
+}
+#endif
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/udp.h>
+#include <linux/skbuff.h>
+#include <linux/if.h>
+#include <net/udp_tunnel.h>
+#define udp_tunnel_xmit_skb(a, b, c, d, e, f, g, h, i, j, k, l) do { struct net_device *dev__ = (c)->dev; int ret__; ret__ = udp_tunnel_xmit_skb((b)->sk_socket, a, c, d, e, f, g, h, i, j, k); iptunnel_xmit_stats(ret__, &dev__->stats, dev__->tstats); } while (0)
+#if IS_ENABLED(CONFIG_IPV6)
+#define udp_tunnel6_xmit_skb(a, b, c, d, e, f, g, h, i, j, k, l) udp_tunnel6_xmit_skb((b)->sk_socket, a, c, d, e, f, g, h, j, k);
+#endif
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+#include <linux/if.h>
+#include <net/udp_tunnel.h>
+#if LINUX_VERISON_CODE >= KERNEL_VERSION(3, 18, 0)
+static inline void fake_destructor(struct sk_buff *skb)
+{
+}
+#endif
+#define udp_tunnel_xmit_skb(a, b, c, d, e, f, g, h, i, j, k, l) do { struct net_device *dev__ = (c)->dev; int ret__; (c)->destructor = fake_destructor; (c)->sk = (b); ret__ = udp_tunnel_xmit_skb(a, c, d, e, f, g, h, i, j, k, l); iptunnel_xmit_stats(ret__, &dev__->stats, dev__->tstats); } while (0)
+#if IS_ENABLED(CONFIG_IPV6)
+#define udp_tunnel6_xmit_skb(a, b, c, d, e, f, g, h, i, j, k, l) do { (c)->destructor = fake_destructor; (c)->sk = (b); udp_tunnel6_xmit_skb(a, c, d, e, f, g, h, j, k, l); } while(0)
+#endif
+#else
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+#include <linux/if.h>
+#include <net/udp_tunnel.h>
+#define udp_tunnel_xmit_skb(a, b, c, d, e, f, g, h, i, j, k, l) do { struct net_device *dev__ = (c)->dev; int ret__ = udp_tunnel_xmit_skb(a, b, c, d, e, f, g, h, i, j, k, l); iptunnel_xmit_stats(ret__, &dev__->stats, dev__->tstats); } while (0)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) && IS_ENABLED(CONFIG_IPV6) && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+#include <linux/if.h>
+#include <net/udp_tunnel.h>
+#define udp_tunnel6_xmit_skb(a, b, c, d, e, f, g, h, i, j, k, l) udp_tunnel6_xmit_skb(a, b, c, d, e, f, g, h, j, k, l)
+#endif
+
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+#include <linux/skbuff.h>
+#include <linux/if.h>
+#include <net/udp_tunnel.h>
+struct udp_port_cfg_new {
+ u8 family;
+ union {
+ struct in_addr local_ip;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr local_ip6;
+#endif
+ };
+ union {
+ struct in_addr peer_ip;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr peer_ip6;
+#endif
+ };
+ __be16 local_udp_port;
+ __be16 peer_udp_port;
+ unsigned int use_udp_checksums:1, use_udp6_tx_checksums:1, use_udp6_rx_checksums:1, ipv6_v6only:1;
+};
+static inline int __maybe_unused udp_sock_create_new(struct net *net, struct udp_port_cfg_new *cfg, struct socket **sockp)
+{
+ struct udp_port_cfg old_cfg = {
+ .family = cfg->family,
+ .local_ip = cfg->local_ip,
+#if IS_ENABLED(CONFIG_IPV6)
+ .local_ip6 = cfg->local_ip6,
+#endif
+ .peer_ip = cfg->peer_ip,
+#if IS_ENABLED(CONFIG_IPV6)
+ .peer_ip6 = cfg->peer_ip6,
+#endif
+ .local_udp_port = cfg->local_udp_port,
+ .peer_udp_port = cfg->peer_udp_port,
+ .use_udp_checksums = cfg->use_udp_checksums,
+ .use_udp6_tx_checksums = cfg->use_udp6_tx_checksums,
+ .use_udp6_rx_checksums = cfg->use_udp6_rx_checksums
+ };
+ if (cfg->family == AF_INET)
+ return udp_sock_create4(net, &old_cfg, sockp);
+
+#if IS_ENABLED(CONFIG_IPV6)
+ if (cfg->family == AF_INET6) {
+ int ret;
+ int old_bindv6only;
+ struct net *nobns;
+
+ if (cfg->ipv6_v6only) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
+ nobns = &init_net;
+#else
+ nobns = net;
+#endif
+ /* Since udp_port_cfg only learned of ipv6_v6only in 4.3, we do this horrible
+ * hack here and set the sysctl variable temporarily to something that will
+ * set the right option for us in sock_create. It's super racey! */
+ old_bindv6only = nobns->ipv6.sysctl.bindv6only;
+ nobns->ipv6.sysctl.bindv6only = 1;
+ }
+ ret = udp_sock_create6(net, &old_cfg, sockp);
+ if (cfg->ipv6_v6only)
+ nobns->ipv6.sysctl.bindv6only = old_bindv6only;
+ return ret;
+ }
+#endif
+ return -EPFNOSUPPORT;
+}
+#define udp_port_cfg udp_port_cfg_new
+#define udp_sock_create(a, b, c) udp_sock_create_new(a, b, c)
+#endif