git: 793793553558 - main - netlink: convert to IfAPI.

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Fri, 16 Jun 2023 16:00:05 UTC
The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=793793553558bc0b0b0e731e33b1608e685fe72b

commit 793793553558bc0b0b0e731e33b1608e685fe72b
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-06-16 15:58:57 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-06-16 15:59:34 +0000

    netlink: convert to IfAPI.
    
    Convert to IfAPI everything except `IF_AFDATA_WLOCK` usage in neigh.c.
    
    Reviewed By: jhibbits
    Differential Revision: https://reviews.freebsd.org/D40577
---
 sys/net/if.c                      |  50 +++++++++++++++
 sys/net/if_var.h                  |  11 ++++
 sys/netlink/route/iface.c         | 124 ++++++++++++++++++++------------------
 sys/netlink/route/iface_drivers.c |   4 +-
 sys/netlink/route/neigh.c         |  29 +++++----
 sys/netlink/route/nexthop.c       |  12 ++--
 sys/netlink/route/rt.c            |   4 +-
 7 files changed, 154 insertions(+), 80 deletions(-)

diff --git a/sys/net/if.c b/sys/net/if.c
index c5f0a65721fc..2d3d85ca5ee8 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -4327,6 +4327,12 @@ if_getidxgen(const if_t ifp)
 	return (ifp->if_idxgen);
 }
 
+const char *
+if_getdescr(if_t ifp)
+{
+	return (ifp->if_description);
+}
+
 void
 if_setdescr(if_t ifp, char *descrbuf)
 {
@@ -4357,6 +4363,12 @@ if_getalloctype(const if_t ifp)
 	return (ifp->if_alloctype);
 }
 
+void
+if_setlastchange(if_t ifp)
+{
+	getmicrotime(&ifp->if_lastchange);
+}
+
 /*
  * This is largely undesirable because it ties ifnet to a device, but does
  * provide flexiblity for an embedded product vendor. Should be used with
@@ -4714,6 +4726,38 @@ if_foreach_addr_type(if_t ifp, int type, if_addr_cb_t cb, void *cb_arg)
 	return (count);
 }
 
+struct ifaddr *
+ifa_iter_start(if_t ifp, struct ifa_iter *iter)
+{
+	struct ifaddr *ifa;
+
+	NET_EPOCH_ASSERT();
+
+	bzero(iter, sizeof(*iter));
+	ifa = CK_STAILQ_FIRST(&ifp->if_addrhead);
+	if (ifa != NULL)
+		iter->context[0] = CK_STAILQ_NEXT(ifa, ifa_link);
+	else
+		iter->context[0] = NULL;
+	return (ifa);
+}
+
+struct ifaddr *
+ifa_iter_next(struct ifa_iter *iter)
+{
+	struct ifaddr *ifa = iter->context[0];
+
+	if (ifa != NULL)
+		iter->context[0] = CK_STAILQ_NEXT(ifa, ifa_link);
+	return (ifa);
+}
+
+void
+ifa_iter_finish(struct ifa_iter *iter)
+{
+	/* Nothing to do here for now. */
+}
+
 int
 if_setsoftc(if_t ifp, void *softc)
 {
@@ -4825,6 +4869,12 @@ if_resolvemulti(if_t ifp, struct sockaddr **srcs, struct sockaddr *dst)
 	return (ifp->if_resolvemulti(ifp, srcs, dst));
 }
 
+int
+if_ioctl(if_t ifp, u_long cmd, void *data)
+{
+	return (ifp->if_ioctl(ifp, cmd, data));
+}
+
 struct mbuf *
 if_dequeue(if_t ifp)
 {
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 13a82d772c37..89d1c0c039c0 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -573,9 +573,11 @@ void if_setdname(if_t ifp, const char *name);
 const char *if_name(if_t ifp);
 int if_setname(if_t ifp, const char *name);
 int if_rename(if_t ifp, char *new_name);
+const char *if_getdescr(if_t ifp);
 void if_setdescr(if_t ifp, char *descrbuf);
 char *if_allocdescr(size_t sz, int malloc_flag);
 void if_freedescr(char *descrbuf);
+void if_setlastchange(if_t ifp);
 int if_getalloctype(const if_t ifp);
 int if_gettype(const if_t ifp);
 int if_setdev(if_t ifp, void *dev);
@@ -633,6 +635,7 @@ void if_etherbpfmtap(if_t ifp, struct mbuf *m);
 void if_vlancap(if_t ifp);
 int if_transmit(if_t ifp, struct mbuf *m);
 void if_init(if_t ifp, void *ctx);
+int if_ioctl(if_t ifp, u_long cmd, void *data);
 int if_resolvemulti(if_t ifp, struct sockaddr **, struct sockaddr *);
 uint64_t if_getcounter(if_t ifp, ift_counter counter);
 struct label *if_getmaclabel(if_t ifp);
@@ -677,6 +680,14 @@ if_t	if_iter_start(struct if_iter *);
 if_t	if_iter_next(struct if_iter *);
 void	if_iter_finish(struct if_iter *);
 
+struct ifa_iter {
+	void *context[4];
+};
+
+struct ifaddr *ifa_iter_start(if_t ifp, struct ifa_iter *iter);
+struct ifaddr *ifa_iter_next(struct ifa_iter *iter);
+void ifa_iter_finish(struct ifa_iter *iter);
+
 /* Functions */
 void if_setinitfn(if_t ifp, if_init_fn_t);
 void if_setinputfn(if_t ifp, if_input_fn_t);
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index 3d7f752fa613..0874b73a5c98 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -120,11 +120,11 @@ struct if_state {
 };
 
 static void
-get_operstate_ether(struct ifnet *ifp, struct if_state *pstate)
+get_operstate_ether(if_t ifp, struct if_state *pstate)
 {
 	struct ifmediareq ifmr = {};
 	int error;
-	error = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (void *)&ifmr);
+	error = if_ioctl(ifp, SIOCGIFMEDIA, (void *)&ifmr);
 
 	if (error != 0) {
 		NL_LOG(LOG_DEBUG, "error calling SIOCGIFMEDIA on %s: %d",
@@ -136,7 +136,7 @@ get_operstate_ether(struct ifnet *ifp, struct if_state *pstate)
 	case IFM_ETHER:
 		if (ifmr.ifm_status & IFM_ACTIVE) {
 			pstate->ifla_carrier = 1;
-			if (ifp->if_flags & IFF_MONITOR)
+			if (if_getflags(ifp) & IFF_MONITOR)
 				pstate->ifla_operstate = IF_OPER_DORMANT;
 			else
 				pstate->ifla_operstate = IF_OPER_UP;
@@ -146,7 +146,7 @@ get_operstate_ether(struct ifnet *ifp, struct if_state *pstate)
 }
 
 static bool
-get_stats(struct nl_writer *nw, struct ifnet *ifp)
+get_stats(struct nl_writer *nw, if_t ifp)
 {
 	struct rtnl_link_stats64 *stats;
 
@@ -158,34 +158,34 @@ get_stats(struct nl_writer *nw, struct ifnet *ifp)
 	nla->nla_len = nla_len;
 	stats = (struct rtnl_link_stats64 *)(nla + 1);
 
-	stats->rx_packets = ifp->if_get_counter(ifp, IFCOUNTER_IPACKETS);
-	stats->tx_packets = ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS);
-	stats->rx_bytes = ifp->if_get_counter(ifp, IFCOUNTER_IBYTES);
-	stats->tx_bytes = ifp->if_get_counter(ifp, IFCOUNTER_OBYTES);
-	stats->rx_errors = ifp->if_get_counter(ifp, IFCOUNTER_IERRORS);
-	stats->tx_errors = ifp->if_get_counter(ifp, IFCOUNTER_OERRORS);
-	stats->rx_dropped = ifp->if_get_counter(ifp, IFCOUNTER_IQDROPS);
-	stats->tx_dropped = ifp->if_get_counter(ifp, IFCOUNTER_OQDROPS);
-	stats->multicast = ifp->if_get_counter(ifp, IFCOUNTER_IMCASTS);
-	stats->rx_nohandler = ifp->if_get_counter(ifp, IFCOUNTER_NOPROTO);
+	stats->rx_packets = if_getcounter(ifp, IFCOUNTER_IPACKETS);
+	stats->tx_packets = if_getcounter(ifp, IFCOUNTER_OPACKETS);
+	stats->rx_bytes = if_getcounter(ifp, IFCOUNTER_IBYTES);
+	stats->tx_bytes = if_getcounter(ifp, IFCOUNTER_OBYTES);
+	stats->rx_errors = if_getcounter(ifp, IFCOUNTER_IERRORS);
+	stats->tx_errors = if_getcounter(ifp, IFCOUNTER_OERRORS);
+	stats->rx_dropped = if_getcounter(ifp, IFCOUNTER_IQDROPS);
+	stats->tx_dropped = if_getcounter(ifp, IFCOUNTER_OQDROPS);
+	stats->multicast = if_getcounter(ifp, IFCOUNTER_IMCASTS);
+	stats->rx_nohandler = if_getcounter(ifp, IFCOUNTER_NOPROTO);
 
 	return (true);
 }
 
 static void
-get_operstate(struct ifnet *ifp, struct if_state *pstate)
+get_operstate(if_t ifp, struct if_state *pstate)
 {
 	pstate->ifla_operstate = IF_OPER_UNKNOWN;
 	pstate->ifla_carrier = 0; /* no carrier */
 
-	switch (ifp->if_type) {
+	switch (if_gettype(ifp)) {
 	case IFT_ETHER:
 	case IFT_L2VLAN:
 		get_operstate_ether(ifp, pstate);
 		break;
 	default:
 		/* Map admin state to the operstate */
-		if (ifp->if_flags & IFF_UP) {
+		if (if_getflags(ifp) & IFF_UP) {
 			pstate->ifla_operstate = IF_OPER_UP;
 			pstate->ifla_carrier = 1;
 		} else
@@ -195,7 +195,7 @@ get_operstate(struct ifnet *ifp, struct if_state *pstate)
 }
 
 static void
-get_hwaddr(struct nl_writer *nw, struct ifnet *ifp)
+get_hwaddr(struct nl_writer *nw, if_t ifp)
 {
 	struct ifreq ifr = {};
 
@@ -206,9 +206,9 @@ get_hwaddr(struct nl_writer *nw, struct ifnet *ifp)
 }
 
 static unsigned
-ifp_flags_to_netlink(const struct ifnet *ifp)
+ifp_flags_to_netlink(const if_t ifp)
 {
-        return (ifp->if_flags | ifp->if_drv_flags);
+        return (if_getflags(ifp) | if_getdrvflags(ifp));
 }
 
 #define LLADDR_CONST(s) ((const void *)((s)->sdl_data + (s)->sdl_nlen))
@@ -290,7 +290,7 @@ dump_iface_caps(struct nl_writer *nw, struct ifnet *ifp)
  * This function is called without epoch and MAY sleep.
  */
 static bool
-dump_iface(struct nl_writer *nw, struct ifnet *ifp, const struct nlmsghdr *hdr,
+dump_iface(struct nl_writer *nw, if_t ifp, const struct nlmsghdr *hdr,
     int if_flags_mask)
 {
         struct ifinfomsg *ifinfo;
@@ -303,8 +303,8 @@ dump_iface(struct nl_writer *nw, struct ifnet *ifp, const struct nlmsghdr *hdr,
         ifinfo = nlmsg_reserve_object(nw, struct ifinfomsg);
         ifinfo->ifi_family = AF_UNSPEC;
         ifinfo->__ifi_pad = 0;
-        ifinfo->ifi_type = ifp->if_type;
-        ifinfo->ifi_index = ifp->if_index;
+        ifinfo->ifi_type = if_gettype(ifp);
+        ifinfo->ifi_index = if_getindex(ifp);
         ifinfo->ifi_flags = ifp_flags_to_netlink(ifp);
         ifinfo->ifi_change = if_flags_mask;
 
@@ -328,20 +328,20 @@ dump_iface(struct nl_writer *nw, struct ifnet *ifp, const struct nlmsghdr *hdr,
                 dump_sa(nw, IFLA_ADDRESS, ifa->ifa_addr);
         }
 
-        if ((ifp->if_broadcastaddr != NULL)) {
-		nlattr_add(nw, IFLA_BROADCAST, ifp->if_addrlen,
-		    ifp->if_broadcastaddr);
+        if ((if_getbroadcastaddr(ifp) != NULL)) {
+		nlattr_add(nw, IFLA_BROADCAST, if_getaddrlen(ifp),
+		    if_getbroadcastaddr(ifp));
         }
 
-        nlattr_add_u32(nw, IFLA_MTU, ifp->if_mtu);
+        nlattr_add_u32(nw, IFLA_MTU, if_getmtu(ifp));
 /*
         nlattr_add_u32(nw, IFLA_MIN_MTU, 60);
         nlattr_add_u32(nw, IFLA_MAX_MTU, 9000);
         nlattr_add_u32(nw, IFLA_GROUP, 0);
 */
 
-	if (ifp->if_description != NULL)
-		nlattr_add_string(nw, IFLA_IFALIAS, ifp->if_description);
+	if (if_getdescr(ifp) != NULL)
+		nlattr_add_string(nw, IFLA_IFALIAS, if_getdescr(ifp));
 
 	/* Store FreeBSD-specific attributes */
 	int off = nlattr_add_nested(nw, IFLA_FREEBSD);
@@ -354,7 +354,7 @@ dump_iface(struct nl_writer *nw, struct ifnet *ifp, const struct nlmsghdr *hdr,
 
 	get_stats(nw, ifp);
 
-	uint32_t val = (ifp->if_flags & IFF_PROMISC) != 0;
+	uint32_t val = (if_getflags(ifp) & IFF_PROMISC) != 0;
         nlattr_add_u32(nw, IFLA_PROMISCUITY, val);
 
 	ifc_dump_ifp_nl(ifp, nw);
@@ -412,13 +412,13 @@ static const struct nlattr_parser nla_p_if[] = {
 NL_DECLARE_STRICT_PARSER(ifmsg_parser, struct ifinfomsg, check_ifmsg, nlf_p_if, nla_p_if);
 
 static bool
-match_iface(struct ifnet *ifp, void *_arg)
+match_iface(if_t ifp, void *_arg)
 {
 	struct nl_parsed_link *attrs = (struct nl_parsed_link *)_arg;
 
-	if (attrs->ifi_index != 0 && attrs->ifi_index != ifp->if_index)
+	if (attrs->ifi_index != 0 && attrs->ifi_index != if_getindex(ifp))
 		return (false);
-	if (attrs->ifi_type != 0 && attrs->ifi_index != ifp->if_type)
+	if (attrs->ifi_type != 0 && attrs->ifi_index != if_gettype(ifp))
 		return (false);
 	if (attrs->ifla_ifname != NULL && strcmp(attrs->ifla_ifname, if_name(ifp)))
 		return (false);
@@ -428,7 +428,7 @@ match_iface(struct ifnet *ifp, void *_arg)
 }
 
 static int
-dump_cb(struct ifnet *ifp, void *_arg)
+dump_cb(if_t ifp, void *_arg)
 {
 	struct netlink_walkargs *wa = (struct netlink_walkargs *)_arg;
 	if (!dump_iface(wa->nw, ifp, &wa->hdr, 0))
@@ -448,7 +448,7 @@ static int
 rtnl_handle_getlink(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *npt)
 {
 	struct epoch_tracker et;
-        struct ifnet *ifp;
+        if_t ifp;
 	int error = 0;
 
 	struct nl_parsed_link attrs = {};
@@ -529,7 +529,7 @@ static int
 rtnl_handle_dellink(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *npt)
 {
 	struct epoch_tracker et;
-        struct ifnet *ifp;
+        if_t ifp;
 	int error;
 
 	struct nl_parsed_link attrs = {};
@@ -609,7 +609,7 @@ static int
 modify_link(struct nlmsghdr *hdr, struct nl_parsed_link *lattrs,
     struct nlattr_bmask *bm, struct nlpcb *nlp, struct nl_pstate *npt)
 {
-	struct ifnet *ifp = NULL;
+	if_t ifp = NULL;
 	struct epoch_tracker et;
 
 	if (lattrs->ifi_index == 0 && lattrs->ifla_ifname == NULL) {
@@ -948,7 +948,7 @@ export_cache_info(struct nl_writer *nw, struct ifaddr *ifa)
            ('IFA_CACHEINFO', {'ifa_preferred': 4294967295, 'ifa_valid': 4294967295, 'cstamp': 63745746, 'tstamp': 63745746})],
  */
 static bool
-dump_iface_addr(struct nl_writer *nw, struct ifnet *ifp, struct ifaddr *ifa,
+dump_iface_addr(struct nl_writer *nw, if_t ifp, struct ifaddr *ifa,
     const struct nlmsghdr *hdr)
 {
         struct ifaddrmsg *ifamsg;
@@ -966,9 +966,9 @@ dump_iface_addr(struct nl_writer *nw, struct ifnet *ifp, struct ifaddr *ifa,
         ifamsg->ifa_prefixlen = get_sa_plen(ifa->ifa_netmask);
         ifamsg->ifa_flags = 0; // ifa_flags is useless
         ifamsg->ifa_scope = ifa_get_scope(ifa);
-        ifamsg->ifa_index = ifp->if_index;
+        ifamsg->ifa_index = if_getindex(ifp);
 
-	if ((ifp->if_flags & IFF_POINTOPOINT) && sa_dst != NULL && sa_dst->sa_family != 0) {
+	if ((if_getflags(ifp) & IFF_POINTOPOINT) && sa_dst != NULL && sa_dst->sa_family != 0) {
 		/* P2P interface may have IPv6 LL with no dst address */
 		dump_sa(nw, IFA_ADDRESS, sa_dst);
 		dump_sa(nw, IFA_LOCAL, sa);
@@ -983,7 +983,7 @@ dump_iface_addr(struct nl_writer *nw, struct ifnet *ifp, struct ifaddr *ifa,
 			dump_sa(nw, IFA_LOCAL, sa);
 #endif
 	}
-	if (ifp->if_flags & IFF_BROADCAST)
+	if (if_getflags(ifp) & IFF_BROADCAST)
 		dump_sa(nw, IFA_BROADCAST, ifa->ifa_broadaddr);
 
         nlattr_add_string(nw, IFA_LABEL, if_name(ifp));
@@ -1027,11 +1027,13 @@ enomem:
 }
 
 static int
-dump_iface_addrs(struct netlink_walkargs *wa, struct ifnet *ifp)
+dump_iface_addrs(struct netlink_walkargs *wa, if_t ifp)
 {
         struct ifaddr *ifa;
+	struct ifa_iter it;
+	int error = 0;
 
-	CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+	for (ifa = ifa_iter_start(ifp, &it); ifa != NULL; ifa = ifa_iter_next(&it)) {
 		if (wa->family != 0 && wa->family != ifa->ifa_addr->sa_family)
 			continue;
 		if (ifa->ifa_addr->sa_family == AF_LINK)
@@ -1039,18 +1041,21 @@ dump_iface_addrs(struct netlink_walkargs *wa, struct ifnet *ifp)
 		if (prison_if(wa->cred, ifa->ifa_addr) != 0)
 			continue;
 		wa->count++;
-		if (!dump_iface_addr(wa->nw, ifp, ifa, &wa->hdr))
-			return (ENOMEM);
+		if (!dump_iface_addr(wa->nw, ifp, ifa, &wa->hdr)) {
+			error = ENOMEM;
+			break;
+		}
 		wa->dumped++;
 	}
+	ifa_iter_finish(&it);
 
-	return (0);
+	return (error);
 }
 
 static int
 rtnl_handle_getaddr(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *npt)
 {
-        struct ifnet *ifp;
+        if_t ifp;
 	int error = 0;
 
 	struct nl_parsed_ifa attrs = {};
@@ -1078,11 +1083,14 @@ rtnl_handle_getaddr(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *n
 		else
 			error = dump_iface_addrs(&wa, ifp);
 	} else {
-		CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+		struct if_iter it;
+
+		for (ifp = if_iter_start(&it); ifp != NULL; ifp = if_iter_next(&it)) {
 			error = dump_iface_addrs(&wa, ifp);
 			if (error != 0)
 				break;
 		}
+		if_iter_finish(&it);
 	}
 
 	NL_LOG(LOG_DEBUG2, "End dump, iterated %d dumped %d", wa.count, wa.dumped);
@@ -1098,7 +1106,7 @@ rtnl_handle_getaddr(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *n
 #ifdef INET
 static int
 handle_newaddr_inet(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs,
-    struct ifnet *ifp, struct nlpcb *nlp, struct nl_pstate *npt)
+    if_t ifp, struct nlpcb *nlp, struct nl_pstate *npt)
 {
 	int plen = attrs->ifa_prefixlen;
 	int if_flags = if_getflags(ifp);
@@ -1182,7 +1190,7 @@ handle_newaddr_inet(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs,
 
 static int
 handle_deladdr_inet(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs,
-    struct ifnet *ifp, struct nlpcb *nlp, struct nl_pstate *npt)
+    if_t ifp, struct nlpcb *nlp, struct nl_pstate *npt)
 {
 	struct sockaddr_in *addr = (struct sockaddr_in *)attrs->ifa_local;
 
@@ -1203,7 +1211,7 @@ handle_deladdr_inet(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs,
 #ifdef INET6
 static int
 handle_newaddr_inet6(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs,
-    struct ifnet *ifp, struct nlpcb *nlp, struct nl_pstate *npt)
+    if_t ifp, struct nlpcb *nlp, struct nl_pstate *npt)
 {
 	struct sockaddr_in6 *addr, *dst;
 
@@ -1266,7 +1274,7 @@ handle_newaddr_inet6(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs,
 
 static int
 handle_deladdr_inet6(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs,
-    struct ifnet *ifp, struct nlpcb *nlp, struct nl_pstate *npt)
+    if_t ifp, struct nlpcb *nlp, struct nl_pstate *npt)
 {
 	struct sockaddr_in6 *addr = (struct sockaddr_in6 *)attrs->ifa_local;
 
@@ -1297,7 +1305,7 @@ rtnl_handle_addr(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *npt)
 		return (error);
 
 	NET_EPOCH_ENTER(et);
-	struct ifnet *ifp = ifnet_byindex_ref(attrs.ifa_index);
+	if_t ifp = ifnet_byindex_ref(attrs.ifa_index);
 	NET_EPOCH_EXIT(et);
 
 	if (ifp == NULL) {
@@ -1386,7 +1394,7 @@ rtnl_handle_ifaddr(void *arg __unused, struct ifaddr *ifa, int cmd)
 }
 
 static void
-rtnl_handle_ifevent(struct ifnet *ifp, int nlmsg_type, int if_flags_mask)
+rtnl_handle_ifevent(if_t ifp, int nlmsg_type, int if_flags_mask)
 {
 	struct nlmsghdr hdr = { .nlmsg_type = nlmsg_type };
 	struct nl_writer nw = {};
@@ -1403,28 +1411,28 @@ rtnl_handle_ifevent(struct ifnet *ifp, int nlmsg_type, int if_flags_mask)
 }
 
 static void
-rtnl_handle_ifattach(void *arg, struct ifnet *ifp)
+rtnl_handle_ifattach(void *arg, if_t ifp)
 {
 	NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
 	rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0);
 }
 
 static void
-rtnl_handle_ifdetach(void *arg, struct ifnet *ifp)
+rtnl_handle_ifdetach(void *arg, if_t ifp)
 {
 	NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
 	rtnl_handle_ifevent(ifp, NL_RTM_DELLINK, 0);
 }
 
 static void
-rtnl_handle_iflink(void *arg, struct ifnet *ifp)
+rtnl_handle_iflink(void *arg, if_t ifp)
 {
 	NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
 	rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, 0);
 }
 
 void
-rtnl_handle_ifnet_event(struct ifnet *ifp, int if_flags_mask)
+rtnl_handle_ifnet_event(if_t ifp, int if_flags_mask)
 {
 	NL_LOG(LOG_DEBUG2, "ifnet %s", if_name(ifp));
 	rtnl_handle_ifevent(ifp, NL_RTM_NEWLINK, if_flags_mask);
diff --git a/sys/netlink/route/iface_drivers.c b/sys/netlink/route/iface_drivers.c
index 1e839695d960..a0f9ef925a04 100644
--- a/sys/netlink/route/iface_drivers.c
+++ b/sys/netlink/route/iface_drivers.c
@@ -77,7 +77,7 @@ _nl_modify_ifp_generic(struct ifnet *ifp, struct nl_parsed_link *lattrs,
 
 			memcpy(buf, lattrs->ifla_ifalias, len);
 			if_setdescr(ifp, buf);
-			getmicrotime(&ifp->if_lastchange);
+			if_setlastchange(ifp);
 		} else {
 			nlmsg_report_err_msg(npt, "Not enough privileges to set descr");
 			return (EPERM);
@@ -122,7 +122,7 @@ void
 _nl_store_ifp_cookie(struct nl_pstate *npt, struct ifnet *ifp)
 {
 	int ifname_len = strlen(if_name(ifp));
-	uint32_t ifindex = (uint32_t)ifp->if_index;
+	uint32_t ifindex = (uint32_t)if_getindex(ifp);
 
 	int nla_len = sizeof(struct nlattr) * 3 +
 		sizeof(ifindex) + NL_ITEM_ALIGN(ifname_len + 1);
diff --git a/sys/netlink/route/neigh.c b/sys/netlink/route/neigh.c
index 74a162bb9464..55749fcbe761 100644
--- a/sys/netlink/route/neigh.c
+++ b/sys/netlink/route/neigh.c
@@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/syslog.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_private.h>
 #include <net/if_llatbl.h>
 #include <netlink/netlink.h>
 #include <netlink/netlink_ctl.h>
@@ -62,7 +64,7 @@ struct netlink_walkargs {
 	struct nl_writer *nw;
 	struct nlmsghdr hdr;
 	struct nlpcb *so;
-	struct ifnet *ifp;
+	if_t ifp;
 	int family;
 	int error;
 	int count;
@@ -156,7 +158,7 @@ dump_lle_locked(struct llentry *lle, void *arg)
 
 	ndm = nlmsg_reserve_object(nw, struct ndmsg);
 	ndm->ndm_family = wa->family;
-	ndm->ndm_ifindex = wa->ifp->if_index;
+	ndm->ndm_ifindex = if_getindex(wa->ifp);
 	ndm->ndm_state = lle_state_to_nl_state(wa->family, lle);
 	ndm->ndm_flags = lle_flags_to_nl_flags(lle);
 
@@ -178,7 +180,7 @@ dump_lle_locked(struct llentry *lle, void *arg)
 
 	if (lle->r_flags & RLLE_VALID) {
 		/* Has L2 */
-		int addrlen = wa->ifp->if_addrlen;
+		int addrlen = if_getaddrlen(wa->ifp);
 		nlattr_add(nw, NDA_LLADDR, addrlen, lle->ll_addr);
 	}
 
@@ -226,7 +228,7 @@ dump_llt(struct lltable *llt, struct netlink_walkargs *wa)
 }
 
 static int
-dump_llts_iface(struct netlink_walkargs *wa, struct ifnet *ifp, int family)
+dump_llts_iface(struct netlink_walkargs *wa, if_t ifp, int family)
 {
 	int error = 0;
 
@@ -248,21 +250,24 @@ dump_llts_iface(struct netlink_walkargs *wa, struct ifnet *ifp, int family)
 }
 
 static int
-dump_llts(struct netlink_walkargs *wa, struct ifnet *ifp, int family)
+dump_llts(struct netlink_walkargs *wa, if_t ifp, int family)
 {
-	NL_LOG(LOG_DEBUG, "Start dump ifp=%s family=%d", ifp ? if_name(ifp) : "NULL", family);
+	NL_LOG(LOG_DEBUG2, "Start dump ifp=%s family=%d", ifp ? if_name(ifp) : "NULL", family);
 
 	wa->hdr.nlmsg_flags |= NLM_F_MULTI;
 
 	if (ifp != NULL) {
 		dump_llts_iface(wa, ifp, family);
 	} else {
-		CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+		struct if_iter it;
+
+		for (ifp = if_iter_start(&it); ifp != NULL; ifp = if_iter_next(&it)) {
 			dump_llts_iface(wa, ifp, family);
 		}
+		if_iter_finish(&it);
 	}
 
-	NL_LOG(LOG_DEBUG, "End dump, iterated %d dumped %d", wa->count, wa->dumped);
+	NL_LOG(LOG_DEBUG2, "End dump, iterated %d dumped %d", wa->count, wa->dumped);
 
 	if (!nlmsg_end_dump(wa->nw, wa->error, &wa->hdr)) {
                 NL_LOG(LOG_DEBUG, "Unable to add new message");
@@ -273,7 +278,7 @@ dump_llts(struct netlink_walkargs *wa, struct ifnet *ifp, int family)
 }
 
 static int
-get_lle(struct netlink_walkargs *wa, struct ifnet *ifp, int family, struct sockaddr *dst)
+get_lle(struct netlink_walkargs *wa, if_t ifp, int family, struct sockaddr *dst)
 {
 	struct lltable *llt = lltable_get(ifp, family);
 	if (llt == NULL)
@@ -290,7 +295,7 @@ get_lle(struct netlink_walkargs *wa, struct ifnet *ifp, int family, struct socka
 }
 
 static void
-set_scope6(struct sockaddr *sa, struct ifnet *ifp)
+set_scope6(struct sockaddr *sa, if_t ifp)
 {
 #ifdef INET6
 	if (sa != NULL && sa->sa_family == AF_INET6 && ifp != NULL) {
@@ -382,7 +387,7 @@ rtnl_handle_newneigh(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *
 		return (EINVAL);
 	}
 
-	int addrlen = attrs.nda_ifp->if_addrlen;
+	int addrlen = if_getaddrlen(attrs.nda_ifp);
 	if (attrs.nda_lladdr->nla_len != sizeof(struct nlattr) + addrlen) {
 		NLMSG_REPORT_ERR_MSG(npt,
 		    "NDA_LLADDR address length (%d) is different from expected (%d)",
@@ -552,7 +557,7 @@ static const struct rtnl_cmd_handler cmd_handlers[] = {
 static void
 rtnl_lle_event(void *arg __unused, struct llentry *lle, int evt)
 {
-	struct ifnet *ifp;
+	if_t ifp;
 	int family;
 
 	LLE_WLOCK_ASSERT(lle);
diff --git a/sys/netlink/route/nexthop.c b/sys/netlink/route/nexthop.c
index d1652cfb1508..fd3ef021a042 100644
--- a/sys/netlink/route/nexthop.c
+++ b/sys/netlink/route/nexthop.c
@@ -455,7 +455,7 @@ dump_nhop(const struct nhop_object *nh, uint32_t uidx, struct nlmsghdr *hdr,
 		nlattr_add_flag(nw, NHA_BLACKHOLE);
 		goto done;
 	}
-	nlattr_add_u32(nw, NHA_OIF, nh->nh_ifp->if_index);
+	nlattr_add_u32(nw, NHA_OIF, if_getindex(nh->nh_ifp));
 
 	switch (nh->gw_sa.sa_family) {
 #ifdef INET
@@ -476,7 +476,7 @@ dump_nhop(const struct nhop_object *nh, uint32_t uidx, struct nlmsghdr *hdr,
 
 	int off = nlattr_add_nested(nw, NHA_FREEBSD);
 	if (off != 0) {
-		nlattr_add_u32(nw, NHAF_AIF, nh->nh_aifp->if_index);
+		nlattr_add_u32(nw, NHAF_AIF, if_getindex(nh->nh_aifp));
 
 		if (uidx == 0) {
 			nlattr_add_u32(nw, NHAF_KID, nhop_get_idx(nh));
@@ -679,7 +679,7 @@ nlattr_get_nhg(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void
 }
 
 static void
-set_scope6(struct sockaddr *sa, struct ifnet *ifp)
+set_scope6(struct sockaddr *sa, if_t ifp)
 {
 #ifdef INET6
 	if (sa != NULL && sa->sa_family == AF_INET6 && ifp != NULL) {
@@ -799,7 +799,7 @@ newnhg(struct unhop_ctl *ctl, struct nl_parsed_nhop *attrs, struct user_nhop *un
  * Returns 0 on success or errno.
  */
 int
-nl_set_nexthop_gw(struct nhop_object *nh, struct sockaddr *gw, struct ifnet *ifp,
+nl_set_nexthop_gw(struct nhop_object *nh, struct sockaddr *gw, if_t ifp,
     struct nl_pstate *npt)
 {
 #ifdef INET6
@@ -810,7 +810,7 @@ nl_set_nexthop_gw(struct nhop_object *nh, struct sockaddr *gw, struct ifnet *ifp
 				NLMSG_REPORT_ERR_MSG(npt, "interface not set");
 				return (EINVAL);
 			}
-			in6_set_unicast_scopeid(&gw6->sin6_addr, ifp->if_index);
+			in6_set_unicast_scopeid(&gw6->sin6_addr, if_getindex(ifp));
 		}
 	}
 #endif
@@ -908,7 +908,7 @@ rtnl_handle_newnhop(struct nlmsghdr *hdr, struct nlpcb *nlp,
 		}
 	}
 
-	NL_LOG(LOG_DEBUG, "IFINDEX %d", attrs.nha_oif ? attrs.nha_oif->if_index : 0);
+	NL_LOG(LOG_DEBUG, "IFINDEX %d", attrs.nha_oif ? if_getindex(attrs.nha_oif) : 0);
 
 	unhop = malloc(sizeof(struct user_nhop), M_NETLINK, M_NOWAIT | M_ZERO);
 	if (unhop == NULL) {
diff --git a/sys/netlink/route/rt.c b/sys/netlink/route/rt.c
index e194b8f009c1..70101680e2c0 100644
--- a/sys/netlink/route/rt.c
+++ b/sys/netlink/route/rt.c
@@ -201,7 +201,7 @@ dump_rc_nhg(struct nl_writer *nw, const struct nhgrp_object *nhg, struct rtmsg *
 		if (rtnh == NULL)
 			return;
 		rtnh->rtnh_flags = 0;
-		rtnh->rtnh_ifindex = wn[i].nh->nh_ifp->if_index;
+		rtnh->rtnh_ifindex = if_getindex(wn[i].nh->nh_ifp);
 		rtnh->rtnh_hops = wn[i].weight;
 		dump_rc_nhop_gw(nw, wn[i].nh);
 		uint32_t rtflags = nhop_get_rtflags(wn[i].nh);
@@ -256,7 +256,7 @@ dump_rc_nhop(struct nl_writer *nw, const struct route_nhop_data *rnd, struct rtm
 		nlattr_add_u32(nw, NL_RTA_EXPIRES, nh_expire - time_uptime);
 
 	/* In any case, fill outgoing interface */
-	nlattr_add_u32(nw, NL_RTA_OIF, nh->nh_ifp->if_index);
+	nlattr_add_u32(nw, NL_RTA_OIF, if_getindex(nh->nh_ifp));
 
 	if (rnd->rnd_weight != RT_DEFAULT_WEIGHT)
 		nlattr_add_u32(nw, NL_RTA_WEIGHT, rnd->rnd_weight);