git: 9c89392f12d7 - main - Add in_localip_fib(), in6_localip_fib().

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Fri, 12 Nov 2021 17:07:23 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=9c89392f12d707db8992ff8017d397bd8b0cd69b

commit 9c89392f12d707db8992ff8017d397bd8b0cd69b
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2021-11-12 16:59:42 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2021-11-12 16:59:42 +0000

    Add in_localip_fib(), in6_localip_fib().
    
    Check if given address/FIB exists locally.
    
    Reviewed by:            melifaro
    Differential revision:  https://reviews.freebsd.org/D32913
---
 sys/netinet/in.c   | 18 ++++++++++++++++++
 sys/netinet/in.h   |  1 +
 sys/netinet6/in6.c | 21 +++++++++++++++++++++
 sys/netinet6/in6.h |  1 +
 4 files changed, 41 insertions(+)

diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 6bc4f638a98a..fccad3d9ede2 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -137,6 +137,24 @@ in_localip(struct in_addr in)
 	return (false);
 }
 
+/*
+ * Like in_localip(), but FIB-aware.
+ */
+bool
+in_localip_fib(struct in_addr in, uint16_t fib)
+{
+	struct in_ifaddr *ia;
+
+	NET_EPOCH_ASSERT();
+
+	CK_LIST_FOREACH(ia, INADDR_HASH(in.s_addr), ia_hash)
+		if (IA_SIN(ia)->sin_addr.s_addr == in.s_addr &&
+		    ia->ia_ifa.ifa_ifp->if_fib == fib)
+			return (true);
+
+	return (false);
+}
+
 /*
  * Return 1 if an internet address is configured on an interface.
  */
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 92d150701422..1fc5c173b33c 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -662,6 +662,7 @@ int	 in_ifaddr_broadcast(struct in_addr, struct in_ifaddr *);
 int	 in_canforward(struct in_addr);
 int	 in_localaddr(struct in_addr);
 bool	 in_localip(struct in_addr);
+bool	 in_localip_fib(struct in_addr, uint16_t);
 int	 in_ifhasaddr(struct ifnet *, struct in_addr);
 struct in_ifaddr *in_findlocal(uint32_t, bool);
 int	 inet_aton(const char *, struct in_addr *); /* in libkern */
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index d54aba58edb6..feee4f3f64a5 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1753,6 +1753,27 @@ in6_localip(struct in6_addr *in6)
 	return (0);
 }
 
+/*
+ * Like in6_localip(), but FIB-aware.
+ */
+bool
+in6_localip_fib(struct in6_addr *in6, uint16_t fib)
+{
+	struct rm_priotracker in6_ifa_tracker;
+	struct in6_ifaddr *ia;
+
+	IN6_IFADDR_RLOCK(&in6_ifa_tracker);
+	CK_LIST_FOREACH(ia, IN6ADDR_HASH(in6), ia6_hash) {
+		if (IN6_ARE_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr) &&
+		    ia->ia_ifa.ifa_ifp->if_fib == fib) {
+			IN6_IFADDR_RUNLOCK(&in6_ifa_tracker);
+			return (true);
+		}
+	}
+	IN6_IFADDR_RUNLOCK(&in6_ifa_tracker);
+	return (false);
+}
+
 /*
  * Return 1 if an internet address is configured on an interface.
  */
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h
index 10bc1f91c554..34682da04898 100644
--- a/sys/netinet6/in6.h
+++ b/sys/netinet6/in6.h
@@ -674,6 +674,7 @@ int	in6_cksum_partial(struct mbuf *, u_int8_t, u_int32_t, u_int32_t,
 			  u_int32_t);
 int	in6_localaddr(struct in6_addr *);
 int	in6_localip(struct in6_addr *);
+bool	in6_localip_fib(struct in6_addr *, uint16_t);
 int	in6_ifhasaddr(struct ifnet *, struct in6_addr *);
 int	in6_addrscope(const struct in6_addr *);
 char	*ip6_sprintf(char *, const struct in6_addr *);