mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-26 10:53:39 +01:00
netlink: export more IPv6 ifa info
* Fill in IFA_CACHEINFO with prefix lifetime data * Map IPv6 IN6_IFF_ flags to Netlink IFA_F_ flags * Store original ia6_flags in the FreeBSD-specific IFAF_FLAGS field MFC after: 2 weeks
This commit is contained in:
parent
1224878016
commit
30d0fc6f33
@ -302,13 +302,16 @@ struct snl_parsed_addr {
|
||||
struct sockaddr *ifa_address;
|
||||
struct sockaddr *ifa_broadcast;
|
||||
char *ifa_label;
|
||||
struct ifa_cacheinfo *ifa_cacheinfo;
|
||||
uint32_t ifaf_vhid;
|
||||
uint32_t ifaf_flags;
|
||||
};
|
||||
|
||||
#define _IN(_field) offsetof(struct ifaddrmsg, _field)
|
||||
#define _OUT(_field) offsetof(struct snl_parsed_addr, _field)
|
||||
static const struct snl_attr_parser _nla_p_addr_fbsd[] = {
|
||||
{ .type = IFAF_VHID, .off = _OUT(ifaf_vhid), .cb = snl_attr_get_uint32 },
|
||||
{ .type = IFAF_FLAGS, .off = _OUT(ifaf_flags), .cb = snl_attr_get_uint32 },
|
||||
};
|
||||
SNL_DECLARE_ATTR_PARSER(_addr_fbsd_parser, _nla_p_addr_fbsd);
|
||||
|
||||
@ -317,6 +320,7 @@ static const struct snl_attr_parser _nla_p_addr_s[] = {
|
||||
{ .type = IFA_LOCAL, .off = _OUT(ifa_local), .cb = snl_attr_get_ip },
|
||||
{ .type = IFA_LABEL, .off = _OUT(ifa_label), .cb = snl_attr_dup_string },
|
||||
{ .type = IFA_BROADCAST, .off = _OUT(ifa_broadcast), .cb = snl_attr_get_ip },
|
||||
{ .type = IFA_CACHEINFO, .off = _OUT(ifa_cacheinfo), .cb = snl_attr_dup_struct },
|
||||
{ .type = IFA_FREEBSD, .arg = &_addr_fbsd_parser, .cb = snl_attr_get_nested },
|
||||
};
|
||||
static const struct snl_field_parser _fp_p_addr_s[] = {
|
||||
|
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/route.h>
|
||||
#include <net/route/nhop.h>
|
||||
#include <net/route/route_ctl.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/netlink_ctl.h>
|
||||
#include <netlink/netlink_route.h>
|
||||
@ -749,6 +750,52 @@ get_sa_plen(const struct sockaddr *sa)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
static uint32_t
|
||||
in6_flags_to_nl(uint32_t flags)
|
||||
{
|
||||
uint32_t nl_flags = 0;
|
||||
|
||||
if (flags & IN6_IFF_TEMPORARY)
|
||||
nl_flags |= IFA_F_TEMPORARY;
|
||||
if (flags & IN6_IFF_NODAD)
|
||||
nl_flags |= IFA_F_NODAD;
|
||||
if (flags & IN6_IFF_DEPRECATED)
|
||||
nl_flags |= IFA_F_DEPRECATED;
|
||||
if (flags & IN6_IFF_TENTATIVE)
|
||||
nl_flags |= IFA_F_TENTATIVE;
|
||||
if ((flags & (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY)) == 0)
|
||||
flags |= IFA_F_PERMANENT;
|
||||
if (flags & IN6_IFF_DUPLICATED)
|
||||
flags |= IFA_F_DADFAILED;
|
||||
return (nl_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
export_cache_info6(struct nl_writer *nw, const struct in6_ifaddr *ia)
|
||||
{
|
||||
struct ifa_cacheinfo ci = {
|
||||
.cstamp = ia->ia6_createtime * 1000,
|
||||
.tstamp = ia->ia6_updatetime * 1000,
|
||||
.ifa_prefered = ia->ia6_lifetime.ia6t_pltime,
|
||||
.ifa_valid = ia->ia6_lifetime.ia6t_vltime,
|
||||
};
|
||||
|
||||
nlattr_add(nw, IFA_CACHEINFO, sizeof(ci), &ci);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
export_cache_info(struct nl_writer *nw, struct ifaddr *ifa)
|
||||
{
|
||||
switch (ifa->ifa_addr->sa_family) {
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
export_cache_info6(nw, (struct in6_ifaddr *)ifa);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* {'attrs': [('IFA_ADDRESS', '12.0.0.1'),
|
||||
@ -796,8 +843,17 @@ dump_iface_addr(struct nl_writer *nw, struct ifnet *ifp, struct ifaddr *ifa,
|
||||
|
||||
nlattr_add_string(nw, IFA_LABEL, if_name(ifp));
|
||||
|
||||
uint32_t val = 0; // ifa->ifa_flags;
|
||||
nlattr_add_u32(nw, IFA_FLAGS, val);
|
||||
uint32_t nl_ifa_flags = 0;
|
||||
#ifdef INET6
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
|
||||
nl_ifa_flags = in6_flags_to_nl(ia->ia6_flags);
|
||||
}
|
||||
#endif
|
||||
nlattr_add_u32(nw, IFA_FLAGS, nl_ifa_flags);
|
||||
|
||||
export_cache_info(nw, ifa);
|
||||
|
||||
/* Store FreeBSD-specific attributes */
|
||||
int off = nlattr_add_nested(nw, IFA_FREEBSD);
|
||||
if (off != 0) {
|
||||
@ -805,6 +861,14 @@ dump_iface_addr(struct nl_writer *nw, struct ifnet *ifp, struct ifaddr *ifa,
|
||||
uint32_t vhid = (uint32_t)(*carp_get_vhid_p)(ifa);
|
||||
nlattr_add_u32(nw, IFAF_VHID, vhid);
|
||||
}
|
||||
#ifdef INET6
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
uint32_t ifa_flags = ((struct in6_ifaddr *)ifa)->ia6_flags;
|
||||
|
||||
nlattr_add_u32(nw, IFAF_FLAGS, ifa_flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@ enum {
|
||||
enum {
|
||||
IFAF_UNSPEC,
|
||||
IFAF_VHID = 1, /* u32: carp vhid */
|
||||
IFAF_FLAGS = 2, /* u32: FreeBSD-specific ifa flags */
|
||||
__IFAF_MAX,
|
||||
};
|
||||
#define IFAF_MAX (__IFAF_MAX - 1)
|
||||
@ -89,10 +90,10 @@ enum {
|
||||
|
||||
/* IFA_CACHEINFO value */
|
||||
struct ifa_cacheinfo {
|
||||
uint32_t ifa_prefered;
|
||||
uint32_t ifa_valid;
|
||||
uint32_t cstamp;
|
||||
uint32_t tstamp;
|
||||
uint32_t ifa_prefered; /* seconds till the end of the prefix considered preferred */
|
||||
uint32_t ifa_valid; /* seconds till the end of the prefix considered valid */
|
||||
uint32_t cstamp; /* creation time in 1ms intervals from the boot time */
|
||||
uint32_t tstamp; /* update time in 1ms intervals from the boot time */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user