aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c8
-rw-r--r--net/core/dst.c17
-rw-r--r--net/core/neighbour.c4
-rw-r--r--net/core/rtnetlink.c8
-rw-r--r--net/decnet/dn_dev.c2
-rw-r--r--net/decnet/dn_rules.c2
-rw-r--r--net/ipv4/arp.c11
-rw-r--r--net/ipv4/cipso_ipv4.c64
-rw-r--r--net/ipv4/devinet.c415
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/fib_rules.c2
-rw-r--r--net/ipv4/igmp.c18
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/ipmr.c23
-rw-r--r--net/ipv4/netfilter/ip_tables.c81
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c13
-rw-r--r--net/ipv4/proc.c2
-rw-r--r--net/ipv4/route.c14
-rw-r--r--net/ipv4/sysctl_net_ipv4.c6
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_probe.c6
-rw-r--r--net/ipv4/tcp_timer.c4
-rw-r--r--net/ipv4/udp.c241
-rw-r--r--net/ipv4/udp_impl.h6
-rw-r--r--net/ipv4/udplite.c7
-rw-r--r--net/ipv6/addrconf.c2
-rw-r--r--net/ipv6/fib6_rules.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c9
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/udp.c21
-rw-r--r--net/ipv6/udp_impl.h2
-rw-r--r--net/ipv6/udplite.c2
-rw-r--r--net/irda/irlap_event.c28
-rw-r--r--net/irda/irlap_frame.c3
-rw-r--r--net/key/af_key.c10
-rw-r--r--net/netfilter/nf_conntrack_amanda.c12
-rw-r--r--net/netfilter/nf_conntrack_core.c26
-rw-r--r--net/netfilter/nf_conntrack_expect.c4
-rw-r--r--net/netfilter/nf_conntrack_helper.c2
-rw-r--r--net/netfilter/nf_conntrack_netlink.c34
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c2
-rw-r--r--net/netlabel/netlabel_cipso_v4.c2
-rw-r--r--net/netlabel/netlabel_kapi.c43
-rw-r--r--net/netlabel/netlabel_mgmt.c2
-rw-r--r--net/netlabel/netlabel_unlabeled.c2
-rw-r--r--net/netlink/attr.c8
-rw-r--r--net/netlink/genetlink.c2
-rw-r--r--net/sched/sch_atm.c1
-rw-r--r--net/sched/sch_cbq.c8
-rw-r--r--net/unix/af_unix.c13
-rw-r--r--net/xfrm/xfrm_policy.c63
-rw-r--r--net/xfrm/xfrm_state.c46
-rw-r--r--net/xfrm/xfrm_user.c9
53 files changed, 639 insertions, 683 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 5a7f20f78574..26090621ea6b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2577,7 +2577,7 @@ unsigned dev_get_flags(const struct net_device *dev)
2577 2577
2578int dev_change_flags(struct net_device *dev, unsigned flags) 2578int dev_change_flags(struct net_device *dev, unsigned flags)
2579{ 2579{
2580 int ret; 2580 int ret, changes;
2581 int old_flags = dev->flags; 2581 int old_flags = dev->flags;
2582 2582
2583 /* 2583 /*
@@ -2632,8 +2632,10 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
2632 dev_set_allmulti(dev, inc); 2632 dev_set_allmulti(dev, inc);
2633 } 2633 }
2634 2634
2635 if (old_flags ^ dev->flags) 2635 /* Exclude state transition flags, already notified */
2636 rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags); 2636 changes = (old_flags ^ dev->flags) & ~(IFF_UP | IFF_RUNNING);
2637 if (changes)
2638 rtmsg_ifinfo(RTM_NEWLINK, dev, changes);
2637 2639
2638 return ret; 2640 return ret;
2639} 2641}
diff --git a/net/core/dst.c b/net/core/dst.c
index 764bccb3d992..c6a05879d58c 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -111,13 +111,7 @@ out:
111 spin_unlock(&dst_lock); 111 spin_unlock(&dst_lock);
112} 112}
113 113
114static int dst_discard_in(struct sk_buff *skb) 114static int dst_discard(struct sk_buff *skb)
115{
116 kfree_skb(skb);
117 return 0;
118}
119
120static int dst_discard_out(struct sk_buff *skb)
121{ 115{
122 kfree_skb(skb); 116 kfree_skb(skb);
123 return 0; 117 return 0;
@@ -138,8 +132,7 @@ void * dst_alloc(struct dst_ops * ops)
138 dst->ops = ops; 132 dst->ops = ops;
139 dst->lastuse = jiffies; 133 dst->lastuse = jiffies;
140 dst->path = dst; 134 dst->path = dst;
141 dst->input = dst_discard_in; 135 dst->input = dst->output = dst_discard;
142 dst->output = dst_discard_out;
143#if RT_CACHE_DEBUG >= 2 136#if RT_CACHE_DEBUG >= 2
144 atomic_inc(&dst_total); 137 atomic_inc(&dst_total);
145#endif 138#endif
@@ -153,8 +146,7 @@ static void ___dst_free(struct dst_entry * dst)
153 protocol module is unloaded. 146 protocol module is unloaded.
154 */ 147 */
155 if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { 148 if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
156 dst->input = dst_discard_in; 149 dst->input = dst->output = dst_discard;
157 dst->output = dst_discard_out;
158 } 150 }
159 dst->obsolete = 2; 151 dst->obsolete = 2;
160} 152}
@@ -242,8 +234,7 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
242 return; 234 return;
243 235
244 if (!unregister) { 236 if (!unregister) {
245 dst->input = dst_discard_in; 237 dst->input = dst->output = dst_discard;
246 dst->output = dst_discard_out;
247 } else { 238 } else {
248 dst->dev = &loopback_dev; 239 dst->dev = &loopback_dev;
249 dev_hold(&loopback_dev); 240 dev_hold(&loopback_dev);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 6f3bb73053c2..9df26a07f067 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1761,7 +1761,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
1761 return NULL; 1761 return NULL;
1762} 1762}
1763 1763
1764static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { 1764static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
1765 [NDTA_NAME] = { .type = NLA_STRING }, 1765 [NDTA_NAME] = { .type = NLA_STRING },
1766 [NDTA_THRESH1] = { .type = NLA_U32 }, 1766 [NDTA_THRESH1] = { .type = NLA_U32 },
1767 [NDTA_THRESH2] = { .type = NLA_U32 }, 1767 [NDTA_THRESH2] = { .type = NLA_U32 },
@@ -1770,7 +1770,7 @@ static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = {
1770 [NDTA_PARMS] = { .type = NLA_NESTED }, 1770 [NDTA_PARMS] = { .type = NLA_NESTED },
1771}; 1771};
1772 1772
1773static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = { 1773static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
1774 [NDTPA_IFINDEX] = { .type = NLA_U32 }, 1774 [NDTPA_IFINDEX] = { .type = NLA_U32 },
1775 [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, 1775 [NDTPA_QUEUE_LEN] = { .type = NLA_U32 },
1776 [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, 1776 [NDTPA_PROXY_QLEN] = { .type = NLA_U32 },
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 27da9cdec6a8..02e8bf084277 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -551,7 +551,7 @@ cont:
551 return skb->len; 551 return skb->len;
552} 552}
553 553
554static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = { 554static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
555 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, 555 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
556 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, 556 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
557 [IFLA_MTU] = { .type = NLA_U32 }, 557 [IFLA_MTU] = { .type = NLA_U32 },
@@ -580,7 +580,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
580 580
581 err = -EINVAL; 581 err = -EINVAL;
582 ifm = nlmsg_data(nlh); 582 ifm = nlmsg_data(nlh);
583 if (ifm->ifi_index >= 0) 583 if (ifm->ifi_index > 0)
584 dev = dev_get_by_index(ifm->ifi_index); 584 dev = dev_get_by_index(ifm->ifi_index);
585 else if (tb[IFLA_IFNAME]) 585 else if (tb[IFLA_IFNAME])
586 dev = dev_get_by_name(ifname); 586 dev = dev_get_by_name(ifname);
@@ -672,7 +672,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
672 * name provided implies that a name change has been 672 * name provided implies that a name change has been
673 * requested. 673 * requested.
674 */ 674 */
675 if (ifm->ifi_index >= 0 && ifname[0]) { 675 if (ifm->ifi_index > 0 && ifname[0]) {
676 err = dev_change_name(dev, ifname); 676 err = dev_change_name(dev, ifname);
677 if (err < 0) 677 if (err < 0)
678 goto errout_dev; 678 goto errout_dev;
@@ -740,7 +740,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
740 return err; 740 return err;
741 741
742 ifm = nlmsg_data(nlh); 742 ifm = nlmsg_data(nlh);
743 if (ifm->ifi_index >= 0) { 743 if (ifm->ifi_index > 0) {
744 dev = dev_get_by_index(ifm->ifi_index); 744 dev = dev_get_by_index(ifm->ifi_index);
745 if (dev == NULL) 745 if (dev == NULL)
746 return -ENODEV; 746 return -ENODEV;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 764a56a13e38..ab41c1879fd4 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -638,7 +638,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex)
638 return dn_dev; 638 return dn_dev;
639} 639}
640 640
641static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { 641static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = {
642 [IFA_ADDRESS] = { .type = NLA_U16 }, 642 [IFA_ADDRESS] = { .type = NLA_U16 },
643 [IFA_LOCAL] = { .type = NLA_U16 }, 643 [IFA_LOCAL] = { .type = NLA_U16 },
644 [IFA_LABEL] = { .type = NLA_STRING, 644 [IFA_LABEL] = { .type = NLA_STRING,
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 17a1932216d6..84ff3dd37070 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -108,7 +108,7 @@ errout:
108 return err; 108 return err;
109} 109}
110 110
111static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { 111static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = {
112 FRA_GENERIC_POLICY, 112 FRA_GENERIC_POLICY,
113}; 113};
114 114
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 7110779a0244..e00767e8ebd9 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -877,7 +877,7 @@ static int arp_process(struct sk_buff *skb)
877 877
878 n = __neigh_lookup(&arp_tbl, &sip, dev, 0); 878 n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
879 879
880 if (ipv4_devconf.arp_accept) { 880 if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) {
881 /* Unsolicited ARP is not accepted by default. 881 /* Unsolicited ARP is not accepted by default.
882 It is possible, that this option should be enabled for some 882 It is possible, that this option should be enabled for some
883 devices (strip is candidate) 883 devices (strip is candidate)
@@ -987,11 +987,11 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev)
987 return 0; 987 return 0;
988 } 988 }
989 if (dev == NULL) { 989 if (dev == NULL) {
990 ipv4_devconf.proxy_arp = 1; 990 IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
991 return 0; 991 return 0;
992 } 992 }
993 if (__in_dev_get_rtnl(dev)) { 993 if (__in_dev_get_rtnl(dev)) {
994 __in_dev_get_rtnl(dev)->cnf.proxy_arp = 1; 994 IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
995 return 0; 995 return 0;
996 } 996 }
997 return -ENXIO; 997 return -ENXIO;
@@ -1093,11 +1093,12 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev)
1093 return pneigh_delete(&arp_tbl, &ip, dev); 1093 return pneigh_delete(&arp_tbl, &ip, dev);
1094 if (mask == 0) { 1094 if (mask == 0) {
1095 if (dev == NULL) { 1095 if (dev == NULL) {
1096 ipv4_devconf.proxy_arp = 0; 1096 IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
1097 return 0; 1097 return 0;
1098 } 1098 }
1099 if (__in_dev_get_rtnl(dev)) { 1099 if (__in_dev_get_rtnl(dev)) {
1100 __in_dev_get_rtnl(dev)->cnf.proxy_arp = 0; 1100 IN_DEV_CONF_SET(__in_dev_get_rtnl(dev),
1101 PROXY_ARP, 0);
1101 return 0; 1102 return 0;
1102 } 1103 }
1103 return -ENXIO; 1104 return -ENXIO;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 86a2b52aad38..ab56a052ce31 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -45,6 +45,7 @@
45#include <net/cipso_ipv4.h> 45#include <net/cipso_ipv4.h>
46#include <asm/atomic.h> 46#include <asm/atomic.h>
47#include <asm/bug.h> 47#include <asm/bug.h>
48#include <asm/unaligned.h>
48 49
49struct cipso_v4_domhsh_entry { 50struct cipso_v4_domhsh_entry {
50 char *domain; 51 char *domain;
@@ -1000,7 +1001,7 @@ static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def,
1000 return -EFAULT; 1001 return -EFAULT;
1001 1002
1002 for (iter = 0; iter < enumcat_len; iter += 2) { 1003 for (iter = 0; iter < enumcat_len; iter += 2) {
1003 cat = ntohs(*((__be16 *)&enumcat[iter])); 1004 cat = ntohs(get_unaligned((__be16 *)&enumcat[iter]));
1004 if (cat <= cat_prev) 1005 if (cat <= cat_prev)
1005 return -EFAULT; 1006 return -EFAULT;
1006 cat_prev = cat; 1007 cat_prev = cat;
@@ -1068,8 +1069,8 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
1068 1069
1069 for (iter = 0; iter < net_cat_len; iter += 2) { 1070 for (iter = 0; iter < net_cat_len; iter += 2) {
1070 ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat, 1071 ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
1071 ntohs(*((__be16 *)&net_cat[iter])), 1072 ntohs(get_unaligned((__be16 *)&net_cat[iter])),
1072 GFP_ATOMIC); 1073 GFP_ATOMIC);
1073 if (ret_val != 0) 1074 if (ret_val != 0)
1074 return ret_val; 1075 return ret_val;
1075 } 1076 }
@@ -1102,9 +1103,10 @@ static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def,
1102 return -EFAULT; 1103 return -EFAULT;
1103 1104
1104 for (iter = 0; iter < rngcat_len; iter += 4) { 1105 for (iter = 0; iter < rngcat_len; iter += 4) {
1105 cat_high = ntohs(*((__be16 *)&rngcat[iter])); 1106 cat_high = ntohs(get_unaligned((__be16 *)&rngcat[iter]));
1106 if ((iter + 4) <= rngcat_len) 1107 if ((iter + 4) <= rngcat_len)
1107 cat_low = ntohs(*((__be16 *)&rngcat[iter + 2])); 1108 cat_low = ntohs(
1109 get_unaligned((__be16 *)&rngcat[iter + 2]));
1108 else 1110 else
1109 cat_low = 0; 1111 cat_low = 0;
1110 1112
@@ -1201,9 +1203,10 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
1201 u16 cat_high; 1203 u16 cat_high;
1202 1204
1203 for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) { 1205 for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) {
1204 cat_high = ntohs(*((__be16 *)&net_cat[net_iter])); 1206 cat_high = ntohs(get_unaligned((__be16 *)&net_cat[net_iter]));
1205 if ((net_iter + 4) <= net_cat_len) 1207 if ((net_iter + 4) <= net_cat_len)
1206 cat_low = ntohs(*((__be16 *)&net_cat[net_iter + 2])); 1208 cat_low = ntohs(
1209 get_unaligned((__be16 *)&net_cat[net_iter + 2]));
1207 else 1210 else
1208 cat_low = 0; 1211 cat_low = 0;
1209 1212
@@ -1565,7 +1568,7 @@ int cipso_v4_validate(unsigned char **option)
1565 } 1568 }
1566 1569
1567 rcu_read_lock(); 1570 rcu_read_lock();
1568 doi_def = cipso_v4_doi_search(ntohl(*((__be32 *)&opt[2]))); 1571 doi_def = cipso_v4_doi_search(ntohl(get_unaligned((__be32 *)&opt[2])));
1569 if (doi_def == NULL) { 1572 if (doi_def == NULL) {
1570 err_offset = 2; 1573 err_offset = 2;
1571 goto validate_return_locked; 1574 goto validate_return_locked;
@@ -1709,22 +1712,22 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
1709} 1712}
1710 1713
1711/** 1714/**
1712 * cipso_v4_socket_setattr - Add a CIPSO option to a socket 1715 * cipso_v4_sock_setattr - Add a CIPSO option to a socket
1713 * @sock: the socket 1716 * @sk: the socket
1714 * @doi_def: the CIPSO DOI to use 1717 * @doi_def: the CIPSO DOI to use
1715 * @secattr: the specific security attributes of the socket 1718 * @secattr: the specific security attributes of the socket
1716 * 1719 *
1717 * Description: 1720 * Description:
1718 * Set the CIPSO option on the given socket using the DOI definition and 1721 * Set the CIPSO option on the given socket using the DOI definition and
1719 * security attributes passed to the function. This function requires 1722 * security attributes passed to the function. This function requires
1720 * exclusive access to @sock->sk, which means it either needs to be in the 1723 * exclusive access to @sk, which means it either needs to be in the
1721 * process of being created or locked via lock_sock(sock->sk). Returns zero on 1724 * process of being created or locked. Returns zero on success and negative
1722 * success and negative values on failure. 1725 * values on failure.
1723 * 1726 *
1724 */ 1727 */
1725int cipso_v4_socket_setattr(const struct socket *sock, 1728int cipso_v4_sock_setattr(struct sock *sk,
1726 const struct cipso_v4_doi *doi_def, 1729 const struct cipso_v4_doi *doi_def,
1727 const struct netlbl_lsm_secattr *secattr) 1730 const struct netlbl_lsm_secattr *secattr)
1728{ 1731{
1729 int ret_val = -EPERM; 1732 int ret_val = -EPERM;
1730 u32 iter; 1733 u32 iter;
@@ -1732,7 +1735,6 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1732 u32 buf_len = 0; 1735 u32 buf_len = 0;
1733 u32 opt_len; 1736 u32 opt_len;
1734 struct ip_options *opt = NULL; 1737 struct ip_options *opt = NULL;
1735 struct sock *sk;
1736 struct inet_sock *sk_inet; 1738 struct inet_sock *sk_inet;
1737 struct inet_connection_sock *sk_conn; 1739 struct inet_connection_sock *sk_conn;
1738 1740
@@ -1740,7 +1742,6 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1740 * defined yet but it is not a problem as the only users of these 1742 * defined yet but it is not a problem as the only users of these
1741 * "lite" PF_INET sockets are functions which do an accept() call 1743 * "lite" PF_INET sockets are functions which do an accept() call
1742 * afterwards so we will label the socket as part of the accept(). */ 1744 * afterwards so we will label the socket as part of the accept(). */
1743 sk = sock->sk;
1744 if (sk == NULL) 1745 if (sk == NULL)
1745 return 0; 1746 return 0;
1746 1747
@@ -1858,7 +1859,7 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1858 if (ret_val == 0) 1859 if (ret_val == 0)
1859 return ret_val; 1860 return ret_val;
1860 1861
1861 doi = ntohl(*(__be32 *)&cipso_ptr[2]); 1862 doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2]));
1862 rcu_read_lock(); 1863 rcu_read_lock();
1863 doi_def = cipso_v4_doi_search(doi); 1864 doi_def = cipso_v4_doi_search(doi);
1864 if (doi_def == NULL) { 1865 if (doi_def == NULL) {
@@ -1892,29 +1893,6 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1892} 1893}
1893 1894
1894/** 1895/**
1895 * cipso_v4_socket_getattr - Get the security attributes from a socket
1896 * @sock: the socket
1897 * @secattr: the security attributes
1898 *
1899 * Description:
1900 * Query @sock to see if there is a CIPSO option attached to the socket and if
1901 * there is return the CIPSO security attributes in @secattr. Returns zero on
1902 * success and negative values on failure.
1903 *
1904 */
1905int cipso_v4_socket_getattr(const struct socket *sock,
1906 struct netlbl_lsm_secattr *secattr)
1907{
1908 int ret_val;
1909
1910 lock_sock(sock->sk);
1911 ret_val = cipso_v4_sock_getattr(sock->sk, secattr);
1912 release_sock(sock->sk);
1913
1914 return ret_val;
1915}
1916
1917/**
1918 * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option 1896 * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option
1919 * @skb: the packet 1897 * @skb: the packet
1920 * @secattr: the security attributes 1898 * @secattr: the security attributes
@@ -1936,7 +1914,7 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
1936 if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0) 1914 if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0)
1937 return 0; 1915 return 0;
1938 1916
1939 doi = ntohl(*(__be32 *)&cipso_ptr[2]); 1917 doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2]));
1940 rcu_read_lock(); 1918 rcu_read_lock();
1941 doi_def = cipso_v4_doi_search(doi); 1919 doi_def = cipso_v4_doi_search(doi);
1942 if (doi_def == NULL) 1920 if (doi_def == NULL)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 7f95e6e9beeb..abf6352f990f 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -64,21 +64,27 @@
64#include <net/rtnetlink.h> 64#include <net/rtnetlink.h>
65 65
66struct ipv4_devconf ipv4_devconf = { 66struct ipv4_devconf ipv4_devconf = {
67 .accept_redirects = 1, 67 .data = {
68 .send_redirects = 1, 68 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
69 .secure_redirects = 1, 69 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
70 .shared_media = 1, 70 [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
71 [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
72 },
71}; 73};
72 74
73static struct ipv4_devconf ipv4_devconf_dflt = { 75static struct ipv4_devconf ipv4_devconf_dflt = {
74 .accept_redirects = 1, 76 .data = {
75 .send_redirects = 1, 77 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
76 .secure_redirects = 1, 78 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
77 .shared_media = 1, 79 [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
78 .accept_source_route = 1, 80 [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
81 [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
82 },
79}; 83};
80 84
81static struct nla_policy ifa_ipv4_policy[IFA_MAX+1] __read_mostly = { 85#define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr)
86
87static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
82 [IFA_LOCAL] = { .type = NLA_U32 }, 88 [IFA_LOCAL] = { .type = NLA_U32 },
83 [IFA_ADDRESS] = { .type = NLA_U32 }, 89 [IFA_ADDRESS] = { .type = NLA_U32 },
84 [IFA_BROADCAST] = { .type = NLA_U32 }, 90 [IFA_BROADCAST] = { .type = NLA_U32 },
@@ -141,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev)
141 } 147 }
142} 148}
143 149
144struct in_device *inetdev_init(struct net_device *dev) 150static struct in_device *inetdev_init(struct net_device *dev)
145{ 151{
146 struct in_device *in_dev; 152 struct in_device *in_dev;
147 153
@@ -321,12 +327,8 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
321 } 327 }
322 328
323 } 329 }
324 if (destroy) { 330 if (destroy)
325 inet_free_ifa(ifa1); 331 inet_free_ifa(ifa1);
326
327 if (!in_dev->ifa_list)
328 inetdev_destroy(in_dev);
329 }
330} 332}
331 333
332static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 334static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
@@ -399,12 +401,10 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
399 ASSERT_RTNL(); 401 ASSERT_RTNL();
400 402
401 if (!in_dev) { 403 if (!in_dev) {
402 in_dev = inetdev_init(dev); 404 inet_free_ifa(ifa);
403 if (!in_dev) { 405 return -ENOBUFS;
404 inet_free_ifa(ifa);
405 return -ENOBUFS;
406 }
407 } 406 }
407 ipv4_devconf_setall(in_dev);
408 if (ifa->ifa_dev != in_dev) { 408 if (ifa->ifa_dev != in_dev) {
409 BUG_TRAP(!ifa->ifa_dev); 409 BUG_TRAP(!ifa->ifa_dev);
410 in_dev_hold(in_dev); 410 in_dev_hold(in_dev);
@@ -514,13 +514,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
514 514
515 in_dev = __in_dev_get_rtnl(dev); 515 in_dev = __in_dev_get_rtnl(dev);
516 if (in_dev == NULL) { 516 if (in_dev == NULL) {
517 in_dev = inetdev_init(dev); 517 err = -ENOBUFS;
518 if (in_dev == NULL) { 518 goto errout;
519 err = -ENOBUFS;
520 goto errout;
521 }
522 } 519 }
523 520
521 ipv4_devconf_setall(in_dev);
522
524 ifa = inet_alloc_ifa(); 523 ifa = inet_alloc_ifa();
525 if (ifa == NULL) { 524 if (ifa == NULL) {
526 /* 525 /*
@@ -1057,11 +1056,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1057 if (!in_dev) { 1056 if (!in_dev) {
1058 if (event == NETDEV_REGISTER) { 1057 if (event == NETDEV_REGISTER) {
1059 in_dev = inetdev_init(dev); 1058 in_dev = inetdev_init(dev);
1060 if (!in_dev)
1061 panic("devinet: Failed to create loopback\n");
1062 if (dev == &loopback_dev) { 1059 if (dev == &loopback_dev) {
1063 in_dev->cnf.no_xfrm = 1; 1060 if (!in_dev)
1064 in_dev->cnf.no_policy = 1; 1061 panic("devinet: "
1062 "Failed to create loopback\n");
1063 IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
1064 IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
1065 } 1065 }
1066 } 1066 }
1067 goto out; 1067 goto out;
@@ -1237,13 +1237,98 @@ errout:
1237 1237
1238#ifdef CONFIG_SYSCTL 1238#ifdef CONFIG_SYSCTL
1239 1239
1240static void devinet_copy_dflt_conf(int i)
1241{
1242 struct net_device *dev;
1243
1244 read_lock(&dev_base_lock);
1245 for_each_netdev(dev) {
1246 struct in_device *in_dev;
1247 rcu_read_lock();
1248 in_dev = __in_dev_get_rcu(dev);
1249 if (in_dev && !test_bit(i, in_dev->cnf.state))
1250 in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i];
1251 rcu_read_unlock();
1252 }
1253 read_unlock(&dev_base_lock);
1254}
1255
1256static int devinet_conf_proc(ctl_table *ctl, int write,
1257 struct file* filp, void __user *buffer,
1258 size_t *lenp, loff_t *ppos)
1259{
1260 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1261
1262 if (write) {
1263 struct ipv4_devconf *cnf = ctl->extra1;
1264 int i = (int *)ctl->data - cnf->data;
1265
1266 set_bit(i, cnf->state);
1267
1268 if (cnf == &ipv4_devconf_dflt)
1269 devinet_copy_dflt_conf(i);
1270 }
1271
1272 return ret;
1273}
1274
1275static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
1276 void __user *oldval, size_t __user *oldlenp,
1277 void __user *newval, size_t newlen)
1278{
1279 struct ipv4_devconf *cnf;
1280 int *valp = table->data;
1281 int new;
1282 int i;
1283
1284 if (!newval || !newlen)
1285 return 0;
1286
1287 if (newlen != sizeof(int))
1288 return -EINVAL;
1289
1290 if (get_user(new, (int __user *)newval))
1291 return -EFAULT;
1292
1293 if (new == *valp)
1294 return 0;
1295
1296 if (oldval && oldlenp) {
1297 size_t len;
1298
1299 if (get_user(len, oldlenp))
1300 return -EFAULT;
1301
1302 if (len) {
1303 if (len > table->maxlen)
1304 len = table->maxlen;
1305 if (copy_to_user(oldval, valp, len))
1306 return -EFAULT;
1307 if (put_user(len, oldlenp))
1308 return -EFAULT;
1309 }
1310 }
1311
1312 *valp = new;
1313
1314 cnf = table->extra1;
1315 i = (int *)table->data - cnf->data;
1316
1317 set_bit(i, cnf->state);
1318
1319 if (cnf == &ipv4_devconf_dflt)
1320 devinet_copy_dflt_conf(i);
1321
1322 return 1;
1323}
1324
1240void inet_forward_change(void) 1325void inet_forward_change(void)
1241{ 1326{
1242 struct net_device *dev; 1327 struct net_device *dev;
1243 int on = ipv4_devconf.forwarding; 1328 int on = IPV4_DEVCONF_ALL(FORWARDING);
1244 1329
1245 ipv4_devconf.accept_redirects = !on; 1330 IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on;
1246 ipv4_devconf_dflt.forwarding = on; 1331 IPV4_DEVCONF_DFLT(FORWARDING) = on;
1247 1332
1248 read_lock(&dev_base_lock); 1333 read_lock(&dev_base_lock);
1249 for_each_netdev(dev) { 1334 for_each_netdev(dev) {
@@ -1251,7 +1336,7 @@ void inet_forward_change(void)
1251 rcu_read_lock(); 1336 rcu_read_lock();
1252 in_dev = __in_dev_get_rcu(dev); 1337 in_dev = __in_dev_get_rcu(dev);
1253 if (in_dev) 1338 if (in_dev)
1254 in_dev->cnf.forwarding = on; 1339 IN_DEV_CONF_SET(in_dev, FORWARDING, on);
1255 rcu_read_unlock(); 1340 rcu_read_unlock();
1256 } 1341 }
1257 read_unlock(&dev_base_lock); 1342 read_unlock(&dev_base_lock);
@@ -1268,9 +1353,9 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
1268 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); 1353 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1269 1354
1270 if (write && *valp != val) { 1355 if (write && *valp != val) {
1271 if (valp == &ipv4_devconf.forwarding) 1356 if (valp == &IPV4_DEVCONF_ALL(FORWARDING))
1272 inet_forward_change(); 1357 inet_forward_change();
1273 else if (valp != &ipv4_devconf_dflt.forwarding) 1358 else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING))
1274 rt_cache_flush(0); 1359 rt_cache_flush(0);
1275 } 1360 }
1276 1361
@@ -1295,42 +1380,43 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
1295 void __user *oldval, size_t __user *oldlenp, 1380 void __user *oldval, size_t __user *oldlenp,
1296 void __user *newval, size_t newlen) 1381 void __user *newval, size_t newlen)
1297{ 1382{
1298 int *valp = table->data; 1383 int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp,
1299 int new; 1384 newval, newlen);
1300 1385
1301 if (!newval || !newlen) 1386 if (ret == 1)
1302 return 0; 1387 rt_cache_flush(0);
1303 1388
1304 if (newlen != sizeof(int)) 1389 return ret;
1305 return -EINVAL; 1390}
1306 1391
1307 if (get_user(new, (int __user *)newval))
1308 return -EFAULT;
1309 1392
1310 if (new == *valp) 1393#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc, sysctl) \
1311 return 0; 1394 { \
1395 .ctl_name = NET_IPV4_CONF_ ## attr, \
1396 .procname = name, \
1397 .data = ipv4_devconf.data + \
1398 NET_IPV4_CONF_ ## attr - 1, \
1399 .maxlen = sizeof(int), \
1400 .mode = mval, \
1401 .proc_handler = proc, \
1402 .strategy = sysctl, \
1403 .extra1 = &ipv4_devconf, \
1404 }
1312 1405
1313 if (oldval && oldlenp) { 1406#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
1314 size_t len; 1407 DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \
1408 devinet_conf_sysctl)
1315 1409
1316 if (get_user(len, oldlenp)) 1410#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
1317 return -EFAULT; 1411 DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \
1412 devinet_conf_sysctl)
1318 1413
1319 if (len) { 1414#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \
1320 if (len > table->maxlen) 1415 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 1416
1417#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
1418 DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \
1419 ipv4_doint_and_flush_strategy)
1334 1420
1335static struct devinet_sysctl_table { 1421static struct devinet_sysctl_table {
1336 struct ctl_table_header *sysctl_header; 1422 struct ctl_table_header *sysctl_header;
@@ -1341,178 +1427,34 @@ static struct devinet_sysctl_table {
1341 ctl_table devinet_root_dir[2]; 1427 ctl_table devinet_root_dir[2];
1342} devinet_sysctl = { 1428} devinet_sysctl = {
1343 .devinet_vars = { 1429 .devinet_vars = {
1344 { 1430 DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
1345 .ctl_name = NET_IPV4_CONF_FORWARDING, 1431 devinet_sysctl_forward,
1346 .procname = "forwarding", 1432 devinet_conf_sysctl),
1347 .data = &ipv4_devconf.forwarding, 1433 DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
1348 .maxlen = sizeof(int), 1434
1349 .mode = 0644, 1435 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
1350 .proc_handler = &devinet_sysctl_forward, 1436 DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
1351 }, 1437 DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
1352 { 1438 DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
1353 .ctl_name = NET_IPV4_CONF_MC_FORWARDING, 1439 DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
1354 .procname = "mc_forwarding", 1440 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
1355 .data = &ipv4_devconf.mc_forwarding, 1441 "accept_source_route"),
1356 .maxlen = sizeof(int), 1442 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
1357 .mode = 0444, 1443 DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
1358 .proc_handler = &proc_dointvec, 1444 DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
1359 }, 1445 DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
1360 { 1446 DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
1361 .ctl_name = NET_IPV4_CONF_ACCEPT_REDIRECTS, 1447 DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
1362 .procname = "accept_redirects", 1448 DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
1363 .data = &ipv4_devconf.accept_redirects, 1449 DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
1364 .maxlen = sizeof(int), 1450 DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
1365 .mode = 0644, 1451
1366 .proc_handler = &proc_dointvec, 1452 DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
1367 }, 1453 DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
1368 { 1454 DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
1369 .ctl_name = NET_IPV4_CONF_SECURE_REDIRECTS, 1455 "force_igmp_version"),
1370 .procname = "secure_redirects", 1456 DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
1371 .data = &ipv4_devconf.secure_redirects, 1457 "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 }, 1458 },
1517 .devinet_dev = { 1459 .devinet_dev = {
1518 { 1460 {
@@ -1561,6 +1503,7 @@ static void devinet_sysctl_register(struct in_device *in_dev,
1561 return; 1503 return;
1562 for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) { 1504 for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
1563 t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf; 1505 t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
1506 t->devinet_vars[i].extra1 = p;
1564 } 1507 }
1565 1508
1566 if (dev) { 1509 if (dev) {
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 9ad1f6252a97..311d633f7f39 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -441,7 +441,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg)
441 return -EINVAL; 441 return -EINVAL;
442} 442}
443 443
444struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = { 444const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
445 [RTA_DST] = { .type = NLA_U32 }, 445 [RTA_DST] = { .type = NLA_U32 },
446 [RTA_SRC] = { .type = NLA_U32 }, 446 [RTA_SRC] = { .type = NLA_U32 },
447 [RTA_IIF] = { .type = NLA_U32 }, 447 [RTA_IIF] = { .type = NLA_U32 },
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 33083ad52e9f..2a947840210e 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -169,7 +169,7 @@ static struct fib_table *fib_empty_table(void)
169 return NULL; 169 return NULL;
170} 170}
171 171
172static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { 172static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = {
173 FRA_GENERIC_POLICY, 173 FRA_GENERIC_POLICY,
174 [FRA_FLOW] = { .type = NLA_U32 }, 174 [FRA_FLOW] = { .type = NLA_U32 },
175}; 175};
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index f4dd47453108..a646409c2d06 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -128,14 +128,16 @@
128 * contradict to specs provided this delay is small enough. 128 * contradict to specs provided this delay is small enough.
129 */ 129 */
130 130
131#define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \ 131#define IGMP_V1_SEEN(in_dev) \
132 (in_dev)->cnf.force_igmp_version == 1 || \ 132 (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \
133 ((in_dev)->mr_v1_seen && \ 133 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
134 time_before(jiffies, (in_dev)->mr_v1_seen))) 134 ((in_dev)->mr_v1_seen && \
135#define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \ 135 time_before(jiffies, (in_dev)->mr_v1_seen)))
136 (in_dev)->cnf.force_igmp_version == 2 || \ 136#define IGMP_V2_SEEN(in_dev) \
137 ((in_dev)->mr_v2_seen && \ 137 (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \
138 time_before(jiffies, (in_dev)->mr_v2_seen))) 138 IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
139 ((in_dev)->mr_v2_seen && \
140 time_before(jiffies, (in_dev)->mr_v2_seen)))
139 141
140static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); 142static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
141static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); 143static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index d6427d918512..34ea4547ebbe 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1352,7 +1352,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1352 } 1352 }
1353 1353
1354 { 1354 {
1355 struct flowi fl = { .nl_u = { .ip4_u = 1355 struct flowi fl = { .oif = arg->bound_dev_if,
1356 .nl_u = { .ip4_u =
1356 { .daddr = daddr, 1357 { .daddr = daddr,
1357 .saddr = rt->rt_spec_dst, 1358 .saddr = rt->rt_spec_dst,
1358 .tos = RT_TOS(ip_hdr(skb)->tos) } }, 1359 .tos = RT_TOS(ip_hdr(skb)->tos) } },
@@ -1376,6 +1377,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1376 inet->tos = ip_hdr(skb)->tos; 1377 inet->tos = ip_hdr(skb)->tos;
1377 sk->sk_priority = skb->priority; 1378 sk->sk_priority = skb->priority;
1378 sk->sk_protocol = ip_hdr(skb)->protocol; 1379 sk->sk_protocol = ip_hdr(skb)->protocol;
1380 sk->sk_bound_dev_if = arg->bound_dev_if;
1379 ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0, 1381 ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
1380 &ipc, rt, MSG_DONTWAIT); 1382 &ipc, rt, MSG_DONTWAIT);
1381 if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { 1383 if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 0ebae413ae87..d96582acdf69 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
152 dev->flags |= IFF_MULTICAST; 152 dev->flags |= IFF_MULTICAST;
153 153
154 in_dev = __in_dev_get_rtnl(dev); 154 in_dev = __in_dev_get_rtnl(dev);
155 if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL) 155 if (in_dev == NULL)
156 goto failure; 156 goto failure;
157 in_dev->cnf.rp_filter = 0; 157
158 ipv4_devconf_setall(in_dev);
159 IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
158 160
159 if (dev_open(dev)) 161 if (dev_open(dev))
160 goto failure; 162 goto failure;
@@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void)
218 } 220 }
219 dev->iflink = 0; 221 dev->iflink = 0;
220 222
221 if ((in_dev = inetdev_init(dev)) == NULL) 223 rcu_read_lock();
224 if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
225 rcu_read_unlock();
222 goto failure; 226 goto failure;
227 }
223 228
224 in_dev->cnf.rp_filter = 0; 229 ipv4_devconf_setall(in_dev);
230 IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
231 rcu_read_unlock();
225 232
226 if (dev_open(dev)) 233 if (dev_open(dev))
227 goto failure; 234 goto failure;
@@ -281,7 +288,7 @@ static int vif_delete(int vifi)
281 dev_set_allmulti(dev, -1); 288 dev_set_allmulti(dev, -1);
282 289
283 if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { 290 if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
284 in_dev->cnf.mc_forwarding--; 291 IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
285 ip_rt_multicast_event(in_dev); 292 ip_rt_multicast_event(in_dev);
286 } 293 }
287 294
@@ -426,7 +433,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
426 433
427 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) 434 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
428 return -EADDRNOTAVAIL; 435 return -EADDRNOTAVAIL;
429 in_dev->cnf.mc_forwarding++; 436 IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
430 dev_set_allmulti(dev, +1); 437 dev_set_allmulti(dev, +1);
431 ip_rt_multicast_event(in_dev); 438 ip_rt_multicast_event(in_dev);
432 439
@@ -841,7 +848,7 @@ static void mrtsock_destruct(struct sock *sk)
841{ 848{
842 rtnl_lock(); 849 rtnl_lock();
843 if (sk == mroute_socket) { 850 if (sk == mroute_socket) {
844 ipv4_devconf.mc_forwarding--; 851 IPV4_DEVCONF_ALL(MC_FORWARDING)--;
845 852
846 write_lock_bh(&mrt_lock); 853 write_lock_bh(&mrt_lock);
847 mroute_socket=NULL; 854 mroute_socket=NULL;
@@ -890,7 +897,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
890 mroute_socket=sk; 897 mroute_socket=sk;
891 write_unlock_bh(&mrt_lock); 898 write_unlock_bh(&mrt_lock);
892 899
893 ipv4_devconf.mc_forwarding++; 900 IPV4_DEVCONF_ALL(MC_FORWARDING)++;
894 } 901 }
895 rtnl_unlock(); 902 rtnl_unlock();
896 return ret; 903 return ret;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index e3f83bf160d9..9bacf1a03630 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -499,7 +499,8 @@ check_entry(struct ipt_entry *e, const char *name)
499} 499}
500 500
501static inline int check_match(struct ipt_entry_match *m, const char *name, 501static inline int check_match(struct ipt_entry_match *m, const char *name,
502 const struct ipt_ip *ip, unsigned int hookmask) 502 const struct ipt_ip *ip, unsigned int hookmask,
503 unsigned int *i)
503{ 504{
504 struct xt_match *match; 505 struct xt_match *match;
505 int ret; 506 int ret;
@@ -515,6 +516,8 @@ static inline int check_match(struct ipt_entry_match *m, const char *name,
515 m->u.kernel.match->name); 516 m->u.kernel.match->name);
516 ret = -EINVAL; 517 ret = -EINVAL;
517 } 518 }
519 if (!ret)
520 (*i)++;
518 return ret; 521 return ret;
519} 522}
520 523
@@ -537,11 +540,10 @@ find_check_match(struct ipt_entry_match *m,
537 } 540 }
538 m->u.kernel.match = match; 541 m->u.kernel.match = match;
539 542
540 ret = check_match(m, name, ip, hookmask); 543 ret = check_match(m, name, ip, hookmask, i);
541 if (ret) 544 if (ret)
542 goto err; 545 goto err;
543 546
544 (*i)++;
545 return 0; 547 return 0;
546err: 548err:
547 module_put(m->u.kernel.match->me); 549 module_put(m->u.kernel.match->me);
@@ -1425,7 +1427,7 @@ out:
1425} 1427}
1426 1428
1427static inline int 1429static inline int
1428compat_check_calc_match(struct ipt_entry_match *m, 1430compat_find_calc_match(struct ipt_entry_match *m,
1429 const char *name, 1431 const char *name,
1430 const struct ipt_ip *ip, 1432 const struct ipt_ip *ip,
1431 unsigned int hookmask, 1433 unsigned int hookmask,
@@ -1449,6 +1451,31 @@ compat_check_calc_match(struct ipt_entry_match *m,
1449} 1451}
1450 1452
1451static inline int 1453static inline int
1454compat_release_match(struct ipt_entry_match *m, unsigned int *i)
1455{
1456 if (i && (*i)-- == 0)
1457 return 1;
1458
1459 module_put(m->u.kernel.match->me);
1460 return 0;
1461}
1462
1463static inline int
1464compat_release_entry(struct ipt_entry *e, unsigned int *i)
1465{
1466 struct ipt_entry_target *t;
1467
1468 if (i && (*i)-- == 0)
1469 return 1;
1470
1471 /* Cleanup all matches */
1472 IPT_MATCH_ITERATE(e, compat_release_match, NULL);
1473 t = ipt_get_target(e);
1474 module_put(t->u.kernel.target->me);
1475 return 0;
1476}
1477
1478static inline int
1452check_compat_entry_size_and_hooks(struct ipt_entry *e, 1479check_compat_entry_size_and_hooks(struct ipt_entry *e,
1453 struct xt_table_info *newinfo, 1480 struct xt_table_info *newinfo,
1454 unsigned int *size, 1481 unsigned int *size,
@@ -1485,10 +1512,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1485 off = 0; 1512 off = 0;
1486 entry_offset = (void *)e - (void *)base; 1513 entry_offset = (void *)e - (void *)base;
1487 j = 0; 1514 j = 0;
1488 ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip, 1515 ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
1489 e->comefrom, &off, &j); 1516 e->comefrom, &off, &j);
1490 if (ret != 0) 1517 if (ret != 0)
1491 goto cleanup_matches; 1518 goto release_matches;
1492 1519
1493 t = ipt_get_target(e); 1520 t = ipt_get_target(e);
1494 target = try_then_request_module(xt_find_target(AF_INET, 1521 target = try_then_request_module(xt_find_target(AF_INET,
@@ -1499,7 +1526,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1499 duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", 1526 duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
1500 t->u.user.name); 1527 t->u.user.name);
1501 ret = target ? PTR_ERR(target) : -ENOENT; 1528 ret = target ? PTR_ERR(target) : -ENOENT;
1502 goto cleanup_matches; 1529 goto release_matches;
1503 } 1530 }
1504 t->u.kernel.target = target; 1531 t->u.kernel.target = target;
1505 1532
@@ -1526,8 +1553,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1526 1553
1527out: 1554out:
1528 module_put(t->u.kernel.target->me); 1555 module_put(t->u.kernel.target->me);
1529cleanup_matches: 1556release_matches:
1530 IPT_MATCH_ITERATE(e, cleanup_match, &j); 1557 IPT_MATCH_ITERATE(e, compat_release_match, &j);
1531 return ret; 1558 return ret;
1532} 1559}
1533 1560
@@ -1574,15 +1601,26 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
1574 return ret; 1601 return ret;
1575} 1602}
1576 1603
1577static inline int compat_check_entry(struct ipt_entry *e, const char *name) 1604static inline int compat_check_entry(struct ipt_entry *e, const char *name,
1605 unsigned int *i)
1578{ 1606{
1579 int ret; 1607 int j, ret;
1580 1608
1581 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom); 1609 j = 0;
1610 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
1582 if (ret) 1611 if (ret)
1583 return ret; 1612 goto cleanup_matches;
1613
1614 ret = check_target(e, name);
1615 if (ret)
1616 goto cleanup_matches;
1584 1617
1585 return check_target(e, name); 1618 (*i)++;
1619 return 0;
1620
1621 cleanup_matches:
1622 IPT_MATCH_ITERATE(e, cleanup_match, &j);
1623 return ret;
1586} 1624}
1587 1625
1588static int 1626static int
@@ -1673,10 +1711,17 @@ translate_compat_table(const char *name,
1673 if (!mark_source_chains(newinfo, valid_hooks, entry1)) 1711 if (!mark_source_chains(newinfo, valid_hooks, entry1))
1674 goto free_newinfo; 1712 goto free_newinfo;
1675 1713
1714 i = 0;
1676 ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, 1715 ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
1677 name); 1716 name, &i);
1678 if (ret) 1717 if (ret) {
1679 goto free_newinfo; 1718 j -= i;
1719 IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i,
1720 compat_release_entry, &j);
1721 IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
1722 xt_free_table_info(newinfo);
1723 return ret;
1724 }
1680 1725
1681 /* And one copy for every other CPU */ 1726 /* And one copy for every other CPU */
1682 for_each_possible_cpu(i) 1727 for_each_possible_cpu(i)
@@ -1691,7 +1736,7 @@ translate_compat_table(const char *name,
1691free_newinfo: 1736free_newinfo:
1692 xt_free_table_info(newinfo); 1737 xt_free_table_info(newinfo);
1693out: 1738out:
1694 IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); 1739 IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
1695 return ret; 1740 return ret;
1696out_unlock: 1741out_unlock:
1697 compat_flush_offsets(); 1742 compat_flush_offsets();
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index fd62a41d69cc..6dc72a815f77 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -133,6 +133,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
133 struct nf_conn *ct; 133 struct nf_conn *ct;
134 enum ip_conntrack_info ctinfo; 134 enum ip_conntrack_info ctinfo;
135 struct nf_conn_help *help; 135 struct nf_conn_help *help;
136 struct nf_conntrack_helper *helper;
136 137
137 /* This is where we call the helper: as the packet goes out. */ 138 /* This is where we call the helper: as the packet goes out. */
138 ct = nf_ct_get(*pskb, &ctinfo); 139 ct = nf_ct_get(*pskb, &ctinfo);
@@ -140,12 +141,14 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
140 return NF_ACCEPT; 141 return NF_ACCEPT;
141 142
142 help = nfct_help(ct); 143 help = nfct_help(ct);
143 if (!help || !help->helper) 144 if (!help)
144 return NF_ACCEPT; 145 return NF_ACCEPT;
145 146 /* rcu_read_lock()ed by nf_hook_slow */
146 return help->helper->help(pskb, 147 helper = rcu_dereference(help->helper);
147 skb_network_offset(*pskb) + ip_hdrlen(*pskb), 148 if (!helper)
148 ct, ctinfo); 149 return NF_ACCEPT;
150 return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb),
151 ct, ctinfo);
149} 152}
150 153
151static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, 154static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index cdbc6c135849..3b690cf2a4ee 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -260,7 +260,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
260 seq_printf(seq, " %s", snmp4_ipstats_list[i].name); 260 seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
261 261
262 seq_printf(seq, "\nIp: %d %d", 262 seq_printf(seq, "\nIp: %d %d",
263 ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl); 263 IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl);
264 264
265 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) 265 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
266 seq_printf(seq, " %lu", 266 seq_printf(seq, " %lu",
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8603cfb271f2..29ca63e81ced 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1636,7 +1636,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1636 1636
1637 atomic_set(&rth->u.dst.__refcnt, 1); 1637 atomic_set(&rth->u.dst.__refcnt, 1);
1638 rth->u.dst.flags= DST_HOST; 1638 rth->u.dst.flags= DST_HOST;
1639 if (in_dev->cnf.no_policy) 1639 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
1640 rth->u.dst.flags |= DST_NOPOLICY; 1640 rth->u.dst.flags |= DST_NOPOLICY;
1641 rth->fl.fl4_dst = daddr; 1641 rth->fl.fl4_dst = daddr;
1642 rth->rt_dst = daddr; 1642 rth->rt_dst = daddr;
@@ -1778,9 +1778,9 @@ static inline int __mkroute_input(struct sk_buff *skb,
1778 if (res->fi->fib_nhs > 1) 1778 if (res->fi->fib_nhs > 1)
1779 rth->u.dst.flags |= DST_BALANCED; 1779 rth->u.dst.flags |= DST_BALANCED;
1780#endif 1780#endif
1781 if (in_dev->cnf.no_policy) 1781 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
1782 rth->u.dst.flags |= DST_NOPOLICY; 1782 rth->u.dst.flags |= DST_NOPOLICY;
1783 if (out_dev->cnf.no_xfrm) 1783 if (IN_DEV_CONF_GET(out_dev, NOXFRM))
1784 rth->u.dst.flags |= DST_NOXFRM; 1784 rth->u.dst.flags |= DST_NOXFRM;
1785 rth->fl.fl4_dst = daddr; 1785 rth->fl.fl4_dst = daddr;
1786 rth->rt_dst = daddr; 1786 rth->rt_dst = daddr;
@@ -2021,7 +2021,7 @@ local_input:
2021 2021
2022 atomic_set(&rth->u.dst.__refcnt, 1); 2022 atomic_set(&rth->u.dst.__refcnt, 1);
2023 rth->u.dst.flags= DST_HOST; 2023 rth->u.dst.flags= DST_HOST;
2024 if (in_dev->cnf.no_policy) 2024 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
2025 rth->u.dst.flags |= DST_NOPOLICY; 2025 rth->u.dst.flags |= DST_NOPOLICY;
2026 rth->fl.fl4_dst = daddr; 2026 rth->fl.fl4_dst = daddr;
2027 rth->rt_dst = daddr; 2027 rth->rt_dst = daddr;
@@ -2218,9 +2218,9 @@ static inline int __mkroute_output(struct rtable **result,
2218 rth->u.dst.flags |= DST_BALANCED; 2218 rth->u.dst.flags |= DST_BALANCED;
2219 } 2219 }
2220#endif 2220#endif
2221 if (in_dev->cnf.no_xfrm) 2221 if (IN_DEV_CONF_GET(in_dev, NOXFRM))
2222 rth->u.dst.flags |= DST_NOXFRM; 2222 rth->u.dst.flags |= DST_NOXFRM;
2223 if (in_dev->cnf.no_policy) 2223 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
2224 rth->u.dst.flags |= DST_NOPOLICY; 2224 rth->u.dst.flags |= DST_NOPOLICY;
2225 2225
2226 rth->fl.fl4_dst = oldflp->fl4_dst; 2226 rth->fl.fl4_dst = oldflp->fl4_dst;
@@ -2759,7 +2759,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2759 __be32 dst = rt->rt_dst; 2759 __be32 dst = rt->rt_dst;
2760 2760
2761 if (MULTICAST(dst) && !LOCAL_MCAST(dst) && 2761 if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
2762 ipv4_devconf.mc_forwarding) { 2762 IPV4_DEVCONF_ALL(MC_FORWARDING)) {
2763 int err = ipmr_get_route(skb, r, nowait); 2763 int err = ipmr_get_route(skb, r, nowait);
2764 if (err <= 0) { 2764 if (err <= 0) {
2765 if (!nowait) { 2765 if (!nowait) {
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 6817d6485df5..53ef0f4bbdaa 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -37,12 +37,12 @@ static
37int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, 37int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
38 void __user *buffer, size_t *lenp, loff_t *ppos) 38 void __user *buffer, size_t *lenp, loff_t *ppos)
39{ 39{
40 int val = ipv4_devconf.forwarding; 40 int val = IPV4_DEVCONF_ALL(FORWARDING);
41 int ret; 41 int ret;
42 42
43 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); 43 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
44 44
45 if (write && ipv4_devconf.forwarding != val) 45 if (write && IPV4_DEVCONF_ALL(FORWARDING) != val)
46 inet_forward_change(); 46 inet_forward_change();
47 47
48 return ret; 48 return ret;
@@ -222,7 +222,7 @@ ctl_table ipv4_table[] = {
222 { 222 {
223 .ctl_name = NET_IPV4_FORWARD, 223 .ctl_name = NET_IPV4_FORWARD,
224 .procname = "ip_forward", 224 .procname = "ip_forward",
225 .data = &ipv4_devconf.forwarding, 225 .data = &IPV4_DEVCONF_ALL(FORWARDING),
226 .maxlen = sizeof(int), 226 .maxlen = sizeof(int),
227 .mode = 0644, 227 .mode = 0644,
228 .proc_handler = &ipv4_sysctl_forward, 228 .proc_handler = &ipv4_sysctl_forward,
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 47c61055eb60..97e294e82679 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -705,6 +705,8 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
705 ip_hdr(skb)->saddr, /* XXX */ 705 ip_hdr(skb)->saddr, /* XXX */
706 arg.iov[0].iov_len, IPPROTO_TCP, 0); 706 arg.iov[0].iov_len, IPPROTO_TCP, 0);
707 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 707 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
708 if (twsk)
709 arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
708 710
709 ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); 711 ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
710 712
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index 760165a0800c..d9323dfff826 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -63,6 +63,9 @@ struct {
63 * FIXME: causes an extra copy 63 * FIXME: causes an extra copy
64 */ 64 */
65static void printl(const char *fmt, ...) 65static void printl(const char *fmt, ...)
66 __attribute__ ((format (printf, 1, 2)));
67
68static void printl(const char *fmt, ...)
66{ 69{
67 va_list args; 70 va_list args;
68 int len; 71 int len;
@@ -80,8 +83,7 @@ static void printl(const char *fmt, ...)
80 83
81 kfifo_put(tcpw.fifo, tbuf, len); 84 kfifo_put(tcpw.fifo, tbuf, len);
82 wake_up(&tcpw.wait); 85 wake_up(&tcpw.wait);
83} __attribute__ ((format (printf, 1, 2))); 86}
84
85 87
86/* 88/*
87 * Hook inserted to be called before each receive packet. 89 * Hook inserted to be called before each receive packet.
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index e61340150ba6..e9b151b3a598 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -292,9 +292,9 @@ static void tcp_retransmit_timer(struct sock *sk)
292 * we cannot allow such beasts to hang infinitely. 292 * we cannot allow such beasts to hang infinitely.
293 */ 293 */
294#ifdef TCP_DEBUG 294#ifdef TCP_DEBUG
295 if (net_ratelimit()) { 295 if (1) {
296 struct inet_sock *inet = inet_sk(sk); 296 struct inet_sock *inet = inet_sk(sk);
297 printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", 297 LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
298 NIPQUAD(inet->daddr), ntohs(inet->dport), 298 NIPQUAD(inet->daddr), ntohs(inet->dport),
299 inet->num, tp->snd_una, tp->snd_nxt); 299 inet->num, tp->snd_una, tp->snd_nxt);
300 } 300 }
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 5da703e699da..facb7e29304e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -114,36 +114,14 @@ DEFINE_RWLOCK(udp_hash_lock);
114 114
115static int udp_port_rover; 115static int udp_port_rover;
116 116
117/* 117static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[])
118 * Note about this hash function :
119 * Typical use is probably daddr = 0, only dport is going to vary hash
120 */
121static inline unsigned int udp_hash_port(__u16 port)
122{
123 return port;
124}
125
126static inline int __udp_lib_port_inuse(unsigned int hash, int port,
127 const struct sock *this_sk,
128 struct hlist_head udptable[],
129 const struct udp_get_port_ops *ops)
130{ 118{
131 struct sock *sk; 119 struct sock *sk;
132 struct hlist_node *node; 120 struct hlist_node *node;
133 struct inet_sock *inet;
134 121
135 sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) { 122 sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
136 if (sk->sk_hash != hash) 123 if (sk->sk_hash == num)
137 continue;
138 inet = inet_sk(sk);
139 if (inet->num != port)
140 continue;
141 if (this_sk) {
142 if (ops->saddr_cmp(sk, this_sk))
143 return 1;
144 } else if (ops->saddr_any(sk))
145 return 1; 124 return 1;
146 }
147 return 0; 125 return 0;
148} 126}
149 127
@@ -154,16 +132,16 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port,
154 * @snum: port number to look up 132 * @snum: port number to look up
155 * @udptable: hash list table, must be of UDP_HTABLE_SIZE 133 * @udptable: hash list table, must be of UDP_HTABLE_SIZE
156 * @port_rover: pointer to record of last unallocated port 134 * @port_rover: pointer to record of last unallocated port
157 * @ops: AF-dependent address operations 135 * @saddr_comp: AF-dependent comparison of bound local IP addresses
158 */ 136 */
159int __udp_lib_get_port(struct sock *sk, unsigned short snum, 137int __udp_lib_get_port(struct sock *sk, unsigned short snum,
160 struct hlist_head udptable[], int *port_rover, 138 struct hlist_head udptable[], int *port_rover,
161 const struct udp_get_port_ops *ops) 139 int (*saddr_comp)(const struct sock *sk1,
140 const struct sock *sk2 ) )
162{ 141{
163 struct hlist_node *node; 142 struct hlist_node *node;
164 struct hlist_head *head; 143 struct hlist_head *head;
165 struct sock *sk2; 144 struct sock *sk2;
166 unsigned int hash;
167 int error = 1; 145 int error = 1;
168 146
169 write_lock_bh(&udp_hash_lock); 147 write_lock_bh(&udp_hash_lock);
@@ -178,8 +156,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
178 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { 156 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
179 int size; 157 int size;
180 158
181 hash = ops->hash_port_and_rcv_saddr(result, sk); 159 head = &udptable[result & (UDP_HTABLE_SIZE - 1)];
182 head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
183 if (hlist_empty(head)) { 160 if (hlist_empty(head)) {
184 if (result > sysctl_local_port_range[1]) 161 if (result > sysctl_local_port_range[1])
185 result = sysctl_local_port_range[0] + 162 result = sysctl_local_port_range[0] +
@@ -204,16 +181,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
204 result = sysctl_local_port_range[0] 181 result = sysctl_local_port_range[0]
205 + ((result - sysctl_local_port_range[0]) & 182 + ((result - sysctl_local_port_range[0]) &
206 (UDP_HTABLE_SIZE - 1)); 183 (UDP_HTABLE_SIZE - 1));
207 hash = udp_hash_port(result); 184 if (! __udp_lib_lport_inuse(result, udptable))
208 if (__udp_lib_port_inuse(hash, result,
209 NULL, udptable, ops))
210 continue;
211 if (ops->saddr_any(sk))
212 break;
213
214 hash = ops->hash_port_and_rcv_saddr(result, sk);
215 if (! __udp_lib_port_inuse(hash, result,
216 sk, udptable, ops))
217 break; 185 break;
218 } 186 }
219 if (i >= (1 << 16) / UDP_HTABLE_SIZE) 187 if (i >= (1 << 16) / UDP_HTABLE_SIZE)
@@ -221,40 +189,21 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
221gotit: 189gotit:
222 *port_rover = snum = result; 190 *port_rover = snum = result;
223 } else { 191 } else {
224 hash = udp_hash_port(snum); 192 head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
225 head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
226 193
227 sk_for_each(sk2, node, head) 194 sk_for_each(sk2, node, head)
228 if (sk2->sk_hash == hash && 195 if (sk2->sk_hash == snum &&
229 sk2 != sk && 196 sk2 != sk &&
230 inet_sk(sk2)->num == snum && 197 (!sk2->sk_reuse || !sk->sk_reuse) &&
231 (!sk2->sk_reuse || !sk->sk_reuse) && 198 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
232 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || 199 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
233 sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && 200 (*saddr_comp)(sk, sk2) )
234 ops->saddr_cmp(sk, sk2))
235 goto fail; 201 goto fail;
236
237 if (!ops->saddr_any(sk)) {
238 hash = ops->hash_port_and_rcv_saddr(snum, sk);
239 head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
240
241 sk_for_each(sk2, node, head)
242 if (sk2->sk_hash == hash &&
243 sk2 != sk &&
244 inet_sk(sk2)->num == snum &&
245 (!sk2->sk_reuse || !sk->sk_reuse) &&
246 (!sk2->sk_bound_dev_if ||
247 !sk->sk_bound_dev_if ||
248 sk2->sk_bound_dev_if ==
249 sk->sk_bound_dev_if) &&
250 ops->saddr_cmp(sk, sk2))
251 goto fail;
252 }
253 } 202 }
254 inet_sk(sk)->num = snum; 203 inet_sk(sk)->num = snum;
255 sk->sk_hash = hash; 204 sk->sk_hash = snum;
256 if (sk_unhashed(sk)) { 205 if (sk_unhashed(sk)) {
257 head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; 206 head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
258 sk_add_node(sk, head); 207 sk_add_node(sk, head);
259 sock_prot_inc_use(sk->sk_prot); 208 sock_prot_inc_use(sk->sk_prot);
260 } 209 }
@@ -265,12 +214,12 @@ fail:
265} 214}
266 215
267int udp_get_port(struct sock *sk, unsigned short snum, 216int udp_get_port(struct sock *sk, unsigned short snum,
268 const struct udp_get_port_ops *ops) 217 int (*scmp)(const struct sock *, const struct sock *))
269{ 218{
270 return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, ops); 219 return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
271} 220}
272 221
273static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) 222int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
274{ 223{
275 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); 224 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
276 225
@@ -279,33 +228,9 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
279 inet1->rcv_saddr == inet2->rcv_saddr )); 228 inet1->rcv_saddr == inet2->rcv_saddr ));
280} 229}
281 230
282static int ipv4_rcv_saddr_any(const struct sock *sk)
283{
284 return !inet_sk(sk)->rcv_saddr;
285}
286
287static inline unsigned int ipv4_hash_port_and_addr(__u16 port, __be32 addr)
288{
289 addr ^= addr >> 16;
290 addr ^= addr >> 8;
291 return port ^ addr;
292}
293
294static unsigned int ipv4_hash_port_and_rcv_saddr(__u16 port,
295 const struct sock *sk)
296{
297 return ipv4_hash_port_and_addr(port, inet_sk(sk)->rcv_saddr);
298}
299
300const struct udp_get_port_ops udp_ipv4_ops = {
301 .saddr_cmp = ipv4_rcv_saddr_equal,
302 .saddr_any = ipv4_rcv_saddr_any,
303 .hash_port_and_rcv_saddr = ipv4_hash_port_and_rcv_saddr,
304};
305
306static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) 231static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
307{ 232{
308 return udp_get_port(sk, snum, &udp_ipv4_ops); 233 return udp_get_port(sk, snum, ipv4_rcv_saddr_equal);
309} 234}
310 235
311/* UDP is nearly always wildcards out the wazoo, it makes no sense to try 236/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
@@ -317,77 +242,63 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
317{ 242{
318 struct sock *sk, *result = NULL; 243 struct sock *sk, *result = NULL;
319 struct hlist_node *node; 244 struct hlist_node *node;
320 unsigned int hash, hashwild; 245 unsigned short hnum = ntohs(dport);
321 int score, best = -1, hport = ntohs(dport); 246 int badness = -1;
322
323 hash = ipv4_hash_port_and_addr(hport, daddr);
324 hashwild = udp_hash_port(hport);
325 247
326 read_lock(&udp_hash_lock); 248 read_lock(&udp_hash_lock);
327 249 sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
328lookup:
329
330 sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) {
331 struct inet_sock *inet = inet_sk(sk); 250 struct inet_sock *inet = inet_sk(sk);
332 251
333 if (sk->sk_hash != hash || ipv6_only_sock(sk) || 252 if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
334 inet->num != hport) 253 int score = (sk->sk_family == PF_INET ? 1 : 0);
335 continue; 254 if (inet->rcv_saddr) {
336 255 if (inet->rcv_saddr != daddr)
337 score = (sk->sk_family == PF_INET ? 1 : 0); 256 continue;
338 if (inet->rcv_saddr) { 257 score+=2;
339 if (inet->rcv_saddr != daddr) 258 }
340 continue; 259 if (inet->daddr) {
341 score+=2; 260 if (inet->daddr != saddr)
342 } 261 continue;
343 if (inet->daddr) { 262 score+=2;
344 if (inet->daddr != saddr) 263 }
345 continue; 264 if (inet->dport) {
346 score+=2; 265 if (inet->dport != sport)
347 } 266 continue;
348 if (inet->dport) { 267 score+=2;
349 if (inet->dport != sport) 268 }
350 continue; 269 if (sk->sk_bound_dev_if) {
351 score+=2; 270 if (sk->sk_bound_dev_if != dif)
352 } 271 continue;
353 if (sk->sk_bound_dev_if) { 272 score+=2;
354 if (sk->sk_bound_dev_if != dif) 273 }
355 continue; 274 if (score == 9) {
356 score+=2; 275 result = sk;
357 } 276 break;
358 if (score == 9) { 277 } else if (score > badness) {
359 result = sk; 278 result = sk;
360 goto found; 279 badness = score;
361 } else if (score > best) { 280 }
362 result = sk;
363 best = score;
364 } 281 }
365 } 282 }
366
367 if (hash != hashwild) {
368 hash = hashwild;
369 goto lookup;
370 }
371found:
372 if (result) 283 if (result)
373 sock_hold(result); 284 sock_hold(result);
374 read_unlock(&udp_hash_lock); 285 read_unlock(&udp_hash_lock);
375 return result; 286 return result;
376} 287}
377 288
378static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum, 289static inline struct sock *udp_v4_mcast_next(struct sock *sk,
379 int hport, __be32 loc_addr, 290 __be16 loc_port, __be32 loc_addr,
380 __be16 rmt_port, __be32 rmt_addr, 291 __be16 rmt_port, __be32 rmt_addr,
381 int dif) 292 int dif)
382{ 293{
383 struct hlist_node *node; 294 struct hlist_node *node;
384 struct sock *s = sk; 295 struct sock *s = sk;
296 unsigned short hnum = ntohs(loc_port);
385 297
386 sk_for_each_from(s, node) { 298 sk_for_each_from(s, node) {
387 struct inet_sock *inet = inet_sk(s); 299 struct inet_sock *inet = inet_sk(s);
388 300
389 if (s->sk_hash != hnum || 301 if (s->sk_hash != hnum ||
390 inet->num != hport ||
391 (inet->daddr && inet->daddr != rmt_addr) || 302 (inet->daddr && inet->daddr != rmt_addr) ||
392 (inet->dport != rmt_port && inet->dport) || 303 (inet->dport != rmt_port && inet->dport) ||
393 (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || 304 (inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
@@ -1221,45 +1132,29 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
1221 __be32 saddr, __be32 daddr, 1132 __be32 saddr, __be32 daddr,
1222 struct hlist_head udptable[]) 1133 struct hlist_head udptable[])
1223{ 1134{
1224 struct sock *sk, *skw, *sknext; 1135 struct sock *sk;
1225 int dif; 1136 int dif;
1226 int hport = ntohs(uh->dest);
1227 unsigned int hash = ipv4_hash_port_and_addr(hport, daddr);
1228 unsigned int hashwild = udp_hash_port(hport);
1229
1230 dif = skb->dev->ifindex;
1231 1137
1232 read_lock(&udp_hash_lock); 1138 read_lock(&udp_hash_lock);
1233 1139 sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
1234 sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]); 1140 dif = skb->dev->ifindex;
1235 skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]); 1141 sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
1236
1237 sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif);
1238 if (!sk) {
1239 hash = hashwild;
1240 sk = udp_v4_mcast_next(skw, hash, hport, daddr, uh->source,
1241 saddr, dif);
1242 }
1243 if (sk) { 1142 if (sk) {
1143 struct sock *sknext = NULL;
1144
1244 do { 1145 do {
1245 struct sk_buff *skb1 = skb; 1146 struct sk_buff *skb1 = skb;
1246 sknext = udp_v4_mcast_next(sk_next(sk), hash, hport, 1147
1247 daddr, uh->source, saddr, dif); 1148 sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr,
1248 if (!sknext && hash != hashwild) { 1149 uh->source, saddr, dif);
1249 hash = hashwild;
1250 sknext = udp_v4_mcast_next(skw, hash, hport,
1251 daddr, uh->source, saddr, dif);
1252 }
1253 if (sknext) 1150 if (sknext)
1254 skb1 = skb_clone(skb, GFP_ATOMIC); 1151 skb1 = skb_clone(skb, GFP_ATOMIC);
1255 1152
1256 if (skb1) { 1153 if (skb1) {
1257 int ret = udp_queue_rcv_skb(sk, skb1); 1154 int ret = udp_queue_rcv_skb(sk, skb1);
1258 if (ret > 0) 1155 if (ret > 0)
1259 /* 1156 /* we should probably re-process instead
1260 * we should probably re-process 1157 * of dropping packets here. */
1261 * instead of dropping packets here.
1262 */
1263 kfree_skb(skb1); 1158 kfree_skb(skb1);
1264 } 1159 }
1265 sk = sknext; 1160 sk = sknext;
@@ -1346,7 +1241,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1346 return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); 1241 return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
1347 1242
1348 sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, 1243 sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
1349 skb->dev->ifindex, udptable); 1244 skb->dev->ifindex, udptable );
1350 1245
1351 if (sk != NULL) { 1246 if (sk != NULL) {
1352 int ret = udp_queue_rcv_skb(sk, skb); 1247 int ret = udp_queue_rcv_skb(sk, skb);
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
index 06d94195e644..820a477cfaa6 100644
--- a/net/ipv4/udp_impl.h
+++ b/net/ipv4/udp_impl.h
@@ -5,14 +5,14 @@
5#include <net/protocol.h> 5#include <net/protocol.h>
6#include <net/inet_common.h> 6#include <net/inet_common.h>
7 7
8extern const struct udp_get_port_ops udp_ipv4_ops;
9
10extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); 8extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int );
11extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); 9extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []);
12 10
13extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, 11extern int __udp_lib_get_port(struct sock *sk, unsigned short snum,
14 struct hlist_head udptable[], int *port_rover, 12 struct hlist_head udptable[], int *port_rover,
15 const struct udp_get_port_ops *ops); 13 int (*)(const struct sock*,const struct sock*));
14extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
15
16 16
17extern int udp_setsockopt(struct sock *sk, int level, int optname, 17extern int udp_setsockopt(struct sock *sk, int level, int optname,
18 char __user *optval, int optlen); 18 char __user *optval, int optlen);
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index 3653b32dce2d..f34fd686a8f1 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -19,15 +19,14 @@ struct hlist_head udplite_hash[UDP_HTABLE_SIZE];
19static int udplite_port_rover; 19static int udplite_port_rover;
20 20
21int udplite_get_port(struct sock *sk, unsigned short p, 21int udplite_get_port(struct sock *sk, unsigned short p,
22 const struct udp_get_port_ops *ops) 22 int (*c)(const struct sock *, const struct sock *))
23{ 23{
24 return __udp_lib_get_port(sk, p, udplite_hash, 24 return __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c);
25 &udplite_port_rover, ops);
26} 25}
27 26
28static int udplite_v4_get_port(struct sock *sk, unsigned short snum) 27static int udplite_v4_get_port(struct sock *sk, unsigned short snum)
29{ 28{
30 return udplite_get_port(sk, snum, &udp_ipv4_ops); 29 return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal);
31} 30}
32 31
33static int udplite_rcv(struct sk_buff *skb) 32static int udplite_rcv(struct sk_buff *skb)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 329de679ac38..5a5f8bd4597a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2990,7 +2990,7 @@ static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
2990 return pfx; 2990 return pfx;
2991} 2991}
2992 2992
2993static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = { 2993static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
2994 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, 2994 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
2995 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, 2995 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
2996 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, 2996 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index fc3882c90604..53b3998a486c 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -157,7 +157,7 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
157 return 1; 157 return 1;
158} 158}
159 159
160static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { 160static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = {
161 FRA_GENERIC_POLICY, 161 FRA_GENERIC_POLICY,
162}; 162};
163 163
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index dc442fb791b0..1b1797f1f33d 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
160{ 160{
161 struct nf_conn *ct; 161 struct nf_conn *ct;
162 struct nf_conn_help *help; 162 struct nf_conn_help *help;
163 struct nf_conntrack_helper *helper;
163 enum ip_conntrack_info ctinfo; 164 enum ip_conntrack_info ctinfo;
164 unsigned int ret, protoff; 165 unsigned int ret, protoff;
165 unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; 166 unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
@@ -172,7 +173,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
172 goto out; 173 goto out;
173 174
174 help = nfct_help(ct); 175 help = nfct_help(ct);
175 if (!help || !help->helper) 176 if (!help)
177 goto out;
178 /* rcu_read_lock()ed by nf_hook_slow */
179 helper = rcu_dereference(help->helper);
180 if (!helper)
176 goto out; 181 goto out;
177 182
178 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, 183 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
@@ -182,7 +187,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
182 return NF_ACCEPT; 187 return NF_ACCEPT;
183 } 188 }
184 189
185 ret = help->helper->help(pskb, protoff, ct, ctinfo); 190 ret = helper->help(pskb, protoff, ct, ctinfo);
186 if (ret != NF_ACCEPT) 191 if (ret != NF_ACCEPT)
187 return ret; 192 return ret;
188out: 193out:
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1324b06796c0..fe8d9837f9f8 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1999,7 +1999,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned mtu)
1999 fib6_clean_all(rt6_mtu_change_route, 0, &arg); 1999 fib6_clean_all(rt6_mtu_change_route, 0, &arg);
2000} 2000}
2001 2001
2002static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = { 2002static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
2003 [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, 2003 [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) },
2004 [RTA_OIF] = { .type = NLA_U32 }, 2004 [RTA_OIF] = { .type = NLA_U32 },
2005 [RTA_IIF] = { .type = NLA_U32 }, 2005 [RTA_IIF] = { .type = NLA_U32 },
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d1fbddd172e7..4210951edb6e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -52,28 +52,9 @@
52 52
53DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; 53DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
54 54
55static int ipv6_rcv_saddr_any(const struct sock *sk)
56{
57 struct ipv6_pinfo *np = inet6_sk(sk);
58
59 return ipv6_addr_any(&np->rcv_saddr);
60}
61
62static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port,
63 const struct sock *sk)
64{
65 return port;
66}
67
68const struct udp_get_port_ops udp_ipv6_ops = {
69 .saddr_cmp = ipv6_rcv_saddr_equal,
70 .saddr_any = ipv6_rcv_saddr_any,
71 .hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr,
72};
73
74static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) 55static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
75{ 56{
76 return udp_get_port(sk, snum, &udp_ipv6_ops); 57 return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
77} 58}
78 59
79static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, 60static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 36b0c11a28a3..6e252f318f7c 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -6,8 +6,6 @@
6#include <net/addrconf.h> 6#include <net/addrconf.h>
7#include <net/inet_common.h> 7#include <net/inet_common.h>
8 8
9extern const struct udp_get_port_ops udp_ipv6_ops;
10
11extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); 9extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int );
12extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, 10extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
13 int , int , int , __be32 , struct hlist_head []); 11 int , int , int , __be32 , struct hlist_head []);
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index c40a51362f89..f54016a55004 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = {
37 37
38static int udplite_v6_get_port(struct sock *sk, unsigned short snum) 38static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
39{ 39{
40 return udplite_get_port(sk, snum, &udp_ipv6_ops); 40 return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
41} 41}
42 42
43struct proto udplitev6_prot = { 43struct proto udplitev6_prot = {
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
index 0b02073ffdf3..a8b8873aa263 100644
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -317,23 +317,6 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
317} 317}
318 318
319/* 319/*
320 * Function irlap_next_state (self, state)
321 *
322 * Switches state and provides debug information
323 *
324 */
325static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state)
326{
327 /*
328 if (!self || self->magic != LAP_MAGIC)
329 return;
330
331 IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[state]);
332 */
333 self->state = state;
334}
335
336/*
337 * Function irlap_state_ndm (event, skb, frame) 320 * Function irlap_state_ndm (event, skb, frame)
338 * 321 *
339 * NDM (Normal Disconnected Mode) state 322 * NDM (Normal Disconnected Mode) state
@@ -1086,7 +1069,6 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
1086 } else { 1069 } else {
1087 /* Final packet of window */ 1070 /* Final packet of window */
1088 irlap_send_data_primary_poll(self, skb); 1071 irlap_send_data_primary_poll(self, skb);
1089 irlap_next_state(self, LAP_NRM_P);
1090 1072
1091 /* 1073 /*
1092 * Make sure state machine does not try to send 1074 * Make sure state machine does not try to send
@@ -1436,14 +1418,14 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
1436 */ 1418 */
1437 self->remote_busy = FALSE; 1419 self->remote_busy = FALSE;
1438 1420
1421 /* Stop final timer */
1422 del_timer(&self->final_timer);
1423
1439 /* 1424 /*
1440 * Nr as expected? 1425 * Nr as expected?
1441 */ 1426 */
1442 ret = irlap_validate_nr_received(self, info->nr); 1427 ret = irlap_validate_nr_received(self, info->nr);
1443 if (ret == NR_EXPECTED) { 1428 if (ret == NR_EXPECTED) {
1444 /* Stop final timer */
1445 del_timer(&self->final_timer);
1446
1447 /* Update Nr received */ 1429 /* Update Nr received */
1448 irlap_update_nr_received(self, info->nr); 1430 irlap_update_nr_received(self, info->nr);
1449 1431
@@ -1475,14 +1457,12 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
1475 1457
1476 /* Resend rejected frames */ 1458 /* Resend rejected frames */
1477 irlap_resend_rejected_frames(self, CMD_FRAME); 1459 irlap_resend_rejected_frames(self, CMD_FRAME);
1478 1460 irlap_start_final_timer(self, self->final_timeout * 2);
1479 /* Final timer ??? Jean II */
1480 1461
1481 irlap_next_state(self, LAP_NRM_P); 1462 irlap_next_state(self, LAP_NRM_P);
1482 } else if (ret == NR_INVALID) { 1463 } else if (ret == NR_INVALID) {
1483 IRDA_DEBUG(1, "%s(), Received RR with " 1464 IRDA_DEBUG(1, "%s(), Received RR with "
1484 "invalid nr !\n", __FUNCTION__); 1465 "invalid nr !\n", __FUNCTION__);
1485 del_timer(&self->final_timer);
1486 1466
1487 irlap_next_state(self, LAP_RESET_WAIT); 1467 irlap_next_state(self, LAP_RESET_WAIT);
1488 1468
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
index 3c5a68e36414..3013c49ab975 100644
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -798,16 +798,19 @@ void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
798 self->vs = (self->vs + 1) % 8; 798 self->vs = (self->vs + 1) % 8;
799 self->ack_required = FALSE; 799 self->ack_required = FALSE;
800 800
801 irlap_next_state(self, LAP_NRM_P);
801 irlap_send_i_frame(self, tx_skb, CMD_FRAME); 802 irlap_send_i_frame(self, tx_skb, CMD_FRAME);
802 } else { 803 } else {
803 IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__); 804 IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
804 805
805 if (self->ack_required) { 806 if (self->ack_required) {
806 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME); 807 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
808 irlap_next_state(self, LAP_NRM_P);
807 irlap_send_rr_frame(self, CMD_FRAME); 809 irlap_send_rr_frame(self, CMD_FRAME);
808 self->ack_required = FALSE; 810 self->ack_required = FALSE;
809 } else { 811 } else {
810 skb->data[1] |= PF_BIT; 812 skb->data[1] |= PF_BIT;
813 irlap_next_state(self, LAP_NRM_P);
811 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME); 814 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
812 } 815 }
813 } 816 }
diff --git a/net/key/af_key.c b/net/key/af_key.c
index d302ddae580c..0f8304b0246b 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1682,6 +1682,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
1682 unsigned proto; 1682 unsigned proto;
1683 struct km_event c; 1683 struct km_event c;
1684 struct xfrm_audit audit_info; 1684 struct xfrm_audit audit_info;
1685 int err;
1685 1686
1686 proto = pfkey_satype2proto(hdr->sadb_msg_satype); 1687 proto = pfkey_satype2proto(hdr->sadb_msg_satype);
1687 if (proto == 0) 1688 if (proto == 0)
@@ -1689,7 +1690,9 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
1689 1690
1690 audit_info.loginuid = audit_get_loginuid(current->audit_context); 1691 audit_info.loginuid = audit_get_loginuid(current->audit_context);
1691 audit_info.secid = 0; 1692 audit_info.secid = 0;
1692 xfrm_state_flush(proto, &audit_info); 1693 err = xfrm_state_flush(proto, &audit_info);
1694 if (err)
1695 return err;
1693 c.data.proto = proto; 1696 c.data.proto = proto;
1694 c.seq = hdr->sadb_msg_seq; 1697 c.seq = hdr->sadb_msg_seq;
1695 c.pid = hdr->sadb_msg_pid; 1698 c.pid = hdr->sadb_msg_pid;
@@ -2683,10 +2686,13 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2683{ 2686{
2684 struct km_event c; 2687 struct km_event c;
2685 struct xfrm_audit audit_info; 2688 struct xfrm_audit audit_info;
2689 int err;
2686 2690
2687 audit_info.loginuid = audit_get_loginuid(current->audit_context); 2691 audit_info.loginuid = audit_get_loginuid(current->audit_context);
2688 audit_info.secid = 0; 2692 audit_info.secid = 0;
2689 xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); 2693 err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
2694 if (err)
2695 return err;
2690 c.data.type = XFRM_POLICY_TYPE_MAIN; 2696 c.data.type = XFRM_POLICY_TYPE_MAIN;
2691 c.event = XFRM_MSG_FLUSHPOLICY; 2697 c.event = XFRM_MSG_FLUSHPOLICY;
2692 c.pid = hdr->sadb_msg_pid; 2698 c.pid = hdr->sadb_msg_pid;
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index b8869eab7650..0568f2e86b59 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -208,13 +208,14 @@ static int __init nf_conntrack_amanda_init(void)
208{ 208{
209 int ret, i; 209 int ret, i;
210 210
211 ret = -ENOMEM;
212 for (i = 0; i < ARRAY_SIZE(search); i++) { 211 for (i = 0; i < ARRAY_SIZE(search); i++) {
213 search[i].ts = textsearch_prepare(ts_algo, search[i].string, 212 search[i].ts = textsearch_prepare(ts_algo, search[i].string,
214 search[i].len, 213 search[i].len,
215 GFP_KERNEL, TS_AUTOLOAD); 214 GFP_KERNEL, TS_AUTOLOAD);
216 if (search[i].ts == NULL) 215 if (IS_ERR(search[i].ts)) {
216 ret = PTR_ERR(search[i].ts);
217 goto err1; 217 goto err1;
218 }
218 } 219 }
219 ret = nf_conntrack_helper_register(&amanda_helper[0]); 220 ret = nf_conntrack_helper_register(&amanda_helper[0]);
220 if (ret < 0) 221 if (ret < 0)
@@ -227,10 +228,9 @@ static int __init nf_conntrack_amanda_init(void)
227err2: 228err2:
228 nf_conntrack_helper_unregister(&amanda_helper[0]); 229 nf_conntrack_helper_unregister(&amanda_helper[0]);
229err1: 230err1:
230 for (; i >= 0; i--) { 231 while (--i >= 0)
231 if (search[i].ts) 232 textsearch_destroy(search[i].ts);
232 textsearch_destroy(search[i].ts); 233
233 }
234 return ret; 234 return ret;
235} 235}
236 236
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 483e927a9ca4..7a15e30356f2 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -350,9 +350,15 @@ static void death_by_timeout(unsigned long ul_conntrack)
350{ 350{
351 struct nf_conn *ct = (void *)ul_conntrack; 351 struct nf_conn *ct = (void *)ul_conntrack;
352 struct nf_conn_help *help = nfct_help(ct); 352 struct nf_conn_help *help = nfct_help(ct);
353 struct nf_conntrack_helper *helper;
353 354
354 if (help && help->helper && help->helper->destroy) 355 if (help) {
355 help->helper->destroy(ct); 356 rcu_read_lock();
357 helper = rcu_dereference(help->helper);
358 if (helper && helper->destroy)
359 helper->destroy(ct);
360 rcu_read_unlock();
361 }
356 362
357 write_lock_bh(&nf_conntrack_lock); 363 write_lock_bh(&nf_conntrack_lock);
358 /* Inside lock so preempt is disabled on module removal path. 364 /* Inside lock so preempt is disabled on module removal path.
@@ -661,6 +667,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
661 unsigned int dataoff) 667 unsigned int dataoff)
662{ 668{
663 struct nf_conn *conntrack; 669 struct nf_conn *conntrack;
670 struct nf_conn_help *help;
664 struct nf_conntrack_tuple repl_tuple; 671 struct nf_conntrack_tuple repl_tuple;
665 struct nf_conntrack_expect *exp; 672 struct nf_conntrack_expect *exp;
666 u_int32_t features = 0; 673 u_int32_t features = 0;
@@ -691,6 +698,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
691 write_lock_bh(&nf_conntrack_lock); 698 write_lock_bh(&nf_conntrack_lock);
692 exp = find_expectation(tuple); 699 exp = find_expectation(tuple);
693 700
701 help = nfct_help(conntrack);
694 if (exp) { 702 if (exp) {
695 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", 703 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
696 conntrack, exp); 704 conntrack, exp);
@@ -698,7 +706,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
698 __set_bit(IPS_EXPECTED_BIT, &conntrack->status); 706 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
699 conntrack->master = exp->master; 707 conntrack->master = exp->master;
700 if (exp->helper) 708 if (exp->helper)
701 nfct_help(conntrack)->helper = exp->helper; 709 rcu_assign_pointer(help->helper, exp->helper);
702#ifdef CONFIG_NF_CONNTRACK_MARK 710#ifdef CONFIG_NF_CONNTRACK_MARK
703 conntrack->mark = exp->master->mark; 711 conntrack->mark = exp->master->mark;
704#endif 712#endif
@@ -708,10 +716,11 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
708 nf_conntrack_get(&conntrack->master->ct_general); 716 nf_conntrack_get(&conntrack->master->ct_general);
709 NF_CT_STAT_INC(expect_new); 717 NF_CT_STAT_INC(expect_new);
710 } else { 718 } else {
711 struct nf_conn_help *help = nfct_help(conntrack); 719 if (help) {
712 720 /* not in hash table yet, so not strictly necessary */
713 if (help) 721 rcu_assign_pointer(help->helper,
714 help->helper = __nf_ct_helper_find(&repl_tuple); 722 __nf_ct_helper_find(&repl_tuple));
723 }
715 NF_CT_STAT_INC(new); 724 NF_CT_STAT_INC(new);
716 } 725 }
717 726
@@ -893,7 +902,8 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
893 helper = __nf_ct_helper_find(newreply); 902 helper = __nf_ct_helper_find(newreply);
894 if (helper) 903 if (helper)
895 memset(&help->help, 0, sizeof(help->help)); 904 memset(&help->help, 0, sizeof(help->help));
896 help->helper = helper; 905 /* not in hash table yet, so not strictly necessary */
906 rcu_assign_pointer(help->helper, helper);
897 } 907 }
898 write_unlock_bh(&nf_conntrack_lock); 908 write_unlock_bh(&nf_conntrack_lock);
899} 909}
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 117cbfdb910c..504fb6c083f9 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -337,6 +337,10 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
337 NF_CT_ASSERT(master_help); 337 NF_CT_ASSERT(master_help);
338 338
339 write_lock_bh(&nf_conntrack_lock); 339 write_lock_bh(&nf_conntrack_lock);
340 if (!master_help->helper) {
341 ret = -ESHUTDOWN;
342 goto out;
343 }
340 list_for_each_entry(i, &nf_conntrack_expect_list, list) { 344 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
341 if (expect_matches(i, expect)) { 345 if (expect_matches(i, expect)) {
342 /* Refresh timer: if it's dying, ignore.. */ 346 /* Refresh timer: if it's dying, ignore.. */
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 0743be4434b0..f868b7fbd9b4 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -93,7 +93,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,
93 93
94 if (help && help->helper == me) { 94 if (help && help->helper == me) {
95 nf_conntrack_event(IPCT_HELPER, ct); 95 nf_conntrack_event(IPCT_HELPER, ct);
96 help->helper = NULL; 96 rcu_assign_pointer(help->helper, NULL);
97 } 97 }
98 return 0; 98 return 0;
99} 99}
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index d6d39e241327..3f73327794ab 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -171,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
171{ 171{
172 struct nfattr *nest_helper; 172 struct nfattr *nest_helper;
173 const struct nf_conn_help *help = nfct_help(ct); 173 const struct nf_conn_help *help = nfct_help(ct);
174 struct nf_conntrack_helper *helper;
174 175
175 if (!help || !help->helper) 176 if (!help)
176 return 0; 177 return 0;
177 178
179 rcu_read_lock();
180 helper = rcu_dereference(help->helper);
181 if (!helper)
182 goto out;
183
178 nest_helper = NFA_NEST(skb, CTA_HELP); 184 nest_helper = NFA_NEST(skb, CTA_HELP);
179 NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name); 185 NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name);
180 186
181 if (help->helper->to_nfattr) 187 if (helper->to_nfattr)
182 help->helper->to_nfattr(skb, ct); 188 helper->to_nfattr(skb, ct);
183 189
184 NFA_NEST_END(skb, nest_helper); 190 NFA_NEST_END(skb, nest_helper);
185 191out:
192 rcu_read_unlock();
186 return 0; 193 return 0;
187 194
188nfattr_failure: 195nfattr_failure:
196 rcu_read_unlock();
189 return -1; 197 return -1;
190} 198}
191 199
@@ -842,7 +850,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
842 if (help && help->helper) { 850 if (help && help->helper) {
843 /* we had a helper before ... */ 851 /* we had a helper before ... */
844 nf_ct_remove_expectations(ct); 852 nf_ct_remove_expectations(ct);
845 help->helper = NULL; 853 rcu_assign_pointer(help->helper, NULL);
846 } 854 }
847 855
848 return 0; 856 return 0;
@@ -866,7 +874,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
866 874
867 /* need to zero data of old helper */ 875 /* need to zero data of old helper */
868 memset(&help->help, 0, sizeof(help->help)); 876 memset(&help->help, 0, sizeof(help->help));
869 help->helper = helper; 877 rcu_assign_pointer(help->helper, helper);
870 878
871 return 0; 879 return 0;
872} 880}
@@ -950,6 +958,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
950 struct nf_conn *ct; 958 struct nf_conn *ct;
951 int err = -EINVAL; 959 int err = -EINVAL;
952 struct nf_conn_help *help; 960 struct nf_conn_help *help;
961 struct nf_conntrack_helper *helper = NULL;
953 962
954 ct = nf_conntrack_alloc(otuple, rtuple); 963 ct = nf_conntrack_alloc(otuple, rtuple);
955 if (ct == NULL || IS_ERR(ct)) 964 if (ct == NULL || IS_ERR(ct))
@@ -980,14 +989,17 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
980#endif 989#endif
981 990
982 help = nfct_help(ct); 991 help = nfct_help(ct);
983 if (help) 992 if (help) {
984 help->helper = nf_ct_helper_find_get(rtuple); 993 helper = nf_ct_helper_find_get(rtuple);
994 /* not in hash table yet so not strictly necessary */
995 rcu_assign_pointer(help->helper, helper);
996 }
985 997
986 add_timer(&ct->timeout); 998 add_timer(&ct->timeout);
987 nf_conntrack_hash_insert(ct); 999 nf_conntrack_hash_insert(ct);
988 1000
989 if (help && help->helper) 1001 if (helper)
990 nf_ct_helper_put(help->helper); 1002 nf_ct_helper_put(helper);
991 1003
992 return 0; 1004 return 0;
993 1005
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 5434472420fe..339c397d1b5f 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -100,7 +100,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
100 struct nf_conn_help *help = nfct_help(ct); 100 struct nf_conn_help *help = nfct_help(ct);
101 struct nf_ct_gre_keymap **kmp, *km; 101 struct nf_ct_gre_keymap **kmp, *km;
102 102
103 BUG_ON(strcmp(help->helper->name, "pptp"));
104 kmp = &help->help.ct_pptp_info.keymap[dir]; 103 kmp = &help->help.ct_pptp_info.keymap[dir];
105 if (*kmp) { 104 if (*kmp) {
106 /* check whether it's a retransmission */ 105 /* check whether it's a retransmission */
@@ -137,7 +136,6 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
137 enum ip_conntrack_dir dir; 136 enum ip_conntrack_dir dir;
138 137
139 DEBUGP("entering for ct %p\n", ct); 138 DEBUGP("entering for ct %p\n", ct);
140 BUG_ON(strcmp(help->helper->name, "pptp"));
141 139
142 write_lock_bh(&nf_ct_gre_lock); 140 write_lock_bh(&nf_ct_gre_lock);
143 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { 141 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 07e47dbcb0a9..24b660f16ce3 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -59,7 +59,7 @@ static struct genl_family netlbl_cipsov4_gnl_family = {
59}; 59};
60 60
61/* NetLabel Netlink attribute policy */ 61/* NetLabel Netlink attribute policy */
62static struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { 62static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
63 [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 }, 63 [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 },
64 [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 }, 64 [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 },
65 [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 }, 65 [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 },
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index f2535e7f2869..b165712aaa70 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -246,19 +246,18 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
246 246
247/** 247/**
248 * netlbl_socket_setattr - Label a socket using the correct protocol 248 * netlbl_socket_setattr - Label a socket using the correct protocol
249 * @sock: the socket to label 249 * @sk: the socket to label
250 * @secattr: the security attributes 250 * @secattr: the security attributes
251 * 251 *
252 * Description: 252 * Description:
253 * Attach the correct label to the given socket using the security attributes 253 * Attach the correct label to the given socket using the security attributes
254 * specified in @secattr. This function requires exclusive access to 254 * specified in @secattr. This function requires exclusive access to @sk,
255 * @sock->sk, which means it either needs to be in the process of being 255 * which means it either needs to be in the process of being created or locked.
256 * created or locked via lock_sock(sock->sk). Returns zero on success, 256 * Returns zero on success, negative values on failure.
257 * negative values on failure.
258 * 257 *
259 */ 258 */
260int netlbl_socket_setattr(const struct socket *sock, 259int netlbl_sock_setattr(struct sock *sk,
261 const struct netlbl_lsm_secattr *secattr) 260 const struct netlbl_lsm_secattr *secattr)
262{ 261{
263 int ret_val = -ENOENT; 262 int ret_val = -ENOENT;
264 struct netlbl_dom_map *dom_entry; 263 struct netlbl_dom_map *dom_entry;
@@ -269,9 +268,9 @@ int netlbl_socket_setattr(const struct socket *sock,
269 goto socket_setattr_return; 268 goto socket_setattr_return;
270 switch (dom_entry->type) { 269 switch (dom_entry->type) {
271 case NETLBL_NLTYPE_CIPSOV4: 270 case NETLBL_NLTYPE_CIPSOV4:
272 ret_val = cipso_v4_socket_setattr(sock, 271 ret_val = cipso_v4_sock_setattr(sk,
273 dom_entry->type_def.cipsov4, 272 dom_entry->type_def.cipsov4,
274 secattr); 273 secattr);
275 break; 274 break;
276 case NETLBL_NLTYPE_UNLABELED: 275 case NETLBL_NLTYPE_UNLABELED:
277 ret_val = 0; 276 ret_val = 0;
@@ -309,30 +308,6 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
309} 308}
310 309
311/** 310/**
312 * netlbl_socket_getattr - Determine the security attributes of a socket
313 * @sock: the socket
314 * @secattr: the security attributes
315 *
316 * Description:
317 * Examines the given socket to see any NetLabel style labeling has been
318 * applied to the socket, if so it parses the socket label and returns the
319 * security attributes in @secattr. Returns zero on success, negative values
320 * on failure.
321 *
322 */
323int netlbl_socket_getattr(const struct socket *sock,
324 struct netlbl_lsm_secattr *secattr)
325{
326 int ret_val;
327
328 ret_val = cipso_v4_socket_getattr(sock, secattr);
329 if (ret_val == 0)
330 return 0;
331
332 return netlbl_unlabel_getattr(secattr);
333}
334
335/**
336 * netlbl_skbuff_getattr - Determine the security attributes of a packet 311 * netlbl_skbuff_getattr - Determine the security attributes of a packet
337 * @skb: the packet 312 * @skb: the packet
338 * @secattr: the security attributes 313 * @secattr: the security attributes
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index e8c80f33f3d7..e00fc219c72b 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -59,7 +59,7 @@ static struct genl_family netlbl_mgmt_gnl_family = {
59}; 59};
60 60
61/* NetLabel Netlink attribute policy */ 61/* NetLabel Netlink attribute policy */
62static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { 62static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
63 [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING }, 63 [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING },
64 [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 }, 64 [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 },
65 [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 }, 65 [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 },
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index b931edee4b8b..5c303c68af1d 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -61,7 +61,7 @@ static struct genl_family netlbl_unlabel_gnl_family = {
61}; 61};
62 62
63/* NetLabel Netlink attribute policy */ 63/* NetLabel Netlink attribute policy */
64static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { 64static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
65 [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, 65 [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
66}; 66};
67 67
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
index df5f820a4c32..c591212793ee 100644
--- a/net/netlink/attr.c
+++ b/net/netlink/attr.c
@@ -24,9 +24,9 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
24}; 24};
25 25
26static int validate_nla(struct nlattr *nla, int maxtype, 26static int validate_nla(struct nlattr *nla, int maxtype,
27 struct nla_policy *policy) 27 const struct nla_policy *policy)
28{ 28{
29 struct nla_policy *pt; 29 const struct nla_policy *pt;
30 int minlen = 0, attrlen = nla_len(nla); 30 int minlen = 0, attrlen = nla_len(nla);
31 31
32 if (nla->nla_type <= 0 || nla->nla_type > maxtype) 32 if (nla->nla_type <= 0 || nla->nla_type > maxtype)
@@ -99,7 +99,7 @@ static int validate_nla(struct nlattr *nla, int maxtype,
99 * Returns 0 on success or a negative error code. 99 * Returns 0 on success or a negative error code.
100 */ 100 */
101int nla_validate(struct nlattr *head, int len, int maxtype, 101int nla_validate(struct nlattr *head, int len, int maxtype,
102 struct nla_policy *policy) 102 const struct nla_policy *policy)
103{ 103{
104 struct nlattr *nla; 104 struct nlattr *nla;
105 int rem, err; 105 int rem, err;
@@ -130,7 +130,7 @@ errout:
130 * Returns 0 on success or a negative error code. 130 * Returns 0 on success or a negative error code.
131 */ 131 */
132int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, 132int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
133 struct nla_policy *policy) 133 const struct nla_policy *policy)
134{ 134{
135 struct nlattr *nla; 135 struct nlattr *nla;
136 int rem, err; 136 int rem, err;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 6e31234a4196..b9ab62f938d0 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -472,7 +472,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
472 return skb; 472 return skb;
473} 473}
474 474
475static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = { 475static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
476 [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, 476 [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
477 [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, 477 [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
478 .len = GENL_NAMSIZ - 1 }, 478 .len = GENL_NAMSIZ - 1 },
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index be7d299acd73..d1c383fca82c 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -599,6 +599,7 @@ static void atm_tc_destroy(struct Qdisc *sch)
599 /* races ? */ 599 /* races ? */
600 while ((flow = p->flows)) { 600 while ((flow = p->flows)) {
601 tcf_destroy_chain(flow->filter_list); 601 tcf_destroy_chain(flow->filter_list);
602 flow->filter_list = NULL;
602 if (flow->ref > 1) 603 if (flow->ref > 1)
603 printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, 604 printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
604 flow->ref); 605 flow->ref);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index a294542cb8e4..ee2d5967d109 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1748,10 +1748,12 @@ cbq_destroy(struct Qdisc* sch)
1748 * classes from root to leafs which means that filters can still 1748 * classes from root to leafs which means that filters can still
1749 * be bound to classes which have been destroyed already. --TGR '04 1749 * be bound to classes which have been destroyed already. --TGR '04
1750 */ 1750 */
1751 for (h = 0; h < 16; h++) 1751 for (h = 0; h < 16; h++) {
1752 for (cl = q->classes[h]; cl; cl = cl->next) 1752 for (cl = q->classes[h]; cl; cl = cl->next) {
1753 tcf_destroy_chain(cl->filter_list); 1753 tcf_destroy_chain(cl->filter_list);
1754 1754 cl->filter_list = NULL;
1755 }
1756 }
1755 for (h = 0; h < 16; h++) { 1757 for (h = 0; h < 16; h++) {
1756 struct cbq_class *next; 1758 struct cbq_class *next;
1757 1759
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 87c794d8fa2d..d70fa30d4294 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1744,20 +1744,23 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1744 int chunk; 1744 int chunk;
1745 struct sk_buff *skb; 1745 struct sk_buff *skb;
1746 1746
1747 unix_state_lock(sk);
1747 skb = skb_dequeue(&sk->sk_receive_queue); 1748 skb = skb_dequeue(&sk->sk_receive_queue);
1748 if (skb==NULL) 1749 if (skb==NULL)
1749 { 1750 {
1750 if (copied >= target) 1751 if (copied >= target)
1751 break; 1752 goto unlock;
1752 1753
1753 /* 1754 /*
1754 * POSIX 1003.1g mandates this order. 1755 * POSIX 1003.1g mandates this order.
1755 */ 1756 */
1756 1757
1757 if ((err = sock_error(sk)) != 0) 1758 if ((err = sock_error(sk)) != 0)
1758 break; 1759 goto unlock;
1759 if (sk->sk_shutdown & RCV_SHUTDOWN) 1760 if (sk->sk_shutdown & RCV_SHUTDOWN)
1760 break; 1761 goto unlock;
1762
1763 unix_state_unlock(sk);
1761 err = -EAGAIN; 1764 err = -EAGAIN;
1762 if (!timeo) 1765 if (!timeo)
1763 break; 1766 break;
@@ -1771,7 +1774,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1771 } 1774 }
1772 mutex_lock(&u->readlock); 1775 mutex_lock(&u->readlock);
1773 continue; 1776 continue;
1777 unlock:
1778 unix_state_unlock(sk);
1779 break;
1774 } 1780 }
1781 unix_state_unlock(sk);
1775 1782
1776 if (check_creds) { 1783 if (check_creds) {
1777 /* Never glue messages from different writers */ 1784 /* Never glue messages from different writers */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 64a375178c5f..157bfbd250ba 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -834,11 +834,67 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
834} 834}
835EXPORT_SYMBOL(xfrm_policy_byid); 835EXPORT_SYMBOL(xfrm_policy_byid);
836 836
837void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) 837#ifdef CONFIG_SECURITY_NETWORK_XFRM
838static inline int
839xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
838{ 840{
839 int dir; 841 int dir, err = 0;
842
843 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
844 struct xfrm_policy *pol;
845 struct hlist_node *entry;
846 int i;
847
848 hlist_for_each_entry(pol, entry,
849 &xfrm_policy_inexact[dir], bydst) {
850 if (pol->type != type)
851 continue;
852 err = security_xfrm_policy_delete(pol);
853 if (err) {
854 xfrm_audit_log(audit_info->loginuid,
855 audit_info->secid,
856 AUDIT_MAC_IPSEC_DELSPD, 0,
857 pol, NULL);
858 return err;
859 }
860 }
861 for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
862 hlist_for_each_entry(pol, entry,
863 xfrm_policy_bydst[dir].table + i,
864 bydst) {
865 if (pol->type != type)
866 continue;
867 err = security_xfrm_policy_delete(pol);
868 if (err) {
869 xfrm_audit_log(audit_info->loginuid,
870 audit_info->secid,
871 AUDIT_MAC_IPSEC_DELSPD,
872 0, pol, NULL);
873 return err;
874 }
875 }
876 }
877 }
878 return err;
879}
880#else
881static inline int
882xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
883{
884 return 0;
885}
886#endif
887
888int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
889{
890 int dir, err = 0;
840 891
841 write_lock_bh(&xfrm_policy_lock); 892 write_lock_bh(&xfrm_policy_lock);
893
894 err = xfrm_policy_flush_secctx_check(type, audit_info);
895 if (err)
896 goto out;
897
842 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { 898 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
843 struct xfrm_policy *pol; 899 struct xfrm_policy *pol;
844 struct hlist_node *entry; 900 struct hlist_node *entry;
@@ -891,7 +947,9 @@ void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
891 xfrm_policy_count[dir] -= killed; 947 xfrm_policy_count[dir] -= killed;
892 } 948 }
893 atomic_inc(&flow_cache_genid); 949 atomic_inc(&flow_cache_genid);
950out:
894 write_unlock_bh(&xfrm_policy_lock); 951 write_unlock_bh(&xfrm_policy_lock);
952 return err;
895} 953}
896EXPORT_SYMBOL(xfrm_policy_flush); 954EXPORT_SYMBOL(xfrm_policy_flush);
897 955
@@ -2583,4 +2641,3 @@ restore_state:
2583} 2641}
2584EXPORT_SYMBOL(xfrm_migrate); 2642EXPORT_SYMBOL(xfrm_migrate);
2585#endif 2643#endif
2586
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 372f06eb8bb7..85f3f43a6cca 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -391,12 +391,48 @@ int xfrm_state_delete(struct xfrm_state *x)
391} 391}
392EXPORT_SYMBOL(xfrm_state_delete); 392EXPORT_SYMBOL(xfrm_state_delete);
393 393
394void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) 394#ifdef CONFIG_SECURITY_NETWORK_XFRM
395static inline int
396xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
395{ 397{
396 int i; 398 int i, err = 0;
397 int err = 0; 399
400 for (i = 0; i <= xfrm_state_hmask; i++) {
401 struct hlist_node *entry;
402 struct xfrm_state *x;
403
404 hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
405 if (xfrm_id_proto_match(x->id.proto, proto) &&
406 (err = security_xfrm_state_delete(x)) != 0) {
407 xfrm_audit_log(audit_info->loginuid,
408 audit_info->secid,
409 AUDIT_MAC_IPSEC_DELSA,
410 0, NULL, x);
411
412 return err;
413 }
414 }
415 }
416
417 return err;
418}
419#else
420static inline int
421xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
422{
423 return 0;
424}
425#endif
426
427int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
428{
429 int i, err = 0;
398 430
399 spin_lock_bh(&xfrm_state_lock); 431 spin_lock_bh(&xfrm_state_lock);
432 err = xfrm_state_flush_secctx_check(proto, audit_info);
433 if (err)
434 goto out;
435
400 for (i = 0; i <= xfrm_state_hmask; i++) { 436 for (i = 0; i <= xfrm_state_hmask; i++) {
401 struct hlist_node *entry; 437 struct hlist_node *entry;
402 struct xfrm_state *x; 438 struct xfrm_state *x;
@@ -419,8 +455,12 @@ restart:
419 } 455 }
420 } 456 }
421 } 457 }
458 err = 0;
459
460out:
422 spin_unlock_bh(&xfrm_state_lock); 461 spin_unlock_bh(&xfrm_state_lock);
423 wake_up(&km_waitq); 462 wake_up(&km_waitq);
463 return err;
424} 464}
425EXPORT_SYMBOL(xfrm_state_flush); 465EXPORT_SYMBOL(xfrm_state_flush);
426 466
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b14c7e590c31..c06883bf620e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1418,10 +1418,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
1418 struct km_event c; 1418 struct km_event c;
1419 struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); 1419 struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
1420 struct xfrm_audit audit_info; 1420 struct xfrm_audit audit_info;
1421 int err;
1421 1422
1422 audit_info.loginuid = NETLINK_CB(skb).loginuid; 1423 audit_info.loginuid = NETLINK_CB(skb).loginuid;
1423 audit_info.secid = NETLINK_CB(skb).sid; 1424 audit_info.secid = NETLINK_CB(skb).sid;
1424 xfrm_state_flush(p->proto, &audit_info); 1425 err = xfrm_state_flush(p->proto, &audit_info);
1426 if (err)
1427 return err;
1425 c.data.proto = p->proto; 1428 c.data.proto = p->proto;
1426 c.event = nlh->nlmsg_type; 1429 c.event = nlh->nlmsg_type;
1427 c.seq = nlh->nlmsg_seq; 1430 c.seq = nlh->nlmsg_seq;
@@ -1582,7 +1585,9 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1582 1585
1583 audit_info.loginuid = NETLINK_CB(skb).loginuid; 1586 audit_info.loginuid = NETLINK_CB(skb).loginuid;
1584 audit_info.secid = NETLINK_CB(skb).sid; 1587 audit_info.secid = NETLINK_CB(skb).sid;
1585 xfrm_policy_flush(type, &audit_info); 1588 err = xfrm_policy_flush(type, &audit_info);
1589 if (err)
1590 return err;
1586 c.data.type = type; 1591 c.data.type = type;
1587 c.event = nlh->nlmsg_type; 1592 c.event = nlh->nlmsg_type;
1588 c.seq = nlh->nlmsg_seq; 1593 c.seq = nlh->nlmsg_seq;