aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2023-01-06 19:13:42 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2023-01-06 19:18:54 +0000
commit13214c601a49d733bd17d42b927788bb9feea536 (patch)
tree49b6104c52cd3002dfb405803076d16714dc9b49
parent638937d466648a9e5733225aef62eeae02db4f03 (diff)
downloadsrc-13214c601a49d733bd17d42b927788bb9feea536.tar.gz
src-13214c601a49d733bd17d42b927788bb9feea536.zip
netlink: fix ifaddr reporting.
Output the proper attributes for IPv4/IPvv6 ifaddrs: * IFA_ADDRESS contains local address in every case except p2p, in that case it contains the peer address * IFA_LOCAL contains local address. It is always present in IPv4, or in IPv6/p2p. * IFA_BROADCAST contains the network broadcast address (if any) Reported by: Adam Wood <aswood@gmail.com> Tested by: Adam Wood <aswood@gmail.com>
-rw-r--r--sys/netlink/route/iface.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index b033ba71009d..81ae5bc8090f 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -794,11 +794,23 @@ dump_iface_addr(struct nl_writer *nw, struct ifnet *ifp, struct ifaddr *ifa,
ifamsg->ifa_scope = ifa_get_scope(ifa);
ifamsg->ifa_index = ifp->if_index;
- struct sockaddr *dst_sa = ifa->ifa_dstaddr;
- if ((dst_sa == NULL) || (dst_sa->sa_family != sa->sa_family))
- dst_sa = sa;
- dump_sa(nw, IFA_ADDRESS, dst_sa);
- dump_sa(nw, IFA_LOCAL, sa);
+ if (ifp->if_flags & IFF_POINTOPOINT) {
+ dump_sa(nw, IFA_ADDRESS, ifa->ifa_dstaddr);
+ dump_sa(nw, IFA_LOCAL, sa);
+ } else {
+ dump_sa(nw, IFA_ADDRESS, sa);
+#ifdef INET
+ /*
+ * In most cases, IFA_ADDRESS == IFA_LOCAL
+ * Skip IFA_LOCAL for anything except INET
+ */
+ if (sa->sa_family == AF_INET)
+ dump_sa(nw, IFA_LOCAL, sa);
+#endif
+ }
+ if (ifp->if_flags & IFF_BROADCAST)
+ dump_sa(nw, IFA_BROADCAST, ifa->ifa_broadaddr);
+
nlattr_add_string(nw, IFA_LABEL, if_name(ifp));
uint32_t val = 0; // ifa->ifa_flags;