diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/8021q/vlan_dev.c | 3 | ||||
| -rw-r--r-- | net/bridge/br_multicast.c | 33 | ||||
| -rw-r--r-- | net/core/skbuff.c | 100 | ||||
| -rw-r--r-- | net/core/sock.c | 5 | ||||
| -rw-r--r-- | net/ipv4/inet_fragment.c | 5 | ||||
| -rw-r--r-- | net/ipv4/tcp_output.c | 11 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 5 | ||||
| -rw-r--r-- | net/ipv6/exthdrs_offload.c | 4 | ||||
| -rw-r--r-- | net/ipv6/route.c | 2 | ||||
| -rw-r--r-- | net/l2tp/l2tp_core.c | 4 | ||||
| -rw-r--r-- | net/l2tp/l2tp_core.h | 1 | ||||
| -rw-r--r-- | net/l2tp/l2tp_netlink.c | 4 | ||||
| -rw-r--r-- | net/l2tp/l2tp_ppp.c | 13 | ||||
| -rw-r--r-- | net/mac80211/chan.c | 6 | ||||
| -rw-r--r-- | net/mac80211/mesh_ps.c | 1 | ||||
| -rw-r--r-- | net/mac80211/sta_info.c | 1 | ||||
| -rw-r--r-- | net/sched/sch_api.c | 7 | ||||
| -rw-r--r-- | net/sched/sch_fq.c | 21 | ||||
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 4 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 5 | ||||
| -rw-r--r-- | net/socket.c | 17 | ||||
| -rw-r--r-- | net/tipc/config.c | 9 | ||||
| -rw-r--r-- | net/tipc/handler.c | 1 | ||||
| -rw-r--r-- | net/tipc/name_table.c | 37 | ||||
| -rw-r--r-- | net/tipc/server.c | 14 | ||||
| -rw-r--r-- | net/tipc/socket.c | 4 | ||||
| -rw-r--r-- | net/tipc/subscr.c | 19 | ||||
| -rw-r--r-- | net/unix/af_unix.c | 3 | ||||
| -rw-r--r-- | net/wireless/core.c | 2 |
29 files changed, 214 insertions, 127 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index de51c48c4393..4b65aa492fb6 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -538,6 +538,9 @@ static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev | |||
| 538 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 538 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); |
| 539 | struct net_device *real_dev = vlan->real_dev; | 539 | struct net_device *real_dev = vlan->real_dev; |
| 540 | 540 | ||
| 541 | if (saddr == NULL) | ||
| 542 | saddr = dev->dev_addr; | ||
| 543 | |||
| 541 | return dev_hard_header(skb, real_dev, type, daddr, saddr, len); | 544 | return dev_hard_header(skb, real_dev, type, daddr, saddr, len); |
| 542 | } | 545 | } |
| 543 | 546 | ||
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index ef66365b7354..93067ecdb9a2 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -1127,9 +1127,10 @@ static void br_multicast_query_received(struct net_bridge *br, | |||
| 1127 | struct net_bridge_port *port, | 1127 | struct net_bridge_port *port, |
| 1128 | struct bridge_mcast_querier *querier, | 1128 | struct bridge_mcast_querier *querier, |
| 1129 | int saddr, | 1129 | int saddr, |
| 1130 | bool is_general_query, | ||
| 1130 | unsigned long max_delay) | 1131 | unsigned long max_delay) |
| 1131 | { | 1132 | { |
| 1132 | if (saddr) | 1133 | if (saddr && is_general_query) |
| 1133 | br_multicast_update_querier_timer(br, querier, max_delay); | 1134 | br_multicast_update_querier_timer(br, querier, max_delay); |
| 1134 | else if (timer_pending(&querier->timer)) | 1135 | else if (timer_pending(&querier->timer)) |
| 1135 | return; | 1136 | return; |
| @@ -1181,8 +1182,16 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
| 1181 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; | 1182 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; |
| 1182 | } | 1183 | } |
| 1183 | 1184 | ||
| 1185 | /* RFC2236+RFC3376 (IGMPv2+IGMPv3) require the multicast link layer | ||
| 1186 | * all-systems destination addresses (224.0.0.1) for general queries | ||
| 1187 | */ | ||
| 1188 | if (!group && iph->daddr != htonl(INADDR_ALLHOSTS_GROUP)) { | ||
| 1189 | err = -EINVAL; | ||
| 1190 | goto out; | ||
| 1191 | } | ||
| 1192 | |||
| 1184 | br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr, | 1193 | br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr, |
| 1185 | max_delay); | 1194 | !group, max_delay); |
| 1186 | 1195 | ||
| 1187 | if (!group) | 1196 | if (!group) |
| 1188 | goto out; | 1197 | goto out; |
| @@ -1228,6 +1237,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
| 1228 | unsigned long max_delay; | 1237 | unsigned long max_delay; |
| 1229 | unsigned long now = jiffies; | 1238 | unsigned long now = jiffies; |
| 1230 | const struct in6_addr *group = NULL; | 1239 | const struct in6_addr *group = NULL; |
| 1240 | bool is_general_query; | ||
| 1231 | int err = 0; | 1241 | int err = 0; |
| 1232 | 1242 | ||
| 1233 | spin_lock(&br->multicast_lock); | 1243 | spin_lock(&br->multicast_lock); |
| @@ -1235,6 +1245,12 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
| 1235 | (port && port->state == BR_STATE_DISABLED)) | 1245 | (port && port->state == BR_STATE_DISABLED)) |
| 1236 | goto out; | 1246 | goto out; |
| 1237 | 1247 | ||
| 1248 | /* RFC2710+RFC3810 (MLDv1+MLDv2) require link-local source addresses */ | ||
| 1249 | if (!(ipv6_addr_type(&ip6h->saddr) & IPV6_ADDR_LINKLOCAL)) { | ||
| 1250 | err = -EINVAL; | ||
| 1251 | goto out; | ||
| 1252 | } | ||
| 1253 | |||
| 1238 | if (skb->len == sizeof(*mld)) { | 1254 | if (skb->len == sizeof(*mld)) { |
| 1239 | if (!pskb_may_pull(skb, sizeof(*mld))) { | 1255 | if (!pskb_may_pull(skb, sizeof(*mld))) { |
| 1240 | err = -EINVAL; | 1256 | err = -EINVAL; |
| @@ -1256,8 +1272,19 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
| 1256 | max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); | 1272 | max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); |
| 1257 | } | 1273 | } |
| 1258 | 1274 | ||
| 1275 | is_general_query = group && ipv6_addr_any(group); | ||
| 1276 | |||
| 1277 | /* RFC2710+RFC3810 (MLDv1+MLDv2) require the multicast link layer | ||
| 1278 | * all-nodes destination address (ff02::1) for general queries | ||
| 1279 | */ | ||
| 1280 | if (is_general_query && !ipv6_addr_is_ll_all_nodes(&ip6h->daddr)) { | ||
| 1281 | err = -EINVAL; | ||
| 1282 | goto out; | ||
| 1283 | } | ||
| 1284 | |||
| 1259 | br_multicast_query_received(br, port, &br->ip6_querier, | 1285 | br_multicast_query_received(br, port, &br->ip6_querier, |
| 1260 | !ipv6_addr_any(&ip6h->saddr), max_delay); | 1286 | !ipv6_addr_any(&ip6h->saddr), |
| 1287 | is_general_query, max_delay); | ||
| 1261 | 1288 | ||
| 1262 | if (!group) | 1289 | if (!group) |
| 1263 | goto out; | 1290 | goto out; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 5d6236d9fdce..869c7afe3b07 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -2838,81 +2838,84 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum); | |||
| 2838 | 2838 | ||
| 2839 | /** | 2839 | /** |
| 2840 | * skb_segment - Perform protocol segmentation on skb. | 2840 | * skb_segment - Perform protocol segmentation on skb. |
| 2841 | * @skb: buffer to segment | 2841 | * @head_skb: buffer to segment |
| 2842 | * @features: features for the output path (see dev->features) | 2842 | * @features: features for the output path (see dev->features) |
| 2843 | * | 2843 | * |
| 2844 | * This function performs segmentation on the given skb. It returns | 2844 | * This function performs segmentation on the given skb. It returns |
| 2845 | * a pointer to the first in a list of new skbs for the segments. | 2845 | * a pointer to the first in a list of new skbs for the segments. |
| 2846 | * In case of error it returns ERR_PTR(err). | 2846 | * In case of error it returns ERR_PTR(err). |
| 2847 | */ | 2847 | */ |
| 2848 | struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | 2848 | struct sk_buff *skb_segment(struct sk_buff *head_skb, |
| 2849 | netdev_features_t features) | ||
| 2849 | { | 2850 | { |
| 2850 | struct sk_buff *segs = NULL; | 2851 | struct sk_buff *segs = NULL; |
| 2851 | struct sk_buff *tail = NULL; | 2852 | struct sk_buff *tail = NULL; |
| 2852 | struct sk_buff *fskb = skb_shinfo(skb)->frag_list; | 2853 | struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list; |
| 2853 | skb_frag_t *skb_frag = skb_shinfo(skb)->frags; | 2854 | skb_frag_t *frag = skb_shinfo(head_skb)->frags; |
| 2854 | unsigned int mss = skb_shinfo(skb)->gso_size; | 2855 | unsigned int mss = skb_shinfo(head_skb)->gso_size; |
| 2855 | unsigned int doffset = skb->data - skb_mac_header(skb); | 2856 | unsigned int doffset = head_skb->data - skb_mac_header(head_skb); |
| 2857 | struct sk_buff *frag_skb = head_skb; | ||
| 2856 | unsigned int offset = doffset; | 2858 | unsigned int offset = doffset; |
| 2857 | unsigned int tnl_hlen = skb_tnl_header_len(skb); | 2859 | unsigned int tnl_hlen = skb_tnl_header_len(head_skb); |
| 2858 | unsigned int headroom; | 2860 | unsigned int headroom; |
| 2859 | unsigned int len; | 2861 | unsigned int len; |
| 2860 | __be16 proto; | 2862 | __be16 proto; |
| 2861 | bool csum; | 2863 | bool csum; |
| 2862 | int sg = !!(features & NETIF_F_SG); | 2864 | int sg = !!(features & NETIF_F_SG); |
| 2863 | int nfrags = skb_shinfo(skb)->nr_frags; | 2865 | int nfrags = skb_shinfo(head_skb)->nr_frags; |
| 2864 | int err = -ENOMEM; | 2866 | int err = -ENOMEM; |
| 2865 | int i = 0; | 2867 | int i = 0; |
| 2866 | int pos; | 2868 | int pos; |
| 2867 | 2869 | ||
| 2868 | proto = skb_network_protocol(skb); | 2870 | proto = skb_network_protocol(head_skb); |
| 2869 | if (unlikely(!proto)) | 2871 | if (unlikely(!proto)) |
| 2870 | return ERR_PTR(-EINVAL); | 2872 | return ERR_PTR(-EINVAL); |
| 2871 | 2873 | ||
| 2872 | csum = !!can_checksum_protocol(features, proto); | 2874 | csum = !!can_checksum_protocol(features, proto); |
| 2873 | __skb_push(skb, doffset); | 2875 | __skb_push(head_skb, doffset); |
| 2874 | headroom = skb_headroom(skb); | 2876 | headroom = skb_headroom(head_skb); |
| 2875 | pos = skb_headlen(skb); | 2877 | pos = skb_headlen(head_skb); |
| 2876 | 2878 | ||
| 2877 | do { | 2879 | do { |
| 2878 | struct sk_buff *nskb; | 2880 | struct sk_buff *nskb; |
| 2879 | skb_frag_t *frag; | 2881 | skb_frag_t *nskb_frag; |
| 2880 | int hsize; | 2882 | int hsize; |
| 2881 | int size; | 2883 | int size; |
| 2882 | 2884 | ||
| 2883 | len = skb->len - offset; | 2885 | len = head_skb->len - offset; |
| 2884 | if (len > mss) | 2886 | if (len > mss) |
| 2885 | len = mss; | 2887 | len = mss; |
| 2886 | 2888 | ||
| 2887 | hsize = skb_headlen(skb) - offset; | 2889 | hsize = skb_headlen(head_skb) - offset; |
| 2888 | if (hsize < 0) | 2890 | if (hsize < 0) |
| 2889 | hsize = 0; | 2891 | hsize = 0; |
| 2890 | if (hsize > len || !sg) | 2892 | if (hsize > len || !sg) |
| 2891 | hsize = len; | 2893 | hsize = len; |
| 2892 | 2894 | ||
| 2893 | if (!hsize && i >= nfrags && skb_headlen(fskb) && | 2895 | if (!hsize && i >= nfrags && skb_headlen(list_skb) && |
| 2894 | (skb_headlen(fskb) == len || sg)) { | 2896 | (skb_headlen(list_skb) == len || sg)) { |
| 2895 | BUG_ON(skb_headlen(fskb) > len); | 2897 | BUG_ON(skb_headlen(list_skb) > len); |
| 2896 | 2898 | ||
| 2897 | i = 0; | 2899 | i = 0; |
| 2898 | nfrags = skb_shinfo(fskb)->nr_frags; | 2900 | nfrags = skb_shinfo(list_skb)->nr_frags; |
| 2899 | skb_frag = skb_shinfo(fskb)->frags; | 2901 | frag = skb_shinfo(list_skb)->frags; |
| 2900 | pos += skb_headlen(fskb); | 2902 | frag_skb = list_skb; |
| 2903 | pos += skb_headlen(list_skb); | ||
| 2901 | 2904 | ||
| 2902 | while (pos < offset + len) { | 2905 | while (pos < offset + len) { |
| 2903 | BUG_ON(i >= nfrags); | 2906 | BUG_ON(i >= nfrags); |
| 2904 | 2907 | ||
| 2905 | size = skb_frag_size(skb_frag); | 2908 | size = skb_frag_size(frag); |
| 2906 | if (pos + size > offset + len) | 2909 | if (pos + size > offset + len) |
| 2907 | break; | 2910 | break; |
| 2908 | 2911 | ||
| 2909 | i++; | 2912 | i++; |
| 2910 | pos += size; | 2913 | pos += size; |
| 2911 | skb_frag++; | 2914 | frag++; |
| 2912 | } | 2915 | } |
| 2913 | 2916 | ||
| 2914 | nskb = skb_clone(fskb, GFP_ATOMIC); | 2917 | nskb = skb_clone(list_skb, GFP_ATOMIC); |
| 2915 | fskb = fskb->next; | 2918 | list_skb = list_skb->next; |
| 2916 | 2919 | ||
| 2917 | if (unlikely(!nskb)) | 2920 | if (unlikely(!nskb)) |
| 2918 | goto err; | 2921 | goto err; |
| @@ -2933,7 +2936,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2933 | __skb_push(nskb, doffset); | 2936 | __skb_push(nskb, doffset); |
| 2934 | } else { | 2937 | } else { |
| 2935 | nskb = __alloc_skb(hsize + doffset + headroom, | 2938 | nskb = __alloc_skb(hsize + doffset + headroom, |
| 2936 | GFP_ATOMIC, skb_alloc_rx_flag(skb), | 2939 | GFP_ATOMIC, skb_alloc_rx_flag(head_skb), |
| 2937 | NUMA_NO_NODE); | 2940 | NUMA_NO_NODE); |
| 2938 | 2941 | ||
| 2939 | if (unlikely(!nskb)) | 2942 | if (unlikely(!nskb)) |
| @@ -2949,12 +2952,12 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2949 | segs = nskb; | 2952 | segs = nskb; |
| 2950 | tail = nskb; | 2953 | tail = nskb; |
| 2951 | 2954 | ||
| 2952 | __copy_skb_header(nskb, skb); | 2955 | __copy_skb_header(nskb, head_skb); |
| 2953 | nskb->mac_len = skb->mac_len; | 2956 | nskb->mac_len = head_skb->mac_len; |
| 2954 | 2957 | ||
| 2955 | skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom); | 2958 | skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom); |
| 2956 | 2959 | ||
| 2957 | skb_copy_from_linear_data_offset(skb, -tnl_hlen, | 2960 | skb_copy_from_linear_data_offset(head_skb, -tnl_hlen, |
| 2958 | nskb->data - tnl_hlen, | 2961 | nskb->data - tnl_hlen, |
| 2959 | doffset + tnl_hlen); | 2962 | doffset + tnl_hlen); |
| 2960 | 2963 | ||
| @@ -2963,30 +2966,32 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2963 | 2966 | ||
| 2964 | if (!sg) { | 2967 | if (!sg) { |
| 2965 | nskb->ip_summed = CHECKSUM_NONE; | 2968 | nskb->ip_summed = CHECKSUM_NONE; |
| 2966 | nskb->csum = skb_copy_and_csum_bits(skb, offset, | 2969 | nskb->csum = skb_copy_and_csum_bits(head_skb, offset, |
| 2967 | skb_put(nskb, len), | 2970 | skb_put(nskb, len), |
| 2968 | len, 0); | 2971 | len, 0); |
| 2969 | continue; | 2972 | continue; |
| 2970 | } | 2973 | } |
| 2971 | 2974 | ||
| 2972 | frag = skb_shinfo(nskb)->frags; | 2975 | nskb_frag = skb_shinfo(nskb)->frags; |
| 2973 | 2976 | ||
| 2974 | skb_copy_from_linear_data_offset(skb, offset, | 2977 | skb_copy_from_linear_data_offset(head_skb, offset, |
| 2975 | skb_put(nskb, hsize), hsize); | 2978 | skb_put(nskb, hsize), hsize); |
| 2976 | 2979 | ||
| 2977 | skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; | 2980 | skb_shinfo(nskb)->tx_flags = skb_shinfo(head_skb)->tx_flags & |
| 2981 | SKBTX_SHARED_FRAG; | ||
| 2978 | 2982 | ||
| 2979 | while (pos < offset + len) { | 2983 | while (pos < offset + len) { |
| 2980 | if (i >= nfrags) { | 2984 | if (i >= nfrags) { |
| 2981 | BUG_ON(skb_headlen(fskb)); | 2985 | BUG_ON(skb_headlen(list_skb)); |
| 2982 | 2986 | ||
| 2983 | i = 0; | 2987 | i = 0; |
| 2984 | nfrags = skb_shinfo(fskb)->nr_frags; | 2988 | nfrags = skb_shinfo(list_skb)->nr_frags; |
| 2985 | skb_frag = skb_shinfo(fskb)->frags; | 2989 | frag = skb_shinfo(list_skb)->frags; |
| 2990 | frag_skb = list_skb; | ||
| 2986 | 2991 | ||
| 2987 | BUG_ON(!nfrags); | 2992 | BUG_ON(!nfrags); |
| 2988 | 2993 | ||
| 2989 | fskb = fskb->next; | 2994 | list_skb = list_skb->next; |
| 2990 | } | 2995 | } |
| 2991 | 2996 | ||
| 2992 | if (unlikely(skb_shinfo(nskb)->nr_frags >= | 2997 | if (unlikely(skb_shinfo(nskb)->nr_frags >= |
| @@ -2997,27 +3002,30 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2997 | goto err; | 3002 | goto err; |
| 2998 | } | 3003 | } |
| 2999 | 3004 | ||
| 3000 | *frag = *skb_frag; | 3005 | if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC))) |
| 3001 | __skb_frag_ref(frag); | 3006 | goto err; |
| 3002 | size = skb_frag_size(frag); | 3007 | |
| 3008 | *nskb_frag = *frag; | ||
| 3009 | __skb_frag_ref(nskb_frag); | ||
| 3010 | size = skb_frag_size(nskb_frag); | ||
| 3003 | 3011 | ||
| 3004 | if (pos < offset) { | 3012 | if (pos < offset) { |
| 3005 | frag->page_offset += offset - pos; | 3013 | nskb_frag->page_offset += offset - pos; |
| 3006 | skb_frag_size_sub(frag, offset - pos); | 3014 | skb_frag_size_sub(nskb_frag, offset - pos); |
| 3007 | } | 3015 | } |
| 3008 | 3016 | ||
| 3009 | skb_shinfo(nskb)->nr_frags++; | 3017 | skb_shinfo(nskb)->nr_frags++; |
| 3010 | 3018 | ||
| 3011 | if (pos + size <= offset + len) { | 3019 | if (pos + size <= offset + len) { |
| 3012 | i++; | 3020 | i++; |
| 3013 | skb_frag++; | 3021 | frag++; |
| 3014 | pos += size; | 3022 | pos += size; |
| 3015 | } else { | 3023 | } else { |
| 3016 | skb_frag_size_sub(frag, pos + size - (offset + len)); | 3024 | skb_frag_size_sub(nskb_frag, pos + size - (offset + len)); |
| 3017 | goto skip_fraglist; | 3025 | goto skip_fraglist; |
| 3018 | } | 3026 | } |
| 3019 | 3027 | ||
| 3020 | frag++; | 3028 | nskb_frag++; |
| 3021 | } | 3029 | } |
| 3022 | 3030 | ||
| 3023 | skip_fraglist: | 3031 | skip_fraglist: |
| @@ -3031,7 +3039,7 @@ perform_csum_check: | |||
| 3031 | nskb->len - doffset, 0); | 3039 | nskb->len - doffset, 0); |
| 3032 | nskb->ip_summed = CHECKSUM_NONE; | 3040 | nskb->ip_summed = CHECKSUM_NONE; |
| 3033 | } | 3041 | } |
| 3034 | } while ((offset += len) < skb->len); | 3042 | } while ((offset += len) < head_skb->len); |
| 3035 | 3043 | ||
| 3036 | return segs; | 3044 | return segs; |
| 3037 | 3045 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 5b6a9431b017..c0fc6bdad1e3 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -2357,10 +2357,13 @@ void release_sock(struct sock *sk) | |||
| 2357 | if (sk->sk_backlog.tail) | 2357 | if (sk->sk_backlog.tail) |
| 2358 | __release_sock(sk); | 2358 | __release_sock(sk); |
| 2359 | 2359 | ||
| 2360 | /* Warning : release_cb() might need to release sk ownership, | ||
| 2361 | * ie call sock_release_ownership(sk) before us. | ||
| 2362 | */ | ||
| 2360 | if (sk->sk_prot->release_cb) | 2363 | if (sk->sk_prot->release_cb) |
| 2361 | sk->sk_prot->release_cb(sk); | 2364 | sk->sk_prot->release_cb(sk); |
| 2362 | 2365 | ||
| 2363 | sk->sk_lock.owned = 0; | 2366 | sock_release_ownership(sk); |
| 2364 | if (waitqueue_active(&sk->sk_lock.wq)) | 2367 | if (waitqueue_active(&sk->sk_lock.wq)) |
| 2365 | wake_up(&sk->sk_lock.wq); | 2368 | wake_up(&sk->sk_lock.wq); |
| 2366 | spin_unlock_bh(&sk->sk_lock.slock); | 2369 | spin_unlock_bh(&sk->sk_lock.slock); |
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index bb075fc9a14f..3b01959bf4bb 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
| @@ -208,7 +208,7 @@ int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force) | |||
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | work = frag_mem_limit(nf) - nf->low_thresh; | 210 | work = frag_mem_limit(nf) - nf->low_thresh; |
| 211 | while (work > 0) { | 211 | while (work > 0 || force) { |
| 212 | spin_lock(&nf->lru_lock); | 212 | spin_lock(&nf->lru_lock); |
| 213 | 213 | ||
| 214 | if (list_empty(&nf->lru_list)) { | 214 | if (list_empty(&nf->lru_list)) { |
| @@ -278,9 +278,10 @@ static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, | |||
| 278 | 278 | ||
| 279 | atomic_inc(&qp->refcnt); | 279 | atomic_inc(&qp->refcnt); |
| 280 | hlist_add_head(&qp->list, &hb->chain); | 280 | hlist_add_head(&qp->list, &hb->chain); |
| 281 | inet_frag_lru_add(nf, qp); | ||
| 281 | spin_unlock(&hb->chain_lock); | 282 | spin_unlock(&hb->chain_lock); |
| 282 | read_unlock(&f->lock); | 283 | read_unlock(&f->lock); |
| 283 | inet_frag_lru_add(nf, qp); | 284 | |
| 284 | return qp; | 285 | return qp; |
| 285 | } | 286 | } |
| 286 | 287 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f0eb4e337ec8..17a11e65e57f 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -767,6 +767,17 @@ void tcp_release_cb(struct sock *sk) | |||
| 767 | if (flags & (1UL << TCP_TSQ_DEFERRED)) | 767 | if (flags & (1UL << TCP_TSQ_DEFERRED)) |
| 768 | tcp_tsq_handler(sk); | 768 | tcp_tsq_handler(sk); |
| 769 | 769 | ||
| 770 | /* Here begins the tricky part : | ||
| 771 | * We are called from release_sock() with : | ||
| 772 | * 1) BH disabled | ||
| 773 | * 2) sk_lock.slock spinlock held | ||
| 774 | * 3) socket owned by us (sk->sk_lock.owned == 1) | ||
| 775 | * | ||
| 776 | * But following code is meant to be called from BH handlers, | ||
| 777 | * so we should keep BH disabled, but early release socket ownership | ||
| 778 | */ | ||
| 779 | sock_release_ownership(sk); | ||
| 780 | |||
| 770 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { | 781 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { |
| 771 | tcp_write_timer_handler(sk); | 782 | tcp_write_timer_handler(sk); |
| 772 | __sock_put(sk); | 783 | __sock_put(sk); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index fdbfeca36d63..344e972426df 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -1103,8 +1103,11 @@ retry: | |||
| 1103 | * Lifetime is greater than REGEN_ADVANCE time units. In particular, | 1103 | * Lifetime is greater than REGEN_ADVANCE time units. In particular, |
| 1104 | * an implementation must not create a temporary address with a zero | 1104 | * an implementation must not create a temporary address with a zero |
| 1105 | * Preferred Lifetime. | 1105 | * Preferred Lifetime. |
| 1106 | * Use age calculation as in addrconf_verify to avoid unnecessary | ||
| 1107 | * temporary addresses being generated. | ||
| 1106 | */ | 1108 | */ |
| 1107 | if (tmp_prefered_lft <= regen_advance) { | 1109 | age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ; |
| 1110 | if (tmp_prefered_lft <= regen_advance + age) { | ||
| 1108 | in6_ifa_put(ifp); | 1111 | in6_ifa_put(ifp); |
| 1109 | in6_dev_put(idev); | 1112 | in6_dev_put(idev); |
| 1110 | ret = -1; | 1113 | ret = -1; |
diff --git a/net/ipv6/exthdrs_offload.c b/net/ipv6/exthdrs_offload.c index cf77f3abfd06..447a7fbd1bb6 100644 --- a/net/ipv6/exthdrs_offload.c +++ b/net/ipv6/exthdrs_offload.c | |||
| @@ -25,11 +25,11 @@ int __init ipv6_exthdrs_offload_init(void) | |||
| 25 | int ret; | 25 | int ret; |
| 26 | 26 | ||
| 27 | ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING); | 27 | ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING); |
| 28 | if (!ret) | 28 | if (ret) |
| 29 | goto out; | 29 | goto out; |
| 30 | 30 | ||
| 31 | ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS); | 31 | ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS); |
| 32 | if (!ret) | 32 | if (ret) |
| 33 | goto out_rt; | 33 | goto out_rt; |
| 34 | 34 | ||
| 35 | out: | 35 | out: |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 11dac21e6586..fba54a407bb2 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -1513,7 +1513,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
| 1513 | if (!table) | 1513 | if (!table) |
| 1514 | goto out; | 1514 | goto out; |
| 1515 | 1515 | ||
| 1516 | rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table); | 1516 | rt = ip6_dst_alloc(net, NULL, (cfg->fc_flags & RTF_ADDRCONF) ? 0 : DST_NOCOUNT, table); |
| 1517 | 1517 | ||
| 1518 | if (!rt) { | 1518 | if (!rt) { |
| 1519 | err = -ENOMEM; | 1519 | err = -ENOMEM; |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 735d0f60c83a..85d9d94c0a3c 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
| @@ -112,7 +112,6 @@ struct l2tp_net { | |||
| 112 | spinlock_t l2tp_session_hlist_lock; | 112 | spinlock_t l2tp_session_hlist_lock; |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | static void l2tp_session_set_header_len(struct l2tp_session *session, int version); | ||
| 116 | static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); | 115 | static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); |
| 117 | 116 | ||
| 118 | static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) | 117 | static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) |
| @@ -1863,7 +1862,7 @@ EXPORT_SYMBOL_GPL(l2tp_session_delete); | |||
| 1863 | /* We come here whenever a session's send_seq, cookie_len or | 1862 | /* We come here whenever a session's send_seq, cookie_len or |
| 1864 | * l2specific_len parameters are set. | 1863 | * l2specific_len parameters are set. |
| 1865 | */ | 1864 | */ |
| 1866 | static void l2tp_session_set_header_len(struct l2tp_session *session, int version) | 1865 | void l2tp_session_set_header_len(struct l2tp_session *session, int version) |
| 1867 | { | 1866 | { |
| 1868 | if (version == L2TP_HDR_VER_2) { | 1867 | if (version == L2TP_HDR_VER_2) { |
| 1869 | session->hdr_len = 6; | 1868 | session->hdr_len = 6; |
| @@ -1876,6 +1875,7 @@ static void l2tp_session_set_header_len(struct l2tp_session *session, int versio | |||
| 1876 | } | 1875 | } |
| 1877 | 1876 | ||
| 1878 | } | 1877 | } |
| 1878 | EXPORT_SYMBOL_GPL(l2tp_session_set_header_len); | ||
| 1879 | 1879 | ||
| 1880 | struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) | 1880 | struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) |
| 1881 | { | 1881 | { |
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 1f01ba3435bc..3f93ccd6ba97 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h | |||
| @@ -263,6 +263,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, | |||
| 263 | int length, int (*payload_hook)(struct sk_buff *skb)); | 263 | int length, int (*payload_hook)(struct sk_buff *skb)); |
| 264 | int l2tp_session_queue_purge(struct l2tp_session *session); | 264 | int l2tp_session_queue_purge(struct l2tp_session *session); |
| 265 | int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb); | 265 | int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb); |
| 266 | void l2tp_session_set_header_len(struct l2tp_session *session, int version); | ||
| 266 | 267 | ||
| 267 | int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, | 268 | int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, |
| 268 | int hdr_len); | 269 | int hdr_len); |
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 4cfd722e9153..bd7387adea9e 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c | |||
| @@ -578,8 +578,10 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf | |||
| 578 | if (info->attrs[L2TP_ATTR_RECV_SEQ]) | 578 | if (info->attrs[L2TP_ATTR_RECV_SEQ]) |
| 579 | session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]); | 579 | session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]); |
| 580 | 580 | ||
| 581 | if (info->attrs[L2TP_ATTR_SEND_SEQ]) | 581 | if (info->attrs[L2TP_ATTR_SEND_SEQ]) { |
| 582 | session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]); | 582 | session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]); |
| 583 | l2tp_session_set_header_len(session, session->tunnel->version); | ||
| 584 | } | ||
| 583 | 585 | ||
| 584 | if (info->attrs[L2TP_ATTR_LNS_MODE]) | 586 | if (info->attrs[L2TP_ATTR_LNS_MODE]) |
| 585 | session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]); | 587 | session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]); |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index be5fadf34739..5990919356a5 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
| @@ -254,12 +254,14 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int | |||
| 254 | po = pppox_sk(sk); | 254 | po = pppox_sk(sk); |
| 255 | ppp_input(&po->chan, skb); | 255 | ppp_input(&po->chan, skb); |
| 256 | } else { | 256 | } else { |
| 257 | l2tp_info(session, PPPOL2TP_MSG_DATA, "%s: socket not bound\n", | 257 | l2tp_dbg(session, PPPOL2TP_MSG_DATA, |
| 258 | session->name); | 258 | "%s: recv %d byte data frame, passing to L2TP socket\n", |
| 259 | session->name, data_len); | ||
| 259 | 260 | ||
| 260 | /* Not bound. Nothing we can do, so discard. */ | 261 | if (sock_queue_rcv_skb(sk, skb) < 0) { |
| 261 | atomic_long_inc(&session->stats.rx_errors); | 262 | atomic_long_inc(&session->stats.rx_errors); |
| 262 | kfree_skb(skb); | 263 | kfree_skb(skb); |
| 264 | } | ||
| 263 | } | 265 | } |
| 264 | 266 | ||
| 265 | return; | 267 | return; |
| @@ -1312,6 +1314,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk, | |||
| 1312 | po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : | 1314 | po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : |
| 1313 | PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; | 1315 | PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; |
| 1314 | } | 1316 | } |
| 1317 | l2tp_session_set_header_len(session, session->tunnel->version); | ||
| 1315 | l2tp_info(session, PPPOL2TP_MSG_CONTROL, | 1318 | l2tp_info(session, PPPOL2TP_MSG_CONTROL, |
| 1316 | "%s: set send_seq=%d\n", | 1319 | "%s: set send_seq=%d\n", |
| 1317 | session->name, session->send_seq); | 1320 | session->name, session->send_seq); |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index f43613a97dd6..0c1ecfdf9a12 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
| @@ -100,6 +100,12 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, | |||
| 100 | } | 100 | } |
| 101 | max_bw = max(max_bw, width); | 101 | max_bw = max(max_bw, width); |
| 102 | } | 102 | } |
| 103 | |||
| 104 | /* use the configured bandwidth in case of monitor interface */ | ||
| 105 | sdata = rcu_dereference(local->monitor_sdata); | ||
| 106 | if (sdata && rcu_access_pointer(sdata->vif.chanctx_conf) == conf) | ||
| 107 | max_bw = max(max_bw, conf->def.width); | ||
| 108 | |||
| 103 | rcu_read_unlock(); | 109 | rcu_read_unlock(); |
| 104 | 110 | ||
| 105 | return max_bw; | 111 | return max_bw; |
diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c index 2802f9d9279d..ad8b377b4b9f 100644 --- a/net/mac80211/mesh_ps.c +++ b/net/mac80211/mesh_ps.c | |||
| @@ -36,6 +36,7 @@ static struct sk_buff *mps_qos_null_get(struct sta_info *sta) | |||
| 36 | sdata->vif.addr); | 36 | sdata->vif.addr); |
| 37 | nullfunc->frame_control = fc; | 37 | nullfunc->frame_control = fc; |
| 38 | nullfunc->duration_id = 0; | 38 | nullfunc->duration_id = 0; |
| 39 | nullfunc->seq_ctrl = 0; | ||
| 39 | /* no address resolution for this frame -> set addr 1 immediately */ | 40 | /* no address resolution for this frame -> set addr 1 immediately */ |
| 40 | memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); | 41 | memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); |
| 41 | memset(skb_put(skb, 2), 0, 2); /* append QoS control field */ | 42 | memset(skb_put(skb, 2), 0, 2); /* append QoS control field */ |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a023b432143b..137a192e64bc 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -1206,6 +1206,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
| 1206 | memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); | 1206 | memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); |
| 1207 | memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); | 1207 | memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); |
| 1208 | memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); | 1208 | memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); |
| 1209 | nullfunc->seq_ctrl = 0; | ||
| 1209 | 1210 | ||
| 1210 | skb->priority = tid; | 1211 | skb->priority = tid; |
| 1211 | skb_set_queue_mapping(skb, ieee802_1d_to_ac[tid]); | 1212 | skb_set_queue_mapping(skb, ieee802_1d_to_ac[tid]); |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 1313145e3b86..a07d55e75698 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
| @@ -273,11 +273,12 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) | |||
| 273 | 273 | ||
| 274 | void qdisc_list_add(struct Qdisc *q) | 274 | void qdisc_list_add(struct Qdisc *q) |
| 275 | { | 275 | { |
| 276 | struct Qdisc *root = qdisc_dev(q)->qdisc; | 276 | if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) { |
| 277 | struct Qdisc *root = qdisc_dev(q)->qdisc; | ||
| 277 | 278 | ||
| 278 | WARN_ON_ONCE(root == &noop_qdisc); | 279 | WARN_ON_ONCE(root == &noop_qdisc); |
| 279 | if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) | ||
| 280 | list_add_tail(&q->list, &root->list); | 280 | list_add_tail(&q->list, &root->list); |
| 281 | } | ||
| 281 | } | 282 | } |
| 282 | EXPORT_SYMBOL(qdisc_list_add); | 283 | EXPORT_SYMBOL(qdisc_list_add); |
| 283 | 284 | ||
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 08ef7a42c0e4..21e251766eb1 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c | |||
| @@ -601,6 +601,7 @@ static int fq_resize(struct Qdisc *sch, u32 log) | |||
| 601 | { | 601 | { |
| 602 | struct fq_sched_data *q = qdisc_priv(sch); | 602 | struct fq_sched_data *q = qdisc_priv(sch); |
| 603 | struct rb_root *array; | 603 | struct rb_root *array; |
| 604 | void *old_fq_root; | ||
| 604 | u32 idx; | 605 | u32 idx; |
| 605 | 606 | ||
| 606 | if (q->fq_root && log == q->fq_trees_log) | 607 | if (q->fq_root && log == q->fq_trees_log) |
| @@ -615,13 +616,19 @@ static int fq_resize(struct Qdisc *sch, u32 log) | |||
| 615 | for (idx = 0; idx < (1U << log); idx++) | 616 | for (idx = 0; idx < (1U << log); idx++) |
| 616 | array[idx] = RB_ROOT; | 617 | array[idx] = RB_ROOT; |
| 617 | 618 | ||
| 618 | if (q->fq_root) { | 619 | sch_tree_lock(sch); |
| 619 | fq_rehash(q, q->fq_root, q->fq_trees_log, array, log); | 620 | |
| 620 | fq_free(q->fq_root); | 621 | old_fq_root = q->fq_root; |
| 621 | } | 622 | if (old_fq_root) |
| 623 | fq_rehash(q, old_fq_root, q->fq_trees_log, array, log); | ||
| 624 | |||
| 622 | q->fq_root = array; | 625 | q->fq_root = array; |
| 623 | q->fq_trees_log = log; | 626 | q->fq_trees_log = log; |
| 624 | 627 | ||
| 628 | sch_tree_unlock(sch); | ||
| 629 | |||
| 630 | fq_free(old_fq_root); | ||
| 631 | |||
| 625 | return 0; | 632 | return 0; |
| 626 | } | 633 | } |
| 627 | 634 | ||
| @@ -697,9 +704,11 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 697 | q->flow_refill_delay = usecs_to_jiffies(usecs_delay); | 704 | q->flow_refill_delay = usecs_to_jiffies(usecs_delay); |
| 698 | } | 705 | } |
| 699 | 706 | ||
| 700 | if (!err) | 707 | if (!err) { |
| 708 | sch_tree_unlock(sch); | ||
| 701 | err = fq_resize(sch, fq_log); | 709 | err = fq_resize(sch, fq_log); |
| 702 | 710 | sch_tree_lock(sch); | |
| 711 | } | ||
| 703 | while (sch->q.qlen > sch->limit) { | 712 | while (sch->q.qlen > sch->limit) { |
| 704 | struct sk_buff *skb = fq_dequeue(sch); | 713 | struct sk_buff *skb = fq_dequeue(sch); |
| 705 | 714 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 632090b961c3..3a1767ef3201 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
| @@ -1421,8 +1421,8 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk) | |||
| 1421 | BUG_ON(!list_empty(&chunk->list)); | 1421 | BUG_ON(!list_empty(&chunk->list)); |
| 1422 | list_del_init(&chunk->transmitted_list); | 1422 | list_del_init(&chunk->transmitted_list); |
| 1423 | 1423 | ||
| 1424 | /* Free the chunk skb data and the SCTP_chunk stub itself. */ | 1424 | consume_skb(chunk->skb); |
| 1425 | dev_kfree_skb(chunk->skb); | 1425 | consume_skb(chunk->auth_chunk); |
| 1426 | 1426 | ||
| 1427 | SCTP_DBG_OBJCNT_DEC(chunk); | 1427 | SCTP_DBG_OBJCNT_DEC(chunk); |
| 1428 | kmem_cache_free(sctp_chunk_cachep, chunk); | 1428 | kmem_cache_free(sctp_chunk_cachep, chunk); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index ae65b6b5973a..01e002430c85 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -760,7 +760,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | |||
| 760 | 760 | ||
| 761 | /* Make sure that we and the peer are AUTH capable */ | 761 | /* Make sure that we and the peer are AUTH capable */ |
| 762 | if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { | 762 | if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { |
| 763 | kfree_skb(chunk->auth_chunk); | ||
| 764 | sctp_association_free(new_asoc); | 763 | sctp_association_free(new_asoc); |
| 765 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | 764 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); |
| 766 | } | 765 | } |
| @@ -775,10 +774,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | |||
| 775 | auth.transport = chunk->transport; | 774 | auth.transport = chunk->transport; |
| 776 | 775 | ||
| 777 | ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth); | 776 | ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth); |
| 778 | |||
| 779 | /* We can now safely free the auth_chunk clone */ | ||
| 780 | kfree_skb(chunk->auth_chunk); | ||
| 781 | |||
| 782 | if (ret != SCTP_IERROR_NO_ERROR) { | 777 | if (ret != SCTP_IERROR_NO_ERROR) { |
| 783 | sctp_association_free(new_asoc); | 778 | sctp_association_free(new_asoc); |
| 784 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | 779 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); |
diff --git a/net/socket.c b/net/socket.c index 879933aaed4c..a19ae1968d37 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -450,16 +450,17 @@ EXPORT_SYMBOL(sockfd_lookup); | |||
| 450 | 450 | ||
| 451 | static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) | 451 | static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) |
| 452 | { | 452 | { |
| 453 | struct file *file; | 453 | struct fd f = fdget(fd); |
| 454 | struct socket *sock; | 454 | struct socket *sock; |
| 455 | 455 | ||
| 456 | *err = -EBADF; | 456 | *err = -EBADF; |
| 457 | file = fget_light(fd, fput_needed); | 457 | if (f.file) { |
| 458 | if (file) { | 458 | sock = sock_from_file(f.file, err); |
| 459 | sock = sock_from_file(file, err); | 459 | if (likely(sock)) { |
| 460 | if (sock) | 460 | *fput_needed = f.flags; |
| 461 | return sock; | 461 | return sock; |
| 462 | fput_light(file, *fput_needed); | 462 | } |
| 463 | fdput(f); | ||
| 463 | } | 464 | } |
| 464 | return NULL; | 465 | return NULL; |
| 465 | } | 466 | } |
| @@ -1985,6 +1986,10 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, | |||
| 1985 | { | 1986 | { |
| 1986 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) | 1987 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) |
| 1987 | return -EFAULT; | 1988 | return -EFAULT; |
| 1989 | |||
| 1990 | if (kmsg->msg_namelen < 0) | ||
| 1991 | return -EINVAL; | ||
| 1992 | |||
| 1988 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) | 1993 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) |
| 1989 | kmsg->msg_namelen = sizeof(struct sockaddr_storage); | 1994 | kmsg->msg_namelen = sizeof(struct sockaddr_storage); |
| 1990 | return 0; | 1995 | return 0; |
diff --git a/net/tipc/config.c b/net/tipc/config.c index e74eef2e7490..e6d721692ae0 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c | |||
| @@ -376,7 +376,6 @@ static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr, | |||
| 376 | struct tipc_cfg_msg_hdr *req_hdr; | 376 | struct tipc_cfg_msg_hdr *req_hdr; |
| 377 | struct tipc_cfg_msg_hdr *rep_hdr; | 377 | struct tipc_cfg_msg_hdr *rep_hdr; |
| 378 | struct sk_buff *rep_buf; | 378 | struct sk_buff *rep_buf; |
| 379 | int ret; | ||
| 380 | 379 | ||
| 381 | /* Validate configuration message header (ignore invalid message) */ | 380 | /* Validate configuration message header (ignore invalid message) */ |
| 382 | req_hdr = (struct tipc_cfg_msg_hdr *)buf; | 381 | req_hdr = (struct tipc_cfg_msg_hdr *)buf; |
| @@ -398,12 +397,8 @@ static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr, | |||
| 398 | memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr)); | 397 | memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr)); |
| 399 | rep_hdr->tcm_len = htonl(rep_buf->len); | 398 | rep_hdr->tcm_len = htonl(rep_buf->len); |
| 400 | rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST); | 399 | rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST); |
| 401 | 400 | tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data, | |
| 402 | ret = tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data, | 401 | rep_buf->len); |
| 403 | rep_buf->len); | ||
| 404 | if (ret < 0) | ||
| 405 | pr_err("Sending cfg reply message failed, no memory\n"); | ||
| 406 | |||
| 407 | kfree_skb(rep_buf); | 402 | kfree_skb(rep_buf); |
| 408 | } | 403 | } |
| 409 | } | 404 | } |
diff --git a/net/tipc/handler.c b/net/tipc/handler.c index e4bc8a296744..1fabf160501f 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c | |||
| @@ -58,7 +58,6 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument) | |||
| 58 | 58 | ||
| 59 | spin_lock_bh(&qitem_lock); | 59 | spin_lock_bh(&qitem_lock); |
| 60 | if (!handler_enabled) { | 60 | if (!handler_enabled) { |
| 61 | pr_err("Signal request ignored by handler\n"); | ||
| 62 | spin_unlock_bh(&qitem_lock); | 61 | spin_unlock_bh(&qitem_lock); |
| 63 | return -ENOPROTOOPT; | 62 | return -ENOPROTOOPT; |
| 64 | } | 63 | } |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 48302be175ce..042e8e3cabc0 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
| @@ -941,17 +941,48 @@ int tipc_nametbl_init(void) | |||
| 941 | return 0; | 941 | return 0; |
| 942 | } | 942 | } |
| 943 | 943 | ||
| 944 | /** | ||
| 945 | * tipc_purge_publications - remove all publications for a given type | ||
| 946 | * | ||
| 947 | * tipc_nametbl_lock must be held when calling this function | ||
| 948 | */ | ||
| 949 | static void tipc_purge_publications(struct name_seq *seq) | ||
| 950 | { | ||
| 951 | struct publication *publ, *safe; | ||
| 952 | struct sub_seq *sseq; | ||
| 953 | struct name_info *info; | ||
| 954 | |||
| 955 | if (!seq->sseqs) { | ||
| 956 | nameseq_delete_empty(seq); | ||
| 957 | return; | ||
| 958 | } | ||
| 959 | sseq = seq->sseqs; | ||
| 960 | info = sseq->info; | ||
| 961 | list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) { | ||
| 962 | tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node, | ||
| 963 | publ->ref, publ->key); | ||
| 964 | } | ||
| 965 | } | ||
| 966 | |||
| 944 | void tipc_nametbl_stop(void) | 967 | void tipc_nametbl_stop(void) |
| 945 | { | 968 | { |
| 946 | u32 i; | 969 | u32 i; |
| 970 | struct name_seq *seq; | ||
| 971 | struct hlist_head *seq_head; | ||
| 972 | struct hlist_node *safe; | ||
| 947 | 973 | ||
| 948 | /* Verify name table is empty, then release it */ | 974 | /* Verify name table is empty and purge any lingering |
| 975 | * publications, then release the name table | ||
| 976 | */ | ||
| 949 | write_lock_bh(&tipc_nametbl_lock); | 977 | write_lock_bh(&tipc_nametbl_lock); |
| 950 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { | 978 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { |
| 951 | if (hlist_empty(&table.types[i])) | 979 | if (hlist_empty(&table.types[i])) |
| 952 | continue; | 980 | continue; |
| 953 | pr_err("nametbl_stop(): orphaned hash chain detected\n"); | 981 | seq_head = &table.types[i]; |
| 954 | break; | 982 | hlist_for_each_entry_safe(seq, safe, seq_head, ns_list) { |
| 983 | tipc_purge_publications(seq); | ||
| 984 | } | ||
| 985 | continue; | ||
| 955 | } | 986 | } |
| 956 | kfree(table.types); | 987 | kfree(table.types); |
| 957 | table.types = NULL; | 988 | table.types = NULL; |
diff --git a/net/tipc/server.c b/net/tipc/server.c index 373979789a73..646a930eefbf 100644 --- a/net/tipc/server.c +++ b/net/tipc/server.c | |||
| @@ -87,7 +87,6 @@ static void tipc_clean_outqueues(struct tipc_conn *con); | |||
| 87 | static void tipc_conn_kref_release(struct kref *kref) | 87 | static void tipc_conn_kref_release(struct kref *kref) |
| 88 | { | 88 | { |
| 89 | struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); | 89 | struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); |
| 90 | struct tipc_server *s = con->server; | ||
| 91 | 90 | ||
| 92 | if (con->sock) { | 91 | if (con->sock) { |
| 93 | tipc_sock_release_local(con->sock); | 92 | tipc_sock_release_local(con->sock); |
| @@ -95,10 +94,6 @@ static void tipc_conn_kref_release(struct kref *kref) | |||
| 95 | } | 94 | } |
| 96 | 95 | ||
| 97 | tipc_clean_outqueues(con); | 96 | tipc_clean_outqueues(con); |
| 98 | |||
| 99 | if (con->conid) | ||
| 100 | s->tipc_conn_shutdown(con->conid, con->usr_data); | ||
| 101 | |||
| 102 | kfree(con); | 97 | kfree(con); |
| 103 | } | 98 | } |
| 104 | 99 | ||
| @@ -181,6 +176,9 @@ static void tipc_close_conn(struct tipc_conn *con) | |||
| 181 | struct tipc_server *s = con->server; | 176 | struct tipc_server *s = con->server; |
| 182 | 177 | ||
| 183 | if (test_and_clear_bit(CF_CONNECTED, &con->flags)) { | 178 | if (test_and_clear_bit(CF_CONNECTED, &con->flags)) { |
| 179 | if (con->conid) | ||
| 180 | s->tipc_conn_shutdown(con->conid, con->usr_data); | ||
| 181 | |||
| 184 | spin_lock_bh(&s->idr_lock); | 182 | spin_lock_bh(&s->idr_lock); |
| 185 | idr_remove(&s->conn_idr, con->conid); | 183 | idr_remove(&s->conn_idr, con->conid); |
| 186 | s->idr_in_use--; | 184 | s->idr_in_use--; |
| @@ -429,10 +427,12 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid, | |||
| 429 | list_add_tail(&e->list, &con->outqueue); | 427 | list_add_tail(&e->list, &con->outqueue); |
| 430 | spin_unlock_bh(&con->outqueue_lock); | 428 | spin_unlock_bh(&con->outqueue_lock); |
| 431 | 429 | ||
| 432 | if (test_bit(CF_CONNECTED, &con->flags)) | 430 | if (test_bit(CF_CONNECTED, &con->flags)) { |
| 433 | if (!queue_work(s->send_wq, &con->swork)) | 431 | if (!queue_work(s->send_wq, &con->swork)) |
| 434 | conn_put(con); | 432 | conn_put(con); |
| 435 | 433 | } else { | |
| 434 | conn_put(con); | ||
| 435 | } | ||
| 436 | return 0; | 436 | return 0; |
| 437 | } | 437 | } |
| 438 | 438 | ||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index a4cf274455aa..0ed0eaa62f29 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -997,7 +997,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long timeo) | |||
| 997 | 997 | ||
| 998 | for (;;) { | 998 | for (;;) { |
| 999 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 999 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
| 1000 | if (skb_queue_empty(&sk->sk_receive_queue)) { | 1000 | if (timeo && skb_queue_empty(&sk->sk_receive_queue)) { |
| 1001 | if (sock->state == SS_DISCONNECTING) { | 1001 | if (sock->state == SS_DISCONNECTING) { |
| 1002 | err = -ENOTCONN; | 1002 | err = -ENOTCONN; |
| 1003 | break; | 1003 | break; |
| @@ -1623,7 +1623,7 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) | |||
| 1623 | for (;;) { | 1623 | for (;;) { |
| 1624 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, | 1624 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, |
| 1625 | TASK_INTERRUPTIBLE); | 1625 | TASK_INTERRUPTIBLE); |
| 1626 | if (skb_queue_empty(&sk->sk_receive_queue)) { | 1626 | if (timeo && skb_queue_empty(&sk->sk_receive_queue)) { |
| 1627 | release_sock(sk); | 1627 | release_sock(sk); |
| 1628 | timeo = schedule_timeout(timeo); | 1628 | timeo = schedule_timeout(timeo); |
| 1629 | lock_sock(sk); | 1629 | lock_sock(sk); |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 7cb0bd5b1176..11c9ae00837d 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
| @@ -96,20 +96,16 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower, | |||
| 96 | { | 96 | { |
| 97 | struct tipc_subscriber *subscriber = sub->subscriber; | 97 | struct tipc_subscriber *subscriber = sub->subscriber; |
| 98 | struct kvec msg_sect; | 98 | struct kvec msg_sect; |
| 99 | int ret; | ||
| 100 | 99 | ||
| 101 | msg_sect.iov_base = (void *)&sub->evt; | 100 | msg_sect.iov_base = (void *)&sub->evt; |
| 102 | msg_sect.iov_len = sizeof(struct tipc_event); | 101 | msg_sect.iov_len = sizeof(struct tipc_event); |
| 103 | |||
| 104 | sub->evt.event = htohl(event, sub->swap); | 102 | sub->evt.event = htohl(event, sub->swap); |
| 105 | sub->evt.found_lower = htohl(found_lower, sub->swap); | 103 | sub->evt.found_lower = htohl(found_lower, sub->swap); |
| 106 | sub->evt.found_upper = htohl(found_upper, sub->swap); | 104 | sub->evt.found_upper = htohl(found_upper, sub->swap); |
| 107 | sub->evt.port.ref = htohl(port_ref, sub->swap); | 105 | sub->evt.port.ref = htohl(port_ref, sub->swap); |
| 108 | sub->evt.port.node = htohl(node, sub->swap); | 106 | sub->evt.port.node = htohl(node, sub->swap); |
| 109 | ret = tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, | 107 | tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, msg_sect.iov_base, |
| 110 | msg_sect.iov_base, msg_sect.iov_len); | 108 | msg_sect.iov_len); |
| 111 | if (ret < 0) | ||
| 112 | pr_err("Sending subscription event failed, no memory\n"); | ||
| 113 | } | 109 | } |
| 114 | 110 | ||
| 115 | /** | 111 | /** |
| @@ -153,14 +149,6 @@ static void subscr_timeout(struct tipc_subscription *sub) | |||
| 153 | /* The spin lock per subscriber is used to protect its members */ | 149 | /* The spin lock per subscriber is used to protect its members */ |
| 154 | spin_lock_bh(&subscriber->lock); | 150 | spin_lock_bh(&subscriber->lock); |
| 155 | 151 | ||
| 156 | /* Validate if the connection related to the subscriber is | ||
| 157 | * closed (in case subscriber is terminating) | ||
| 158 | */ | ||
| 159 | if (subscriber->conid == 0) { | ||
| 160 | spin_unlock_bh(&subscriber->lock); | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 164 | /* Validate timeout (in case subscription is being cancelled) */ | 152 | /* Validate timeout (in case subscription is being cancelled) */ |
| 165 | if (sub->timeout == TIPC_WAIT_FOREVER) { | 153 | if (sub->timeout == TIPC_WAIT_FOREVER) { |
| 166 | spin_unlock_bh(&subscriber->lock); | 154 | spin_unlock_bh(&subscriber->lock); |
| @@ -215,9 +203,6 @@ static void subscr_release(struct tipc_subscriber *subscriber) | |||
| 215 | 203 | ||
| 216 | spin_lock_bh(&subscriber->lock); | 204 | spin_lock_bh(&subscriber->lock); |
| 217 | 205 | ||
| 218 | /* Invalidate subscriber reference */ | ||
| 219 | subscriber->conid = 0; | ||
| 220 | |||
| 221 | /* Destroy any existing subscriptions for subscriber */ | 206 | /* Destroy any existing subscriptions for subscriber */ |
| 222 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, | 207 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, |
| 223 | subscription_list) { | 208 | subscription_list) { |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 29fc8bee9702..ce6ec6c2f4de 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -163,9 +163,8 @@ static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) | |||
| 163 | 163 | ||
| 164 | static inline unsigned int unix_hash_fold(__wsum n) | 164 | static inline unsigned int unix_hash_fold(__wsum n) |
| 165 | { | 165 | { |
| 166 | unsigned int hash = (__force unsigned int)n; | 166 | unsigned int hash = (__force unsigned int)csum_fold(n); |
| 167 | 167 | ||
| 168 | hash ^= hash>>16; | ||
| 169 | hash ^= hash>>8; | 168 | hash ^= hash>>8; |
| 170 | return hash&(UNIX_HASH_SIZE-1); | 169 | return hash&(UNIX_HASH_SIZE-1); |
| 171 | } | 170 | } |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 010892b81a06..a3bf18d11609 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -788,8 +788,6 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, | |||
| 788 | default: | 788 | default: |
| 789 | break; | 789 | break; |
| 790 | } | 790 | } |
| 791 | |||
| 792 | wdev->beacon_interval = 0; | ||
| 793 | } | 791 | } |
| 794 | 792 | ||
| 795 | static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | 793 | static int cfg80211_netdev_notifier_call(struct notifier_block *nb, |
