The problem is that SITNL_ADDATTR is not forcing type safety and on
big endian architcutre passing a smaller size than the underlying
integer type of data causes only the more significant byte(s) to be passed
instead.
A proper fix would be to add specific methods for common integer types like
SITNL_ADDATTR_u8, SITNL_ADDATTR_u16, SITNL_ADDATTR_u32 like netlink library
does with NLA_PUT_U32, NLA_PUT_U16, NLA_PUT_U8.
Change-Id: I560f45fb0011180be8ca2b0e7fbc63030fa10f35
Github: closes OpenVPN/ovpn-dco#96
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Antonio Quartulli <antonio@mandelbit.com>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1547
Message-Id: <
20260219110954.21471-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg35752.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit
b3e0e8696b162794beefc22aad7406b328471cf6)
{
dco_context_t *dco = arg;
struct rtattr *data = SITNL_NEST(&req.n, sizeof(req), IFLA_INFO_DATA);
- SITNL_ADDATTR(&req.n, sizeof(req), IFLA_OVPN_MODE, &dco->ifmode, sizeof(uint8_t));
+
+ /* the netlink format is uint8_t for this and using something
+ * other than uint8_t here (enum underlying type is undefined but
+ * commonly int) causes the values to be 0 when passed
+ * on big endian arch as we only take the (biggest endian) byte
+ * directly at the address
+ */
+ uint8_t ifmode = (uint8_t)dco->ifmode;
+ SITNL_ADDATTR(&req.n, sizeof(req), IFLA_OVPN_MODE, &ifmode, sizeof(uint8_t));
SITNL_NEST_END(&req.n, data);
}
#endif