net/netdev: Support managing multiple IPv6 addresses by ioctl
1. Supporting `SIOCSIFADDR` and `SIOCDIFADDR` with Linux in6_ifreq struct to manage ipv6 addresses. Ref: https://man7.org/linux/man-pages/man7/netdevice.7.html 2. Supporting alias like 'eth0:0' for multiple IPv6 addresses, to keep previous ioctl `SIOCGLIFADDR`, `SIOCSLIFADDR`, `SIOCGLIFNETMASK` and `SIOCSLIFNETMASK` working. Ref: https://man7.org/linux/man-pages/man8/ifconfig.8.html Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
7f421a46ca
commit
3e4d847f42
@ -1057,7 +1057,7 @@ static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd,
|
|||||||
ssize_t len;
|
ssize_t len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
len = net_ioctl_arglen(cmd);
|
len = net_ioctl_arglen(PF_RPMSG, cmd);
|
||||||
if (len >= 0)
|
if (len >= 0)
|
||||||
{
|
{
|
||||||
FAR struct net_rpmsg_ioctl_s *msg;
|
FAR struct net_rpmsg_ioctl_s *msg;
|
||||||
|
@ -335,6 +335,13 @@ struct in6_pktinfo
|
|||||||
int ipi6_ifindex; /* send/recv interface index */
|
int ipi6_ifindex; /* send/recv interface index */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct in6_ifreq
|
||||||
|
{
|
||||||
|
struct in6_addr ifr6_addr; /* The IPv6 address of the request */
|
||||||
|
uint32_t ifr6_prefixlen; /* The IPv6 prefix length */
|
||||||
|
int ifr6_ifindex; /* The interface index of the request */
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -301,7 +301,7 @@ void net_initialize(void);
|
|||||||
* Calculate the ioctl argument buffer length.
|
* Calculate the ioctl argument buffer length.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
*
|
* domain The socket domain
|
||||||
* cmd The ioctl command
|
* cmd The ioctl command
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -309,7 +309,7 @@ void net_initialize(void);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
ssize_t net_ioctl_arglen(int cmd);
|
ssize_t net_ioctl_arglen(uint8_t domain, int cmd);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Critical section management.
|
* Critical section management.
|
||||||
|
@ -26,7 +26,9 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
@ -139,6 +141,77 @@ static int ifconf_ipv4_callback(FAR struct net_driver_s *dev, FAR void *arg)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: ifconf_ipv6_addr_callback
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Callback from netdev_ipv6_foreach() that does the real implementation of
|
||||||
|
* netdev_ipv6_ifconf().
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - The network device for this callback.
|
||||||
|
* addr - The IPv6 address.
|
||||||
|
* arg - User callback argument
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero is returned on success; a negated errno value is returned on any
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
static int ifconf_ipv6_addr_callback(FAR struct net_driver_s *dev,
|
||||||
|
FAR struct netdev_ifaddr6_s *addr,
|
||||||
|
FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR struct ifconf_ipv6_info_s *info = (FAR struct ifconf_ipv6_info_s *)arg;
|
||||||
|
FAR struct lifconf *lifc = info->lifc;
|
||||||
|
|
||||||
|
if (lifc->lifc_len + sizeof(struct lifreq) <= info->bufsize)
|
||||||
|
{
|
||||||
|
FAR struct lifreq *req =
|
||||||
|
(FAR struct lifreq *)&lifc->lifc_buf[lifc->lifc_len];
|
||||||
|
FAR struct sockaddr_in6 *inaddr =
|
||||||
|
(FAR struct sockaddr_in6 *)&req->lifr_addr;
|
||||||
|
#ifdef CONFIG_NETDEV_MULTIPLE_IPv6
|
||||||
|
int addr_idx = addr - dev->d_ipv6;
|
||||||
|
|
||||||
|
/* There is space for information about another adapter. Within
|
||||||
|
* each ifreq structure, lifr_name will receive the interface
|
||||||
|
* name and lifr_addr the address. The actual number of bytes
|
||||||
|
* transferred is returned in lifc_len.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (addr_idx > 0)
|
||||||
|
{
|
||||||
|
/* eth0:0 represents the second addr on eth0 */
|
||||||
|
|
||||||
|
if (snprintf(req->lifr_name, IFNAMSIZ,
|
||||||
|
"%s:%d", dev->d_ifname, addr_idx - 1) >= IFNAMSIZ)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: ifname too long to print %s:%d\n",
|
||||||
|
dev->d_ifname, addr_idx - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
strlcpy(req->lifr_name, dev->d_ifname, IFNAMSIZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
inaddr->sin6_family = AF_INET6;
|
||||||
|
inaddr->sin6_port = 0;
|
||||||
|
net_ipv6addr_copy(inaddr->sin6_addr.s6_addr16, addr->addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the size of the buffer in any event */
|
||||||
|
|
||||||
|
lifc->lifc_len += sizeof(struct lifreq);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ifconf_ipv6_callback
|
* Name: ifconf_ipv6_callback
|
||||||
*
|
*
|
||||||
@ -160,10 +233,8 @@ static int ifconf_ipv4_callback(FAR struct net_driver_s *dev, FAR void *arg)
|
|||||||
static int ifconf_ipv6_callback(FAR struct net_driver_s *dev, FAR void *arg)
|
static int ifconf_ipv6_callback(FAR struct net_driver_s *dev, FAR void *arg)
|
||||||
{
|
{
|
||||||
FAR struct ifconf_ipv6_info_s *info = (FAR struct ifconf_ipv6_info_s *)arg;
|
FAR struct ifconf_ipv6_info_s *info = (FAR struct ifconf_ipv6_info_s *)arg;
|
||||||
FAR struct lifconf *lifc;
|
|
||||||
|
|
||||||
DEBUGASSERT(dev != NULL && info != NULL && info->lifc != NULL);
|
DEBUGASSERT(dev != NULL && info != NULL && info->lifc != NULL);
|
||||||
lifc = info->lifc;
|
|
||||||
|
|
||||||
/* Check if this adapter has an IPv6 address assigned and is in the UP
|
/* Check if this adapter has an IPv6 address assigned and is in the UP
|
||||||
* state.
|
* state.
|
||||||
@ -186,29 +257,7 @@ static int ifconf_ipv6_callback(FAR struct net_driver_s *dev, FAR void *arg)
|
|||||||
* cases.
|
* cases.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (lifc->lifc_len + sizeof(struct lifreq) <= info->bufsize)
|
return netdev_ipv6_foreach(dev, ifconf_ipv6_addr_callback, arg);
|
||||||
{
|
|
||||||
FAR struct lifreq *req =
|
|
||||||
(FAR struct lifreq *)&lifc->lifc_buf[lifc->lifc_len];
|
|
||||||
FAR struct sockaddr_in6 *inaddr =
|
|
||||||
(FAR struct sockaddr_in6 *)&req->lifr_addr;
|
|
||||||
|
|
||||||
/* There is space for information about another adapter. Within
|
|
||||||
* each ifreq structure, lifr_name will receive the interface
|
|
||||||
* name and lifr_addr the address. The actual number of bytes
|
|
||||||
* transferred is returned in lifc_len.
|
|
||||||
*/
|
|
||||||
|
|
||||||
strlcpy(req->lifr_name, dev->d_ifname, IFNAMSIZ);
|
|
||||||
|
|
||||||
inaddr->sin6_family = AF_INET6;
|
|
||||||
inaddr->sin6_port = 0;
|
|
||||||
net_ipv6addr_copy(inaddr->sin6_addr.s6_addr16, dev->d_ipv6addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment the size of the buffer in any event */
|
|
||||||
|
|
||||||
lifc->lifc_len += sizeof(struct lifreq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -652,31 +652,32 @@ static int netdev_wifr_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: netdev_ifr_dev
|
* Name: netdev_ifr_split_idx
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Verify the struct ifreq and get the Ethernet device.
|
* Split the address index from device name like 'eth0:0'.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* req - The argument of the ioctl cmd
|
* req - The argument of the ioctl cmd
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* A pointer to the driver structure on success; NULL on failure.
|
* The address index from device name.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static FAR struct net_driver_s *netdev_ifr_dev(FAR struct ifreq *req)
|
static unsigned int netdev_ifr_split_idx(FAR struct ifreq *req)
|
||||||
{
|
{
|
||||||
if (req != NULL)
|
FAR char *colon = strchr(req->ifr_name, ':');
|
||||||
{
|
int idx;
|
||||||
/* Find the network device associated with the device name
|
|
||||||
* in the request data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return netdev_findbyname(req->ifr_name);
|
if (colon)
|
||||||
|
{
|
||||||
|
*colon++ = '\0'; /* Remove suffix from device name */
|
||||||
|
idx = atoi(colon);
|
||||||
|
return idx >= 0 ? idx + 1 : 0; /* eth0:0 represents the second addr */
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -686,7 +687,7 @@ static FAR struct net_driver_s *netdev_ifr_dev(FAR struct ifreq *req)
|
|||||||
* Calculate the ioctl argument buffer length of ifreq.
|
* Calculate the ioctl argument buffer length of ifreq.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
*
|
* domain The socket domain
|
||||||
* cmd The ioctl command
|
* cmd The ioctl command
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -694,12 +695,11 @@ static FAR struct net_driver_s *netdev_ifr_dev(FAR struct ifreq *req)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static ssize_t net_ioctl_ifreq_arglen(int cmd)
|
static ssize_t net_ioctl_ifreq_arglen(uint8_t domain, int cmd)
|
||||||
{
|
{
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case SIOCGIFADDR:
|
case SIOCGIFADDR:
|
||||||
case SIOCSIFADDR:
|
|
||||||
case SIOCGIFDSTADDR:
|
case SIOCGIFDSTADDR:
|
||||||
case SIOCSIFDSTADDR:
|
case SIOCSIFDSTADDR:
|
||||||
case SIOCGIFBRDADDR:
|
case SIOCGIFBRDADDR:
|
||||||
@ -710,7 +710,6 @@ static ssize_t net_ioctl_ifreq_arglen(int cmd)
|
|||||||
case SIOCGIFMTU:
|
case SIOCGIFMTU:
|
||||||
case SIOCGIFHWADDR:
|
case SIOCGIFHWADDR:
|
||||||
case SIOCSIFHWADDR:
|
case SIOCSIFHWADDR:
|
||||||
case SIOCDIFADDR:
|
|
||||||
case SIOCGIFCOUNT:
|
case SIOCGIFCOUNT:
|
||||||
case SIOCSIFFLAGS:
|
case SIOCSIFFLAGS:
|
||||||
case SIOCGIFFLAGS:
|
case SIOCGIFFLAGS:
|
||||||
@ -730,6 +729,11 @@ static ssize_t net_ioctl_ifreq_arglen(int cmd)
|
|||||||
case SIOCGIFINDEX:
|
case SIOCGIFINDEX:
|
||||||
return sizeof(struct ifreq);
|
return sizeof(struct ifreq);
|
||||||
|
|
||||||
|
case SIOCSIFADDR:
|
||||||
|
case SIOCDIFADDR:
|
||||||
|
return domain == PF_INET6 ?
|
||||||
|
sizeof(struct in6_ifreq) : sizeof(struct ifreq);
|
||||||
|
|
||||||
case SIOCGLIFADDR:
|
case SIOCGLIFADDR:
|
||||||
case SIOCSLIFADDR:
|
case SIOCSLIFADDR:
|
||||||
case SIOCGLIFDSTADDR:
|
case SIOCGLIFDSTADDR:
|
||||||
@ -769,6 +773,7 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
FAR struct ifreq *req)
|
FAR struct ifreq *req)
|
||||||
{
|
{
|
||||||
FAR struct net_driver_s *dev = NULL;
|
FAR struct net_driver_s *dev = NULL;
|
||||||
|
unsigned int idx = 0;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
ninfo("cmd: %d\n", cmd);
|
ninfo("cmd: %d\n", cmd);
|
||||||
@ -827,15 +832,27 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
if (net_ioctl_ifreq_arglen(cmd) > 0)
|
if (req == NULL)
|
||||||
{
|
{
|
||||||
dev = netdev_ifr_dev(req);
|
net_unlock();
|
||||||
|
return -ENOTTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (net_ioctl_ifreq_arglen(psock->s_domain, cmd)
|
||||||
|
>= (ssize_t)sizeof(struct ifreq))
|
||||||
|
{
|
||||||
|
idx = netdev_ifr_split_idx(req);
|
||||||
|
UNUSED(idx);
|
||||||
|
dev = netdev_findbyname(req->ifr_name);
|
||||||
|
}
|
||||||
|
else if (net_ioctl_ifreq_arglen(psock->s_domain, cmd)
|
||||||
|
== (ssize_t)sizeof(struct in6_ifreq))
|
||||||
|
{
|
||||||
|
FAR struct in6_ifreq *ifr6 = (FAR struct in6_ifreq *)req;
|
||||||
|
dev = netdev_findbyindex(ifr6->ifr6_ifindex);
|
||||||
|
}
|
||||||
|
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
{
|
|
||||||
ret = -ENODEV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ret = -ENOTTY;
|
ret = -ENOTTY;
|
||||||
}
|
}
|
||||||
@ -857,12 +874,6 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
ioctl_get_ipv4addr(&req->ifr_addr, dev->d_ipaddr);
|
ioctl_get_ipv4addr(&req->ifr_addr, dev->d_ipaddr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCSIFADDR: /* Set IP address */
|
|
||||||
ioctl_set_ipv4addr(&dev->d_ipaddr, &req->ifr_addr);
|
|
||||||
netlink_device_notify_ipaddr(dev, RTM_NEWADDR, AF_INET,
|
|
||||||
&dev->d_ipaddr, net_ipv4_mask2pref(dev->d_netmask));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SIOCGIFDSTADDR: /* Get P-to-P address */
|
case SIOCGIFDSTADDR: /* Get P-to-P address */
|
||||||
ioctl_get_ipv4addr(&req->ifr_dstaddr, dev->d_draddr);
|
ioctl_get_ipv4addr(&req->ifr_dstaddr, dev->d_draddr);
|
||||||
break;
|
break;
|
||||||
@ -893,16 +904,18 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
case SIOCGLIFADDR: /* Get IP address */
|
case SIOCGLIFADDR: /* Get IP address */
|
||||||
{
|
{
|
||||||
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
||||||
ioctl_get_ipv6addr(&lreq->lifr_addr, dev->d_ipv6addr);
|
idx = MIN(idx, CONFIG_NETDEV_MAX_IPv6_ADDR - 1);
|
||||||
|
ioctl_get_ipv6addr(&lreq->lifr_addr, dev->d_ipv6[idx].addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCSLIFADDR: /* Set IP address */
|
case SIOCSLIFADDR: /* Set IP address */
|
||||||
{
|
{
|
||||||
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
||||||
ioctl_set_ipv6addr(dev->d_ipv6addr, &lreq->lifr_addr);
|
idx = MIN(idx, CONFIG_NETDEV_MAX_IPv6_ADDR - 1);
|
||||||
|
ioctl_set_ipv6addr(dev->d_ipv6[idx].addr, &lreq->lifr_addr);
|
||||||
netlink_device_notify_ipaddr(dev, RTM_NEWADDR, AF_INET6,
|
netlink_device_notify_ipaddr(dev, RTM_NEWADDR, AF_INET6,
|
||||||
dev->d_ipv6addr, net_ipv6_mask2pref(dev->d_ipv6netmask));
|
dev->d_ipv6[idx].addr, net_ipv6_mask2pref(dev->d_ipv6[idx].mask));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -928,14 +941,16 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
case SIOCGLIFNETMASK: /* Get network mask */
|
case SIOCGLIFNETMASK: /* Get network mask */
|
||||||
{
|
{
|
||||||
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
||||||
ioctl_get_ipv6addr(&lreq->lifr_addr, dev->d_ipv6netmask);
|
idx = MIN(idx, CONFIG_NETDEV_MAX_IPv6_ADDR - 1);
|
||||||
|
ioctl_get_ipv6addr(&lreq->lifr_addr, dev->d_ipv6[idx].mask);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCSLIFNETMASK: /* Set network mask */
|
case SIOCSLIFNETMASK: /* Set network mask */
|
||||||
{
|
{
|
||||||
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
||||||
ioctl_set_ipv6addr(dev->d_ipv6netmask, &lreq->lifr_addr);
|
idx = MIN(idx, CONFIG_NETDEV_MAX_IPv6_ADDR - 1);
|
||||||
|
ioctl_set_ipv6addr(dev->d_ipv6[idx].mask, &lreq->lifr_addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -1057,16 +1072,53 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case SIOCSIFADDR: /* Set IP address */
|
||||||
|
#ifdef CONFIG_NET_IPv4
|
||||||
|
if (psock->s_domain != PF_INET6)
|
||||||
|
{
|
||||||
|
ioctl_set_ipv4addr(&dev->d_ipaddr, &req->ifr_addr);
|
||||||
|
netlink_device_notify_ipaddr(dev, RTM_NEWADDR, AF_INET,
|
||||||
|
&dev->d_ipaddr, net_ipv4_mask2pref(dev->d_netmask));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
if (psock->s_domain == PF_INET6)
|
||||||
|
{
|
||||||
|
FAR struct in6_ifreq *ifr6 = (FAR struct in6_ifreq *)req;
|
||||||
|
ret = netdev_ipv6_add(dev, ifr6->ifr6_addr.in6_u.u6_addr16,
|
||||||
|
ifr6->ifr6_prefixlen);
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
|
netlink_device_notify_ipaddr(dev, RTM_NEWADDR, AF_INET6,
|
||||||
|
ifr6->ifr6_addr.in6_u.u6_addr16, ifr6->ifr6_prefixlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
case SIOCDIFADDR: /* Delete IP address */
|
case SIOCDIFADDR: /* Delete IP address */
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
|
if (psock->s_domain != PF_INET6)
|
||||||
|
{
|
||||||
netlink_device_notify_ipaddr(dev, RTM_DELADDR, AF_INET,
|
netlink_device_notify_ipaddr(dev, RTM_DELADDR, AF_INET,
|
||||||
&dev->d_ipaddr, net_ipv4_mask2pref(dev->d_netmask));
|
&dev->d_ipaddr, net_ipv4_mask2pref(dev->d_netmask));
|
||||||
dev->d_ipaddr = 0;
|
dev->d_ipaddr = 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
if (psock->s_domain == PF_INET6)
|
||||||
|
{
|
||||||
|
FAR struct in6_ifreq *ifr6 = (FAR struct in6_ifreq *)req;
|
||||||
|
ret = netdev_ipv6_del(dev, ifr6->ifr6_addr.in6_u.u6_addr16,
|
||||||
|
ifr6->ifr6_prefixlen);
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
netlink_device_notify_ipaddr(dev, RTM_DELADDR, AF_INET6,
|
netlink_device_notify_ipaddr(dev, RTM_DELADDR, AF_INET6,
|
||||||
dev->d_ipv6addr, net_ipv6_mask2pref(dev->d_ipv6netmask));
|
ifr6->ifr6_addr.in6_u.u6_addr16, ifr6->ifr6_prefixlen);
|
||||||
memset(&dev->d_ipv6addr, 0, sizeof(net_ipv6addr_t));
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1589,7 +1641,7 @@ static int netdev_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
* Calculate the ioctl argument buffer length.
|
* Calculate the ioctl argument buffer length.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
*
|
* domain The socket domain
|
||||||
* cmd The ioctl command
|
* cmd The ioctl command
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -1597,11 +1649,11 @@ static int netdev_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
ssize_t net_ioctl_arglen(int cmd)
|
ssize_t net_ioctl_arglen(uint8_t domain, int cmd)
|
||||||
{
|
{
|
||||||
ssize_t arglen;
|
ssize_t arglen;
|
||||||
|
|
||||||
arglen = net_ioctl_ifreq_arglen(cmd);
|
arglen = net_ioctl_ifreq_arglen(domain, cmd);
|
||||||
if (arglen > 0)
|
if (arglen > 0)
|
||||||
{
|
{
|
||||||
return arglen;
|
return arglen;
|
||||||
|
@ -183,7 +183,7 @@ int usrsock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg_)
|
|||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
arglen = net_ioctl_arglen(cmd);
|
arglen = net_ioctl_arglen(psock->s_domain, cmd);
|
||||||
if (arglen < 0)
|
if (arglen < 0)
|
||||||
{
|
{
|
||||||
return arglen;
|
return arglen;
|
||||||
|
Loading…
Reference in New Issue
Block a user