From 757cab18d6427d9246618ce48c158f2b05183838 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 27 Feb 2020 16:16:48 +0100 Subject: BGP: Support for MD5SIG together with remote range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When dynamic BGP with remote range is configured, MD5SIG needs to use newer socket option (TCP_MD5SIG_EXT) to specify remote addres range for listening socket. Thanks to Adam KuĊ‚agowski for the suggestion. --- sysdep/linux/sysio.h | 63 +++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 28 deletions(-) (limited to 'sysdep/linux') diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index b1cc25dc..8c3efd6e 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -6,35 +6,28 @@ * Can be freely distributed and used under the terms of the GNU GPL. */ - -#ifndef IP_MINTTL -#define IP_MINTTL 21 -#endif - -#ifndef IPV6_TCLASS -#define IPV6_TCLASS 67 -#endif - #ifndef IPV6_MINHOPCOUNT #define IPV6_MINHOPCOUNT 73 #endif +#ifndef TCP_MD5SIG_EXT +#define TCP_MD5SIG_EXT 32 +#endif -#ifndef TCP_MD5SIG - -#define TCP_MD5SIG 14 -#define TCP_MD5SIG_MAXKEYLEN 80 +#ifndef TCP_MD5SIG_FLAG_PREFIX +#define TCP_MD5SIG_FLAG_PREFIX 1 +#endif -struct tcp_md5sig { - struct sockaddr_storage tcpm_addr; /* address associated */ - u16 __tcpm_pad1; /* zero */ - u16 tcpm_keylen; /* key length */ - u32 __tcpm_pad2; /* zero */ - u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */ +/* We redefine the tcp_md5sig structure with different name to avoid collision with older headers */ +struct tcp_md5sig_ext { + struct sockaddr_storage tcpm_addr; /* Address associated */ + u8 tcpm_flags; /* Extension flags */ + u8 tcpm_prefixlen; /* Address prefix */ + u16 tcpm_keylen; /* Key length */ + u32 __tcpm_pad2; /* Zero */ + u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* Key (binary) */ }; -#endif - /* Linux does not care if sa_len is larger than needed */ #define SA_LEN(x) sizeof(sockaddr) @@ -169,9 +162,9 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen) */ int -sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, struct iface *ifa, char *passwd, int setkey UNUSED) +sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, int pxlen, struct iface *ifa, char *passwd, int setkey UNUSED) { - struct tcp_md5sig md5; + struct tcp_md5sig_ext md5; memset(&md5, 0, sizeof(md5)); sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, remote, ifa, 0); @@ -187,12 +180,26 @@ sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, struct iface *ifa memcpy(&md5.tcpm_key, passwd, len); } - if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG, &md5, sizeof(md5)) < 0) + if (pxlen < 0) { - if (errno == ENOPROTOOPT) - ERR_MSG("Kernel does not support TCP MD5 signatures"); - else - ERR("TCP_MD5SIG"); + if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG, &md5, sizeof(md5)) < 0) + if (errno == ENOPROTOOPT) + ERR_MSG("Kernel does not support TCP MD5 signatures"); + else + ERR("TCP_MD5SIG"); + } + else + { + md5.tcpm_flags = TCP_MD5SIG_FLAG_PREFIX; + md5.tcpm_prefixlen = pxlen; + + if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG_EXT, &md5, sizeof(md5)) < 0) + { + if (errno == ENOPROTOOPT) + ERR_MSG("Kernel does not support extended TCP MD5 signatures"); + else + ERR("TCP_MD5SIG_EXT"); + } } return 0; -- cgit v1.2.3