passt: Shrink binary size by dropping static initialisers

...from 11MiB to 155KiB for 'make avx2', 95KiB with -Os and stripped.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Stefano Brivio 2021-10-05 21:15:01 +02:00
parent a26722b875
commit 16f4b983de
4 changed files with 73 additions and 53 deletions

24
dhcp.c
View file

@ -46,11 +46,8 @@ struct opt {
unsigned char c[255]; unsigned char c[255];
}; };
static struct opt opts[255] = { static struct opt opts[255];
[1] = { 0, 4, { 0 }, 0, { 0 }, }, /* Mask */
[3] = { 0, 4, { 0 }, 0, { 0 }, }, /* Router */
[51] = { 0, 4, { 0xff, 0xff, 0xff, 0xff }, 0, { 0 }, }, /* Lease time */
[53] = { 0, 1, { 0 }, 0, { 0 }, }, /* Type */
#define DHCPDISCOVER 1 #define DHCPDISCOVER 1
#define DHCPOFFER 2 #define DHCPOFFER 2
#define DHCPREQUEST 3 #define DHCPREQUEST 3
@ -60,8 +57,21 @@ static struct opt opts[255] = {
#define DHCPRELEASE 7 #define DHCPRELEASE 7
#define DHCPINFORM 8 #define DHCPINFORM 8
#define DHCPFORCERENEW 9 #define DHCPFORCERENEW 9
[54] = { 0, 4, { 0 }, 0, { 0 }, }, /* Server ID */
}; /**
* dhcp_init() - Initialise DHCP options
*/
void dhcp_init(void)
{
opts[1] = (struct opt) { 0, 4, { 0 }, 0, { 0 }, }; /* Mask */
opts[3] = (struct opt) { 0, 4, { 0 }, 0, { 0 }, }; /* Router */
opts[51] = (struct opt) { 0, 4, { 0xff,
0xff,
0xff,
0xff }, 0, { 0 }, }; /* Lease time */
opts[53] = (struct opt) { 0, 1, { 0 }, 0, { 0 }, }; /* Type */
opts[54] = (struct opt) { 0, 4, { 0 }, 0, { 0 }, }; /* Server ID */
}
/** /**
* struct msg - BOOTP/DHCP message * struct msg - BOOTP/DHCP message

1
dhcp.h
View file

@ -1 +1,2 @@
int dhcp(struct ctx *c, struct ethhdr *eh, size_t len); int dhcp(struct ctx *c, struct ethhdr *eh, size_t len);
void dhcp_init(void);

View file

@ -54,6 +54,7 @@
#include "util.h" #include "util.h"
#include "passt.h" #include "passt.h"
#include "dhcp.h"
#include "dhcpv6.h" #include "dhcpv6.h"
#include "icmp.h" #include "icmp.h"
#include "tcp.h" #include "tcp.h"
@ -376,8 +377,6 @@ int main(int argc, char **argv)
} }
sock_probe_mem(&c); sock_probe_mem(&c);
proto_update_l2_buf(c.mac_guest, c.mac, &c.addr4);
tap_sock_init(&c); tap_sock_init(&c);
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
@ -386,6 +385,11 @@ int main(int argc, char **argv)
(!c.no_tcp && tcp_sock_init(&c, &now))) (!c.no_tcp && tcp_sock_init(&c, &now)))
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
proto_update_l2_buf(c.mac_guest, c.mac, &c.addr4);
if (c.v4 && !c.no_dhcp)
dhcp_init();
if (c.v6 && !c.no_dhcpv6) if (c.v6 && !c.no_dhcpv6)
dhcpv6_init(&c); dhcpv6_init(&c);

93
tcp.c
View file

@ -576,7 +576,7 @@ void tcp_remap_to_init(in_port_t port, in_port_t delta)
* @uh: Headroom for TCP header * @uh: Headroom for TCP header
* @data: Storage for TCP payload * @data: Storage for TCP payload
*/ */
__extension__ static struct tcp4_l2_buf_t { static struct tcp4_l2_buf_t {
uint32_t psum; /* 0 */ uint32_t psum; /* 0 */
uint32_t tsum; /* 4 */ uint32_t tsum; /* 4 */
#ifdef __AVX2__ #ifdef __AVX2__
@ -593,16 +593,7 @@ __extension__ static struct tcp4_l2_buf_t {
#else #else
} __attribute__ ((packed, aligned(__alignof__(unsigned int)))) } __attribute__ ((packed, aligned(__alignof__(unsigned int))))
#endif #endif
tcp4_l2_buf[TCP_TAP_FRAMES] = { tcp4_l2_buf[TCP_TAP_FRAMES];
[ 0 ... TCP_TAP_FRAMES - 1 ] = {
0, 0,
#ifdef __AVX2__
{ 0 },
#endif
0, L2_BUF_ETH_IP4_INIT, L2_BUF_IP4_INIT(IPPROTO_TCP),
{ .doff = sizeof(struct tcphdr) / 4, .ack = 1 }, { 0 },
},
};
static int tcp4_l2_buf_mss; static int tcp4_l2_buf_mss;
static int tcp4_l2_buf_mss_nr_set; static int tcp4_l2_buf_mss_nr_set;
@ -618,7 +609,7 @@ static int tcp4_l2_buf_mss_tap_nr_set;
* @th: Headroom for TCP header * @th: Headroom for TCP header
* @data: Storage for TCP payload * @data: Storage for TCP payload
*/ */
__extension__ struct tcp6_l2_buf_t { struct tcp6_l2_buf_t {
#ifdef __AVX2__ #ifdef __AVX2__
uint8_t pad[14]; /* 0 align ip6h to 32 bytes */ uint8_t pad[14]; /* 0 align ip6h to 32 bytes */
#else #else
@ -635,13 +626,7 @@ __extension__ struct tcp6_l2_buf_t {
#else #else
} __attribute__ ((packed, aligned(__alignof__(unsigned int)))) } __attribute__ ((packed, aligned(__alignof__(unsigned int))))
#endif #endif
tcp6_l2_buf[TCP_TAP_FRAMES] = { tcp6_l2_buf[TCP_TAP_FRAMES];
[ 0 ... TCP_TAP_FRAMES - 1 ] = {
{ 0 },
0, L2_BUF_ETH_IP6_INIT, L2_BUF_IP6_INIT(IPPROTO_TCP),
{ .doff = sizeof(struct tcphdr) / 4, .ack = 1 }, { 0 },
},
};
static int tcp6_l2_buf_mss; static int tcp6_l2_buf_mss;
static int tcp6_l2_buf_mss_nr_set; static int tcp6_l2_buf_mss_nr_set;
@ -661,12 +646,7 @@ static struct iovec tcp6_l2_flags_iov_tap [TCP_TAP_FRAMES];
static struct msghdr tcp4_l2_mh_sock; static struct msghdr tcp4_l2_mh_sock;
static struct msghdr tcp6_l2_mh_sock; static struct msghdr tcp6_l2_mh_sock;
__extension__ static struct mmsghdr tcp_l2_mh_tap [TCP_TAP_FRAMES];
static struct mmsghdr tcp_l2_mh_tap [TCP_TAP_FRAMES] = {
[ 0 ... TCP_TAP_FRAMES - 1 ] = {
.msg_hdr.msg_iovlen = 1,
},
};
/* sendmsg() to socket */ /* sendmsg() to socket */
static struct iovec tcp_tap_iov [UIO_MAXIOV]; static struct iovec tcp_tap_iov [UIO_MAXIOV];
@ -682,7 +662,7 @@ static struct iovec tcp_tap_iov [UIO_MAXIOV];
* @th: Headroom for TCP header * @th: Headroom for TCP header
* @opts: Headroom for TCP options * @opts: Headroom for TCP options
*/ */
__extension__ static struct tcp4_l2_flags_buf_t { static struct tcp4_l2_flags_buf_t {
uint32_t psum; /* 0 */ uint32_t psum; /* 0 */
uint32_t tsum; /* 4 */ uint32_t tsum; /* 4 */
#ifdef __AVX2__ #ifdef __AVX2__
@ -699,16 +679,7 @@ __extension__ static struct tcp4_l2_flags_buf_t {
#else #else
} __attribute__ ((packed, aligned(__alignof__(unsigned int)))) } __attribute__ ((packed, aligned(__alignof__(unsigned int))))
#endif #endif
tcp4_l2_flags_buf[TCP_TAP_FRAMES] = { tcp4_l2_flags_buf[TCP_TAP_FRAMES];
[ 0 ... TCP_TAP_FRAMES - 1 ] = {
0, 0,
#ifdef __AVX2__
{ 0 },
#endif
0, L2_BUF_ETH_IP4_INIT, L2_BUF_IP4_INIT(IPPROTO_TCP),
{ 0 }, { 0 },
},
};
static int tcp4_l2_flags_buf_used; static int tcp4_l2_flags_buf_used;
@ -721,7 +692,7 @@ static int tcp4_l2_flags_buf_used;
* @th: Headroom for TCP header * @th: Headroom for TCP header
* @opts: Headroom for TCP options * @opts: Headroom for TCP options
*/ */
__extension__ struct tcp6_l2_flags_buf_t { static struct tcp6_l2_flags_buf_t {
#ifdef __AVX2__ #ifdef __AVX2__
uint8_t pad[14]; /* 0 align ip6h to 32 bytes */ uint8_t pad[14]; /* 0 align ip6h to 32 bytes */
#else #else
@ -737,13 +708,7 @@ __extension__ struct tcp6_l2_flags_buf_t {
#else #else
} __attribute__ ((packed, aligned(__alignof__(unsigned int)))) } __attribute__ ((packed, aligned(__alignof__(unsigned int))))
#endif #endif
tcp6_l2_flags_buf[TCP_TAP_FRAMES] = { tcp6_l2_flags_buf[TCP_TAP_FRAMES];
[ 0 ... TCP_TAP_FRAMES - 1 ] = {
{ 0 },
0, L2_BUF_ETH_IP6_INIT, L2_BUF_IP6_INIT(IPPROTO_TCP),
{ 0 }, { 0 },
},
};
static int tcp6_l2_flags_buf_used; static int tcp6_l2_flags_buf_used;
@ -984,6 +949,26 @@ static void tcp_sock4_iov_init(void)
struct iovec *iov; struct iovec *iov;
int i; int i;
for (i = 0; i < ARRAY_SIZE(tcp4_l2_buf); i++) {
tcp4_l2_buf[i] = (struct tcp4_l2_buf_t) { 0, 0,
#ifdef __AVX2__
{ 0 },
#endif
0, L2_BUF_ETH_IP4_INIT, L2_BUF_IP4_INIT(IPPROTO_TCP),
{ .doff = sizeof(struct tcphdr) / 4, .ack = 1 }, { 0 },
};
}
for (i = 0; i < ARRAY_SIZE(tcp4_l2_flags_buf); i++) {
tcp4_l2_flags_buf[i] = (struct tcp4_l2_flags_buf_t) { 0, 0,
#ifdef __AVX2__
{ 0 },
#endif
0, L2_BUF_ETH_IP4_INIT, L2_BUF_IP4_INIT(IPPROTO_TCP),
{ 0 }, { 0 },
};
}
tcp4_l2_iov_sock[0].iov_base = tcp_buf_discard; tcp4_l2_iov_sock[0].iov_base = tcp_buf_discard;
for (i = 0, iov = tcp4_l2_iov_sock + 1; i < TCP_TAP_FRAMES; for (i = 0, iov = tcp4_l2_iov_sock + 1; i < TCP_TAP_FRAMES;
i++, iov++) { i++, iov++) {
@ -1010,6 +995,22 @@ static void tcp_sock6_iov_init(void)
struct iovec *iov; struct iovec *iov;
int i; int i;
for (i = 0; i < ARRAY_SIZE(tcp6_l2_buf); i++) {
tcp6_l2_buf[i] = (struct tcp6_l2_buf_t) {
{ 0 },
0, L2_BUF_ETH_IP6_INIT, L2_BUF_IP6_INIT(IPPROTO_TCP),
{ .doff = sizeof(struct tcphdr) / 4, .ack = 1 }, { 0 },
};
}
for (i = 0; i < ARRAY_SIZE(tcp6_l2_flags_buf); i++) {
tcp6_l2_flags_buf[i] = (struct tcp6_l2_flags_buf_t) {
{ 0 },
0, L2_BUF_ETH_IP6_INIT, L2_BUF_IP6_INIT(IPPROTO_TCP),
{ 0 }, { 0 },
};
}
tcp6_l2_iov_sock[0].iov_base = tcp_buf_discard; tcp6_l2_iov_sock[0].iov_base = tcp_buf_discard;
for (i = 0, iov = tcp6_l2_iov_sock + 1; i < TCP_TAP_FRAMES; for (i = 0, iov = tcp6_l2_iov_sock + 1; i < TCP_TAP_FRAMES;
i++, iov++) { i++, iov++) {
@ -3529,6 +3530,7 @@ int tcp_sock_init(struct ctx *c, struct timespec *now)
{ {
struct tcp_sock_refill_arg refill_arg = { c, 0 }; struct tcp_sock_refill_arg refill_arg = { c, 0 };
in_port_t port; in_port_t port;
int i;
getrandom(&c->tcp.hash_secret, sizeof(c->tcp.hash_secret), GRND_RANDOM); getrandom(&c->tcp.hash_secret, sizeof(c->tcp.hash_secret), GRND_RANDOM);
@ -3539,6 +3541,9 @@ int tcp_sock_init(struct ctx *c, struct timespec *now)
tcp_sock_init_one(c, 0, port); tcp_sock_init_one(c, 0, port);
} }
for (i = 0; i < ARRAY_SIZE(tcp_l2_mh_tap); i++)
tcp_l2_mh_tap[i] = (struct mmsghdr) { .msg_hdr.msg_iovlen = 1 };
if (c->v4) if (c->v4)
tcp_sock4_iov_init(); tcp_sock4_iov_init();