aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c1
-rw-r--r--net/ipv4/devinet.c34
-rw-r--r--net/ipv4/esp4.c2
-rw-r--r--net/ipv4/icmp.c9
-rw-r--r--net/ipv4/ipvs/Makefile2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto.c3
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_icmp.c182
-rw-r--r--net/ipv4/multipath_drr.c20
-rw-r--r--net/ipv4/multipath_random.c2
-rw-r--r--net/ipv4/multipath_rr.c22
-rw-r--r--net/ipv4/multipath_wrandom.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c1
-rw-r--r--net/ipv4/netfilter/ip_queue.c10
-rw-r--r--net/ipv4/netfilter/ipt_recent.c10
-rw-r--r--net/ipv4/sysctl_net_ipv4.c9
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/udp.c12
17 files changed, 80 insertions, 243 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index b3cb49ce5fa..03942f13394 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1181,6 +1181,7 @@ EXPORT_SYMBOL(inet_stream_connect);
EXPORT_SYMBOL(inet_stream_ops);
EXPORT_SYMBOL(inet_unregister_protosw);
EXPORT_SYMBOL(net_statistics);
+EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
#ifdef INET_REFCNT_DEBUG
EXPORT_SYMBOL(inet_sock_nr);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 3cc96730c4e..478a30179a5 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -233,11 +233,14 @@ int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
int destroy)
{
+ struct in_ifaddr *promote = NULL;
struct in_ifaddr *ifa1 = *ifap;
ASSERT_RTNL();
- /* 1. Deleting primary ifaddr forces deletion all secondaries */
+ /* 1. Deleting primary ifaddr forces deletion all secondaries
+ * unless alias promotion is set
+ **/
if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
struct in_ifaddr *ifa;
@@ -251,11 +254,16 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
continue;
}
- *ifap1 = ifa->ifa_next;
+ if (!IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
+ *ifap1 = ifa->ifa_next;
- rtmsg_ifa(RTM_DELADDR, ifa);
- notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
- inet_free_ifa(ifa);
+ rtmsg_ifa(RTM_DELADDR, ifa);
+ notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
+ inet_free_ifa(ifa);
+ } else {
+ promote = ifa;
+ break;
+ }
}
}
@@ -281,6 +289,13 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
if (!in_dev->ifa_list)
inetdev_destroy(in_dev);
}
+
+ if (promote && IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
+ /* not sure if we should send a delete notify first? */
+ promote->ifa_flags &= ~IFA_F_SECONDARY;
+ rtmsg_ifa(RTM_NEWADDR, promote);
+ notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote);
+ }
}
static int inet_insert_ifa(struct in_ifaddr *ifa)
@@ -1384,6 +1399,15 @@ static struct devinet_sysctl_table {
.proc_handler = &ipv4_doint_and_flush,
.strategy = &ipv4_doint_and_flush_strategy,
},
+ {
+ .ctl_name = NET_IPV4_CONF_PROMOTE_SECONDARIES,
+ .procname = "promote_secondaries",
+ .data = &ipv4_devconf.promote_secondaries,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &ipv4_doint_and_flush,
+ .strategy = &ipv4_doint_and_flush_strategy,
+ },
},
.devinet_dev = {
{
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 053a883247b..eae84cc39d3 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -478,7 +478,7 @@ static int __init esp4_init(void)
{
struct xfrm_decap_state decap;
- if (sizeof(struct esp_decap_data) <
+ if (sizeof(struct esp_decap_data) >
sizeof(decap.decap_data)) {
extern void decap_data_too_small(void);
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 85bf0d3e294..cb759484979 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -207,6 +207,7 @@ int sysctl_icmp_ignore_bogus_error_responses;
int sysctl_icmp_ratelimit = 1 * HZ;
int sysctl_icmp_ratemask = 0x1818;
+int sysctl_icmp_errors_use_inbound_ifaddr;
/*
* ICMP control array. This specifies what to do with each ICMP.
@@ -511,8 +512,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
*/
saddr = iph->daddr;
- if (!(rt->rt_flags & RTCF_LOCAL))
- saddr = 0;
+ if (!(rt->rt_flags & RTCF_LOCAL)) {
+ if (sysctl_icmp_errors_use_inbound_ifaddr)
+ saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
+ else
+ saddr = 0;
+ }
tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) |
IPTOS_PREC_INTERNETCONTROL) :
diff --git a/net/ipv4/ipvs/Makefile b/net/ipv4/ipvs/Makefile
index a788461a40c..30e85de9fff 100644
--- a/net/ipv4/ipvs/Makefile
+++ b/net/ipv4/ipvs/Makefile
@@ -11,7 +11,7 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o
ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \
ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \
- ip_vs_est.o ip_vs_proto.o ip_vs_proto_icmp.o \
+ ip_vs_est.o ip_vs_proto.o \
$(ip_vs_proto-objs-y)
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index 253c46252bd..867d4e9c659 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -216,9 +216,6 @@ int ip_vs_protocol_init(void)
#ifdef CONFIG_IP_VS_PROTO_UDP
REGISTER_PROTOCOL(&ip_vs_protocol_udp);
#endif
-#ifdef CONFIG_IP_VS_PROTO_ICMP
- REGISTER_PROTOCOL(&ip_vs_protocol_icmp);
-#endif
#ifdef CONFIG_IP_VS_PROTO_AH
REGISTER_PROTOCOL(&ip_vs_protocol_ah);
#endif
diff --git a/net/ipv4/ipvs/ip_vs_proto_icmp.c b/net/ipv4/ipvs/ip_vs_proto_icmp.c
deleted file mode 100644
index 191e94aa1c1..00000000000
--- a/net/ipv4/ipvs/ip_vs_proto_icmp.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * ip_vs_proto_icmp.c: ICMP load balancing support for IP Virtual Server
- *
- * Authors: Julian Anastasov <ja@ssi.bg>, March 2002
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation;
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/icmp.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter_ipv4.h>
-
-#include <net/ip_vs.h>
-
-
-static int icmp_timeouts[1] = { 1*60*HZ };
-
-static char * icmp_state_name_table[1] = { "ICMP" };
-
-static struct ip_vs_conn *
-icmp_conn_in_get(const struct sk_buff *skb,
- struct ip_vs_protocol *pp,
- const struct iphdr *iph,
- unsigned int proto_off,
- int inverse)
-{
-#if 0
- struct ip_vs_conn *cp;
-
- if (likely(!inverse)) {
- cp = ip_vs_conn_in_get(iph->protocol,
- iph->saddr, 0,
- iph->daddr, 0);
- } else {
- cp = ip_vs_conn_in_get(iph->protocol,
- iph->daddr, 0,
- iph->saddr, 0);
- }
-
- return cp;
-
-#else
- return NULL;
-#endif
-}
-
-static struct ip_vs_conn *
-icmp_conn_out_get(const struct sk_buff *skb,
- struct ip_vs_protocol *pp,
- const struct iphdr *iph,
- unsigned int proto_off,
- int inverse)
-{
-#if 0
- struct ip_vs_conn *cp;
-
- if (likely(!inverse)) {
- cp = ip_vs_conn_out_get(iph->protocol,
- iph->saddr, 0,
- iph->daddr, 0);
- } else {
- cp = ip_vs_conn_out_get(IPPROTO_UDP,
- iph->daddr, 0,
- iph->saddr, 0);
- }
-
- return cp;
-#else
- return NULL;
-#endif
-}
-
-static int
-icmp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
- int *verdict, struct ip_vs_conn **cpp)
-{
- *verdict = NF_ACCEPT;
- return 0;
-}
-
-static int
-icmp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
-{
- if (!(skb->nh.iph->frag_off & __constant_htons(IP_OFFSET))) {
- if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
- if (ip_vs_checksum_complete(skb, skb->nh.iph->ihl * 4)) {
- IP_VS_DBG_RL_PKT(0, pp, skb, 0, "Failed checksum for");
- return 0;
- }
- }
- }
- return 1;
-}
-
-static void
-icmp_debug_packet(struct ip_vs_protocol *pp,
- const struct sk_buff *skb,
- int offset,
- const char *msg)
-{
- char buf[256];
- struct iphdr _iph, *ih;
-
- ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
- if (ih == NULL)
- sprintf(buf, "%s TRUNCATED", pp->name);
- else if (ih->frag_off & __constant_htons(IP_OFFSET))
- sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u frag",
- pp->name, NIPQUAD(ih->saddr),
- NIPQUAD(ih->daddr));
- else {
- struct icmphdr _icmph, *ic;
-
- ic = skb_header_pointer(skb, offset + ih->ihl*4,
- sizeof(_icmph), &_icmph);
- if (ic == NULL)
- sprintf(buf, "%s TRUNCATED to %u bytes\n",
- pp->name, skb->len - offset);
- else
- sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u T:%d C:%d",
- pp->name, NIPQUAD(ih->saddr),
- NIPQUAD(ih->daddr),
- ic->type, ic->code);
- }
- printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
-}
-
-static int
-icmp_state_transition(struct ip_vs_conn *cp, int direction,
- const struct sk_buff *skb,
- struct ip_vs_protocol *pp)
-{
- cp->timeout = pp->timeout_table[IP_VS_ICMP_S_NORMAL];
- return 1;
-}
-
-static int
-icmp_set_state_timeout(struct ip_vs_protocol *pp, char *sname, int to)
-{
- int num;
- char **names;
-
- num = IP_VS_ICMP_S_LAST;
- names = icmp_state_name_table;
- return ip_vs_set_state_timeout(pp->timeout_table, num, names, sname, to);
-}
-
-
-static void icmp_init(struct ip_vs_protocol *pp)
-{
- pp->timeout_table = icmp_timeouts;
-}
-
-static void icmp_exit(struct ip_vs_protocol *pp)
-{
-}
-
-struct ip_vs_protocol ip_vs_protocol_icmp = {
- .name = "ICMP",
- .protocol = IPPROTO_ICMP,
- .dont_defrag = 0,
- .init = icmp_init,
- .exit = icmp_exit,
- .conn_schedule = icmp_conn_schedule,
- .conn_in_get = icmp_conn_in_get,
- .conn_out_get = icmp_conn_out_get,
- .snat_handler = NULL,
- .dnat_handler = NULL,
- .csum_check = icmp_csum_check,
- .state_transition = icmp_state_transition,
- .register_app = NULL,
- .unregister_app = NULL,
- .app_conn_bind = NULL,
- .debug_packet = icmp_debug_packet,
- .timeout_change = NULL,
- .set_state_timeout = icmp_set_state_timeout,
-};
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c
index 9349686131f..c9cf8726051 100644
--- a/net/ipv4/multipath_drr.c
+++ b/net/ipv4/multipath_drr.c
@@ -31,6 +31,7 @@
#include <linux/igmp.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/module.h>
#include <linux/mroute.h>
#include <linux/init.h>
#include <net/ip.h>
@@ -57,7 +58,6 @@ struct multipath_device {
static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES];
static DEFINE_SPINLOCK(state_lock);
-static struct rtable *last_selection = NULL;
static int inline __multipath_findslot(void)
{
@@ -111,11 +111,6 @@ struct notifier_block drr_dev_notifier = {
.notifier_call = drr_dev_event,
};
-static void drr_remove(struct rtable *rt)
-{
- if (last_selection == rt)
- last_selection = NULL;
-}
static void drr_safe_inc(atomic_t *usecount)
{
@@ -144,14 +139,6 @@ static void drr_select_route(const struct flowi *flp,
int devidx = -1;
int cur_min_devidx = -1;
- /* if necessary and possible utilize the old alternative */
- if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 &&
- last_selection != NULL) {
- result = last_selection;
- *rp = result;
- return;
- }
-
/* 1. make sure all alt. nexthops have the same GC related data */
/* 2. determine the new candidate to be returned */
result = NULL;
@@ -229,12 +216,10 @@ static void drr_select_route(const struct flowi *flp,
}
*rp = result;
- last_selection = result;
}
static struct ip_mp_alg_ops drr_ops = {
.mp_alg_select_route = drr_select_route,
- .mp_alg_remove = drr_remove,
};
static int __init drr_init(void)
@@ -244,7 +229,7 @@ static int __init drr_init(void)
if (err)
return err;
- err = multipath_alg_register(&drr_ops, IP_MP_ALG_RR);
+ err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR);
if (err)
goto fail;
@@ -263,3 +248,4 @@ static void __exit drr_exit(void)
module_init(drr_init);
module_exit(drr_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c
index 805a16e47de..5249dbe7c55 100644
--- a/net/ipv4/multipath_random.c
+++ b/net/ipv4/multipath_random.c
@@ -31,6 +31,7 @@
#include <linux/igmp.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/module.h>
#include <linux/mroute.h>
#include <linux/init.h>
#include <net/ip.h>
@@ -126,3 +127,4 @@ static void __exit random_exit(void)
module_init(random_init);
module_exit(random_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c
index 554a8256816..b6cd2870478 100644
--- a/net/ipv4/multipath_rr.c
+++ b/net/ipv4/multipath_rr.c
@@ -31,6 +31,7 @@
#include <linux/igmp.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/module.h>
#include <linux/mroute.h>
#include <linux/init.h>
#include <net/ip.h>
@@ -47,29 +48,12 @@
#include <net/checksum.h>
#include <net/ip_mp_alg.h>
-#define MULTIPATH_MAX_CANDIDATES 40
-
-static struct rtable* last_used = NULL;
-
-static void rr_remove(struct rtable *rt)
-{
- if (last_used == rt)
- last_used = NULL;
-}
-
static void rr_select_route(const struct flowi *flp,
struct rtable *first, struct rtable **rp)
{
struct rtable *nh, *result, *min_use_cand = NULL;
int min_use = -1;
- /* if necessary and possible utilize the old alternative */
- if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 &&
- last_used != NULL) {
- result = last_used;
- goto out;
- }
-
/* 1. make sure all alt. nexthops have the same GC related data
* 2. determine the new candidate to be returned
*/
@@ -90,15 +74,12 @@ static void rr_select_route(const struct flowi *flp,
if (!result)
result = first;
-out:
- last_used = result;
result->u.dst.__use++;
*rp = result;
}
static struct ip_mp_alg_ops rr_ops = {
.mp_alg_select_route = rr_select_route,
- .mp_alg_remove = rr_remove,
};
static int __init rr_init(void)
@@ -113,3 +94,4 @@ static void __exit rr_exit(void)
module_init(rr_init);
module_exit(rr_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index c3d2ca1a678..bd7d75b6abe 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -31,6 +31,7 @@
#include <linux/igmp.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/module.h>
#include <linux/mroute.h>
#include <linux/init.h>
#include <net/ip.h>
@@ -342,3 +343,4 @@ static void __exit wrandom_exit(void)
module_init(wrandom_init);
module_exit(wrandom_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 46ca45f74d8..bc59f7b3980 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -256,6 +256,7 @@ static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
struct list_head *e = v;
+ ++*pos;
e = e->next;
if (e == &ip_conntrack_expect_list)
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index e5746b67441..eda1fba431a 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -3,6 +3,7 @@
* communicating with userspace via netlink.
*
* (C) 2000-2002 James Morris <jmorris@intercode.com.au>
+ * (C) 2003-2005 Netfilter Core Team <coreteam@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,6 +18,7 @@
* 2005-01-10: Added /proc counter for dropped packets; fixed so
* packets aren't delivered to user space if they're going
* to be dropped.
+ * 2005-05-26: local_bh_{disable,enable} around nf_reinject (Harald Welte)
*
*/
#include <linux/module.h>
@@ -71,7 +73,15 @@ static DECLARE_MUTEX(ipqnl_sem);
static void
ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)
{
+ /* TCP input path (and probably other bits) assume to be called
+ * from softirq context, not from syscall, like ipq_issue_verdict is
+ * called. TCP input path deadlocks with locks taken from timer
+ * softirq, e.g. We therefore emulate this by local_bh_disable() */
+
+ local_bh_disable();
nf_reinject(entry->skb, entry->info, verdict);
+ local_bh_enable();
+
kfree(entry);
}
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 25ab9fabdcb..2d44b07688a 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -223,7 +223,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned
curr_table->table[count].last_seen = 0;
curr_table->table[count].addr = 0;
curr_table->table[count].ttl = 0;
- memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+ memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long));
curr_table->table[count].oldest_pkt = 0;
curr_table->table[count].time_pos = 0;
curr_table->time_info[count].position = count;
@@ -502,7 +502,7 @@ match(const struct sk_buff *skb,
location = time_info[curr_table->time_pos].position;
hash_table[r_list[location].hash_entry] = -1;
hash_table[hash_result] = location;
- memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+ memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long));
r_list[location].time_pos = curr_table->time_pos;
r_list[location].addr = addr;
r_list[location].ttl = ttl;
@@ -631,7 +631,7 @@ match(const struct sk_buff *skb,
r_list[location].last_seen = 0;
r_list[location].addr = 0;
r_list[location].ttl = 0;
- memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+ memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long));
r_list[location].oldest_pkt = 0;
ans = !info->invert;
}
@@ -734,10 +734,10 @@ checkentry(const char *tablename,
memset(curr_table->table,0,sizeof(struct recent_ip_list)*ip_list_tot);
#ifdef DEBUG
if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for pkt_list.\n",
- sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot);
+ sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot);
#endif
- hold = vmalloc(sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot);
+ hold = vmalloc(sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot);
#ifdef DEBUG
if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: After pkt_list allocation.\n");
#endif
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 3aafb298c1c..23068bddbf0 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -23,6 +23,7 @@ extern int sysctl_ip_nonlocal_bind;
extern int sysctl_icmp_echo_ignore_all;
extern int sysctl_icmp_echo_ignore_broadcasts;
extern int sysctl_icmp_ignore_bogus_error_responses;
+extern int sysctl_icmp_errors_use_inbound_ifaddr;
/* From ip_fragment.c */
extern int sysctl_ipfrag_low_thresh;
@@ -396,6 +397,14 @@ ctl_table ipv4_table[] = {
.proc_handler = &proc_dointvec
},
{
+ .ctl_name = NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,
+ .procname = "icmp_errors_use_inbound_ifaddr",
+ .data = &sysctl_icmp_errors_use_inbound_ifaddr,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+ {
.ctl_name = NET_IPV4_ROUTE,
.procname = "route",
.maxlen = 0,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index a037bafcba3..0d9a4fd5f1a 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2338,7 +2338,7 @@ void __init tcp_init(void)
(tcp_bhash_size * sizeof(struct tcp_bind_hashbucket));
order++)
;
- if (order > 4) {
+ if (order >= 4) {
sysctl_local_port_range[0] = 32768;
sysctl_local_port_range[1] = 61000;
sysctl_tcp_max_tw_buckets = 180000;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 4a6952e3fee..7c24e64b443 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -738,7 +738,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
unsigned long amount;
amount = 0;
- spin_lock_irq(&sk->sk_receive_queue.lock);
+ spin_lock_bh(&sk->sk_receive_queue.lock);
skb = skb_peek(&sk->sk_receive_queue);
if (skb != NULL) {
/*
@@ -748,7 +748,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
*/
amount = skb->len - sizeof(struct udphdr);
}
- spin_unlock_irq(&sk->sk_receive_queue.lock);
+ spin_unlock_bh(&sk->sk_receive_queue.lock);
return put_user(amount, (int __user *)arg);
}
@@ -848,12 +848,12 @@ csum_copy_err:
/* Clear queue. */
if (flags&MSG_PEEK) {
int clear = 0;
- spin_lock_irq(&sk->sk_receive_queue.lock);
+ spin_lock_bh(&sk->sk_receive_queue.lock);
if (skb == skb_peek(&sk->sk_receive_queue)) {
__skb_unlink(skb, &sk->sk_receive_queue);
clear = 1;
}
- spin_unlock_irq(&sk->sk_receive_queue.lock);
+ spin_unlock_bh(&sk->sk_receive_queue.lock);
if (clear)
kfree_skb(skb);
}
@@ -1334,7 +1334,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
struct sk_buff_head *rcvq = &sk->sk_receive_queue;
struct sk_buff *skb;
- spin_lock_irq(&rcvq->lock);
+ spin_lock_bh(&rcvq->lock);
while ((skb = skb_peek(rcvq)) != NULL) {
if (udp_checksum_complete(skb)) {
UDP_INC_STATS_BH(UDP_MIB_INERRORS);
@@ -1345,7 +1345,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
break;
}
}
- spin_unlock_irq(&rcvq->lock);
+ spin_unlock_bh(&rcvq->lock);
/* nothing to see, move along */
if (skb == NULL)