diff options
Diffstat (limited to 'net')
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 | ||
2578 | int dev_change_flags(struct net_device *dev, unsigned flags) | 2578 | int dev_change_flags(struct net_device *dev, unsigned flags) |
2579 | { | 2579 | { |
2580 | int ret; | 2580 | int ret, changes; |
2581 | int old_flags = dev->flags; | 2581 | int old_flags = dev->flags; |
2582 | 2582 | ||
2583 | /* | 2583 | /* |
@@ -2632,8 +2632,10 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
2632 | dev_set_allmulti(dev, inc); | 2632 | dev_set_allmulti(dev, inc); |
2633 | } | 2633 | } |
2634 | 2634 | ||
2635 | if (old_flags ^ dev->flags) | 2635 | /* Exclude state transition flags, already notified */ |
2636 | rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags); | 2636 | changes = (old_flags ^ dev->flags) & ~(IFF_UP | IFF_RUNNING); |
2637 | if (changes) | ||
2638 | rtmsg_ifinfo(RTM_NEWLINK, dev, changes); | ||
2637 | 2639 | ||
2638 | return ret; | 2640 | return ret; |
2639 | } | 2641 | } |
diff --git a/net/core/dst.c b/net/core/dst.c index 764bccb3d992..c6a05879d58c 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -111,13 +111,7 @@ out: | |||
111 | spin_unlock(&dst_lock); | 111 | spin_unlock(&dst_lock); |
112 | } | 112 | } |
113 | 113 | ||
114 | static int dst_discard_in(struct sk_buff *skb) | 114 | static int dst_discard(struct sk_buff *skb) |
115 | { | ||
116 | kfree_skb(skb); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int dst_discard_out(struct sk_buff *skb) | ||
121 | { | 115 | { |
122 | kfree_skb(skb); | 116 | kfree_skb(skb); |
123 | return 0; | 117 | return 0; |
@@ -138,8 +132,7 @@ void * dst_alloc(struct dst_ops * ops) | |||
138 | dst->ops = ops; | 132 | dst->ops = ops; |
139 | dst->lastuse = jiffies; | 133 | dst->lastuse = jiffies; |
140 | dst->path = dst; | 134 | dst->path = dst; |
141 | dst->input = dst_discard_in; | 135 | dst->input = dst->output = dst_discard; |
142 | dst->output = dst_discard_out; | ||
143 | #if RT_CACHE_DEBUG >= 2 | 136 | #if RT_CACHE_DEBUG >= 2 |
144 | atomic_inc(&dst_total); | 137 | atomic_inc(&dst_total); |
145 | #endif | 138 | #endif |
@@ -153,8 +146,7 @@ static void ___dst_free(struct dst_entry * dst) | |||
153 | protocol module is unloaded. | 146 | protocol module is unloaded. |
154 | */ | 147 | */ |
155 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { | 148 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { |
156 | dst->input = dst_discard_in; | 149 | dst->input = dst->output = dst_discard; |
157 | dst->output = dst_discard_out; | ||
158 | } | 150 | } |
159 | dst->obsolete = 2; | 151 | dst->obsolete = 2; |
160 | } | 152 | } |
@@ -242,8 +234,7 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
242 | return; | 234 | return; |
243 | 235 | ||
244 | if (!unregister) { | 236 | if (!unregister) { |
245 | dst->input = dst_discard_in; | 237 | dst->input = dst->output = dst_discard; |
246 | dst->output = dst_discard_out; | ||
247 | } else { | 238 | } else { |
248 | dst->dev = &loopback_dev; | 239 | dst->dev = &loopback_dev; |
249 | dev_hold(&loopback_dev); | 240 | dev_hold(&loopback_dev); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 6f3bb73053c2..9df26a07f067 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1761,7 +1761,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, | |||
1761 | return NULL; | 1761 | return NULL; |
1762 | } | 1762 | } |
1763 | 1763 | ||
1764 | static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { | 1764 | static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = { |
1765 | [NDTA_NAME] = { .type = NLA_STRING }, | 1765 | [NDTA_NAME] = { .type = NLA_STRING }, |
1766 | [NDTA_THRESH1] = { .type = NLA_U32 }, | 1766 | [NDTA_THRESH1] = { .type = NLA_U32 }, |
1767 | [NDTA_THRESH2] = { .type = NLA_U32 }, | 1767 | [NDTA_THRESH2] = { .type = NLA_U32 }, |
@@ -1770,7 +1770,7 @@ static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { | |||
1770 | [NDTA_PARMS] = { .type = NLA_NESTED }, | 1770 | [NDTA_PARMS] = { .type = NLA_NESTED }, |
1771 | }; | 1771 | }; |
1772 | 1772 | ||
1773 | static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = { | 1773 | static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { |
1774 | [NDTPA_IFINDEX] = { .type = NLA_U32 }, | 1774 | [NDTPA_IFINDEX] = { .type = NLA_U32 }, |
1775 | [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, | 1775 | [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, |
1776 | [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, | 1776 | [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 27da9cdec6a8..02e8bf084277 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -551,7 +551,7 @@ cont: | |||
551 | return skb->len; | 551 | return skb->len; |
552 | } | 552 | } |
553 | 553 | ||
554 | static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = { | 554 | static const struct nla_policy ifla_policy[IFLA_MAX+1] = { |
555 | [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, | 555 | [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, |
556 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, | 556 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, |
557 | [IFLA_MTU] = { .type = NLA_U32 }, | 557 | [IFLA_MTU] = { .type = NLA_U32 }, |
@@ -580,7 +580,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
580 | 580 | ||
581 | err = -EINVAL; | 581 | err = -EINVAL; |
582 | ifm = nlmsg_data(nlh); | 582 | ifm = nlmsg_data(nlh); |
583 | if (ifm->ifi_index >= 0) | 583 | if (ifm->ifi_index > 0) |
584 | dev = dev_get_by_index(ifm->ifi_index); | 584 | dev = dev_get_by_index(ifm->ifi_index); |
585 | else if (tb[IFLA_IFNAME]) | 585 | else if (tb[IFLA_IFNAME]) |
586 | dev = dev_get_by_name(ifname); | 586 | dev = dev_get_by_name(ifname); |
@@ -672,7 +672,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
672 | * name provided implies that a name change has been | 672 | * name provided implies that a name change has been |
673 | * requested. | 673 | * requested. |
674 | */ | 674 | */ |
675 | if (ifm->ifi_index >= 0 && ifname[0]) { | 675 | if (ifm->ifi_index > 0 && ifname[0]) { |
676 | err = dev_change_name(dev, ifname); | 676 | err = dev_change_name(dev, ifname); |
677 | if (err < 0) | 677 | if (err < 0) |
678 | goto errout_dev; | 678 | goto errout_dev; |
@@ -740,7 +740,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
740 | return err; | 740 | return err; |
741 | 741 | ||
742 | ifm = nlmsg_data(nlh); | 742 | ifm = nlmsg_data(nlh); |
743 | if (ifm->ifi_index >= 0) { | 743 | if (ifm->ifi_index > 0) { |
744 | dev = dev_get_by_index(ifm->ifi_index); | 744 | dev = dev_get_by_index(ifm->ifi_index); |
745 | if (dev == NULL) | 745 | if (dev == NULL) |
746 | return -ENODEV; | 746 | return -ENODEV; |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 764a56a13e38..ab41c1879fd4 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -638,7 +638,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex) | |||
638 | return dn_dev; | 638 | return dn_dev; |
639 | } | 639 | } |
640 | 640 | ||
641 | static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { | 641 | static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = { |
642 | [IFA_ADDRESS] = { .type = NLA_U16 }, | 642 | [IFA_ADDRESS] = { .type = NLA_U16 }, |
643 | [IFA_LOCAL] = { .type = NLA_U16 }, | 643 | [IFA_LOCAL] = { .type = NLA_U16 }, |
644 | [IFA_LABEL] = { .type = NLA_STRING, | 644 | [IFA_LABEL] = { .type = NLA_STRING, |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 17a1932216d6..84ff3dd37070 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -108,7 +108,7 @@ errout: | |||
108 | return err; | 108 | return err; |
109 | } | 109 | } |
110 | 110 | ||
111 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { | 111 | static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = { |
112 | FRA_GENERIC_POLICY, | 112 | FRA_GENERIC_POLICY, |
113 | }; | 113 | }; |
114 | 114 | ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 7110779a0244..e00767e8ebd9 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -877,7 +877,7 @@ static int arp_process(struct sk_buff *skb) | |||
877 | 877 | ||
878 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); | 878 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); |
879 | 879 | ||
880 | if (ipv4_devconf.arp_accept) { | 880 | if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) { |
881 | /* Unsolicited ARP is not accepted by default. | 881 | /* Unsolicited ARP is not accepted by default. |
882 | It is possible, that this option should be enabled for some | 882 | It is possible, that this option should be enabled for some |
883 | devices (strip is candidate) | 883 | devices (strip is candidate) |
@@ -987,11 +987,11 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev) | |||
987 | return 0; | 987 | return 0; |
988 | } | 988 | } |
989 | if (dev == NULL) { | 989 | if (dev == NULL) { |
990 | ipv4_devconf.proxy_arp = 1; | 990 | IPV4_DEVCONF_ALL(PROXY_ARP) = 1; |
991 | return 0; | 991 | return 0; |
992 | } | 992 | } |
993 | if (__in_dev_get_rtnl(dev)) { | 993 | if (__in_dev_get_rtnl(dev)) { |
994 | __in_dev_get_rtnl(dev)->cnf.proxy_arp = 1; | 994 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1); |
995 | return 0; | 995 | return 0; |
996 | } | 996 | } |
997 | return -ENXIO; | 997 | return -ENXIO; |
@@ -1093,11 +1093,12 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev) | |||
1093 | return pneigh_delete(&arp_tbl, &ip, dev); | 1093 | return pneigh_delete(&arp_tbl, &ip, dev); |
1094 | if (mask == 0) { | 1094 | if (mask == 0) { |
1095 | if (dev == NULL) { | 1095 | if (dev == NULL) { |
1096 | ipv4_devconf.proxy_arp = 0; | 1096 | IPV4_DEVCONF_ALL(PROXY_ARP) = 0; |
1097 | return 0; | 1097 | return 0; |
1098 | } | 1098 | } |
1099 | if (__in_dev_get_rtnl(dev)) { | 1099 | if (__in_dev_get_rtnl(dev)) { |
1100 | __in_dev_get_rtnl(dev)->cnf.proxy_arp = 0; | 1100 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), |
1101 | PROXY_ARP, 0); | ||
1101 | return 0; | 1102 | return 0; |
1102 | } | 1103 | } |
1103 | return -ENXIO; | 1104 | return -ENXIO; |
diff --git a/net/ipv4/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 | ||
49 | struct cipso_v4_domhsh_entry { | 50 | struct 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 | */ |
1725 | int cipso_v4_socket_setattr(const struct socket *sock, | 1728 | int 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 | */ | ||
1905 | int 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 | ||
66 | struct ipv4_devconf ipv4_devconf = { | 66 | struct ipv4_devconf ipv4_devconf = { |
67 | .accept_redirects = 1, | 67 | .data = { |
68 | .send_redirects = 1, | 68 | [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, |
69 | .secure_redirects = 1, | 69 | [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1, |
70 | .shared_media = 1, | 70 | [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1, |
71 | [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1, | ||
72 | }, | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | static struct ipv4_devconf ipv4_devconf_dflt = { | 75 | static struct ipv4_devconf ipv4_devconf_dflt = { |
74 | .accept_redirects = 1, | 76 | .data = { |
75 | .send_redirects = 1, | 77 | [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, |
76 | .secure_redirects = 1, | 78 | [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1, |
77 | .shared_media = 1, | 79 | [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1, |
78 | .accept_source_route = 1, | 80 | [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1, |
81 | [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1, | ||
82 | }, | ||
79 | }; | 83 | }; |
80 | 84 | ||
81 | static struct nla_policy ifa_ipv4_policy[IFA_MAX+1] __read_mostly = { | 85 | #define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr) |
86 | |||
87 | static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = { | ||
82 | [IFA_LOCAL] = { .type = NLA_U32 }, | 88 | [IFA_LOCAL] = { .type = NLA_U32 }, |
83 | [IFA_ADDRESS] = { .type = NLA_U32 }, | 89 | [IFA_ADDRESS] = { .type = NLA_U32 }, |
84 | [IFA_BROADCAST] = { .type = NLA_U32 }, | 90 | [IFA_BROADCAST] = { .type = NLA_U32 }, |
@@ -141,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev) | |||
141 | } | 147 | } |
142 | } | 148 | } |
143 | 149 | ||
144 | struct in_device *inetdev_init(struct net_device *dev) | 150 | static struct in_device *inetdev_init(struct net_device *dev) |
145 | { | 151 | { |
146 | struct in_device *in_dev; | 152 | struct in_device *in_dev; |
147 | 153 | ||
@@ -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 | ||
332 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | 334 | static 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 | ||
1240 | static 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 | |||
1256 | static 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 | |||
1275 | static 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 | |||
1240 | void inet_forward_change(void) | 1325 | void 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 | ||
1335 | static struct devinet_sysctl_table { | 1421 | static 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 | ||
444 | struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = { | 444 | const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = { |
445 | [RTA_DST] = { .type = NLA_U32 }, | 445 | [RTA_DST] = { .type = NLA_U32 }, |
446 | [RTA_SRC] = { .type = NLA_U32 }, | 446 | [RTA_SRC] = { .type = NLA_U32 }, |
447 | [RTA_IIF] = { .type = NLA_U32 }, | 447 | [RTA_IIF] = { .type = NLA_U32 }, |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 33083ad52e9f..2a947840210e 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -169,7 +169,7 @@ static struct fib_table *fib_empty_table(void) | |||
169 | return NULL; | 169 | return NULL; |
170 | } | 170 | } |
171 | 171 | ||
172 | static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { | 172 | static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = { |
173 | FRA_GENERIC_POLICY, | 173 | FRA_GENERIC_POLICY, |
174 | [FRA_FLOW] = { .type = NLA_U32 }, | 174 | [FRA_FLOW] = { .type = NLA_U32 }, |
175 | }; | 175 | }; |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index f4dd47453108..a646409c2d06 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -128,14 +128,16 @@ | |||
128 | * contradict to specs provided this delay is small enough. | 128 | * contradict to specs provided this delay is small enough. |
129 | */ | 129 | */ |
130 | 130 | ||
131 | #define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \ | 131 | #define IGMP_V1_SEEN(in_dev) \ |
132 | (in_dev)->cnf.force_igmp_version == 1 || \ | 132 | (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \ |
133 | ((in_dev)->mr_v1_seen && \ | 133 | IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \ |
134 | time_before(jiffies, (in_dev)->mr_v1_seen))) | 134 | ((in_dev)->mr_v1_seen && \ |
135 | #define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \ | 135 | time_before(jiffies, (in_dev)->mr_v1_seen))) |
136 | (in_dev)->cnf.force_igmp_version == 2 || \ | 136 | #define IGMP_V2_SEEN(in_dev) \ |
137 | ((in_dev)->mr_v2_seen && \ | 137 | (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \ |
138 | time_before(jiffies, (in_dev)->mr_v2_seen))) | 138 | IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \ |
139 | ((in_dev)->mr_v2_seen && \ | ||
140 | time_before(jiffies, (in_dev)->mr_v2_seen))) | ||
139 | 141 | ||
140 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); | 142 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); |
141 | static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); | 143 | static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index d6427d918512..34ea4547ebbe 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -1352,7 +1352,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
1352 | } | 1352 | } |
1353 | 1353 | ||
1354 | { | 1354 | { |
1355 | struct flowi fl = { .nl_u = { .ip4_u = | 1355 | struct flowi fl = { .oif = arg->bound_dev_if, |
1356 | .nl_u = { .ip4_u = | ||
1356 | { .daddr = daddr, | 1357 | { .daddr = daddr, |
1357 | .saddr = rt->rt_spec_dst, | 1358 | .saddr = rt->rt_spec_dst, |
1358 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, | 1359 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, |
@@ -1376,6 +1377,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
1376 | inet->tos = ip_hdr(skb)->tos; | 1377 | inet->tos = ip_hdr(skb)->tos; |
1377 | sk->sk_priority = skb->priority; | 1378 | sk->sk_priority = skb->priority; |
1378 | sk->sk_protocol = ip_hdr(skb)->protocol; | 1379 | sk->sk_protocol = ip_hdr(skb)->protocol; |
1380 | sk->sk_bound_dev_if = arg->bound_dev_if; | ||
1379 | ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0, | 1381 | ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0, |
1380 | &ipc, rt, MSG_DONTWAIT); | 1382 | &ipc, rt, MSG_DONTWAIT); |
1381 | if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { | 1383 | if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 0ebae413ae87..d96582acdf69 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v) | |||
152 | dev->flags |= IFF_MULTICAST; | 152 | dev->flags |= IFF_MULTICAST; |
153 | 153 | ||
154 | in_dev = __in_dev_get_rtnl(dev); | 154 | in_dev = __in_dev_get_rtnl(dev); |
155 | if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL) | 155 | if (in_dev == NULL) |
156 | goto failure; | 156 | goto failure; |
157 | in_dev->cnf.rp_filter = 0; | 157 | |
158 | ipv4_devconf_setall(in_dev); | ||
159 | IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; | ||
158 | 160 | ||
159 | if (dev_open(dev)) | 161 | if (dev_open(dev)) |
160 | goto failure; | 162 | goto failure; |
@@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void) | |||
218 | } | 220 | } |
219 | dev->iflink = 0; | 221 | dev->iflink = 0; |
220 | 222 | ||
221 | if ((in_dev = inetdev_init(dev)) == NULL) | 223 | rcu_read_lock(); |
224 | if ((in_dev = __in_dev_get_rcu(dev)) == NULL) { | ||
225 | rcu_read_unlock(); | ||
222 | goto failure; | 226 | goto failure; |
227 | } | ||
223 | 228 | ||
224 | in_dev->cnf.rp_filter = 0; | 229 | ipv4_devconf_setall(in_dev); |
230 | IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; | ||
231 | rcu_read_unlock(); | ||
225 | 232 | ||
226 | if (dev_open(dev)) | 233 | if (dev_open(dev)) |
227 | goto failure; | 234 | goto failure; |
@@ -281,7 +288,7 @@ static int vif_delete(int vifi) | |||
281 | dev_set_allmulti(dev, -1); | 288 | dev_set_allmulti(dev, -1); |
282 | 289 | ||
283 | if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { | 290 | if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { |
284 | in_dev->cnf.mc_forwarding--; | 291 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--; |
285 | ip_rt_multicast_event(in_dev); | 292 | ip_rt_multicast_event(in_dev); |
286 | } | 293 | } |
287 | 294 | ||
@@ -426,7 +433,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock) | |||
426 | 433 | ||
427 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) | 434 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) |
428 | return -EADDRNOTAVAIL; | 435 | return -EADDRNOTAVAIL; |
429 | in_dev->cnf.mc_forwarding++; | 436 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; |
430 | dev_set_allmulti(dev, +1); | 437 | dev_set_allmulti(dev, +1); |
431 | ip_rt_multicast_event(in_dev); | 438 | ip_rt_multicast_event(in_dev); |
432 | 439 | ||
@@ -841,7 +848,7 @@ static void mrtsock_destruct(struct sock *sk) | |||
841 | { | 848 | { |
842 | rtnl_lock(); | 849 | rtnl_lock(); |
843 | if (sk == mroute_socket) { | 850 | if (sk == mroute_socket) { |
844 | ipv4_devconf.mc_forwarding--; | 851 | IPV4_DEVCONF_ALL(MC_FORWARDING)--; |
845 | 852 | ||
846 | write_lock_bh(&mrt_lock); | 853 | write_lock_bh(&mrt_lock); |
847 | mroute_socket=NULL; | 854 | mroute_socket=NULL; |
@@ -890,7 +897,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt | |||
890 | mroute_socket=sk; | 897 | mroute_socket=sk; |
891 | write_unlock_bh(&mrt_lock); | 898 | write_unlock_bh(&mrt_lock); |
892 | 899 | ||
893 | ipv4_devconf.mc_forwarding++; | 900 | IPV4_DEVCONF_ALL(MC_FORWARDING)++; |
894 | } | 901 | } |
895 | rtnl_unlock(); | 902 | rtnl_unlock(); |
896 | return ret; | 903 | return ret; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index e3f83bf160d9..9bacf1a03630 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -499,7 +499,8 @@ check_entry(struct ipt_entry *e, const char *name) | |||
499 | } | 499 | } |
500 | 500 | ||
501 | static inline int check_match(struct ipt_entry_match *m, const char *name, | 501 | static inline int check_match(struct ipt_entry_match *m, const char *name, |
502 | const struct ipt_ip *ip, unsigned int hookmask) | 502 | const struct ipt_ip *ip, unsigned int hookmask, |
503 | unsigned int *i) | ||
503 | { | 504 | { |
504 | struct xt_match *match; | 505 | struct xt_match *match; |
505 | int ret; | 506 | int ret; |
@@ -515,6 +516,8 @@ static inline int check_match(struct ipt_entry_match *m, const char *name, | |||
515 | m->u.kernel.match->name); | 516 | m->u.kernel.match->name); |
516 | ret = -EINVAL; | 517 | ret = -EINVAL; |
517 | } | 518 | } |
519 | if (!ret) | ||
520 | (*i)++; | ||
518 | return ret; | 521 | return ret; |
519 | } | 522 | } |
520 | 523 | ||
@@ -537,11 +540,10 @@ find_check_match(struct ipt_entry_match *m, | |||
537 | } | 540 | } |
538 | m->u.kernel.match = match; | 541 | m->u.kernel.match = match; |
539 | 542 | ||
540 | ret = check_match(m, name, ip, hookmask); | 543 | ret = check_match(m, name, ip, hookmask, i); |
541 | if (ret) | 544 | if (ret) |
542 | goto err; | 545 | goto err; |
543 | 546 | ||
544 | (*i)++; | ||
545 | return 0; | 547 | return 0; |
546 | err: | 548 | err: |
547 | module_put(m->u.kernel.match->me); | 549 | module_put(m->u.kernel.match->me); |
@@ -1425,7 +1427,7 @@ out: | |||
1425 | } | 1427 | } |
1426 | 1428 | ||
1427 | static inline int | 1429 | static inline int |
1428 | compat_check_calc_match(struct ipt_entry_match *m, | 1430 | compat_find_calc_match(struct ipt_entry_match *m, |
1429 | const char *name, | 1431 | const char *name, |
1430 | const struct ipt_ip *ip, | 1432 | const struct ipt_ip *ip, |
1431 | unsigned int hookmask, | 1433 | unsigned int hookmask, |
@@ -1449,6 +1451,31 @@ compat_check_calc_match(struct ipt_entry_match *m, | |||
1449 | } | 1451 | } |
1450 | 1452 | ||
1451 | static inline int | 1453 | static inline int |
1454 | compat_release_match(struct ipt_entry_match *m, unsigned int *i) | ||
1455 | { | ||
1456 | if (i && (*i)-- == 0) | ||
1457 | return 1; | ||
1458 | |||
1459 | module_put(m->u.kernel.match->me); | ||
1460 | return 0; | ||
1461 | } | ||
1462 | |||
1463 | static inline int | ||
1464 | compat_release_entry(struct ipt_entry *e, unsigned int *i) | ||
1465 | { | ||
1466 | struct ipt_entry_target *t; | ||
1467 | |||
1468 | if (i && (*i)-- == 0) | ||
1469 | return 1; | ||
1470 | |||
1471 | /* Cleanup all matches */ | ||
1472 | IPT_MATCH_ITERATE(e, compat_release_match, NULL); | ||
1473 | t = ipt_get_target(e); | ||
1474 | module_put(t->u.kernel.target->me); | ||
1475 | return 0; | ||
1476 | } | ||
1477 | |||
1478 | static inline int | ||
1452 | check_compat_entry_size_and_hooks(struct ipt_entry *e, | 1479 | check_compat_entry_size_and_hooks(struct ipt_entry *e, |
1453 | struct xt_table_info *newinfo, | 1480 | struct xt_table_info *newinfo, |
1454 | unsigned int *size, | 1481 | unsigned int *size, |
@@ -1485,10 +1512,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
1485 | off = 0; | 1512 | off = 0; |
1486 | entry_offset = (void *)e - (void *)base; | 1513 | entry_offset = (void *)e - (void *)base; |
1487 | j = 0; | 1514 | j = 0; |
1488 | ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip, | 1515 | ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip, |
1489 | e->comefrom, &off, &j); | 1516 | e->comefrom, &off, &j); |
1490 | if (ret != 0) | 1517 | if (ret != 0) |
1491 | goto cleanup_matches; | 1518 | goto release_matches; |
1492 | 1519 | ||
1493 | t = ipt_get_target(e); | 1520 | t = ipt_get_target(e); |
1494 | target = try_then_request_module(xt_find_target(AF_INET, | 1521 | target = try_then_request_module(xt_find_target(AF_INET, |
@@ -1499,7 +1526,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
1499 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", | 1526 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", |
1500 | t->u.user.name); | 1527 | t->u.user.name); |
1501 | ret = target ? PTR_ERR(target) : -ENOENT; | 1528 | ret = target ? PTR_ERR(target) : -ENOENT; |
1502 | goto cleanup_matches; | 1529 | goto release_matches; |
1503 | } | 1530 | } |
1504 | t->u.kernel.target = target; | 1531 | t->u.kernel.target = target; |
1505 | 1532 | ||
@@ -1526,8 +1553,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
1526 | 1553 | ||
1527 | out: | 1554 | out: |
1528 | module_put(t->u.kernel.target->me); | 1555 | module_put(t->u.kernel.target->me); |
1529 | cleanup_matches: | 1556 | release_matches: |
1530 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | 1557 | IPT_MATCH_ITERATE(e, compat_release_match, &j); |
1531 | return ret; | 1558 | return ret; |
1532 | } | 1559 | } |
1533 | 1560 | ||
@@ -1574,15 +1601,26 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
1574 | return ret; | 1601 | return ret; |
1575 | } | 1602 | } |
1576 | 1603 | ||
1577 | static inline int compat_check_entry(struct ipt_entry *e, const char *name) | 1604 | static inline int compat_check_entry(struct ipt_entry *e, const char *name, |
1605 | unsigned int *i) | ||
1578 | { | 1606 | { |
1579 | int ret; | 1607 | int j, ret; |
1580 | 1608 | ||
1581 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom); | 1609 | j = 0; |
1610 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); | ||
1582 | if (ret) | 1611 | if (ret) |
1583 | return ret; | 1612 | goto cleanup_matches; |
1613 | |||
1614 | ret = check_target(e, name); | ||
1615 | if (ret) | ||
1616 | goto cleanup_matches; | ||
1584 | 1617 | ||
1585 | return check_target(e, name); | 1618 | (*i)++; |
1619 | return 0; | ||
1620 | |||
1621 | cleanup_matches: | ||
1622 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | ||
1623 | return ret; | ||
1586 | } | 1624 | } |
1587 | 1625 | ||
1588 | static int | 1626 | static int |
@@ -1673,10 +1711,17 @@ translate_compat_table(const char *name, | |||
1673 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) | 1711 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) |
1674 | goto free_newinfo; | 1712 | goto free_newinfo; |
1675 | 1713 | ||
1714 | i = 0; | ||
1676 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, | 1715 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, |
1677 | name); | 1716 | name, &i); |
1678 | if (ret) | 1717 | if (ret) { |
1679 | goto free_newinfo; | 1718 | j -= i; |
1719 | IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i, | ||
1720 | compat_release_entry, &j); | ||
1721 | IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); | ||
1722 | xt_free_table_info(newinfo); | ||
1723 | return ret; | ||
1724 | } | ||
1680 | 1725 | ||
1681 | /* And one copy for every other CPU */ | 1726 | /* And one copy for every other CPU */ |
1682 | for_each_possible_cpu(i) | 1727 | for_each_possible_cpu(i) |
@@ -1691,7 +1736,7 @@ translate_compat_table(const char *name, | |||
1691 | free_newinfo: | 1736 | free_newinfo: |
1692 | xt_free_table_info(newinfo); | 1737 | xt_free_table_info(newinfo); |
1693 | out: | 1738 | out: |
1694 | IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); | 1739 | IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); |
1695 | return ret; | 1740 | return ret; |
1696 | out_unlock: | 1741 | out_unlock: |
1697 | compat_flush_offsets(); | 1742 | compat_flush_offsets(); |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index fd62a41d69cc..6dc72a815f77 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -133,6 +133,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum, | |||
133 | struct nf_conn *ct; | 133 | struct nf_conn *ct; |
134 | enum ip_conntrack_info ctinfo; | 134 | enum ip_conntrack_info ctinfo; |
135 | struct nf_conn_help *help; | 135 | struct nf_conn_help *help; |
136 | struct nf_conntrack_helper *helper; | ||
136 | 137 | ||
137 | /* This is where we call the helper: as the packet goes out. */ | 138 | /* This is where we call the helper: as the packet goes out. */ |
138 | ct = nf_ct_get(*pskb, &ctinfo); | 139 | ct = nf_ct_get(*pskb, &ctinfo); |
@@ -140,12 +141,14 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum, | |||
140 | return NF_ACCEPT; | 141 | return NF_ACCEPT; |
141 | 142 | ||
142 | help = nfct_help(ct); | 143 | help = nfct_help(ct); |
143 | if (!help || !help->helper) | 144 | if (!help) |
144 | return NF_ACCEPT; | 145 | return NF_ACCEPT; |
145 | 146 | /* rcu_read_lock()ed by nf_hook_slow */ | |
146 | return help->helper->help(pskb, | 147 | helper = rcu_dereference(help->helper); |
147 | skb_network_offset(*pskb) + ip_hdrlen(*pskb), | 148 | if (!helper) |
148 | ct, ctinfo); | 149 | return NF_ACCEPT; |
150 | return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb), | ||
151 | ct, ctinfo); | ||
149 | } | 152 | } |
150 | 153 | ||
151 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | 154 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index cdbc6c135849..3b690cf2a4ee 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -260,7 +260,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
260 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); | 260 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); |
261 | 261 | ||
262 | seq_printf(seq, "\nIp: %d %d", | 262 | seq_printf(seq, "\nIp: %d %d", |
263 | ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl); | 263 | IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl); |
264 | 264 | ||
265 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) | 265 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) |
266 | seq_printf(seq, " %lu", | 266 | seq_printf(seq, " %lu", |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 8603cfb271f2..29ca63e81ced 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1636,7 +1636,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1636 | 1636 | ||
1637 | atomic_set(&rth->u.dst.__refcnt, 1); | 1637 | atomic_set(&rth->u.dst.__refcnt, 1); |
1638 | rth->u.dst.flags= DST_HOST; | 1638 | rth->u.dst.flags= DST_HOST; |
1639 | if (in_dev->cnf.no_policy) | 1639 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
1640 | rth->u.dst.flags |= DST_NOPOLICY; | 1640 | rth->u.dst.flags |= DST_NOPOLICY; |
1641 | rth->fl.fl4_dst = daddr; | 1641 | rth->fl.fl4_dst = daddr; |
1642 | rth->rt_dst = daddr; | 1642 | rth->rt_dst = daddr; |
@@ -1778,9 +1778,9 @@ static inline int __mkroute_input(struct sk_buff *skb, | |||
1778 | if (res->fi->fib_nhs > 1) | 1778 | if (res->fi->fib_nhs > 1) |
1779 | rth->u.dst.flags |= DST_BALANCED; | 1779 | rth->u.dst.flags |= DST_BALANCED; |
1780 | #endif | 1780 | #endif |
1781 | if (in_dev->cnf.no_policy) | 1781 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
1782 | rth->u.dst.flags |= DST_NOPOLICY; | 1782 | rth->u.dst.flags |= DST_NOPOLICY; |
1783 | if (out_dev->cnf.no_xfrm) | 1783 | if (IN_DEV_CONF_GET(out_dev, NOXFRM)) |
1784 | rth->u.dst.flags |= DST_NOXFRM; | 1784 | rth->u.dst.flags |= DST_NOXFRM; |
1785 | rth->fl.fl4_dst = daddr; | 1785 | rth->fl.fl4_dst = daddr; |
1786 | rth->rt_dst = daddr; | 1786 | rth->rt_dst = daddr; |
@@ -2021,7 +2021,7 @@ local_input: | |||
2021 | 2021 | ||
2022 | atomic_set(&rth->u.dst.__refcnt, 1); | 2022 | atomic_set(&rth->u.dst.__refcnt, 1); |
2023 | rth->u.dst.flags= DST_HOST; | 2023 | rth->u.dst.flags= DST_HOST; |
2024 | if (in_dev->cnf.no_policy) | 2024 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
2025 | rth->u.dst.flags |= DST_NOPOLICY; | 2025 | rth->u.dst.flags |= DST_NOPOLICY; |
2026 | rth->fl.fl4_dst = daddr; | 2026 | rth->fl.fl4_dst = daddr; |
2027 | rth->rt_dst = daddr; | 2027 | rth->rt_dst = daddr; |
@@ -2218,9 +2218,9 @@ static inline int __mkroute_output(struct rtable **result, | |||
2218 | rth->u.dst.flags |= DST_BALANCED; | 2218 | rth->u.dst.flags |= DST_BALANCED; |
2219 | } | 2219 | } |
2220 | #endif | 2220 | #endif |
2221 | if (in_dev->cnf.no_xfrm) | 2221 | if (IN_DEV_CONF_GET(in_dev, NOXFRM)) |
2222 | rth->u.dst.flags |= DST_NOXFRM; | 2222 | rth->u.dst.flags |= DST_NOXFRM; |
2223 | if (in_dev->cnf.no_policy) | 2223 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
2224 | rth->u.dst.flags |= DST_NOPOLICY; | 2224 | rth->u.dst.flags |= DST_NOPOLICY; |
2225 | 2225 | ||
2226 | rth->fl.fl4_dst = oldflp->fl4_dst; | 2226 | rth->fl.fl4_dst = oldflp->fl4_dst; |
@@ -2759,7 +2759,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
2759 | __be32 dst = rt->rt_dst; | 2759 | __be32 dst = rt->rt_dst; |
2760 | 2760 | ||
2761 | if (MULTICAST(dst) && !LOCAL_MCAST(dst) && | 2761 | if (MULTICAST(dst) && !LOCAL_MCAST(dst) && |
2762 | ipv4_devconf.mc_forwarding) { | 2762 | IPV4_DEVCONF_ALL(MC_FORWARDING)) { |
2763 | int err = ipmr_get_route(skb, r, nowait); | 2763 | int err = ipmr_get_route(skb, r, nowait); |
2764 | if (err <= 0) { | 2764 | if (err <= 0) { |
2765 | if (!nowait) { | 2765 | if (!nowait) { |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 6817d6485df5..53ef0f4bbdaa 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -37,12 +37,12 @@ static | |||
37 | int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, | 37 | int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, |
38 | void __user *buffer, size_t *lenp, loff_t *ppos) | 38 | void __user *buffer, size_t *lenp, loff_t *ppos) |
39 | { | 39 | { |
40 | int val = ipv4_devconf.forwarding; | 40 | int val = IPV4_DEVCONF_ALL(FORWARDING); |
41 | int ret; | 41 | int ret; |
42 | 42 | ||
43 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 43 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
44 | 44 | ||
45 | if (write && ipv4_devconf.forwarding != val) | 45 | if (write && IPV4_DEVCONF_ALL(FORWARDING) != val) |
46 | inet_forward_change(); | 46 | inet_forward_change(); |
47 | 47 | ||
48 | return ret; | 48 | return ret; |
@@ -222,7 +222,7 @@ ctl_table ipv4_table[] = { | |||
222 | { | 222 | { |
223 | .ctl_name = NET_IPV4_FORWARD, | 223 | .ctl_name = NET_IPV4_FORWARD, |
224 | .procname = "ip_forward", | 224 | .procname = "ip_forward", |
225 | .data = &ipv4_devconf.forwarding, | 225 | .data = &IPV4_DEVCONF_ALL(FORWARDING), |
226 | .maxlen = sizeof(int), | 226 | .maxlen = sizeof(int), |
227 | .mode = 0644, | 227 | .mode = 0644, |
228 | .proc_handler = &ipv4_sysctl_forward, | 228 | .proc_handler = &ipv4_sysctl_forward, |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 47c61055eb60..97e294e82679 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -705,6 +705,8 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, | |||
705 | ip_hdr(skb)->saddr, /* XXX */ | 705 | ip_hdr(skb)->saddr, /* XXX */ |
706 | arg.iov[0].iov_len, IPPROTO_TCP, 0); | 706 | arg.iov[0].iov_len, IPPROTO_TCP, 0); |
707 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; | 707 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
708 | if (twsk) | ||
709 | arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if; | ||
708 | 710 | ||
709 | ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); | 711 | ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); |
710 | 712 | ||
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index 760165a0800c..d9323dfff826 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c | |||
@@ -63,6 +63,9 @@ struct { | |||
63 | * FIXME: causes an extra copy | 63 | * FIXME: causes an extra copy |
64 | */ | 64 | */ |
65 | static void printl(const char *fmt, ...) | 65 | static void printl(const char *fmt, ...) |
66 | __attribute__ ((format (printf, 1, 2))); | ||
67 | |||
68 | static void printl(const char *fmt, ...) | ||
66 | { | 69 | { |
67 | va_list args; | 70 | va_list args; |
68 | int len; | 71 | int len; |
@@ -80,8 +83,7 @@ static void printl(const char *fmt, ...) | |||
80 | 83 | ||
81 | kfifo_put(tcpw.fifo, tbuf, len); | 84 | kfifo_put(tcpw.fifo, tbuf, len); |
82 | wake_up(&tcpw.wait); | 85 | wake_up(&tcpw.wait); |
83 | } __attribute__ ((format (printf, 1, 2))); | 86 | } |
84 | |||
85 | 87 | ||
86 | /* | 88 | /* |
87 | * Hook inserted to be called before each receive packet. | 89 | * Hook inserted to be called before each receive packet. |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index e61340150ba6..e9b151b3a598 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -292,9 +292,9 @@ static void tcp_retransmit_timer(struct sock *sk) | |||
292 | * we cannot allow such beasts to hang infinitely. | 292 | * we cannot allow such beasts to hang infinitely. |
293 | */ | 293 | */ |
294 | #ifdef TCP_DEBUG | 294 | #ifdef TCP_DEBUG |
295 | if (net_ratelimit()) { | 295 | if (1) { |
296 | struct inet_sock *inet = inet_sk(sk); | 296 | struct inet_sock *inet = inet_sk(sk); |
297 | printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", | 297 | LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", |
298 | NIPQUAD(inet->daddr), ntohs(inet->dport), | 298 | NIPQUAD(inet->daddr), ntohs(inet->dport), |
299 | inet->num, tp->snd_una, tp->snd_nxt); | 299 | inet->num, tp->snd_una, tp->snd_nxt); |
300 | } | 300 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5da703e699da..facb7e29304e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -114,36 +114,14 @@ DEFINE_RWLOCK(udp_hash_lock); | |||
114 | 114 | ||
115 | static int udp_port_rover; | 115 | static int udp_port_rover; |
116 | 116 | ||
117 | /* | 117 | static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[]) |
118 | * Note about this hash function : | ||
119 | * Typical use is probably daddr = 0, only dport is going to vary hash | ||
120 | */ | ||
121 | static inline unsigned int udp_hash_port(__u16 port) | ||
122 | { | ||
123 | return port; | ||
124 | } | ||
125 | |||
126 | static inline int __udp_lib_port_inuse(unsigned int hash, int port, | ||
127 | const struct sock *this_sk, | ||
128 | struct hlist_head udptable[], | ||
129 | const struct udp_get_port_ops *ops) | ||
130 | { | 118 | { |
131 | struct sock *sk; | 119 | struct sock *sk; |
132 | struct hlist_node *node; | 120 | struct hlist_node *node; |
133 | struct inet_sock *inet; | ||
134 | 121 | ||
135 | sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) { | 122 | sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) |
136 | if (sk->sk_hash != hash) | 123 | if (sk->sk_hash == num) |
137 | continue; | ||
138 | inet = inet_sk(sk); | ||
139 | if (inet->num != port) | ||
140 | continue; | ||
141 | if (this_sk) { | ||
142 | if (ops->saddr_cmp(sk, this_sk)) | ||
143 | return 1; | ||
144 | } else if (ops->saddr_any(sk)) | ||
145 | return 1; | 124 | return 1; |
146 | } | ||
147 | return 0; | 125 | return 0; |
148 | } | 126 | } |
149 | 127 | ||
@@ -154,16 +132,16 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port, | |||
154 | * @snum: port number to look up | 132 | * @snum: port number to look up |
155 | * @udptable: hash list table, must be of UDP_HTABLE_SIZE | 133 | * @udptable: hash list table, must be of UDP_HTABLE_SIZE |
156 | * @port_rover: pointer to record of last unallocated port | 134 | * @port_rover: pointer to record of last unallocated port |
157 | * @ops: AF-dependent address operations | 135 | * @saddr_comp: AF-dependent comparison of bound local IP addresses |
158 | */ | 136 | */ |
159 | int __udp_lib_get_port(struct sock *sk, unsigned short snum, | 137 | int __udp_lib_get_port(struct sock *sk, unsigned short snum, |
160 | struct hlist_head udptable[], int *port_rover, | 138 | struct hlist_head udptable[], int *port_rover, |
161 | const struct udp_get_port_ops *ops) | 139 | int (*saddr_comp)(const struct sock *sk1, |
140 | const struct sock *sk2 ) ) | ||
162 | { | 141 | { |
163 | struct hlist_node *node; | 142 | struct hlist_node *node; |
164 | struct hlist_head *head; | 143 | struct hlist_head *head; |
165 | struct sock *sk2; | 144 | struct sock *sk2; |
166 | unsigned int hash; | ||
167 | int error = 1; | 145 | int error = 1; |
168 | 146 | ||
169 | write_lock_bh(&udp_hash_lock); | 147 | write_lock_bh(&udp_hash_lock); |
@@ -178,8 +156,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
178 | for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { | 156 | for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { |
179 | int size; | 157 | int size; |
180 | 158 | ||
181 | hash = ops->hash_port_and_rcv_saddr(result, sk); | 159 | head = &udptable[result & (UDP_HTABLE_SIZE - 1)]; |
182 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
183 | if (hlist_empty(head)) { | 160 | if (hlist_empty(head)) { |
184 | if (result > sysctl_local_port_range[1]) | 161 | if (result > sysctl_local_port_range[1]) |
185 | result = sysctl_local_port_range[0] + | 162 | result = sysctl_local_port_range[0] + |
@@ -204,16 +181,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
204 | result = sysctl_local_port_range[0] | 181 | result = sysctl_local_port_range[0] |
205 | + ((result - sysctl_local_port_range[0]) & | 182 | + ((result - sysctl_local_port_range[0]) & |
206 | (UDP_HTABLE_SIZE - 1)); | 183 | (UDP_HTABLE_SIZE - 1)); |
207 | hash = udp_hash_port(result); | 184 | if (! __udp_lib_lport_inuse(result, udptable)) |
208 | if (__udp_lib_port_inuse(hash, result, | ||
209 | NULL, udptable, ops)) | ||
210 | continue; | ||
211 | if (ops->saddr_any(sk)) | ||
212 | break; | ||
213 | |||
214 | hash = ops->hash_port_and_rcv_saddr(result, sk); | ||
215 | if (! __udp_lib_port_inuse(hash, result, | ||
216 | sk, udptable, ops)) | ||
217 | break; | 185 | break; |
218 | } | 186 | } |
219 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) | 187 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) |
@@ -221,40 +189,21 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
221 | gotit: | 189 | gotit: |
222 | *port_rover = snum = result; | 190 | *port_rover = snum = result; |
223 | } else { | 191 | } else { |
224 | hash = udp_hash_port(snum); | 192 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; |
225 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
226 | 193 | ||
227 | sk_for_each(sk2, node, head) | 194 | sk_for_each(sk2, node, head) |
228 | if (sk2->sk_hash == hash && | 195 | if (sk2->sk_hash == snum && |
229 | sk2 != sk && | 196 | sk2 != sk && |
230 | inet_sk(sk2)->num == snum && | 197 | (!sk2->sk_reuse || !sk->sk_reuse) && |
231 | (!sk2->sk_reuse || !sk->sk_reuse) && | 198 | (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if |
232 | (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || | 199 | || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && |
233 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && | 200 | (*saddr_comp)(sk, sk2) ) |
234 | ops->saddr_cmp(sk, sk2)) | ||
235 | goto fail; | 201 | goto fail; |
236 | |||
237 | if (!ops->saddr_any(sk)) { | ||
238 | hash = ops->hash_port_and_rcv_saddr(snum, sk); | ||
239 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
240 | |||
241 | sk_for_each(sk2, node, head) | ||
242 | if (sk2->sk_hash == hash && | ||
243 | sk2 != sk && | ||
244 | inet_sk(sk2)->num == snum && | ||
245 | (!sk2->sk_reuse || !sk->sk_reuse) && | ||
246 | (!sk2->sk_bound_dev_if || | ||
247 | !sk->sk_bound_dev_if || | ||
248 | sk2->sk_bound_dev_if == | ||
249 | sk->sk_bound_dev_if) && | ||
250 | ops->saddr_cmp(sk, sk2)) | ||
251 | goto fail; | ||
252 | } | ||
253 | } | 202 | } |
254 | inet_sk(sk)->num = snum; | 203 | inet_sk(sk)->num = snum; |
255 | sk->sk_hash = hash; | 204 | sk->sk_hash = snum; |
256 | if (sk_unhashed(sk)) { | 205 | if (sk_unhashed(sk)) { |
257 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | 206 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; |
258 | sk_add_node(sk, head); | 207 | sk_add_node(sk, head); |
259 | sock_prot_inc_use(sk->sk_prot); | 208 | sock_prot_inc_use(sk->sk_prot); |
260 | } | 209 | } |
@@ -265,12 +214,12 @@ fail: | |||
265 | } | 214 | } |
266 | 215 | ||
267 | int udp_get_port(struct sock *sk, unsigned short snum, | 216 | int udp_get_port(struct sock *sk, unsigned short snum, |
268 | const struct udp_get_port_ops *ops) | 217 | int (*scmp)(const struct sock *, const struct sock *)) |
269 | { | 218 | { |
270 | return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, ops); | 219 | return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp); |
271 | } | 220 | } |
272 | 221 | ||
273 | static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | 222 | int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) |
274 | { | 223 | { |
275 | struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); | 224 | struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); |
276 | 225 | ||
@@ -279,33 +228,9 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | |||
279 | inet1->rcv_saddr == inet2->rcv_saddr )); | 228 | inet1->rcv_saddr == inet2->rcv_saddr )); |
280 | } | 229 | } |
281 | 230 | ||
282 | static int ipv4_rcv_saddr_any(const struct sock *sk) | ||
283 | { | ||
284 | return !inet_sk(sk)->rcv_saddr; | ||
285 | } | ||
286 | |||
287 | static inline unsigned int ipv4_hash_port_and_addr(__u16 port, __be32 addr) | ||
288 | { | ||
289 | addr ^= addr >> 16; | ||
290 | addr ^= addr >> 8; | ||
291 | return port ^ addr; | ||
292 | } | ||
293 | |||
294 | static unsigned int ipv4_hash_port_and_rcv_saddr(__u16 port, | ||
295 | const struct sock *sk) | ||
296 | { | ||
297 | return ipv4_hash_port_and_addr(port, inet_sk(sk)->rcv_saddr); | ||
298 | } | ||
299 | |||
300 | const struct udp_get_port_ops udp_ipv4_ops = { | ||
301 | .saddr_cmp = ipv4_rcv_saddr_equal, | ||
302 | .saddr_any = ipv4_rcv_saddr_any, | ||
303 | .hash_port_and_rcv_saddr = ipv4_hash_port_and_rcv_saddr, | ||
304 | }; | ||
305 | |||
306 | static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) | 231 | static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) |
307 | { | 232 | { |
308 | return udp_get_port(sk, snum, &udp_ipv4_ops); | 233 | return udp_get_port(sk, snum, ipv4_rcv_saddr_equal); |
309 | } | 234 | } |
310 | 235 | ||
311 | /* UDP is nearly always wildcards out the wazoo, it makes no sense to try | 236 | /* UDP is nearly always wildcards out the wazoo, it makes no sense to try |
@@ -317,77 +242,63 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport, | |||
317 | { | 242 | { |
318 | struct sock *sk, *result = NULL; | 243 | struct sock *sk, *result = NULL; |
319 | struct hlist_node *node; | 244 | struct hlist_node *node; |
320 | unsigned int hash, hashwild; | 245 | unsigned short hnum = ntohs(dport); |
321 | int score, best = -1, hport = ntohs(dport); | 246 | int badness = -1; |
322 | |||
323 | hash = ipv4_hash_port_and_addr(hport, daddr); | ||
324 | hashwild = udp_hash_port(hport); | ||
325 | 247 | ||
326 | read_lock(&udp_hash_lock); | 248 | read_lock(&udp_hash_lock); |
327 | 249 | sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { | |
328 | lookup: | ||
329 | |||
330 | sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) { | ||
331 | struct inet_sock *inet = inet_sk(sk); | 250 | struct inet_sock *inet = inet_sk(sk); |
332 | 251 | ||
333 | if (sk->sk_hash != hash || ipv6_only_sock(sk) || | 252 | if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) { |
334 | inet->num != hport) | 253 | int score = (sk->sk_family == PF_INET ? 1 : 0); |
335 | continue; | 254 | if (inet->rcv_saddr) { |
336 | 255 | if (inet->rcv_saddr != daddr) | |
337 | score = (sk->sk_family == PF_INET ? 1 : 0); | 256 | continue; |
338 | if (inet->rcv_saddr) { | 257 | score+=2; |
339 | if (inet->rcv_saddr != daddr) | 258 | } |
340 | continue; | 259 | if (inet->daddr) { |
341 | score+=2; | 260 | if (inet->daddr != saddr) |
342 | } | 261 | continue; |
343 | if (inet->daddr) { | 262 | score+=2; |
344 | if (inet->daddr != saddr) | 263 | } |
345 | continue; | 264 | if (inet->dport) { |
346 | score+=2; | 265 | if (inet->dport != sport) |
347 | } | 266 | continue; |
348 | if (inet->dport) { | 267 | score+=2; |
349 | if (inet->dport != sport) | 268 | } |
350 | continue; | 269 | if (sk->sk_bound_dev_if) { |
351 | score+=2; | 270 | if (sk->sk_bound_dev_if != dif) |
352 | } | 271 | continue; |
353 | if (sk->sk_bound_dev_if) { | 272 | score+=2; |
354 | if (sk->sk_bound_dev_if != dif) | 273 | } |
355 | continue; | 274 | if (score == 9) { |
356 | score+=2; | 275 | result = sk; |
357 | } | 276 | break; |
358 | if (score == 9) { | 277 | } else if (score > badness) { |
359 | result = sk; | 278 | result = sk; |
360 | goto found; | 279 | badness = score; |
361 | } else if (score > best) { | 280 | } |
362 | result = sk; | ||
363 | best = score; | ||
364 | } | 281 | } |
365 | } | 282 | } |
366 | |||
367 | if (hash != hashwild) { | ||
368 | hash = hashwild; | ||
369 | goto lookup; | ||
370 | } | ||
371 | found: | ||
372 | if (result) | 283 | if (result) |
373 | sock_hold(result); | 284 | sock_hold(result); |
374 | read_unlock(&udp_hash_lock); | 285 | read_unlock(&udp_hash_lock); |
375 | return result; | 286 | return result; |
376 | } | 287 | } |
377 | 288 | ||
378 | static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum, | 289 | static inline struct sock *udp_v4_mcast_next(struct sock *sk, |
379 | int hport, __be32 loc_addr, | 290 | __be16 loc_port, __be32 loc_addr, |
380 | __be16 rmt_port, __be32 rmt_addr, | 291 | __be16 rmt_port, __be32 rmt_addr, |
381 | int dif) | 292 | int dif) |
382 | { | 293 | { |
383 | struct hlist_node *node; | 294 | struct hlist_node *node; |
384 | struct sock *s = sk; | 295 | struct sock *s = sk; |
296 | unsigned short hnum = ntohs(loc_port); | ||
385 | 297 | ||
386 | sk_for_each_from(s, node) { | 298 | sk_for_each_from(s, node) { |
387 | struct inet_sock *inet = inet_sk(s); | 299 | struct inet_sock *inet = inet_sk(s); |
388 | 300 | ||
389 | if (s->sk_hash != hnum || | 301 | if (s->sk_hash != hnum || |
390 | inet->num != hport || | ||
391 | (inet->daddr && inet->daddr != rmt_addr) || | 302 | (inet->daddr && inet->daddr != rmt_addr) || |
392 | (inet->dport != rmt_port && inet->dport) || | 303 | (inet->dport != rmt_port && inet->dport) || |
393 | (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || | 304 | (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || |
@@ -1221,45 +1132,29 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb, | |||
1221 | __be32 saddr, __be32 daddr, | 1132 | __be32 saddr, __be32 daddr, |
1222 | struct hlist_head udptable[]) | 1133 | struct hlist_head udptable[]) |
1223 | { | 1134 | { |
1224 | struct sock *sk, *skw, *sknext; | 1135 | struct sock *sk; |
1225 | int dif; | 1136 | int dif; |
1226 | int hport = ntohs(uh->dest); | ||
1227 | unsigned int hash = ipv4_hash_port_and_addr(hport, daddr); | ||
1228 | unsigned int hashwild = udp_hash_port(hport); | ||
1229 | |||
1230 | dif = skb->dev->ifindex; | ||
1231 | 1137 | ||
1232 | read_lock(&udp_hash_lock); | 1138 | read_lock(&udp_hash_lock); |
1233 | 1139 | sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); | |
1234 | sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]); | 1140 | dif = skb->dev->ifindex; |
1235 | skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]); | 1141 | sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); |
1236 | |||
1237 | sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif); | ||
1238 | if (!sk) { | ||
1239 | hash = hashwild; | ||
1240 | sk = udp_v4_mcast_next(skw, hash, hport, daddr, uh->source, | ||
1241 | saddr, dif); | ||
1242 | } | ||
1243 | if (sk) { | 1142 | if (sk) { |
1143 | struct sock *sknext = NULL; | ||
1144 | |||
1244 | do { | 1145 | do { |
1245 | struct sk_buff *skb1 = skb; | 1146 | struct sk_buff *skb1 = skb; |
1246 | sknext = udp_v4_mcast_next(sk_next(sk), hash, hport, | 1147 | |
1247 | daddr, uh->source, saddr, dif); | 1148 | sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr, |
1248 | if (!sknext && hash != hashwild) { | 1149 | uh->source, saddr, dif); |
1249 | hash = hashwild; | ||
1250 | sknext = udp_v4_mcast_next(skw, hash, hport, | ||
1251 | daddr, uh->source, saddr, dif); | ||
1252 | } | ||
1253 | if (sknext) | 1150 | if (sknext) |
1254 | skb1 = skb_clone(skb, GFP_ATOMIC); | 1151 | skb1 = skb_clone(skb, GFP_ATOMIC); |
1255 | 1152 | ||
1256 | if (skb1) { | 1153 | if (skb1) { |
1257 | int ret = udp_queue_rcv_skb(sk, skb1); | 1154 | int ret = udp_queue_rcv_skb(sk, skb1); |
1258 | if (ret > 0) | 1155 | if (ret > 0) |
1259 | /* | 1156 | /* we should probably re-process instead |
1260 | * we should probably re-process | 1157 | * of dropping packets here. */ |
1261 | * instead of dropping packets here. | ||
1262 | */ | ||
1263 | kfree_skb(skb1); | 1158 | kfree_skb(skb1); |
1264 | } | 1159 | } |
1265 | sk = sknext; | 1160 | sk = sknext; |
@@ -1346,7 +1241,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
1346 | return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); | 1241 | return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); |
1347 | 1242 | ||
1348 | sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, | 1243 | sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, |
1349 | skb->dev->ifindex, udptable); | 1244 | skb->dev->ifindex, udptable ); |
1350 | 1245 | ||
1351 | if (sk != NULL) { | 1246 | if (sk != NULL) { |
1352 | int ret = udp_queue_rcv_skb(sk, skb); | 1247 | int ret = udp_queue_rcv_skb(sk, skb); |
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h index 06d94195e644..820a477cfaa6 100644 --- a/net/ipv4/udp_impl.h +++ b/net/ipv4/udp_impl.h | |||
@@ -5,14 +5,14 @@ | |||
5 | #include <net/protocol.h> | 5 | #include <net/protocol.h> |
6 | #include <net/inet_common.h> | 6 | #include <net/inet_common.h> |
7 | 7 | ||
8 | extern const struct udp_get_port_ops udp_ipv4_ops; | ||
9 | |||
10 | extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); | 8 | extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); |
11 | extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); | 9 | extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); |
12 | 10 | ||
13 | extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, | 11 | extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, |
14 | struct hlist_head udptable[], int *port_rover, | 12 | struct hlist_head udptable[], int *port_rover, |
15 | const struct udp_get_port_ops *ops); | 13 | int (*)(const struct sock*,const struct sock*)); |
14 | extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *); | ||
15 | |||
16 | 16 | ||
17 | extern int udp_setsockopt(struct sock *sk, int level, int optname, | 17 | extern int udp_setsockopt(struct sock *sk, int level, int optname, |
18 | char __user *optval, int optlen); | 18 | char __user *optval, int optlen); |
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index 3653b32dce2d..f34fd686a8f1 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c | |||
@@ -19,15 +19,14 @@ struct hlist_head udplite_hash[UDP_HTABLE_SIZE]; | |||
19 | static int udplite_port_rover; | 19 | static int udplite_port_rover; |
20 | 20 | ||
21 | int udplite_get_port(struct sock *sk, unsigned short p, | 21 | int udplite_get_port(struct sock *sk, unsigned short p, |
22 | const struct udp_get_port_ops *ops) | 22 | int (*c)(const struct sock *, const struct sock *)) |
23 | { | 23 | { |
24 | return __udp_lib_get_port(sk, p, udplite_hash, | 24 | return __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c); |
25 | &udplite_port_rover, ops); | ||
26 | } | 25 | } |
27 | 26 | ||
28 | static int udplite_v4_get_port(struct sock *sk, unsigned short snum) | 27 | static int udplite_v4_get_port(struct sock *sk, unsigned short snum) |
29 | { | 28 | { |
30 | return udplite_get_port(sk, snum, &udp_ipv4_ops); | 29 | return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal); |
31 | } | 30 | } |
32 | 31 | ||
33 | static int udplite_rcv(struct sk_buff *skb) | 32 | static int udplite_rcv(struct sk_buff *skb) |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 329de679ac38..5a5f8bd4597a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2990,7 +2990,7 @@ static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local) | |||
2990 | return pfx; | 2990 | return pfx; |
2991 | } | 2991 | } |
2992 | 2992 | ||
2993 | static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = { | 2993 | static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { |
2994 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, | 2994 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, |
2995 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, | 2995 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, |
2996 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, | 2996 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index fc3882c90604..53b3998a486c 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -157,7 +157,7 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | |||
157 | return 1; | 157 | return 1; |
158 | } | 158 | } |
159 | 159 | ||
160 | static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { | 160 | static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = { |
161 | FRA_GENERIC_POLICY, | 161 | FRA_GENERIC_POLICY, |
162 | }; | 162 | }; |
163 | 163 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index dc442fb791b0..1b1797f1f33d 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
160 | { | 160 | { |
161 | struct nf_conn *ct; | 161 | struct nf_conn *ct; |
162 | struct nf_conn_help *help; | 162 | struct nf_conn_help *help; |
163 | struct nf_conntrack_helper *helper; | ||
163 | enum ip_conntrack_info ctinfo; | 164 | enum ip_conntrack_info ctinfo; |
164 | unsigned int ret, protoff; | 165 | unsigned int ret, protoff; |
165 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; | 166 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; |
@@ -172,7 +173,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
172 | goto out; | 173 | goto out; |
173 | 174 | ||
174 | help = nfct_help(ct); | 175 | help = nfct_help(ct); |
175 | if (!help || !help->helper) | 176 | if (!help) |
177 | goto out; | ||
178 | /* rcu_read_lock()ed by nf_hook_slow */ | ||
179 | helper = rcu_dereference(help->helper); | ||
180 | if (!helper) | ||
176 | goto out; | 181 | goto out; |
177 | 182 | ||
178 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | 183 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, |
@@ -182,7 +187,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
182 | return NF_ACCEPT; | 187 | return NF_ACCEPT; |
183 | } | 188 | } |
184 | 189 | ||
185 | ret = help->helper->help(pskb, protoff, ct, ctinfo); | 190 | ret = helper->help(pskb, protoff, ct, ctinfo); |
186 | if (ret != NF_ACCEPT) | 191 | if (ret != NF_ACCEPT) |
187 | return ret; | 192 | return ret; |
188 | out: | 193 | out: |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1324b06796c0..fe8d9837f9f8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1999,7 +1999,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned mtu) | |||
1999 | fib6_clean_all(rt6_mtu_change_route, 0, &arg); | 1999 | fib6_clean_all(rt6_mtu_change_route, 0, &arg); |
2000 | } | 2000 | } |
2001 | 2001 | ||
2002 | static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = { | 2002 | static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { |
2003 | [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, | 2003 | [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, |
2004 | [RTA_OIF] = { .type = NLA_U32 }, | 2004 | [RTA_OIF] = { .type = NLA_U32 }, |
2005 | [RTA_IIF] = { .type = NLA_U32 }, | 2005 | [RTA_IIF] = { .type = NLA_U32 }, |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d1fbddd172e7..4210951edb6e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -52,28 +52,9 @@ | |||
52 | 52 | ||
53 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; | 53 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; |
54 | 54 | ||
55 | static int ipv6_rcv_saddr_any(const struct sock *sk) | ||
56 | { | ||
57 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
58 | |||
59 | return ipv6_addr_any(&np->rcv_saddr); | ||
60 | } | ||
61 | |||
62 | static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port, | ||
63 | const struct sock *sk) | ||
64 | { | ||
65 | return port; | ||
66 | } | ||
67 | |||
68 | const struct udp_get_port_ops udp_ipv6_ops = { | ||
69 | .saddr_cmp = ipv6_rcv_saddr_equal, | ||
70 | .saddr_any = ipv6_rcv_saddr_any, | ||
71 | .hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr, | ||
72 | }; | ||
73 | |||
74 | static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) | 55 | static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) |
75 | { | 56 | { |
76 | return udp_get_port(sk, snum, &udp_ipv6_ops); | 57 | return udp_get_port(sk, snum, ipv6_rcv_saddr_equal); |
77 | } | 58 | } |
78 | 59 | ||
79 | static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, | 60 | static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, |
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h index 36b0c11a28a3..6e252f318f7c 100644 --- a/net/ipv6/udp_impl.h +++ b/net/ipv6/udp_impl.h | |||
@@ -6,8 +6,6 @@ | |||
6 | #include <net/addrconf.h> | 6 | #include <net/addrconf.h> |
7 | #include <net/inet_common.h> | 7 | #include <net/inet_common.h> |
8 | 8 | ||
9 | extern const struct udp_get_port_ops udp_ipv6_ops; | ||
10 | |||
11 | extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); | 9 | extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); |
12 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, | 10 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, |
13 | int , int , int , __be32 , struct hlist_head []); | 11 | int , int , int , __be32 , struct hlist_head []); |
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index c40a51362f89..f54016a55004 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
@@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = { | |||
37 | 37 | ||
38 | static int udplite_v6_get_port(struct sock *sk, unsigned short snum) | 38 | static int udplite_v6_get_port(struct sock *sk, unsigned short snum) |
39 | { | 39 | { |
40 | return udplite_get_port(sk, snum, &udp_ipv6_ops); | 40 | return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal); |
41 | } | 41 | } |
42 | 42 | ||
43 | struct proto udplitev6_prot = { | 43 | struct proto udplitev6_prot = { |
diff --git a/net/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 | */ | ||
325 | static 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) | |||
227 | err2: | 228 | err2: |
228 | nf_conntrack_helper_unregister(&amanda_helper[0]); | 229 | nf_conntrack_helper_unregister(&amanda_helper[0]); |
229 | err1: | 230 | err1: |
230 | for (; i >= 0; i--) { | 231 | while (--i >= 0) |
231 | if (search[i].ts) | 232 | textsearch_destroy(search[i].ts); |
232 | textsearch_destroy(search[i].ts); | 233 | |
233 | } | ||
234 | return ret; | 234 | return ret; |
235 | } | 235 | } |
236 | 236 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 483e927a9ca4..7a15e30356f2 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -350,9 +350,15 @@ static void death_by_timeout(unsigned long ul_conntrack) | |||
350 | { | 350 | { |
351 | struct nf_conn *ct = (void *)ul_conntrack; | 351 | struct nf_conn *ct = (void *)ul_conntrack; |
352 | struct nf_conn_help *help = nfct_help(ct); | 352 | struct nf_conn_help *help = nfct_help(ct); |
353 | struct nf_conntrack_helper *helper; | ||
353 | 354 | ||
354 | if (help && help->helper && help->helper->destroy) | 355 | if (help) { |
355 | help->helper->destroy(ct); | 356 | rcu_read_lock(); |
357 | helper = rcu_dereference(help->helper); | ||
358 | if (helper && helper->destroy) | ||
359 | helper->destroy(ct); | ||
360 | rcu_read_unlock(); | ||
361 | } | ||
356 | 362 | ||
357 | write_lock_bh(&nf_conntrack_lock); | 363 | write_lock_bh(&nf_conntrack_lock); |
358 | /* Inside lock so preempt is disabled on module removal path. | 364 | /* Inside lock so preempt is disabled on module removal path. |
@@ -661,6 +667,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
661 | unsigned int dataoff) | 667 | unsigned int dataoff) |
662 | { | 668 | { |
663 | struct nf_conn *conntrack; | 669 | struct nf_conn *conntrack; |
670 | struct nf_conn_help *help; | ||
664 | struct nf_conntrack_tuple repl_tuple; | 671 | struct nf_conntrack_tuple repl_tuple; |
665 | struct nf_conntrack_expect *exp; | 672 | struct nf_conntrack_expect *exp; |
666 | u_int32_t features = 0; | 673 | u_int32_t features = 0; |
@@ -691,6 +698,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
691 | write_lock_bh(&nf_conntrack_lock); | 698 | write_lock_bh(&nf_conntrack_lock); |
692 | exp = find_expectation(tuple); | 699 | exp = find_expectation(tuple); |
693 | 700 | ||
701 | help = nfct_help(conntrack); | ||
694 | if (exp) { | 702 | if (exp) { |
695 | DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", | 703 | DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", |
696 | conntrack, exp); | 704 | conntrack, exp); |
@@ -698,7 +706,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
698 | __set_bit(IPS_EXPECTED_BIT, &conntrack->status); | 706 | __set_bit(IPS_EXPECTED_BIT, &conntrack->status); |
699 | conntrack->master = exp->master; | 707 | conntrack->master = exp->master; |
700 | if (exp->helper) | 708 | if (exp->helper) |
701 | nfct_help(conntrack)->helper = exp->helper; | 709 | rcu_assign_pointer(help->helper, exp->helper); |
702 | #ifdef CONFIG_NF_CONNTRACK_MARK | 710 | #ifdef CONFIG_NF_CONNTRACK_MARK |
703 | conntrack->mark = exp->master->mark; | 711 | conntrack->mark = exp->master->mark; |
704 | #endif | 712 | #endif |
@@ -708,10 +716,11 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
708 | nf_conntrack_get(&conntrack->master->ct_general); | 716 | nf_conntrack_get(&conntrack->master->ct_general); |
709 | NF_CT_STAT_INC(expect_new); | 717 | NF_CT_STAT_INC(expect_new); |
710 | } else { | 718 | } else { |
711 | struct nf_conn_help *help = nfct_help(conntrack); | 719 | if (help) { |
712 | 720 | /* not in hash table yet, so not strictly necessary */ | |
713 | if (help) | 721 | rcu_assign_pointer(help->helper, |
714 | help->helper = __nf_ct_helper_find(&repl_tuple); | 722 | __nf_ct_helper_find(&repl_tuple)); |
723 | } | ||
715 | NF_CT_STAT_INC(new); | 724 | NF_CT_STAT_INC(new); |
716 | } | 725 | } |
717 | 726 | ||
@@ -893,7 +902,8 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, | |||
893 | helper = __nf_ct_helper_find(newreply); | 902 | helper = __nf_ct_helper_find(newreply); |
894 | if (helper) | 903 | if (helper) |
895 | memset(&help->help, 0, sizeof(help->help)); | 904 | memset(&help->help, 0, sizeof(help->help)); |
896 | help->helper = helper; | 905 | /* not in hash table yet, so not strictly necessary */ |
906 | rcu_assign_pointer(help->helper, helper); | ||
897 | } | 907 | } |
898 | write_unlock_bh(&nf_conntrack_lock); | 908 | write_unlock_bh(&nf_conntrack_lock); |
899 | } | 909 | } |
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index 117cbfdb910c..504fb6c083f9 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c | |||
@@ -337,6 +337,10 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect) | |||
337 | NF_CT_ASSERT(master_help); | 337 | NF_CT_ASSERT(master_help); |
338 | 338 | ||
339 | write_lock_bh(&nf_conntrack_lock); | 339 | write_lock_bh(&nf_conntrack_lock); |
340 | if (!master_help->helper) { | ||
341 | ret = -ESHUTDOWN; | ||
342 | goto out; | ||
343 | } | ||
340 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { | 344 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { |
341 | if (expect_matches(i, expect)) { | 345 | if (expect_matches(i, expect)) { |
342 | /* Refresh timer: if it's dying, ignore.. */ | 346 | /* Refresh timer: if it's dying, ignore.. */ |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 0743be4434b0..f868b7fbd9b4 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
@@ -93,7 +93,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i, | |||
93 | 93 | ||
94 | if (help && help->helper == me) { | 94 | if (help && help->helper == me) { |
95 | nf_conntrack_event(IPCT_HELPER, ct); | 95 | nf_conntrack_event(IPCT_HELPER, ct); |
96 | help->helper = NULL; | 96 | rcu_assign_pointer(help->helper, NULL); |
97 | } | 97 | } |
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index d6d39e241327..3f73327794ab 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -171,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) | |||
171 | { | 171 | { |
172 | struct nfattr *nest_helper; | 172 | struct nfattr *nest_helper; |
173 | const struct nf_conn_help *help = nfct_help(ct); | 173 | const struct nf_conn_help *help = nfct_help(ct); |
174 | struct nf_conntrack_helper *helper; | ||
174 | 175 | ||
175 | if (!help || !help->helper) | 176 | if (!help) |
176 | return 0; | 177 | return 0; |
177 | 178 | ||
179 | rcu_read_lock(); | ||
180 | helper = rcu_dereference(help->helper); | ||
181 | if (!helper) | ||
182 | goto out; | ||
183 | |||
178 | nest_helper = NFA_NEST(skb, CTA_HELP); | 184 | nest_helper = NFA_NEST(skb, CTA_HELP); |
179 | NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name); | 185 | NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name); |
180 | 186 | ||
181 | if (help->helper->to_nfattr) | 187 | if (helper->to_nfattr) |
182 | help->helper->to_nfattr(skb, ct); | 188 | helper->to_nfattr(skb, ct); |
183 | 189 | ||
184 | NFA_NEST_END(skb, nest_helper); | 190 | NFA_NEST_END(skb, nest_helper); |
185 | 191 | out: | |
192 | rcu_read_unlock(); | ||
186 | return 0; | 193 | return 0; |
187 | 194 | ||
188 | nfattr_failure: | 195 | nfattr_failure: |
196 | rcu_read_unlock(); | ||
189 | return -1; | 197 | return -1; |
190 | } | 198 | } |
191 | 199 | ||
@@ -842,7 +850,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) | |||
842 | if (help && help->helper) { | 850 | if (help && help->helper) { |
843 | /* we had a helper before ... */ | 851 | /* we had a helper before ... */ |
844 | nf_ct_remove_expectations(ct); | 852 | nf_ct_remove_expectations(ct); |
845 | help->helper = NULL; | 853 | rcu_assign_pointer(help->helper, NULL); |
846 | } | 854 | } |
847 | 855 | ||
848 | return 0; | 856 | return 0; |
@@ -866,7 +874,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) | |||
866 | 874 | ||
867 | /* need to zero data of old helper */ | 875 | /* need to zero data of old helper */ |
868 | memset(&help->help, 0, sizeof(help->help)); | 876 | memset(&help->help, 0, sizeof(help->help)); |
869 | help->helper = helper; | 877 | rcu_assign_pointer(help->helper, helper); |
870 | 878 | ||
871 | return 0; | 879 | return 0; |
872 | } | 880 | } |
@@ -950,6 +958,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
950 | struct nf_conn *ct; | 958 | struct nf_conn *ct; |
951 | int err = -EINVAL; | 959 | int err = -EINVAL; |
952 | struct nf_conn_help *help; | 960 | struct nf_conn_help *help; |
961 | struct nf_conntrack_helper *helper = NULL; | ||
953 | 962 | ||
954 | ct = nf_conntrack_alloc(otuple, rtuple); | 963 | ct = nf_conntrack_alloc(otuple, rtuple); |
955 | if (ct == NULL || IS_ERR(ct)) | 964 | if (ct == NULL || IS_ERR(ct)) |
@@ -980,14 +989,17 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
980 | #endif | 989 | #endif |
981 | 990 | ||
982 | help = nfct_help(ct); | 991 | help = nfct_help(ct); |
983 | if (help) | 992 | if (help) { |
984 | help->helper = nf_ct_helper_find_get(rtuple); | 993 | helper = nf_ct_helper_find_get(rtuple); |
994 | /* not in hash table yet so not strictly necessary */ | ||
995 | rcu_assign_pointer(help->helper, helper); | ||
996 | } | ||
985 | 997 | ||
986 | add_timer(&ct->timeout); | 998 | add_timer(&ct->timeout); |
987 | nf_conntrack_hash_insert(ct); | 999 | nf_conntrack_hash_insert(ct); |
988 | 1000 | ||
989 | if (help && help->helper) | 1001 | if (helper) |
990 | nf_ct_helper_put(help->helper); | 1002 | nf_ct_helper_put(helper); |
991 | 1003 | ||
992 | return 0; | 1004 | return 0; |
993 | 1005 | ||
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 5434472420fe..339c397d1b5f 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c | |||
@@ -100,7 +100,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, | |||
100 | struct nf_conn_help *help = nfct_help(ct); | 100 | struct nf_conn_help *help = nfct_help(ct); |
101 | struct nf_ct_gre_keymap **kmp, *km; | 101 | struct nf_ct_gre_keymap **kmp, *km; |
102 | 102 | ||
103 | BUG_ON(strcmp(help->helper->name, "pptp")); | ||
104 | kmp = &help->help.ct_pptp_info.keymap[dir]; | 103 | kmp = &help->help.ct_pptp_info.keymap[dir]; |
105 | if (*kmp) { | 104 | if (*kmp) { |
106 | /* check whether it's a retransmission */ | 105 | /* check whether it's a retransmission */ |
@@ -137,7 +136,6 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct) | |||
137 | enum ip_conntrack_dir dir; | 136 | enum ip_conntrack_dir dir; |
138 | 137 | ||
139 | DEBUGP("entering for ct %p\n", ct); | 138 | DEBUGP("entering for ct %p\n", ct); |
140 | BUG_ON(strcmp(help->helper->name, "pptp")); | ||
141 | 139 | ||
142 | write_lock_bh(&nf_ct_gre_lock); | 140 | write_lock_bh(&nf_ct_gre_lock); |
143 | for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { | 141 | for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { |
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 07e47dbcb0a9..24b660f16ce3 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -59,7 +59,7 @@ static struct genl_family netlbl_cipsov4_gnl_family = { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* NetLabel Netlink attribute policy */ | 61 | /* NetLabel Netlink attribute policy */ |
62 | static struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { | 62 | static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { |
63 | [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 }, | 63 | [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 }, |
64 | [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 }, | 64 | [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 }, |
65 | [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 }, | 65 | [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 }, |
diff --git a/net/netlabel/netlabel_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 | */ |
260 | int netlbl_socket_setattr(const struct socket *sock, | 259 | int 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 | */ | ||
323 | int 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 */ |
62 | static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { | 62 | static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { |
63 | [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING }, | 63 | [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING }, |
64 | [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 }, | 64 | [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 }, |
65 | [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 }, | 65 | [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 }, |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index b931edee4b8b..5c303c68af1d 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -61,7 +61,7 @@ static struct genl_family netlbl_unlabel_gnl_family = { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* NetLabel Netlink attribute policy */ | 63 | /* NetLabel Netlink attribute policy */ |
64 | static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { | 64 | static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { |
65 | [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, | 65 | [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, |
66 | }; | 66 | }; |
67 | 67 | ||
diff --git a/net/netlink/attr.c b/net/netlink/attr.c index df5f820a4c32..c591212793ee 100644 --- a/net/netlink/attr.c +++ b/net/netlink/attr.c | |||
@@ -24,9 +24,9 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = { | |||
24 | }; | 24 | }; |
25 | 25 | ||
26 | static int validate_nla(struct nlattr *nla, int maxtype, | 26 | static int validate_nla(struct nlattr *nla, int maxtype, |
27 | struct nla_policy *policy) | 27 | const struct nla_policy *policy) |
28 | { | 28 | { |
29 | struct nla_policy *pt; | 29 | const struct nla_policy *pt; |
30 | int minlen = 0, attrlen = nla_len(nla); | 30 | int minlen = 0, attrlen = nla_len(nla); |
31 | 31 | ||
32 | if (nla->nla_type <= 0 || nla->nla_type > maxtype) | 32 | if (nla->nla_type <= 0 || nla->nla_type > maxtype) |
@@ -99,7 +99,7 @@ static int validate_nla(struct nlattr *nla, int maxtype, | |||
99 | * Returns 0 on success or a negative error code. | 99 | * Returns 0 on success or a negative error code. |
100 | */ | 100 | */ |
101 | int nla_validate(struct nlattr *head, int len, int maxtype, | 101 | int nla_validate(struct nlattr *head, int len, int maxtype, |
102 | struct nla_policy *policy) | 102 | const struct nla_policy *policy) |
103 | { | 103 | { |
104 | struct nlattr *nla; | 104 | struct nlattr *nla; |
105 | int rem, err; | 105 | int rem, err; |
@@ -130,7 +130,7 @@ errout: | |||
130 | * Returns 0 on success or a negative error code. | 130 | * Returns 0 on success or a negative error code. |
131 | */ | 131 | */ |
132 | int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, | 132 | int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, |
133 | struct nla_policy *policy) | 133 | const struct nla_policy *policy) |
134 | { | 134 | { |
135 | struct nlattr *nla; | 135 | struct nlattr *nla; |
136 | int rem, err; | 136 | int rem, err; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 6e31234a4196..b9ab62f938d0 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -472,7 +472,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, | |||
472 | return skb; | 472 | return skb; |
473 | } | 473 | } |
474 | 474 | ||
475 | static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = { | 475 | static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = { |
476 | [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, | 476 | [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, |
477 | [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, | 477 | [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, |
478 | .len = GENL_NAMSIZ - 1 }, | 478 | .len = GENL_NAMSIZ - 1 }, |
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index be7d299acd73..d1c383fca82c 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
@@ -599,6 +599,7 @@ static void atm_tc_destroy(struct Qdisc *sch) | |||
599 | /* races ? */ | 599 | /* races ? */ |
600 | while ((flow = p->flows)) { | 600 | while ((flow = p->flows)) { |
601 | tcf_destroy_chain(flow->filter_list); | 601 | tcf_destroy_chain(flow->filter_list); |
602 | flow->filter_list = NULL; | ||
602 | if (flow->ref > 1) | 603 | if (flow->ref > 1) |
603 | printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, | 604 | printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, |
604 | flow->ref); | 605 | flow->ref); |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index a294542cb8e4..ee2d5967d109 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -1748,10 +1748,12 @@ cbq_destroy(struct Qdisc* sch) | |||
1748 | * classes from root to leafs which means that filters can still | 1748 | * classes from root to leafs which means that filters can still |
1749 | * be bound to classes which have been destroyed already. --TGR '04 | 1749 | * be bound to classes which have been destroyed already. --TGR '04 |
1750 | */ | 1750 | */ |
1751 | for (h = 0; h < 16; h++) | 1751 | for (h = 0; h < 16; h++) { |
1752 | for (cl = q->classes[h]; cl; cl = cl->next) | 1752 | for (cl = q->classes[h]; cl; cl = cl->next) { |
1753 | tcf_destroy_chain(cl->filter_list); | 1753 | tcf_destroy_chain(cl->filter_list); |
1754 | 1754 | cl->filter_list = NULL; | |
1755 | } | ||
1756 | } | ||
1755 | for (h = 0; h < 16; h++) { | 1757 | for (h = 0; h < 16; h++) { |
1756 | struct cbq_class *next; | 1758 | struct cbq_class *next; |
1757 | 1759 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 87c794d8fa2d..d70fa30d4294 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1744,20 +1744,23 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1744 | int chunk; | 1744 | int chunk; |
1745 | struct sk_buff *skb; | 1745 | struct sk_buff *skb; |
1746 | 1746 | ||
1747 | unix_state_lock(sk); | ||
1747 | skb = skb_dequeue(&sk->sk_receive_queue); | 1748 | skb = skb_dequeue(&sk->sk_receive_queue); |
1748 | if (skb==NULL) | 1749 | if (skb==NULL) |
1749 | { | 1750 | { |
1750 | if (copied >= target) | 1751 | if (copied >= target) |
1751 | break; | 1752 | goto unlock; |
1752 | 1753 | ||
1753 | /* | 1754 | /* |
1754 | * POSIX 1003.1g mandates this order. | 1755 | * POSIX 1003.1g mandates this order. |
1755 | */ | 1756 | */ |
1756 | 1757 | ||
1757 | if ((err = sock_error(sk)) != 0) | 1758 | if ((err = sock_error(sk)) != 0) |
1758 | break; | 1759 | goto unlock; |
1759 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1760 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
1760 | break; | 1761 | goto unlock; |
1762 | |||
1763 | unix_state_unlock(sk); | ||
1761 | err = -EAGAIN; | 1764 | err = -EAGAIN; |
1762 | if (!timeo) | 1765 | if (!timeo) |
1763 | break; | 1766 | break; |
@@ -1771,7 +1774,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1771 | } | 1774 | } |
1772 | mutex_lock(&u->readlock); | 1775 | mutex_lock(&u->readlock); |
1773 | continue; | 1776 | continue; |
1777 | unlock: | ||
1778 | unix_state_unlock(sk); | ||
1779 | break; | ||
1774 | } | 1780 | } |
1781 | unix_state_unlock(sk); | ||
1775 | 1782 | ||
1776 | if (check_creds) { | 1783 | if (check_creds) { |
1777 | /* Never glue messages from different writers */ | 1784 | /* Never glue messages from different writers */ |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 64a375178c5f..157bfbd250ba 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -834,11 +834,67 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, | |||
834 | } | 834 | } |
835 | EXPORT_SYMBOL(xfrm_policy_byid); | 835 | EXPORT_SYMBOL(xfrm_policy_byid); |
836 | 836 | ||
837 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | 837 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
838 | static inline int | ||
839 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
838 | { | 840 | { |
839 | int dir; | 841 | int dir, err = 0; |
842 | |||
843 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | ||
844 | struct xfrm_policy *pol; | ||
845 | struct hlist_node *entry; | ||
846 | int i; | ||
847 | |||
848 | hlist_for_each_entry(pol, entry, | ||
849 | &xfrm_policy_inexact[dir], bydst) { | ||
850 | if (pol->type != type) | ||
851 | continue; | ||
852 | err = security_xfrm_policy_delete(pol); | ||
853 | if (err) { | ||
854 | xfrm_audit_log(audit_info->loginuid, | ||
855 | audit_info->secid, | ||
856 | AUDIT_MAC_IPSEC_DELSPD, 0, | ||
857 | pol, NULL); | ||
858 | return err; | ||
859 | } | ||
860 | } | ||
861 | for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { | ||
862 | hlist_for_each_entry(pol, entry, | ||
863 | xfrm_policy_bydst[dir].table + i, | ||
864 | bydst) { | ||
865 | if (pol->type != type) | ||
866 | continue; | ||
867 | err = security_xfrm_policy_delete(pol); | ||
868 | if (err) { | ||
869 | xfrm_audit_log(audit_info->loginuid, | ||
870 | audit_info->secid, | ||
871 | AUDIT_MAC_IPSEC_DELSPD, | ||
872 | 0, pol, NULL); | ||
873 | return err; | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | } | ||
878 | return err; | ||
879 | } | ||
880 | #else | ||
881 | static inline int | ||
882 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
883 | { | ||
884 | return 0; | ||
885 | } | ||
886 | #endif | ||
887 | |||
888 | int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | ||
889 | { | ||
890 | int dir, err = 0; | ||
840 | 891 | ||
841 | write_lock_bh(&xfrm_policy_lock); | 892 | write_lock_bh(&xfrm_policy_lock); |
893 | |||
894 | err = xfrm_policy_flush_secctx_check(type, audit_info); | ||
895 | if (err) | ||
896 | goto out; | ||
897 | |||
842 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 898 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
843 | struct xfrm_policy *pol; | 899 | struct xfrm_policy *pol; |
844 | struct hlist_node *entry; | 900 | struct hlist_node *entry; |
@@ -891,7 +947,9 @@ void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
891 | xfrm_policy_count[dir] -= killed; | 947 | xfrm_policy_count[dir] -= killed; |
892 | } | 948 | } |
893 | atomic_inc(&flow_cache_genid); | 949 | atomic_inc(&flow_cache_genid); |
950 | out: | ||
894 | write_unlock_bh(&xfrm_policy_lock); | 951 | write_unlock_bh(&xfrm_policy_lock); |
952 | return err; | ||
895 | } | 953 | } |
896 | EXPORT_SYMBOL(xfrm_policy_flush); | 954 | EXPORT_SYMBOL(xfrm_policy_flush); |
897 | 955 | ||
@@ -2583,4 +2641,3 @@ restore_state: | |||
2583 | } | 2641 | } |
2584 | EXPORT_SYMBOL(xfrm_migrate); | 2642 | EXPORT_SYMBOL(xfrm_migrate); |
2585 | #endif | 2643 | #endif |
2586 | |||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 372f06eb8bb7..85f3f43a6cca 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -391,12 +391,48 @@ int xfrm_state_delete(struct xfrm_state *x) | |||
391 | } | 391 | } |
392 | EXPORT_SYMBOL(xfrm_state_delete); | 392 | EXPORT_SYMBOL(xfrm_state_delete); |
393 | 393 | ||
394 | void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | 394 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
395 | static inline int | ||
396 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
395 | { | 397 | { |
396 | int i; | 398 | int i, err = 0; |
397 | int err = 0; | 399 | |
400 | for (i = 0; i <= xfrm_state_hmask; i++) { | ||
401 | struct hlist_node *entry; | ||
402 | struct xfrm_state *x; | ||
403 | |||
404 | hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { | ||
405 | if (xfrm_id_proto_match(x->id.proto, proto) && | ||
406 | (err = security_xfrm_state_delete(x)) != 0) { | ||
407 | xfrm_audit_log(audit_info->loginuid, | ||
408 | audit_info->secid, | ||
409 | AUDIT_MAC_IPSEC_DELSA, | ||
410 | 0, NULL, x); | ||
411 | |||
412 | return err; | ||
413 | } | ||
414 | } | ||
415 | } | ||
416 | |||
417 | return err; | ||
418 | } | ||
419 | #else | ||
420 | static inline int | ||
421 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
422 | { | ||
423 | return 0; | ||
424 | } | ||
425 | #endif | ||
426 | |||
427 | int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | ||
428 | { | ||
429 | int i, err = 0; | ||
398 | 430 | ||
399 | spin_lock_bh(&xfrm_state_lock); | 431 | spin_lock_bh(&xfrm_state_lock); |
432 | err = xfrm_state_flush_secctx_check(proto, audit_info); | ||
433 | if (err) | ||
434 | goto out; | ||
435 | |||
400 | for (i = 0; i <= xfrm_state_hmask; i++) { | 436 | for (i = 0; i <= xfrm_state_hmask; i++) { |
401 | struct hlist_node *entry; | 437 | struct hlist_node *entry; |
402 | struct xfrm_state *x; | 438 | struct xfrm_state *x; |
@@ -419,8 +455,12 @@ restart: | |||
419 | } | 455 | } |
420 | } | 456 | } |
421 | } | 457 | } |
458 | err = 0; | ||
459 | |||
460 | out: | ||
422 | spin_unlock_bh(&xfrm_state_lock); | 461 | spin_unlock_bh(&xfrm_state_lock); |
423 | wake_up(&km_waitq); | 462 | wake_up(&km_waitq); |
463 | return err; | ||
424 | } | 464 | } |
425 | EXPORT_SYMBOL(xfrm_state_flush); | 465 | EXPORT_SYMBOL(xfrm_state_flush); |
426 | 466 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b14c7e590c31..c06883bf620e 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1418,10 +1418,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1418 | struct km_event c; | 1418 | struct km_event c; |
1419 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); | 1419 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); |
1420 | struct xfrm_audit audit_info; | 1420 | struct xfrm_audit audit_info; |
1421 | int err; | ||
1421 | 1422 | ||
1422 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1423 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1423 | audit_info.secid = NETLINK_CB(skb).sid; | 1424 | audit_info.secid = NETLINK_CB(skb).sid; |
1424 | xfrm_state_flush(p->proto, &audit_info); | 1425 | err = xfrm_state_flush(p->proto, &audit_info); |
1426 | if (err) | ||
1427 | return err; | ||
1425 | c.data.proto = p->proto; | 1428 | c.data.proto = p->proto; |
1426 | c.event = nlh->nlmsg_type; | 1429 | c.event = nlh->nlmsg_type; |
1427 | c.seq = nlh->nlmsg_seq; | 1430 | c.seq = nlh->nlmsg_seq; |
@@ -1582,7 +1585,9 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1582 | 1585 | ||
1583 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1586 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1584 | audit_info.secid = NETLINK_CB(skb).sid; | 1587 | audit_info.secid = NETLINK_CB(skb).sid; |
1585 | xfrm_policy_flush(type, &audit_info); | 1588 | err = xfrm_policy_flush(type, &audit_info); |
1589 | if (err) | ||
1590 | return err; | ||
1586 | c.data.type = type; | 1591 | c.data.type = type; |
1587 | c.event = nlh->nlmsg_type; | 1592 | c.event = nlh->nlmsg_type; |
1588 | c.seq = nlh->nlmsg_seq; | 1593 | c.seq = nlh->nlmsg_seq; |