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_ROUTER_DEL,
|
||||||
NET_EVENT_IPV6_CMD_ROUTE_ADD,
|
NET_EVENT_IPV6_CMD_ROUTE_ADD,
|
||||||
NET_EVENT_IPV6_CMD_ROUTE_DEL,
|
NET_EVENT_IPV6_CMD_ROUTE_DEL,
|
||||||
|
NET_EVENT_IPV6_CMD_DAD_SUCCEED,
|
||||||
|
NET_EVENT_IPV6_CMD_DAD_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NET_EVENT_IPV6_ADDR_ADD \
|
#define NET_EVENT_IPV6_ADDR_ADD \
|
||||||
|
@ -90,6 +92,12 @@ enum net_event_ipv6_cmd {
|
||||||
#define NET_EVENT_IPV6_ROUTE_DEL \
|
#define NET_EVENT_IPV6_ROUTE_DEL \
|
||||||
(_NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_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*/
|
/* IPv4 Events*/
|
||||||
#define _NET_IPV4_LAYER NET_MGMT_LAYER_L3
|
#define _NET_IPV4_LAYER NET_MGMT_LAYER_L3
|
||||||
#define _NET_IPV4_CORE_CODE 0x004
|
#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 in6_addr *net_if_ipv6_get_ll_addr(enum net_addr_state state,
|
||||||
struct net_if **iface);
|
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
|
* @brief Return global IPv6 address from the first interface that has
|
||||||
* a global IPv6 address either in TENTATIVE or PREFERRED state.
|
* 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
net_if_ipv6_addr_rm(iface, addr);
|
net_if_ipv6_dad_failed(iface, addr);
|
||||||
|
|
||||||
return true;
|
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);
|
tmp = net_if_ipv6_addr_lookup(&ifaddr->address.in6_addr, &iface);
|
||||||
if (tmp == ifaddr) {
|
if (tmp == ifaddr) {
|
||||||
|
net_mgmt_event_notify(NET_EVENT_IPV6_DAD_SUCCEED, iface);
|
||||||
|
|
||||||
/* The address gets added to neighbor cache which is not needed
|
/* The address gets added to neighbor cache which is not needed
|
||||||
* in this case as the address is our own one.
|
* 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);
|
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
|
#else
|
||||||
static inline void net_if_ipv6_start_dad(struct net_if *iface,
|
static inline void net_if_ipv6_start_dad(struct net_if *iface,
|
||||||
struct net_if_addr *ifaddr)
|
struct net_if_addr *ifaddr)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue