Page MenuHomeFreeBSD

D44392.diff
No OneTemporary

D44392.diff

diff --git a/sys/compat/linux/linux_netlink.c b/sys/compat/linux/linux_netlink.c
--- a/sys/compat/linux/linux_netlink.c
+++ b/sys/compat/linux/linux_netlink.c
@@ -31,7 +31,6 @@
#include <sys/types.h>
#include <sys/ck.h>
#include <sys/lock.h>
-#include <sys/malloc.h>
#include <sys/socket.h>
#include <sys/vnode.h>
@@ -73,37 +72,55 @@
return (*((const uint32_t *)NL_RTA_DATA_CONST(rta)));
}
-static struct nlmsghdr *
+static int
rtnl_neigh_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
struct ndmsg *ndm = (struct ndmsg *)(hdr + 1);
+ sa_family_t f;
+
+ if (hdr->nlmsg_len < sizeof(struct nlmsghdr) + sizeof(struct ndmsg))
+ return (EBADMSG);
+ if ((f = linux_to_bsd_domain(ndm->ndm_family)) == AF_UNKNOWN)
+ return (EPFNOSUPPORT);
- if (hdr->nlmsg_len >= sizeof(struct nlmsghdr) + sizeof(struct ndmsg))
- ndm->ndm_family = linux_to_bsd_domain(ndm->ndm_family);
+ ndm->ndm_family = f;
- return (hdr);
+ return (0);
}
-static struct nlmsghdr *
+static int
rtnl_ifaddr_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
struct ifaddrmsg *ifam = (struct ifaddrmsg *)(hdr + 1);
+ sa_family_t f;
- if (hdr->nlmsg_len >= sizeof(struct nlmsghdr) + sizeof(struct ifaddrmsg))
- ifam->ifa_family = linux_to_bsd_domain(ifam->ifa_family);
+ if (hdr->nlmsg_len < sizeof(struct nlmsghdr) + sizeof(struct ifaddrmsg))
+ return (EBADMSG);
+ if ((f = linux_to_bsd_domain(ifam->ifa_family)) == AF_UNKNOWN)
+ return (EPFNOSUPPORT);
- return (hdr);
+ ifam->ifa_family = f;
+
+ return (0);
}
-static struct nlmsghdr *
+/*
+ * XXX: in case of error state of hdr is inconsistent.
+ */
+static int
rtnl_route_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
/* Tweak address families and default fib only */
struct rtmsg *rtm = (struct rtmsg *)(hdr + 1);
struct nlattr *nla, *nla_head;
int attrs_len;
+ sa_family_t f;
- rtm->rtm_family = linux_to_bsd_domain(rtm->rtm_family);
+ if (hdr->nlmsg_len < sizeof(struct nlmsghdr) + sizeof(struct rtmsg))
+ return (EBADMSG);
+ if ((f = linux_to_bsd_domain(rtm->rtm_family)) == AF_UNKNOWN)
+ return (EPFNOSUPPORT);
+ rtm->rtm_family = f;
if (rtm->rtm_table == 254)
rtm->rtm_table = 0;
@@ -122,7 +139,7 @@
switch (rta->rta_type) {
case NL_RTA_TABLE:
if (!valid_rta_u32(rta))
- goto done;
+ return (EBADMSG);
rtm->rtm_table = 0;
uint32_t fibnum = _rta_get_uint32(rta);
RT_LOG(LOG_DEBUG3, "GET RTABLE: %u", fibnum);
@@ -133,13 +150,13 @@
}
}
-done:
- return (hdr);
+ return (0);
}
-static struct nlmsghdr *
+static int
rtnl_from_linux(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
+
switch (hdr->nlmsg_type) {
case NL_RTM_GETROUTE:
case NL_RTM_NEWROUTE:
@@ -157,21 +174,22 @@
default:
RT_LOG(LOG_DEBUG, "Passing message type %d untranslated",
hdr->nlmsg_type);
+ /* XXXGL: maybe return error? */
}
- return (hdr);
+ return (0);
}
-static struct nlmsghdr *
-nlmsg_from_linux(int netlink_family, struct nlmsghdr *hdr,
+static int
+nlmsg_from_linux(int netlink_family, struct nlmsghdr **hdr,
struct nl_pstate *npt)
{
switch (netlink_family) {
case NETLINK_ROUTE:
- return (rtnl_from_linux(hdr, npt));
+ return (rtnl_from_linux(*hdr, npt));
}
- return (hdr);
+ return (0);
}
diff --git a/sys/netlink/netlink_io.c b/sys/netlink/netlink_io.c
--- a/sys/netlink/netlink_io.c
+++ b/sys/netlink/netlink_io.c
@@ -275,25 +275,21 @@
npt->hdr = hdr;
- if (hdr->nlmsg_flags & NLM_F_REQUEST && hdr->nlmsg_type >= NLMSG_MIN_TYPE) {
+ if (hdr->nlmsg_flags & NLM_F_REQUEST &&
+ hdr->nlmsg_type >= NLMSG_MIN_TYPE) {
NL_LOG(LOG_DEBUG2, "handling message with msg type: %d",
hdr->nlmsg_type);
-
- if (nlp->nl_linux && linux_netlink_p != NULL) {
- struct nlmsghdr *hdr_orig = hdr;
- hdr = linux_netlink_p->msg_from_linux(nlp->nl_proto, hdr, npt);
- if (hdr == NULL) {
- /* Failed to translate to kernel format. Report an error back */
- hdr = hdr_orig;
- npt->hdr = hdr;
- if (hdr->nlmsg_flags & NLM_F_ACK)
- nlmsg_ack(nlp, EOPNOTSUPP, hdr, npt);
- return (0);
- }
+ if (nlp->nl_linux) {
+ MPASS(linux_netlink_p != NULL);
+ error = linux_netlink_p->msg_from_linux(nlp->nl_proto,
+ &hdr, npt);
+ if (error)
+ goto ack;
}
error = handler(hdr, npt);
NL_LOG(LOG_DEBUG2, "retcode: %d", error);
}
+ack:
if ((hdr->nlmsg_flags & NLM_F_ACK) || (error != 0 && error != EINTR)) {
if (!npt->nw->suppress_ack) {
NL_LOG(LOG_DEBUG3, "ack");
diff --git a/sys/netlink/netlink_linux.h b/sys/netlink/netlink_linux.h
--- a/sys/netlink/netlink_linux.h
+++ b/sys/netlink/netlink_linux.h
@@ -38,7 +38,7 @@
struct nl_writer;
typedef bool msgs_to_linux_cb_t(struct nl_writer *nw, struct nlpcb *nlp);
-typedef struct nlmsghdr *msg_from_linux_cb_t(int netlink_family, struct nlmsghdr *hdr,
+typedef int msg_from_linux_cb_t(int netlink_family, struct nlmsghdr **hdr,
struct nl_pstate *npt);
struct linux_netlink_provider {

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 15, 3:37 PM (12 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29721766
Default Alt Text
D44392.diff (4 KB)

Event Timeline