aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ah4.c4
-rw-r--r--net/ipv4/arp.c3
-rw-r--r--net/ipv4/devinet.c6
-rw-r--r--net/ipv4/esp4.c4
-rw-r--r--net/ipv4/fib_hash.c6
-rw-r--r--net/ipv4/fib_rules.c3
-rw-r--r--net/ipv4/fib_semantics.c27
-rw-r--r--net/ipv4/fib_trie.c2
-rw-r--r--net/ipv4/igmp.c50
-rw-r--r--net/ipv4/inet_diag.c3
-rw-r--r--net/ipv4/ip_gre.c1
-rw-r--r--net/ipv4/ip_input.c3
-rw-r--r--net/ipv4/ip_options.c1
-rw-r--r--net/ipv4/ip_output.c11
-rw-r--r--net/ipv4/ip_sockglue.c9
-rw-r--r--net/ipv4/ipcomp.c6
-rw-r--r--net/ipv4/ipip.c1
-rw-r--r--net/ipv4/ipmr.c21
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c10
-rw-r--r--net/ipv4/ipvs/ip_vs_est.c3
-rw-r--r--net/ipv4/netfilter/arp_tables.c27
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c17
-rw-r--r--net/ipv4/netfilter/ip_conntrack_sip.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_snmp_basic.c4
-rw-r--r--net/ipv4/netfilter/ip_tables.c36
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c3
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c5
-rw-r--r--net/ipv4/netfilter/ipt_hashlimit.c14
-rw-r--r--net/ipv4/raw.c1
-rw-r--r--net/ipv4/route.c10
-rw-r--r--net/ipv4/tcp.c5
-rw-r--r--net/ipv4/tcp_highspeed.c13
-rw-r--r--net/ipv4/tcp_input.c3
-rw-r--r--net/ipv4/tcp_ipv4.c5
-rw-r--r--net/ipv4/tcp_minisocks.c4
-rw-r--r--net/ipv4/tcp_output.c12
-rw-r--r--net/ipv4/tcp_probe.c5
-rw-r--r--net/ipv4/udp.c3
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c1
41 files changed, 201 insertions, 149 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 8e748be36c5a..1366bc6ce6a5 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -215,12 +215,10 @@ static int ah_init_state(struct xfrm_state *x)
if (x->encap)
goto error;
- ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
+ ahp = kzalloc(sizeof(*ahp), GFP_KERNEL);
if (ahp == NULL)
return -ENOMEM;
- memset(ahp, 0, sizeof(*ahp));
-
ahp->key = x->aalg->alg_key;
ahp->key_len = (x->aalg->alg_key_len+7)/8;
ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 7b51b3bdb548..c8a3723bc001 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1372,12 +1372,11 @@ static int arp_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct neigh_seq_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct neigh_seq_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
- memset(s, 0, sizeof(*s));
rc = seq_open(file, &arp_seq_ops);
if (rc)
goto out_kfree;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a7c65e9e5ec9..a6cc31d911eb 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -93,10 +93,9 @@ static void devinet_sysctl_unregister(struct ipv4_devconf *p);
static struct in_ifaddr *inet_alloc_ifa(void)
{
- struct in_ifaddr *ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
+ struct in_ifaddr *ifa = kzalloc(sizeof(*ifa), GFP_KERNEL);
if (ifa) {
- memset(ifa, 0, sizeof(*ifa));
INIT_RCU_HEAD(&ifa->rcu_head);
}
@@ -140,10 +139,9 @@ struct in_device *inetdev_init(struct net_device *dev)
ASSERT_RTNL();
- in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL);
+ in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL);
if (!in_dev)
goto out;
- memset(in_dev, 0, sizeof(*in_dev));
INIT_RCU_HEAD(&in_dev->rcu_head);
memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
in_dev->cnf.sysctl = NULL;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 4e112738b3fa..fc2f8ce441de 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -316,12 +316,10 @@ static int esp_init_state(struct xfrm_state *x)
if (x->ealg == NULL)
goto error;
- esp = kmalloc(sizeof(*esp), GFP_KERNEL);
+ esp = kzalloc(sizeof(*esp), GFP_KERNEL);
if (esp == NULL)
return -ENOMEM;
- memset(esp, 0, sizeof(*esp));
-
if (x->aalg) {
struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 3c1d32ad35f2..72c633b357cf 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -204,11 +204,10 @@ static struct fn_zone *
fn_new_zone(struct fn_hash *table, int z)
{
int i;
- struct fn_zone *fz = kmalloc(sizeof(struct fn_zone), GFP_KERNEL);
+ struct fn_zone *fz = kzalloc(sizeof(struct fn_zone), GFP_KERNEL);
if (!fz)
return NULL;
- memset(fz, 0, sizeof(struct fn_zone));
if (z) {
fz->fz_divisor = 16;
} else {
@@ -1046,7 +1045,7 @@ static int fib_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct fib_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct fib_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
@@ -1057,7 +1056,6 @@ static int fib_seq_open(struct inode *inode, struct file *file)
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 773b12ba4e3c..79b04718bdfd 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -196,10 +196,9 @@ int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
}
}
- new_r = kmalloc(sizeof(*new_r), GFP_KERNEL);
+ new_r = kzalloc(sizeof(*new_r), GFP_KERNEL);
if (!new_r)
return -ENOMEM;
- memset(new_r, 0, sizeof(*new_r));
if (rta[RTA_SRC-1])
memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 4);
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 5f87533684d5..51738000f3dc 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -159,7 +159,7 @@ void free_fib_info(struct fib_info *fi)
void fib_release_info(struct fib_info *fi)
{
- write_lock(&fib_info_lock);
+ write_lock_bh(&fib_info_lock);
if (fi && --fi->fib_treeref == 0) {
hlist_del(&fi->fib_hash);
if (fi->fib_prefsrc)
@@ -172,7 +172,7 @@ void fib_release_info(struct fib_info *fi)
fi->fib_dead = 1;
fib_info_put(fi);
}
- write_unlock(&fib_info_lock);
+ write_unlock_bh(&fib_info_lock);
}
static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
@@ -598,7 +598,7 @@ static void fib_hash_move(struct hlist_head *new_info_hash,
unsigned int old_size = fib_hash_size;
unsigned int i, bytes;
- write_lock(&fib_info_lock);
+ write_lock_bh(&fib_info_lock);
old_info_hash = fib_info_hash;
old_laddrhash = fib_info_laddrhash;
fib_hash_size = new_size;
@@ -639,7 +639,7 @@ static void fib_hash_move(struct hlist_head *new_info_hash,
}
fib_info_laddrhash = new_laddrhash;
- write_unlock(&fib_info_lock);
+ write_unlock_bh(&fib_info_lock);
bytes = old_size * sizeof(struct hlist_head *);
fib_hash_free(old_info_hash, bytes);
@@ -709,11 +709,10 @@ fib_create_info(const struct rtmsg *r, struct kern_rta *rta,
goto failure;
}
- fi = kmalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
+ fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
if (fi == NULL)
goto failure;
fib_info_cnt++;
- memset(fi, 0, sizeof(*fi)+nhs*sizeof(struct fib_nh));
fi->fib_protocol = r->rtm_protocol;
@@ -821,7 +820,7 @@ link_it:
fi->fib_treeref++;
atomic_inc(&fi->fib_clntref);
- write_lock(&fib_info_lock);
+ write_lock_bh(&fib_info_lock);
hlist_add_head(&fi->fib_hash,
&fib_info_hash[fib_info_hashfn(fi)]);
if (fi->fib_prefsrc) {
@@ -840,7 +839,7 @@ link_it:
head = &fib_info_devhash[hash];
hlist_add_head(&nh->nh_hash, head);
} endfor_nexthops(fi)
- write_unlock(&fib_info_lock);
+ write_unlock_bh(&fib_info_lock);
return fi;
err_inval:
@@ -962,10 +961,6 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
rtm->rtm_protocol = fi->fib_protocol;
if (fi->fib_priority)
RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority);
-#ifdef CONFIG_NET_CLS_ROUTE
- if (fi->fib_nh[0].nh_tclassid)
- RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid);
-#endif
if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
goto rtattr_failure;
if (fi->fib_prefsrc)
@@ -975,6 +970,10 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
RTA_PUT(skb, RTA_GATEWAY, 4, &fi->fib_nh->nh_gw);
if (fi->fib_nh->nh_oif)
RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif);
+#ifdef CONFIG_NET_CLS_ROUTE
+ if (fi->fib_nh[0].nh_tclassid)
+ RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid);
+#endif
}
#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (fi->fib_nhs > 1) {
@@ -993,6 +992,10 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
nhp->rtnh_ifindex = nh->nh_oif;
if (nh->nh_gw)
RTA_PUT(skb, RTA_GATEWAY, 4, &nh->nh_gw);
+#ifdef CONFIG_NET_CLS_ROUTE
+ if (nh->nh_tclassid)
+ RTA_PUT(skb, RTA_FLOW, 4, &nh->nh_tclassid);
+#endif
nhp->rtnh_len = skb->tail - (unsigned char*)nhp;
} endfor_nexthops(fi);
mp_head->rta_type = RTA_MULTIPATH;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 1cb65305e102..23fb9d9768e3 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1252,8 +1252,8 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
*/
if (!fa_head) {
- fa_head = fib_insert_node(t, &err, key, plen);
err = 0;
+ fa_head = fib_insert_node(t, &err, key, plen);
if (err)
goto out_free_new_fa;
}
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index d299c8e547d6..8e8117c19e4d 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1028,10 +1028,9 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
* for deleted items allows change reports to use common code with
* non-deleted or query-response MCA's.
*/
- pmc = kmalloc(sizeof(*pmc), GFP_KERNEL);
+ pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
if (!pmc)
return;
- memset(pmc, 0, sizeof(*pmc));
spin_lock_bh(&im->lock);
pmc->interface = im->interface;
in_dev_hold(in_dev);
@@ -1529,10 +1528,9 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
psf_prev = psf;
}
if (!psf) {
- psf = kmalloc(sizeof(*psf), GFP_ATOMIC);
+ psf = kzalloc(sizeof(*psf), GFP_ATOMIC);
if (!psf)
return -ENOBUFS;
- memset(psf, 0, sizeof(*psf));
psf->sf_inaddr = *psfsrc;
if (psf_prev) {
psf_prev->sf_next = psf;
@@ -1795,29 +1793,35 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
struct in_device *in_dev;
u32 group = imr->imr_multiaddr.s_addr;
u32 ifindex;
+ int ret = -EADDRNOTAVAIL;
rtnl_lock();
in_dev = ip_mc_find_dev(imr);
- if (!in_dev) {
- rtnl_unlock();
- return -ENODEV;
- }
ifindex = imr->imr_ifindex;
for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) {
- if (iml->multi.imr_multiaddr.s_addr == group &&
- iml->multi.imr_ifindex == ifindex) {
- (void) ip_mc_leave_src(sk, iml, in_dev);
+ if (iml->multi.imr_multiaddr.s_addr != group)
+ continue;
+ if (ifindex) {
+ if (iml->multi.imr_ifindex != ifindex)
+ continue;
+ } else if (imr->imr_address.s_addr && imr->imr_address.s_addr !=
+ iml->multi.imr_address.s_addr)
+ continue;
+
+ (void) ip_mc_leave_src(sk, iml, in_dev);
- *imlp = iml->next;
+ *imlp = iml->next;
+ if (in_dev)
ip_mc_dec_group(in_dev, group);
- rtnl_unlock();
- sock_kfree_s(sk, iml, sizeof(*iml));
- return 0;
- }
+ rtnl_unlock();
+ sock_kfree_s(sk, iml, sizeof(*iml));
+ return 0;
}
+ if (!in_dev)
+ ret = -ENODEV;
rtnl_unlock();
- return -EADDRNOTAVAIL;
+ return ret;
}
int ip_mc_source(int add, int omode, struct sock *sk, struct
@@ -2201,13 +2205,13 @@ void ip_mc_drop_socket(struct sock *sk)
struct in_device *in_dev;
inet->mc_list = iml->next;
- if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) {
- (void) ip_mc_leave_src(sk, iml, in_dev);
+ in_dev = inetdev_by_index(iml->multi.imr_ifindex);
+ (void) ip_mc_leave_src(sk, iml, in_dev);
+ if (in_dev != NULL) {
ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
in_dev_put(in_dev);
}
sock_kfree_s(sk, iml, sizeof(*iml));
-
}
rtnl_unlock();
}
@@ -2380,7 +2384,7 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct igmp_mc_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct igmp_mc_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
@@ -2390,7 +2394,6 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file)
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
@@ -2555,7 +2558,7 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct igmp_mcf_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct igmp_mcf_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
@@ -2565,7 +2568,6 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 8e7e41b66c79..492858e6faf0 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -909,11 +909,10 @@ static int __init inet_diag_init(void)
sizeof(struct inet_diag_handler *));
int err = -ENOMEM;
- inet_diag_table = kmalloc(inet_diag_table_size, GFP_KERNEL);
+ inet_diag_table = kzalloc(inet_diag_table_size, GFP_KERNEL);
if (!inet_diag_table)
goto out;
- memset(inet_diag_table, 0, inet_diag_table_size);
idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv,
THIS_MODULE);
if (idiagnl == NULL)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6ff9b10d9563..0f9b3a31997b 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -617,7 +617,6 @@ static int ipgre_rcv(struct sk_buff *skb)
skb->mac.raw = skb->nh.raw;
skb->nh.raw = __pskb_pull(skb, offset);
skb_postpull_rcsum(skb, skb->h.raw, offset);
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
skb->pkt_type = PACKET_HOST;
#ifdef CONFIG_NET_IPGRE_BROADCAST
if (MULTICAST(iph->daddr)) {
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index e1a7dba2fa8a..212734ca238f 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -428,6 +428,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
goto drop;
}
+ /* Remove any debris in the socket control block */
+ memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
+
return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
ip_rcv_finish);
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index cbcae6544622..406056edc02b 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -256,7 +256,6 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
if (!opt) {
opt = &(IPCB(skb)->opt);
- memset(opt, 0, sizeof(struct ip_options));
iph = skb->nh.raw;
opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr);
optptr = iph + sizeof(struct iphdr);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 7c9f9a6421b8..4c20f5546893 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -526,6 +526,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
err = output(skb);
+ if (!err)
+ IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
if (err || !frag)
break;
@@ -649,9 +651,6 @@ slow_path:
/*
* Put this fragment into the sending queue.
*/
-
- IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
-
iph->tot_len = htons(len + hlen);
ip_send_check(iph);
@@ -659,6 +658,8 @@ slow_path:
err = output(skb2);
if (err)
goto fail;
+
+ IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
}
kfree_skb(skb);
IP_INC_STATS(IPSTATS_MIB_FRAGOKS);
@@ -946,7 +947,7 @@ alloc_new_skb:
skb_prev->csum = csum_sub(skb_prev->csum,
skb->csum);
data += fraggap;
- skb_trim(skb_prev, maxfraglen);
+ pskb_trim_unique(skb_prev, maxfraglen);
}
copy = datalen - transhdrlen - fraggap;
@@ -1141,7 +1142,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
data, fraggap, 0);
skb_prev->csum = csum_sub(skb_prev->csum,
skb->csum);
- skb_trim(skb_prev, maxfraglen);
+ pskb_trim_unique(skb_prev, maxfraglen);
}
/*
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 84f43a3c9098..2d05c4133d3e 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -112,14 +112,19 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
{
char *secdata;
- u32 seclen;
+ u32 seclen, secid;
int err;
- err = security_socket_getpeersec_dgram(skb, &secdata, &seclen);
+ err = security_socket_getpeersec_dgram(NULL, skb, &secid);
+ if (err)
+ return;
+
+ err = security_secid_to_secctx(secid, &secdata, &seclen);
if (err)
return;
put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
+ security_release_secctx(secdata, seclen);
}
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 8e0374847532..a0c28b2b756e 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -70,7 +70,8 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)
if (err)
goto out;
- skb_put(skb, dlen - plen);
+ skb->truesize += dlen - plen;
+ __skb_put(skb, dlen - plen);
memcpy(skb->data, scratch, dlen);
out:
put_cpu();
@@ -409,11 +410,10 @@ static int ipcomp_init_state(struct xfrm_state *x)
goto out;
err = -ENOMEM;
- ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
+ ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
if (!ipcd)
goto out;
- memset(ipcd, 0, sizeof(*ipcd));
x->props.header_len = 0;
if (x->props.mode)
x->props.header_len += sizeof(struct iphdr);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 3291d5192aad..76ab50b0d6ef 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -487,7 +487,6 @@ static int ipip_rcv(struct sk_buff *skb)
skb->mac.raw = skb->nh.raw;
skb->nh.raw = skb->data;
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
skb->protocol = htons(ETH_P_IP);
skb->pkt_type = PACKET_HOST;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index ba33f8621c67..85893eef6b16 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1461,7 +1461,6 @@ int pim_rcv_v1(struct sk_buff * skb)
skb_pull(skb, (u8*)encap - skb->data);
skb->nh.iph = (struct iphdr *)skb->data;
skb->dev = reg_dev;
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
skb->protocol = htons(ETH_P_IP);
skb->ip_summed = 0;
skb->pkt_type = PACKET_HOST;
@@ -1517,7 +1516,6 @@ static int pim_rcv(struct sk_buff * skb)
skb_pull(skb, (u8*)encap - skb->data);
skb->nh.iph = (struct iphdr *)skb->data;
skb->dev = reg_dev;
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
skb->protocol = htons(ETH_P_IP);
skb->ip_summed = 0;
skb->pkt_type = PACKET_HOST;
@@ -1580,6 +1578,7 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
cache = ipmr_cache_find(rt->rt_src, rt->rt_dst);
if (cache==NULL) {
+ struct sk_buff *skb2;
struct net_device *dev;
int vif;
@@ -1593,12 +1592,18 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
read_unlock(&mrt_lock);
return -ENODEV;
}
- skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
- skb->nh.iph->ihl = sizeof(struct iphdr)>>2;
- skb->nh.iph->saddr = rt->rt_src;
- skb->nh.iph->daddr = rt->rt_dst;
- skb->nh.iph->version = 0;
- err = ipmr_cache_unresolved(vif, skb);
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (!skb2) {
+ read_unlock(&mrt_lock);
+ return -ENOMEM;
+ }
+
+ skb2->nh.raw = skb_push(skb2, sizeof(struct iphdr));
+ skb2->nh.iph->ihl = sizeof(struct iphdr)>>2;
+ skb2->nh.iph->saddr = rt->rt_src;
+ skb2->nh.iph->daddr = rt->rt_dst;
+ skb2->nh.iph->version = 0;
+ err = ipmr_cache_unresolved(vif, skb2);
read_unlock(&mrt_lock);
return err;
}
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index f28ec6882162..6a28fafe910c 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -735,12 +735,11 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest,
if (atype != RTN_LOCAL && atype != RTN_UNICAST)
return -EINVAL;
- dest = kmalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC);
+ dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC);
if (dest == NULL) {
IP_VS_ERR("ip_vs_new_dest: kmalloc failed.\n");
return -ENOMEM;
}
- memset(dest, 0, sizeof(struct ip_vs_dest));
dest->protocol = svc->protocol;
dest->vaddr = svc->addr;
@@ -1050,14 +1049,12 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p)
goto out_mod_dec;
}
- svc = (struct ip_vs_service *)
- kmalloc(sizeof(struct ip_vs_service), GFP_ATOMIC);
+ svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC);
if (svc == NULL) {
IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n");
ret = -ENOMEM;
goto out_err;
}
- memset(svc, 0, sizeof(struct ip_vs_service));
/* I'm the first user of the service */
atomic_set(&svc->usecnt, 1);
@@ -1797,7 +1794,7 @@ static int ip_vs_info_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct ip_vs_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct ip_vs_iter *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
@@ -1808,7 +1805,6 @@ static int ip_vs_info_open(struct inode *inode, struct file *file)
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c
index 4c1940381ba0..7d68b80c4c19 100644
--- a/net/ipv4/ipvs/ip_vs_est.c
+++ b/net/ipv4/ipvs/ip_vs_est.c
@@ -123,11 +123,10 @@ int ip_vs_new_estimator(struct ip_vs_stats *stats)
{
struct ip_vs_estimator *est;
- est = kmalloc(sizeof(*est), GFP_KERNEL);
+ est = kzalloc(sizeof(*est), GFP_KERNEL);
if (est == NULL)
return -ENOMEM;
- memset(est, 0, sizeof(*est));
est->stats = stats;
est->last_conns = stats->conns;
est->cps = stats->cps<<10;
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 80c73ca90116..df4854cf598b 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1170,21 +1170,34 @@ static int __init arp_tables_init(void)
{
int ret;
- xt_proto_init(NF_ARP);
+ ret = xt_proto_init(NF_ARP);
+ if (ret < 0)
+ goto err1;
/* Noone else will be downing sem now, so we won't sleep */
- xt_register_target(&arpt_standard_target);
- xt_register_target(&arpt_error_target);
+ ret = xt_register_target(&arpt_standard_target);
+ if (ret < 0)
+ goto err2;
+ ret = xt_register_target(&arpt_error_target);
+ if (ret < 0)
+ goto err3;
/* Register setsockopt */
ret = nf_register_sockopt(&arpt_sockopts);
- if (ret < 0) {
- duprintf("Unable to register sockopts.\n");
- return ret;
- }
+ if (ret < 0)
+ goto err4;
printk("arp_tables: (C) 2002 David S. Miller\n");
return 0;
+
+err4:
+ xt_unregister_target(&arpt_error_target);
+err3:
+ xt_unregister_target(&arpt_standard_target);
+err2:
+ xt_proto_fini(NF_ARP);
+err1:
+ return ret;
}
static void __exit arp_tables_fini(void)
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
index af35235672d5..9a39e2969712 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
@@ -1200,7 +1200,7 @@ static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct,
tuple.dst.protonum = IPPROTO_TCP;
exp = __ip_conntrack_expect_find(&tuple);
- if (exp->master == ct)
+ if (exp && exp->master == ct)
return exp;
return NULL;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 33891bb1fde4..0d4cc92391fa 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -415,21 +415,18 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
cb->args[0], *id);
read_lock_bh(&ip_conntrack_lock);
+ last = (struct ip_conntrack *)cb->args[1];
for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) {
restart:
- last = (struct ip_conntrack *)cb->args[1];
list_for_each_prev(i, &ip_conntrack_hash[cb->args[0]]) {
h = (struct ip_conntrack_tuple_hash *) i;
if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
continue;
ct = tuplehash_to_ctrack(h);
- if (last != NULL) {
- if (ct == last) {
- ip_conntrack_put(last);
- cb->args[1] = 0;
- last = NULL;
- } else
+ if (cb->args[1]) {
+ if (ct != last)
continue;
+ cb->args[1] = 0;
}
if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
@@ -440,17 +437,17 @@ restart:
goto out;
}
}
- if (last != NULL) {
- ip_conntrack_put(last);
+ if (cb->args[1]) {
cb->args[1] = 0;
goto restart;
}
}
out:
read_unlock_bh(&ip_conntrack_lock);
+ if (last)
+ ip_conntrack_put(last);
DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
-
return skb->len;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_sip.c b/net/ipv4/netfilter/ip_conntrack_sip.c
index fc87ce0da40d..4f222d6be009 100644
--- a/net/ipv4/netfilter/ip_conntrack_sip.c
+++ b/net/ipv4/netfilter/ip_conntrack_sip.c
@@ -442,7 +442,7 @@ static int __init init(void)
sip[i].tuple.src.u.udp.port = htons(ports[i]);
sip[i].mask.src.u.udp.port = 0xFFFF;
sip[i].mask.dst.protonum = 0xFF;
- sip[i].max_expected = 1;
+ sip[i].max_expected = 2;
sip[i].timeout = 3 * 60; /* 3 minutes */
sip[i].me = THIS_MODULE;
sip[i].help = sip_help;
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 7bd3c22003a2..7a9fa04a467a 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -534,6 +534,8 @@ static struct nf_hook_ops ip_conntrack_ops[] = {
/* Sysctl support */
+int ip_conntrack_checksum = 1;
+
#ifdef CONFIG_SYSCTL
/* From ip_conntrack_core.c */
@@ -568,8 +570,6 @@ extern unsigned int ip_ct_generic_timeout;
static int log_invalid_proto_min = 0;
static int log_invalid_proto_max = 255;
-int ip_conntrack_checksum = 1;
-
static struct ctl_table_header *ip_ct_sysctl_header;
static ctl_table ip_ct_sysctl_table[] = {
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 0b1b416759cc..18b7fbdccb61 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -1255,9 +1255,9 @@ static int help(struct sk_buff **pskb,
struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
/* SNMP replies and originating SNMP traps get mangled */
- if (udph->source == ntohs(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
+ if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
return NF_ACCEPT;
- if (udph->dest == ntohs(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
+ if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
return NF_ACCEPT;
/* No NAT? */
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index fc5bdd5eb7d3..048514f15f2f 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -230,7 +230,7 @@ ipt_do_table(struct sk_buff **pskb,
const char *indev, *outdev;
void *table_base;
struct ipt_entry *e, *back;
- struct xt_table_info *private = table->private;
+ struct xt_table_info *private;
/* Initialization */
ip = (*pskb)->nh.iph;
@@ -247,6 +247,7 @@ ipt_do_table(struct sk_buff **pskb,
read_lock_bh(&table->lock);
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
+ private = table->private;
table_base = (void *)private->entries[smp_processor_id()];
e = get_entry(table_base, private->hook_entry[hook]);
@@ -2239,22 +2240,39 @@ static int __init ip_tables_init(void)
{
int ret;
- xt_proto_init(AF_INET);
+ ret = xt_proto_init(AF_INET);
+ if (ret < 0)
+ goto err1;
/* Noone else will be downing sem now, so we won't sleep */
- xt_register_target(&ipt_standard_target);
- xt_register_target(&ipt_error_target);
- xt_register_match(&icmp_matchstruct);
+ ret = xt_register_target(&ipt_standard_target);
+ if (ret < 0)
+ goto err2;
+ ret = xt_register_target(&ipt_error_target);
+ if (ret < 0)
+ goto err3;
+ ret = xt_register_match(&icmp_matchstruct);
+ if (ret < 0)
+ goto err4;
/* Register setsockopt */
ret = nf_register_sockopt(&ipt_sockopts);
- if (ret < 0) {
- duprintf("Unable to register sockopts.\n");
- return ret;
- }
+ if (ret < 0)
+ goto err5;
printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n");
return 0;
+
+err5:
+ xt_unregister_match(&icmp_matchstruct);
+err4:
+ xt_unregister_target(&ipt_error_target);
+err3:
+ xt_unregister_target(&ipt_standard_target);
+err2:
+ xt_proto_fini(AF_INET);
+err1:
+ return ret;
}
static void __exit ip_tables_fini(void)
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index cbffeae3f565..d994c5f5744c 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -172,11 +172,10 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
struct clusterip_config *c;
char buffer[16];
- c = kmalloc(sizeof(*c), GFP_ATOMIC);
+ c = kzalloc(sizeof(*c), GFP_ATOMIC);
if (!c)
return NULL;
- memset(c, 0, sizeof(*c));
c->dev = dev;
c->clusterip = ip;
memcpy(&c->clustermac, &i->clustermac, ETH_ALEN);
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index d7dd7fe7051c..d46fd677fa11 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -115,6 +115,11 @@ static void ulog_send(unsigned int nlgroupnum)
del_timer(&ub->timer);
}
+ if (!ub->skb) {
+ DEBUGP("ipt_ULOG: ulog_send: nothing to send\n");
+ return;
+ }
+
/* last nlmsg needs NLMSG_DONE */
if (ub->qlen > 1)
ub->lastnlh->nlmsg_type = NLMSG_DONE;
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c
index 92980ab8ce48..3bd2368e1fc9 100644
--- a/net/ipv4/netfilter/ipt_hashlimit.c
+++ b/net/ipv4/netfilter/ipt_hashlimit.c
@@ -454,15 +454,12 @@ hashlimit_match(const struct sk_buff *skb,
dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
hinfo->cfg.burst);
dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
-
- spin_unlock_bh(&hinfo->lock);
- return 1;
+ } else {
+ /* update expiration timeout */
+ dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
+ rateinfo_recalc(dh, now);
}
- /* update expiration timeout */
- dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
-
- rateinfo_recalc(dh, now);
if (dh->rateinfo.credit >= dh->rateinfo.cost) {
/* We're underlimit. */
dh->rateinfo.credit -= dh->rateinfo.cost;
@@ -508,6 +505,9 @@ hashlimit_checkentry(const char *tablename,
if (!r->cfg.expire)
return 0;
+ if (r->name[sizeof(r->name) - 1] != '\0')
+ return 0;
+
/* This is the best we've got: We cannot release and re-grab lock,
* since checkentry() is called before ip_tables.c grabs ipt_mutex.
* We also cannot grab the hashtable spinlock, since htable_create will
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index bd221ec3f81e..62b2762a2420 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -609,6 +609,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (sin) {
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = skb->nh.iph->saddr;
+ sin->sin_port = 0;
memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
}
if (inet->cmsg_flags)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 2dc6dbb28467..b873cbcdd0b8 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -104,6 +104,7 @@
#include <net/icmp.h>
#include <net/xfrm.h>
#include <net/ip_mp_alg.h>
+#include <net/netevent.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
@@ -1125,6 +1126,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
struct rtable *rth, **rthp;
u32 skeys[2] = { saddr, 0 };
int ikeys[2] = { dev->ifindex, 0 };
+ struct netevent_redirect netevent;
if (!in_dev)
return;
@@ -1216,6 +1218,11 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
rt_drop(rt);
goto do_next;
}
+
+ netevent.old = &rth->u.dst;
+ netevent.new = &rt->u.dst;
+ call_netevent_notifiers(NETEVENT_REDIRECT,
+ &netevent);
rt_del(hash, rth);
if (!rt_intern_hash(hash, rt, &rt))
@@ -1452,6 +1459,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
}
dst->metrics[RTAX_MTU-1] = mtu;
dst_set_expires(dst, ip_rt_mtu_expires);
+ call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
}
}
@@ -3149,7 +3157,7 @@ int __init ip_rt_init(void)
rhash_entries,
(num_physpages >= 128 * 1024) ?
15 : 17,
- HASH_HIGHMEM,
+ 0,
&rt_hash_log,
&rt_hash_mask,
0);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f6a2d9223d07..934396bb1376 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1132,7 +1132,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
tp->ucopy.dma_chan = NULL;
preempt_disable();
if ((len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) &&
- !sysctl_tcp_low_latency && __get_cpu_var(softnet_data.net_dma)) {
+ !sysctl_tcp_low_latency && __get_cpu_var(softnet_data).net_dma) {
preempt_enable_no_resched();
tp->ucopy.pinned_list = dma_pin_iovec_pages(msg->msg_iov, len);
} else
@@ -1659,7 +1659,8 @@ adjudge_to_death:
const int tmo = tcp_fin_time(sk);
if (tmo > TCP_TIMEWAIT_LEN) {
- inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk));
+ inet_csk_reset_keepalive_timer(sk,
+ tmo - TCP_TIMEWAIT_LEN);
} else {
tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
goto out;
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c
index aaa1538c0692..fa3e1aad660c 100644
--- a/net/ipv4/tcp_highspeed.c
+++ b/net/ipv4/tcp_highspeed.c
@@ -139,14 +139,19 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
tp->snd_cwnd++;
}
} else {
- /* Update AIMD parameters */
+ /* Update AIMD parameters.
+ *
+ * We want to guarantee that:
+ * hstcp_aimd_vals[ca->ai-1].cwnd <
+ * snd_cwnd <=
+ * hstcp_aimd_vals[ca->ai].cwnd
+ */
if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
ca->ai < HSTCP_AIMD_MAX - 1)
ca->ai++;
- } else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) {
- while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
- ca->ai > 0)
+ } else if (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd) {
+ while (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd)
ca->ai--;
}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 738dad9f7d49..104af5d5bcbc 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3541,7 +3541,8 @@ void tcp_cwnd_application_limited(struct sock *sk)
if (inet_csk(sk)->icsk_ca_state == TCP_CA_Open &&
sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
/* Limited by application or receiver window. */
- u32 win_used = max(tp->snd_cwnd_used, 2U);
+ u32 init_win = tcp_init_cwnd(tp, __sk_dst_get(sk));
+ u32 win_used = max(tp->snd_cwnd_used, init_win);
if (win_used < tp->snd_cwnd) {
tp->snd_ssthresh = tcp_current_ssthresh(sk);
tp->snd_cwnd = (tp->snd_cwnd + win_used) >> 1;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a891133f00e4..4b04c3edd4a9 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -438,7 +438,6 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
It can f.e. if SYNs crossed.
*/
if (!sock_owned_by_user(sk)) {
- TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
sk->sk_err = err;
sk->sk_error_report(sk);
@@ -874,7 +873,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
drop_and_free:
reqsk_free(req);
drop:
- TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
return 0;
}
@@ -1640,10 +1638,9 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
if (unlikely(afinfo == NULL))
return -EINVAL;
- s = kmalloc(sizeof(*s), GFP_KERNEL);
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
return -ENOMEM;
- memset(s, 0, sizeof(*s));
s->family = afinfo->family;
s->seq_ops.start = tcp_seq_start;
s->seq_ops.next = tcp_seq_next;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 0ccb7cb22b15..624e2b2c7f53 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -589,8 +589,10 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
/* RFC793: "second check the RST bit" and
* "fourth, check the SYN bit"
*/
- if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN))
+ if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) {
+ TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
goto embryonic_reset;
+ }
/* ACK sequence verified above, just make sure ACK is
* set. If ACK not set, just silently drop the packet.
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 5c08ea20a18d..507adefbc17c 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -466,7 +466,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
if (skb->len != tcp_header_size)
tcp_event_data_sent(tp, skb, sk);
- TCP_INC_STATS(TCP_MIB_OUTSEGS);
+ if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq)
+ TCP_INC_STATS(TCP_MIB_OUTSEGS);
err = icsk->icsk_af_ops->queue_xmit(skb, 0);
if (likely(err <= 0))
@@ -2157,10 +2158,9 @@ int tcp_connect(struct sock *sk)
skb_shinfo(buff)->gso_size = 0;
skb_shinfo(buff)->gso_type = 0;
buff->csum = 0;
+ tp->snd_nxt = tp->write_seq;
TCP_SKB_CB(buff)->seq = tp->write_seq++;
TCP_SKB_CB(buff)->end_seq = tp->write_seq;
- tp->snd_nxt = tp->write_seq;
- tp->pushed_seq = tp->write_seq;
/* Send it off. */
TCP_SKB_CB(buff)->when = tcp_time_stamp;
@@ -2170,6 +2170,12 @@ int tcp_connect(struct sock *sk)
sk_charge_skb(sk, buff);
tp->packets_out += tcp_skb_pcount(buff);
tcp_transmit_skb(sk, buff, 1, GFP_KERNEL);
+
+ /* We change tp->snd_nxt after the tcp_transmit_skb() call
+ * in order to make this packet get counted in tcpOutSegs.
+ */
+ tp->snd_nxt = tp->write_seq;
+ tp->pushed_seq = tp->write_seq;
TCP_INC_STATS(TCP_MIB_ACTIVEOPENS);
/* Timer for repeating the SYN until an answer. */
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index d7d517a3a238..dab37d2f65fc 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -114,7 +114,7 @@ static int tcpprobe_open(struct inode * inode, struct file * file)
static ssize_t tcpprobe_read(struct file *file, char __user *buf,
size_t len, loff_t *ppos)
{
- int error = 0, cnt;
+ int error = 0, cnt = 0;
unsigned char *tbuf;
if (!buf || len < 0)
@@ -130,11 +130,12 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf,
error = wait_event_interruptible(tcpw.wait,
__kfifo_len(tcpw.fifo) != 0);
if (error)
- return error;
+ goto out_free;
cnt = kfifo_get(tcpw.fifo, tbuf, len);
error = copy_to_user(buf, tbuf, cnt);
+out_free:
vfree(tbuf);
return error ? error : cnt;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 9bfcddad695b..f136cec96d95 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1468,11 +1468,10 @@ static int udp_seq_open(struct inode *inode, struct file *file)
struct udp_seq_afinfo *afinfo = PDE(inode)->data;
struct seq_file *seq;
int rc = -ENOMEM;
- struct udp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
- memset(s, 0, sizeof(*s));
s->family = afinfo->family;
s->seq_ops.start = udp_seq_start;
s->seq_ops.next = udp_seq_next;
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index f8d880beb12f..13cafbe56ce3 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -92,7 +92,6 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
skb->mac.raw = memmove(skb->data - skb->mac_len,
skb->mac.raw, skb->mac_len);
skb->nh.raw = skb->data;
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
err = 0;
out: