Re: [PATCH 2/2] tcp: md5: add fields to the tcp_md5sig struct to set a key address prefix

From: Eric Dumazet
Date: Wed Jun 07 2017 - 00:08:42 EST


On Tue, 2017-06-06 at 17:54 -0700, Ivan Delalande wrote:
> Replace padding in the socket option structure tcp_md5sig with a new
> flag field and address prefix length so it can be specified when
> configuring a new key with the TCP_MD5SIG socket option.
>
> Signed-off-by: Bob Gilligan <gilligan@xxxxxxxxxx>
> Signed-off-by: Eric Mowat <mowat@xxxxxxxxxx>
> Signed-off-by: Ivan Delalande <colona@xxxxxxxxxx>
> ---
> include/uapi/linux/tcp.h | 6 +++++-
> net/ipv4/tcp_ipv4.c | 13 +++++++++++--
> net/ipv6/tcp_ipv6.c | 20 +++++++++++++++-----
> 3 files changed, 31 insertions(+), 8 deletions(-)
>
> diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
> index 38a2b07afdff..52ac30aa0652 100644
> --- a/include/uapi/linux/tcp.h
> +++ b/include/uapi/linux/tcp.h
> @@ -234,9 +234,13 @@ enum {
> /* for TCP_MD5SIG socket option */
> #define TCP_MD5SIG_MAXKEYLEN 80
>
> +/* tcp_md5sig flags */
> +#define TCP_MD5SIG_FLAG_PREFIX 1 /* address prefix length */
> +
> struct tcp_md5sig {
> struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
> - __u16 __tcpm_pad1; /* zero */
> + __u8 tcpm_flags; /* flags */
> + __u8 tcpm_prefixlen; /* address prefix */
> __u16 tcpm_keylen; /* key length */
> __u32 __tcpm_pad2; /* zero */
> __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 51ca3bd5a8a3..2b1bb67b3388 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1069,6 +1069,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
> {
> struct tcp_md5sig cmd;
> struct sockaddr_in *sin = (struct sockaddr_in *)&cmd.tcpm_addr;
> + u8 prefixlen;
>
> if (optlen < sizeof(cmd))
> return -EINVAL;
> @@ -1079,15 +1080,23 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
> if (sin->sin_family != AF_INET)
> return -EINVAL;
>
> + if (cmd.tcpm_flags & TCP_MD5SIG_FLAG_PREFIX) {
> + prefixlen = cmd.tcpm_prefixlen;
> + if (prefixlen > 32)
> + return -EINVAL;
> + } else {
> + prefixlen = 32;
> + }

This will break some applications that maybe did not clear the
__tcpm_pad1 field ?


You need to find another way to maintain compatibility with old
applications.