devctl: add ADDR_ADD and ADDR_DEL devctl event for IFNET

Add devd event on network iface address add/remove.  Can be used to
automate actions on any address change.

Reviewed by:		imp@ (and minor style tweaks)
Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D30840
This commit is contained in:
Rozhuk Ivan 2021-06-23 10:20:10 -06:00 committed by Warner Losh
parent 4fb3e0bb94
commit a75819461e
2 changed files with 33 additions and 0 deletions

View File

@ -469,6 +469,10 @@ The network interface is attached to the system.
The network interface is detached from the system.
.It Li IFNET Ta Em inet Ta Li RENAME Ta
The network interface is renamed.
.It Li IFNET Ta Em inet Ta Li ADDR_ADD Ta
The network interface address added.
.It Li IFNET Ta Em inet Ta Li ADDR_DEL Ta
The network interface address removed.
.El
.Pp
.Bl -column "System" "Subsystem" "1234567" -compact

View File

@ -50,6 +50,7 @@
#include <sys/syslog.h>
#include <sys/sysproto.h>
#include <sys/proc.h>
#include <sys/devctl.h>
#include <sys/domain.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
@ -67,6 +68,7 @@
#include <netinet/in.h>
#include <netinet/ip_mroute.h>
#include <netinet6/in6_var.h>
VNET_PCPUSTAT_DEFINE(struct rtstat, rtstat);
@ -685,6 +687,10 @@ rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netma
int
rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
{
#if defined(INET) || defined(INET6)
struct sockaddr *sa = ifa->ifa_addr;
struct ifnet *ifp = ifa->ifa_ifp;
#endif
KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
("unexpected cmd %d", cmd));
@ -693,6 +699,29 @@ rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
EVENTHANDLER_DIRECT_INVOKE(rt_addrmsg, ifa, cmd);
#ifdef INET
if (sa->sa_family == AF_INET) {
char addrstr[INET_ADDRSTRLEN];
char strbuf[INET_ADDRSTRLEN + 12];
inet_ntoa_r(((struct sockaddr_in *)sa)->sin_addr, addrstr);
snprintf(strbuf, sizeof(strbuf), "address=%s", addrstr);
devctl_notify("IFNET", ifp->if_xname,
(cmd == RTM_ADD) ? "ADDR_ADD" : "ADDR_DEL", strbuf);
}
#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
char addrstr[INET6_ADDRSTRLEN];
char strbuf[INET6_ADDRSTRLEN + 12];
ip6_sprintf(addrstr, IFA_IN6(ifa));
snprintf(strbuf, sizeof(strbuf), "address=%s", addrstr);
devctl_notify("IFNET", ifp->if_xname,
(cmd == RTM_ADD) ? "ADDR_ADD" : "ADDR_DEL", strbuf);
}
#endif
if (V_rt_add_addr_allfibs)
fibnum = RT_ALL_FIBS;
return (rtsock_addrmsg(cmd, ifa, fibnum));