History

ipvs: add sync_maxlen parameter for the sync daemon

Allow setups with large MTU to send large sync packets by adding sync_maxlen parameter. The default value is now based on MTU but no more than 1500 for compatibility reasons. To avoid problems if MTU changes allow fragmentation by sending packets with DF=0. Problem reported by Dan Carpenter.

Julian Anastasov committed 11 years ago

Commit e4ff6751 parent e0b26cc4 files · +108 −102Browse files

Unified · Split

4 files
  1. include/net/ip_vs.h +11 −8
  2. include/uapi/linux/ip_vs.h +1 −0
  3. net/netfilter/ipvs/ip_vs_ctl.c +33 −20
  4. net/netfilter/ipvs/ip_vs_sync.c +63 −74
include/net/ip_vs.h+11−8
@@ -846,6 +846,13 @@ struct ipvs_master_sync_state { · 845 unmodified lines
846846 /* How much time to keep dests in trash */
847847 #define IP_VS_DEST_TRASH_PERIOD (120 * HZ)
848848
849+struct ipvs_sync_daemon_cfg {
850+ int syncid;
851+ u16 sync_maxlen;
852+ /* multicast interface name */
853+ char mcast_ifn[IP_VS_IFNAME_MAXLEN];
854+};
855+
849856 /* IPVS in network namespace */
850857 struct netns_ipvs {
851858 int gen; /* Generation */
@@ -961,15 +968,10 @@ struct netns_ipvs { · 109 unmodified lines
961968 spinlock_t sync_buff_lock;
962969 struct task_struct **backup_threads;
963970 int threads_mask;
964− int send_mesg_maxlen;
965− int recv_mesg_maxlen;
966971 volatile int sync_state;
967− volatile int master_syncid;
968− volatile int backup_syncid;
969972 struct mutex sync_mutex;
970− /* multicast interface name */
971− char master_mcast_ifn[IP_VS_IFNAME_MAXLEN];
972− char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
973+ struct ipvs_sync_daemon_cfg mcfg; /* Master Configuration */
974+ struct ipvs_sync_daemon_cfg bcfg; /* Backup Configuration */
973975 /* net name space ptr */
974976 struct net *net; /* Needed by timer routines */
975977 /* Number of heterogeneous destinations, needed becaus heterogeneous
@@ -1408,7 +1410,8 @@ static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest) · 432 unmodified lines
14081410 /* IPVS sync daemon data and function prototypes
14091411 * (from ip_vs_sync.c)
14101412 */
1411−int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid);
1413+int start_sync_thread(struct net *net, struct ipvs_sync_daemon_cfg *cfg,
1414+ int state);
14121415 int stop_sync_thread(struct net *net, int state);
14131416 void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp, int pkts);
14141417
include/uapi/linux/ip_vs.h+1−0
@@ -406,6 +406,7 @@ enum { · 405 unmodified lines
406406 IPVS_DAEMON_ATTR_STATE, /* sync daemon state (master/backup) */
407407 IPVS_DAEMON_ATTR_MCAST_IFN, /* multicast interface name */
408408 IPVS_DAEMON_ATTR_SYNC_ID, /* SyncID we belong to */
409+ IPVS_DAEMON_ATTR_SYNC_MAXLEN, /* UDP Payload Size */
409410 __IPVS_DAEMON_ATTR_MAX,
410411 };
411412
net/netfilter/ipvs/ip_vs_ctl.c+33−20
@@ -2336,10 +2336,15 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) · 2335 unmodified lines
23362336 struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
23372337
23382338 if (cmd == IP_VS_SO_SET_STARTDAEMON) {
2339+ struct ipvs_sync_daemon_cfg cfg;
2340+
2341+ memset(&cfg, 0, sizeof(cfg));
2342+ strlcpy(cfg.mcast_ifn, dm->mcast_ifn,
2343+ sizeof(cfg.mcast_ifn));
2344+ cfg.syncid = dm->syncid;
23392345 rtnl_lock();
23402346 mutex_lock(&ipvs->sync_mutex);
2341− ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
2342− dm->syncid);
2347+ ret = start_sync_thread(net, &cfg, dm->state);
23432348 mutex_unlock(&ipvs->sync_mutex);
23442349 rtnl_unlock();
23452350 } else {
@@ -2650,15 +2655,15 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) · 304 unmodified lines
26502655 mutex_lock(&ipvs->sync_mutex);
26512656 if (ipvs->sync_state & IP_VS_STATE_MASTER) {
26522657 d[0].state = IP_VS_STATE_MASTER;
2653− strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
2658+ strlcpy(d[0].mcast_ifn, ipvs->mcfg.mcast_ifn,
26542659 sizeof(d[0].mcast_ifn));
2655− d[0].syncid = ipvs->master_syncid;
2660+ d[0].syncid = ipvs->mcfg.syncid;
26562661 }
26572662 if (ipvs->sync_state & IP_VS_STATE_BACKUP) {
26582663 d[1].state = IP_VS_STATE_BACKUP;
2659− strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
2664+ strlcpy(d[1].mcast_ifn, ipvs->bcfg.mcast_ifn,
26602665 sizeof(d[1].mcast_ifn));
2661− d[1].syncid = ipvs->backup_syncid;
2666+ d[1].syncid = ipvs->bcfg.syncid;
26622667 }
26632668 if (copy_to_user(user, &d, sizeof(d)) != 0)
26642669 ret = -EFAULT;
@@ -2813,6 +2818,7 @@ static const struct nla_policy ip_vs_daemon_policy[IPVS_DAEMON_ATTR_MAX + 1] = { · 148 unmodified lines
28132818 [IPVS_DAEMON_ATTR_MCAST_IFN] = { .type = NLA_NUL_STRING,
28142819 .len = IP_VS_IFNAME_MAXLEN },
28152820 [IPVS_DAEMON_ATTR_SYNC_ID] = { .type = NLA_U32 },
2821+ [IPVS_DAEMON_ATTR_SYNC_MAXLEN] = { .type = NLA_U16 },
28162822 };
28172823
28182824 /* Policy used for attributes in nested attribute IPVS_CMD_ATTR_SERVICE */
@@ -3271,7 +3277,7 @@ static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest, · 452 unmodified lines
32713277 }
32723278
32733279 static int ip_vs_genl_fill_daemon(struct sk_buff *skb, __u32 state,
3274− const char *mcast_ifn, __u32 syncid)
3280+ struct ipvs_sync_daemon_cfg *c)
32753281 {
32763282 struct nlattr *nl_daemon;
32773283
@@ -3280,8 +3286,9 @@ static int ip_vs_genl_fill_daemon(struct sk_buff *skb, __u32 state, · 2 unmodified lines
32803286 return -EMSGSIZE;
32813287
32823288 if (nla_put_u32(skb, IPVS_DAEMON_ATTR_STATE, state) ||
3283− nla_put_string(skb, IPVS_DAEMON_ATTR_MCAST_IFN, mcast_ifn) ||
3284− nla_put_u32(skb, IPVS_DAEMON_ATTR_SYNC_ID, syncid))
3289+ nla_put_string(skb, IPVS_DAEMON_ATTR_MCAST_IFN, c->mcast_ifn) ||
3290+ nla_put_u32(skb, IPVS_DAEMON_ATTR_SYNC_ID, c->syncid) ||
3291+ nla_put_u16(skb, IPVS_DAEMON_ATTR_SYNC_MAXLEN, c->sync_maxlen))
32853292 goto nla_put_failure;
32863293 nla_nest_end(skb, nl_daemon);
32873294
@@ -3293,7 +3300,7 @@ nla_put_failure: · 5 unmodified lines
32933300 }
32943301
32953302 static int ip_vs_genl_dump_daemon(struct sk_buff *skb, __u32 state,
3296− const char *mcast_ifn, __u32 syncid,
3303+ struct ipvs_sync_daemon_cfg *c,
32973304 struct netlink_callback *cb)
32983305 {
32993306 void *hdr;
@@ -3303,7 +3310,7 @@ static int ip_vs_genl_dump_daemon(struct sk_buff *skb, __u32 state, · 3 unmodified lines
33033310 if (!hdr)
33043311 return -EMSGSIZE;
33053312
3306− if (ip_vs_genl_fill_daemon(skb, state, mcast_ifn, syncid))
3313+ if (ip_vs_genl_fill_daemon(skb, state, c))
33073314 goto nla_put_failure;
33083315
33093316 genlmsg_end(skb, hdr);
@@ -3323,8 +3330,7 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb, · 13 unmodified lines
33233330 mutex_lock(&ipvs->sync_mutex);
33243331 if ((ipvs->sync_state & IP_VS_STATE_MASTER) && !cb->args[0]) {
33253332 if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_MASTER,
3326− ipvs->master_mcast_ifn,
3327− ipvs->master_syncid, cb) < 0)
3333+ &ipvs->mcfg, cb) < 0)
33283334 goto nla_put_failure;
33293335
33303336 cb->args[0] = 1;
@@ -3332,8 +3338,7 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb, · 1 unmodified line
33323338
33333339 if ((ipvs->sync_state & IP_VS_STATE_BACKUP) && !cb->args[1]) {
33343340 if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_BACKUP,
3335− ipvs->backup_mcast_ifn,
3336− ipvs->backup_syncid, cb) < 0)
3341+ &ipvs->bcfg, cb) < 0)
33373342 goto nla_put_failure;
33383343
33393344 cb->args[1] = 1;
@@ -3348,25 +3353,33 @@ nla_put_failure: · 8 unmodified lines
33483353 static int ip_vs_genl_new_daemon(struct net *net, struct nlattr **attrs)
33493354 {
33503355 struct netns_ipvs *ipvs = net_ipvs(net);
3356+ struct ipvs_sync_daemon_cfg c;
3357+ struct nlattr *a;
33513358 int ret;
33523359
3360+ memset(&c, 0, sizeof(c));
33533361 if (!(attrs[IPVS_DAEMON_ATTR_STATE] &&
33543362 attrs[IPVS_DAEMON_ATTR_MCAST_IFN] &&
33553363 attrs[IPVS_DAEMON_ATTR_SYNC_ID]))
33563364 return -EINVAL;
3365+ strlcpy(c.mcast_ifn, nla_data(attrs[IPVS_DAEMON_ATTR_MCAST_IFN]),
3366+ sizeof(c.mcast_ifn));
3367+ c.syncid = nla_get_u32(attrs[IPVS_DAEMON_ATTR_SYNC_ID]);
3368+
3369+ a = attrs[IPVS_DAEMON_ATTR_SYNC_MAXLEN];
3370+ if (a)
3371+ c.sync_maxlen = nla_get_u16(a);
33573372
33583373 /* The synchronization protocol is incompatible with mixed family
33593374 * services
33603375 */
3361− if (net_ipvs(net)->mixed_address_family_dests > 0)
3376+ if (ipvs->mixed_address_family_dests > 0)
33623377 return -EINVAL;
33633378
33643379 rtnl_lock();
33653380 mutex_lock(&ipvs->sync_mutex);
3366− ret = start_sync_thread(net,
3367− nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]),
3368− nla_data(attrs[IPVS_DAEMON_ATTR_MCAST_IFN]),
3369− nla_get_u32(attrs[IPVS_DAEMON_ATTR_SYNC_ID]));
3381+ ret = start_sync_thread(net, &c,
3382+ nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]));
33703383 mutex_unlock(&ipvs->sync_mutex);
33713384 rtnl_unlock();
33723385 return ret;
net/netfilter/ipvs/ip_vs_sync.c+63−74
@@ -320,26 +320,28 @@ sb_dequeue(struct netns_ipvs *ipvs, struct ipvs_master_sync_state *ms) · 319 unmodified lines
320320 * Create a new sync buffer for Version 1 proto.
321321 */
322322 static inline struct ip_vs_sync_buff *
323−ip_vs_sync_buff_create(struct netns_ipvs *ipvs)
323+ip_vs_sync_buff_create(struct netns_ipvs *ipvs, unsigned int len)
324324 {
325325 struct ip_vs_sync_buff *sb;
326326
327327 if (!(sb=kmalloc(sizeof(struct ip_vs_sync_buff), GFP_ATOMIC)))
328328 return NULL;
329329
330− sb->mesg = kmalloc(ipvs->send_mesg_maxlen, GFP_ATOMIC);
330+ len = max_t(unsigned int, len + sizeof(struct ip_vs_sync_mesg),
331+ ipvs->mcfg.sync_maxlen);
332+ sb->mesg = kmalloc(len, GFP_ATOMIC);
331333 if (!sb->mesg) {
332334 kfree(sb);
333335 return NULL;
334336 }
335337 sb->mesg->reserved = 0; /* old nr_conns i.e. must be zero now */
336338 sb->mesg->version = SYNC_PROTO_VER;
337− sb->mesg->syncid = ipvs->master_syncid;
339+ sb->mesg->syncid = ipvs->mcfg.syncid;
338340 sb->mesg->size = htons(sizeof(struct ip_vs_sync_mesg));
339341 sb->mesg->nr_conns = 0;
340342 sb->mesg->spare = 0;
341343 sb->head = (unsigned char *)sb->mesg + sizeof(struct ip_vs_sync_mesg);
342− sb->end = (unsigned char *)sb->mesg + ipvs->send_mesg_maxlen;
344+ sb->end = (unsigned char *)sb->mesg + len;
343345
344346 sb->firstuse = jiffies;
345347 return sb;
@@ -402,7 +404,7 @@ select_master_thread_id(struct netns_ipvs *ipvs, struct ip_vs_conn *cp) · 56 unmodified lines
402404 * Create a new sync buffer for Version 0 proto.
403405 */
404406 static inline struct ip_vs_sync_buff *
405−ip_vs_sync_buff_create_v0(struct netns_ipvs *ipvs)
407+ip_vs_sync_buff_create_v0(struct netns_ipvs *ipvs, unsigned int len)
406408 {
407409 struct ip_vs_sync_buff *sb;
408410 struct ip_vs_sync_mesg_v0 *mesg;
@@ -410,17 +412,19 @@ ip_vs_sync_buff_create_v0(struct netns_ipvs *ipvs) · 1 unmodified line
410412 if (!(sb=kmalloc(sizeof(struct ip_vs_sync_buff), GFP_ATOMIC)))
411413 return NULL;
412414
413− sb->mesg = kmalloc(ipvs->send_mesg_maxlen, GFP_ATOMIC);
415+ len = max_t(unsigned int, len + sizeof(struct ip_vs_sync_mesg_v0),
416+ ipvs->mcfg.sync_maxlen);
417+ sb->mesg = kmalloc(len, GFP_ATOMIC);
414418 if (!sb->mesg) {
415419 kfree(sb);
416420 return NULL;
417421 }
418422 mesg = (struct ip_vs_sync_mesg_v0 *)sb->mesg;
419423 mesg->nr_conns = 0;
420− mesg->syncid = ipvs->master_syncid;
424+ mesg->syncid = ipvs->mcfg.syncid;
421425 mesg->size = htons(sizeof(struct ip_vs_sync_mesg_v0));
422426 sb->head = (unsigned char *)mesg + sizeof(struct ip_vs_sync_mesg_v0);
423− sb->end = (unsigned char *)mesg + ipvs->send_mesg_maxlen;
427+ sb->end = (unsigned char *)mesg + len;
424428 sb->firstuse = jiffies;
425429 return sb;
426430 }
@@ -533,7 +537,7 @@ static void ip_vs_sync_conn_v0(struct net *net, struct ip_vs_conn *cp, · 106 unmodified lines
533537 struct ip_vs_sync_buff *buff;
534538 struct ipvs_master_sync_state *ms;
535539 int id;
536− int len;
540+ unsigned int len;
537541
538542 if (unlikely(cp->af != AF_INET))
539543 return;
@@ -553,17 +557,19 @@ static void ip_vs_sync_conn_v0(struct net *net, struct ip_vs_conn *cp, · 13 unmodified lines
553557 id = select_master_thread_id(ipvs, cp);
554558 ms = &ipvs->ms[id];
555559 buff = ms->sync_buff;
560+ len = (cp->flags & IP_VS_CONN_F_SEQ_MASK) ? FULL_CONN_SIZE :
561+ SIMPLE_CONN_SIZE;
556562 if (buff) {
557563 m = (struct ip_vs_sync_mesg_v0 *) buff->mesg;
558564 /* Send buffer if it is for v1 */
559− if (!m->nr_conns) {
565+ if (buff->head + len > buff->end || !m->nr_conns) {
560566 sb_queue_tail(ipvs, ms);
561567 ms->sync_buff = NULL;
562568 buff = NULL;
563569 }
564570 }
565571 if (!buff) {
566− buff = ip_vs_sync_buff_create_v0(ipvs);
572+ buff = ip_vs_sync_buff_create_v0(ipvs, len);
567573 if (!buff) {
568574 spin_unlock_bh(&ipvs->sync_buff_lock);
569575 pr_err("ip_vs_sync_buff_create failed.\n");
@@ -572,8 +578,6 @@ static void ip_vs_sync_conn_v0(struct net *net, struct ip_vs_conn *cp, · 2 unmodified lines
572578 ms->sync_buff = buff;
573579 }
574580
575− len = (cp->flags & IP_VS_CONN_F_SEQ_MASK) ? FULL_CONN_SIZE :
576− SIMPLE_CONN_SIZE;
577581 m = (struct ip_vs_sync_mesg_v0 *) buff->mesg;
578582 s = (struct ip_vs_sync_conn_v0 *) buff->head;
579583
@@ -597,12 +601,6 @@ static void ip_vs_sync_conn_v0(struct net *net, struct ip_vs_conn *cp, · 17 unmodified lines
597601 m->nr_conns++;
598602 m->size = htons(ntohs(m->size) + len);
599603 buff->head += len;
600−
601− /* check if there is a space for next one */
602− if (buff->head + FULL_CONN_SIZE > buff->end) {
603− sb_queue_tail(ipvs, ms);
604− ms->sync_buff = NULL;
605− }
606604 spin_unlock_bh(&ipvs->sync_buff_lock);
607605
608606 /* synchronize its controller if it has */
@@ -694,7 +692,7 @@ sloop: · 85 unmodified lines
694692 }
695693
696694 if (!buff) {
697− buff = ip_vs_sync_buff_create(ipvs);
695+ buff = ip_vs_sync_buff_create(ipvs, len);
698696 if (!buff) {
699697 spin_unlock_bh(&ipvs->sync_buff_lock);
700698 pr_err("ip_vs_sync_buff_create failed.\n");
@@ -1219,7 +1217,7 @@ static void ip_vs_process_message(struct net *net, __u8 *buffer, · 518 unmodified lines
12191217 return;
12201218 }
12211219 /* SyncID sanity check */
1222− if (ipvs->backup_syncid != 0 && m2->syncid != ipvs->backup_syncid) {
1220+ if (ipvs->bcfg.syncid != 0 && m2->syncid != ipvs->bcfg.syncid) {
12231221 IP_VS_DBG(7, "BACKUP, Ignoring syncid = %d\n", m2->syncid);
12241222 return;
12251223 }
@@ -1319,6 +1317,17 @@ static void set_mcast_ttl(struct sock *sk, u_char ttl) · 93 unmodified lines
13191317 release_sock(sk);
13201318 }
13211319
1320+/* Control fragmentation of messages */
1321+static void set_mcast_pmtudisc(struct sock *sk, int val)
1322+{
1323+ struct inet_sock *inet = inet_sk(sk);
1324+
1325+ /* setsockopt(sock, SOL_IP, IP_MTU_DISCOVER, &val, sizeof(val)); */
1326+ lock_sock(sk);
1327+ inet->pmtudisc = val;
1328+ release_sock(sk);
1329+}
1330+
13221331 /*
13231332 * Specifiy default interface for outgoing multicasts
13241333 */
@@ -1344,43 +1353,6 @@ static int set_mcast_if(struct sock *sk, char *ifname) · 19 unmodified lines
13441353 }
13451354
13461355
1347−/*
1348− * Set the maximum length of sync message according to the
1349− * specified interface's MTU.
1350− */
1351−static int set_sync_mesg_maxlen(struct net *net, int sync_state)
1352−{
1353− struct netns_ipvs *ipvs = net_ipvs(net);
1354− struct net_device *dev;
1355− int num;
1356−
1357− if (sync_state == IP_VS_STATE_MASTER) {
1358− dev = __dev_get_by_name(net, ipvs->master_mcast_ifn);
1359− if (!dev)
1360− return -ENODEV;
1361−
1362− num = (dev->mtu - sizeof(struct iphdr) -
1363− sizeof(struct udphdr) -
1364− SYNC_MESG_HEADER_LEN - 20) / SIMPLE_CONN_SIZE;
1365− ipvs->send_mesg_maxlen = SYNC_MESG_HEADER_LEN +
1366− SIMPLE_CONN_SIZE * min(num, MAX_CONNS_PER_SYNCBUFF);
1367− IP_VS_DBG(7, "setting the maximum length of sync sending "
1368− "message %d.\n", ipvs->send_mesg_maxlen);
1369− } else if (sync_state == IP_VS_STATE_BACKUP) {
1370− dev = __dev_get_by_name(net, ipvs->backup_mcast_ifn);
1371− if (!dev)
1372− return -ENODEV;
1373−
1374− ipvs->recv_mesg_maxlen = dev->mtu -
1375− sizeof(struct iphdr) - sizeof(struct udphdr);
1376− IP_VS_DBG(7, "setting the maximum length of sync receiving "
1377− "message %d.\n", ipvs->recv_mesg_maxlen);
1378− }
1379−
1380− return 0;
1381−}
1382−
1383−
13841356 /*
13851357 * Join a multicast group.
13861358 * the group is specified by a class D multicast address 224.0.0.0/8
@@ -1461,7 +1433,7 @@ static struct socket *make_send_sock(struct net *net, int id) · 74 unmodified lines
14611433 pr_err("Error during creation of socket; terminating\n");
14621434 return ERR_PTR(result);
14631435 }
1464− result = set_mcast_if(sock->sk, ipvs->master_mcast_ifn);
1436+ result = set_mcast_if(sock->sk, ipvs->mcfg.mcast_ifn);
14651437 if (result < 0) {
14661438 pr_err("Error setting outbound mcast interface\n");
14671439 goto error;
@@ -1469,11 +1441,13 @@ static struct socket *make_send_sock(struct net *net, int id) · 1 unmodified line
14691441
14701442 set_mcast_loop(sock->sk, 0);
14711443 set_mcast_ttl(sock->sk, 1);
1444+ /* Allow fragmentation if MTU changes */
1445+ set_mcast_pmtudisc(sock->sk, IP_PMTUDISC_DONT);
14721446 result = sysctl_sync_sock_size(ipvs);
14731447 if (result > 0)
14741448 set_sock_size(sock->sk, 1, result);
14751449
1476− result = bind_mcastif_addr(sock, ipvs->master_mcast_ifn);
1450+ result = bind_mcastif_addr(sock, ipvs->mcfg.mcast_ifn);
14771451 if (result < 0) {
14781452 pr_err("Error binding address of the mcast interface\n");
14791453 goto error;
@@ -1531,7 +1505,7 @@ static struct socket *make_receive_sock(struct net *net, int id) · 51 unmodified lines
15311505 /* join the multicast group */
15321506 result = join_mcast_group(sock->sk,
15331507 (struct in_addr *) &mcast_addr.sin_addr,
1534− ipvs->backup_mcast_ifn);
1508+ ipvs->bcfg.mcast_ifn);
15351509 if (result < 0) {
15361510 pr_err("Error joining to the multicast group\n");
15371511 goto error;
@@ -1639,7 +1613,7 @@ static int sync_thread_master(void *data) · 101 unmodified lines
16391613
16401614 pr_info("sync thread started: state = MASTER, mcast_ifn = %s, "
16411615 "syncid = %d, id = %d\n",
1642− ipvs->master_mcast_ifn, ipvs->master_syncid, tinfo->id);
1616+ ipvs->mcfg.mcast_ifn, ipvs->mcfg.syncid, tinfo->id);
16431617
16441618 for (;;) {
16451619 sb = next_sync_buff(ipvs, ms);
@@ -1693,7 +1667,7 @@ static int sync_thread_backup(void *data) · 47 unmodified lines
16931667
16941668 pr_info("sync thread started: state = BACKUP, mcast_ifn = %s, "
16951669 "syncid = %d, id = %d\n",
1696− ipvs->backup_mcast_ifn, ipvs->backup_syncid, tinfo->id);
1670+ ipvs->bcfg.mcast_ifn, ipvs->bcfg.syncid, tinfo->id);
16971671
16981672 while (!kthread_should_stop()) {
16991673 wait_event_interruptible(*sk_sleep(tinfo->sock->sk),
@@ -1703,7 +1677,7 @@ static int sync_thread_backup(void *data) · 3 unmodified lines
17031677 /* do we have data now? */
17041678 while (!skb_queue_empty(&(tinfo->sock->sk->sk_receive_queue))) {
17051679 len = ip_vs_receive(tinfo->sock, tinfo->buf,
1706− ipvs->recv_mesg_maxlen);
1680+ ipvs->bcfg.sync_maxlen);
17071681 if (len <= 0) {
17081682 if (len != -EAGAIN)
17091683 pr_err("receiving message error\n");
@@ -1723,16 +1697,19 @@ static int sync_thread_backup(void *data) · 13 unmodified lines
17231697 }
17241698
17251699
1726−int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid)
1700+int start_sync_thread(struct net *net, struct ipvs_sync_daemon_cfg *c,
1701+ int state)
17271702 {
17281703 struct ip_vs_sync_thread_data *tinfo;
17291704 struct task_struct **array = NULL, *task;
17301705 struct socket *sock;
17311706 struct netns_ipvs *ipvs = net_ipvs(net);
1707+ struct net_device *dev;
17321708 char *name;
17331709 int (*threadfn)(void *data);
1734− int id, count;
1710+ int id, count, hlen;
17351711 int result = -ENOMEM;
1712+ u16 mtu, min_mtu;
17361713
17371714 IP_VS_DBG(7, "%s(): pid %d\n", __func__, task_pid_nr(current));
17381715 IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n",
@@ -1744,22 +1721,35 @@ int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid) · 5 unmodified lines
17441721 } else
17451722 count = ipvs->threads_mask + 1;
17461723
1724+ dev = __dev_get_by_name(net, c->mcast_ifn);
1725+ if (!dev) {
1726+ pr_err("Unknown mcast interface: %s\n", c->mcast_ifn);
1727+ return -ENODEV;
1728+ }
1729+ hlen = sizeof(struct iphdr) + sizeof(struct udphdr);
1730+ mtu = (state == IP_VS_STATE_BACKUP) ?
1731+ clamp(dev->mtu, 1500U, 65535U) : 1500U;
1732+ min_mtu = (state == IP_VS_STATE_BACKUP) ? 1024 : 1;
1733+
1734+ if (c->sync_maxlen)
1735+ c->sync_maxlen = clamp_t(unsigned int,
1736+ c->sync_maxlen, min_mtu,
1737+ 65535 - hlen);
1738+ else
1739+ c->sync_maxlen = mtu - hlen;
1740+
17471741 if (state == IP_VS_STATE_MASTER) {
17481742 if (ipvs->ms)
17491743 return -EEXIST;
17501744
1751− strlcpy(ipvs->master_mcast_ifn, mcast_ifn,
1752− sizeof(ipvs->master_mcast_ifn));
1753− ipvs->master_syncid = syncid;
1745+ ipvs->mcfg = *c;
17541746 name = "ipvs-m:%d:%d";
17551747 threadfn = sync_thread_master;
17561748 } else if (state == IP_VS_STATE_BACKUP) {
17571749 if (ipvs->backup_threads)
17581750 return -EEXIST;
17591751
1760− strlcpy(ipvs->backup_mcast_ifn, mcast_ifn,
1761− sizeof(ipvs->backup_mcast_ifn));
1762− ipvs->backup_syncid = syncid;
1752+ ipvs->bcfg = *c;
17631753 name = "ipvs-b:%d:%d";
17641754 threadfn = sync_thread_backup;
17651755 } else {
@@ -1787,7 +1777,6 @@ int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid) · 21 unmodified lines
17871777 if (!array)
17881778 goto out;
17891779 }
1790− set_sync_mesg_maxlen(net, state);
17911780
17921781 tinfo = NULL;
17931782 for (id = 0; id < count; id++) {
@@ -1805,7 +1794,7 @@ int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid) · 11 unmodified lines
18051794 tinfo->net = net;
18061795 tinfo->sock = sock;
18071796 if (state == IP_VS_STATE_BACKUP) {
1808− tinfo->buf = kmalloc(ipvs->recv_mesg_maxlen,
1797+ tinfo->buf = kmalloc(ipvs->bcfg.sync_maxlen,
18091798 GFP_KERNEL);
18101799 if (!tinfo->buf)
18111800 goto outtinfo;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t