aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Wegener <sven.wegener@stealer.net>2008-09-19 14:41:56 -0400
committerSimon Horman <horms@verge.net.au>2008-09-21 19:55:58 -0400
commite6f225ebb7c35fe30fdf8608927c5cf8fce6de7d (patch)
treecd6c67a447fcf35c020fb52d3ac4d60402ed80f1
parentf5fff5dc8a7a3f395b0525c02ba92c95d42b7390 (diff)
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>
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c6
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 28237a5f62e..de5e7e118ee 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -30,6 +30,7 @@
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/kthread.h> 31#include <linux/kthread.h>
32#include <linux/wait.h> 32#include <linux/wait.h>
33#include <linux/kernel.h>
33 34
34#include <net/ip.h> 35#include <net/ip.h>
35#include <net/sock.h> 36#include <net/sock.h>
@@ -99,6 +100,7 @@ struct ip_vs_sync_thread_data {
99*/ 100*/
100 101
101#define SYNC_MESG_HEADER_LEN 4 102#define SYNC_MESG_HEADER_LEN 4
103#define MAX_CONNS_PER_SYNCBUFF 255 /* nr_conns in ip_vs_sync_mesg is 8 bit */
102 104
103struct ip_vs_sync_mesg { 105struct ip_vs_sync_mesg {
104 __u8 nr_conns; 106 __u8 nr_conns;
@@ -516,8 +518,8 @@ static int set_sync_mesg_maxlen(int sync_state)
516 num = (dev->mtu - sizeof(struct iphdr) - 518 num = (dev->mtu - sizeof(struct iphdr) -
517 sizeof(struct udphdr) - 519 sizeof(struct udphdr) -
518 SYNC_MESG_HEADER_LEN - 20) / SIMPLE_CONN_SIZE; 520 SYNC_MESG_HEADER_LEN - 20) / SIMPLE_CONN_SIZE;
519 sync_send_mesg_maxlen = 521 sync_send_mesg_maxlen = SYNC_MESG_HEADER_LEN +
520 SYNC_MESG_HEADER_LEN + SIMPLE_CONN_SIZE * num; 522 SIMPLE_CONN_SIZE * min(num, MAX_CONNS_PER_SYNCBUFF);
521 IP_VS_DBG(7, "setting the maximum length of sync sending " 523 IP_VS_DBG(7, "setting the maximum length of sync sending "
522 "message %d.\n", sync_send_mesg_maxlen); 524 "message %d.\n", sync_send_mesg_maxlen);
523 } else if (sync_state == IP_VS_STATE_BACKUP) { 525 } else if (sync_state == IP_VS_STATE_BACKUP) {