diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-07 20:08:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-07 20:08:06 -0400 |
commit | df3872a9664667edae729361c9948b652de5c6f4 (patch) | |
tree | d191c1e6413f82b7a3f074a29b2d1fb92476d30f | |
parent | e5e3c84b70e58fc605635fd340fb8dba3cc59058 (diff) | |
parent | 4aa2e62c45b5ca08be2d0d3c0744d7585b56e860 (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.
...
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 | ||
11 | struct ipv4_devconf | 12 | struct 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 | ||
37 | extern struct ipv4_devconf ipv4_devconf; | 19 | extern 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) | 48 | static 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) | 54 | static 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 | |||
62 | static 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 | ||
88 | struct in_ifaddr | 110 | struct in_ifaddr |
89 | { | 111 | { |
@@ -108,7 +130,6 @@ extern struct net_device *ip_dev_find(__be32 addr); | |||
108 | extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); | 130 | extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); |
109 | extern int devinet_ioctl(unsigned int cmd, void __user *); | 131 | extern int devinet_ioctl(unsigned int cmd, void __user *); |
110 | extern void devinet_init(void); | 132 | extern void devinet_init(void); |
111 | extern struct in_device *inetdev_init(struct net_device *dev); | ||
112 | extern struct in_device *inetdev_by_index(int); | 133 | extern struct in_device *inetdev_by_index(int); |
113 | extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); | 134 | extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); |
114 | extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope); | 135 | extern __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 | */ |
65 | struct rfkill { | 65 | struct 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 | ||
148 | void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, | 149 | void 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 */ |
216 | extern struct nla_policy rtm_ipv4_policy[]; | 216 | extern const struct nla_policy rtm_ipv4_policy[]; |
217 | extern void ip_fib_init(void); | 217 | extern void ip_fib_init(void); |
218 | extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | 218 | extern 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 | ||
224 | extern int nla_validate(struct nlattr *head, int len, int maxtype, | 224 | extern int nla_validate(struct nlattr *head, int len, int maxtype, |
225 | struct nla_policy *policy); | 225 | const struct nla_policy *policy); |
226 | extern int nla_parse(struct nlattr *tb[], int maxtype, | 226 | extern 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); |
229 | extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype); | 229 | extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype); |
230 | extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, | 230 | extern 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 | */ |
361 | static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, | 361 | static 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 | */ |
394 | static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, | 394 | static 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 | */ |
730 | static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, | 730 | static 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 | */ |
992 | static inline int nla_validate_nested(struct nlattr *start, int maxtype, | 992 | static 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 | ||
122 | struct 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 */ |
130 | extern int udp_get_port(struct sock *sk, unsigned short snum, | 123 | extern 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 *)); |
132 | extern void udp_err(struct sk_buff *, u32); | 125 | extern void udp_err(struct sk_buff *, u32); |
133 | 126 | ||
134 | extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, | 127 | extern 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 | ||
121 | extern void udplite4_register(void); | 121 | extern void udplite4_register(void); |
122 | extern int udplite_get_port(struct sock *sk, unsigned short snum, | 122 | extern 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 | ||
965 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); | 965 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); |
966 | extern int xfrm_state_delete(struct xfrm_state *x); | 966 | extern int xfrm_state_delete(struct xfrm_state *x); |
967 | extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); | 967 | extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); |
968 | extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); | 968 | extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); |
969 | extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si); | 969 | extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si); |
970 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); | 970 | extern 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); |
1022 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err); | 1022 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err); |
1023 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); | 1023 | int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
1024 | u32 xfrm_get_acqseq(void); | 1024 | u32 xfrm_get_acqseq(void); |
1025 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); | 1025 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); |
1026 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | 1026 | struct 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); |
1029 | extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); | 1029 | extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
1030 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 1030 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
1031 | extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, | 1031 | extern 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 | ||
2578 | int dev_change_flags(struct net_device *dev, unsigned flags) | 2578 | int 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 | ||
114 | static int dst_discard_in(struct sk_buff *skb) | 114 | static int dst_discard(struct sk_buff *skb) |
115 | { | ||
116 | kfree_skb(skb); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static 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 | ||
1764 | static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { | 1764 | static 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 | ||
1773 | static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = { | 1773 | static 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 | ||
554 | static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = { | 554 | static 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 | ||
641 | static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { | 641 | static 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 | ||
111 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { | 111 | static 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 | ||
66 | struct ipv4_devconf ipv4_devconf = { | 66 | struct 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 | ||
73 | static struct ipv4_devconf ipv4_devconf_dflt = { | 75 | static 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 | ||
81 | static struct nla_policy ifa_ipv4_policy[IFA_MAX+1] __read_mostly = { | 85 | #define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr) |
86 | |||
87 | static 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 | ||
144 | struct in_device *inetdev_init(struct net_device *dev) | 150 | static 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 | ||
1244 | static 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 | |||
1260 | static 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 | |||
1279 | static 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 | |||
1240 | void inet_forward_change(void) | 1329 | void 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 | ||
1335 | static struct devinet_sysctl_table { | 1425 | static 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 | ||
444 | struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = { | 444 | const 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 | ||
172 | static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { | 172 | static 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 | ||
140 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); | 142 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); |
141 | static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); | 143 | static 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 | ||
501 | static inline int check_match(struct ipt_entry_match *m, const char *name, | 501 | static 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; |
546 | err: | 548 | err: |
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 | ||
1427 | static inline int | 1429 | static inline int |
1428 | compat_check_calc_match(struct ipt_entry_match *m, | 1430 | compat_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 | ||
1451 | static inline int | 1453 | static inline int |
1454 | compat_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 | |||
1463 | static inline int | ||
1464 | compat_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 | |||
1478 | static inline int | ||
1452 | check_compat_entry_size_and_hooks(struct ipt_entry *e, | 1479 | check_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 | ||
1527 | out: | 1554 | out: |
1528 | module_put(t->u.kernel.target->me); | 1555 | module_put(t->u.kernel.target->me); |
1529 | cleanup_matches: | 1556 | release_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 | ||
1577 | static inline int compat_check_entry(struct ipt_entry *e, const char *name) | 1604 | static 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 | ||
1588 | static int | 1626 | static 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, | |||
1691 | free_newinfo: | 1736 | free_newinfo: |
1692 | xt_free_table_info(newinfo); | 1737 | xt_free_table_info(newinfo); |
1693 | out: | 1738 | out: |
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; |
1696 | out_unlock: | 1741 | out_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 | ||
151 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | 154 | static 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 | |||
37 | int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, | 37 | int 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 | */ |
65 | static void printl(const char *fmt, ...) | 65 | static void printl(const char *fmt, ...) |
66 | __attribute__ ((format (printf, 1, 2))); | ||
67 | |||
68 | static 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 | ||
115 | static int udp_port_rover; | 115 | static int udp_port_rover; |
116 | 116 | ||
117 | /* | 117 | static 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 | */ | ||
121 | static inline unsigned int udp_hash_port(__u16 port) | ||
122 | { | ||
123 | return port; | ||
124 | } | ||
125 | |||
126 | static 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 | */ |
159 | int __udp_lib_get_port(struct sock *sk, unsigned short snum, | 137 | int __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, | |||
221 | gotit: | 189 | gotit: |
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 | ||
267 | int udp_get_port(struct sock *sk, unsigned short snum, | 216 | int 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 | ||
273 | static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | 222 | int 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 | ||
282 | static int ipv4_rcv_saddr_any(const struct sock *sk) | ||
283 | { | ||
284 | return !inet_sk(sk)->rcv_saddr; | ||
285 | } | ||
286 | |||
287 | static 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 | |||
294 | static 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 | |||
300 | const 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 | |||
306 | static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) | 231 | static 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)]) { | |
328 | lookup: | ||
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 | } | ||
371 | found: | ||
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 | ||
378 | static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum, | 289 | static 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 | ||
8 | extern const struct udp_get_port_ops udp_ipv4_ops; | ||
9 | |||
10 | extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); | 8 | extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); |
11 | extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); | 9 | extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); |
12 | 10 | ||
13 | extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, | 11 | extern 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*)); |
14 | extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *); | ||
15 | |||
16 | 16 | ||
17 | extern int udp_setsockopt(struct sock *sk, int level, int optname, | 17 | extern 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]; | |||
19 | static int udplite_port_rover; | 19 | static int udplite_port_rover; |
20 | 20 | ||
21 | int udplite_get_port(struct sock *sk, unsigned short p, | 21 | int 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 | ||
28 | static int udplite_v4_get_port(struct sock *sk, unsigned short snum) | 27 | static 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 | ||
33 | static int udplite_rcv(struct sk_buff *skb) | 32 | static 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 | ||
2993 | static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = { | 2993 | static 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 | ||
160 | static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { | 160 | static 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; |
188 | out: | 193 | out: |
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 | ||
2002 | static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = { | 2002 | static 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 | ||
53 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; | 53 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; |
54 | 54 | ||
55 | static 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 | |||
62 | static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port, | ||
63 | const struct sock *sk) | ||
64 | { | ||
65 | return port; | ||
66 | } | ||
67 | |||
68 | const 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 | |||
74 | static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) | 55 | static 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 | ||
79 | static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, | 60 | static 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 | ||
9 | extern const struct udp_get_port_ops udp_ipv6_ops; | ||
10 | |||
11 | extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); | 9 | extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); |
12 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, | 10 | extern 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 | ||
38 | static int udplite_v6_get_port(struct sock *sk, unsigned short snum) | 38 | static 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 | ||
43 | struct proto udplitev6_prot = { | 43 | struct 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) | |||
227 | err2: | 228 | err2: |
228 | nf_conntrack_helper_unregister(&amanda_helper[0]); | 229 | nf_conntrack_helper_unregister(&amanda_helper[0]); |
229 | err1: | 230 | err1: |
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 | 191 | out: | |
192 | rcu_read_unlock(); | ||
186 | return 0; | 193 | return 0; |
187 | 194 | ||
188 | nfattr_failure: | 195 | nfattr_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 */ |
62 | static struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { | 62 | static 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 */ |
62 | static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { | 62 | static 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 */ |
64 | static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { | 64 | static 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 | ||
26 | static int validate_nla(struct nlattr *nla, int maxtype, | 26 | static 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 | */ |
101 | int nla_validate(struct nlattr *head, int len, int maxtype, | 101 | int 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 | */ |
132 | int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, | 132 | int 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 | ||
475 | static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = { | 475 | static 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 | } |
835 | EXPORT_SYMBOL(xfrm_policy_byid); | 835 | EXPORT_SYMBOL(xfrm_policy_byid); |
836 | 836 | ||
837 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | 837 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
838 | static inline int | ||
839 | xfrm_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 | ||
881 | static inline int | ||
882 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
883 | { | ||
884 | return 0; | ||
885 | } | ||
886 | #endif | ||
887 | |||
888 | int 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); |
950 | out: | ||
894 | write_unlock_bh(&xfrm_policy_lock); | 951 | write_unlock_bh(&xfrm_policy_lock); |
952 | return err; | ||
895 | } | 953 | } |
896 | EXPORT_SYMBOL(xfrm_policy_flush); | 954 | EXPORT_SYMBOL(xfrm_policy_flush); |
897 | 955 | ||
@@ -2583,4 +2641,3 @@ restore_state: | |||
2583 | } | 2641 | } |
2584 | EXPORT_SYMBOL(xfrm_migrate); | 2642 | EXPORT_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 | } |
392 | EXPORT_SYMBOL(xfrm_state_delete); | 392 | EXPORT_SYMBOL(xfrm_state_delete); |
393 | 393 | ||
394 | void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | 394 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
395 | static inline int | ||
396 | xfrm_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 | ||
420 | static inline int | ||
421 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
422 | { | ||
423 | return 0; | ||
424 | } | ||
425 | #endif | ||
426 | |||
427 | int 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 | |||
460 | out: | ||
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 | } |
425 | EXPORT_SYMBOL(xfrm_state_flush); | 465 | EXPORT_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; |