The branch main has been updated by melifaro:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3c851dc19bbde2056a9367cc43e935f9a35925a4

commit 3c851dc19bbde2056a9367cc43e935f9a35925a4
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2023-05-10 09:49:34 +0000
Commit:     Alexander V. Chernikov <melif...@freebsd.org>
CommitDate: 2023-05-10 09:57:01 +0000

    netlink: provide original interface lladdr in the interface dump.
    
    * Store lladdr in the FreeBSD-specific IFLAF_ORIG_HWADDR attr
    * Do not export empty IFLA_ADDRESS for interfaces w/o lladdrs.
    
    MFC after:      2 weeks
---
 sys/netlink/netlink_snl_route_parsers.h |  9 ++++++++-
 sys/netlink/route/iface.c               | 25 +++++++++++++++++++++++--
 sys/netlink/route/interface.h           |  9 +++++++++
 3 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/sys/netlink/netlink_snl_route_parsers.h 
b/sys/netlink/netlink_snl_route_parsers.h
index a4877a4d7939..75ba6d461731 100644
--- a/sys/netlink/netlink_snl_route_parsers.h
+++ b/sys/netlink/netlink_snl_route_parsers.h
@@ -202,10 +202,16 @@ struct snl_parsed_link {
        char                            *ifla_ifalias;
        uint32_t                        ifla_promiscuity;
        struct rtnl_link_stats64        *ifla_stats64;
+       struct nlattr                   *iflaf_orig_hwaddr;
 };
 
 #define        _IN(_field)     offsetof(struct ifinfomsg, _field)
 #define        _OUT(_field)    offsetof(struct snl_parsed_link, _field)
+static const struct snl_attr_parser _nla_p_link_fbsd[] = {
+       { .type = IFLAF_ORIG_HWADDR, .off = _OUT(iflaf_orig_hwaddr), .cb = 
snl_attr_dup_nla },
+};
+SNL_DECLARE_ATTR_PARSER(_link_fbsd_parser, _nla_p_link_fbsd);
+
 static const struct snl_attr_parser _nla_p_link[] = {
        { .type = IFLA_ADDRESS, .off = _OUT(ifla_address), .cb = 
snl_attr_dup_nla },
        { .type = IFLA_BROADCAST, .off = _OUT(ifla_broadcast), .cb = 
snl_attr_dup_nla },
@@ -216,6 +222,7 @@ static const struct snl_attr_parser _nla_p_link[] = {
        { .type = IFLA_STATS64, .off = _OUT(ifla_stats64), .cb = 
snl_attr_dup_struct },
        { .type = IFLA_PROMISCUITY, .off = _OUT(ifla_promiscuity), .cb = 
snl_attr_get_uint32 },
        { .type = IFLA_CARRIER, .off = _OUT(ifla_carrier), .cb = 
snl_attr_get_uint8 },
+       { .type = IFLA_FREEBSD, .arg = &_link_fbsd_parser, .cb = 
snl_attr_get_nested },
 };
 static const struct snl_field_parser _fp_p_link[] = {
        {.off_in = _IN(ifi_index), .off_out = _OUT(ifi_index), .cb = 
snl_field_get_uint32 },
@@ -394,7 +401,7 @@ SNL_DECLARE_PARSER_EXT(snl_nhmsg_parser, struct nhmsg, 
_fp_p_nh, _nla_p_nh, _cb_
 
 static const struct snl_hdr_parser *snl_all_route_parsers[] = {
        &_metrics_mp_nh_parser, &_mpath_nh_parser, &_metrics_parser, 
&snl_rtm_route_parser,
-       &snl_rtm_link_parser, &snl_rtm_link_parser_simple,
+       &_link_fbsd_parser, &snl_rtm_link_parser, &snl_rtm_link_parser_simple,
        &_neigh_fbsd_parser, &snl_rtm_neigh_parser,
        &_addr_fbsd_parser, &snl_rtm_addr_parser, &_nh_fbsd_parser, 
&snl_nhmsg_parser,
 };
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index edcf8b635f50..aaed11e637a2 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -194,6 +194,17 @@ get_operstate(struct ifnet *ifp, struct if_state *pstate)
        }
 }
 
+static void
+get_hwaddr(struct nl_writer *nw, struct ifnet *ifp)
+{
+       struct ifreq ifr = {};
+
+       if (if_gethwaddr(ifp, &ifr) == 0) {
+               nlattr_add(nw, IFLAF_ORIG_HWADDR, if_getaddrlen(ifp),
+                   ifr.ifr_addr.sa_data);
+       }
+}
+
 static unsigned
 ifp_flags_to_netlink(const struct ifnet *ifp)
 {
@@ -281,8 +292,10 @@ dump_iface(struct nl_writer *nw, struct ifnet *ifp, const 
struct nlmsghdr *hdr,
         nlattr_add_u8(nw, IFLA_PROTO_DOWN, val);
         nlattr_add_u8(nw, IFLA_LINKMODE, val);
 */
-        if ((ifp->if_addr != NULL)) {
-                dump_sa(nw, IFLA_ADDRESS, ifp->if_addr->ifa_addr);
+        if (if_getaddrlen(ifp) != 0) {
+               struct ifaddr *ifa = if_getifaddr(ifp);
+
+                dump_sa(nw, IFLA_ADDRESS, ifa->ifa_addr);
         }
 
         if ((ifp->if_broadcastaddr != NULL)) {
@@ -300,6 +313,14 @@ dump_iface(struct nl_writer *nw, struct ifnet *ifp, const 
struct nlmsghdr *hdr,
        if (ifp->if_description != NULL)
                nlattr_add_string(nw, IFLA_IFALIAS, ifp->if_description);
 
+       /* Store FreeBSD-specific attributes */
+       int off = nlattr_add_nested(nw, IFLA_FREEBSD);
+       if (off != 0) {
+               get_hwaddr(nw, ifp);
+
+               nlattr_set_len(nw, off);
+       }
+
        get_stats(nw, ifp);
 
        uint32_t val = (ifp->if_flags & IFF_PROMISC) != 0;
diff --git a/sys/netlink/route/interface.h b/sys/netlink/route/interface.h
index ec0e1e246a07..c78a0be60a21 100644
--- a/sys/netlink/route/interface.h
+++ b/sys/netlink/route/interface.h
@@ -142,10 +142,19 @@ enum {
        IFLA_DEVLINK_PORT,
        IFLA_GSO_IPV4_MAX_SIZE,
        IFLA_GRO_IPV4_MAX_SIZE,
+       IFLA_FREEBSD,
        __IFLA_MAX
 };
 #define IFLA_MAX (__IFLA_MAX - 1)
 
+enum {
+       IFLAF_UNSPEC            = 0,
+       IFLAF_ORIG_IFNAME       = 1,    /* string, original interface name at 
creation */
+       IFLAF_ORIG_HWADDR       = 2,    /* binary, original hardware address */
+       __IFLAF_MAX
+};
+#define IFLAF_MAX (__IFLAF_MAX - 1)
+
 /*
  * Attributes that can be used as filters:
  *  IFLA_IFNAME, IFLA_GROUP, IFLA_ALT_IFNAME

Reply via email to