• Jakub Kicinski's avatar
    netlink: add variable-length / auto integers · 374d345d
    Jakub Kicinski authored
    We currently push everyone to use padding to align 64b values
    in netlink. Un-padded nla_put_u64() doesn't even exist any more.
    
    The story behind this possibly start with this thread:
    https://lore.kernel.org/netdev/20121204.130914.1457976839967676240.davem@davemloft.net/
    where DaveM was concerned about the alignment of a structure
    containing 64b stats. If user space tries to access such struct
    directly:
    
    	struct some_stats *stats = nla_data(attr);
    	printf("A: %llu", stats->a);
    
    lack of alignment may become problematic for some architectures.
    These days we most often put every single member in a separate
    attribute, meaning that the code above would use a helper like
    nla_get_u64(), which can deal with alignment internally.
    Even for arches which don't have good unaligned access - access
    aligned to 4B should be pretty efficient.
    Kernel and well known libraries deal with unaligned input already.
    
    Padded 64b is quite space-inefficient (64b + pad means at worst 16B
    per attr vs 32b which takes 8B). It is also more typing:
    
        if (nla_put_u64_pad(rsp, NETDEV_A_SOMETHING_SOMETHING,
                            value, NETDEV_A_SOMETHING_PAD))
    
    Create a new attribute type which will use 32 bits at netlink
    level if value is small enough (probably most of the time?),
    and (4B-aligned) 64 bits otherwise. Kernel API is just:
    
        if (nla_put_uint(rsp, NETDEV_A_SOMETHING_SOMETHING, value))
    
    Calling this new type "just" sint / uint with no specific size
    will hopefully also make people more comfortable with using it.
    Currently telling people "don't use u8, you may need the bits,
    and netlink will round up to 4B, anyway" is the #1 comment
    we give to newcomers.
    
    In terms of netlink layout it looks like this:
    
             0       4       8       12      16
    32b:     [nlattr][ u32  ]
    64b:     [  pad ][nlattr][     u64      ]
    uint(32) [nlattr][ u32  ]
    uint(64) [nlattr][     u64      ]
    Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    Acked-by: default avatarNicolas Dichtel <nicolas.dichtel@6wind.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    374d345d
policy.c 11.7 KB