aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-07 20:08:06 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-07 20:08:06 -0400
commitdf3872a9664667edae729361c9948b652de5c6f4 (patch)
treed191c1e6413f82b7a3f074a29b2d1fb92476d30f
parente5e3c84b70e58fc605635fd340fb8dba3cc59058 (diff)
parent4aa2e62c45b5ca08be2d0d3c0744d7585b56e860 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (24 commits) xfrm: Add security check before flushing SAD/SPD [NET_SCHED]: Fix filter double free [NET]: Avoid duplicate netlink notification when changing link state [UDP]: Revert 2-pass hashing changes. [AF_UNIX]: Fix stream recvmsg() race. [NETFILTER]: nf_conntrack_amanda: fix textsearch_prepare() error check [NETFILTER]: ip_tables: fix compat related crash [NETFILTER]: nf_conntrack: fix helper module unload races [RTNETLINK]: ifindex 0 does not exist [NETLINK]: Mark netlink policies const [TCP] tcp_probe: Attach printf attribute properly to printl(). [TCP]: Use LIMIT_NETDEBUG in tcp_retransmit_timer(). [NET]: Merge dst_discard_in and dst_discard_out. [RFKILL]: Make rfkill->name const [IPV4]: Restore old behaviour of default config values [IPV4]: Add default config support after inetdev_init [IPV4]: Convert IPv4 devconf to an array [IPV4]: Only panic if inetdev_init fails for loopback [TCP]: Honour sk_bound_dev_if in tcp_v4_send_ack [BNX2]: Update version and reldate. ...
-rw-r--r--drivers/infiniband/hw/amso1100/c2.c2
-rw-r--r--drivers/net/bnx2.c61
-rw-r--r--drivers/net/bnx2.h1
-rw-r--r--include/linux/inetdevice.h103
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h20
-rw-r--r--include/linux/rfkill.h2
-rw-r--r--include/net/fib_rules.h2
-rw-r--r--include/net/genetlink.h2
-rw-r--r--include/net/ip.h1
-rw-r--r--include/net/ip_fib.h2
-rw-r--r--include/net/netlink.h12
-rw-r--r--include/net/udp.h9
-rw-r--r--include/net/udplite.h2
-rw-r--r--include/net/xfrm.h6
-rw-r--r--net/core/dev.c8
-rw-r--r--net/core/dst.c17
-rw-r--r--net/core/neighbour.c4
-rw-r--r--net/core/rtnetlink.c8
-rw-r--r--net/decnet/dn_dev.c2
-rw-r--r--net/decnet/dn_rules.c2
-rw-r--r--net/ipv4/arp.c11
-rw-r--r--net/ipv4/devinet.c409
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/fib_rules.c2
-rw-r--r--net/ipv4/igmp.c18
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/ipmr.c23
-rw-r--r--net/ipv4/netfilter/ip_tables.c81
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c13
-rw-r--r--net/ipv4/proc.c2
-rw-r--r--net/ipv4/route.c14
-rw-r--r--net/ipv4/sysctl_net_ipv4.c6
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_probe.c6
-rw-r--r--net/ipv4/tcp_timer.c4
-rw-r--r--net/ipv4/udp.c241
-rw-r--r--net/ipv4/udp_impl.h6
-rw-r--r--net/ipv4/udplite.c7
-rw-r--r--net/ipv6/addrconf.c2
-rw-r--r--net/ipv6/fib6_rules.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c9
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/udp.c21
-rw-r--r--net/ipv6/udp_impl.h2
-rw-r--r--net/ipv6/udplite.c2
-rw-r--r--net/key/af_key.c10
-rw-r--r--net/netfilter/nf_conntrack_amanda.c12
-rw-r--r--net/netfilter/nf_conntrack_core.c26
-rw-r--r--net/netfilter/nf_conntrack_expect.c4
-rw-r--r--net/netfilter/nf_conntrack_helper.c2
-rw-r--r--net/netfilter/nf_conntrack_netlink.c34
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c2
-rw-r--r--net/netlabel/netlabel_cipso_v4.c2
-rw-r--r--net/netlabel/netlabel_mgmt.c2
-rw-r--r--net/netlabel/netlabel_unlabeled.c2
-rw-r--r--net/netlink/attr.c8
-rw-r--r--net/netlink/genetlink.c2
-rw-r--r--net/sched/sch_atm.c1
-rw-r--r--net/sched/sch_cbq.c8
-rw-r--r--net/unix/af_unix.c13
-rw-r--r--net/xfrm/xfrm_policy.c63
-rw-r--r--net/xfrm/xfrm_state.c46
-rw-r--r--net/xfrm/xfrm_user.c9
63 files changed, 748 insertions, 655 deletions
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
index 58bc272bd407..0aecea67f3e6 100644
--- a/drivers/infiniband/hw/amso1100/c2.c
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -672,7 +672,7 @@ static int c2_up(struct net_device *netdev)
672 * rdma interface. 672 * rdma interface.
673 */ 673 */
674 in_dev = in_dev_get(netdev); 674 in_dev = in_dev_get(netdev);
675 in_dev->cnf.arp_ignore = 1; 675 IN_DEV_CONF_SET(in_dev, ARP_IGNORE, 1);
676 in_dev_put(in_dev); 676 in_dev_put(in_dev);
677 677
678 return 0; 678 return 0;
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index da7c3b0c533c..ce3ed67a878e 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -54,8 +54,8 @@
54 54
55#define DRV_MODULE_NAME "bnx2" 55#define DRV_MODULE_NAME "bnx2"
56#define PFX DRV_MODULE_NAME ": " 56#define PFX DRV_MODULE_NAME ": "
57#define DRV_MODULE_VERSION "1.5.10" 57#define DRV_MODULE_VERSION "1.5.11"
58#define DRV_MODULE_RELDATE "May 1, 2007" 58#define DRV_MODULE_RELDATE "June 4, 2007"
59 59
60#define RUN_AT(x) (jiffies + (x)) 60#define RUN_AT(x) (jiffies + (x))
61 61
@@ -1778,6 +1778,15 @@ bnx2_init_5709_context(struct bnx2 *bp)
1778 val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12); 1778 val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12);
1779 val |= (BCM_PAGE_BITS - 8) << 16; 1779 val |= (BCM_PAGE_BITS - 8) << 16;
1780 REG_WR(bp, BNX2_CTX_COMMAND, val); 1780 REG_WR(bp, BNX2_CTX_COMMAND, val);
1781 for (i = 0; i < 10; i++) {
1782 val = REG_RD(bp, BNX2_CTX_COMMAND);
1783 if (!(val & BNX2_CTX_COMMAND_MEM_INIT))
1784 break;
1785 udelay(2);
1786 }
1787 if (val & BNX2_CTX_COMMAND_MEM_INIT)
1788 return -EBUSY;
1789
1781 for (i = 0; i < bp->ctx_pages; i++) { 1790 for (i = 0; i < bp->ctx_pages; i++) {
1782 int j; 1791 int j;
1783 1792
@@ -1811,6 +1820,7 @@ bnx2_init_context(struct bnx2 *bp)
1811 vcid = 96; 1820 vcid = 96;
1812 while (vcid) { 1821 while (vcid) {
1813 u32 vcid_addr, pcid_addr, offset; 1822 u32 vcid_addr, pcid_addr, offset;
1823 int i;
1814 1824
1815 vcid--; 1825 vcid--;
1816 1826
@@ -1831,16 +1841,20 @@ bnx2_init_context(struct bnx2 *bp)
1831 pcid_addr = vcid_addr; 1841 pcid_addr = vcid_addr;
1832 } 1842 }
1833 1843
1834 REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00); 1844 for (i = 0; i < (CTX_SIZE / PHY_CTX_SIZE); i++) {
1835 REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); 1845 vcid_addr += (i << PHY_CTX_SHIFT);
1846 pcid_addr += (i << PHY_CTX_SHIFT);
1836 1847
1837 /* Zero out the context. */ 1848 REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
1838 for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) { 1849 REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
1839 CTX_WR(bp, 0x00, offset, 0); 1850
1840 } 1851 /* Zero out the context. */
1852 for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
1853 CTX_WR(bp, 0x00, offset, 0);
1841 1854
1842 REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr); 1855 REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
1843 REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); 1856 REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
1857 }
1844 } 1858 }
1845} 1859}
1846 1860
@@ -3691,9 +3705,11 @@ bnx2_init_chip(struct bnx2 *bp)
3691 3705
3692 /* Initialize context mapping and zero out the quick contexts. The 3706 /* Initialize context mapping and zero out the quick contexts. The
3693 * context block must have already been enabled. */ 3707 * context block must have already been enabled. */
3694 if (CHIP_NUM(bp) == CHIP_NUM_5709) 3708 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
3695 bnx2_init_5709_context(bp); 3709 rc = bnx2_init_5709_context(bp);
3696 else 3710 if (rc)
3711 return rc;
3712 } else
3697 bnx2_init_context(bp); 3713 bnx2_init_context(bp);
3698 3714
3699 if ((rc = bnx2_init_cpus(bp)) != 0) 3715 if ((rc = bnx2_init_cpus(bp)) != 0)
@@ -3772,7 +3788,10 @@ bnx2_init_chip(struct bnx2 *bp)
3772 REG_WR(bp, BNX2_HC_CMD_TICKS, 3788 REG_WR(bp, BNX2_HC_CMD_TICKS,
3773 (bp->cmd_ticks_int << 16) | bp->cmd_ticks); 3789 (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
3774 3790
3775 REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00); 3791 if (CHIP_NUM(bp) == CHIP_NUM_5708)
3792 REG_WR(bp, BNX2_HC_STATS_TICKS, 0);
3793 else
3794 REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
3776 REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ 3795 REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */
3777 3796
3778 if (CHIP_ID(bp) == CHIP_ID_5706_A1) 3797 if (CHIP_ID(bp) == CHIP_ID_5706_A1)
@@ -3799,6 +3818,11 @@ bnx2_init_chip(struct bnx2 *bp)
3799 /* Initialize the receive filter. */ 3818 /* Initialize the receive filter. */
3800 bnx2_set_rx_mode(bp->dev); 3819 bnx2_set_rx_mode(bp->dev);
3801 3820
3821 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
3822 val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
3823 val |= BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
3824 REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
3825 }
3802 rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET, 3826 rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
3803 0); 3827 0);
3804 3828
@@ -4620,6 +4644,11 @@ bnx2_timer(unsigned long data)
4620 4644
4621 bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); 4645 bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
4622 4646
4647 /* workaround occasional corrupted counters */
4648 if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks)
4649 REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd |
4650 BNX2_HC_COMMAND_STATS_NOW);
4651
4623 if (bp->phy_flags & PHY_SERDES_FLAG) { 4652 if (bp->phy_flags & PHY_SERDES_FLAG) {
4624 if (CHIP_NUM(bp) == CHIP_NUM_5706) 4653 if (CHIP_NUM(bp) == CHIP_NUM_5706)
4625 bnx2_5706_serdes_timer(bp); 4654 bnx2_5706_serdes_timer(bp);
@@ -5417,6 +5446,10 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
5417 0xff; 5446 0xff;
5418 5447
5419 bp->stats_ticks = coal->stats_block_coalesce_usecs; 5448 bp->stats_ticks = coal->stats_block_coalesce_usecs;
5449 if (CHIP_NUM(bp) == CHIP_NUM_5708) {
5450 if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC)
5451 bp->stats_ticks = USEC_PER_SEC;
5452 }
5420 if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00; 5453 if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00;
5421 bp->stats_ticks &= 0xffff00; 5454 bp->stats_ticks &= 0xffff00;
5422 5455
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index bd6288d6350f..49a5de253b17 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1373,6 +1373,7 @@ struct l2_fhdr {
1373#define BNX2_MISC_NEW_CORE_CTL 0x000008c8 1373#define BNX2_MISC_NEW_CORE_CTL 0x000008c8
1374#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS (1L<<0) 1374#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS (1L<<0)
1375#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ (1L<<1) 1375#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ (1L<<1)
1376#define BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE (1L<<16)
1376#define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN (0x3fffL<<2) 1377#define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN (0x3fffL<<2)
1377#define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC (0xffffL<<16) 1378#define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC (0xffffL<<16)
1378 1379
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index c0f7aec331c2..ae04901aa09a 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -3,6 +3,7 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/bitmap.h>
6#include <linux/if.h> 7#include <linux/if.h>
7#include <linux/netdevice.h> 8#include <linux/netdevice.h>
8#include <linux/rcupdate.h> 9#include <linux/rcupdate.h>
@@ -10,28 +11,9 @@
10 11
11struct ipv4_devconf 12struct ipv4_devconf
12{ 13{
13 int accept_redirects;
14 int send_redirects;
15 int secure_redirects;
16 int shared_media;
17 int accept_source_route;
18 int rp_filter;
19 int proxy_arp;
20 int bootp_relay;
21 int log_martians;
22 int forwarding;
23 int mc_forwarding;
24 int tag;
25 int arp_filter;
26 int arp_announce;
27 int arp_ignore;
28 int arp_accept;
29 int medium_id;
30 int no_xfrm;
31 int no_policy;
32 int force_igmp_version;
33 int promote_secondaries;
34 void *sysctl; 14 void *sysctl;
15 int data[__NET_IPV4_CONF_MAX - 1];
16 DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
35}; 17};
36 18
37extern struct ipv4_devconf ipv4_devconf; 19extern struct ipv4_devconf ipv4_devconf;
@@ -60,30 +42,70 @@ struct in_device
60 struct rcu_head rcu_head; 42 struct rcu_head rcu_head;
61}; 43};
62 44
63#define IN_DEV_FORWARD(in_dev) ((in_dev)->cnf.forwarding) 45#define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1])
64#define IN_DEV_MFORWARD(in_dev) (ipv4_devconf.mc_forwarding && (in_dev)->cnf.mc_forwarding) 46#define IPV4_DEVCONF_ALL(attr) IPV4_DEVCONF(ipv4_devconf, attr)
65#define IN_DEV_RPFILTER(in_dev) (ipv4_devconf.rp_filter && (in_dev)->cnf.rp_filter) 47
66#define IN_DEV_SOURCE_ROUTE(in_dev) (ipv4_devconf.accept_source_route && (in_dev)->cnf.accept_source_route) 48static inline int ipv4_devconf_get(struct in_device *in_dev, int index)
67#define IN_DEV_BOOTP_RELAY(in_dev) (ipv4_devconf.bootp_relay && (in_dev)->cnf.bootp_relay) 49{
68 50 index--;
69#define IN_DEV_LOG_MARTIANS(in_dev) (ipv4_devconf.log_martians || (in_dev)->cnf.log_martians) 51 return in_dev->cnf.data[index];
70#define IN_DEV_PROXY_ARP(in_dev) (ipv4_devconf.proxy_arp || (in_dev)->cnf.proxy_arp) 52}
71#define IN_DEV_SHARED_MEDIA(in_dev) (ipv4_devconf.shared_media || (in_dev)->cnf.shared_media) 53
72#define IN_DEV_TX_REDIRECTS(in_dev) (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects) 54static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
73#define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) 55 int val)
74#define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag) 56{
75#define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id) 57 index--;
76#define IN_DEV_PROMOTE_SECONDARIES(in_dev) (ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries) 58 set_bit(index, in_dev->cnf.state);
59 in_dev->cnf.data[index] = val;
60}
61
62static inline void ipv4_devconf_setall(struct in_device *in_dev)
63{
64 bitmap_fill(in_dev->cnf.state, __NET_IPV4_CONF_MAX - 1);
65}
66
67#define IN_DEV_CONF_GET(in_dev, attr) \
68 ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr)
69#define IN_DEV_CONF_SET(in_dev, attr, val) \
70 ipv4_devconf_set((in_dev), NET_IPV4_CONF_ ## attr, (val))
71
72#define IN_DEV_ANDCONF(in_dev, attr) \
73 (IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr))
74#define IN_DEV_ORCONF(in_dev, attr) \
75 (IPV4_DEVCONF_ALL(attr) || IN_DEV_CONF_GET((in_dev), attr))
76#define IN_DEV_MAXCONF(in_dev, attr) \
77 (max(IPV4_DEVCONF_ALL(attr), IN_DEV_CONF_GET((in_dev), attr)))
78
79#define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
80#define IN_DEV_MFORWARD(in_dev) (IPV4_DEVCONF_ALL(MC_FORWARDING) && \
81 IPV4_DEVCONF((in_dev)->cnf, \
82 MC_FORWARDING))
83#define IN_DEV_RPFILTER(in_dev) IN_DEV_ANDCONF((in_dev), RP_FILTER)
84#define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \
85 ACCEPT_SOURCE_ROUTE)
86#define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)
87
88#define IN_DEV_LOG_MARTIANS(in_dev) IN_DEV_ORCONF((in_dev), LOG_MARTIANS)
89#define IN_DEV_PROXY_ARP(in_dev) IN_DEV_ORCONF((in_dev), PROXY_ARP)
90#define IN_DEV_SHARED_MEDIA(in_dev) IN_DEV_ORCONF((in_dev), SHARED_MEDIA)
91#define IN_DEV_TX_REDIRECTS(in_dev) IN_DEV_ORCONF((in_dev), SEND_REDIRECTS)
92#define IN_DEV_SEC_REDIRECTS(in_dev) IN_DEV_ORCONF((in_dev), \
93 SECURE_REDIRECTS)
94#define IN_DEV_IDTAG(in_dev) IN_DEV_CONF_GET(in_dev, TAG)
95#define IN_DEV_MEDIUM_ID(in_dev) IN_DEV_CONF_GET(in_dev, MEDIUM_ID)
96#define IN_DEV_PROMOTE_SECONDARIES(in_dev) \
97 IN_DEV_ORCONF((in_dev), \
98 PROMOTE_SECONDARIES)
77 99
78#define IN_DEV_RX_REDIRECTS(in_dev) \ 100#define IN_DEV_RX_REDIRECTS(in_dev) \
79 ((IN_DEV_FORWARD(in_dev) && \ 101 ((IN_DEV_FORWARD(in_dev) && \
80 (ipv4_devconf.accept_redirects && (in_dev)->cnf.accept_redirects)) \ 102 IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \
81 || (!IN_DEV_FORWARD(in_dev) && \ 103 || (!IN_DEV_FORWARD(in_dev) && \
82 (ipv4_devconf.accept_redirects || (in_dev)->cnf.accept_redirects))) 104 IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))
83 105
84#define IN_DEV_ARPFILTER(in_dev) (ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter) 106#define IN_DEV_ARPFILTER(in_dev) IN_DEV_ORCONF((in_dev), ARPFILTER)
85#define IN_DEV_ARP_ANNOUNCE(in_dev) (max(ipv4_devconf.arp_announce, (in_dev)->cnf.arp_announce)) 107#define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
86#define IN_DEV_ARP_IGNORE(in_dev) (max(ipv4_devconf.arp_ignore, (in_dev)->cnf.arp_ignore)) 108#define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
87 109
88struct in_ifaddr 110struct in_ifaddr
89{ 111{
@@ -108,7 +130,6 @@ extern struct net_device *ip_dev_find(__be32 addr);
108extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); 130extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
109extern int devinet_ioctl(unsigned int cmd, void __user *); 131extern int devinet_ioctl(unsigned int cmd, void __user *);
110extern void devinet_init(void); 132extern void devinet_init(void);
111extern struct in_device *inetdev_init(struct net_device *dev);
112extern struct in_device *inetdev_by_index(int); 133extern struct in_device *inetdev_by_index(int);
113extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); 134extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
114extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope); 135extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index 2f46dd728ee1..e992cd6b28f5 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -264,6 +264,26 @@ ipt_get_target(struct ipt_entry *e)
264 __ret; \ 264 __ret; \
265}) 265})
266 266
267/* fn returns 0 to continue iteration */
268#define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
269({ \
270 unsigned int __i, __n; \
271 int __ret = 0; \
272 struct ipt_entry *__entry; \
273 \
274 for (__i = 0, __n = 0; __i < (size); \
275 __i += __entry->next_offset, __n++) { \
276 __entry = (void *)(entries) + __i; \
277 if (__n < n) \
278 continue; \
279 \
280 __ret = fn(__entry , ## args); \
281 if (__ret != 0) \
282 break; \
283 } \
284 __ret; \
285})
286
267/* 287/*
268 * Main firewall chains definitions and global var's definitions. 288 * Main firewall chains definitions and global var's definitions.
269 */ 289 */
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 7c1ffbab7865..a8a6ea809da0 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -63,7 +63,7 @@ enum rfkill_state {
63 * This structure represents a RF switch located on a network device. 63 * This structure represents a RF switch located on a network device.
64 */ 64 */
65struct rfkill { 65struct rfkill {
66 char *name; 66 const char *name;
67 enum rfkill_type type; 67 enum rfkill_type type;
68 68
69 enum rfkill_state state; 69 enum rfkill_state state;
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index ed3a8872c6ca..83e41dd15ccd 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -64,7 +64,7 @@ struct fib_rules_ops
64 void (*flush_cache)(void); 64 void (*flush_cache)(void);
65 65
66 int nlgroup; 66 int nlgroup;
67 struct nla_policy *policy; 67 const struct nla_policy *policy;
68 struct list_head *rules_list; 68 struct list_head *rules_list;
69 struct module *owner; 69 struct module *owner;
70}; 70};
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index adff4c898d50..b6eaca122db8 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -60,7 +60,7 @@ struct genl_ops
60{ 60{
61 u8 cmd; 61 u8 cmd;
62 unsigned int flags; 62 unsigned int flags;
63 struct nla_policy *policy; 63 const struct nla_policy *policy;
64 int (*doit)(struct sk_buff *skb, 64 int (*doit)(struct sk_buff *skb,
65 struct genl_info *info); 65 struct genl_info *info);
66 int (*dumpit)(struct sk_buff *skb, 66 int (*dumpit)(struct sk_buff *skb,
diff --git a/include/net/ip.h b/include/net/ip.h
index bb207db03675..abf2820a1125 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -143,6 +143,7 @@ struct ip_reply_arg {
143 __wsum csum; 143 __wsum csum;
144 int csumoffset; /* u16 offset of csum in iov[0].iov_base */ 144 int csumoffset; /* u16 offset of csum in iov[0].iov_base */
145 /* -1 if not needed */ 145 /* -1 if not needed */
146 int bound_dev_if;
146}; 147};
147 148
148void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, 149void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 5a4a0366c24f..69252cbe05b0 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -213,7 +213,7 @@ extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
213#endif /* CONFIG_IP_MULTIPLE_TABLES */ 213#endif /* CONFIG_IP_MULTIPLE_TABLES */
214 214
215/* Exported by fib_frontend.c */ 215/* Exported by fib_frontend.c */
216extern struct nla_policy rtm_ipv4_policy[]; 216extern const struct nla_policy rtm_ipv4_policy[];
217extern void ip_fib_init(void); 217extern void ip_fib_init(void);
218extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, 218extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
219 struct net_device *dev, __be32 *spec_dst, u32 *itag); 219 struct net_device *dev, __be32 *spec_dst, u32 *itag);
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 0bf325c29aff..7b510a9edb91 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -222,10 +222,10 @@ extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb,
222 gfp_t flags); 222 gfp_t flags);
223 223
224extern int nla_validate(struct nlattr *head, int len, int maxtype, 224extern int nla_validate(struct nlattr *head, int len, int maxtype,
225 struct nla_policy *policy); 225 const struct nla_policy *policy);
226extern int nla_parse(struct nlattr *tb[], int maxtype, 226extern int nla_parse(struct nlattr *tb[], int maxtype,
227 struct nlattr *head, int len, 227 struct nlattr *head, int len,
228 struct nla_policy *policy); 228 const struct nla_policy *policy);
229extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype); 229extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
230extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, 230extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
231 size_t dstsize); 231 size_t dstsize);
@@ -360,7 +360,7 @@ static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
360 */ 360 */
361static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, 361static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
362 struct nlattr *tb[], int maxtype, 362 struct nlattr *tb[], int maxtype,
363 struct nla_policy *policy) 363 const struct nla_policy *policy)
364{ 364{
365 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 365 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
366 return -EINVAL; 366 return -EINVAL;
@@ -392,7 +392,7 @@ static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
392 * @policy: validation policy 392 * @policy: validation policy
393 */ 393 */
394static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, 394static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
395 struct nla_policy *policy) 395 const struct nla_policy *policy)
396{ 396{
397 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 397 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
398 return -EINVAL; 398 return -EINVAL;
@@ -729,7 +729,7 @@ static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype)
729 */ 729 */
730static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, 730static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
731 struct nlattr *nla, 731 struct nlattr *nla,
732 struct nla_policy *policy) 732 const struct nla_policy *policy)
733{ 733{
734 return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); 734 return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
735} 735}
@@ -990,7 +990,7 @@ static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
990 * Returns 0 on success or a negative error code. 990 * Returns 0 on success or a negative error code.
991 */ 991 */
992static inline int nla_validate_nested(struct nlattr *start, int maxtype, 992static inline int nla_validate_nested(struct nlattr *start, int maxtype,
993 struct nla_policy *policy) 993 const struct nla_policy *policy)
994{ 994{
995 return nla_validate(nla_data(start), nla_len(start), maxtype, policy); 995 return nla_validate(nla_data(start), nla_len(start), maxtype, policy);
996} 996}
diff --git a/include/net/udp.h b/include/net/udp.h
index 496f89d45c8b..98755ebaf163 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -119,16 +119,9 @@ static inline void udp_lib_close(struct sock *sk, long timeout)
119} 119}
120 120
121 121
122struct udp_get_port_ops {
123 int (*saddr_cmp)(const struct sock *sk1, const struct sock *sk2);
124 int (*saddr_any)(const struct sock *sk);
125 unsigned int (*hash_port_and_rcv_saddr)(__u16 port,
126 const struct sock *sk);
127};
128
129/* net/ipv4/udp.c */ 122/* net/ipv4/udp.c */
130extern int udp_get_port(struct sock *sk, unsigned short snum, 123extern int udp_get_port(struct sock *sk, unsigned short snum,
131 const struct udp_get_port_ops *ops); 124 int (*saddr_cmp)(const struct sock *, const struct sock *));
132extern void udp_err(struct sk_buff *, u32); 125extern void udp_err(struct sk_buff *, u32);
133 126
134extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, 127extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk,
diff --git a/include/net/udplite.h b/include/net/udplite.h
index 50b4b424d1ca..635b0eafca95 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -120,5 +120,5 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
120 120
121extern void udplite4_register(void); 121extern void udplite4_register(void);
122extern int udplite_get_port(struct sock *sk, unsigned short snum, 122extern int udplite_get_port(struct sock *sk, unsigned short snum,
123 const struct udp_get_port_ops *ops); 123 int (*scmp)(const struct sock *, const struct sock *));
124#endif /* _UDPLITE_H */ 124#endif /* _UDPLITE_H */
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 90185e8b335e..311f25af5e1a 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -964,7 +964,7 @@ struct xfrmk_spdinfo {
964 964
965extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); 965extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
966extern int xfrm_state_delete(struct xfrm_state *x); 966extern int xfrm_state_delete(struct xfrm_state *x);
967extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); 967extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
968extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); 968extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
969extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si); 969extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
970extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); 970extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
@@ -1020,13 +1020,13 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
1020 struct xfrm_sec_ctx *ctx, int delete, 1020 struct xfrm_sec_ctx *ctx, int delete,
1021 int *err); 1021 int *err);
1022struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err); 1022struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
1023void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); 1023int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
1024u32 xfrm_get_acqseq(void); 1024u32 xfrm_get_acqseq(void);
1025void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); 1025void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
1026struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, 1026struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
1027 xfrm_address_t *daddr, xfrm_address_t *saddr, 1027 xfrm_address_t *daddr, xfrm_address_t *saddr,
1028 int create, unsigned short family); 1028 int create, unsigned short family);
1029extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); 1029extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
1030extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); 1030extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
1031extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, 1031extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
1032 struct flowi *fl, int family, int strict); 1032 struct flowi *fl, int family, int strict);
diff --git a/net/core/dev.c b/net/core/dev.c
index 5a7f20f78574..26090621ea6b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2577,7 +2577,7 @@ unsigned dev_get_flags(const struct net_device *dev)
2577 2577
2578int dev_change_flags(struct net_device *dev, unsigned flags) 2578int dev_change_flags(struct net_device *dev, unsigned flags)
2579{ 2579{
2580 int ret; 2580 int ret, changes;
2581 int old_flags = dev->flags; 2581 int old_flags = dev->flags;
2582 2582
2583 /* 2583 /*
@@ -2632,8 +2632,10 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
2632 dev_set_allmulti(dev, inc); 2632 dev_set_allmulti(dev, inc);
2633 } 2633 }
2634 2634
2635 if (old_flags ^ dev->flags) 2635 /* Exclude state transition flags, already notified */
2636 rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags); 2636 changes = (old_flags ^ dev->flags) & ~(IFF_UP | IFF_RUNNING);
2637 if (changes)
2638 rtmsg_ifinfo(RTM_NEWLINK, dev, changes);
2637 2639
2638 return ret; 2640 return ret;
2639} 2641}
diff --git a/net/core/dst.c b/net/core/dst.c
index 764bccb3d992..c6a05879d58c 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -111,13 +111,7 @@ out:
111 spin_unlock(&dst_lock); 111 spin_unlock(&dst_lock);
112} 112}
113 113
114static int dst_discard_in(struct sk_buff *skb) 114static int dst_discard(struct sk_buff *skb)
115{
116 kfree_skb(skb);
117 return 0;
118}
119
120static int dst_discard_out(struct sk_buff *skb)
121{ 115{
122 kfree_skb(skb); 116 kfree_skb(skb);
123 return 0; 117 return 0;
@@ -138,8 +132,7 @@ void * dst_alloc(struct dst_ops * ops)
138 dst->ops = ops; 132 dst->ops = ops;
139 dst->lastuse = jiffies; 133 dst->lastuse = jiffies;
140 dst->path = dst; 134 dst->path = dst;
141 dst->input = dst_discard_in; 135 dst->input = dst->output = dst_discard;
142 dst->output = dst_discard_out;
143#if RT_CACHE_DEBUG >= 2 136#if RT_CACHE_DEBUG >= 2
144 atomic_inc(&dst_total); 137 atomic_inc(&dst_total);
145#endif 138#endif
@@ -153,8 +146,7 @@ static void ___dst_free(struct dst_entry * dst)
153 protocol module is unloaded. 146 protocol module is unloaded.
154 */ 147 */
155 if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { 148 if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
156 dst->input = dst_discard_in; 149 dst->input = dst->output = dst_discard;
157 dst->output = dst_discard_out;
158 } 150 }
159 dst->obsolete = 2; 151 dst->obsolete = 2;
160} 152}
@@ -242,8 +234,7 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
242 return; 234 return;
243 235
244 if (!unregister) { 236 if (!unregister) {
245 dst->input = dst_discard_in; 237 dst->input = dst->output = dst_discard;
246 dst->output = dst_discard_out;
247 } else { 238 } else {
248 dst->dev = &loopback_dev; 239 dst->dev = &loopback_dev;
249 dev_hold(&loopback_dev); 240 dev_hold(&loopback_dev);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 6f3bb73053c2..9df26a07f067 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1761,7 +1761,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
1761 return NULL; 1761 return NULL;
1762} 1762}
1763 1763
1764static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { 1764static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
1765 [NDTA_NAME] = { .type = NLA_STRING }, 1765 [NDTA_NAME] = { .type = NLA_STRING },
1766 [NDTA_THRESH1] = { .type = NLA_U32 }, 1766 [NDTA_THRESH1] = { .type = NLA_U32 },
1767 [NDTA_THRESH2] = { .type = NLA_U32 }, 1767 [NDTA_THRESH2] = { .type = NLA_U32 },
@@ -1770,7 +1770,7 @@ static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = {
1770 [NDTA_PARMS] = { .type = NLA_NESTED }, 1770 [NDTA_PARMS] = { .type = NLA_NESTED },
1771}; 1771};
1772 1772
1773static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = { 1773static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
1774 [NDTPA_IFINDEX] = { .type = NLA_U32 }, 1774 [NDTPA_IFINDEX] = { .type = NLA_U32 },
1775 [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, 1775 [NDTPA_QUEUE_LEN] = { .type = NLA_U32 },
1776 [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, 1776 [NDTPA_PROXY_QLEN] = { .type = NLA_U32 },
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 27da9cdec6a8..02e8bf084277 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -551,7 +551,7 @@ cont:
551 return skb->len; 551 return skb->len;
552} 552}
553 553
554static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = { 554static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
555 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, 555 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
556 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, 556 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
557 [IFLA_MTU] = { .type = NLA_U32 }, 557 [IFLA_MTU] = { .type = NLA_U32 },
@@ -580,7 +580,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
580 580
581 err = -EINVAL; 581 err = -EINVAL;
582 ifm = nlmsg_data(nlh); 582 ifm = nlmsg_data(nlh);
583 if (ifm->ifi_index >= 0) 583 if (ifm->ifi_index > 0)
584 dev = dev_get_by_index(ifm->ifi_index); 584 dev = dev_get_by_index(ifm->ifi_index);
585 else if (tb[IFLA_IFNAME]) 585 else if (tb[IFLA_IFNAME])
586 dev = dev_get_by_name(ifname); 586 dev = dev_get_by_name(ifname);
@@ -672,7 +672,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
672 * name provided implies that a name change has been 672 * name provided implies that a name change has been
673 * requested. 673 * requested.
674 */ 674 */
675 if (ifm->ifi_index >= 0 && ifname[0]) { 675 if (ifm->ifi_index > 0 && ifname[0]) {
676 err = dev_change_name(dev, ifname); 676 err = dev_change_name(dev, ifname);
677 if (err < 0) 677 if (err < 0)
678 goto errout_dev; 678 goto errout_dev;
@@ -740,7 +740,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
740 return err; 740 return err;
741 741
742 ifm = nlmsg_data(nlh); 742 ifm = nlmsg_data(nlh);
743 if (ifm->ifi_index >= 0) { 743 if (ifm->ifi_index > 0) {
744 dev = dev_get_by_index(ifm->ifi_index); 744 dev = dev_get_by_index(ifm->ifi_index);
745 if (dev == NULL) 745 if (dev == NULL)
746 return -ENODEV; 746 return -ENODEV;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 764a56a13e38..ab41c1879fd4 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -638,7 +638,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex)
638 return dn_dev; 638 return dn_dev;
639} 639}
640 640
641static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { 641static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = {
642 [IFA_ADDRESS] = { .type = NLA_U16 }, 642 [IFA_ADDRESS] = { .type = NLA_U16 },
643 [IFA_LOCAL] = { .type = NLA_U16 }, 643 [IFA_LOCAL] = { .type = NLA_U16 },
644 [IFA_LABEL] = { .type = NLA_STRING, 644 [IFA_LABEL] = { .type = NLA_STRING,
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 17a1932216d6..84ff3dd37070 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -108,7 +108,7 @@ errout:
108 return err; 108 return err;
109} 109}
110 110
111static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { 111static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = {
112 FRA_GENERIC_POLICY, 112 FRA_GENERIC_POLICY,
113}; 113};
114 114
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 7110779a0244..e00767e8ebd9 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -877,7 +877,7 @@ static int arp_process(struct sk_buff *skb)
877 877
878 n = __neigh_lookup(&arp_tbl, &sip, dev, 0); 878 n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
879 879
880 if (ipv4_devconf.arp_accept) { 880 if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) {
881 /* Unsolicited ARP is not accepted by default. 881 /* Unsolicited ARP is not accepted by default.
882 It is possible, that this option should be enabled for some 882 It is possible, that this option should be enabled for some
883 devices (strip is candidate) 883 devices (strip is candidate)
@@ -987,11 +987,11 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev)
987 return 0; 987 return 0;
988 } 988 }
989 if (dev == NULL) { 989 if (dev == NULL) {
990 ipv4_devconf.proxy_arp = 1; 990 IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
991 return 0; 991 return 0;
992 } 992 }
993 if (__in_dev_get_rtnl(dev)) { 993 if (__in_dev_get_rtnl(dev)) {
994 __in_dev_get_rtnl(dev)->cnf.proxy_arp = 1; 994 IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
995 return 0; 995 return 0;
996 } 996 }
997 return -ENXIO; 997 return -ENXIO;
@@ -1093,11 +1093,12 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev)
1093 return pneigh_delete(&arp_tbl, &ip, dev); 1093 return pneigh_delete(&arp_tbl, &ip, dev);
1094 if (mask == 0) { 1094 if (mask == 0) {
1095 if (dev == NULL) { 1095 if (dev == NULL) {
1096 ipv4_devconf.proxy_arp = 0; 1096 IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
1097 return 0; 1097 return 0;
1098 } 1098 }
1099 if (__in_dev_get_rtnl(dev)) { 1099 if (__in_dev_get_rtnl(dev)) {
1100 __in_dev_get_rtnl(dev)->cnf.proxy_arp = 0; 1100 IN_DEV_CONF_SET(__in_dev_get_rtnl(dev),
1101 PROXY_ARP, 0);
1101 return 0; 1102 return 0;
1102 } 1103 }
1103 return -ENXIO; 1104 return -ENXIO;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 7f95e6e9beeb..fa97b96a3d89 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -64,21 +64,27 @@
64#include <net/rtnetlink.h> 64#include <net/rtnetlink.h>
65 65
66struct ipv4_devconf ipv4_devconf = { 66struct ipv4_devconf ipv4_devconf = {
67 .accept_redirects = 1, 67 .data = {
68 .send_redirects = 1, 68 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
69 .secure_redirects = 1, 69 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
70 .shared_media = 1, 70 [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
71 [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
72 },
71}; 73};
72 74
73static struct ipv4_devconf ipv4_devconf_dflt = { 75static struct ipv4_devconf ipv4_devconf_dflt = {
74 .accept_redirects = 1, 76 .data = {
75 .send_redirects = 1, 77 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
76 .secure_redirects = 1, 78 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
77 .shared_media = 1, 79 [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
78 .accept_source_route = 1, 80 [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
81 [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
82 },
79}; 83};
80 84
81static struct nla_policy ifa_ipv4_policy[IFA_MAX+1] __read_mostly = { 85#define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr)
86
87static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
82 [IFA_LOCAL] = { .type = NLA_U32 }, 88 [IFA_LOCAL] = { .type = NLA_U32 },
83 [IFA_ADDRESS] = { .type = NLA_U32 }, 89 [IFA_ADDRESS] = { .type = NLA_U32 },
84 [IFA_BROADCAST] = { .type = NLA_U32 }, 90 [IFA_BROADCAST] = { .type = NLA_U32 },
@@ -141,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev)
141 } 147 }
142} 148}
143 149
144struct in_device *inetdev_init(struct net_device *dev) 150static struct in_device *inetdev_init(struct net_device *dev)
145{ 151{
146 struct in_device *in_dev; 152 struct in_device *in_dev;
147 153
@@ -399,12 +405,10 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
399 ASSERT_RTNL(); 405 ASSERT_RTNL();
400 406
401 if (!in_dev) { 407 if (!in_dev) {
402 in_dev = inetdev_init(dev); 408 inet_free_ifa(ifa);
403 if (!in_dev) { 409 return -ENOBUFS;
404 inet_free_ifa(ifa);
405 return -ENOBUFS;
406 }
407 } 410 }
411 ipv4_devconf_setall(in_dev);
408 if (ifa->ifa_dev != in_dev) { 412 if (ifa->ifa_dev != in_dev) {
409 BUG_TRAP(!ifa->ifa_dev); 413 BUG_TRAP(!ifa->ifa_dev);
410 in_dev_hold(in_dev); 414 in_dev_hold(in_dev);
@@ -514,13 +518,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
514 518
515 in_dev = __in_dev_get_rtnl(dev); 519 in_dev = __in_dev_get_rtnl(dev);
516 if (in_dev == NULL) { 520 if (in_dev == NULL) {
517 in_dev = inetdev_init(dev); 521 err = -ENOBUFS;
518 if (in_dev == NULL) { 522 goto errout;
519 err = -ENOBUFS;
520 goto errout;
521 }
522 } 523 }
523 524
525 ipv4_devconf_setall(in_dev);
526
524 ifa = inet_alloc_ifa(); 527 ifa = inet_alloc_ifa();
525 if (ifa == NULL) { 528 if (ifa == NULL) {
526 /* 529 /*
@@ -1057,11 +1060,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1057 if (!in_dev) { 1060 if (!in_dev) {
1058 if (event == NETDEV_REGISTER) { 1061 if (event == NETDEV_REGISTER) {
1059 in_dev = inetdev_init(dev); 1062 in_dev = inetdev_init(dev);
1060 if (!in_dev)
1061 panic("devinet: Failed to create loopback\n");
1062 if (dev == &loopback_dev) { 1063 if (dev == &loopback_dev) {
1063 in_dev->cnf.no_xfrm = 1; 1064 if (!in_dev)
1064 in_dev->cnf.no_policy = 1; 1065 panic("devinet: "
1066 "Failed to create loopback\n");
1067 IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
1068 IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
1065 } 1069 }
1066 } 1070 }
1067 goto out; 1071 goto out;
@@ -1237,13 +1241,98 @@ errout:
1237 1241
1238#ifdef CONFIG_SYSCTL 1242#ifdef CONFIG_SYSCTL
1239 1243
1244static void devinet_copy_dflt_conf(int i)
1245{
1246 struct net_device *dev;
1247
1248 read_lock(&dev_base_lock);
1249 for_each_netdev(dev) {
1250 struct in_device *in_dev;
1251 rcu_read_lock();
1252 in_dev = __in_dev_get_rcu(dev);
1253 if (in_dev && !test_bit(i, in_dev->cnf.state))
1254 in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i];
1255 rcu_read_unlock();
1256 }
1257 read_unlock(&dev_base_lock);
1258}
1259
1260static int devinet_conf_proc(ctl_table *ctl, int write,
1261 struct file* filp, void __user *buffer,
1262 size_t *lenp, loff_t *ppos)
1263{
1264 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1265
1266 if (write) {
1267 struct ipv4_devconf *cnf = ctl->extra1;
1268 int i = (int *)ctl->data - cnf->data;
1269
1270 set_bit(i, cnf->state);
1271
1272 if (cnf == &ipv4_devconf_dflt)
1273 devinet_copy_dflt_conf(i);
1274 }
1275
1276 return ret;
1277}
1278
1279static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
1280 void __user *oldval, size_t __user *oldlenp,
1281 void __user *newval, size_t newlen)
1282{
1283 struct ipv4_devconf *cnf;
1284 int *valp = table->data;
1285 int new;
1286 int i;
1287
1288 if (!newval || !newlen)
1289 return 0;
1290
1291 if (newlen != sizeof(int))
1292 return -EINVAL;
1293
1294 if (get_user(new, (int __user *)newval))
1295 return -EFAULT;
1296
1297 if (new == *valp)
1298 return 0;
1299
1300 if (oldval && oldlenp) {
1301 size_t len;
1302
1303 if (get_user(len, oldlenp))
1304 return -EFAULT;
1305
1306 if (len) {
1307 if (len > table->maxlen)
1308 len = table->maxlen;
1309 if (copy_to_user(oldval, valp, len))
1310 return -EFAULT;
1311 if (put_user(len, oldlenp))
1312 return -EFAULT;
1313 }
1314 }
1315
1316 *valp = new;
1317
1318 cnf = table->extra1;
1319 i = (int *)table->data - cnf->data;
1320
1321 set_bit(i, cnf->state);
1322
1323 if (cnf == &ipv4_devconf_dflt)
1324 devinet_copy_dflt_conf(i);
1325
1326 return 1;
1327}
1328
1240void inet_forward_change(void) 1329void inet_forward_change(void)
1241{ 1330{
1242 struct net_device *dev; 1331 struct net_device *dev;
1243 int on = ipv4_devconf.forwarding; 1332 int on = IPV4_DEVCONF_ALL(FORWARDING);
1244 1333
1245 ipv4_devconf.accept_redirects = !on; 1334 IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on;
1246 ipv4_devconf_dflt.forwarding = on; 1335 IPV4_DEVCONF_DFLT(FORWARDING) = on;
1247 1336
1248 read_lock(&dev_base_lock); 1337 read_lock(&dev_base_lock);
1249 for_each_netdev(dev) { 1338 for_each_netdev(dev) {
@@ -1251,7 +1340,7 @@ void inet_forward_change(void)
1251 rcu_read_lock(); 1340 rcu_read_lock();
1252 in_dev = __in_dev_get_rcu(dev); 1341 in_dev = __in_dev_get_rcu(dev);
1253 if (in_dev) 1342 if (in_dev)
1254 in_dev->cnf.forwarding = on; 1343 IN_DEV_CONF_SET(in_dev, FORWARDING, on);
1255 rcu_read_unlock(); 1344 rcu_read_unlock();
1256 } 1345 }
1257 read_unlock(&dev_base_lock); 1346 read_unlock(&dev_base_lock);
@@ -1268,9 +1357,9 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
1268 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); 1357 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1269 1358
1270 if (write && *valp != val) { 1359 if (write && *valp != val) {
1271 if (valp == &ipv4_devconf.forwarding) 1360 if (valp == &IPV4_DEVCONF_ALL(FORWARDING))
1272 inet_forward_change(); 1361 inet_forward_change();
1273 else if (valp != &ipv4_devconf_dflt.forwarding) 1362 else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING))
1274 rt_cache_flush(0); 1363 rt_cache_flush(0);
1275 } 1364 }
1276 1365
@@ -1295,42 +1384,43 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
1295 void __user *oldval, size_t __user *oldlenp, 1384 void __user *oldval, size_t __user *oldlenp,
1296 void __user *newval, size_t newlen) 1385 void __user *newval, size_t newlen)
1297{ 1386{
1298 int *valp = table->data; 1387 int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp,
1299 int new; 1388 newval, newlen);
1300 1389
1301 if (!newval || !newlen) 1390 if (ret == 1)
1302 return 0; 1391 rt_cache_flush(0);
1303 1392
1304 if (newlen != sizeof(int)) 1393 return ret;
1305 return -EINVAL; 1394}
1306 1395
1307 if (get_user(new, (int __user *)newval))
1308 return -EFAULT;
1309 1396
1310 if (new == *valp) 1397#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc, sysctl) \
1311 return 0; 1398 { \
1399 .ctl_name = NET_IPV4_CONF_ ## attr, \
1400 .procname = name, \
1401 .data = ipv4_devconf.data + \
1402 NET_IPV4_CONF_ ## attr - 1, \
1403 .maxlen = sizeof(int), \
1404 .mode = mval, \
1405 .proc_handler = proc, \
1406 .strategy = sysctl, \
1407 .extra1 = &ipv4_devconf, \
1408 }
1312 1409
1313 if (oldval && oldlenp) { 1410#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
1314 size_t len; 1411 DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \
1412 devinet_conf_sysctl)
1315 1413
1316 if (get_user(len, oldlenp)) 1414#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
1317 return -EFAULT; 1415 DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \
1416 devinet_conf_sysctl)
1318 1417
1319 if (len) { 1418#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \
1320 if (len > table->maxlen) 1419 DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc, sysctl)
1321 len = table->maxlen;
1322 if (copy_to_user(oldval, valp, len))
1323 return -EFAULT;
1324 if (put_user(len, oldlenp))
1325 return -EFAULT;
1326 }
1327 }
1328
1329 *valp = new;
1330 rt_cache_flush(0);
1331 return 1;
1332}
1333 1420
1421#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
1422 DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \
1423 ipv4_doint_and_flush_strategy)
1334 1424
1335static struct devinet_sysctl_table { 1425static struct devinet_sysctl_table {
1336 struct ctl_table_header *sysctl_header; 1426 struct ctl_table_header *sysctl_header;
@@ -1341,178 +1431,34 @@ static struct devinet_sysctl_table {
1341 ctl_table devinet_root_dir[2]; 1431 ctl_table devinet_root_dir[2];
1342} devinet_sysctl = { 1432} devinet_sysctl = {
1343 .devinet_vars = { 1433 .devinet_vars = {
1344 { 1434 DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
1345 .ctl_name = NET_IPV4_CONF_FORWARDING, 1435 devinet_sysctl_forward,
1346 .procname = "forwarding", 1436 devinet_conf_sysctl),
1347 .data = &ipv4_devconf.forwarding, 1437 DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
1348 .maxlen = sizeof(int), 1438
1349 .mode = 0644, 1439 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
1350 .proc_handler = &devinet_sysctl_forward, 1440 DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
1351 }, 1441 DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
1352 { 1442 DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
1353 .ctl_name = NET_IPV4_CONF_MC_FORWARDING, 1443 DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
1354 .procname = "mc_forwarding", 1444 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
1355 .data = &ipv4_devconf.mc_forwarding, 1445 "accept_source_route"),
1356 .maxlen = sizeof(int), 1446 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
1357 .mode = 0444, 1447 DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
1358 .proc_handler = &proc_dointvec, 1448 DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
1359 }, 1449 DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
1360 { 1450 DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
1361 .ctl_name = NET_IPV4_CONF_ACCEPT_REDIRECTS, 1451 DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
1362 .procname = "accept_redirects", 1452 DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
1363 .data = &ipv4_devconf.accept_redirects, 1453 DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
1364 .maxlen = sizeof(int), 1454 DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
1365 .mode = 0644, 1455
1366 .proc_handler = &proc_dointvec, 1456 DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
1367 }, 1457 DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
1368 { 1458 DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
1369 .ctl_name = NET_IPV4_CONF_SECURE_REDIRECTS, 1459 "force_igmp_version"),
1370 .procname = "secure_redirects", 1460 DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
1371 .data = &ipv4_devconf.secure_redirects, 1461 "promote_secondaries"),
1372 .maxlen = sizeof(int),
1373 .mode = 0644,
1374 .proc_handler = &proc_dointvec,
1375 },
1376 {
1377 .ctl_name = NET_IPV4_CONF_SHARED_MEDIA,
1378 .procname = "shared_media",
1379 .data = &ipv4_devconf.shared_media,
1380 .maxlen = sizeof(int),
1381 .mode = 0644,
1382 .proc_handler = &proc_dointvec,
1383 },
1384 {
1385 .ctl_name = NET_IPV4_CONF_RP_FILTER,
1386 .procname = "rp_filter",
1387 .data = &ipv4_devconf.rp_filter,
1388 .maxlen = sizeof(int),
1389 .mode = 0644,
1390 .proc_handler = &proc_dointvec,
1391 },
1392 {
1393 .ctl_name = NET_IPV4_CONF_SEND_REDIRECTS,
1394 .procname = "send_redirects",
1395 .data = &ipv4_devconf.send_redirects,
1396 .maxlen = sizeof(int),
1397 .mode = 0644,
1398 .proc_handler = &proc_dointvec,
1399 },
1400 {
1401 .ctl_name = NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,
1402 .procname = "accept_source_route",
1403 .data = &ipv4_devconf.accept_source_route,
1404 .maxlen = sizeof(int),
1405 .mode = 0644,
1406 .proc_handler = &proc_dointvec,
1407 },
1408 {
1409 .ctl_name = NET_IPV4_CONF_PROXY_ARP,
1410 .procname = "proxy_arp",
1411 .data = &ipv4_devconf.proxy_arp,
1412 .maxlen = sizeof(int),
1413 .mode = 0644,
1414 .proc_handler = &proc_dointvec,
1415 },
1416 {
1417 .ctl_name = NET_IPV4_CONF_MEDIUM_ID,
1418 .procname = "medium_id",
1419 .data = &ipv4_devconf.medium_id,
1420 .maxlen = sizeof(int),
1421 .mode = 0644,
1422 .proc_handler = &proc_dointvec,
1423 },
1424 {
1425 .ctl_name = NET_IPV4_CONF_BOOTP_RELAY,
1426 .procname = "bootp_relay",
1427 .data = &ipv4_devconf.bootp_relay,
1428 .maxlen = sizeof(int),
1429 .mode = 0644,
1430 .proc_handler = &proc_dointvec,
1431 },
1432 {
1433 .ctl_name = NET_IPV4_CONF_LOG_MARTIANS,
1434 .procname = "log_martians",
1435 .data = &ipv4_devconf.log_martians,
1436 .maxlen = sizeof(int),
1437 .mode = 0644,
1438 .proc_handler = &proc_dointvec,
1439 },
1440 {
1441 .ctl_name = NET_IPV4_CONF_TAG,
1442 .procname = "tag",
1443 .data = &ipv4_devconf.tag,
1444 .maxlen = sizeof(int),
1445 .mode = 0644,
1446 .proc_handler = &proc_dointvec,
1447 },
1448 {
1449 .ctl_name = NET_IPV4_CONF_ARPFILTER,
1450 .procname = "arp_filter",
1451 .data = &ipv4_devconf.arp_filter,
1452 .maxlen = sizeof(int),
1453 .mode = 0644,
1454 .proc_handler = &proc_dointvec,
1455 },
1456 {
1457 .ctl_name = NET_IPV4_CONF_ARP_ANNOUNCE,
1458 .procname = "arp_announce",
1459 .data = &ipv4_devconf.arp_announce,
1460 .maxlen = sizeof(int),
1461 .mode = 0644,
1462 .proc_handler = &proc_dointvec,
1463 },
1464 {
1465 .ctl_name = NET_IPV4_CONF_ARP_IGNORE,
1466 .procname = "arp_ignore",
1467 .data = &ipv4_devconf.arp_ignore,
1468 .maxlen = sizeof(int),
1469 .mode = 0644,
1470 .proc_handler = &proc_dointvec,
1471 },
1472 {
1473 .ctl_name = NET_IPV4_CONF_ARP_ACCEPT,
1474 .procname = "arp_accept",
1475 .data = &ipv4_devconf.arp_accept,
1476 .maxlen = sizeof(int),
1477 .mode = 0644,
1478 .proc_handler = &proc_dointvec,
1479 },
1480 {
1481 .ctl_name = NET_IPV4_CONF_NOXFRM,
1482 .procname = "disable_xfrm",
1483 .data = &ipv4_devconf.no_xfrm,
1484 .maxlen = sizeof(int),
1485 .mode = 0644,
1486 .proc_handler = &ipv4_doint_and_flush,
1487 .strategy = &ipv4_doint_and_flush_strategy,
1488 },
1489 {
1490 .ctl_name = NET_IPV4_CONF_NOPOLICY,
1491 .procname = "disable_policy",
1492 .data = &ipv4_devconf.no_policy,
1493 .maxlen = sizeof(int),
1494 .mode = 0644,
1495 .proc_handler = &ipv4_doint_and_flush,
1496 .strategy = &ipv4_doint_and_flush_strategy,
1497 },
1498 {
1499 .ctl_name = NET_IPV4_CONF_FORCE_IGMP_VERSION,
1500 .procname = "force_igmp_version",
1501 .data = &ipv4_devconf.force_igmp_version,
1502 .maxlen = sizeof(int),
1503 .mode = 0644,
1504 .proc_handler = &ipv4_doint_and_flush,
1505 .strategy = &ipv4_doint_and_flush_strategy,
1506 },
1507 {
1508 .ctl_name = NET_IPV4_CONF_PROMOTE_SECONDARIES,
1509 .procname = "promote_secondaries",
1510 .data = &ipv4_devconf.promote_secondaries,
1511 .maxlen = sizeof(int),
1512 .mode = 0644,
1513 .proc_handler = &ipv4_doint_and_flush,
1514 .strategy = &ipv4_doint_and_flush_strategy,
1515 },
1516 }, 1462 },
1517 .devinet_dev = { 1463 .devinet_dev = {
1518 { 1464 {
@@ -1561,6 +1507,7 @@ static void devinet_sysctl_register(struct in_device *in_dev,
1561 return; 1507 return;
1562 for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) { 1508 for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
1563 t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf; 1509 t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
1510 t->devinet_vars[i].extra1 = p;
1564 } 1511 }
1565 1512
1566 if (dev) { 1513 if (dev) {
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 9ad1f6252a97..311d633f7f39 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -441,7 +441,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg)
441 return -EINVAL; 441 return -EINVAL;
442} 442}
443 443
444struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = { 444const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
445 [RTA_DST] = { .type = NLA_U32 }, 445 [RTA_DST] = { .type = NLA_U32 },
446 [RTA_SRC] = { .type = NLA_U32 }, 446 [RTA_SRC] = { .type = NLA_U32 },
447 [RTA_IIF] = { .type = NLA_U32 }, 447 [RTA_IIF] = { .type = NLA_U32 },
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 33083ad52e9f..2a947840210e 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -169,7 +169,7 @@ static struct fib_table *fib_empty_table(void)
169 return NULL; 169 return NULL;
170} 170}
171 171
172static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { 172static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = {
173 FRA_GENERIC_POLICY, 173 FRA_GENERIC_POLICY,
174 [FRA_FLOW] = { .type = NLA_U32 }, 174 [FRA_FLOW] = { .type = NLA_U32 },
175}; 175};
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index f4dd47453108..a646409c2d06 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -128,14 +128,16 @@
128 * contradict to specs provided this delay is small enough. 128 * contradict to specs provided this delay is small enough.
129 */ 129 */
130 130
131#define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \ 131#define IGMP_V1_SEEN(in_dev) \
132 (in_dev)->cnf.force_igmp_version == 1 || \ 132 (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \
133 ((in_dev)->mr_v1_seen && \ 133 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
134 time_before(jiffies, (in_dev)->mr_v1_seen))) 134 ((in_dev)->mr_v1_seen && \
135#define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \ 135 time_before(jiffies, (in_dev)->mr_v1_seen)))
136 (in_dev)->cnf.force_igmp_version == 2 || \ 136#define IGMP_V2_SEEN(in_dev) \
137 ((in_dev)->mr_v2_seen && \ 137 (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \
138 time_before(jiffies, (in_dev)->mr_v2_seen))) 138 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
139 ((in_dev)->mr_v2_seen && \
140 time_before(jiffies, (in_dev)->mr_v2_seen)))
139 141
140static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); 142static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
141static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); 143static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index d6427d918512..34ea4547ebbe 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1352,7 +1352,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1352 } 1352 }
1353 1353
1354 { 1354 {
1355 struct flowi fl = { .nl_u = { .ip4_u = 1355 struct flowi fl = { .oif = arg->bound_dev_if,
1356 .nl_u = { .ip4_u =
1356 { .daddr = daddr, 1357 { .daddr = daddr,
1357 .saddr = rt->rt_spec_dst, 1358 .saddr = rt->rt_spec_dst,
1358 .tos = RT_TOS(ip_hdr(skb)->tos) } }, 1359 .tos = RT_TOS(ip_hdr(skb)->tos) } },
@@ -1376,6 +1377,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1376 inet->tos = ip_hdr(skb)->tos; 1377 inet->tos = ip_hdr(skb)->tos;
1377 sk->sk_priority = skb->priority; 1378 sk->sk_priority = skb->priority;
1378 sk->sk_protocol = ip_hdr(skb)->protocol; 1379 sk->sk_protocol = ip_hdr(skb)->protocol;
1380 sk->sk_bound_dev_if = arg->bound_dev_if;
1379 ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0, 1381 ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
1380 &ipc, rt, MSG_DONTWAIT); 1382 &ipc, rt, MSG_DONTWAIT);
1381 if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { 1383 if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 0ebae413ae87..d96582acdf69 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
152 dev->flags |= IFF_MULTICAST; 152 dev->flags |= IFF_MULTICAST;
153 153
154 in_dev = __in_dev_get_rtnl(dev); 154 in_dev = __in_dev_get_rtnl(dev);
155 if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL) 155 if (in_dev == NULL)
156 goto failure; 156 goto failure;
157 in_dev->cnf.rp_filter = 0; 157
158 ipv4_devconf_setall(in_dev);
159 IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
158 160
159 if (dev_open(dev)) 161 if (dev_open(dev))
160 goto failure; 162 goto failure;
@@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void)
218 } 220 }
219 dev->iflink = 0; 221 dev->iflink = 0;
220 222
221 if ((in_dev = inetdev_init(dev)) == NULL) 223 rcu_read_lock();
224 if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
225 rcu_read_unlock();
222 goto failure; 226 goto failure;
227 }
223 228
224 in_dev->cnf.rp_filter = 0; 229 ipv4_devconf_setall(in_dev);
230 IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
231 rcu_read_unlock();
225 232
226 if (dev_open(dev)) 233 if (dev_open(dev))
227 goto failure; 234 goto failure;
@@ -281,7 +288,7 @@ static int vif_delete(int vifi)
281 dev_set_allmulti(dev, -1); 288 dev_set_allmulti(dev, -1);
282 289
283 if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { 290 if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
284 in_dev->cnf.mc_forwarding--; 291 IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
285 ip_rt_multicast_event(in_dev); 292 ip_rt_multicast_event(in_dev);
286 } 293 }
287 294
@@ -426,7 +433,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
426 433
427 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) 434 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
428 return -EADDRNOTAVAIL; 435 return -EADDRNOTAVAIL;
429 in_dev->cnf.mc_forwarding++; 436 IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
430 dev_set_allmulti(dev, +1); 437 dev_set_allmulti(dev, +1);
431 ip_rt_multicast_event(in_dev); 438 ip_rt_multicast_event(in_dev);
432 439
@@ -841,7 +848,7 @@ static void mrtsock_destruct(struct sock *sk)
841{ 848{
842 rtnl_lock(); 849 rtnl_lock();
843 if (sk == mroute_socket) { 850 if (sk == mroute_socket) {
844 ipv4_devconf.mc_forwarding--; 851 IPV4_DEVCONF_ALL(MC_FORWARDING)--;
845 852
846 write_lock_bh(&mrt_lock); 853 write_lock_bh(&mrt_lock);
847 mroute_socket=NULL; 854 mroute_socket=NULL;
@@ -890,7 +897,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
890 mroute_socket=sk; 897 mroute_socket=sk;
891 write_unlock_bh(&mrt_lock); 898 write_unlock_bh(&mrt_lock);
892 899
893 ipv4_devconf.mc_forwarding++; 900 IPV4_DEVCONF_ALL(MC_FORWARDING)++;
894 } 901 }
895 rtnl_unlock(); 902 rtnl_unlock();
896 return ret; 903 return ret;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index e3f83bf160d9..9bacf1a03630 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -499,7 +499,8 @@ check_entry(struct ipt_entry *e, const char *name)
499} 499}
500 500
501static inline int check_match(struct ipt_entry_match *m, const char *name, 501static inline int check_match(struct ipt_entry_match *m, const char *name,
502 const struct ipt_ip *ip, unsigned int hookmask) 502 const struct ipt_ip *ip, unsigned int hookmask,
503 unsigned int *i)
503{ 504{
504 struct xt_match *match; 505 struct xt_match *match;
505 int ret; 506 int ret;
@@ -515,6 +516,8 @@ static inline int check_match(struct ipt_entry_match *m, const char *name,
515 m->u.kernel.match->name); 516 m->u.kernel.match->name);
516 ret = -EINVAL; 517 ret = -EINVAL;
517 } 518 }
519 if (!ret)
520 (*i)++;
518 return ret; 521 return ret;
519} 522}
520 523
@@ -537,11 +540,10 @@ find_check_match(struct ipt_entry_match *m,
537 } 540 }
538 m->u.kernel.match = match; 541 m->u.kernel.match = match;
539 542
540 ret = check_match(m, name, ip, hookmask); 543 ret = check_match(m, name, ip, hookmask, i);
541 if (ret) 544 if (ret)
542 goto err; 545 goto err;
543 546
544 (*i)++;
545 return 0; 547 return 0;
546err: 548err:
547 module_put(m->u.kernel.match->me); 549 module_put(m->u.kernel.match->me);
@@ -1425,7 +1427,7 @@ out:
1425} 1427}
1426 1428
1427static inline int 1429static inline int
1428compat_check_calc_match(struct ipt_entry_match *m, 1430compat_find_calc_match(struct ipt_entry_match *m,
1429 const char *name, 1431 const char *name,
1430 const struct ipt_ip *ip, 1432 const struct ipt_ip *ip,
1431 unsigned int hookmask, 1433 unsigned int hookmask,
@@ -1449,6 +1451,31 @@ compat_check_calc_match(struct ipt_entry_match *m,
1449} 1451}
1450 1452
1451static inline int 1453static inline int
1454compat_release_match(struct ipt_entry_match *m, unsigned int *i)
1455{
1456 if (i && (*i)-- == 0)
1457 return 1;
1458
1459 module_put(m->u.kernel.match->me);
1460 return 0;
1461}
1462
1463static inline int
1464compat_release_entry(struct ipt_entry *e, unsigned int *i)
1465{
1466 struct ipt_entry_target *t;
1467
1468 if (i && (*i)-- == 0)
1469 return 1;
1470
1471 /* Cleanup all matches */
1472 IPT_MATCH_ITERATE(e, compat_release_match, NULL);
1473 t = ipt_get_target(e);
1474 module_put(t->u.kernel.target->me);
1475 return 0;
1476}
1477
1478static inline int
1452check_compat_entry_size_and_hooks(struct ipt_entry *e, 1479check_compat_entry_size_and_hooks(struct ipt_entry *e,
1453 struct xt_table_info *newinfo, 1480 struct xt_table_info *newinfo,
1454 unsigned int *size, 1481 unsigned int *size,
@@ -1485,10 +1512,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1485 off = 0; 1512 off = 0;
1486 entry_offset = (void *)e - (void *)base; 1513 entry_offset = (void *)e - (void *)base;
1487 j = 0; 1514 j = 0;
1488 ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip, 1515 ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
1489 e->comefrom, &off, &j); 1516 e->comefrom, &off, &j);
1490 if (ret != 0) 1517 if (ret != 0)
1491 goto cleanup_matches; 1518 goto release_matches;
1492 1519
1493 t = ipt_get_target(e); 1520 t = ipt_get_target(e);
1494 target = try_then_request_module(xt_find_target(AF_INET, 1521 target = try_then_request_module(xt_find_target(AF_INET,
@@ -1499,7 +1526,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1499 duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", 1526 duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
1500 t->u.user.name); 1527 t->u.user.name);
1501 ret = target ? PTR_ERR(target) : -ENOENT; 1528 ret = target ? PTR_ERR(target) : -ENOENT;
1502 goto cleanup_matches; 1529 goto release_matches;
1503 } 1530 }
1504 t->u.kernel.target = target; 1531 t->u.kernel.target = target;
1505 1532
@@ -1526,8 +1553,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1526 1553
1527out: 1554out:
1528 module_put(t->u.kernel.target->me); 1555 module_put(t->u.kernel.target->me);
1529cleanup_matches: 1556release_matches:
1530 IPT_MATCH_ITERATE(e, cleanup_match, &j); 1557 IPT_MATCH_ITERATE(e, compat_release_match, &j);
1531 return ret; 1558 return ret;
1532} 1559}
1533 1560
@@ -1574,15 +1601,26 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
1574 return ret; 1601 return ret;
1575} 1602}
1576 1603
1577static inline int compat_check_entry(struct ipt_entry *e, const char *name) 1604static inline int compat_check_entry(struct ipt_entry *e, const char *name,
1605 unsigned int *i)
1578{ 1606{
1579 int ret; 1607 int j, ret;
1580 1608
1581 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom); 1609 j = 0;
1610 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
1582 if (ret) 1611 if (ret)
1583 return ret; 1612 goto cleanup_matches;
1613
1614 ret = check_target(e, name);
1615 if (ret)
1616 goto cleanup_matches;
1584 1617
1585 return check_target(e, name); 1618 (*i)++;
1619 return 0;
1620
1621 cleanup_matches:
1622 IPT_MATCH_ITERATE(e, cleanup_match, &j);
1623 return ret;
1586} 1624}
1587 1625
1588static int 1626static int
@@ -1673,10 +1711,17 @@ translate_compat_table(const char *name,
1673 if (!mark_source_chains(newinfo, valid_hooks, entry1)) 1711 if (!mark_source_chains(newinfo, valid_hooks, entry1))
1674 goto free_newinfo; 1712 goto free_newinfo;
1675 1713
1714 i = 0;
1676 ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, 1715 ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
1677 name); 1716 name, &i);
1678 if (ret) 1717 if (ret) {
1679 goto free_newinfo; 1718 j -= i;
1719 IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i,
1720 compat_release_entry, &j);
1721 IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
1722 xt_free_table_info(newinfo);
1723 return ret;
1724 }
1680 1725
1681 /* And one copy for every other CPU */ 1726 /* And one copy for every other CPU */
1682 for_each_possible_cpu(i) 1727 for_each_possible_cpu(i)
@@ -1691,7 +1736,7 @@ translate_compat_table(const char *name,
1691free_newinfo: 1736free_newinfo:
1692 xt_free_table_info(newinfo); 1737 xt_free_table_info(newinfo);
1693out: 1738out:
1694 IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); 1739 IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
1695 return ret; 1740 return ret;
1696out_unlock: 1741out_unlock:
1697 compat_flush_offsets(); 1742 compat_flush_offsets();
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index fd62a41d69cc..6dc72a815f77 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -133,6 +133,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
133 struct nf_conn *ct; 133 struct nf_conn *ct;
134 enum ip_conntrack_info ctinfo; 134 enum ip_conntrack_info ctinfo;
135 struct nf_conn_help *help; 135 struct nf_conn_help *help;
136 struct nf_conntrack_helper *helper;
136 137
137 /* This is where we call the helper: as the packet goes out. */ 138 /* This is where we call the helper: as the packet goes out. */
138 ct = nf_ct_get(*pskb, &ctinfo); 139 ct = nf_ct_get(*pskb, &ctinfo);
@@ -140,12 +141,14 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
140 return NF_ACCEPT; 141 return NF_ACCEPT;
141 142
142 help = nfct_help(ct); 143 help = nfct_help(ct);
143 if (!help || !help->helper) 144 if (!help)
144 return NF_ACCEPT; 145 return NF_ACCEPT;
145 146 /* rcu_read_lock()ed by nf_hook_slow */
146 return help->helper->help(pskb, 147 helper = rcu_dereference(help->helper);
147 skb_network_offset(*pskb) + ip_hdrlen(*pskb), 148 if (!helper)
148 ct, ctinfo); 149 return NF_ACCEPT;
150 return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb),
151 ct, ctinfo);
149} 152}
150 153
151static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, 154static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index cdbc6c135849..3b690cf2a4ee 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -260,7 +260,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
260 seq_printf(seq, " %s", snmp4_ipstats_list[i].name); 260 seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
261 261
262 seq_printf(seq, "\nIp: %d %d", 262 seq_printf(seq, "\nIp: %d %d",
263 ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl); 263 IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl);
264 264
265 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) 265 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
266 seq_printf(seq, " %lu", 266 seq_printf(seq, " %lu",
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8603cfb271f2..29ca63e81ced 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1636,7 +1636,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1636 1636
1637 atomic_set(&rth->u.dst.__refcnt, 1); 1637 atomic_set(&rth->u.dst.__refcnt, 1);
1638 rth->u.dst.flags= DST_HOST; 1638 rth->u.dst.flags= DST_HOST;
1639 if (in_dev->cnf.no_policy) 1639 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
1640 rth->u.dst.flags |= DST_NOPOLICY; 1640 rth->u.dst.flags |= DST_NOPOLICY;
1641 rth->fl.fl4_dst = daddr; 1641 rth->fl.fl4_dst = daddr;
1642 rth->rt_dst = daddr; 1642 rth->rt_dst = daddr;
@@ -1778,9 +1778,9 @@ static inline int __mkroute_input(struct sk_buff *skb,
1778 if (res->fi->fib_nhs > 1) 1778 if (res->fi->fib_nhs > 1)
1779 rth->u.dst.flags |= DST_BALANCED; 1779 rth->u.dst.flags |= DST_BALANCED;
1780#endif 1780#endif
1781 if (in_dev->cnf.no_policy) 1781 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
1782 rth->u.dst.flags |= DST_NOPOLICY; 1782 rth->u.dst.flags |= DST_NOPOLICY;
1783 if (out_dev->cnf.no_xfrm) 1783 if (IN_DEV_CONF_GET(out_dev, NOXFRM))
1784 rth->u.dst.flags |= DST_NOXFRM; 1784 rth->u.dst.flags |= DST_NOXFRM;
1785 rth->fl.fl4_dst = daddr; 1785 rth->fl.fl4_dst = daddr;
1786 rth->rt_dst = daddr; 1786 rth->rt_dst = daddr;
@@ -2021,7 +2021,7 @@ local_input:
2021 2021
2022 atomic_set(&rth->u.dst.__refcnt, 1); 2022 atomic_set(&rth->u.dst.__refcnt, 1);
2023 rth->u.dst.flags= DST_HOST; 2023 rth->u.dst.flags= DST_HOST;
2024 if (in_dev->cnf.no_policy) 2024 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
2025 rth->u.dst.flags |= DST_NOPOLICY; 2025 rth->u.dst.flags |= DST_NOPOLICY;
2026 rth->fl.fl4_dst = daddr; 2026 rth->fl.fl4_dst = daddr;
2027 rth->rt_dst = daddr; 2027 rth->rt_dst = daddr;
@@ -2218,9 +2218,9 @@ static inline int __mkroute_output(struct rtable **result,
2218 rth->u.dst.flags |= DST_BALANCED; 2218 rth->u.dst.flags |= DST_BALANCED;
2219 } 2219 }
2220#endif 2220#endif
2221 if (in_dev->cnf.no_xfrm) 2221 if (IN_DEV_CONF_GET(in_dev, NOXFRM))
2222 rth->u.dst.flags |= DST_NOXFRM; 2222 rth->u.dst.flags |= DST_NOXFRM;
2223 if (in_dev->cnf.no_policy) 2223 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
2224 rth->u.dst.flags |= DST_NOPOLICY; 2224 rth->u.dst.flags |= DST_NOPOLICY;
2225 2225
2226 rth->fl.fl4_dst = oldflp->fl4_dst; 2226 rth->fl.fl4_dst = oldflp->fl4_dst;
@@ -2759,7 +2759,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2759 __be32 dst = rt->rt_dst; 2759 __be32 dst = rt->rt_dst;
2760 2760
2761 if (MULTICAST(dst) && !LOCAL_MCAST(dst) && 2761 if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
2762 ipv4_devconf.mc_forwarding) { 2762 IPV4_DEVCONF_ALL(MC_FORWARDING)) {
2763 int err = ipmr_get_route(skb, r, nowait); 2763 int err = ipmr_get_route(skb, r, nowait);
2764 if (err <= 0) { 2764 if (err <= 0) {
2765 if (!nowait) { 2765 if (!nowait) {
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 6817d6485df5..53ef0f4bbdaa 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -37,12 +37,12 @@ static
37int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, 37int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
38 void __user *buffer, size_t *lenp, loff_t *ppos) 38 void __user *buffer, size_t *lenp, loff_t *ppos)
39{ 39{
40 int val = ipv4_devconf.forwarding; 40 int val = IPV4_DEVCONF_ALL(FORWARDING);
41 int ret; 41 int ret;
42 42
43 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); 43 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
44 44
45 if (write && ipv4_devconf.forwarding != val) 45 if (write && IPV4_DEVCONF_ALL(FORWARDING) != val)
46 inet_forward_change(); 46 inet_forward_change();
47 47
48 return ret; 48 return ret;
@@ -222,7 +222,7 @@ ctl_table ipv4_table[] = {
222 { 222 {
223 .ctl_name = NET_IPV4_FORWARD, 223 .ctl_name = NET_IPV4_FORWARD,
224 .procname = "ip_forward", 224 .procname = "ip_forward",
225 .data = &ipv4_devconf.forwarding, 225 .data = &IPV4_DEVCONF_ALL(FORWARDING),
226 .maxlen = sizeof(int), 226 .maxlen = sizeof(int),
227 .mode = 0644, 227 .mode = 0644,
228 .proc_handler = &ipv4_sysctl_forward, 228 .proc_handler = &ipv4_sysctl_forward,
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 47c61055eb60..97e294e82679 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -705,6 +705,8 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
705 ip_hdr(skb)->saddr, /* XXX */ 705 ip_hdr(skb)->saddr, /* XXX */
706 arg.iov[0].iov_len, IPPROTO_TCP, 0); 706 arg.iov[0].iov_len, IPPROTO_TCP, 0);
707 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 707 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
708 if (twsk)
709 arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
708 710
709 ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); 711 ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
710 712
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index 760165a0800c..d9323dfff826 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -63,6 +63,9 @@ struct {
63 * FIXME: causes an extra copy 63 * FIXME: causes an extra copy
64 */ 64 */
65static void printl(const char *fmt, ...) 65static void printl(const char *fmt, ...)
66 __attribute__ ((format (printf, 1, 2)));
67
68static void printl(const char *fmt, ...)
66{ 69{
67 va_list args; 70 va_list args;
68 int len; 71 int len;
@@ -80,8 +83,7 @@ static void printl(const char *fmt, ...)
80 83
81 kfifo_put(tcpw.fifo, tbuf, len); 84 kfifo_put(tcpw.fifo, tbuf, len);
82 wake_up(&tcpw.wait); 85 wake_up(&tcpw.wait);
83} __attribute__ ((format (printf, 1, 2))); 86}
84
85 87
86/* 88/*
87 * Hook inserted to be called before each receive packet. 89 * Hook inserted to be called before each receive packet.
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index e61340150ba6..e9b151b3a598 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -292,9 +292,9 @@ static void tcp_retransmit_timer(struct sock *sk)
292 * we cannot allow such beasts to hang infinitely. 292 * we cannot allow such beasts to hang infinitely.
293 */ 293 */
294#ifdef TCP_DEBUG 294#ifdef TCP_DEBUG
295 if (net_ratelimit()) { 295 if (1) {
296 struct inet_sock *inet = inet_sk(sk); 296 struct inet_sock *inet = inet_sk(sk);
297 printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", 297 LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
298 NIPQUAD(inet->daddr), ntohs(inet->dport), 298 NIPQUAD(inet->daddr), ntohs(inet->dport),
299 inet->num, tp->snd_una, tp->snd_nxt); 299 inet->num, tp->snd_una, tp->snd_nxt);
300 } 300 }
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 5da703e699da..facb7e29304e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -114,36 +114,14 @@ DEFINE_RWLOCK(udp_hash_lock);
114 114
115static int udp_port_rover; 115static int udp_port_rover;
116 116
117/* 117static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[])
118 * Note about this hash function :
119 * Typical use is probably daddr = 0, only dport is going to vary hash
120 */
121static inline unsigned int udp_hash_port(__u16 port)
122{
123 return port;
124}
125
126static inline int __udp_lib_port_inuse(unsigned int hash, int port,
127 const struct sock *this_sk,
128 struct hlist_head udptable[],
129 const struct udp_get_port_ops *ops)
130{ 118{
131 struct sock *sk; 119 struct sock *sk;
132 struct hlist_node *node; 120 struct hlist_node *node;
133 struct inet_sock *inet;
134 121
135 sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) { 122 sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
136 if (sk->sk_hash != hash) 123 if (sk->sk_hash == num)
137 continue;
138 inet = inet_sk(sk);
139 if (inet->num != port)
140 continue;
141 if (this_sk) {
142 if (ops->saddr_cmp(sk, this_sk))
143 return 1;
144 } else if (ops->saddr_any(sk))
145 return 1; 124 return 1;
146 }
147 return 0; 125 return 0;
148} 126}
149 127
@@ -154,16 +132,16 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port,
154 * @snum: port number to look up 132 * @snum: port number to look up
155 * @udptable: hash list table, must be of UDP_HTABLE_SIZE 133 * @udptable: hash list table, must be of UDP_HTABLE_SIZE
156 * @port_rover: pointer to record of last unallocated port 134 * @port_rover: pointer to record of last unallocated port
157 * @ops: AF-dependent address operations 135 * @saddr_comp: AF-dependent comparison of bound local IP addresses
158 */ 136 */
159int __udp_lib_get_port(struct sock *sk, unsigned short snum, 137int __udp_lib_get_port(struct sock *sk, unsigned short snum,
160 struct hlist_head udptable[], int *port_rover, 138 struct hlist_head udptable[], int *port_rover,
161 const struct udp_get_port_ops *ops) 139 int (*saddr_comp)(const struct sock *sk1,
140 const struct sock *sk2 ) )
162{ 141{
163 struct hlist_node *node; 142 struct hlist_node *node;
164 struct hlist_head *head; 143 struct hlist_head *head;
165 struct sock *sk2; 144 struct sock *sk2;
166 unsigned int hash;
167 int error = 1; 145 int error = 1;
168 146
169 write_lock_bh(&udp_hash_lock); 147 write_lock_bh(&udp_hash_lock);
@@ -178,8 +156,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
178 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { 156 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
179 int size; 157 int size;
180 158
181 hash = ops->hash_port_and_rcv_saddr(result, sk); 159 head = &udptable[result & (UDP_HTABLE_SIZE - 1)];
182 head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
183 if (hlist_empty(head)) { 160 if (hlist_empty(head)) {
184 if (result > sysctl_local_port_range[1]) 161 if (result > sysctl_local_port_range[1])
185 result = sysctl_local_port_range[0] + 162 result = sysctl_local_port_range[0] +
@@ -204,16 +181,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
204 result = sysctl_local_port_range[0] 181 result = sysctl_local_port_range[0]
205 + ((result - sysctl_local_port_range[0]) & 182 + ((result - sysctl_local_port_range[0]) &
206 (UDP_HTABLE_SIZE - 1)); 183 (UDP_HTABLE_SIZE - 1));
207 hash = udp_hash_port(result); 184 if (! __udp_lib_lport_inuse(result, udptable))
208 if (__udp_lib_port_inuse(hash, result,
209 NULL, udptable, ops))
210 continue;
211 if (ops->saddr_any(sk))
212 break;
213
214 hash = ops->hash_port_and_rcv_saddr(result, sk);
215 if (! __udp_lib_port_inuse(hash, result,
216 sk, udptable, ops))
217 break; 185 break;
218 } 186 }
219 if (i >= (1 << 16) / UDP_HTABLE_SIZE) 187 if (i >= (1 << 16) / UDP_HTABLE_SIZE)
@@ -221,40 +189,21 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
221gotit: 189gotit:
222 *port_rover = snum = result; 190 *port_rover = snum = result;
223 } else { 191 } else {
224 hash = udp_hash_port(snum); 192 head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
225 head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
226 193
227 sk_for_each(sk2, node, head) 194 sk_for_each(sk2, node, head)
228 if (sk2->sk_hash == hash && 195 if (sk2->sk_hash == snum &&
229 sk2 != sk && 196 sk2 != sk &&
230 inet_sk(sk2)->num == snum && 197 (!sk2->sk_reuse || !sk->sk_reuse) &&
231 (!sk2->sk_reuse || !sk->sk_reuse) && 198 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
232 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || 199 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
233 sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && 200 (*saddr_comp)(sk, sk2) )
234 ops->saddr_cmp(sk, sk2))
235 goto fail; 201 goto fail;
236
237 if (!ops->saddr_any(sk)) {
238 hash = ops->hash_port_and_rcv_saddr(snum, sk);
239 head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
240
241 sk_for_each(sk2, node, head)
242 if (sk2->sk_hash == hash &&
243 sk2 != sk &&
244 inet_sk(sk2)->num == snum &&
245 (!sk2->sk_reuse || !sk->sk_reuse) &&
246 (!sk2->sk_bound_dev_if ||
247 !sk->sk_bound_dev_if ||
248 sk2->sk_bound_dev_if ==
249 sk->sk_bound_dev_if) &&
250 ops->saddr_cmp(sk, sk2))
251 goto fail;
252 }
253 } 202 }
254 inet_sk(sk)->num = snum; 203 inet_sk(sk)->num = snum;
255 sk->sk_hash = hash; 204 sk->sk_hash = snum;
256 if (sk_unhashed(sk)) { 205 if (sk_unhashed(sk)) {
257 head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; 206 head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
258 sk_add_node(sk, head); 207 sk_add_node(sk, head);
259 sock_prot_inc_use(sk->sk_prot); 208 sock_prot_inc_use(sk->sk_prot);
260 } 209 }
@@ -265,12 +214,12 @@ fail:
265} 214}
266 215
267int udp_get_port(struct sock *sk, unsigned short snum, 216int udp_get_port(struct sock *sk, unsigned short snum,
268 const struct udp_get_port_ops *ops) 217 int (*scmp)(const struct sock *, const struct sock *))
269{ 218{
270 return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, ops); 219 return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
271} 220}
272 221
273static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) 222int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
274{ 223{
275 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); 224 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
276 225
@@ -279,33 +228,9 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
279 inet1->rcv_saddr == inet2->rcv_saddr )); 228 inet1->rcv_saddr == inet2->rcv_saddr ));
280} 229}
281 230
282static int ipv4_rcv_saddr_any(const struct sock *sk)
283{
284 return !inet_sk(sk)->rcv_saddr;
285}
286
287static inline unsigned int ipv4_hash_port_and_addr(__u16 port, __be32 addr)
288{
289 addr ^= addr >> 16;
290 addr ^= addr >> 8;
291 return port ^ addr;
292}
293
294static unsigned int ipv4_hash_port_and_rcv_saddr(__u16 port,
295 const struct sock *sk)
296{
297 return ipv4_hash_port_and_addr(port, inet_sk(sk)->rcv_saddr);
298}
299
300const struct udp_get_port_ops udp_ipv4_ops = {
301 .saddr_cmp = ipv4_rcv_saddr_equal,
302 .saddr_any = ipv4_rcv_saddr_any,
303 .hash_port_and_rcv_saddr = ipv4_hash_port_and_rcv_saddr,
304};
305
306static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) 231static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
307{ 232{
308 return udp_get_port(sk, snum, &udp_ipv4_ops); 233 return udp_get_port(sk, snum, ipv4_rcv_saddr_equal);
309} 234}
310 235
311/* UDP is nearly always wildcards out the wazoo, it makes no sense to try 236/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
@@ -317,77 +242,63 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
317{ 242{
318 struct sock *sk, *result = NULL; 243 struct sock *sk, *result = NULL;
319 struct hlist_node *node; 244 struct hlist_node *node;
320 unsigned int hash, hashwild; 245 unsigned short hnum = ntohs(dport);
321 int score, best = -1, hport = ntohs(dport); 246 int badness = -1;
322
323 hash = ipv4_hash_port_and_addr(hport, daddr);
324 hashwild = udp_hash_port(hport);
325 247
326 read_lock(&udp_hash_lock); 248 read_lock(&udp_hash_lock);
327 249 sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
328lookup:
329
330 sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) {
331 struct inet_sock *inet = inet_sk(sk); 250 struct inet_sock *inet = inet_sk(sk);
332 251
333 if (sk->sk_hash != hash || ipv6_only_sock(sk) || 252 if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
334 inet->num != hport) 253 int score = (sk->sk_family == PF_INET ? 1 : 0);
335 continue; 254 if (inet->rcv_saddr) {
336 255 if (inet->rcv_saddr != daddr)
337 score = (sk->sk_family == PF_INET ? 1 : 0); 256 continue;
338 if (inet->rcv_saddr) { 257 score+=2;
339 if (inet->rcv_saddr != daddr) 258 }
340 continue; 259 if (inet->daddr) {
341 score+=2; 260 if (inet->daddr != saddr)
342 } 261 continue;
343 if (inet->daddr) { 262 score+=2;
344 if (inet->daddr != saddr) 263 }
345 continue; 264 if (inet->dport) {
346 score+=2; 265 if (inet->dport != sport)
347 } 266 continue;
348 if (inet->dport) { 267 score+=2;
349 if (inet->dport != sport) 268 }
350 continue; 269 if (sk->sk_bound_dev_if) {
351 score+=2; 270 if (sk->sk_bound_dev_if != dif)
352 } 271 continue;
353 if (sk->sk_bound_dev_if) { 272 score+=2;
354 if (sk->sk_bound_dev_if != dif) 273 }
355 continue; 274 if (score == 9) {
356 score+=2; 275 result = sk;
357 } 276 break;
358 if (score == 9) { 277 } else if (score > badness) {
359 result = sk; 278 result = sk;
360 goto found; 279 badness = score;
361 } else if (score > best) { 280 }
362 result = sk;
363 best = score;
364 } 281 }
365 } 282 }
366
367 if (hash != hashwild) {
368 hash = hashwild;
369 goto lookup;
370 }
371found:
372 if (result) 283 if (result)
373 sock_hold(result); 284 sock_hold(result);
374 read_unlock(&udp_hash_lock); 285 read_unlock(&udp_hash_lock);
375 return result; 286 return result;
376} 287}
377 288
378static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum, 289static inline struct sock *udp_v4_mcast_next(struct sock *sk,
379 int hport, __be32 loc_addr, 290 __be16 loc_port, __be32 loc_addr,
380 __be16 rmt_port, __be32 rmt_addr, 291 __be16 rmt_port, __be32 rmt_addr,
381 int dif) 292 int dif)
382{ 293{
383 struct hlist_node *node; 294 struct hlist_node *node;
384 struct sock *s = sk; 295 struct sock *s = sk;
296 unsigned short hnum = ntohs(loc_port);
385 297
386 sk_for_each_from(s, node) { 298 sk_for_each_from(s, node) {
387 struct inet_sock *inet = inet_sk(s); 299 struct inet_sock *inet = inet_sk(s);
388 300
389 if (s->sk_hash != hnum || 301 if (s->sk_hash != hnum ||
390 inet->num != hport ||
391 (inet->daddr && inet->daddr != rmt_addr) || 302 (inet->daddr && inet->daddr != rmt_addr) ||
392 (inet->dport != rmt_port && inet->dport) || 303 (inet->dport != rmt_port && inet->dport) ||
393 (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || 304 (inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
@@ -1221,45 +1132,29 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
1221 __be32 saddr, __be32 daddr, 1132 __be32 saddr, __be32 daddr,
1222 struct hlist_head udptable[]) 1133 struct hlist_head udptable[])
1223{ 1134{
1224 struct sock *sk, *skw, *sknext; 1135 struct sock *sk;
1225 int dif; 1136 int dif;
1226 int hport = ntohs(uh->dest);
1227 unsigned int hash = ipv4_hash_port_and_addr(hport, daddr);
1228 unsigned int hashwild = udp_hash_port(hport);
1229
1230 dif = skb->dev->ifindex;
1231 1137
1232 read_lock(&udp_hash_lock); 1138 read_lock(&udp_hash_lock);
1233 1139 sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
1234 sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]); 1140 dif = skb->dev->ifindex;
1235 skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]); 1141 sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
1236
1237 sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif);
1238 if (!sk) {
1239 hash = hashwild;
1240 sk = udp_v4_mcast_next(skw, hash, hport, daddr, uh->source,
1241 saddr, dif);
1242 }
1243 if (sk) { 1142 if (sk) {
1143 struct sock *sknext = NULL;
1144
1244 do { 1145 do {
1245 struct sk_buff *skb1 = skb; 1146 struct sk_buff *skb1 = skb;
1246 sknext = udp_v4_mcast_next(sk_next(sk), hash, hport, 1147
1247 daddr, uh->source, saddr, dif); 1148 sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr,
1248 if (!sknext && hash != hashwild) { 1149 uh->source, saddr, dif);
1249 hash = hashwild;
1250 sknext = udp_v4_mcast_next(skw, hash, hport,
1251 daddr, uh->source, saddr, dif);
1252 }
1253 if (sknext) 1150 if (sknext)
1254 skb1 = skb_clone(skb, GFP_ATOMIC); 1151 skb1 = skb_clone(skb, GFP_ATOMIC);
1255 1152
1256 if (skb1) { 1153 if (skb1) {
1257 int ret = udp_queue_rcv_skb(sk, skb1); 1154 int ret = udp_queue_rcv_skb(sk, skb1);
1258 if (ret > 0) 1155 if (ret > 0)
1259 /* 1156 /* we should probably re-process instead
1260 * we should probably re-process 1157 * of dropping packets here. */
1261 * instead of dropping packets here.
1262 */
1263 kfree_skb(skb1); 1158 kfree_skb(skb1);
1264 } 1159 }
1265 sk = sknext; 1160 sk = sknext;
@@ -1346,7 +1241,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1346 return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); 1241 return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
1347 1242
1348 sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, 1243 sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
1349 skb->dev->ifindex, udptable); 1244 skb->dev->ifindex, udptable );
1350 1245
1351 if (sk != NULL) { 1246 if (sk != NULL) {
1352 int ret = udp_queue_rcv_skb(sk, skb); 1247 int ret = udp_queue_rcv_skb(sk, skb);
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
index 06d94195e644..820a477cfaa6 100644
--- a/net/ipv4/udp_impl.h
+++ b/net/ipv4/udp_impl.h
@@ -5,14 +5,14 @@
5#include <net/protocol.h> 5#include <net/protocol.h>
6#include <net/inet_common.h> 6#include <net/inet_common.h>
7 7
8extern const struct udp_get_port_ops udp_ipv4_ops;
9
10extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); 8extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int );
11extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); 9extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []);
12 10
13extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, 11extern int __udp_lib_get_port(struct sock *sk, unsigned short snum,
14 struct hlist_head udptable[], int *port_rover, 12 struct hlist_head udptable[], int *port_rover,
15 const struct udp_get_port_ops *ops); 13 int (*)(const struct sock*,const struct sock*));
14extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
15
16 16
17extern int udp_setsockopt(struct sock *sk, int level, int optname, 17extern int udp_setsockopt(struct sock *sk, int level, int optname,
18 char __user *optval, int optlen); 18 char __user *optval, int optlen);
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index 3653b32dce2d..f34fd686a8f1 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -19,15 +19,14 @@ struct hlist_head udplite_hash[UDP_HTABLE_SIZE];
19static int udplite_port_rover; 19static int udplite_port_rover;
20 20
21int udplite_get_port(struct sock *sk, unsigned short p, 21int udplite_get_port(struct sock *sk, unsigned short p,
22 const struct udp_get_port_ops *ops) 22 int (*c)(const struct sock *, const struct sock *))
23{ 23{
24 return __udp_lib_get_port(sk, p, udplite_hash, 24 return __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c);
25 &udplite_port_rover, ops);
26} 25}
27 26
28static int udplite_v4_get_port(struct sock *sk, unsigned short snum) 27static int udplite_v4_get_port(struct sock *sk, unsigned short snum)
29{ 28{
30 return udplite_get_port(sk, snum, &udp_ipv4_ops); 29 return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal);
31} 30}
32 31
33static int udplite_rcv(struct sk_buff *skb) 32static int udplite_rcv(struct sk_buff *skb)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 329de679ac38..5a5f8bd4597a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2990,7 +2990,7 @@ static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
2990 return pfx; 2990 return pfx;
2991} 2991}
2992 2992
2993static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = { 2993static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
2994 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, 2994 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
2995 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, 2995 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
2996 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, 2996 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index fc3882c90604..53b3998a486c 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -157,7 +157,7 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
157 return 1; 157 return 1;
158} 158}
159 159
160static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { 160static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = {
161 FRA_GENERIC_POLICY, 161 FRA_GENERIC_POLICY,
162}; 162};
163 163
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index dc442fb791b0..1b1797f1f33d 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
160{ 160{
161 struct nf_conn *ct; 161 struct nf_conn *ct;
162 struct nf_conn_help *help; 162 struct nf_conn_help *help;
163 struct nf_conntrack_helper *helper;
163 enum ip_conntrack_info ctinfo; 164 enum ip_conntrack_info ctinfo;
164 unsigned int ret, protoff; 165 unsigned int ret, protoff;
165 unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; 166 unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
@@ -172,7 +173,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
172 goto out; 173 goto out;
173 174
174 help = nfct_help(ct); 175 help = nfct_help(ct);
175 if (!help || !help->helper) 176 if (!help)
177 goto out;
178 /* rcu_read_lock()ed by nf_hook_slow */
179 helper = rcu_dereference(help->helper);
180 if (!helper)
176 goto out; 181 goto out;
177 182
178 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, 183 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
@@ -182,7 +187,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
182 return NF_ACCEPT; 187 return NF_ACCEPT;
183 } 188 }
184 189
185 ret = help->helper->help(pskb, protoff, ct, ctinfo); 190 ret = helper->help(pskb, protoff, ct, ctinfo);
186 if (ret != NF_ACCEPT) 191 if (ret != NF_ACCEPT)
187 return ret; 192 return ret;
188out: 193out:
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1324b06796c0..fe8d9837f9f8 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1999,7 +1999,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned mtu)
1999 fib6_clean_all(rt6_mtu_change_route, 0, &arg); 1999 fib6_clean_all(rt6_mtu_change_route, 0, &arg);
2000} 2000}
2001 2001
2002static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = { 2002static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
2003 [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, 2003 [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) },
2004 [RTA_OIF] = { .type = NLA_U32 }, 2004 [RTA_OIF] = { .type = NLA_U32 },
2005 [RTA_IIF] = { .type = NLA_U32 }, 2005 [RTA_IIF] = { .type = NLA_U32 },
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d1fbddd172e7..4210951edb6e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -52,28 +52,9 @@
52 52
53DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; 53DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
54 54
55static int ipv6_rcv_saddr_any(const struct sock *sk)
56{
57 struct ipv6_pinfo *np = inet6_sk(sk);
58
59 return ipv6_addr_any(&np->rcv_saddr);
60}
61
62static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port,
63 const struct sock *sk)
64{
65 return port;
66}
67
68const struct udp_get_port_ops udp_ipv6_ops = {
69 .saddr_cmp = ipv6_rcv_saddr_equal,
70 .saddr_any = ipv6_rcv_saddr_any,
71 .hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr,
72};
73
74static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) 55static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
75{ 56{
76 return udp_get_port(sk, snum, &udp_ipv6_ops); 57 return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
77} 58}
78 59
79static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, 60static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 36b0c11a28a3..6e252f318f7c 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -6,8 +6,6 @@
6#include <net/addrconf.h> 6#include <net/addrconf.h>
7#include <net/inet_common.h> 7#include <net/inet_common.h>
8 8
9extern const struct udp_get_port_ops udp_ipv6_ops;
10
11extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); 9extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int );
12extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, 10extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
13 int , int , int , __be32 , struct hlist_head []); 11 int , int , int , __be32 , struct hlist_head []);
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index c40a51362f89..f54016a55004 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = {
37 37
38static int udplite_v6_get_port(struct sock *sk, unsigned short snum) 38static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
39{ 39{
40 return udplite_get_port(sk, snum, &udp_ipv6_ops); 40 return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
41} 41}
42 42
43struct proto udplitev6_prot = { 43struct proto udplitev6_prot = {
diff --git a/net/key/af_key.c b/net/key/af_key.c
index d302ddae580c..0f8304b0246b 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1682,6 +1682,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
1682 unsigned proto; 1682 unsigned proto;
1683 struct km_event c; 1683 struct km_event c;
1684 struct xfrm_audit audit_info; 1684 struct xfrm_audit audit_info;
1685 int err;
1685 1686
1686 proto = pfkey_satype2proto(hdr->sadb_msg_satype); 1687 proto = pfkey_satype2proto(hdr->sadb_msg_satype);
1687 if (proto == 0) 1688 if (proto == 0)
@@ -1689,7 +1690,9 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
1689 1690
1690 audit_info.loginuid = audit_get_loginuid(current->audit_context); 1691 audit_info.loginuid = audit_get_loginuid(current->audit_context);
1691 audit_info.secid = 0; 1692 audit_info.secid = 0;
1692 xfrm_state_flush(proto, &audit_info); 1693 err = xfrm_state_flush(proto, &audit_info);
1694 if (err)
1695 return err;
1693 c.data.proto = proto; 1696 c.data.proto = proto;
1694 c.seq = hdr->sadb_msg_seq; 1697 c.seq = hdr->sadb_msg_seq;
1695 c.pid = hdr->sadb_msg_pid; 1698 c.pid = hdr->sadb_msg_pid;
@@ -2683,10 +2686,13 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2683{ 2686{
2684 struct km_event c; 2687 struct km_event c;
2685 struct xfrm_audit audit_info; 2688 struct xfrm_audit audit_info;
2689 int err;
2686 2690
2687 audit_info.loginuid = audit_get_loginuid(current->audit_context); 2691 audit_info.loginuid = audit_get_loginuid(current->audit_context);
2688 audit_info.secid = 0; 2692 audit_info.secid = 0;
2689 xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); 2693 err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
2694 if (err)
2695 return err;
2690 c.data.type = XFRM_POLICY_TYPE_MAIN; 2696 c.data.type = XFRM_POLICY_TYPE_MAIN;
2691 c.event = XFRM_MSG_FLUSHPOLICY; 2697 c.event = XFRM_MSG_FLUSHPOLICY;
2692 c.pid = hdr->sadb_msg_pid; 2698 c.pid = hdr->sadb_msg_pid;
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index b8869eab7650..0568f2e86b59 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -208,13 +208,14 @@ static int __init nf_conntrack_amanda_init(void)
208{ 208{
209 int ret, i; 209 int ret, i;
210 210
211 ret = -ENOMEM;
212 for (i = 0; i < ARRAY_SIZE(search); i++) { 211 for (i = 0; i < ARRAY_SIZE(search); i++) {
213 search[i].ts = textsearch_prepare(ts_algo, search[i].string, 212 search[i].ts = textsearch_prepare(ts_algo, search[i].string,
214 search[i].len, 213 search[i].len,
215 GFP_KERNEL, TS_AUTOLOAD); 214 GFP_KERNEL, TS_AUTOLOAD);
216 if (search[i].ts == NULL) 215 if (IS_ERR(search[i].ts)) {
216 ret = PTR_ERR(search[i].ts);
217 goto err1; 217 goto err1;
218 }
218 } 219 }
219 ret = nf_conntrack_helper_register(&amanda_helper[0]); 220 ret = nf_conntrack_helper_register(&amanda_helper[0]);
220 if (ret < 0) 221 if (ret < 0)
@@ -227,10 +228,9 @@ static int __init nf_conntrack_amanda_init(void)
227err2: 228err2:
228 nf_conntrack_helper_unregister(&amanda_helper[0]); 229 nf_conntrack_helper_unregister(&amanda_helper[0]);
229err1: 230err1:
230 for (; i >= 0; i--) { 231 while (--i >= 0)
231 if (search[i].ts) 232 textsearch_destroy(search[i].ts);
232 textsearch_destroy(search[i].ts); 233
233 }
234 return ret; 234 return ret;
235} 235}
236 236
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 483e927a9ca4..7a15e30356f2 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -350,9 +350,15 @@ static void death_by_timeout(unsigned long ul_conntrack)
350{ 350{
351 struct nf_conn *ct = (void *)ul_conntrack; 351 struct nf_conn *ct = (void *)ul_conntrack;
352 struct nf_conn_help *help = nfct_help(ct); 352 struct nf_conn_help *help = nfct_help(ct);
353 struct nf_conntrack_helper *helper;
353 354
354 if (help && help->helper && help->helper->destroy) 355 if (help) {
355 help->helper->destroy(ct); 356 rcu_read_lock();
357 helper = rcu_dereference(help->helper);
358 if (helper && helper->destroy)
359 helper->destroy(ct);
360 rcu_read_unlock();
361 }
356 362
357 write_lock_bh(&nf_conntrack_lock); 363 write_lock_bh(&nf_conntrack_lock);
358 /* Inside lock so preempt is disabled on module removal path. 364 /* Inside lock so preempt is disabled on module removal path.
@@ -661,6 +667,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
661 unsigned int dataoff) 667 unsigned int dataoff)
662{ 668{
663 struct nf_conn *conntrack; 669 struct nf_conn *conntrack;
670 struct nf_conn_help *help;
664 struct nf_conntrack_tuple repl_tuple; 671 struct nf_conntrack_tuple repl_tuple;
665 struct nf_conntrack_expect *exp; 672 struct nf_conntrack_expect *exp;
666 u_int32_t features = 0; 673 u_int32_t features = 0;
@@ -691,6 +698,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
691 write_lock_bh(&nf_conntrack_lock); 698 write_lock_bh(&nf_conntrack_lock);
692 exp = find_expectation(tuple); 699 exp = find_expectation(tuple);
693 700
701 help = nfct_help(conntrack);
694 if (exp) { 702 if (exp) {
695 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", 703 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
696 conntrack, exp); 704 conntrack, exp);
@@ -698,7 +706,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
698 __set_bit(IPS_EXPECTED_BIT, &conntrack->status); 706 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
699 conntrack->master = exp->master; 707 conntrack->master = exp->master;
700 if (exp->helper) 708 if (exp->helper)
701 nfct_help(conntrack)->helper = exp->helper; 709 rcu_assign_pointer(help->helper, exp->helper);
702#ifdef CONFIG_NF_CONNTRACK_MARK 710#ifdef CONFIG_NF_CONNTRACK_MARK
703 conntrack->mark = exp->master->mark; 711 conntrack->mark = exp->master->mark;
704#endif 712#endif
@@ -708,10 +716,11 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
708 nf_conntrack_get(&conntrack->master->ct_general); 716 nf_conntrack_get(&conntrack->master->ct_general);
709 NF_CT_STAT_INC(expect_new); 717 NF_CT_STAT_INC(expect_new);
710 } else { 718 } else {
711 struct nf_conn_help *help = nfct_help(conntrack); 719 if (help) {
712 720 /* not in hash table yet, so not strictly necessary */
713 if (help) 721 rcu_assign_pointer(help->helper,
714 help->helper = __nf_ct_helper_find(&repl_tuple); 722 __nf_ct_helper_find(&repl_tuple));
723 }
715 NF_CT_STAT_INC(new); 724 NF_CT_STAT_INC(new);
716 } 725 }
717 726
@@ -893,7 +902,8 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
893 helper = __nf_ct_helper_find(newreply); 902 helper = __nf_ct_helper_find(newreply);
894 if (helper) 903 if (helper)
895 memset(&help->help, 0, sizeof(help->help)); 904 memset(&help->help, 0, sizeof(help->help));
896 help->helper = helper; 905 /* not in hash table yet, so not strictly necessary */
906 rcu_assign_pointer(help->helper, helper);
897 } 907 }
898 write_unlock_bh(&nf_conntrack_lock); 908 write_unlock_bh(&nf_conntrack_lock);
899} 909}
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 117cbfdb910c..504fb6c083f9 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -337,6 +337,10 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
337 NF_CT_ASSERT(master_help); 337 NF_CT_ASSERT(master_help);
338 338
339 write_lock_bh(&nf_conntrack_lock); 339 write_lock_bh(&nf_conntrack_lock);
340 if (!master_help->helper) {
341 ret = -ESHUTDOWN;
342 goto out;
343 }
340 list_for_each_entry(i, &nf_conntrack_expect_list, list) { 344 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
341 if (expect_matches(i, expect)) { 345 if (expect_matches(i, expect)) {
342 /* Refresh timer: if it's dying, ignore.. */ 346 /* Refresh timer: if it's dying, ignore.. */
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 0743be4434b0..f868b7fbd9b4 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -93,7 +93,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,
93 93
94 if (help && help->helper == me) { 94 if (help && help->helper == me) {
95 nf_conntrack_event(IPCT_HELPER, ct); 95 nf_conntrack_event(IPCT_HELPER, ct);
96 help->helper = NULL; 96 rcu_assign_pointer(help->helper, NULL);
97 } 97 }
98 return 0; 98 return 0;
99} 99}
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index d6d39e241327..3f73327794ab 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -171,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
171{ 171{
172 struct nfattr *nest_helper; 172 struct nfattr *nest_helper;
173 const struct nf_conn_help *help = nfct_help(ct); 173 const struct nf_conn_help *help = nfct_help(ct);
174 struct nf_conntrack_helper *helper;
174 175
175 if (!help || !help->helper) 176 if (!help)
176 return 0; 177 return 0;
177 178
179 rcu_read_lock();
180 helper = rcu_dereference(help->helper);
181 if (!helper)
182 goto out;
183
178 nest_helper = NFA_NEST(skb, CTA_HELP); 184 nest_helper = NFA_NEST(skb, CTA_HELP);
179 NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name); 185 NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name);
180 186
181 if (help->helper->to_nfattr) 187 if (helper->to_nfattr)
182 help->helper->to_nfattr(skb, ct); 188 helper->to_nfattr(skb, ct);
183 189
184 NFA_NEST_END(skb, nest_helper); 190 NFA_NEST_END(skb, nest_helper);
185 191out:
192 rcu_read_unlock();
186 return 0; 193 return 0;
187 194
188nfattr_failure: 195nfattr_failure:
196 rcu_read_unlock();
189 return -1; 197 return -1;
190} 198}
191 199
@@ -842,7 +850,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
842 if (help && help->helper) { 850 if (help && help->helper) {
843 /* we had a helper before ... */ 851 /* we had a helper before ... */
844 nf_ct_remove_expectations(ct); 852 nf_ct_remove_expectations(ct);
845 help->helper = NULL; 853 rcu_assign_pointer(help->helper, NULL);
846 } 854 }
847 855
848 return 0; 856 return 0;
@@ -866,7 +874,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
866 874
867 /* need to zero data of old helper */ 875 /* need to zero data of old helper */
868 memset(&help->help, 0, sizeof(help->help)); 876 memset(&help->help, 0, sizeof(help->help));
869 help->helper = helper; 877 rcu_assign_pointer(help->helper, helper);
870 878
871 return 0; 879 return 0;
872} 880}
@@ -950,6 +958,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
950 struct nf_conn *ct; 958 struct nf_conn *ct;
951 int err = -EINVAL; 959 int err = -EINVAL;
952 struct nf_conn_help *help; 960 struct nf_conn_help *help;
961 struct nf_conntrack_helper *helper = NULL;
953 962
954 ct = nf_conntrack_alloc(otuple, rtuple); 963 ct = nf_conntrack_alloc(otuple, rtuple);
955 if (ct == NULL || IS_ERR(ct)) 964 if (ct == NULL || IS_ERR(ct))
@@ -980,14 +989,17 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
980#endif 989#endif
981 990
982 help = nfct_help(ct); 991 help = nfct_help(ct);
983 if (help) 992 if (help) {
984 help->helper = nf_ct_helper_find_get(rtuple); 993 helper = nf_ct_helper_find_get(rtuple);
994 /* not in hash table yet so not strictly necessary */
995 rcu_assign_pointer(help->helper, helper);
996 }
985 997
986 add_timer(&ct->timeout); 998 add_timer(&ct->timeout);
987 nf_conntrack_hash_insert(ct); 999 nf_conntrack_hash_insert(ct);
988 1000
989 if (help && help->helper) 1001 if (helper)
990 nf_ct_helper_put(help->helper); 1002 nf_ct_helper_put(helper);
991 1003
992 return 0; 1004 return 0;
993 1005
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 5434472420fe..339c397d1b5f 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -100,7 +100,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
100 struct nf_conn_help *help = nfct_help(ct); 100 struct nf_conn_help *help = nfct_help(ct);
101 struct nf_ct_gre_keymap **kmp, *km; 101 struct nf_ct_gre_keymap **kmp, *km;
102 102
103 BUG_ON(strcmp(help->helper->name, "pptp"));
104 kmp = &help->help.ct_pptp_info.keymap[dir]; 103 kmp = &help->help.ct_pptp_info.keymap[dir];
105 if (*kmp) { 104 if (*kmp) {
106 /* check whether it's a retransmission */ 105 /* check whether it's a retransmission */
@@ -137,7 +136,6 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
137 enum ip_conntrack_dir dir; 136 enum ip_conntrack_dir dir;
138 137
139 DEBUGP("entering for ct %p\n", ct); 138 DEBUGP("entering for ct %p\n", ct);
140 BUG_ON(strcmp(help->helper->name, "pptp"));
141 139
142 write_lock_bh(&nf_ct_gre_lock); 140 write_lock_bh(&nf_ct_gre_lock);
143 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { 141 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 07e47dbcb0a9..24b660f16ce3 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -59,7 +59,7 @@ static struct genl_family netlbl_cipsov4_gnl_family = {
59}; 59};
60 60
61/* NetLabel Netlink attribute policy */ 61/* NetLabel Netlink attribute policy */
62static struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { 62static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
63 [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 }, 63 [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 },
64 [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 }, 64 [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 },
65 [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 }, 65 [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 },
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index e8c80f33f3d7..e00fc219c72b 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -59,7 +59,7 @@ static struct genl_family netlbl_mgmt_gnl_family = {
59}; 59};
60 60
61/* NetLabel Netlink attribute policy */ 61/* NetLabel Netlink attribute policy */
62static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { 62static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
63 [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING }, 63 [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING },
64 [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 }, 64 [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 },
65 [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 }, 65 [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 },
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index b931edee4b8b..5c303c68af1d 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -61,7 +61,7 @@ static struct genl_family netlbl_unlabel_gnl_family = {
61}; 61};
62 62
63/* NetLabel Netlink attribute policy */ 63/* NetLabel Netlink attribute policy */
64static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { 64static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
65 [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, 65 [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
66}; 66};
67 67
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
index df5f820a4c32..c591212793ee 100644
--- a/net/netlink/attr.c
+++ b/net/netlink/attr.c
@@ -24,9 +24,9 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
24}; 24};
25 25
26static int validate_nla(struct nlattr *nla, int maxtype, 26static int validate_nla(struct nlattr *nla, int maxtype,
27 struct nla_policy *policy) 27 const struct nla_policy *policy)
28{ 28{
29 struct nla_policy *pt; 29 const struct nla_policy *pt;
30 int minlen = 0, attrlen = nla_len(nla); 30 int minlen = 0, attrlen = nla_len(nla);
31 31
32 if (nla->nla_type <= 0 || nla->nla_type > maxtype) 32 if (nla->nla_type <= 0 || nla->nla_type > maxtype)
@@ -99,7 +99,7 @@ static int validate_nla(struct nlattr *nla, int maxtype,
99 * Returns 0 on success or a negative error code. 99 * Returns 0 on success or a negative error code.
100 */ 100 */
101int nla_validate(struct nlattr *head, int len, int maxtype, 101int nla_validate(struct nlattr *head, int len, int maxtype,
102 struct nla_policy *policy) 102 const struct nla_policy *policy)
103{ 103{
104 struct nlattr *nla; 104 struct nlattr *nla;
105 int rem, err; 105 int rem, err;
@@ -130,7 +130,7 @@ errout:
130 * Returns 0 on success or a negative error code. 130 * Returns 0 on success or a negative error code.
131 */ 131 */
132int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, 132int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
133 struct nla_policy *policy) 133 const struct nla_policy *policy)
134{ 134{
135 struct nlattr *nla; 135 struct nlattr *nla;
136 int rem, err; 136 int rem, err;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 6e31234a4196..b9ab62f938d0 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -472,7 +472,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
472 return skb; 472 return skb;
473} 473}
474 474
475static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = { 475static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
476 [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, 476 [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
477 [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, 477 [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
478 .len = GENL_NAMSIZ - 1 }, 478 .len = GENL_NAMSIZ - 1 },
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index be7d299acd73..d1c383fca82c 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -599,6 +599,7 @@ static void atm_tc_destroy(struct Qdisc *sch)
599 /* races ? */ 599 /* races ? */
600 while ((flow = p->flows)) { 600 while ((flow = p->flows)) {
601 tcf_destroy_chain(flow->filter_list); 601 tcf_destroy_chain(flow->filter_list);
602 flow->filter_list = NULL;
602 if (flow->ref > 1) 603 if (flow->ref > 1)
603 printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, 604 printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
604 flow->ref); 605 flow->ref);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index a294542cb8e4..ee2d5967d109 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1748,10 +1748,12 @@ cbq_destroy(struct Qdisc* sch)
1748 * classes from root to leafs which means that filters can still 1748 * classes from root to leafs which means that filters can still
1749 * be bound to classes which have been destroyed already. --TGR '04 1749 * be bound to classes which have been destroyed already. --TGR '04
1750 */ 1750 */
1751 for (h = 0; h < 16; h++) 1751 for (h = 0; h < 16; h++) {
1752 for (cl = q->classes[h]; cl; cl = cl->next) 1752 for (cl = q->classes[h]; cl; cl = cl->next) {
1753 tcf_destroy_chain(cl->filter_list); 1753 tcf_destroy_chain(cl->filter_list);
1754 1754 cl->filter_list = NULL;
1755 }
1756 }
1755 for (h = 0; h < 16; h++) { 1757 for (h = 0; h < 16; h++) {
1756 struct cbq_class *next; 1758 struct cbq_class *next;
1757 1759
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 87c794d8fa2d..d70fa30d4294 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1744,20 +1744,23 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1744 int chunk; 1744 int chunk;
1745 struct sk_buff *skb; 1745 struct sk_buff *skb;
1746 1746
1747 unix_state_lock(sk);
1747 skb = skb_dequeue(&sk->sk_receive_queue); 1748 skb = skb_dequeue(&sk->sk_receive_queue);
1748 if (skb==NULL) 1749 if (skb==NULL)
1749 { 1750 {
1750 if (copied >= target) 1751 if (copied >= target)
1751 break; 1752 goto unlock;
1752 1753
1753 /* 1754 /*
1754 * POSIX 1003.1g mandates this order. 1755 * POSIX 1003.1g mandates this order.
1755 */ 1756 */
1756 1757
1757 if ((err = sock_error(sk)) != 0) 1758 if ((err = sock_error(sk)) != 0)
1758 break; 1759 goto unlock;
1759 if (sk->sk_shutdown & RCV_SHUTDOWN) 1760 if (sk->sk_shutdown & RCV_SHUTDOWN)
1760 break; 1761 goto unlock;
1762
1763 unix_state_unlock(sk);
1761 err = -EAGAIN; 1764 err = -EAGAIN;
1762 if (!timeo) 1765 if (!timeo)
1763 break; 1766 break;
@@ -1771,7 +1774,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1771 } 1774 }
1772 mutex_lock(&u->readlock); 1775 mutex_lock(&u->readlock);
1773 continue; 1776 continue;
1777 unlock:
1778 unix_state_unlock(sk);
1779 break;
1774 } 1780 }
1781 unix_state_unlock(sk);
1775 1782
1776 if (check_creds) { 1783 if (check_creds) {
1777 /* Never glue messages from different writers */ 1784 /* Never glue messages from different writers */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 64a375178c5f..157bfbd250ba 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -834,11 +834,67 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
834} 834}
835EXPORT_SYMBOL(xfrm_policy_byid); 835EXPORT_SYMBOL(xfrm_policy_byid);
836 836
837void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) 837#ifdef CONFIG_SECURITY_NETWORK_XFRM
838static inline int
839xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
838{ 840{
839 int dir; 841 int dir, err = 0;
842
843 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
844 struct xfrm_policy *pol;
845 struct hlist_node *entry;
846 int i;
847
848 hlist_for_each_entry(pol, entry,
849 &xfrm_policy_inexact[dir], bydst) {
850 if (pol->type != type)
851 continue;
852 err = security_xfrm_policy_delete(pol);
853 if (err) {
854 xfrm_audit_log(audit_info->loginuid,
855 audit_info->secid,
856 AUDIT_MAC_IPSEC_DELSPD, 0,
857 pol, NULL);
858 return err;
859 }
860 }
861 for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
862 hlist_for_each_entry(pol, entry,
863 xfrm_policy_bydst[dir].table + i,
864 bydst) {
865 if (pol->type != type)
866 continue;
867 err = security_xfrm_policy_delete(pol);
868 if (err) {
869 xfrm_audit_log(audit_info->loginuid,
870 audit_info->secid,
871 AUDIT_MAC_IPSEC_DELSPD,
872 0, pol, NULL);
873 return err;
874 }
875 }
876 }
877 }
878 return err;
879}
880#else
881static inline int
882xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
883{
884 return 0;
885}
886#endif
887
888int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
889{
890 int dir, err = 0;
840 891
841 write_lock_bh(&xfrm_policy_lock); 892 write_lock_bh(&xfrm_policy_lock);
893
894 err = xfrm_policy_flush_secctx_check(type, audit_info);
895 if (err)
896 goto out;
897
842 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { 898 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
843 struct xfrm_policy *pol; 899 struct xfrm_policy *pol;
844 struct hlist_node *entry; 900 struct hlist_node *entry;
@@ -891,7 +947,9 @@ void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
891 xfrm_policy_count[dir] -= killed; 947 xfrm_policy_count[dir] -= killed;
892 } 948 }
893 atomic_inc(&flow_cache_genid); 949 atomic_inc(&flow_cache_genid);
950out:
894 write_unlock_bh(&xfrm_policy_lock); 951 write_unlock_bh(&xfrm_policy_lock);
952 return err;
895} 953}
896EXPORT_SYMBOL(xfrm_policy_flush); 954EXPORT_SYMBOL(xfrm_policy_flush);
897 955
@@ -2583,4 +2641,3 @@ restore_state:
2583} 2641}
2584EXPORT_SYMBOL(xfrm_migrate); 2642EXPORT_SYMBOL(xfrm_migrate);
2585#endif 2643#endif
2586
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 372f06eb8bb7..85f3f43a6cca 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -391,12 +391,48 @@ int xfrm_state_delete(struct xfrm_state *x)
391} 391}
392EXPORT_SYMBOL(xfrm_state_delete); 392EXPORT_SYMBOL(xfrm_state_delete);
393 393
394void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) 394#ifdef CONFIG_SECURITY_NETWORK_XFRM
395static inline int
396xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
395{ 397{
396 int i; 398 int i, err = 0;
397 int err = 0; 399
400 for (i = 0; i <= xfrm_state_hmask; i++) {
401 struct hlist_node *entry;
402 struct xfrm_state *x;
403
404 hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
405 if (xfrm_id_proto_match(x->id.proto, proto) &&
406 (err = security_xfrm_state_delete(x)) != 0) {
407 xfrm_audit_log(audit_info->loginuid,
408 audit_info->secid,
409 AUDIT_MAC_IPSEC_DELSA,
410 0, NULL, x);
411
412 return err;
413 }
414 }
415 }
416
417 return err;
418}
419#else
420static inline int
421xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
422{
423 return 0;
424}
425#endif
426
427int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
428{
429 int i, err = 0;
398 430
399 spin_lock_bh(&xfrm_state_lock); 431 spin_lock_bh(&xfrm_state_lock);
432 err = xfrm_state_flush_secctx_check(proto, audit_info);
433 if (err)
434 goto out;
435
400 for (i = 0; i <= xfrm_state_hmask; i++) { 436 for (i = 0; i <= xfrm_state_hmask; i++) {
401 struct hlist_node *entry; 437 struct hlist_node *entry;
402 struct xfrm_state *x; 438 struct xfrm_state *x;
@@ -419,8 +455,12 @@ restart:
419 } 455 }
420 } 456 }
421 } 457 }
458 err = 0;
459
460out:
422 spin_unlock_bh(&xfrm_state_lock); 461 spin_unlock_bh(&xfrm_state_lock);
423 wake_up(&km_waitq); 462 wake_up(&km_waitq);
463 return err;
424} 464}
425EXPORT_SYMBOL(xfrm_state_flush); 465EXPORT_SYMBOL(xfrm_state_flush);
426 466
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b14c7e590c31..c06883bf620e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1418,10 +1418,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
1418 struct km_event c; 1418 struct km_event c;
1419 struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); 1419 struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
1420 struct xfrm_audit audit_info; 1420 struct xfrm_audit audit_info;
1421 int err;
1421 1422
1422 audit_info.loginuid = NETLINK_CB(skb).loginuid; 1423 audit_info.loginuid = NETLINK_CB(skb).loginuid;
1423 audit_info.secid = NETLINK_CB(skb).sid; 1424 audit_info.secid = NETLINK_CB(skb).sid;
1424 xfrm_state_flush(p->proto, &audit_info); 1425 err = xfrm_state_flush(p->proto, &audit_info);
1426 if (err)
1427 return err;
1425 c.data.proto = p->proto; 1428 c.data.proto = p->proto;
1426 c.event = nlh->nlmsg_type; 1429 c.event = nlh->nlmsg_type;
1427 c.seq = nlh->nlmsg_seq; 1430 c.seq = nlh->nlmsg_seq;
@@ -1582,7 +1585,9 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1582 1585
1583 audit_info.loginuid = NETLINK_CB(skb).loginuid; 1586 audit_info.loginuid = NETLINK_CB(skb).loginuid;
1584 audit_info.secid = NETLINK_CB(skb).sid; 1587 audit_info.secid = NETLINK_CB(skb).sid;
1585 xfrm_policy_flush(type, &audit_info); 1588 err = xfrm_policy_flush(type, &audit_info);
1589 if (err)
1590 return err;
1586 c.data.type = type; 1591 c.data.type = type;
1587 c.event = nlh->nlmsg_type; 1592 c.event = nlh->nlmsg_type;
1588 c.seq = nlh->nlmsg_seq; 1593 c.seq = nlh->nlmsg_seq;