aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2025-01-29 17:48:02 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2025-01-29 23:48:55 +0000
commit876b88a44829123eeb685957ce80a762d894c4d8 (patch)
tree7882095a2ba523d317bfb16498ad26c829be0527
parent810c122695d72d277a07a2854172d6fd09fc9907 (diff)
netlink: consistently use unsigned types in the parser
Use uint32_t for anything that is derived from message length, use uint16_t for anything that represents attribute length and use u_int for array indices.
-rw-r--r--sys/netlink/netlink_ctl.h4
-rw-r--r--sys/netlink/netlink_message_parser.c42
-rw-r--r--sys/netlink/netlink_message_parser.h42
3 files changed, 43 insertions, 45 deletions
diff --git a/sys/netlink/netlink_ctl.h b/sys/netlink/netlink_ctl.h
index a23e9a3a948f..58f7f6c4abe3 100644
--- a/sys/netlink/netlink_ctl.h
+++ b/sys/netlink/netlink_ctl.h
@@ -47,8 +47,8 @@ MALLOC_DECLARE(M_NETLINK);
#define NLA_ALIGN_SIZE sizeof(uint32_t)
#define NLA_ALIGN(_len) _roundup2(_len, NLA_ALIGN_SIZE)
-#define NLA_HDRLEN ((int)sizeof(struct nlattr))
-#define NLA_DATA_LEN(_nla) ((int)((_nla)->nla_len - NLA_HDRLEN))
+#define NLA_HDRLEN ((uint16_t)sizeof(struct nlattr))
+#define NLA_DATA_LEN(_nla) ((_nla)->nla_len - NLA_HDRLEN)
#define NLA_DATA(_nla) NL_ITEM_DATA(_nla, NLA_HDRLEN)
#define NLA_DATA_CONST(_nla) NL_ITEM_DATA_CONST(_nla, NLA_HDRLEN)
#define NLA_TYPE(_nla) ((_nla)->nla_type & 0x3FFF)
diff --git a/sys/netlink/netlink_message_parser.c b/sys/netlink/netlink_message_parser.c
index 4a35440c50e0..caef40ff73b9 100644
--- a/sys/netlink/netlink_message_parser.c
+++ b/sys/netlink/netlink_message_parser.c
@@ -98,7 +98,7 @@ nlmsg_report_cookie_u32(struct nl_pstate *npt, uint32_t val)
}
static const struct nlattr_parser *
-search_states(const struct nlattr_parser *ps, int pslen, int key)
+search_states(const struct nlattr_parser *ps, u_int pslen, int key)
{
int left_i = 0, right_i = pslen - 1;
@@ -122,34 +122,37 @@ search_states(const struct nlattr_parser *ps, int pslen, int key)
}
int
-nl_parse_attrs_raw(struct nlattr *nla_head, int len,
- const struct nlattr_parser *ps, int pslen, struct nl_pstate *npt,
+nl_parse_attrs_raw(struct nlattr *nla_head, uint16_t len,
+ const struct nlattr_parser *ps, u_int pslen, struct nl_pstate *npt,
void *target)
{
- struct nlattr *nla = NULL;
+ const struct nlattr_parser *s;
+ struct nlattr *nla;
+ uint16_t orig_len, off;
int error = 0;
NL_LOG(LOG_DEBUG3, "parse %p remaining_len %d", nla_head, len);
- int orig_len = len;
+ orig_len = len;
NLA_FOREACH(nla, nla_head, len) {
- NL_LOG(LOG_DEBUG3, ">> parsing %p attr_type %d len %d (rem %d)",
+ NL_LOG(LOG_DEBUG3, ">> parsing %p attr_type %u len %u (rem %u)",
nla, nla->nla_type, nla->nla_len, len);
if (nla->nla_len < sizeof(struct nlattr)) {
NLMSG_REPORT_ERR_MSG(npt,
- "Invalid attr %p type %d len: %d",
+ "Invalid attr %p type %u len: %u",
nla, nla->nla_type, nla->nla_len);
- uint32_t off = (char *)nla - (char *)npt->hdr;
+ off = (char *)nla - (char *)npt->hdr;
nlmsg_report_err_offset(npt, off);
return (EINVAL);
}
- int nla_type = nla->nla_type & NLA_TYPE_MASK;
- const struct nlattr_parser *s = search_states(ps, pslen, nla_type);
+ s = search_states(ps, pslen, nla->nla_type & NLA_TYPE_MASK);
if (s != NULL) {
- void *ptr = (void *)((char *)target + s->off);
+ void *ptr;
+
+ ptr = (void *)((char *)target + s->off);
error = s->cb(nla, npt, s->arg, ptr);
if (error != 0) {
- uint32_t off = (char *)nla - (char *)npt->hdr;
+ off = (char *)nla - (char *)npt->hdr;
nlmsg_report_err_offset(npt, off);
NL_LOG(LOG_DEBUG3,
"parse failed at offset %u", off);
@@ -157,42 +160,43 @@ nl_parse_attrs_raw(struct nlattr *nla_head, int len,
}
} else {
/* Ignore non-specified attributes */
- NL_LOG(LOG_DEBUG3, "ignoring attr %d", nla->nla_type);
+ NL_LOG(LOG_DEBUG3, "ignoring attr %u", nla->nla_type);
}
}
if (len >= sizeof(struct nlattr)) {
nla = (struct nlattr *)((char *)nla_head + (orig_len - len));
- NL_LOG(LOG_DEBUG3, " >>> end %p attr_type %d len %d", nla,
+ NL_LOG(LOG_DEBUG3, " >>> end %p attr_type %u len %u", nla,
nla->nla_type, nla->nla_len);
}
- NL_LOG(LOG_DEBUG3, "end parse: %p remaining_len %d", nla, len);
+ NL_LOG(LOG_DEBUG3, "end parse: %p remaining_len %u", nla, len);
return (0);
}
void
-nl_get_attrs_bmask_raw(struct nlattr *nla_head, int len,
+nl_get_attrs_bmask_raw(struct nlattr *nla_head, uint32_t len,
struct nlattr_bmask *bm)
{
struct nlattr *nla = NULL;
+ uint16_t nla_type;
BIT_ZERO(NL_ATTR_BMASK_SIZE, bm);
NLA_FOREACH(nla, nla_head, len) {
if (nla->nla_len < sizeof(struct nlattr))
return;
- int nla_type = nla->nla_type & NLA_TYPE_MASK;
+ nla_type = nla->nla_type & NLA_TYPE_MASK;
if (nla_type < NL_ATTR_BMASK_SIZE)
BIT_SET(NL_ATTR_BMASK_SIZE, nla_type, bm);
else
NL_LOG(LOG_DEBUG2,
- "Skipping type %d in the mask: too short",
+ "Skipping type %u in the mask: too short",
nla_type);
}
}
bool
-nl_has_attr(const struct nlattr_bmask *bm, unsigned int nla_type)
+nl_has_attr(const struct nlattr_bmask *bm, uint16_t nla_type)
{
MPASS(nla_type < NL_ATTR_BMASK_SIZE);
diff --git a/sys/netlink/netlink_message_parser.h b/sys/netlink/netlink_message_parser.h
index 13d52d80ecdc..8492ecb3021b 100644
--- a/sys/netlink/netlink_message_parser.h
+++ b/sys/netlink/netlink_message_parser.h
@@ -112,10 +112,10 @@ typedef bool strict_parser_f(void *hdr, struct nl_pstate *npt);
typedef bool post_parser_f(void *parsed_attrs, struct nl_pstate *npt);
struct nlhdr_parser {
- int nl_hdr_off; /* aligned netlink header size */
- int out_hdr_off; /* target header size */
- int fp_size;
- int np_size;
+ u_int nl_hdr_off; /* aligned netlink header size */
+ u_int out_hdr_off; /* target header size */
+ u_int fp_size;
+ u_int np_size;
const struct nlfield_parser *fp; /* array of header field parsers */
const struct nlattr_parser *np; /* array of attribute parsers */
strict_parser_f *sp; /* Pre-parse strict validation function */
@@ -162,12 +162,12 @@ static const struct nlhdr_parser _name = { \
#define NL_ATTR_BMASK_SIZE 128
BITSET_DEFINE(nlattr_bmask, NL_ATTR_BMASK_SIZE);
-void nl_get_attrs_bmask_raw(struct nlattr *nla_head, int len,
+void nl_get_attrs_bmask_raw(struct nlattr *nla_head, uint32_t len,
struct nlattr_bmask *bm);
-bool nl_has_attr(const struct nlattr_bmask *bm, unsigned int nla_type);
+bool nl_has_attr(const struct nlattr_bmask *bm, uint16_t nla_type);
-int nl_parse_attrs_raw(struct nlattr *nla_head, int len,
- const struct nlattr_parser *ps, int pslen, struct nl_pstate *npt,
+int nl_parse_attrs_raw(struct nlattr *nla_head, uint16_t len,
+ const struct nlattr_parser *ps, u_int pslen, struct nl_pstate *npt,
void *target);
int nlattr_get_flag(struct nlattr *nla, struct nl_pstate *npt,
@@ -226,10 +226,9 @@ void nlmsg_report_cookie_u32(struct nl_pstate *npt, uint32_t val);
* the list of direct function calls without iteration.
*/
static inline int
-nl_parse_header(void *hdr, int len, const struct nlhdr_parser *parser,
+nl_parse_header(void *hdr, uint32_t len, const struct nlhdr_parser *parser,
struct nl_pstate *npt, void *target)
{
- struct nlattr *nla;
int error;
if (__predict_false(len < parser->nl_hdr_off)) {
@@ -258,7 +257,7 @@ nl_parse_header(void *hdr, int len, const struct nlhdr_parser *parser,
return (EINVAL);
/* Extract fields first */
- for (int i = 0; i < parser->fp_size; i++) {
+ for (u_int i = 0; i < parser->fp_size; i++) {
const struct nlfield_parser *fp = &parser->fp[i];
void *src = (char *)hdr + fp->off_in;
void *dst = (char *)target + fp->off_out;
@@ -268,9 +267,9 @@ nl_parse_header(void *hdr, int len, const struct nlhdr_parser *parser,
return (error);
}
- nla = (struct nlattr *)((char *)hdr + parser->nl_hdr_off);
- error = nl_parse_attrs_raw(nla, len - parser->nl_hdr_off, parser->np,
- parser->np_size, npt, target);
+ error = nl_parse_attrs_raw(
+ (struct nlattr *)((char *)hdr + parser->nl_hdr_off),
+ len - parser->nl_hdr_off, parser->np, parser->np_size, npt, target);
if (parser->post_parse != NULL && error == 0) {
if (!parser->post_parse(target, npt))
@@ -284,10 +283,8 @@ static inline int
nl_parse_nested(struct nlattr *nla, const struct nlhdr_parser *parser,
struct nl_pstate *npt, void *target)
{
- struct nlattr *nla_head = (struct nlattr *)NLA_DATA(nla);
-
- return (nl_parse_attrs_raw(nla_head, NLA_DATA_LEN(nla), parser->np,
- parser->np_size, npt, target));
+ return (nl_parse_attrs_raw((struct nlattr *)NLA_DATA(nla),
+ NLA_DATA_LEN(nla), parser->np, parser->np_size, npt, target));
}
/*
@@ -330,12 +327,9 @@ static inline void
nl_get_attrs_bmask_nlmsg(struct nlmsghdr *hdr,
const struct nlhdr_parser *parser, struct nlattr_bmask *bm)
{
- struct nlattr *nla_head;
-
- nla_head = (struct nlattr *)((char *)(hdr + 1) + parser->nl_hdr_off);
- int len = hdr->nlmsg_len - sizeof(*hdr) - parser->nl_hdr_off;
-
- nl_get_attrs_bmask_raw(nla_head, len, bm);
+ nl_get_attrs_bmask_raw(
+ (struct nlattr *)((char *)(hdr + 1) + parser->nl_hdr_off),
+ hdr->nlmsg_len - sizeof(*hdr) - parser->nl_hdr_off, bm);
}
#endif