linux: fix reporting NL_RTM_DELLINK to Netlink sockets
The problem is that ifname_bsd_to_linux_name() requires the interface to exist. But when we are in the context of ifnet_departure_event EVENTHANDLER(9), it does not. Instead of silently dropping the message, let's send the FreeBSD name verbatim. At the moment special translation is done for IFT_LOOPBACK and IFT_ETHER only, and these two kinds of interfaces usually don't depart. So, this is not a final fix, but definitely an improvement. While here, simplify the associated code. Differential Revision: https://reviews.freebsd.org/D51927
This commit is contained in:
@@ -241,25 +241,10 @@ nlmsg_copy_nla(const struct nlattr *nla_orig, struct nl_writer *nw)
|
||||
return (false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate a FreeBSD interface name to a Linux interface name.
|
||||
*/
|
||||
static bool
|
||||
nlmsg_translate_ifname_nla(struct nlattr *nla, struct nl_writer *nw)
|
||||
{
|
||||
char ifname[LINUX_IFNAMSIZ];
|
||||
|
||||
if (ifname_bsd_to_linux_name((char *)(nla + 1), ifname,
|
||||
sizeof(ifname)) <= 0)
|
||||
return (false);
|
||||
return (nlattr_add_string(nw, IFLA_IFNAME, ifname));
|
||||
}
|
||||
|
||||
#define LINUX_NLA_UNHANDLED -1
|
||||
/*
|
||||
* Translate a FreeBSD attribute to a Linux attribute.
|
||||
* Returns LINUX_NLA_UNHANDLED when the attribute is not processed
|
||||
* and the caller must take care of it, otherwise the result is returned.
|
||||
* Returns false when the attribute is not processed and the caller must take
|
||||
* care of it.
|
||||
*/
|
||||
static int
|
||||
nlmsg_translate_all_nla(struct nlmsghdr *hdr, struct nlattr *nla,
|
||||
@@ -271,22 +256,27 @@ nlmsg_translate_all_nla(struct nlmsghdr *hdr, struct nlattr *nla,
|
||||
case NL_RTM_DELLINK:
|
||||
case NL_RTM_GETLINK:
|
||||
switch (nla->nla_type) {
|
||||
case IFLA_IFNAME:
|
||||
return (nlmsg_translate_ifname_nla(nla, nw));
|
||||
case IFLA_IFNAME: {
|
||||
char ifname[LINUX_IFNAMSIZ];
|
||||
|
||||
if (ifname_bsd_to_linux_name((char *)(nla + 1), ifname,
|
||||
sizeof(ifname)) > 0)
|
||||
return (true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (LINUX_NLA_UNHANDLED);
|
||||
return (false);
|
||||
}
|
||||
|
||||
static bool
|
||||
nlmsg_copy_all_nla(struct nlmsghdr *hdr, int raw_hdrlen, struct nl_writer *nw)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int ret;
|
||||
|
||||
int hdrlen = NETLINK_ALIGN(raw_hdrlen);
|
||||
int attrs_len = hdr->nlmsg_len - sizeof(struct nlmsghdr) - hdrlen;
|
||||
@@ -297,15 +287,12 @@ nlmsg_copy_all_nla(struct nlmsghdr *hdr, int raw_hdrlen, struct nl_writer *nw)
|
||||
if (nla->nla_len < sizeof(struct nlattr)) {
|
||||
return (false);
|
||||
}
|
||||
ret = nlmsg_translate_all_nla(hdr, nla, nw);
|
||||
if (ret == LINUX_NLA_UNHANDLED)
|
||||
ret = nlmsg_copy_nla(nla, nw);
|
||||
if (!ret)
|
||||
if (!nlmsg_translate_all_nla(hdr, nla, nw) &&
|
||||
!nlmsg_copy_nla(nla, nw))
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
#undef LINUX_NLA_UNHANDLED
|
||||
|
||||
static unsigned int
|
||||
rtnl_if_flags_to_linux(unsigned int if_flags)
|
||||
|
||||
Reference in New Issue
Block a user