net: Support multiple IPv6 address per netdev

Note that user-space related code, like procfs and lifreq related ioctl commands, are not touched in this commit.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
Zhe Weng 2023-08-25 17:37:11 +08:00 committed by Xiang Xiao
parent 96233e0c42
commit 2b9633e652
31 changed files with 202 additions and 107 deletions

View File

@ -172,6 +172,13 @@
# ifndef CONFIG_NETDEV_MAX_IPv6_ADDR
# define CONFIG_NETDEV_MAX_IPv6_ADDR 1
# endif
# define NETDEV_HAS_V6ADDR(dev) \
(!net_ipv6addr_cmp(netdev_ipv6_srcaddr(dev, g_ipv6_unspecaddr), \
g_ipv6_unspecaddr))
# define NETDEV_IS_MY_V6ADDR(dev,addr) \
(netdev_ipv6_lookup(dev, addr, false) != NULL)
# define NETDEV_V6ADDR_ONLINK(dev,addr) \
(netdev_ipv6_lookup(dev, addr, true) != NULL)
#endif
/****************************************************************************

View File

@ -62,7 +62,7 @@ bool devif_is_loopback(FAR struct net_driver_s *dev)
#ifdef CONFIG_NET_IPv6
if ((IPv6BUF->vtc & IP_VERSION_MASK) == IPv6_VERSION &&
net_ipv6addr_hdrcmp(IPv6BUF->destipaddr, dev->d_ipv6addr))
NETDEV_IS_MY_V6ADDR(dev, IPv6BUF->destipaddr))
{
return true;
}

View File

@ -78,7 +78,7 @@ static int check_dev_destipaddr(FAR struct net_driver_s *dev, FAR void *arg)
* to this device.
*/
if (net_ipv6addr_cmp(ipv6->destipaddr, dev->d_ipv6addr))
if (NETDEV_IS_MY_V6ADDR(dev, ipv6->destipaddr))
{
return 1;
}
@ -389,7 +389,7 @@ static int ipv6_in(FAR struct net_driver_s *dev)
* (the all zero address is the "unspecified" address.
*/
if (net_ipv6addr_cmp(dev->d_ipv6addr, g_ipv6_unspecaddr))
if (!NETDEV_HAS_V6ADDR(dev))
{
nwarn("WARNING: No IP address assigned\n");
goto drop;

View File

@ -313,6 +313,7 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev);
****************************************************************************/
void icmpv6_advertise(FAR struct net_driver_s *dev,
const net_ipv6addr_t tgtaddr,
const net_ipv6addr_t destipaddr);
/****************************************************************************

View File

@ -65,6 +65,7 @@
****************************************************************************/
void icmpv6_advertise(FAR struct net_driver_s *dev,
const net_ipv6addr_t tgtaddr,
const net_ipv6addr_t destipaddr)
{
FAR struct icmpv6_neighbor_advertise_s *adv;
@ -77,7 +78,7 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
l3size = SIZEOF_ICMPV6_NEIGHBOR_ADVERTISE_S(lladdrsize);
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
dev->d_ipv6addr, destipaddr, 255, 0);
tgtaddr, destipaddr, 255, 0);
/* Set up the ICMPv6 Neighbor Advertise response */
@ -92,7 +93,7 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
/* Copy the target address into the Neighbor Advertisement message */
net_ipv6addr_copy(adv->tgtaddr, dev->d_ipv6addr);
net_ipv6addr_copy(adv->tgtaddr, tgtaddr);
/* Set up the options */

View File

@ -40,6 +40,7 @@
#include "netdev/netdev.h"
#include "inet/inet.h"
#include "icmpv6/icmpv6.h"
#include "utils/utils.h"
#ifdef CONFIG_NET_ICMPv6_AUTOCONF
@ -139,9 +140,11 @@ static uint16_t icmpv6_router_eventhandler(FAR struct net_driver_s *dev,
if (state->snd_advertise)
{
/* Send the ICMPv6 Neighbor Advertisement message */
/* Send the ICMPv6 Neighbor Advertisement message, we should
* already have link-local address by previous logic.
*/
icmpv6_advertise(dev, g_ipv6_allnodes);
icmpv6_advertise(dev, netdev_ipv6_lladdr(dev), g_ipv6_allnodes);
}
else
{
@ -311,6 +314,11 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
* will be derived from the link layer (MAC) address.
*/
if (netdev_ipv6_lladdr(dev) != NULL)
{
goto got_lladdr;
}
icmpv6_linkipaddr(dev, lladdr);
ninfo("lladdr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
@ -352,8 +360,13 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
* on the wider Internet (since link-local addresses are not routed).
*/
net_ipv6addr_copy(dev->d_ipv6addr, lladdr);
ret = netdev_ipv6_add(dev, lladdr, net_ipv6_mask2pref(g_ipv6_llnetmask));
if (ret < 0)
{
return ret;
}
got_lladdr:
/* 4. Router Contact: The node next attempts to contact a local router for
* more information on continuing the configuration. This is done either
* by listening for Router Advertisement messages sent periodically by
@ -416,10 +429,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
/* No off-link communications; No router address. */
net_ipv6addr_copy(dev->d_ipv6draddr, g_ipv6_unspecaddr);
/* Set a netmask for the local link address */
net_ipv6addr_copy(dev->d_ipv6netmask, g_ipv6_llnetmask);
}
/* 5. Router Direction: The router provides direction to the node on how

View File

@ -299,7 +299,7 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
/* Check if we are the target of the solicitation */
sol = ICMPv6SOLICIT;
if (net_ipv6addr_cmp(sol->tgtaddr, dev->d_ipv6addr))
if (NETDEV_IS_MY_V6ADDR(dev, sol->tgtaddr))
{
if (sol->opttype == ICMPv6_OPT_SRCLLADDR)
{
@ -312,7 +312,7 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
* solicitation came from.
*/
icmpv6_advertise(dev, ipv6->srcipaddr);
icmpv6_advertise(dev, sol->tgtaddr, ipv6->srcipaddr);
/* All statistics have been updated. Nothing to do but exit. */
@ -341,7 +341,7 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
*/
adv = ICMPv6ADVERTISE;
if (net_ipv6addr_cmp(ipv6->destipaddr, dev->d_ipv6addr))
if (NETDEV_IS_MY_V6ADDR(dev, ipv6->destipaddr))
{
/* This message is required to support the Target link-layer
* address option.
@ -544,7 +544,8 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
icmpv6->type = ICMPv6_ECHO_REPLY;
net_ipv6addr_copy(ipv6->destipaddr, ipv6->srcipaddr);
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
net_ipv6addr_copy(ipv6->srcipaddr,
netdev_ipv6_srcaddr(dev, ipv6->srcipaddr));
icmpv6->chksum = 0;
icmpv6->chksum = ~icmpv6_chksum(dev, iplen);

View File

@ -218,8 +218,7 @@ int icmpv6_neighbor(FAR struct net_driver_s *dev,
/* Check if the destination address is on the local network. */
if (net_ipv6addr_maskcmp(ipaddr, dev->d_ipv6addr, dev->d_ipv6netmask) ||
net_is_addr_linklocal(ipaddr))
if (NETDEV_V6ADDR_ONLINK(dev, ipaddr) || net_is_addr_linklocal(ipaddr))
{
/* Yes.. use the input address for the lookup */

View File

@ -170,6 +170,9 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
FAR struct icmpv6_srclladdr_s *srcaddr;
FAR struct icmpv6_mtu_s *mtu;
FAR struct icmpv6_prefixinfo_s *prefix;
#ifndef CONFIG_NET_ICMPv6_ROUTER_MANUAL
FAR const struct netdev_ifaddr6_s *ifaddr;
#endif
#ifdef CONFIG_NET_ICMPv6_ROUTER_RDNSS
FAR struct icmpv6_rdnss_s *rdnss;
struct rdnss_add_dns_nameserver_s rndss_context;
@ -183,12 +186,18 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
lladdrsize = netdev_lladdrsize(dev);
l3size = sizeof(struct icmpv6_router_advertise_s) +
SIZEOF_ICMPV6_SRCLLADDR_S(lladdrsize) +
sizeof(struct icmpv6_mtu_s) +
sizeof(struct icmpv6_prefixinfo_s);
sizeof(struct icmpv6_mtu_s);
/* Source IP address must be set to link-local IP */
icmpv6_linkipaddr(dev, srcv6addr);
if (netdev_ipv6_lladdr(dev) == NULL)
{
icmpv6_linkipaddr(dev, srcv6addr);
}
else
{
net_ipv6addr_copy(srcv6addr, netdev_ipv6_lladdr(dev));
}
/* Set up the ICMPv6 Router Advertise response */
@ -224,6 +233,16 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
mtu->mtu[0] = 0;
mtu->mtu[1] = HTONS(dev->d_pktsize - dev->d_llhdrlen);
#ifndef CONFIG_NET_ICMPv6_ROUTER_MANUAL
/* We only anounce a prefix when we have one. */
ifaddr = netdev_ipv6_srcifaddr(dev, g_ipv6_unspecaddr);
if (net_ipv6addr_cmp(ifaddr->addr, g_ipv6_unspecaddr))
{
goto skip_prefix;
}
#endif
/* Set up the prefix option */
prefix = (FAR struct icmpv6_prefixinfo_s *)
@ -238,6 +257,8 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
prefix->reserved[0] = 0;
prefix->reserved[1] = 0;
l3size += sizeof(struct icmpv6_prefixinfo_s);
#ifdef CONFIG_NET_ICMPv6_ROUTER_MANUAL
/* Copy the configured prefex */
@ -246,14 +267,14 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
#else
/* Set the prefix and prefix length based on net driver IP and netmask */
prefix->preflen = net_ipv6_mask2pref(dev->d_ipv6netmask);
ipv6addr_mask(prefix->prefix, dev->d_ipv6addr, dev->d_ipv6netmask);
prefix->preflen = net_ipv6_mask2pref(ifaddr->mask);
ipv6addr_mask(prefix->prefix, ifaddr->addr, ifaddr->mask);
skip_prefix:
#endif /* CONFIG_NET_ICMPv6_ROUTER_MANUAL */
#ifdef CONFIG_NET_ICMPv6_ROUTER_RDNSS
rdnss = (FAR struct icmpv6_rdnss_s *)
((FAR uint8_t *)prefix +
sizeof(struct icmpv6_prefixinfo_s));
((FAR uint8_t *)adv + l3size);
rndss_context.rdnss = rdnss;
rndss_context.nservers = 0;

View File

@ -172,7 +172,8 @@ void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data)
dev->d_len = ipicmplen + datalen;
ipv6_build_header(IPv6BUF, dev->d_len - IPv6_HDRLEN, IP_PROTO_ICMP6,
dev->d_ipv6addr, ipv6->srcipaddr, 255, 0);
netdev_ipv6_srcaddr(dev, ipv6->srcipaddr),
ipv6->srcipaddr, 255, 0);
/* Initialize the ICMPv6 header */

View File

@ -75,6 +75,9 @@ void icmpv6_setaddresses(FAR struct net_driver_s *dev,
const net_ipv6addr_t prefix,
unsigned int preflen)
{
FAR const uint16_t *curaddr;
net_ipv6addr_t addr;
net_ipv6addr_t mask;
unsigned int i;
/* Lock the network.
@ -100,20 +103,28 @@ void icmpv6_setaddresses(FAR struct net_driver_s *dev,
preflen = 128;
}
net_ipv6_pref2mask(preflen, dev->d_ipv6netmask);
net_ipv6_pref2mask(preflen, mask);
ninfo("preflen=%d netmask=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
preflen, NTOHS(dev->d_ipv6netmask[0]), NTOHS(dev->d_ipv6netmask[1]),
NTOHS(dev->d_ipv6netmask[2]), NTOHS(dev->d_ipv6netmask[3]),
NTOHS(dev->d_ipv6netmask[4]), NTOHS(dev->d_ipv6netmask[5]),
NTOHS(dev->d_ipv6netmask[6]), NTOHS(dev->d_ipv6netmask[7]));
preflen,
NTOHS(mask[0]), NTOHS(mask[1]), NTOHS(mask[2]), NTOHS(mask[3]),
NTOHS(mask[4]), NTOHS(mask[5]), NTOHS(mask[6]), NTOHS(mask[7]));
/* Copy prefix to the current IPv6 address, applying the mask */
/* Copy prefix to the current link local address, applying the mask.
* According to RFC4862, Section 5.5.3, Page 18, global address is formed
* by prefix + IID, and the IID is normally the link-local suffix.
*/
curaddr = netdev_ipv6_lladdr(dev);
if (curaddr == NULL)
{
icmpv6_linkipaddr(dev, addr);
curaddr = addr;
}
for (i = 0; i < 8; i++)
{
dev->d_ipv6addr[i] = (dev->d_ipv6addr[i] & ~dev->d_ipv6netmask[i]) |
(prefix[i] & dev->d_ipv6netmask[i]);
addr[i] = (curaddr[i] & ~mask[i]) | (prefix[i] & mask[i]);
}
ninfo("prefix=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
@ -121,10 +132,10 @@ void icmpv6_setaddresses(FAR struct net_driver_s *dev,
NTOHS(prefix[3]), NTOHS(prefix[4]), NTOHS(prefix[5]),
NTOHS(prefix[6]), NTOHS(prefix[7]));
ninfo("IP address=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
NTOHS(dev->d_ipv6addr[0]), NTOHS(dev->d_ipv6addr[1]),
NTOHS(dev->d_ipv6addr[2]), NTOHS(dev->d_ipv6addr[3]),
NTOHS(dev->d_ipv6addr[4]), NTOHS(dev->d_ipv6addr[5]),
NTOHS(dev->d_ipv6addr[6]), NTOHS(dev->d_ipv6addr[7]));
NTOHS(addr[0]), NTOHS(addr[1]), NTOHS(addr[2]), NTOHS(addr[3]),
NTOHS(addr[4]), NTOHS(addr[5]), NTOHS(addr[6]), NTOHS(addr[7]));
netdev_ipv6_add(dev, addr, preflen);
/* Finally, copy the router address */

View File

@ -76,7 +76,8 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
l3size = SIZEOF_ICMPV6_ROUTER_SOLICIT_S(lladdrsize);
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
dev->d_ipv6addr, g_ipv6_allrouters, 255, 0);
netdev_ipv6_srcaddr(dev, g_ipv6_allrouters),
g_ipv6_allrouters, 255, 0);
/* Set up the ICMPv6 Router Solicitation message */

View File

@ -115,7 +115,8 @@ static void sendto_request(FAR struct net_driver_s *dev,
dev->d_len = IPv6_HDRLEN + pstate->snd_buflen;
ipv6_build_header(IPv6BUF, pstate->snd_buflen, IP_PROTO_ICMP6,
dev->d_ipv6addr, pstate->snd_toaddr.s6_addr16, 255, 0);
netdev_ipv6_srcaddr(dev, pstate->snd_toaddr.s6_addr16),
pstate->snd_toaddr.s6_addr16, 255, 0);
/* Copy the ICMPv6 request and payload into place after the IPv6 header */
@ -405,8 +406,7 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
* destination device.
*/
if (!net_ipv6addr_maskcmp(state.snd_toaddr.s6_addr16,
dev->d_ipv6addr, dev->d_ipv6netmask))
if (!NETDEV_V6ADDR_ONLINK(dev, state.snd_toaddr.s6_addr16))
{
/* Destination address was not on the local network served
* by this device. If a timeout occurs, then the most

View File

@ -95,7 +95,7 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
dstaddr[7] = ipaddr[7];
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
dev->d_ipv6addr, dstaddr, 255, 0);
netdev_ipv6_srcaddr(dev, ipaddr), dstaddr, 255, 0);
/* Set up the ICMPv6 Neighbor Solicitation message */

View File

@ -150,7 +150,8 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
/* Set the address family and the IP address */
outaddr->sin6_family = AF_INET6;
memcpy(outaddr->sin6_addr.in6_u.u6_addr8, dev->d_ipv6addr, 16);
net_ipv6addr_copy(outaddr->sin6_addr.in6_u.u6_addr8,
netdev_ipv6_srcaddr(dev, *ripaddr));
*addrlen = sizeof(struct sockaddr_in6);
net_unlock();

View File

@ -139,11 +139,21 @@ static clock_t mld_mrc2mrd(uint16_t mrc)
static bool mld_cmpaddr(FAR struct net_driver_s *dev,
const net_ipv6addr_t srcaddr)
{
FAR const uint16_t *lladdr = netdev_ipv6_lladdr(dev);
int i;
if (lladdr == NULL)
{
/* If no link-local address presents, regard address as ::, then nobody
* can be less than it.
*/
return false;
}
for (i = 0; i < 8; i++)
{
if (srcaddr[i] < dev->d_ipv6addr[i])
if (srcaddr[i] < lladdr[i])
{
return true;
}
@ -439,7 +449,7 @@ int mld_query(FAR struct net_driver_s *dev,
/* Not sent to all systems. Check for Unicast General Query */
else if (net_ipv6addr_cmp(ipv6->destipaddr, dev->d_ipv6addr))
else if (NETDEV_IS_MY_V6ADDR(dev, ipv6->destipaddr))
{
mldinfo("Unicast query\n");
MLD_STATINCR(g_netstats.mld.ucast_query_received);

View File

@ -89,6 +89,7 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
{
FAR struct ipv6_router_alert_s *ra;
FAR const uint16_t *destipaddr;
FAR const uint16_t *srcipaddr;
unsigned int mldsize;
/* Only a general query message can have a NULL group */
@ -210,8 +211,18 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
NTOHS(destipaddr[3]), NTOHS(destipaddr[4]), NTOHS(destipaddr[5]),
NTOHS(destipaddr[6]), NTOHS(destipaddr[7]));
srcipaddr = netdev_ipv6_lladdr(dev);
if (srcipaddr == NULL)
{
/* Unspecified address is used when link-local address is not
* available, as described in RFC 3590, Section 4, Page 2.
*/
srcipaddr = g_ipv6_unspecaddr;
}
ipv6_build_header(IPv6BUF, dev->d_sndlen, NEXT_HOPBYBOT_EH,
dev->d_ipv6addr, destipaddr, MLD_TTL, 0);
srcipaddr, destipaddr, MLD_TTL, 0);
/* Add the router alert IP header option.
*

View File

@ -126,8 +126,7 @@ void neighbor_ethernet_out(FAR struct net_driver_s *dev)
/* Check if the destination address is on the local network. */
if (!net_ipv6addr_maskcmp(ip->destipaddr, dev->d_ipv6addr,
dev->d_ipv6netmask))
if (!NETDEV_V6ADDR_ONLINK(dev, ip->destipaddr))
{
/* Destination address is not on the local network */

View File

@ -66,7 +66,7 @@ static int neighbor_match(FAR struct net_driver_s *dev, FAR void *arg)
* lookup.
*/
if (!net_ipv6addr_cmp(dev->d_ipv6addr, info->ni_ipaddr))
if (!NETDEV_IS_MY_V6ADDR(dev, info->ni_ipaddr))
{
return 0;
}

View File

@ -126,13 +126,11 @@ FAR struct net_driver_s *netdev_findby_lipv6addr(
{
/* Is the interface in the "up" state? */
if ((dev->d_flags & IFF_UP) != 0 &&
!net_ipv6addr_cmp(dev->d_ipv6addr, g_ipv6_unspecaddr))
if ((dev->d_flags & IFF_UP) != 0 && NETDEV_HAS_V6ADDR(dev))
{
/* Yes.. check for an address match (under the netmask) */
if (net_ipv6addr_maskcmp(dev->d_ipv6addr, lipaddr,
dev->d_ipv6netmask))
if (NETDEV_V6ADDR_ONLINK(dev, lipaddr))
{
/* Its a match */

View File

@ -169,8 +169,7 @@ static int ifconf_ipv6_callback(FAR struct net_driver_s *dev, FAR void *arg)
* state.
*/
if (!net_ipv6addr_cmp(dev->d_ipv6addr, g_ipv6_unspecaddr) &&
(dev->d_flags & IFF_UP) != 0)
if (NETDEV_HAS_V6ADDR(dev) && IFF_IS_UP(dev->d_flags))
{
/* Check if we would exceed the buffer space provided by the caller.
* NOTE: A common usage model is:

View File

@ -989,14 +989,16 @@ static int netlink_new_ipv6addr(NETLINK_HANDLE handle,
return -ENODEV;
}
memcpy(dev->d_ipv6addr, nla_data(tb[IFA_LOCAL]), 16);
net_ipv6_pref2mask(ifm->ifa_prefixlen, dev->d_ipv6netmask);
ret = netdev_ipv6_add(dev, nla_data(tb[IFA_LOCAL]), ifm->ifa_prefixlen);
if (ret == OK)
{
netlink_device_notify_ipaddr(dev, RTM_NEWADDR, AF_INET6,
nla_data(tb[IFA_LOCAL]), ifm->ifa_prefixlen);
}
netlink_device_notify_ipaddr(dev, RTM_NEWADDR, AF_INET6, dev->d_ipv6addr,
ifm->ifa_prefixlen);
net_unlock();
return OK;
return ret;
}
#endif
@ -1075,6 +1077,11 @@ static int netlink_del_ipv6addr(NETLINK_HANDLE handle,
return ret;
}
if (!tb[IFA_LOCAL] || ifm->ifa_prefixlen > 128)
{
return -EINVAL;
}
net_lock();
dev = netdev_findbyindex(ifm->ifa_index);
@ -1084,20 +1091,22 @@ static int netlink_del_ipv6addr(NETLINK_HANDLE handle,
return -ENODEV;
}
if (tb[IFA_LOCAL] && !net_ipv6addr_cmp(dev->d_ipv6addr,
nla_data(tb[IFA_LOCAL])))
if (!NETDEV_IS_MY_V6ADDR(dev, nla_data(tb[IFA_LOCAL])))
{
net_unlock();
return -EADDRNOTAVAIL;
}
netlink_device_notify_ipaddr(dev, RTM_DELADDR, AF_INET6, dev->d_ipv6addr,
net_ipv6_mask2pref(dev->d_ipv6netmask));
memset(&dev->d_ipv6addr, 0, sizeof(net_ipv6addr_t));
ret = netdev_ipv6_del(dev, nla_data(tb[IFA_LOCAL]), ifm->ifa_prefixlen);
if (ret == OK)
{
netlink_device_notify_ipaddr(dev, RTM_DELADDR, AF_INET6,
nla_data(tb[IFA_LOCAL]), ifm->ifa_prefixlen);
}
net_unlock();
return OK;
return ret;
}
#endif
@ -1110,36 +1119,16 @@ static int netlink_del_ipv6addr(NETLINK_HANDLE handle,
****************************************************************************/
#ifndef CONFIG_NETLINK_DISABLE_GETADDR
static int netlink_addr_callback(FAR struct net_driver_s *dev, FAR void *arg)
#ifdef CONFIG_NET_IPv6
static int netlink_ipv6_addr_callback(FAR struct net_driver_s *dev,
FAR struct netdev_ifaddr6_s *addr,
FAR void *arg)
{
FAR struct nlroute_info_s *info = arg;
FAR struct netlink_response_s *resp;
FAR void *addr = NULL;
uint8_t preflen;
#ifdef CONFIG_NET_IPv4
if (info->req->gen.rtgen_family == AF_INET)
{
addr = &dev->d_ipaddr;
preflen = net_ipv4_mask2pref(dev->d_netmask);
}
#endif
#ifdef CONFIG_NET_IPv6
if (info->req->gen.rtgen_family == AF_INET6)
{
addr = &dev->d_ipv6addr;
preflen = net_ipv6_mask2pref(dev->d_ipv6netmask);
}
#endif
if (addr == NULL)
{
return OK;
}
resp = netlink_get_ifaddr(dev, info->req->gen.rtgen_family, RTM_NEWADDR,
addr, preflen, info->req);
resp = netlink_get_ifaddr(dev, AF_INET6, RTM_NEWADDR, addr->addr,
net_ipv6_mask2pref(addr->mask), info->req);
if (resp == NULL)
{
return -ENOMEM;
@ -1148,6 +1137,37 @@ static int netlink_addr_callback(FAR struct net_driver_s *dev, FAR void *arg)
netlink_add_response(info->handle, resp);
return OK;
}
#endif
static int netlink_addr_callback(FAR struct net_driver_s *dev, FAR void *arg)
{
FAR struct nlroute_info_s *info = arg;
FAR struct netlink_response_s *resp;
#ifdef CONFIG_NET_IPv4
if (info->req->gen.rtgen_family == AF_INET)
{
resp = netlink_get_ifaddr(dev, AF_INET, RTM_NEWADDR, &dev->d_ipaddr,
net_ipv4_mask2pref(dev->d_netmask),
info->req);
if (resp == NULL)
{
return -ENOMEM;
}
netlink_add_response(info->handle, resp);
}
#endif
#ifdef CONFIG_NET_IPv6
if (info->req->gen.rtgen_family == AF_INET6)
{
return netdev_ipv6_foreach(dev, netlink_ipv6_addr_callback, arg);
}
#endif
return OK;
}
static int netlink_get_addr(NETLINK_HANDLE handle,
FAR const struct nlroute_sendto_request_s *req)

View File

@ -167,8 +167,7 @@ static int net_ipv6_devmatch(FAR struct net_route_ipv6_s *route,
*/
if (net_ipv6addr_maskcmp(route->target, match->target, route->netmask) &&
net_ipv6addr_maskcmp(route->router, dev->d_ipv6addr,
dev->d_ipv6netmask))
NETDEV_V6ADDR_ONLINK(dev, route->router))
{
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
/* They match.. Copy the entire routing table entry */

View File

@ -213,7 +213,8 @@ static int sixlowpan_tcp_header(FAR struct tcp_conn_s *conn,
}
else
{
net_ipv6addr_hdrcopy(ipv6tcp->ipv6.srcipaddr, dev->d_ipv6addr);
net_ipv6addr_hdrcopy(ipv6tcp->ipv6.srcipaddr,
netdev_ipv6_srcaddr(dev, conn->u.ipv6.raddr));
}
ninfo("IPv6 length: %d\n",

View File

@ -247,7 +247,8 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
}
else
{
net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, dev->d_ipv6addr);
net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr,
netdev_ipv6_srcaddr(dev, ipv6udp.ipv6.destipaddr));
}
ninfo("IPv6 length: %d\n",

View File

@ -319,8 +319,7 @@ int sixlowpan_destaddrfromip(FAR struct radio_driver_s *radio,
*/
if (!sixlowpan_islinklocal(ipaddr) &&
!net_ipv6addr_maskcmp(radio->r_dev.d_ipv6addr, ipaddr,
radio->r_dev.d_ipv6netmask))
!NETDEV_V6ADDR_ONLINK(&radio->r_dev, ipaddr))
{
return -EADDRNOTAVAIL;
}

View File

@ -440,8 +440,7 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (net_ipv6addr_cmp(addr->sin6_addr.in6_u.u6_addr16,
dev->d_ipv6addr))
if (NETDEV_IS_MY_V6ADDR(dev, addr->sin6_addr.in6_u.u6_addr16))
{
ret = 0;
break;

View File

@ -322,7 +322,8 @@ int psock_tcp_connect(FAR struct socket *psock,
#endif
if (net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_unspecaddr))
{
net_ipv6addr_copy(conn->u.ipv6.laddr, conn->dev->d_ipv6addr);
net_ipv6addr_copy(conn->u.ipv6.laddr,
netdev_ipv6_srcaddr(conn->dev, conn->u.ipv6.raddr));
}
#endif /* CONFIG_NET_IPv6 */

View File

@ -181,7 +181,9 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
{
ninfo("do IPv6 IP header build!\n");
ipv6_build_header(IPv6BUF, dev->d_len - IPv6_HDRLEN,
IP_PROTO_TCP, dev->d_ipv6addr, conn->u.ipv6.raddr,
IP_PROTO_TCP,
netdev_ipv6_srcaddr(dev, conn->u.ipv6.raddr),
conn->u.ipv6.raddr,
conn->sconn.ttl, conn->sconn.s_tclass);
/* Calculate TCP checksum. */
@ -476,7 +478,9 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
ipv6_build_header(ipv6, dev->d_len - IPv6_HDRLEN,
IP_PROTO_TCP, dev->d_ipv6addr, ipv6->srcipaddr,
IP_PROTO_TCP,
netdev_ipv6_srcaddr(dev, ipv6->srcipaddr),
ipv6->srcipaddr,
conn ? conn->sconn.ttl : IP_TTL_DEFAULT,
conn ? conn->sconn.s_tos : 0);
tcp->tcpchksum = 0;

View File

@ -882,8 +882,8 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr)
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (net_ipv6addr_cmp(inaddr->sin6_addr.in6_u.u6_addr16,
dev->d_ipv6addr))
if (NETDEV_IS_MY_V6ADDR(dev,
inaddr->sin6_addr.in6_u.u6_addr16))
{
ret = 0;
break;

View File

@ -149,7 +149,8 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
dev->d_len = dev->d_sndlen + UDP_HDRLEN;
ipv6_build_header(IPv6BUF, dev->d_len, IP_PROTO_UDP,
dev->d_ipv6addr, conn->u.ipv6.raddr,
netdev_ipv6_srcaddr(dev, conn->u.ipv6.raddr),
conn->u.ipv6.raddr,
conn->sconn.ttl, conn->sconn.s_tclass);
/* The total length to send is the size of the application data