net: mgmt: Add IPv6 DAD succeed/failed event
We need a way to know when IPv6 address is successfully set into network interface. If IPv6 DAD (Duplicate Address Detection) succeeds or fails, we send a management event for that. This can be used by other components to detect when the network interface is in usable state. Change-Id: Ifb22415fe21f31f5dba4f55455d6e0f89b414d32 Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
528a393470
commit
57e128654b
4 changed files with 38 additions and 1 deletions
|
@ -52,6 +52,8 @@ enum net_event_ipv6_cmd {
|
|||
NET_EVENT_IPV6_CMD_ROUTER_DEL,
|
||||
NET_EVENT_IPV6_CMD_ROUTE_ADD,
|
||||
NET_EVENT_IPV6_CMD_ROUTE_DEL,
|
||||
NET_EVENT_IPV6_CMD_DAD_SUCCEED,
|
||||
NET_EVENT_IPV6_CMD_DAD_FAILED,
|
||||
};
|
||||
|
||||
#define NET_EVENT_IPV6_ADDR_ADD \
|
||||
|
@ -90,6 +92,12 @@ enum net_event_ipv6_cmd {
|
|||
#define NET_EVENT_IPV6_ROUTE_DEL \
|
||||
(_NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_ROUTE_DEL)
|
||||
|
||||
#define NET_EVENT_IPV6_DAD_SUCCEED \
|
||||
(_NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_DAD_SUCCEED)
|
||||
|
||||
#define NET_EVENT_IPV6_DAD_FAILED \
|
||||
(_NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_DAD_FAILED)
|
||||
|
||||
/* IPv4 Events*/
|
||||
#define _NET_IPV4_LAYER NET_MGMT_LAYER_L3
|
||||
#define _NET_IPV4_CORE_CODE 0x004
|
||||
|
|
|
@ -944,6 +944,15 @@ struct in6_addr *net_if_ipv6_get_ll(struct net_if *iface,
|
|||
struct in6_addr *net_if_ipv6_get_ll_addr(enum net_addr_state state,
|
||||
struct net_if **iface);
|
||||
|
||||
/**
|
||||
* @brief Stop IPv6 Duplicate Address Detection (DAD) procedure if
|
||||
* we find out that our IPv6 address is already in use.
|
||||
*
|
||||
* @param iface Interface where the DAD was running.
|
||||
* @param addr IPv6 address that failed DAD
|
||||
*/
|
||||
void net_if_ipv6_dad_failed(struct net_if *iface, const struct in6_addr *addr);
|
||||
|
||||
/**
|
||||
* @brief Return global IPv6 address from the first interface that has
|
||||
* a global IPv6 address either in TENTATIVE or PREFERRED state.
|
||||
|
|
|
@ -698,7 +698,7 @@ static inline bool dad_failed(struct net_if *iface, struct in6_addr *addr)
|
|||
return false;
|
||||
}
|
||||
|
||||
net_if_ipv6_addr_rm(iface, addr);
|
||||
net_if_ipv6_dad_failed(iface, addr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -397,6 +397,8 @@ static void dad_timeout(struct k_work *work)
|
|||
*/
|
||||
tmp = net_if_ipv6_addr_lookup(&ifaddr->address.in6_addr, &iface);
|
||||
if (tmp == ifaddr) {
|
||||
net_mgmt_event_notify(NET_EVENT_IPV6_DAD_SUCCEED, iface);
|
||||
|
||||
/* The address gets added to neighbor cache which is not needed
|
||||
* in this case as the address is our own one.
|
||||
*/
|
||||
|
@ -444,6 +446,24 @@ void net_if_start_dad(struct net_if *iface)
|
|||
net_sprint_ipv6_addr(&addr), iface);
|
||||
}
|
||||
}
|
||||
|
||||
void net_if_ipv6_dad_failed(struct net_if *iface, const struct in6_addr *addr)
|
||||
{
|
||||
struct net_if_addr *ifaddr;
|
||||
|
||||
ifaddr = net_if_ipv6_addr_lookup(addr, &iface);
|
||||
if (!ifaddr) {
|
||||
NET_ERR("Cannot find %s address in interface %p",
|
||||
net_sprint_ipv6_addr(addr), iface);
|
||||
return;
|
||||
}
|
||||
|
||||
k_delayed_work_cancel(&ifaddr->dad_timer);
|
||||
|
||||
net_mgmt_event_notify(NET_EVENT_IPV6_DAD_FAILED, iface);
|
||||
|
||||
net_if_ipv6_addr_rm(iface, addr);
|
||||
}
|
||||
#else
|
||||
static inline void net_if_ipv6_start_dad(struct net_if *iface,
|
||||
struct net_if_addr *ifaddr)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue