* [PATCH] multi-protocol MSF API sysctl limit support
@ 2004-03-06 9:37 David Stevens
2004-03-08 20:17 ` David S. Miller
0 siblings, 1 reply; 2+ messages in thread
From: David Stevens @ 2004-03-06 9:37 UTC (permalink / raw)
To: netdev, davem
[-- Attachment #1.1: Type: text/plain, Size: 5521 bytes --]
This patch adds support for administrator-controlled multicast source
filter limits for the multiprotocol multicast source filter API. The v4
portion
uses the same sysctl variable as the previous v4-only API patch, and
the v6 portion uses a new v6 sysctl variable, "mld_max_msf".
In-line 2.4.x and attached 2.4.x and 2.6.x versions.
+-DLS
diff -ruN linux-2.4.25F4/include/linux/sysctl.h linux-2.4.25F5/include/linux/sysctl.h
--- linux-2.4.25F4/include/linux/sysctl.h 2004-03-04 17:02:54.000000000 -0800
+++ linux-2.4.25F5/include/linux/sysctl.h 2004-03-05 00:02:57.000000000 -0800
@@ -388,7 +388,8 @@
NET_IPV6_NEIGH=17,
NET_IPV6_ROUTE=18,
NET_IPV6_ICMP=19,
- NET_IPV6_BINDV6ONLY=20
+ NET_IPV6_BINDV6ONLY=20,
+ NET_IPV6_MLD_MAX_MSF=25,
};
enum {
diff -ruN linux-2.4.25F4/include/net/ipv6.h linux-2.4.25F5/include/net/ipv6.h
--- linux-2.4.25F4/include/net/ipv6.h 2004-03-04 17:15:19.000000000 -0800
+++ linux-2.4.25F5/include/net/ipv6.h 2004-03-05 00:19:31.000000000 -0800
@@ -104,6 +104,7 @@
/* sysctls */
extern int sysctl_ipv6_bindv6only;
+extern int sysctl_mld_max_msf;
extern struct ipv6_mib ipv6_statistics[NR_CPUS*2];
#define IP6_INC_STATS(field) SNMP_INC_STATS(ipv6_statistics, field)
diff -ruN linux-2.4.25F4/net/ipv4/ip_sockglue.c linux-2.4.25F5/net/ipv4/ip_sockglue.c
--- linux-2.4.25F4/net/ipv4/ip_sockglue.c 2004-03-04 19:29:33.000000000 -0800
+++ linux-2.4.25F5/net/ipv4/ip_sockglue.c 2004-03-05 16:21:06.000000000 -0800
@@ -762,6 +762,8 @@
}
case MCAST_MSFILTER:
{
+ extern int sysctl_optmem_max;
+ extern int sysctl_igmp_max_msf;
struct sockaddr_in *psin;
struct ip_msfilter *msf = 0;
struct group_filter *gsf = 0;
@@ -769,6 +771,10 @@
if (optlen < GROUP_FILTER_SIZE(0))
goto e_inval;
+ if (optlen > sysctl_optmem_max) {
+ err = -ENOBUFS;
+ break;
+ }
gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
if (gsf == 0) {
err = -ENOBUFS;
@@ -778,7 +784,13 @@
if (copy_from_user(gsf, optval, optlen)) {
goto mc_msf_out;
}
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < optlen) {
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ if (gsf->gf_numsrc >= 0x1ffffff ||
+ gsf->gf_numsrc > sysctl_igmp_max_msf) {
+ err = -ENOBUFS;
+ goto mc_msf_out;
+ }
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
err = EINVAL;
goto mc_msf_out;
}
diff -ruN linux-2.4.25F4/net/ipv6/ipv6_sockglue.c linux-2.4.25F5/net/ipv6/ipv6_sockglue.c
--- linux-2.4.25F4/net/ipv6/ipv6_sockglue.c 2004-02-23 16:35:09.000000000 -0800
+++ linux-2.4.25F5/net/ipv6/ipv6_sockglue.c 2004-03-05 01:57:30.000000000 -0800
@@ -453,6 +453,7 @@
case MCAST_MSFILTER:
{
extern int sysctl_optmem_max;
+ extern int sysctl_mld_max_msf;
struct group_filter *gsf;
if (optlen < GROUP_FILTER_SIZE(0))
@@ -471,8 +472,14 @@
kfree(gsf);
break;
}
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < GROUP_FILTER_SIZE(0) ||
- GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ if (gsf->gf_numsrc >= 0x1ffffffU ||
+ gsf->gf_numsrc > sysctl_mld_max_msf) {
+ kfree(gsf);
+ retv = -ENOBUFS;
+ break;
+ }
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
kfree(gsf);
retv = -EINVAL;
break;
diff -ruN linux-2.4.25F4/net/ipv6/mcast.c linux-2.4.25F5/net/ipv6/mcast.c
--- linux-2.4.25F4/net/ipv6/mcast.c 2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.25F5/net/ipv6/mcast.c 2004-03-04 22:37:31.000000000 -0800
@@ -163,6 +163,10 @@
#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
+#define IPV6_MLD_MAX_MSF 10
+
+int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
+
/*
* socket join on multicast group
*/
@@ -401,6 +405,10 @@
}
/* else, add a new source to the filter */
+ if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+ err = -ENOBUFS;
+ goto done;
+ }
if (!psl || psl->sl_count == psl->sl_max) {
struct ip6_sf_socklist *newpsl;
int count = IP6_SFBLOCK;
diff -ruN linux-2.4.25F4/net/ipv6/sysctl_net_ipv6.c linux-2.4.25F5/net/ipv6/sysctl_net_ipv6.c
--- linux-2.4.25F4/net/ipv6/sysctl_net_ipv6.c 2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.25F5/net/ipv6/sysctl_net_ipv6.c 2004-03-05 00:01:05.000000000 -0800
@@ -24,6 +24,8 @@
{NET_IPV6_ICMP, "icmp", NULL, 0, 0500, ipv6_icmp_table},
{NET_IPV6_BINDV6ONLY, "bindv6only",
&sysctl_ipv6_bindv6only, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV6_MLD_MAX_MSF, "mld_max_msf",
+ &sysctl_mld_max_msf, sizeof(int), 0644, NULL, &proc_dointvec},
{0}
};
(See attached file: 2.4.25mpmsflimit.patch)
(See attached file: 2.6.4rc2mpmsflimit.patch)
[-- Attachment #1.2: Type: text/html, Size: 5411 bytes --]
[-- Attachment #2: 2.4.25mpmsflimit.patch --]
[-- Type: application/octet-stream, Size: 4238 bytes --]
diff -ruN linux-2.4.25F4/include/linux/sysctl.h linux-2.4.25F5/include/linux/sysctl.h
--- linux-2.4.25F4/include/linux/sysctl.h 2004-03-04 17:02:54.000000000 -0800
+++ linux-2.4.25F5/include/linux/sysctl.h 2004-03-05 00:02:57.000000000 -0800
@@ -388,7 +388,8 @@
NET_IPV6_NEIGH=17,
NET_IPV6_ROUTE=18,
NET_IPV6_ICMP=19,
- NET_IPV6_BINDV6ONLY=20
+ NET_IPV6_BINDV6ONLY=20,
+ NET_IPV6_MLD_MAX_MSF=25,
};
enum {
diff -ruN linux-2.4.25F4/include/net/ipv6.h linux-2.4.25F5/include/net/ipv6.h
--- linux-2.4.25F4/include/net/ipv6.h 2004-03-04 17:15:19.000000000 -0800
+++ linux-2.4.25F5/include/net/ipv6.h 2004-03-05 00:19:31.000000000 -0800
@@ -104,6 +104,7 @@
/* sysctls */
extern int sysctl_ipv6_bindv6only;
+extern int sysctl_mld_max_msf;
extern struct ipv6_mib ipv6_statistics[NR_CPUS*2];
#define IP6_INC_STATS(field) SNMP_INC_STATS(ipv6_statistics, field)
diff -ruN linux-2.4.25F4/net/ipv4/ip_sockglue.c linux-2.4.25F5/net/ipv4/ip_sockglue.c
--- linux-2.4.25F4/net/ipv4/ip_sockglue.c 2004-03-04 19:29:33.000000000 -0800
+++ linux-2.4.25F5/net/ipv4/ip_sockglue.c 2004-03-05 16:21:06.000000000 -0800
@@ -762,6 +762,8 @@
}
case MCAST_MSFILTER:
{
+ extern int sysctl_optmem_max;
+ extern int sysctl_igmp_max_msf;
struct sockaddr_in *psin;
struct ip_msfilter *msf = 0;
struct group_filter *gsf = 0;
@@ -769,6 +771,10 @@
if (optlen < GROUP_FILTER_SIZE(0))
goto e_inval;
+ if (optlen > sysctl_optmem_max) {
+ err = -ENOBUFS;
+ break;
+ }
gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
if (gsf == 0) {
err = -ENOBUFS;
@@ -778,7 +784,13 @@
if (copy_from_user(gsf, optval, optlen)) {
goto mc_msf_out;
}
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < optlen) {
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ if (gsf->gf_numsrc >= 0x1ffffff ||
+ gsf->gf_numsrc > sysctl_igmp_max_msf) {
+ err = -ENOBUFS;
+ goto mc_msf_out;
+ }
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
err = EINVAL;
goto mc_msf_out;
}
diff -ruN linux-2.4.25F4/net/ipv6/ipv6_sockglue.c linux-2.4.25F5/net/ipv6/ipv6_sockglue.c
--- linux-2.4.25F4/net/ipv6/ipv6_sockglue.c 2004-02-23 16:35:09.000000000 -0800
+++ linux-2.4.25F5/net/ipv6/ipv6_sockglue.c 2004-03-05 01:57:30.000000000 -0800
@@ -453,6 +453,7 @@
case MCAST_MSFILTER:
{
extern int sysctl_optmem_max;
+ extern int sysctl_mld_max_msf;
struct group_filter *gsf;
if (optlen < GROUP_FILTER_SIZE(0))
@@ -471,8 +472,14 @@
kfree(gsf);
break;
}
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < GROUP_FILTER_SIZE(0) ||
- GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ if (gsf->gf_numsrc >= 0x1ffffffU ||
+ gsf->gf_numsrc > sysctl_mld_max_msf) {
+ kfree(gsf);
+ retv = -ENOBUFS;
+ break;
+ }
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
kfree(gsf);
retv = -EINVAL;
break;
diff -ruN linux-2.4.25F4/net/ipv6/mcast.c linux-2.4.25F5/net/ipv6/mcast.c
--- linux-2.4.25F4/net/ipv6/mcast.c 2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.25F5/net/ipv6/mcast.c 2004-03-04 22:37:31.000000000 -0800
@@ -163,6 +163,10 @@
#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
+#define IPV6_MLD_MAX_MSF 10
+
+int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
+
/*
* socket join on multicast group
*/
@@ -401,6 +405,10 @@
}
/* else, add a new source to the filter */
+ if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+ err = -ENOBUFS;
+ goto done;
+ }
if (!psl || psl->sl_count == psl->sl_max) {
struct ip6_sf_socklist *newpsl;
int count = IP6_SFBLOCK;
diff -ruN linux-2.4.25F4/net/ipv6/sysctl_net_ipv6.c linux-2.4.25F5/net/ipv6/sysctl_net_ipv6.c
--- linux-2.4.25F4/net/ipv6/sysctl_net_ipv6.c 2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.25F5/net/ipv6/sysctl_net_ipv6.c 2004-03-05 00:01:05.000000000 -0800
@@ -24,6 +24,8 @@
{NET_IPV6_ICMP, "icmp", NULL, 0, 0500, ipv6_icmp_table},
{NET_IPV6_BINDV6ONLY, "bindv6only",
&sysctl_ipv6_bindv6only, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV6_MLD_MAX_MSF, "mld_max_msf",
+ &sysctl_mld_max_msf, sizeof(int), 0644, NULL, &proc_dointvec},
{0}
};
[-- Attachment #3: 2.6.4rc2mpmsflimit.patch --]
[-- Type: application/octet-stream, Size: 4299 bytes --]
diff -ruN linux-2.6.4rc2F1/include/linux/sysctl.h linux-2.6.4rc2F2/include/linux/sysctl.h
--- linux-2.6.4rc2F1/include/linux/sysctl.h 2004-03-04 16:57:26.000000000 -0800
+++ linux-2.6.4rc2F2/include/linux/sysctl.h 2004-03-06 00:18:17.000000000 -0800
@@ -405,7 +405,8 @@
NET_IPV6_IP6FRAG_HIGH_THRESH=21,
NET_IPV6_IP6FRAG_LOW_THRESH=22,
NET_IPV6_IP6FRAG_TIME=23,
- NET_IPV6_IP6FRAG_SECRET_INTERVAL=24
+ NET_IPV6_IP6FRAG_SECRET_INTERVAL=24,
+ NET_IPV6_MLD_MAX_MSF=25,
};
enum {
diff -ruN linux-2.6.4rc2F1/include/net/ipv6.h linux-2.6.4rc2F2/include/net/ipv6.h
--- linux-2.6.4rc2F1/include/net/ipv6.h 2004-03-04 16:18:23.000000000 -0800
+++ linux-2.6.4rc2F2/include/net/ipv6.h 2004-03-06 00:10:21.000000000 -0800
@@ -108,6 +108,7 @@
/* sysctls */
extern int sysctl_ipv6_bindv6only;
+extern int sysctl_mld_max_msf;
/* MIBs */
DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
diff -ruN linux-2.6.4rc2F1/net/ipv4/ip_sockglue.c linux-2.6.4rc2F2/net/ipv4/ip_sockglue.c
--- linux-2.6.4rc2F1/net/ipv4/ip_sockglue.c 2004-03-04 19:30:26.000000000 -0800
+++ linux-2.6.4rc2F2/net/ipv4/ip_sockglue.c 2004-03-06 00:10:21.000000000 -0800
@@ -771,6 +771,8 @@
}
case MCAST_MSFILTER:
{
+ extern int sysctl_optmem_max;
+ extern int sysctl_igmp_max_msf;
struct sockaddr_in *psin;
struct ip_msfilter *msf = 0;
struct group_filter *gsf = 0;
@@ -778,6 +780,10 @@
if (optlen < GROUP_FILTER_SIZE(0))
goto e_inval;
+ if (optlen > sysctl_optmem_max) {
+ err = -ENOBUFS;
+ break;
+ }
gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
if (gsf == 0) {
err = -ENOBUFS;
@@ -787,7 +793,13 @@
if (copy_from_user(gsf, optval, optlen)) {
goto mc_msf_out;
}
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < optlen) {
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ if (gsf->gf_numsrc >= 0x1ffffff ||
+ gsf->gf_numsrc > sysctl_igmp_max_msf) {
+ err = -ENOBUFS;
+ goto mc_msf_out;
+ }
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
err = EINVAL;
goto mc_msf_out;
}
diff -ruN linux-2.6.4rc2F1/net/ipv6/ipv6_sockglue.c linux-2.6.4rc2F2/net/ipv6/ipv6_sockglue.c
--- linux-2.6.4rc2F1/net/ipv6/ipv6_sockglue.c 2004-03-04 16:18:24.000000000 -0800
+++ linux-2.6.4rc2F2/net/ipv6/ipv6_sockglue.c 2004-03-06 00:10:21.000000000 -0800
@@ -437,6 +437,7 @@
case MCAST_MSFILTER:
{
extern int sysctl_optmem_max;
+ extern int sysctl_mld_max_msf;
struct group_filter *gsf;
if (optlen < GROUP_FILTER_SIZE(0))
@@ -455,8 +456,14 @@
kfree(gsf);
break;
}
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < GROUP_FILTER_SIZE(0) ||
- GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ if (gsf->gf_numsrc >= 0x1ffffffU ||
+ gsf->gf_numsrc > sysctl_mld_max_msf) {
+ kfree(gsf);
+ retv = -ENOBUFS;
+ break;
+ }
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
kfree(gsf);
retv = -EINVAL;
break;
diff -ruN linux-2.6.4rc2F1/net/ipv6/mcast.c linux-2.6.4rc2F2/net/ipv6/mcast.c
--- linux-2.6.4rc2F1/net/ipv6/mcast.c 2004-03-04 16:18:24.000000000 -0800
+++ linux-2.6.4rc2F2/net/ipv6/mcast.c 2004-03-06 00:10:21.000000000 -0800
@@ -166,6 +166,10 @@
#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
+#define IPV6_MLD_MAX_MSF 10
+
+int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
+
/*
* socket join on multicast group
*/
@@ -404,6 +408,10 @@
}
/* else, add a new source to the filter */
+ if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+ err = -ENOBUFS;
+ goto done;
+ }
if (!psl || psl->sl_count == psl->sl_max) {
struct ip6_sf_socklist *newpsl;
int count = IP6_SFBLOCK;
diff -ruN linux-2.6.4rc2F1/net/ipv6/sysctl_net_ipv6.c linux-2.6.4rc2F2/net/ipv6/sysctl_net_ipv6.c
--- linux-2.6.4rc2F1/net/ipv6/sysctl_net_ipv6.c 2004-03-04 16:18:24.000000000 -0800
+++ linux-2.6.4rc2F2/net/ipv6/sysctl_net_ipv6.c 2004-03-06 00:16:32.000000000 -0800
@@ -76,6 +76,14 @@
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies
},
+ {
+ .ctl_name = NET_IPV6_MLD_MAX_MSF,
+ .procname = "mld_max_msf",
+ .data = &sysctl_mld_max_msf,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
{ .ctl_name = 0 }
};
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] multi-protocol MSF API sysctl limit support
2004-03-06 9:37 [PATCH] multi-protocol MSF API sysctl limit support David Stevens
@ 2004-03-08 20:17 ` David S. Miller
0 siblings, 0 replies; 2+ messages in thread
From: David S. Miller @ 2004-03-08 20:17 UTC (permalink / raw)
To: David Stevens; +Cc: netdev
On Sat, 6 Mar 2004 02:37:56 -0700
David Stevens <dlstevens@us.ibm.com> wrote:
> This patch adds support for administrator-controlled multicast source
> filter limits for the multiprotocol multicast source filter API. The v4
> portion
> uses the same sysctl variable as the previous v4-only API patch, and
> the v6 portion uses a new v6 sysctl variable, "mld_max_msf".
Applied, thanks David.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-03-08 20:17 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-06 9:37 [PATCH] multi-protocol MSF API sysctl limit support David Stevens
2004-03-08 20:17 ` David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).