git: 3c851dc19bbd - main - netlink: provide original interface lladdr in the interface dump.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 10 May 2023 09:57:52 UTC
The branch main has been updated by melifaro:
URL: https://cgit.FreeBSD.org/src/commit/?id=3c851dc19bbde2056a9367cc43e935f9a35925a4
commit 3c851dc19bbde2056a9367cc43e935f9a35925a4
Author: Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-05-10 09:49:34 +0000
Commit: Alexander V. Chernikov <melifaro@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