Commit dd12d6d5 authored by David S. Miller's avatar David S. Miller

Merge nuts.davemloft.net:/disk1/BK/network-2.6

into nuts.davemloft.net:/disk1/BK/net-2.6
parents 52d820cb b46f30e2
...@@ -405,7 +405,8 @@ enum { ...@@ -405,7 +405,8 @@ enum {
NET_IPV6_IP6FRAG_HIGH_THRESH=21, NET_IPV6_IP6FRAG_HIGH_THRESH=21,
NET_IPV6_IP6FRAG_LOW_THRESH=22, NET_IPV6_IP6FRAG_LOW_THRESH=22,
NET_IPV6_IP6FRAG_TIME=23, NET_IPV6_IP6FRAG_TIME=23,
NET_IPV6_IP6FRAG_SECRET_INTERVAL=24 NET_IPV6_IP6FRAG_SECRET_INTERVAL=24,
NET_IPV6_MLD_MAX_MSF=25,
}; };
enum { enum {
......
...@@ -108,6 +108,7 @@ struct frag_hdr { ...@@ -108,6 +108,7 @@ struct frag_hdr {
/* sysctls */ /* sysctls */
extern int sysctl_ipv6_bindv6only; extern int sysctl_ipv6_bindv6only;
extern int sysctl_mld_max_msf;
/* MIBs */ /* MIBs */
DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics); DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
......
...@@ -636,6 +636,7 @@ int ip_route_me_harder(struct sk_buff **pskb) ...@@ -636,6 +636,7 @@ int ip_route_me_harder(struct sk_buff **pskb)
#ifdef CONFIG_IP_ROUTE_FWMARK #ifdef CONFIG_IP_ROUTE_FWMARK
fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark; fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark;
#endif #endif
fl.proto = iph->protocol;
if (ip_route_output_key(&rt, &fl) != 0) if (ip_route_output_key(&rt, &fl) != 0)
return -1; return -1;
......
...@@ -771,6 +771,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt ...@@ -771,6 +771,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
} }
case MCAST_MSFILTER: case MCAST_MSFILTER:
{ {
extern int sysctl_optmem_max;
extern int sysctl_igmp_max_msf;
struct sockaddr_in *psin; struct sockaddr_in *psin;
struct ip_msfilter *msf = 0; struct ip_msfilter *msf = 0;
struct group_filter *gsf = 0; struct group_filter *gsf = 0;
...@@ -778,6 +780,10 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt ...@@ -778,6 +780,10 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
if (optlen < GROUP_FILTER_SIZE(0)) if (optlen < GROUP_FILTER_SIZE(0))
goto e_inval; goto e_inval;
if (optlen > sysctl_optmem_max) {
err = -ENOBUFS;
break;
}
gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL); gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
if (gsf == 0) { if (gsf == 0) {
err = -ENOBUFS; err = -ENOBUFS;
...@@ -787,7 +793,13 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt ...@@ -787,7 +793,13 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
if (copy_from_user(gsf, optval, optlen)) { if (copy_from_user(gsf, optval, optlen)) {
goto mc_msf_out; 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; err = EINVAL;
goto mc_msf_out; goto mc_msf_out;
} }
......
...@@ -1836,9 +1836,9 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void *user, unsigned int len) ...@@ -1836,9 +1836,9 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void *user, unsigned int len)
/* Check for valid protocol: TCP or UDP, even for fwmark!=0 */ /* Check for valid protocol: TCP or UDP, even for fwmark!=0 */
if (usvc->protocol!=IPPROTO_TCP && usvc->protocol!=IPPROTO_UDP) { if (usvc->protocol!=IPPROTO_TCP && usvc->protocol!=IPPROTO_UDP) {
IP_VS_INFO("vs_ctl: invalid protocol: %d %d.%d.%d.%d:%d %s", IP_VS_ERR("set_ctl: invalid protocol: %d %d.%d.%d.%d:%d %s\n",
ntohs(usvc->protocol), NIPQUAD(usvc->addr), usvc->protocol, NIPQUAD(usvc->addr),
ntohs(usvc->port), usvc->sched_name); ntohs(usvc->port), usvc->sched_name);
ret = -EFAULT; ret = -EFAULT;
goto out_unlock; goto out_unlock;
} }
......
...@@ -437,6 +437,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval, ...@@ -437,6 +437,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
case MCAST_MSFILTER: case MCAST_MSFILTER:
{ {
extern int sysctl_optmem_max; extern int sysctl_optmem_max;
extern int sysctl_mld_max_msf;
struct group_filter *gsf; struct group_filter *gsf;
if (optlen < GROUP_FILTER_SIZE(0)) if (optlen < GROUP_FILTER_SIZE(0))
...@@ -455,8 +456,14 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval, ...@@ -455,8 +456,14 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
kfree(gsf); kfree(gsf);
break; break;
} }
if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < GROUP_FILTER_SIZE(0) || /* numsrc >= (4G-140)/128 overflow in 32 bits */
GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) { 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); kfree(gsf);
retv = -EINVAL; retv = -EINVAL;
break; break;
......
...@@ -166,6 +166,10 @@ int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, ...@@ -166,6 +166,10 @@ int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 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 * socket join on multicast group
*/ */
...@@ -404,6 +408,10 @@ int ip6_mc_source(int add, int omode, struct sock *sk, ...@@ -404,6 +408,10 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
} }
/* else, add a new source to the filter */ /* 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) { if (!psl || psl->sl_count == psl->sl_max) {
struct ip6_sf_socklist *newpsl; struct ip6_sf_socklist *newpsl;
int count = IP6_SFBLOCK; int count = IP6_SFBLOCK;
......
...@@ -76,6 +76,14 @@ ctl_table ipv6_table[] = { ...@@ -76,6 +76,14 @@ ctl_table ipv6_table[] = {
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_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 } { .ctl_name = 0 }
}; };
......
...@@ -41,9 +41,6 @@ ...@@ -41,9 +41,6 @@
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
#include <net/inet_ecn.h> #include <net/inet_ecn.h>
#define RED_ECN_ECT 0x02
#define RED_ECN_CE 0x01
/* Random Early Detection (RED) algorithm. /* Random Early Detection (RED) algorithm.
======================================= =======================================
...@@ -165,28 +162,16 @@ static int red_ecn_mark(struct sk_buff *skb) ...@@ -165,28 +162,16 @@ static int red_ecn_mark(struct sk_buff *skb)
switch (skb->protocol) { switch (skb->protocol) {
case __constant_htons(ETH_P_IP): case __constant_htons(ETH_P_IP):
{ if (!INET_ECN_is_capable(skb->nh.iph->tos))
u8 tos = skb->nh.iph->tos;
if (!(tos & RED_ECN_ECT))
return 0; return 0;
if (INET_ECN_is_not_ce(skb->nh.iph->tos))
if (!(tos & RED_ECN_CE))
IP_ECN_set_ce(skb->nh.iph); IP_ECN_set_ce(skb->nh.iph);
return 1; return 1;
}
case __constant_htons(ETH_P_IPV6): case __constant_htons(ETH_P_IPV6):
{ if (!INET_ECN_is_capable(ip6_get_dsfield(skb->nh.ipv6h)))
u32 label = *(u32*)skb->nh.raw;
if (!(label & __constant_htonl(RED_ECN_ECT<<20)))
return 0; return 0;
label |= __constant_htonl(RED_ECN_CE<<20); IP6_ECN_set_ce(skb->nh.ipv6h);
return 1; return 1;
}
default: default:
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment