aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPouria Mousavizadeh Tehrani <pouria@FreeBSD.org>2026-07-17 16:11:42 +0000
committerPouria Mousavizadeh Tehrani <pouria@FreeBSD.org>2026-07-20 17:27:15 +0000
commitb00d30950cde27eda8f51523a40f2c05a38daac1 (patch)
tree901e80e9c515ad76080d54d37332ec4da04d1408
parent6671bbf2f9bb130129a4896bca7edb9e0a638e9f (diff)
net/if.c: Add fib-aware ifa_ifwithaddr()
Add FIB selection logic by introducing ifa_ifwithaddr_fib() to support FIB-specific lookups. Then have ifa_ifwithaddr() wrap it with RT_ALL_FIBS. Also, do the same for ifa_ifwithaddr_check(). Reviewed by: glebius, bnovkov Differential Revision: https://reviews.freebsd.org/D58305
-rw-r--r--sys/net/if.c29
-rw-r--r--sys/net/if_var.h2
2 files changed, 25 insertions, 6 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 440b40102d53..1c57eb1492c2 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1708,18 +1708,18 @@ sa_dl_equal(const struct sockaddr *a, const struct sockaddr *b)
}
/*
- * Locate an interface based on a complete address.
+ * Locate an interface on the specified fib based on a complete address.
*/
-/*ARGSUSED*/
struct ifaddr *
-ifa_ifwithaddr(const struct sockaddr *addr)
+ifa_ifwithaddr_fib(const struct sockaddr *addr, int fibnum)
{
struct ifnet *ifp;
struct ifaddr *ifa;
NET_EPOCH_ASSERT();
-
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+ if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum))
+ continue;
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != addr->sa_family)
continue;
@@ -1740,18 +1740,35 @@ done:
return (ifa);
}
+/*
+ * Locate an interface based on a complete address.
+ */
+struct ifaddr *
+ifa_ifwithaddr(const struct sockaddr *addr)
+{
+
+ return (ifa_ifwithaddr_fib(addr, RT_ALL_FIBS));
+}
+
int
-ifa_ifwithaddr_check(const struct sockaddr *addr)
+ifa_ifwithaddr_fib_check(const struct sockaddr *addr, int fibnum)
{
struct epoch_tracker et;
int rc;
NET_EPOCH_ENTER(et);
- rc = (ifa_ifwithaddr(addr) != NULL);
+ rc = (ifa_ifwithaddr_fib(addr, fibnum) != NULL);
NET_EPOCH_EXIT(et);
return (rc);
}
+int
+ifa_ifwithaddr_check(const struct sockaddr *addr)
+{
+
+ return (ifa_ifwithaddr_fib_check(addr, RT_ALL_FIBS));
+}
+
/*
* Locate an interface based on the broadcast address.
*/
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 3c65b2b4d2d8..9a425fd81054 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -563,7 +563,9 @@ int ifa_add_loopback_route(struct ifaddr *, struct sockaddr *);
int ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);
int ifa_switch_loopback_route(struct ifaddr *, struct sockaddr *);
+struct ifaddr *ifa_ifwithaddr_fib(const struct sockaddr *, int);
struct ifaddr *ifa_ifwithaddr(const struct sockaddr *);
+int ifa_ifwithaddr_fib_check(const struct sockaddr *, int);
int ifa_ifwithaddr_check(const struct sockaddr *);
struct ifaddr *ifa_ifwithbroadaddr(const struct sockaddr *, int);
struct ifaddr *ifa_ifwithdstaddr(const struct sockaddr *, int);