From 2c251d845c759278e7653a4a53df1beb75f536c6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 17 Jan 2015 07:42:09 -0600 Subject: [PATCH] include/net/if.h: Add a bit to the device flags to indicate if the device packet buffer holds an IPv4 or an IPv6 domain packet. Set/clear the flag along with the correct offset to the application payload data as each packet is received. net/socket, net/tcp, net/udp: Add logic to select the domain of the outputgoing packet before sending any UDP or TCP packet. This sets the bit to indicate the IPv4 or IPv6 domain and the correct offset to the output going payload data. --- include/net/if.h | 41 +++++++++++++--- net/devif/devif.h | 16 ++++++- net/socket/sendto.c | 89 +++++++++++++++++++++++++++++++---- net/tcp/Make.defs | 2 +- net/tcp/tcp.h | 25 ++++++++++ net/tcp/tcp_input.c | 16 +++++-- net/tcp/tcp_poll.c | 4 +- net/tcp/tcp_send_buffered.c | 59 +++++++++++++++++++++++ net/tcp/tcp_send_unbuffered.c | 64 ++++++++++++++++++++++++- net/udp/Make.defs | 1 + net/udp/udp.h | 35 ++++++++++++-- net/udp/udp_input.c | 12 +++++ net/udp/udp_poll.c | 4 +- 13 files changed, 337 insertions(+), 31 deletions(-) diff --git a/include/net/if.h b/include/net/if.h index b4ca28eb88..56e778048b 100644 --- a/include/net/if.h +++ b/include/net/if.h @@ -48,14 +48,41 @@ /* Sizing parameters */ -#define IFNAMSIZ 6 /* Older naming standard */ -#define IF_NAMESIZE 6 /* Newer naming standard */ -#define IFHWADDRLEN 6 +#define IFNAMSIZ 6 /* Older naming standard */ +#define IF_NAMESIZE 6 /* Newer naming standard */ +#define IFHWADDRLEN 6 -#define IFF_DOWN (1 << 0) -#define IFF_UP (1 << 1) -#define IFF_RUNNING (1 << 2) -#define IFF_NOARP (1 << 7) +/* Interface flag bits */ + +#define IFF_DOWN (1 << 0) /* Interface is down */ +#define IFF_UP (1 << 1) /* Interface is up */ +#define IFF_RUNNING (1 << 2) /* Carrier is available */ +#define IFF_IPv6 (1 << 3) /* Configured for IPv6 packet (vs ARP or IPv4) */ +#define IFF_NOARP (1 << 7) /* ARP is not required for this packet */ + +/* Interface flag helpers */ + +#define IFF_SET_DOWN(f) do { (f) |= IFF_DOWN; } while (0) +#define IFF_SET_UP(f) do { (f) |= IFF_UP; } while (0) +#define IFF_SET_RUNNING(f) do { (f) |= IFF_RUNNING; } while (0) +#define IFF_SET_IPv6(f) do { (f) |= IFF_IPv6; } while (0) +#define IFF_SET_NOARP(f) do { (f) |= IFF_NOARP; } while (0) + +#define IFF_CLR_DOWN(f) do { (f) &= ~IFF_DOWN; } while (0) +#define IFF_CLR_UP(f) do { (f) &= ~IFF_UP; } while (0) +#define IFF_CLR_RUNNING(f) do { (f) &= ~IFF_RUNNING; } while (0) +#define IFF_CLR_IPv6(f) do { (f) &= ~IFF_IPv6; } while (0) +#define IFF_CLR_NOARP(f) do { (f) &= ~IFF_NOARP; } while (0) + +#define IFF_IS_DOWN(f) ((f) & IFF_DOWN) != 0) +#define IFF_IS_UP(f) ((f) & IFF_UP) != 0) +#define IFF_IS_RUNNING(f) ((f) & IFF_RUNNING) != 0) +#define IFF_IS_IPv6(f) ((f) & IFF_IPv6) != 0) +#define IFF_IS_NOARP(f) ((f) & IFF_NOARP) != 0) + +#define IFF_SET_IPv4(f) IFF_CLR_IPv6(f) +#define IFF_CLR_IPv4(f) IFF_SET_IPv6(f) +#define IFF_IS_IPv4(f) (!IFF_IS_IPv6(f)) /******************************************************************************************* * Public Type Definitions diff --git a/net/devif/devif.h b/net/devif/devif.h index 58b43887e0..270b4b0f65 100644 --- a/net/devif/devif.h +++ b/net/devif/devif.h @@ -1,7 +1,7 @@ /**************************************************************************** * net/devif/devif.h * - * Copyright (C) 2007-2009, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * This logic was leveraged from uIP which also has a BSD-style license: @@ -135,6 +135,20 @@ #define TCP_CONN_EVENTS (TCP_CLOSE | TCP_ABORT | TCP_CONNECTED | TCP_TIMEDOUT) +/* IPv4/IPv6 Helpers */ + +#ifdef CONFIG_NET_IPv4 +# define DEVIF_IS_IPv4(dev) IFF_IS_IPv4(dev->d_flags) +#else +# define DEVIF_IS_IPv4(dev) (0) +#endif + +#ifdef CONFIG_NET_IPv6 +# define DEVIF_IS_IPv6(dev) IFF_IS_IPv6(dev->d_flags) +#else +# define DEVIF_IS_IPv6(dev) (0) +#endif + /**************************************************************************** * Public Type Definitions ****************************************************************************/ diff --git a/net/socket/sendto.c b/net/socket/sendto.c index 1bd9495cf7..c8e40c2ef8 100644 --- a/net/socket/sendto.c +++ b/net/socket/sendto.c @@ -62,6 +62,14 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* If both IPv4 and IPv6 support are both enabled, then we will need to build + * in some additional domain selection support. + */ + +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) +# define NEED_IPDOMAIN_SUPPORT 1 +#endif + /* Timeouts on sendto() do not make sense. Each polling cycle from the * driver is an opportunity to send a packet. If the driver is not polling, * then the network is not up (and there are no polling cycles to drive @@ -88,8 +96,10 @@ struct sendto_s { -#ifdef CONFIG_NET_SENDTO_TIMEOUT +#if defined(CONFIG_NET_SENDTO_TIMEOUT) || defined(NEED_IPDOMAIN_SUPPORT) FAR struct socket *st_sock; /* Points to the parent socket structure */ +#endif +#ifdef CONFIG_NET_SENDTO_TIMEOUT uint32_t st_time; /* Last send time for determining timeout */ #endif FAR struct devif_callback_s *st_cb; /* Reference to callback instance */ @@ -110,7 +120,7 @@ struct sendto_s * Check for send timeout. * * Parameters: - * pstate send state structure + * pstate - sendto state structure * * Returned Value: * TRUE:timeout FALSE:no timeout @@ -123,7 +133,7 @@ struct sendto_s #ifdef CONFIG_NET_SENDTO_TIMEOUT static inline int send_timeout(FAR struct sendto_s *pstate) { - FAR struct socket *psock = 0; + FAR struct socket *psock; /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). * If none... we well let the send wait forever. @@ -143,6 +153,52 @@ static inline int send_timeout(FAR struct sendto_s *pstate) } #endif /* CONFIG_NET_SENDTO_TIMEOUT */ +/**************************************************************************** + * Function: sendto_ipselect + * + * Description: + * If both IPv4 and IPv6 support are enabled, then we will need to select + * which one to use when generating the outgoing packet. If only one + * domain is selected, then the setup is already in place and we need do + * nothing. + * + * Parameters: + * dev - The structure of the network driver that caused the interrupt + * pstate - sendto state structure + * + * Returned Value: + * None + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ + +#ifdef NEED_IPDOMAIN_SUPPORT +static inline void sendto_ipselect(FAR struct net_driver_s *dev, + FAR struct sendto_s *pstate) +{ + FAR struct socket *psock = pstate->st_sock; + DEBUGASSERT(psock); + + /* Which domain the the socket support */ + + if (psock->domain == PF_INET) + { + /* Select the IPv4 domain */ + + udp_ipv4_select(dev); + } + else /* if (psock->domain == PF_INET6) */ + { + /* Select the IPv6 domain */ + + DEBUGASSERT(psock->domain == PF_INET6); + udp_ipv4_select(dev); + } +} +#endif + /**************************************************************************** * Function: sendto_interrupt * @@ -151,7 +207,7 @@ static inline int send_timeout(FAR struct sendto_s *pstate) * send operation when polled by the lower, device interfacing layer. * * Parameters: - * dev The sructure of the network driver that caused the interrupt + * dev The structure of the network driver that caused the interrupt * conn An instance of the UDP connection structure cast to void * * pvpriv An instance of struct sendto_s cast to void* * flags Set of events describing why the callback was invoked @@ -165,8 +221,8 @@ static inline int send_timeout(FAR struct sendto_s *pstate) ****************************************************************************/ #ifdef CONFIG_NET_UDP -static uint16_t sendto_interrupt(struct net_driver_s *dev, void *conn, - void *pvpriv, uint16_t flags) +static uint16_t sendto_interrupt(FAR struct net_driver_s *dev, FAR void *conn, + FAR void *pvpriv, uint16_t flags) { FAR struct sendto_s *pstate = (FAR struct sendto_s *)pvpriv; @@ -207,6 +263,16 @@ static uint16_t sendto_interrupt(struct net_driver_s *dev, void *conn, else { +#ifdef NEED_IPDOMAIN_SUPPORT + /* If both IPv4 and IPv6 support are enabled, then we will need to + * select which one to use when generating the outgoing packet. + * If only one domain is selected, then the setup is already in + * place and we need do nothing. + */ + + sendto_ipselect(dev, pstate); +#endif + /* Copy the user data into d_appdata and send it */ devif_send(dev, pstate->st_buffer, pstate->st_buflen); @@ -390,10 +456,17 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf, state.st_buflen = len; state.st_buffer = buf; - /* Set the initial time for calculating timeouts */ +#if defined(CONFIG_NET_SENDTO_TIMEOUT) || defined(NEED_IPDOMAIN_SUPPORT) + /* Save the reference to the socket structure if it will be needed for + * asynchronous processing. + */ + + state.st_sock = psock; +#endif #ifdef CONFIG_NET_SENDTO_TIMEOUT - state.st_sock = psock; + /* Set the initial time for calculating timeouts */ + state.st_time = clock_systimer(); #endif diff --git a/net/tcp/Make.defs b/net/tcp/Make.defs index 6870539f33..d213960b7c 100644 --- a/net/tcp/Make.defs +++ b/net/tcp/Make.defs @@ -49,7 +49,7 @@ endif NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_poll.c tcp_timer.c tcp_send.c NET_CSRCS += tcp_input.c tcp_appsend.c tcp_listen.c tcp_callback.c -NET_CSRCS += tcp_backlog.c +NET_CSRCS += tcp_backlog.c tcp_ipselect.c # TCP write buffering diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 8f8e857348..e5469d60fe 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -398,6 +398,31 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr_in *addr); #endif +/* Defined in tcp_ipselect.c ************************************************/ +/**************************************************************************** + * Function: tcp_ipv4_select + * + * Description: + * Configure to send or receive an TCP IPv4 packet + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +void tcp_ipv4_select(FAR struct net_driver_s *dev); +#endif + +/**************************************************************************** + * Function: tcp_ipv6_select + * + * Description: + * Configure to send or receive an TCP IPv6 packet + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +void tcp_ipv6_select(FAR struct net_driver_s *dev); +#endif + /* Defined in tcp_seqno.c ***************************************************/ /**************************************************************************** * Name: tcp_setsequence diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index f382e2cc80..29c678763b 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -128,10 +128,6 @@ static void tcp_input(FAR struct net_driver_s *dev, unsigned int iplen) hdrlen = tcpiplen + NET_LL_HDRLEN(dev); - /* Initialize for tcp_send() */ - - dev->d_appdata = &dev->d_buf[hdrlen]; - /* Start of TCP input header processing code. */ if (tcp_chksum(dev) != 0xffff) @@ -886,6 +882,12 @@ drop: #ifdef CONFIG_NET_IPv4 void tcp_ipv4_input(FAR struct net_driver_s *dev) { + /* Configure to receive an TCP IPv4 packet */ + + tcp_ipv4_select(dev); + + /* Then process in the TCP IPv4 input */ + tcp_input(dev, IPv4_HDRLEN); } #endif @@ -910,6 +912,12 @@ void tcp_ipv4_input(FAR struct net_driver_s *dev) #ifdef CONFIG_NET_IPv6 void tcp_ipv6_input(FAR struct net_driver_s *dev) { + /* Configure to receive an TCP IPv6 packet */ + + tcp_ipv6_select(dev); + + /* Then process in the TCP IPv6 input */ + tcp_input(dev, IPv6_HDRLEN); } #endif diff --git a/net/tcp/tcp_poll.c b/net/tcp/tcp_poll.c index 637ac99ac2..e5e99cabef 100644 --- a/net/tcp/tcp_poll.c +++ b/net/tcp/tcp_poll.c @@ -107,9 +107,9 @@ void tcp_poll(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn) */ #if defined(CONFIG_NET_IPv4) - dev->d_appdata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)]; + tcp_ipv4_select(dev); #else /* if defined(CONFIG_NET_IPv6) */ - dev->d_appdata = &dev->d_buf[IPv6TCP_HDRLEN + NET_LL_HDRLEN(dev)]; + tcp_ipv6_select(dev); #endif dev->d_len = 0; diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index fdf875cc0c..4efae569f3 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -78,6 +78,13 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* If both IPv4 and IPv6 support are both enabled, then we will need to build + * in some additional domain selection support. + */ + +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) +# define NEED_IPDOMAIN_SUPPORT 1 +#endif #if defined(CONFIG_NET_IPv4) # define TCPBUF ((struct tcp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) @@ -199,6 +206,49 @@ static inline void psock_lost_connection(FAR struct socket *psock, conn->sent = 0; } +/**************************************************************************** + * Function: send_ipselect + * + * Description: + * If both IPv4 and IPv6 support are enabled, then we will need to select + * which one to use when generating the outgoing packet. If only one + * domain is selected, then the setup is already in place and we need do + * nothing. + * + * Parameters: + * dev - The structure of the network driver that caused the interrupt + * psock - Socket state structure + * + * Returned Value: + * None + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ + +#ifdef NEED_IPDOMAIN_SUPPORT +static inline void send_ipselect(FAR struct net_driver_s *dev, + FAR struct socket *psock) +{ + /* Which domain the the socket support */ + + if (psock->domain == PF_INET) + { + /* Select the IPv4 domain */ + + tcp_ipv4_select(dev); + } + else /* if (psock->domain == PF_INET6) */ + { + /* Select the IPv6 domain */ + + DEBUGASSERT(psock->domain == PF_INET6); + tcp_ipv4_select(dev); + } +} +#endif + /**************************************************************************** * Function: psock_send_interrupt * @@ -605,6 +655,15 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, tcp_setsequence(conn->sndseq, WRB_SEQNO(wrb) + WRB_SENT(wrb)); +#ifdef NEED_IPDOMAIN_SUPPORT + /* If both IPv4 and IPv6 support are enabled, then we will need to + * select which one to use when generating the outgoing packet. + * If only one domain is selected, then the setup is already in + * place and we need do nothing. + */ + + send_ipselect(dev, psock); +#endif /* Then set-up to send that amount of data with the offset * corresponding to the amount of data already sent. (this * won't actually happen until the polling cycle completes). diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 5649d3aa16..decd83a4e6 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -66,6 +66,13 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* If both IPv4 and IPv6 support are both enabled, then we will need to build + * in some additional domain selection support. + */ + +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) +# define NEED_IPDOMAIN_SUPPORT 1 +#endif #if defined(CONFIG_NET_TCP_SPLIT) && !defined(CONFIG_NET_TCP_SPLIT_SIZE) # define CONFIG_NET_TCP_SPLIT_SIZE 40 @@ -123,7 +130,7 @@ struct send_s #ifdef CONFIG_NET_SOCKOPTS static inline int send_timeout(FAR struct send_s *pstate) { - FAR struct socket *psock = 0; + FAR struct socket *psock; /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). * If none... we well let the send wait forever. @@ -143,6 +150,52 @@ static inline int send_timeout(FAR struct send_s *pstate) } #endif /* CONFIG_NET_SOCKOPTS */ +/**************************************************************************** + * Function: tcpsend_ipselect + * + * Description: + * If both IPv4 and IPv6 support are enabled, then we will need to select + * which one to use when generating the outgoing packet. If only one + * domain is selected, then the setup is already in place and we need do + * nothing. + * + * Parameters: + * dev - The structure of the network driver that caused the interrupt + * pstate - sendto state structure + * + * Returned Value: + * None + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ + +#ifdef NEED_IPDOMAIN_SUPPORT +static inline void tcpsend_ipselect(FAR struct net_driver_s *dev, + FAR struct send_s *pstate) +{ + FAR struct socket *psock = pstate->snd_sock; + DEBUGASSERT(psock); + + /* Which domain the the socket support */ + + if (psock->domain == PF_INET) + { + /* Select the IPv4 domain */ + + tcp_ipv4_select(dev); + } + else /* if (psock->domain == PF_INET6) */ + { + /* Select the IPv6 domain */ + + DEBUGASSERT(psock->domain == PF_INET6); + tcp_ipv4_select(dev); + } +} +#endif + /**************************************************************************** * Function: tcpsend_interrupt * @@ -373,6 +426,15 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, nllvdbg("SEND: sndseq %08x->%08x\n", conn->sndseq, seqno); tcp_setsequence(conn->sndseq, seqno); +#ifdef NEED_IPDOMAIN_SUPPORT + /* If both IPv4 and IPv6 support are enabled, then we will need to + * select which one to use when generating the outgoing packet. + * If only one domain is selected, then the setup is already in + * place and we need do nothing. + */ + + tcpsend_ipselect(dev, pstate); +#endif /* Then set-up to send that amount of data. (this won't actually * happen until the polling cycle completes). */ diff --git a/net/udp/Make.defs b/net/udp/Make.defs index d071638416..e0714ce30d 100644 --- a/net/udp/Make.defs +++ b/net/udp/Make.defs @@ -38,6 +38,7 @@ ifeq ($(CONFIG_NET_UDP),y) NET_CSRCS += udp_conn.c udp_poll.c udp_send.c udp_input.c udp_callback.c +NET_CSRCS += udp_ipselect.c # Include UDP build support diff --git a/net/udp/udp.h b/net/udp/udp.h index fd60b7ca8e..cf6948a839 100644 --- a/net/udp/udp.h +++ b/net/udp/udp.h @@ -1,7 +1,7 @@ /**************************************************************************** * net/udp/udp.h * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ * Pre-processor Definitions ****************************************************************************/ -/* Allocate a new TCP data callback */ +/* Allocate a new UDP data callback */ #define udp_callback_alloc(conn) devif_callback_alloc(&conn->list) #define udp_callback_free(conn,cb) devif_callback_free(cb, &conn->list) @@ -136,7 +136,7 @@ void udp_free(FAR struct udp_conn_s *conn); * * Description: * Find a connection structure that is the appropriate - * connection to be used within the provided TCP/IP header + * connection to be used within the provided UDP/IP header * * Assumptions: * Called from network stack logic with the network stack locked @@ -163,8 +163,8 @@ FAR struct udp_conn_s *udp_nextconn(FAR struct udp_conn_s *conn); * Name: udp_bind() * * Description: - * This function implements the UIP specific parts of the standard UDP - * bind() operation. + * This function implements the low-level parts of the standard UDP bind() + * operation. * * Assumptions: * This function is called from normal user level code. @@ -207,6 +207,31 @@ int udp_connect(FAR struct udp_conn_s *conn, FAR const struct sockaddr_in *addr); #endif +/* Defined in udp_ipselect.c ************************************************/ +/**************************************************************************** + * Function: udp_ipv4_select + * + * Description: + * Configure to send or receive an UDP IPv4 packet + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +void udp_ipv4_select(FAR struct net_driver_s *dev); +#endif + +/**************************************************************************** + * Function: udp_ipv6_select + * + * Description: + * Configure to send or receive an UDP IPv6 packet + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +void udp_ipv6_select(FAR struct net_driver_s *dev); +#endif + /* Defined in udp_poll.c ****************************************************/ /**************************************************************************** * Name: udp_poll diff --git a/net/udp/udp_input.c b/net/udp/udp_input.c index d21d47e1b5..57e7d39d4e 100644 --- a/net/udp/udp_input.c +++ b/net/udp/udp_input.c @@ -229,6 +229,12 @@ static int udp_input(FAR struct net_driver_s *dev, unsigned int iplen) #ifdef CONFIG_NET_IPv4 int udp_ipv4_input(FAR struct net_driver_s *dev) { + /* Configure to receive an UDP IPv4 packet */ + + udp_ipv4_select(dev); + + /* Then process in the UDP IPv4 input */ + return udp_input(dev, IPv4_HDRLEN); } #endif @@ -255,6 +261,12 @@ int udp_ipv4_input(FAR struct net_driver_s *dev) #ifdef CONFIG_NET_IPv6 int udp_ipv6_input(FAR struct net_driver_s *dev) { + /* Configure to receive an UDP IPv6 packet */ + + udp_ipv6_select(dev); + + /* Then process in the UDP IPv6 input */ + return udp_input(dev, IPv6_HDRLEN); } #endif diff --git a/net/udp/udp_poll.c b/net/udp/udp_poll.c index a734cf93d6..b7112bd9ce 100644 --- a/net/udp/udp_poll.c +++ b/net/udp/udp_poll.c @@ -104,9 +104,9 @@ void udp_poll(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn) */ #if defined(CONFIG_NET_IPv4) - dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv4UDP_HDRLEN]; + udp_ipv4_select(dev); #else /* if defined(CONFIG_NET_IPv6) */ - dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPv6UDP_HDRLEN]; + udp_ipv6_select(dev); #endif dev->d_len = 0;