diff options
author | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2023-05-09 14:55:47 +0000 |
---|---|---|
committer | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2023-05-09 14:55:47 +0000 |
commit | 88bd9ef618d62171fa9e192f2c3c91e9becdc555 (patch) | |
tree | e307aedc9e6289b98bb95fd159952bce2debf7db /sys/netlink/netlink_snl_route_parsers.h | |
parent | ba9c815d3076f5a13ab6f9ec3f6d534e7774e83b (diff) | |
download | src-88bd9ef618d62171fa9e192f2c3c91e9becdc555.tar.gz src-88bd9ef618d62171fa9e192f2c3c91e9becdc555.zip |
netlink: automatically fill sin6_scope_id in the default snl(3) parsers.
Add the optional post-parse hook to the snl(3) parser declaration.
Use this hook to automatically add the interface indexes to the
link-local sockaddrs.
MFC after: 2 weeks
Diffstat (limited to 'sys/netlink/netlink_snl_route_parsers.h')
-rw-r--r-- | sys/netlink/netlink_snl_route_parsers.h | 73 |
1 files changed, 65 insertions, 8 deletions
diff --git a/sys/netlink/netlink_snl_route_parsers.h b/sys/netlink/netlink_snl_route_parsers.h index 1afbe3feeeb9..6332f9f9e0d9 100644 --- a/sys/netlink/netlink_snl_route_parsers.h +++ b/sys/netlink/netlink_snl_route_parsers.h @@ -33,6 +33,17 @@ /* TODO: this file should be generated automatically */ +static inline void +finalize_sockaddr(struct sockaddr *sa, uint32_t ifindex) +{ + if (sa != NULL && sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; + + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + sin6->sin6_scope_id = ifindex; + } +} + /* RTM_<NEW|DEL|GET>ROUTE message parser */ struct rta_mpath_nh { @@ -63,9 +74,18 @@ static const struct snl_field_parser _fp_p_mp_nh[] = { { .off_in = _IN(rtnh_hops), .off_out = _OUT(rtnh_weight), .cb = snl_field_get_uint8 }, { .off_in = _IN(rtnh_ifindex), .off_out = _OUT(ifindex), .cb = snl_field_get_uint32 }, }; + +static inline bool +_cb_p_mp_nh(struct snl_state *ss, void *_target) +{ + struct rta_mpath_nh *target = _target; + + finalize_sockaddr(target->gw, target->ifindex); + return (true); +} #undef _IN #undef _OUT -SNL_DECLARE_PARSER(_mpath_nh_parser, struct rtnexthop, _fp_p_mp_nh, _nla_p_mp_nh); +SNL_DECLARE_PARSER_EXT(_mpath_nh_parser, struct rtnexthop, _fp_p_mp_nh, _nla_p_mp_nh, _cb_p_mp_nh); struct rta_mpath { int num_nhops; @@ -153,9 +173,19 @@ static const struct snl_field_parser _fp_p_route[] = { {.off_in = _IN(rtm_protocol), .off_out = _OUT(rtm_protocol), .cb = snl_field_get_uint8 }, {.off_in = _IN(rtm_dst_len), .off_out = _OUT(rtm_dst_len), .cb = snl_field_get_uint8 }, }; + +static inline bool +_cb_p_route(struct snl_state *ss, void *_target) +{ + struct snl_parsed_route *target = _target; + + finalize_sockaddr(target->rta_dst, target->rta_oif); + finalize_sockaddr(target->rta_gw, target->rta_oif); + return (true); +} #undef _IN #undef _OUT -SNL_DECLARE_PARSER(snl_rtm_route_parser, struct rtmsg, _fp_p_route, _nla_p_route); +SNL_DECLARE_PARSER_EXT(snl_rtm_route_parser, struct rtmsg, _fp_p_route, _nla_p_route, _cb_p_route); /* RTM_<NEW|DEL|GET>LINK message parser */ struct snl_parsed_link { @@ -251,9 +281,18 @@ static struct snl_field_parser _fp_p_neigh_s[] = { {.off_in = _IN(ndm_state), .off_out = _OUT(ndm_state), .cb = snl_field_get_uint16 }, {.off_in = _IN(ndm_ifindex), .off_out = _OUT(nda_ifindex), .cb = snl_field_get_uint32 }, }; + +static inline bool +_cb_p_neigh(struct snl_state *ss, void *_target) +{ + struct snl_parsed_neigh *target = _target; + + finalize_sockaddr(target->nda_dst, target->nda_ifindex); + return (true); +} #undef _IN #undef _OUT -SNL_DECLARE_PARSER(snl_rtm_neigh_parser, struct ndmsg, _fp_p_neigh_s, _nla_p_neigh_s); +SNL_DECLARE_PARSER_EXT(snl_rtm_neigh_parser, struct ndmsg, _fp_p_neigh_s, _nla_p_neigh_s, _cb_p_neigh); struct snl_parsed_addr { uint8_t ifa_family; @@ -267,21 +306,30 @@ struct snl_parsed_addr { #define _IN(_field) offsetof(struct ifaddrmsg, _field) #define _OUT(_field) offsetof(struct snl_parsed_addr, _field) -static struct snl_attr_parser _nla_p_addr_s[] = { +static const struct snl_attr_parser _nla_p_addr_s[] = { { .type = IFA_ADDRESS, .off = _OUT(ifa_address), .cb = snl_attr_get_ip }, { .type = IFA_LOCAL, .off = _OUT(ifa_local), .cb = snl_attr_get_ip }, { .type = IFA_LABEL, .off = _OUT(ifa_label), .cb = snl_attr_dup_string }, { .type = IFA_BROADCAST, .off = _OUT(ifa_broadcast), .cb = snl_attr_get_ip }, }; -static struct snl_field_parser _fp_p_addr_s[] = { +static const struct snl_field_parser _fp_p_addr_s[] = { {.off_in = _IN(ifa_family), .off_out = _OUT(ifa_family), .cb = snl_field_get_uint8 }, {.off_in = _IN(ifa_prefixlen), .off_out = _OUT(ifa_prefixlen), .cb = snl_field_get_uint8 }, {.off_in = _IN(ifa_index), .off_out = _OUT(ifa_index), .cb = snl_field_get_uint32 }, }; + +static inline bool +_cb_p_addr(struct snl_state *ss, void *_target) +{ + struct snl_parsed_addr *target = _target; + + finalize_sockaddr(target->ifa_address, target->ifa_index); + finalize_sockaddr(target->ifa_local, target->ifa_index); + return (true); +} #undef _IN #undef _OUT -SNL_DECLARE_PARSER(snl_rtm_addr_parser, struct ifaddrmsg, _fp_p_addr_s, _nla_p_addr_s); - +SNL_DECLARE_PARSER_EXT(snl_rtm_addr_parser, struct ifaddrmsg, _fp_p_addr_s, _nla_p_addr_s, _cb_p_addr); struct snl_parsed_nhop { uint32_t nha_id; @@ -320,9 +368,18 @@ static const struct snl_attr_parser _nla_p_nh[] = { { .type = NHA_GATEWAY, .off = _OUT(nha_gw), .cb = snl_attr_get_ip }, { .type = NHA_FREEBSD, .arg = &_nh_fbsd_parser, .cb = snl_attr_get_nested }, }; + +static inline bool +_cb_p_nh(struct snl_state *ss, void *_target) +{ + struct snl_parsed_nhop *target = _target; + + finalize_sockaddr(target->nha_gw, target->nha_oif); + return (true); +} #undef _IN #undef _OUT -SNL_DECLARE_PARSER(snl_nhmsg_parser, struct nhmsg, _fp_p_nh, _nla_p_nh); +SNL_DECLARE_PARSER_EXT(snl_nhmsg_parser, struct nhmsg, _fp_p_nh, _nla_p_nh, _cb_p_nh); static const struct snl_hdr_parser *snl_all_route_parsers[] = { &_metrics_mp_nh_parser, &_mpath_nh_parser, &_metrics_parser, &snl_rtm_route_parser, |