diff options
author | Sven Wegener <sven.wegener@stealer.net> | 2008-09-19 22:41:56 +0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2008-09-22 03:55:58 +0400 |
commit | e6f225ebb7c35fe30fdf8608927c5cf8fce6de7d (patch) | |
tree | cd6c67a447fcf35c020fb52d3ac4d60402ed80f1 /net/ipv4 | |
parent | f5fff5dc8a7a3f395b0525c02ba92c95d42b7390 (diff) | |
download | linux-e6f225ebb7c35fe30fdf8608927c5cf8fce6de7d.tar.xz |
ipvs: Restrict sync message to 255 connections
The nr_conns variable in the sync message header is only eight bits wide
and will overflow on interfaces with a large MTU. As a result the backup
won't parse all connections contained in the sync buffer. On regular
ethernet with an MTU of 1500 this isn't a problem, because we can't
overflow the value, but consider jumbo frames being used on a cross-over
connection between both directors.
We now restrict the size of the sync buffer, so that we never put more
than 255 connections into a single sync buffer.
Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ipvs/ip_vs_sync.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c index 28237a5f62e2..de5e7e118eed 100644 --- a/net/ipv4/ipvs/ip_vs_sync.c +++ b/net/ipv4/ipvs/ip_vs_sync.c @@ -30,6 +30,7 @@ #include <linux/err.h> #include <linux/kthread.h> #include <linux/wait.h> +#include <linux/kernel.h> #include <net/ip.h> #include <net/sock.h> @@ -99,6 +100,7 @@ struct ip_vs_sync_thread_data { */ #define SYNC_MESG_HEADER_LEN 4 +#define MAX_CONNS_PER_SYNCBUFF 255 /* nr_conns in ip_vs_sync_mesg is 8 bit */ struct ip_vs_sync_mesg { __u8 nr_conns; @@ -516,8 +518,8 @@ static int set_sync_mesg_maxlen(int sync_state) num = (dev->mtu - sizeof(struct iphdr) - sizeof(struct udphdr) - SYNC_MESG_HEADER_LEN - 20) / SIMPLE_CONN_SIZE; - sync_send_mesg_maxlen = - SYNC_MESG_HEADER_LEN + SIMPLE_CONN_SIZE * num; + sync_send_mesg_maxlen = SYNC_MESG_HEADER_LEN + + SIMPLE_CONN_SIZE * min(num, MAX_CONNS_PER_SYNCBUFF); IP_VS_DBG(7, "setting the maximum length of sync sending " "message %d.\n", sync_send_mesg_maxlen); } else if (sync_state == IP_VS_STATE_BACKUP) { |