Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147915597
D44392.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D44392.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D44392: linux: make linux_netlink_p->msg_from_linux be able to fail
Attached
Detach File
Event Timeline
Log In to Comment