Support to ARP Address Conflict Detection
Support to ARP Address Conflict Detection Signed-off-by: wangchen <wangchen41@xiaomi.com>
This commit is contained in:
parent
a188cf3480
commit
204f4a18a0
10 changed files with 532 additions and 3 deletions
|
@ -58,6 +58,7 @@
|
|||
#include <netinet/in.h>
|
||||
|
||||
#include <nuttx/net/netconfig.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
@ -245,6 +246,41 @@ struct ipv6_stats_s
|
|||
#endif /* CONFIG_NET_IPv6 */
|
||||
#endif /* CONFIG_NET_STATISTICS */
|
||||
|
||||
#ifdef CONFIG_NET_ARP_ACD
|
||||
#define ARP_ACD_TMR_INTERVAL 100 /* milliseconds */
|
||||
#define ARP_ACD_TICKS_PER_SECOND (1000 / ARP_ACD_TMR_INTERVAL)
|
||||
|
||||
/* RFC 5227 Constants */
|
||||
|
||||
#define ANNOUNCE_NUM 2 /* (number of announcement packets) */
|
||||
#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */
|
||||
#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */
|
||||
#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */
|
||||
|
||||
/* arp acd entry states */
|
||||
|
||||
enum arp_acd_state_e
|
||||
{
|
||||
ARP_ACD_STATE_INIT = 0,
|
||||
ARP_ACD_STATE_ANNOUNCING = 1,
|
||||
ARP_ACD_STATE_FINISH = 2
|
||||
};
|
||||
|
||||
#define ARP_ACD_ADDRESS_NO_CONFLICT 0
|
||||
#define ARP_ACD_ADDRESS_CONFLICT 1
|
||||
|
||||
struct arp_acd_s
|
||||
{
|
||||
enum arp_acd_state_e state; /* current arp_acd_s status */
|
||||
int sendnum; /* sent number of probes or announces, dependent on state */
|
||||
bool conflict_flag; /* arp address conflict flag */
|
||||
bool need_announce; /* need to send arp announce packet */
|
||||
uint32_t ttw; /* ticks to wait */
|
||||
clock_t lastconflict; /* last conflict timestamp */
|
||||
struct work_s work; /* For deferred timeout operations */
|
||||
};
|
||||
#endif /* CONFIG_NET_ARP_ACD */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
|
|
@ -320,6 +320,9 @@ struct net_driver_s
|
|||
in_addr_t d_ipaddr; /* Host IPv4 address assigned to the network interface */
|
||||
in_addr_t d_draddr; /* Default router IP address */
|
||||
in_addr_t d_netmask; /* Network subnet mask */
|
||||
#ifdef CONFIG_NET_ARP_ACD
|
||||
struct arp_acd_s d_acd; /* ipv4 acd entry */
|
||||
#endif /* CONFIG_NET_ARP_ACD */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
|
|
|
@ -76,5 +76,12 @@ config NET_ARP_DUMP
|
|||
---help---
|
||||
Dump ARP packets to the SYSLOG device.
|
||||
|
||||
config NET_ARP_ACD
|
||||
bool "Support of ARP address Address Conflict Detection"
|
||||
default n
|
||||
depends on NET_ARP_SEND
|
||||
---help---
|
||||
Enable Support of ARP address Address Conflict Detection
|
||||
|
||||
endif # NET_ARP
|
||||
endmenu # ARP Configuration
|
||||
|
|
|
@ -35,6 +35,10 @@ ifeq ($(CONFIG_NET_ARP_DUMP),y)
|
|||
NET_CSRCS += arp_dump.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_ARP_ACD),y)
|
||||
NET_CSRCS += arp_acd.c
|
||||
endif
|
||||
|
||||
# Include arp build support
|
||||
|
||||
DEPPATH += --dep-path arp
|
||||
|
|
|
@ -128,9 +128,12 @@ struct arp_iphdr_s
|
|||
* operated upon from the network driver poll.
|
||||
*/
|
||||
|
||||
typedef CODE void (*arp_send_finish_cb_t)(FAR struct net_driver_s *dev,
|
||||
int result);
|
||||
struct arp_send_s
|
||||
{
|
||||
FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */
|
||||
FAR arp_send_finish_cb_t finish_cb; /* Reference to send finish callback */
|
||||
sem_t snd_sem; /* Used to wake up the waiting thread */
|
||||
uint8_t snd_retries; /* Retry count */
|
||||
volatile bool snd_sent; /* True: if request sent */
|
||||
|
@ -275,6 +278,33 @@ int arp_send(in_addr_t ipaddr);
|
|||
# define arp_send(i) (0)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_send_async
|
||||
*
|
||||
* Description:
|
||||
* The arp_send_async() call may be to send an ARP request asyncly to
|
||||
* resolve an IPv4 address.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ipaddr The IP address to be queried.
|
||||
* cb The callback when ARP send is finished, should not be NULL.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success the arp been sent to the driver.
|
||||
* On error a negated errno value is returned:
|
||||
*
|
||||
* -ETIMEDOUT: The number or retry counts has been exceed.
|
||||
* -EHOSTUNREACH: Could not find a route to the host
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called from the normal tasking context.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ARP_SEND
|
||||
int arp_send_async(in_addr_t ipaddr, arp_send_finish_cb_t cb);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_poll
|
||||
*
|
||||
|
@ -523,6 +553,58 @@ void arp_dump(FAR struct arp_hdr_s *arp);
|
|||
# define arp_dump(arp)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_ARP_ACD
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_update
|
||||
*
|
||||
* Description:
|
||||
* interface of ARP Address Conflict Detection monitor
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device driver structure to use in the send operation
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arp_acd_update(FAR struct net_driver_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_set_addr
|
||||
*
|
||||
* Description:
|
||||
* setting address interface of ARP Address Conflict Detection
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device driver structure to use in the send operation
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arp_acd_set_addr(FAR struct net_driver_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_setup
|
||||
*
|
||||
* Description:
|
||||
* set up interface of ARP Address Conflict Detection
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device driver structure to use in the send operation
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arp_acd_setup(FAR struct net_driver_s *dev);
|
||||
|
||||
#endif /* CONFIG_NET_ARP_ACD */
|
||||
|
||||
#else /* CONFIG_NET_ARP */
|
||||
|
||||
/* If ARP is disabled, stub out all ARP interfaces */
|
||||
|
|
281
net/arp/arp_acd.c
Normal file
281
net/arp/arp_acd.c
Normal file
|
@ -0,0 +1,281 @@
|
|||
/****************************************************************************
|
||||
* net/arp/arp_acd.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nuttx/net/ethernet.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/netconfig.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
#include "arp/arp.h"
|
||||
#include "netlink/netlink.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void arp_acd_try_announce(FAR void *net_dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_arrange_announce
|
||||
*
|
||||
* Description:
|
||||
* creat work_queue to send ARP announce
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device driver structure to use in the send operation
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void arp_acd_arrange_announce(FAR struct net_driver_s *dev)
|
||||
{
|
||||
if (dev->d_acd.need_announce == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!work_available(&dev->d_acd.work))
|
||||
{
|
||||
nerr("ERROR work unavailable \n");
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = work_queue(LPWORK, &dev->d_acd.work, arp_acd_try_announce,
|
||||
(FAR void *)dev, DSEC2TICK(dev->d_acd.ttw));
|
||||
if (ret != OK)
|
||||
{
|
||||
nerr("ERROR ret %d \n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_send_finish
|
||||
*
|
||||
* Description:
|
||||
* send finish process of ARP Address Conflict Detection
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device driver structure to use in the send operation
|
||||
* result - arp send result
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void arp_acd_send_finish(FAR struct net_driver_s *dev, int result)
|
||||
{
|
||||
if (result < 0)
|
||||
{
|
||||
nerr("ERROR: arp_send result: %d\n", result);
|
||||
}
|
||||
else
|
||||
{
|
||||
arp_acd_arrange_announce(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_try_announce
|
||||
*
|
||||
* Description:
|
||||
* process status of ARP Address Conflict Detection
|
||||
*
|
||||
* Input Parameters:
|
||||
* net_dev - The device driver structure to use in the send operation
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void arp_acd_try_announce(FAR void *net_dev)
|
||||
{
|
||||
FAR struct net_driver_s *dev = net_dev;
|
||||
|
||||
if (dev == NULL || dev->d_acd.state != ARP_ACD_STATE_ANNOUNCING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* arp_acd_announce */
|
||||
|
||||
arp_send_async(dev->d_ipaddr, arp_acd_send_finish);
|
||||
dev->d_acd.sendnum++;
|
||||
|
||||
if (dev->d_acd.sendnum >= ANNOUNCE_NUM)
|
||||
{
|
||||
dev->d_acd.sendnum = 0;
|
||||
dev->d_acd.ttw = 0;
|
||||
dev->d_acd.state = ARP_ACD_STATE_FINISH;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->d_acd.ttw = ANNOUNCE_INTERVAL * ARP_ACD_TICKS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_update
|
||||
*
|
||||
* Description:
|
||||
* interface of ARP Address Conflict Detection monitor
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device driver structure to use in the send operation
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arp_acd_update(FAR struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct arp_hdr_s *arp = ARPBUF;
|
||||
clock_t now = clock_systime_ticks();
|
||||
|
||||
if (dev->d_acd.conflict_flag == ARP_ACD_ADDRESS_CONFLICT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!net_ipv4addr_hdrcmp(arp->ah_sipaddr, &dev->d_ipaddr) ||
|
||||
(memcmp(arp->ah_shwaddr, dev->d_mac.ether.ether_addr_octet,
|
||||
sizeof(arp->ah_shwaddr)) == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((dev->d_acd.lastconflict > 0) &&
|
||||
(now - dev->d_acd.lastconflict) <
|
||||
DSEC2TICK(DEFEND_INTERVAL * ARP_ACD_TICKS_PER_SECOND))
|
||||
{
|
||||
nerr("ERROR: detect conflict again \n");
|
||||
dev->d_acd.lastconflict = 0;
|
||||
dev->d_acd.conflict_flag = ARP_ACD_ADDRESS_CONFLICT;
|
||||
if (dev->d_acd.state != ARP_ACD_STATE_ANNOUNCING)
|
||||
{
|
||||
dev->d_acd.state = ARP_ACD_STATE_INIT;
|
||||
dev->d_acd.sendnum = 0;
|
||||
dev->d_acd.ttw = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nerr("ERROR: detect conflict \n");
|
||||
dev->d_acd.lastconflict = now;
|
||||
if (dev->d_acd.state != ARP_ACD_STATE_ANNOUNCING)
|
||||
{
|
||||
arp_acd_arrange_announce(dev);
|
||||
|
||||
dev->d_acd.state = ARP_ACD_STATE_ANNOUNCING;
|
||||
dev->d_acd.sendnum = 0;
|
||||
dev->d_acd.ttw =
|
||||
ANNOUNCE_WAIT * ARP_ACD_TICKS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_setup
|
||||
*
|
||||
* Description:
|
||||
* set up interface of ARP Address Conflict Detection
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device driver structure to use in the send operation
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arp_acd_setup(FAR struct net_driver_s *dev)
|
||||
{
|
||||
if (dev->d_acd.need_announce == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dev->d_acd.state = ARP_ACD_STATE_ANNOUNCING;
|
||||
dev->d_acd.sendnum = 0;
|
||||
dev->d_acd.ttw = 0;
|
||||
dev->d_acd.conflict_flag = ARP_ACD_ADDRESS_NO_CONFLICT;
|
||||
dev->d_acd.lastconflict = 0;
|
||||
dev->d_acd.need_announce = false;
|
||||
|
||||
arp_acd_arrange_announce(dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_acd_set_addr
|
||||
*
|
||||
* Description:
|
||||
* setting address interface of ARP Address Conflict Detection
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device driver structure to use in the send operation
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arp_acd_set_addr(FAR struct net_driver_s *dev)
|
||||
{
|
||||
if (!net_ipv4addr_cmp(dev->d_ipaddr, INADDR_ANY))
|
||||
{
|
||||
dev->d_acd.need_announce = true;
|
||||
if (IFF_IS_UP(dev->d_flags))
|
||||
{
|
||||
arp_acd_setup(dev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->d_acd.need_announce = false;
|
||||
dev->d_acd.state = ARP_ACD_STATE_INIT;
|
||||
}
|
||||
}
|
|
@ -98,6 +98,11 @@ static int arp_in(FAR struct net_driver_s *dev)
|
|||
dev->d_len = 0;
|
||||
|
||||
ipaddr = net_ip4addr_conv32(arp->ah_dipaddr);
|
||||
|
||||
#ifdef CONFIG_NET_ARP_ACD
|
||||
arp_acd_update(dev);
|
||||
#endif /* CONFIG_NET_ARP_ACD */
|
||||
|
||||
switch (arp->ah_opcode)
|
||||
{
|
||||
case HTONS(ARP_REQUEST):
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
|
@ -50,7 +51,8 @@
|
|||
* Name: arp_send_terminate
|
||||
****************************************************************************/
|
||||
|
||||
static void arp_send_terminate(FAR struct arp_send_s *state, int result)
|
||||
static void arp_send_terminate(FAR struct net_driver_s *dev,
|
||||
FAR struct arp_send_s *state, int result)
|
||||
{
|
||||
/* Don't allow any further call backs. */
|
||||
|
||||
|
@ -63,6 +65,14 @@ static void arp_send_terminate(FAR struct arp_send_s *state, int result)
|
|||
/* Wake up the waiting thread */
|
||||
|
||||
nxsem_post(&state->snd_sem);
|
||||
|
||||
if (state->finish_cb != NULL)
|
||||
{
|
||||
nxsem_destroy(&state->snd_sem);
|
||||
arp_callback_free(dev, state->snd_cb);
|
||||
state->finish_cb(dev, result);
|
||||
kmm_free(state);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -93,7 +103,7 @@ static uint16_t arp_send_eventhandler(FAR struct net_driver_s *dev,
|
|||
if ((flags & NETDEV_DOWN) != 0)
|
||||
{
|
||||
nerr("ERROR: Interface is down\n");
|
||||
arp_send_terminate(state, -ENETUNREACH);
|
||||
arp_send_terminate(dev, state, -ENETUNREACH);
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
@ -130,7 +140,7 @@ static uint16_t arp_send_eventhandler(FAR struct net_driver_s *dev,
|
|||
|
||||
/* Don't allow any further call backs. */
|
||||
|
||||
arp_send_terminate(state, OK);
|
||||
arp_send_terminate(dev, state, OK);
|
||||
}
|
||||
|
||||
return flags;
|
||||
|
@ -319,6 +329,7 @@ int arp_send(in_addr_t ipaddr)
|
|||
state.snd_cb->flags = (ARP_POLL | NETDEV_DOWN);
|
||||
state.snd_cb->priv = (FAR void *)&state;
|
||||
state.snd_cb->event = arp_send_eventhandler;
|
||||
state.finish_cb = NULL;
|
||||
|
||||
/* Notify the device driver that new TX data is available. */
|
||||
|
||||
|
@ -385,4 +396,82 @@ errout:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arp_send_async
|
||||
*
|
||||
* Description:
|
||||
* The arp_send_async() call may be to send an ARP request asyncly to
|
||||
* resolve an IPv4 address.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ipaddr The IP address to be queried.
|
||||
* cb The callback when ARP send is finished, should not be NULL.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success the arp been sent to the driver.
|
||||
* On error a negated errno value is returned:
|
||||
*
|
||||
* -ETIMEDOUT: The number or retry counts has been exceed.
|
||||
* -EHOSTUNREACH: Could not find a route to the host
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called from the normal tasking context.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int arp_send_async(in_addr_t ipaddr, arp_send_finish_cb_t cb)
|
||||
{
|
||||
FAR struct net_driver_s *dev;
|
||||
FAR struct arp_send_s *state = kmm_zalloc(sizeof(struct arp_send_s));
|
||||
int ret = 0;
|
||||
|
||||
if (!state)
|
||||
{
|
||||
nerr("ERROR: %s \n", ENOMEM_STR);
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
dev = netdev_findby_ripv4addr(INADDR_ANY, ipaddr);
|
||||
if (!dev)
|
||||
{
|
||||
nerr("ERROR: Unreachable: %08lx\n", (unsigned long)ipaddr);
|
||||
ret = -EHOSTUNREACH;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
net_lock();
|
||||
state->snd_cb = arp_callback_alloc(dev);
|
||||
if (!state->snd_cb)
|
||||
{
|
||||
nerr("ERROR: Failed to allocate a callback\n");
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
nxsem_init(&state->snd_sem, 0, 0); /* Doesn't really fail */
|
||||
state->snd_ipaddr = ipaddr; /* IP address to query */
|
||||
|
||||
/* Remember the routing device name */
|
||||
|
||||
strlcpy((FAR char *)state->snd_ifname,
|
||||
(FAR const char *)dev->d_ifname, IFNAMSIZ);
|
||||
|
||||
/* Arm/re-arm the callback */
|
||||
|
||||
state->snd_cb->flags = (ARP_POLL | NETDEV_DOWN);
|
||||
state->snd_cb->priv = (FAR void *)state;
|
||||
state->snd_cb->event = arp_send_eventhandler;
|
||||
state->finish_cb = cb;
|
||||
|
||||
/* Notify the device driver that new TX data is available. */
|
||||
|
||||
netdev_txnotify_dev(dev);
|
||||
|
||||
errout_with_lock:
|
||||
net_unlock();
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_ARP_SEND */
|
||||
|
|
|
@ -982,6 +982,11 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||
/* Yes.. bring the interface up */
|
||||
|
||||
ret = netdev_ifup(dev);
|
||||
#ifdef CONFIG_NET_ARP_ACD
|
||||
/* having address then start acd */
|
||||
|
||||
arp_acd_setup(dev);
|
||||
#endif /* CONFIG_NET_ARP_ACD */
|
||||
}
|
||||
|
||||
/* Is this a request to take the interface down? */
|
||||
|
@ -1080,9 +1085,19 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||
#ifdef CONFIG_NET_IPv4
|
||||
if (psock->s_domain != PF_INET6)
|
||||
{
|
||||
if (net_ipv4addr_cmp(dev->d_ipaddr,
|
||||
((FAR struct sockaddr_in *)&req->ifr_addr)->sin_addr.s_addr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
#ifdef CONFIG_NET_ARP_ACD
|
||||
arp_acd_set_addr(dev);
|
||||
#endif /* CONFIG_NET_ARP_ACD */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -293,6 +293,13 @@ static int netprocfs_inet4addresses(FAR struct netprocfs_file_s *netfile)
|
|||
len += snprintf(&netfile->line[len], NET_LINELEN - len,
|
||||
"\tinet addr:%s ", inet_ntoa_r(addr, inetaddr,
|
||||
sizeof(inetaddr)));
|
||||
#ifdef CONFIG_NET_ARP_ACD
|
||||
if (dev->d_acd.conflict_flag == ARP_ACD_ADDRESS_CONFLICT)
|
||||
{
|
||||
len += snprintf(&netfile->line[len], NET_LINELEN - len,
|
||||
"(conflict!) ");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Show the IPv4 default router address */
|
||||
|
||||
|
|
Loading…
Reference in a new issue