From 3f6bf6a033b156fe8a716cc0cc2278270504343c Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Mon, 15 May 2023 11:33:10 +0000 Subject: netlink: add an optional post-process hook to the message parsers. It is primarily used for adding scopeid to the IPv6 link-local sockaddrs. Having proper sockaddrs after parsing minimises the possibility of human mistake when using the parsing. MFC after: 2 weeks --- sys/netlink/netlink_message_parser.h | 39 ++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'sys/netlink/netlink_message_parser.h') diff --git a/sys/netlink/netlink_message_parser.h b/sys/netlink/netlink_message_parser.h index 5e10ea569829..0934057ac49f 100644 --- a/sys/netlink/netlink_message_parser.h +++ b/sys/netlink/netlink_message_parser.h @@ -110,6 +110,7 @@ struct nlattr_parser { }; 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 */ @@ -118,27 +119,26 @@ struct nlhdr_parser { 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; /* Parser function */ + strict_parser_f *sp; /* Pre-parse strict validation function */ + post_parser_f *post_parse; }; -#define NL_DECLARE_PARSER(_name, _t, _fp, _np) \ -static const struct nlhdr_parser _name = { \ - .nl_hdr_off = sizeof(_t), \ - .fp = &((_fp)[0]), \ - .np = &((_np)[0]), \ - .fp_size = NL_ARRAY_LEN(_fp), \ - .np_size = NL_ARRAY_LEN(_np), \ +#define NL_DECLARE_PARSER_EXT(_name, _t, _sp, _fp, _np, _pp) \ +static const struct nlhdr_parser _name = { \ + .nl_hdr_off = sizeof(_t), \ + .fp = &((_fp)[0]), \ + .np = &((_np)[0]), \ + .fp_size = NL_ARRAY_LEN(_fp), \ + .np_size = NL_ARRAY_LEN(_np), \ + .sp = _sp, \ + .post_parse = _pp, \ } -#define NL_DECLARE_STRICT_PARSER(_name, _t, _sp, _fp, _np)\ -static const struct nlhdr_parser _name = { \ - .nl_hdr_off = sizeof(_t), \ - .fp = &((_fp)[0]), \ - .np = &((_np)[0]), \ - .fp_size = NL_ARRAY_LEN(_fp), \ - .np_size = NL_ARRAY_LEN(_np), \ - .sp = _sp, \ -} +#define NL_DECLARE_PARSER(_name, _t, _fp, _np) \ + NL_DECLARE_PARSER_EXT(_name, _t, NULL, _fp, _np, NULL) + +#define NL_DECLARE_STRICT_PARSER(_name, _t, _sp, _fp, _np) \ + NL_DECLARE_PARSER_EXT(_name, _t, _sp, _fp, _np, NULL) #define NL_DECLARE_ARR_PARSER(_name, _t, _o, _fp, _np) \ static const struct nlhdr_parser _name = { \ @@ -252,6 +252,11 @@ nl_parse_header(void *hdr, int len, const struct nlhdr_parser *parser, error = nl_parse_attrs_raw(nla_head, 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)) + return (EINVAL); + } + return (error); } -- cgit v1.2.3