diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/8021q/vlan.c | 4 | ||||
| -rw-r--r-- | net/8021q/vlan_dev.c | 6 | ||||
| -rw-r--r-- | net/bridge/br_device.c | 6 | ||||
| -rw-r--r-- | net/bridge/br_input.c | 11 | ||||
| -rw-r--r-- | net/bridge/br_vlan.c | 44 | ||||
| -rw-r--r-- | net/core/dev.c | 13 | ||||
| -rw-r--r-- | net/core/skbuff.c | 30 | ||||
| -rw-r--r-- | net/ipv4/gre_demux.c | 8 | ||||
| -rw-r--r-- | net/ipv4/ip_tunnel.c | 3 | ||||
| -rw-r--r-- | net/ipv4/ip_tunnel_core.c | 1 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 2 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 193 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_queue_core.c | 9 | ||||
| -rw-r--r-- | net/openvswitch/datapath.c | 6 | ||||
| -rw-r--r-- | net/openvswitch/flow.c | 26 | ||||
| -rw-r--r-- | net/unix/af_unix.c | 17 |
16 files changed, 257 insertions, 122 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index ec9909935fb6..175273f38cb1 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -307,9 +307,11 @@ static void vlan_sync_address(struct net_device *dev, | |||
| 307 | static void vlan_transfer_features(struct net_device *dev, | 307 | static void vlan_transfer_features(struct net_device *dev, |
| 308 | struct net_device *vlandev) | 308 | struct net_device *vlandev) |
| 309 | { | 309 | { |
| 310 | struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); | ||
| 311 | |||
| 310 | vlandev->gso_max_size = dev->gso_max_size; | 312 | vlandev->gso_max_size = dev->gso_max_size; |
| 311 | 313 | ||
| 312 | if (dev->features & NETIF_F_HW_VLAN_CTAG_TX) | 314 | if (vlan_hw_offload_capable(dev->features, vlan->vlan_proto)) |
| 313 | vlandev->hard_header_len = dev->hard_header_len; | 315 | vlandev->hard_header_len = dev->hard_header_len; |
| 314 | else | 316 | else |
| 315 | vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; | 317 | vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 4b65aa492fb6..27bfe2f8e2de 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -578,6 +578,9 @@ static int vlan_dev_init(struct net_device *dev) | |||
| 578 | 578 | ||
| 579 | dev->features |= real_dev->vlan_features | NETIF_F_LLTX; | 579 | dev->features |= real_dev->vlan_features | NETIF_F_LLTX; |
| 580 | dev->gso_max_size = real_dev->gso_max_size; | 580 | dev->gso_max_size = real_dev->gso_max_size; |
| 581 | if (dev->features & NETIF_F_VLAN_FEATURES) | ||
| 582 | netdev_warn(real_dev, "VLAN features are set incorrectly. Q-in-Q configurations may not work correctly.\n"); | ||
| 583 | |||
| 581 | 584 | ||
| 582 | /* ipv6 shared card related stuff */ | 585 | /* ipv6 shared card related stuff */ |
| 583 | dev->dev_id = real_dev->dev_id; | 586 | dev->dev_id = real_dev->dev_id; |
| @@ -592,7 +595,8 @@ static int vlan_dev_init(struct net_device *dev) | |||
| 592 | #endif | 595 | #endif |
| 593 | 596 | ||
| 594 | dev->needed_headroom = real_dev->needed_headroom; | 597 | dev->needed_headroom = real_dev->needed_headroom; |
| 595 | if (real_dev->features & NETIF_F_HW_VLAN_CTAG_TX) { | 598 | if (vlan_hw_offload_capable(real_dev->features, |
| 599 | vlan_dev_priv(dev)->vlan_proto)) { | ||
| 596 | dev->header_ops = &vlan_passthru_header_ops; | 600 | dev->header_ops = &vlan_passthru_header_ops; |
| 597 | dev->hard_header_len = real_dev->hard_header_len; | 601 | dev->hard_header_len = real_dev->hard_header_len; |
| 598 | } else { | 602 | } else { |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 63f0455c0bc3..8fe8b71b487a 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
| @@ -49,14 +49,14 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 49 | brstats->tx_bytes += skb->len; | 49 | brstats->tx_bytes += skb->len; |
| 50 | u64_stats_update_end(&brstats->syncp); | 50 | u64_stats_update_end(&brstats->syncp); |
| 51 | 51 | ||
| 52 | if (!br_allowed_ingress(br, br_get_vlan_info(br), skb, &vid)) | ||
| 53 | goto out; | ||
| 54 | |||
| 55 | BR_INPUT_SKB_CB(skb)->brdev = dev; | 52 | BR_INPUT_SKB_CB(skb)->brdev = dev; |
| 56 | 53 | ||
| 57 | skb_reset_mac_header(skb); | 54 | skb_reset_mac_header(skb); |
| 58 | skb_pull(skb, ETH_HLEN); | 55 | skb_pull(skb, ETH_HLEN); |
| 59 | 56 | ||
| 57 | if (!br_allowed_ingress(br, br_get_vlan_info(br), skb, &vid)) | ||
| 58 | goto out; | ||
| 59 | |||
| 60 | if (is_broadcast_ether_addr(dest)) | 60 | if (is_broadcast_ether_addr(dest)) |
| 61 | br_flood_deliver(br, skb, false); | 61 | br_flood_deliver(br, skb, false); |
| 62 | else if (is_multicast_ether_addr(dest)) { | 62 | else if (is_multicast_ether_addr(dest)) { |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 28d544627422..d0cca3c65f01 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -29,6 +29,7 @@ static int br_pass_frame_up(struct sk_buff *skb) | |||
| 29 | struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; | 29 | struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; |
| 30 | struct net_bridge *br = netdev_priv(brdev); | 30 | struct net_bridge *br = netdev_priv(brdev); |
| 31 | struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); | 31 | struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); |
| 32 | struct net_port_vlans *pv; | ||
| 32 | 33 | ||
| 33 | u64_stats_update_begin(&brstats->syncp); | 34 | u64_stats_update_begin(&brstats->syncp); |
| 34 | brstats->rx_packets++; | 35 | brstats->rx_packets++; |
| @@ -39,18 +40,18 @@ static int br_pass_frame_up(struct sk_buff *skb) | |||
| 39 | * packet is allowed except in promisc modue when someone | 40 | * packet is allowed except in promisc modue when someone |
| 40 | * may be running packet capture. | 41 | * may be running packet capture. |
| 41 | */ | 42 | */ |
| 43 | pv = br_get_vlan_info(br); | ||
| 42 | if (!(brdev->flags & IFF_PROMISC) && | 44 | if (!(brdev->flags & IFF_PROMISC) && |
| 43 | !br_allowed_egress(br, br_get_vlan_info(br), skb)) { | 45 | !br_allowed_egress(br, pv, skb)) { |
| 44 | kfree_skb(skb); | 46 | kfree_skb(skb); |
| 45 | return NET_RX_DROP; | 47 | return NET_RX_DROP; |
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | skb = br_handle_vlan(br, br_get_vlan_info(br), skb); | ||
| 49 | if (!skb) | ||
| 50 | return NET_RX_DROP; | ||
| 51 | |||
| 52 | indev = skb->dev; | 50 | indev = skb->dev; |
| 53 | skb->dev = brdev; | 51 | skb->dev = brdev; |
| 52 | skb = br_handle_vlan(br, pv, skb); | ||
| 53 | if (!skb) | ||
| 54 | return NET_RX_DROP; | ||
| 54 | 55 | ||
| 55 | return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, | 56 | return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, |
| 56 | netif_receive_skb); | 57 | netif_receive_skb); |
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 8249ca764c79..f23c74b3a953 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
| @@ -119,22 +119,6 @@ static void __vlan_flush(struct net_port_vlans *v) | |||
| 119 | kfree_rcu(v, rcu); | 119 | kfree_rcu(v, rcu); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | /* Strip the tag from the packet. Will return skb with tci set 0. */ | ||
| 123 | static struct sk_buff *br_vlan_untag(struct sk_buff *skb) | ||
| 124 | { | ||
| 125 | if (skb->protocol != htons(ETH_P_8021Q)) { | ||
| 126 | skb->vlan_tci = 0; | ||
| 127 | return skb; | ||
| 128 | } | ||
| 129 | |||
| 130 | skb->vlan_tci = 0; | ||
| 131 | skb = vlan_untag(skb); | ||
| 132 | if (skb) | ||
| 133 | skb->vlan_tci = 0; | ||
| 134 | |||
| 135 | return skb; | ||
| 136 | } | ||
| 137 | |||
| 138 | struct sk_buff *br_handle_vlan(struct net_bridge *br, | 122 | struct sk_buff *br_handle_vlan(struct net_bridge *br, |
| 139 | const struct net_port_vlans *pv, | 123 | const struct net_port_vlans *pv, |
| 140 | struct sk_buff *skb) | 124 | struct sk_buff *skb) |
| @@ -144,13 +128,27 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, | |||
| 144 | if (!br->vlan_enabled) | 128 | if (!br->vlan_enabled) |
| 145 | goto out; | 129 | goto out; |
| 146 | 130 | ||
| 131 | /* Vlan filter table must be configured at this point. The | ||
| 132 | * only exception is the bridge is set in promisc mode and the | ||
| 133 | * packet is destined for the bridge device. In this case | ||
| 134 | * pass the packet as is. | ||
| 135 | */ | ||
| 136 | if (!pv) { | ||
| 137 | if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) { | ||
| 138 | goto out; | ||
| 139 | } else { | ||
| 140 | kfree_skb(skb); | ||
| 141 | return NULL; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 147 | /* At this point, we know that the frame was filtered and contains | 145 | /* At this point, we know that the frame was filtered and contains |
| 148 | * a valid vlan id. If the vlan id is set in the untagged bitmap, | 146 | * a valid vlan id. If the vlan id is set in the untagged bitmap, |
| 149 | * send untagged; otherwise, send tagged. | 147 | * send untagged; otherwise, send tagged. |
| 150 | */ | 148 | */ |
| 151 | br_vlan_get_tag(skb, &vid); | 149 | br_vlan_get_tag(skb, &vid); |
| 152 | if (test_bit(vid, pv->untagged_bitmap)) | 150 | if (test_bit(vid, pv->untagged_bitmap)) |
| 153 | skb = br_vlan_untag(skb); | 151 | skb->vlan_tci = 0; |
| 154 | 152 | ||
| 155 | out: | 153 | out: |
| 156 | return skb; | 154 | return skb; |
| @@ -174,6 +172,18 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
| 174 | if (!v) | 172 | if (!v) |
| 175 | return false; | 173 | return false; |
| 176 | 174 | ||
| 175 | /* If vlan tx offload is disabled on bridge device and frame was | ||
| 176 | * sent from vlan device on the bridge device, it does not have | ||
| 177 | * HW accelerated vlan tag. | ||
| 178 | */ | ||
| 179 | if (unlikely(!vlan_tx_tag_present(skb) && | ||
| 180 | (skb->protocol == htons(ETH_P_8021Q) || | ||
| 181 | skb->protocol == htons(ETH_P_8021AD)))) { | ||
| 182 | skb = vlan_untag(skb); | ||
| 183 | if (unlikely(!skb)) | ||
| 184 | return false; | ||
| 185 | } | ||
| 186 | |||
| 177 | err = br_vlan_get_tag(skb, vid); | 187 | err = br_vlan_get_tag(skb, vid); |
| 178 | if (!*vid) { | 188 | if (!*vid) { |
| 179 | u16 pvid = br_get_pvid(v); | 189 | u16 pvid = br_get_pvid(v); |
diff --git a/net/core/dev.c b/net/core/dev.c index b1b0c8d4d7df..45fa2f11f84d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2286,7 +2286,7 @@ out: | |||
| 2286 | } | 2286 | } |
| 2287 | EXPORT_SYMBOL(skb_checksum_help); | 2287 | EXPORT_SYMBOL(skb_checksum_help); |
| 2288 | 2288 | ||
| 2289 | __be16 skb_network_protocol(struct sk_buff *skb) | 2289 | __be16 skb_network_protocol(struct sk_buff *skb, int *depth) |
| 2290 | { | 2290 | { |
| 2291 | __be16 type = skb->protocol; | 2291 | __be16 type = skb->protocol; |
| 2292 | int vlan_depth = ETH_HLEN; | 2292 | int vlan_depth = ETH_HLEN; |
| @@ -2313,6 +2313,8 @@ __be16 skb_network_protocol(struct sk_buff *skb) | |||
| 2313 | vlan_depth += VLAN_HLEN; | 2313 | vlan_depth += VLAN_HLEN; |
| 2314 | } | 2314 | } |
| 2315 | 2315 | ||
| 2316 | *depth = vlan_depth; | ||
| 2317 | |||
| 2316 | return type; | 2318 | return type; |
| 2317 | } | 2319 | } |
| 2318 | 2320 | ||
| @@ -2326,12 +2328,13 @@ struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb, | |||
| 2326 | { | 2328 | { |
| 2327 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); | 2329 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); |
| 2328 | struct packet_offload *ptype; | 2330 | struct packet_offload *ptype; |
| 2329 | __be16 type = skb_network_protocol(skb); | 2331 | int vlan_depth = skb->mac_len; |
| 2332 | __be16 type = skb_network_protocol(skb, &vlan_depth); | ||
| 2330 | 2333 | ||
| 2331 | if (unlikely(!type)) | 2334 | if (unlikely(!type)) |
| 2332 | return ERR_PTR(-EINVAL); | 2335 | return ERR_PTR(-EINVAL); |
| 2333 | 2336 | ||
| 2334 | __skb_pull(skb, skb->mac_len); | 2337 | __skb_pull(skb, vlan_depth); |
| 2335 | 2338 | ||
| 2336 | rcu_read_lock(); | 2339 | rcu_read_lock(); |
| 2337 | list_for_each_entry_rcu(ptype, &offload_base, list) { | 2340 | list_for_each_entry_rcu(ptype, &offload_base, list) { |
| @@ -2498,8 +2501,10 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, | |||
| 2498 | const struct net_device *dev, | 2501 | const struct net_device *dev, |
| 2499 | netdev_features_t features) | 2502 | netdev_features_t features) |
| 2500 | { | 2503 | { |
| 2504 | int tmp; | ||
| 2505 | |||
| 2501 | if (skb->ip_summed != CHECKSUM_NONE && | 2506 | if (skb->ip_summed != CHECKSUM_NONE && |
| 2502 | !can_checksum_protocol(features, skb_network_protocol(skb))) { | 2507 | !can_checksum_protocol(features, skb_network_protocol(skb, &tmp))) { |
| 2503 | features &= ~NETIF_F_ALL_CSUM; | 2508 | features &= ~NETIF_F_ALL_CSUM; |
| 2504 | } else if (illegal_highdma(dev, skb)) { | 2509 | } else if (illegal_highdma(dev, skb)) { |
| 2505 | features &= ~NETIF_F_SG; | 2510 | features &= ~NETIF_F_SG; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 869c7afe3b07..90b96a11b974 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -2127,25 +2127,31 @@ EXPORT_SYMBOL_GPL(skb_zerocopy_headlen); | |||
| 2127 | * | 2127 | * |
| 2128 | * The `hlen` as calculated by skb_zerocopy_headlen() specifies the | 2128 | * The `hlen` as calculated by skb_zerocopy_headlen() specifies the |
| 2129 | * headroom in the `to` buffer. | 2129 | * headroom in the `to` buffer. |
| 2130 | * | ||
| 2131 | * Return value: | ||
| 2132 | * 0: everything is OK | ||
| 2133 | * -ENOMEM: couldn't orphan frags of @from due to lack of memory | ||
| 2134 | * -EFAULT: skb_copy_bits() found some problem with skb geometry | ||
| 2130 | */ | 2135 | */ |
| 2131 | void | 2136 | int |
| 2132 | skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen) | 2137 | skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen) |
| 2133 | { | 2138 | { |
| 2134 | int i, j = 0; | 2139 | int i, j = 0; |
| 2135 | int plen = 0; /* length of skb->head fragment */ | 2140 | int plen = 0; /* length of skb->head fragment */ |
| 2141 | int ret; | ||
| 2136 | struct page *page; | 2142 | struct page *page; |
| 2137 | unsigned int offset; | 2143 | unsigned int offset; |
| 2138 | 2144 | ||
| 2139 | BUG_ON(!from->head_frag && !hlen); | 2145 | BUG_ON(!from->head_frag && !hlen); |
| 2140 | 2146 | ||
| 2141 | /* dont bother with small payloads */ | 2147 | /* dont bother with small payloads */ |
| 2142 | if (len <= skb_tailroom(to)) { | 2148 | if (len <= skb_tailroom(to)) |
| 2143 | skb_copy_bits(from, 0, skb_put(to, len), len); | 2149 | return skb_copy_bits(from, 0, skb_put(to, len), len); |
| 2144 | return; | ||
| 2145 | } | ||
| 2146 | 2150 | ||
| 2147 | if (hlen) { | 2151 | if (hlen) { |
| 2148 | skb_copy_bits(from, 0, skb_put(to, hlen), hlen); | 2152 | ret = skb_copy_bits(from, 0, skb_put(to, hlen), hlen); |
| 2153 | if (unlikely(ret)) | ||
| 2154 | return ret; | ||
| 2149 | len -= hlen; | 2155 | len -= hlen; |
| 2150 | } else { | 2156 | } else { |
| 2151 | plen = min_t(int, skb_headlen(from), len); | 2157 | plen = min_t(int, skb_headlen(from), len); |
| @@ -2163,6 +2169,11 @@ skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen) | |||
| 2163 | to->len += len + plen; | 2169 | to->len += len + plen; |
| 2164 | to->data_len += len + plen; | 2170 | to->data_len += len + plen; |
| 2165 | 2171 | ||
| 2172 | if (unlikely(skb_orphan_frags(from, GFP_ATOMIC))) { | ||
| 2173 | skb_tx_error(from); | ||
| 2174 | return -ENOMEM; | ||
| 2175 | } | ||
| 2176 | |||
| 2166 | for (i = 0; i < skb_shinfo(from)->nr_frags; i++) { | 2177 | for (i = 0; i < skb_shinfo(from)->nr_frags; i++) { |
| 2167 | if (!len) | 2178 | if (!len) |
| 2168 | break; | 2179 | break; |
| @@ -2173,6 +2184,8 @@ skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen) | |||
| 2173 | j++; | 2184 | j++; |
| 2174 | } | 2185 | } |
| 2175 | skb_shinfo(to)->nr_frags = j; | 2186 | skb_shinfo(to)->nr_frags = j; |
| 2187 | |||
| 2188 | return 0; | ||
| 2176 | } | 2189 | } |
| 2177 | EXPORT_SYMBOL_GPL(skb_zerocopy); | 2190 | EXPORT_SYMBOL_GPL(skb_zerocopy); |
| 2178 | 2191 | ||
| @@ -2866,8 +2879,9 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, | |||
| 2866 | int err = -ENOMEM; | 2879 | int err = -ENOMEM; |
| 2867 | int i = 0; | 2880 | int i = 0; |
| 2868 | int pos; | 2881 | int pos; |
| 2882 | int dummy; | ||
| 2869 | 2883 | ||
| 2870 | proto = skb_network_protocol(head_skb); | 2884 | proto = skb_network_protocol(head_skb, &dummy); |
| 2871 | if (unlikely(!proto)) | 2885 | if (unlikely(!proto)) |
| 2872 | return ERR_PTR(-EINVAL); | 2886 | return ERR_PTR(-EINVAL); |
| 2873 | 2887 | ||
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index 1863422fb7d5..250be7421ab3 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c | |||
| @@ -182,6 +182,14 @@ static int gre_cisco_rcv(struct sk_buff *skb) | |||
| 182 | int i; | 182 | int i; |
| 183 | bool csum_err = false; | 183 | bool csum_err = false; |
| 184 | 184 | ||
| 185 | #ifdef CONFIG_NET_IPGRE_BROADCAST | ||
| 186 | if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { | ||
| 187 | /* Looped back packet, drop it! */ | ||
| 188 | if (rt_is_output_route(skb_rtable(skb))) | ||
| 189 | goto drop; | ||
| 190 | } | ||
| 191 | #endif | ||
| 192 | |||
| 185 | if (parse_gre_header(skb, &tpi, &csum_err) < 0) | 193 | if (parse_gre_header(skb, &tpi, &csum_err) < 0) |
| 186 | goto drop; | 194 | goto drop; |
| 187 | 195 | ||
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 78a89e61925d..a82a22d8f77f 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
| @@ -416,9 +416,6 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, | |||
| 416 | 416 | ||
| 417 | #ifdef CONFIG_NET_IPGRE_BROADCAST | 417 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
| 418 | if (ipv4_is_multicast(iph->daddr)) { | 418 | if (ipv4_is_multicast(iph->daddr)) { |
| 419 | /* Looped back packet, drop it! */ | ||
| 420 | if (rt_is_output_route(skb_rtable(skb))) | ||
| 421 | goto drop; | ||
| 422 | tunnel->dev->stats.multicast++; | 419 | tunnel->dev->stats.multicast++; |
| 423 | skb->pkt_type = PACKET_BROADCAST; | 420 | skb->pkt_type = PACKET_BROADCAST; |
| 424 | } | 421 | } |
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 6f847dd56dbc..8d69626f2206 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
| @@ -108,6 +108,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto) | |||
| 108 | nf_reset(skb); | 108 | nf_reset(skb); |
| 109 | secpath_reset(skb); | 109 | secpath_reset(skb); |
| 110 | skb_clear_hash_if_not_l4(skb); | 110 | skb_clear_hash_if_not_l4(skb); |
| 111 | skb_dst_drop(skb); | ||
| 111 | skb->vlan_tci = 0; | 112 | skb->vlan_tci = 0; |
| 112 | skb_set_queue_mapping(skb, 0); | 113 | skb_set_queue_mapping(skb, 0); |
| 113 | skb->pkt_type = PACKET_HOST; | 114 | skb->pkt_type = PACKET_HOST; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 3cf976510497..1e4eac779f51 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -2628,7 +2628,7 @@ static void get_timewait4_sock(const struct inet_timewait_sock *tw, | |||
| 2628 | { | 2628 | { |
| 2629 | __be32 dest, src; | 2629 | __be32 dest, src; |
| 2630 | __u16 destp, srcp; | 2630 | __u16 destp, srcp; |
| 2631 | long delta = tw->tw_ttd - jiffies; | 2631 | s32 delta = tw->tw_ttd - inet_tw_time_stamp(); |
| 2632 | 2632 | ||
| 2633 | dest = tw->tw_daddr; | 2633 | dest = tw->tw_daddr; |
| 2634 | src = tw->tw_rcv_saddr; | 2634 | src = tw->tw_rcv_saddr; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 344e972426df..6c7fa0853fc7 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -133,10 +133,12 @@ static int ipv6_count_addresses(struct inet6_dev *idev); | |||
| 133 | static struct hlist_head inet6_addr_lst[IN6_ADDR_HSIZE]; | 133 | static struct hlist_head inet6_addr_lst[IN6_ADDR_HSIZE]; |
| 134 | static DEFINE_SPINLOCK(addrconf_hash_lock); | 134 | static DEFINE_SPINLOCK(addrconf_hash_lock); |
| 135 | 135 | ||
| 136 | static void addrconf_verify(unsigned long); | 136 | static void addrconf_verify(void); |
| 137 | static void addrconf_verify_rtnl(void); | ||
| 138 | static void addrconf_verify_work(struct work_struct *); | ||
| 137 | 139 | ||
| 138 | static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0); | 140 | static struct workqueue_struct *addrconf_wq; |
| 139 | static DEFINE_SPINLOCK(addrconf_verify_lock); | 141 | static DECLARE_DELAYED_WORK(addr_chk_work, addrconf_verify_work); |
| 140 | 142 | ||
| 141 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp); | 143 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp); |
| 142 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp); | 144 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp); |
| @@ -151,7 +153,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, | |||
| 151 | u32 flags, u32 noflags); | 153 | u32 flags, u32 noflags); |
| 152 | 154 | ||
| 153 | static void addrconf_dad_start(struct inet6_ifaddr *ifp); | 155 | static void addrconf_dad_start(struct inet6_ifaddr *ifp); |
| 154 | static void addrconf_dad_timer(unsigned long data); | 156 | static void addrconf_dad_work(struct work_struct *w); |
| 155 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp); | 157 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp); |
| 156 | static void addrconf_dad_run(struct inet6_dev *idev); | 158 | static void addrconf_dad_run(struct inet6_dev *idev); |
| 157 | static void addrconf_rs_timer(unsigned long data); | 159 | static void addrconf_rs_timer(unsigned long data); |
| @@ -247,9 +249,9 @@ static void addrconf_del_rs_timer(struct inet6_dev *idev) | |||
| 247 | __in6_dev_put(idev); | 249 | __in6_dev_put(idev); |
| 248 | } | 250 | } |
| 249 | 251 | ||
| 250 | static void addrconf_del_dad_timer(struct inet6_ifaddr *ifp) | 252 | static void addrconf_del_dad_work(struct inet6_ifaddr *ifp) |
| 251 | { | 253 | { |
| 252 | if (del_timer(&ifp->dad_timer)) | 254 | if (cancel_delayed_work(&ifp->dad_work)) |
| 253 | __in6_ifa_put(ifp); | 255 | __in6_ifa_put(ifp); |
| 254 | } | 256 | } |
| 255 | 257 | ||
| @@ -261,12 +263,12 @@ static void addrconf_mod_rs_timer(struct inet6_dev *idev, | |||
| 261 | mod_timer(&idev->rs_timer, jiffies + when); | 263 | mod_timer(&idev->rs_timer, jiffies + when); |
| 262 | } | 264 | } |
| 263 | 265 | ||
| 264 | static void addrconf_mod_dad_timer(struct inet6_ifaddr *ifp, | 266 | static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp, |
| 265 | unsigned long when) | 267 | unsigned long delay) |
| 266 | { | 268 | { |
| 267 | if (!timer_pending(&ifp->dad_timer)) | 269 | if (!delayed_work_pending(&ifp->dad_work)) |
| 268 | in6_ifa_hold(ifp); | 270 | in6_ifa_hold(ifp); |
| 269 | mod_timer(&ifp->dad_timer, jiffies + when); | 271 | mod_delayed_work(addrconf_wq, &ifp->dad_work, delay); |
| 270 | } | 272 | } |
| 271 | 273 | ||
| 272 | static int snmp6_alloc_dev(struct inet6_dev *idev) | 274 | static int snmp6_alloc_dev(struct inet6_dev *idev) |
| @@ -751,8 +753,9 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) | |||
| 751 | 753 | ||
| 752 | in6_dev_put(ifp->idev); | 754 | in6_dev_put(ifp->idev); |
| 753 | 755 | ||
| 754 | if (del_timer(&ifp->dad_timer)) | 756 | if (cancel_delayed_work(&ifp->dad_work)) |
| 755 | pr_notice("Timer is still running, when freeing ifa=%p\n", ifp); | 757 | pr_notice("delayed DAD work was pending while freeing ifa=%p\n", |
| 758 | ifp); | ||
| 756 | 759 | ||
| 757 | if (ifp->state != INET6_IFADDR_STATE_DEAD) { | 760 | if (ifp->state != INET6_IFADDR_STATE_DEAD) { |
| 758 | pr_warn("Freeing alive inet6 address %p\n", ifp); | 761 | pr_warn("Freeing alive inet6 address %p\n", ifp); |
| @@ -849,8 +852,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, | |||
| 849 | 852 | ||
| 850 | spin_lock_init(&ifa->lock); | 853 | spin_lock_init(&ifa->lock); |
| 851 | spin_lock_init(&ifa->state_lock); | 854 | spin_lock_init(&ifa->state_lock); |
| 852 | setup_timer(&ifa->dad_timer, addrconf_dad_timer, | 855 | INIT_DELAYED_WORK(&ifa->dad_work, addrconf_dad_work); |
| 853 | (unsigned long)ifa); | ||
| 854 | INIT_HLIST_NODE(&ifa->addr_lst); | 856 | INIT_HLIST_NODE(&ifa->addr_lst); |
| 855 | ifa->scope = scope; | 857 | ifa->scope = scope; |
| 856 | ifa->prefix_len = pfxlen; | 858 | ifa->prefix_len = pfxlen; |
| @@ -990,6 +992,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
| 990 | enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_NOP; | 992 | enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_NOP; |
| 991 | unsigned long expires; | 993 | unsigned long expires; |
| 992 | 994 | ||
| 995 | ASSERT_RTNL(); | ||
| 996 | |||
| 993 | spin_lock_bh(&ifp->state_lock); | 997 | spin_lock_bh(&ifp->state_lock); |
| 994 | state = ifp->state; | 998 | state = ifp->state; |
| 995 | ifp->state = INET6_IFADDR_STATE_DEAD; | 999 | ifp->state = INET6_IFADDR_STATE_DEAD; |
| @@ -1021,7 +1025,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
| 1021 | 1025 | ||
| 1022 | write_unlock_bh(&ifp->idev->lock); | 1026 | write_unlock_bh(&ifp->idev->lock); |
| 1023 | 1027 | ||
| 1024 | addrconf_del_dad_timer(ifp); | 1028 | addrconf_del_dad_work(ifp); |
| 1025 | 1029 | ||
| 1026 | ipv6_ifa_notify(RTM_DELADDR, ifp); | 1030 | ipv6_ifa_notify(RTM_DELADDR, ifp); |
| 1027 | 1031 | ||
| @@ -1604,7 +1608,7 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) | |||
| 1604 | { | 1608 | { |
| 1605 | if (ifp->flags&IFA_F_PERMANENT) { | 1609 | if (ifp->flags&IFA_F_PERMANENT) { |
| 1606 | spin_lock_bh(&ifp->lock); | 1610 | spin_lock_bh(&ifp->lock); |
| 1607 | addrconf_del_dad_timer(ifp); | 1611 | addrconf_del_dad_work(ifp); |
| 1608 | ifp->flags |= IFA_F_TENTATIVE; | 1612 | ifp->flags |= IFA_F_TENTATIVE; |
| 1609 | if (dad_failed) | 1613 | if (dad_failed) |
| 1610 | ifp->flags |= IFA_F_DADFAILED; | 1614 | ifp->flags |= IFA_F_DADFAILED; |
| @@ -1625,20 +1629,21 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) | |||
| 1625 | spin_unlock_bh(&ifp->lock); | 1629 | spin_unlock_bh(&ifp->lock); |
| 1626 | } | 1630 | } |
| 1627 | ipv6_del_addr(ifp); | 1631 | ipv6_del_addr(ifp); |
| 1628 | } else | 1632 | } else { |
| 1629 | ipv6_del_addr(ifp); | 1633 | ipv6_del_addr(ifp); |
| 1634 | } | ||
| 1630 | } | 1635 | } |
| 1631 | 1636 | ||
| 1632 | static int addrconf_dad_end(struct inet6_ifaddr *ifp) | 1637 | static int addrconf_dad_end(struct inet6_ifaddr *ifp) |
| 1633 | { | 1638 | { |
| 1634 | int err = -ENOENT; | 1639 | int err = -ENOENT; |
| 1635 | 1640 | ||
| 1636 | spin_lock(&ifp->state_lock); | 1641 | spin_lock_bh(&ifp->state_lock); |
| 1637 | if (ifp->state == INET6_IFADDR_STATE_DAD) { | 1642 | if (ifp->state == INET6_IFADDR_STATE_DAD) { |
| 1638 | ifp->state = INET6_IFADDR_STATE_POSTDAD; | 1643 | ifp->state = INET6_IFADDR_STATE_POSTDAD; |
| 1639 | err = 0; | 1644 | err = 0; |
| 1640 | } | 1645 | } |
| 1641 | spin_unlock(&ifp->state_lock); | 1646 | spin_unlock_bh(&ifp->state_lock); |
| 1642 | 1647 | ||
| 1643 | return err; | 1648 | return err; |
| 1644 | } | 1649 | } |
| @@ -1671,7 +1676,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |||
| 1671 | } | 1676 | } |
| 1672 | } | 1677 | } |
| 1673 | 1678 | ||
| 1674 | addrconf_dad_stop(ifp, 1); | 1679 | spin_lock_bh(&ifp->state_lock); |
| 1680 | /* transition from _POSTDAD to _ERRDAD */ | ||
| 1681 | ifp->state = INET6_IFADDR_STATE_ERRDAD; | ||
| 1682 | spin_unlock_bh(&ifp->state_lock); | ||
| 1683 | |||
| 1684 | addrconf_mod_dad_work(ifp, 0); | ||
| 1675 | } | 1685 | } |
| 1676 | 1686 | ||
| 1677 | /* Join to solicited addr multicast group. */ | 1687 | /* Join to solicited addr multicast group. */ |
| @@ -1680,6 +1690,8 @@ void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr) | |||
| 1680 | { | 1690 | { |
| 1681 | struct in6_addr maddr; | 1691 | struct in6_addr maddr; |
| 1682 | 1692 | ||
| 1693 | ASSERT_RTNL(); | ||
| 1694 | |||
| 1683 | if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) | 1695 | if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) |
| 1684 | return; | 1696 | return; |
| 1685 | 1697 | ||
| @@ -1691,6 +1703,8 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | |||
| 1691 | { | 1703 | { |
| 1692 | struct in6_addr maddr; | 1704 | struct in6_addr maddr; |
| 1693 | 1705 | ||
| 1706 | ASSERT_RTNL(); | ||
| 1707 | |||
| 1694 | if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP)) | 1708 | if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP)) |
| 1695 | return; | 1709 | return; |
| 1696 | 1710 | ||
| @@ -1701,6 +1715,9 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | |||
| 1701 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | 1715 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) |
| 1702 | { | 1716 | { |
| 1703 | struct in6_addr addr; | 1717 | struct in6_addr addr; |
| 1718 | |||
| 1719 | ASSERT_RTNL(); | ||
| 1720 | |||
| 1704 | if (ifp->prefix_len >= 127) /* RFC 6164 */ | 1721 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
| 1705 | return; | 1722 | return; |
| 1706 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1723 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
| @@ -1712,6 +1729,9 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | |||
| 1712 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) | 1729 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) |
| 1713 | { | 1730 | { |
| 1714 | struct in6_addr addr; | 1731 | struct in6_addr addr; |
| 1732 | |||
| 1733 | ASSERT_RTNL(); | ||
| 1734 | |||
| 1715 | if (ifp->prefix_len >= 127) /* RFC 6164 */ | 1735 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
| 1716 | return; | 1736 | return; |
| 1717 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1737 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
| @@ -2271,11 +2291,13 @@ ok: | |||
| 2271 | return; | 2291 | return; |
| 2272 | } | 2292 | } |
| 2273 | 2293 | ||
| 2274 | ifp->flags |= IFA_F_MANAGETEMPADDR; | ||
| 2275 | update_lft = 0; | 2294 | update_lft = 0; |
| 2276 | create = 1; | 2295 | create = 1; |
| 2296 | spin_lock_bh(&ifp->lock); | ||
| 2297 | ifp->flags |= IFA_F_MANAGETEMPADDR; | ||
| 2277 | ifp->cstamp = jiffies; | 2298 | ifp->cstamp = jiffies; |
| 2278 | ifp->tokenized = tokenized; | 2299 | ifp->tokenized = tokenized; |
| 2300 | spin_unlock_bh(&ifp->lock); | ||
| 2279 | addrconf_dad_start(ifp); | 2301 | addrconf_dad_start(ifp); |
| 2280 | } | 2302 | } |
| 2281 | 2303 | ||
| @@ -2326,7 +2348,7 @@ ok: | |||
| 2326 | create, now); | 2348 | create, now); |
| 2327 | 2349 | ||
| 2328 | in6_ifa_put(ifp); | 2350 | in6_ifa_put(ifp); |
| 2329 | addrconf_verify(0); | 2351 | addrconf_verify(); |
| 2330 | } | 2352 | } |
| 2331 | } | 2353 | } |
| 2332 | inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo); | 2354 | inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo); |
| @@ -2475,7 +2497,7 @@ static int inet6_addr_add(struct net *net, int ifindex, | |||
| 2475 | manage_tempaddrs(idev, ifp, valid_lft, prefered_lft, | 2497 | manage_tempaddrs(idev, ifp, valid_lft, prefered_lft, |
| 2476 | true, jiffies); | 2498 | true, jiffies); |
| 2477 | in6_ifa_put(ifp); | 2499 | in6_ifa_put(ifp); |
| 2478 | addrconf_verify(0); | 2500 | addrconf_verify_rtnl(); |
| 2479 | return 0; | 2501 | return 0; |
| 2480 | } | 2502 | } |
| 2481 | 2503 | ||
| @@ -3011,7 +3033,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
| 3011 | hlist_for_each_entry_rcu(ifa, h, addr_lst) { | 3033 | hlist_for_each_entry_rcu(ifa, h, addr_lst) { |
| 3012 | if (ifa->idev == idev) { | 3034 | if (ifa->idev == idev) { |
| 3013 | hlist_del_init_rcu(&ifa->addr_lst); | 3035 | hlist_del_init_rcu(&ifa->addr_lst); |
| 3014 | addrconf_del_dad_timer(ifa); | 3036 | addrconf_del_dad_work(ifa); |
| 3015 | goto restart; | 3037 | goto restart; |
| 3016 | } | 3038 | } |
| 3017 | } | 3039 | } |
| @@ -3049,7 +3071,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
| 3049 | while (!list_empty(&idev->addr_list)) { | 3071 | while (!list_empty(&idev->addr_list)) { |
| 3050 | ifa = list_first_entry(&idev->addr_list, | 3072 | ifa = list_first_entry(&idev->addr_list, |
| 3051 | struct inet6_ifaddr, if_list); | 3073 | struct inet6_ifaddr, if_list); |
| 3052 | addrconf_del_dad_timer(ifa); | 3074 | addrconf_del_dad_work(ifa); |
| 3053 | 3075 | ||
| 3054 | list_del(&ifa->if_list); | 3076 | list_del(&ifa->if_list); |
| 3055 | 3077 | ||
| @@ -3148,10 +3170,10 @@ static void addrconf_dad_kick(struct inet6_ifaddr *ifp) | |||
| 3148 | rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1); | 3170 | rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1); |
| 3149 | 3171 | ||
| 3150 | ifp->dad_probes = idev->cnf.dad_transmits; | 3172 | ifp->dad_probes = idev->cnf.dad_transmits; |
| 3151 | addrconf_mod_dad_timer(ifp, rand_num); | 3173 | addrconf_mod_dad_work(ifp, rand_num); |
| 3152 | } | 3174 | } |
| 3153 | 3175 | ||
| 3154 | static void addrconf_dad_start(struct inet6_ifaddr *ifp) | 3176 | static void addrconf_dad_begin(struct inet6_ifaddr *ifp) |
| 3155 | { | 3177 | { |
| 3156 | struct inet6_dev *idev = ifp->idev; | 3178 | struct inet6_dev *idev = ifp->idev; |
| 3157 | struct net_device *dev = idev->dev; | 3179 | struct net_device *dev = idev->dev; |
| @@ -3203,25 +3225,68 @@ out: | |||
| 3203 | read_unlock_bh(&idev->lock); | 3225 | read_unlock_bh(&idev->lock); |
| 3204 | } | 3226 | } |
| 3205 | 3227 | ||
| 3206 | static void addrconf_dad_timer(unsigned long data) | 3228 | static void addrconf_dad_start(struct inet6_ifaddr *ifp) |
| 3207 | { | 3229 | { |
| 3208 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; | 3230 | bool begin_dad = false; |
| 3231 | |||
| 3232 | spin_lock_bh(&ifp->state_lock); | ||
| 3233 | if (ifp->state != INET6_IFADDR_STATE_DEAD) { | ||
| 3234 | ifp->state = INET6_IFADDR_STATE_PREDAD; | ||
| 3235 | begin_dad = true; | ||
| 3236 | } | ||
| 3237 | spin_unlock_bh(&ifp->state_lock); | ||
| 3238 | |||
| 3239 | if (begin_dad) | ||
| 3240 | addrconf_mod_dad_work(ifp, 0); | ||
| 3241 | } | ||
| 3242 | |||
| 3243 | static void addrconf_dad_work(struct work_struct *w) | ||
| 3244 | { | ||
| 3245 | struct inet6_ifaddr *ifp = container_of(to_delayed_work(w), | ||
| 3246 | struct inet6_ifaddr, | ||
| 3247 | dad_work); | ||
| 3209 | struct inet6_dev *idev = ifp->idev; | 3248 | struct inet6_dev *idev = ifp->idev; |
| 3210 | struct in6_addr mcaddr; | 3249 | struct in6_addr mcaddr; |
| 3211 | 3250 | ||
| 3251 | enum { | ||
| 3252 | DAD_PROCESS, | ||
| 3253 | DAD_BEGIN, | ||
| 3254 | DAD_ABORT, | ||
| 3255 | } action = DAD_PROCESS; | ||
| 3256 | |||
| 3257 | rtnl_lock(); | ||
| 3258 | |||
| 3259 | spin_lock_bh(&ifp->state_lock); | ||
| 3260 | if (ifp->state == INET6_IFADDR_STATE_PREDAD) { | ||
| 3261 | action = DAD_BEGIN; | ||
| 3262 | ifp->state = INET6_IFADDR_STATE_DAD; | ||
| 3263 | } else if (ifp->state == INET6_IFADDR_STATE_ERRDAD) { | ||
| 3264 | action = DAD_ABORT; | ||
| 3265 | ifp->state = INET6_IFADDR_STATE_POSTDAD; | ||
| 3266 | } | ||
| 3267 | spin_unlock_bh(&ifp->state_lock); | ||
| 3268 | |||
| 3269 | if (action == DAD_BEGIN) { | ||
| 3270 | addrconf_dad_begin(ifp); | ||
| 3271 | goto out; | ||
| 3272 | } else if (action == DAD_ABORT) { | ||
| 3273 | addrconf_dad_stop(ifp, 1); | ||
| 3274 | goto out; | ||
| 3275 | } | ||
| 3276 | |||
| 3212 | if (!ifp->dad_probes && addrconf_dad_end(ifp)) | 3277 | if (!ifp->dad_probes && addrconf_dad_end(ifp)) |
| 3213 | goto out; | 3278 | goto out; |
| 3214 | 3279 | ||
| 3215 | write_lock(&idev->lock); | 3280 | write_lock_bh(&idev->lock); |
| 3216 | if (idev->dead || !(idev->if_flags & IF_READY)) { | 3281 | if (idev->dead || !(idev->if_flags & IF_READY)) { |
| 3217 | write_unlock(&idev->lock); | 3282 | write_unlock_bh(&idev->lock); |
| 3218 | goto out; | 3283 | goto out; |
| 3219 | } | 3284 | } |
| 3220 | 3285 | ||
| 3221 | spin_lock(&ifp->lock); | 3286 | spin_lock(&ifp->lock); |
| 3222 | if (ifp->state == INET6_IFADDR_STATE_DEAD) { | 3287 | if (ifp->state == INET6_IFADDR_STATE_DEAD) { |
| 3223 | spin_unlock(&ifp->lock); | 3288 | spin_unlock(&ifp->lock); |
| 3224 | write_unlock(&idev->lock); | 3289 | write_unlock_bh(&idev->lock); |
| 3225 | goto out; | 3290 | goto out; |
| 3226 | } | 3291 | } |
| 3227 | 3292 | ||
| @@ -3232,7 +3297,7 @@ static void addrconf_dad_timer(unsigned long data) | |||
| 3232 | 3297 | ||
| 3233 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); | 3298 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); |
| 3234 | spin_unlock(&ifp->lock); | 3299 | spin_unlock(&ifp->lock); |
| 3235 | write_unlock(&idev->lock); | 3300 | write_unlock_bh(&idev->lock); |
| 3236 | 3301 | ||
| 3237 | addrconf_dad_completed(ifp); | 3302 | addrconf_dad_completed(ifp); |
| 3238 | 3303 | ||
| @@ -3240,16 +3305,17 @@ static void addrconf_dad_timer(unsigned long data) | |||
| 3240 | } | 3305 | } |
| 3241 | 3306 | ||
| 3242 | ifp->dad_probes--; | 3307 | ifp->dad_probes--; |
| 3243 | addrconf_mod_dad_timer(ifp, | 3308 | addrconf_mod_dad_work(ifp, |
| 3244 | NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME)); | 3309 | NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME)); |
| 3245 | spin_unlock(&ifp->lock); | 3310 | spin_unlock(&ifp->lock); |
| 3246 | write_unlock(&idev->lock); | 3311 | write_unlock_bh(&idev->lock); |
| 3247 | 3312 | ||
| 3248 | /* send a neighbour solicitation for our addr */ | 3313 | /* send a neighbour solicitation for our addr */ |
| 3249 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); | 3314 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); |
| 3250 | ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any); | 3315 | ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any); |
| 3251 | out: | 3316 | out: |
| 3252 | in6_ifa_put(ifp); | 3317 | in6_ifa_put(ifp); |
| 3318 | rtnl_unlock(); | ||
| 3253 | } | 3319 | } |
| 3254 | 3320 | ||
| 3255 | /* ifp->idev must be at least read locked */ | 3321 | /* ifp->idev must be at least read locked */ |
| @@ -3276,7 +3342,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | |||
| 3276 | struct in6_addr lladdr; | 3342 | struct in6_addr lladdr; |
| 3277 | bool send_rs, send_mld; | 3343 | bool send_rs, send_mld; |
| 3278 | 3344 | ||
| 3279 | addrconf_del_dad_timer(ifp); | 3345 | addrconf_del_dad_work(ifp); |
| 3280 | 3346 | ||
| 3281 | /* | 3347 | /* |
| 3282 | * Configure the address for reception. Now it is valid. | 3348 | * Configure the address for reception. Now it is valid. |
| @@ -3517,23 +3583,23 @@ int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr) | |||
| 3517 | * Periodic address status verification | 3583 | * Periodic address status verification |
| 3518 | */ | 3584 | */ |
| 3519 | 3585 | ||
| 3520 | static void addrconf_verify(unsigned long foo) | 3586 | static void addrconf_verify_rtnl(void) |
| 3521 | { | 3587 | { |
| 3522 | unsigned long now, next, next_sec, next_sched; | 3588 | unsigned long now, next, next_sec, next_sched; |
| 3523 | struct inet6_ifaddr *ifp; | 3589 | struct inet6_ifaddr *ifp; |
| 3524 | int i; | 3590 | int i; |
| 3525 | 3591 | ||
| 3592 | ASSERT_RTNL(); | ||
| 3593 | |||
| 3526 | rcu_read_lock_bh(); | 3594 | rcu_read_lock_bh(); |
| 3527 | spin_lock(&addrconf_verify_lock); | ||
| 3528 | now = jiffies; | 3595 | now = jiffies; |
| 3529 | next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); | 3596 | next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); |
| 3530 | 3597 | ||
| 3531 | del_timer(&addr_chk_timer); | 3598 | cancel_delayed_work(&addr_chk_work); |
| 3532 | 3599 | ||
| 3533 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { | 3600 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { |
| 3534 | restart: | 3601 | restart: |
| 3535 | hlist_for_each_entry_rcu_bh(ifp, | 3602 | hlist_for_each_entry_rcu_bh(ifp, &inet6_addr_lst[i], addr_lst) { |
| 3536 | &inet6_addr_lst[i], addr_lst) { | ||
| 3537 | unsigned long age; | 3603 | unsigned long age; |
| 3538 | 3604 | ||
| 3539 | /* When setting preferred_lft to a value not zero or | 3605 | /* When setting preferred_lft to a value not zero or |
| @@ -3628,13 +3694,22 @@ restart: | |||
| 3628 | 3694 | ||
| 3629 | ADBG(KERN_DEBUG "now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n", | 3695 | ADBG(KERN_DEBUG "now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n", |
| 3630 | now, next, next_sec, next_sched); | 3696 | now, next, next_sec, next_sched); |
| 3631 | 3697 | mod_delayed_work(addrconf_wq, &addr_chk_work, next_sched - now); | |
| 3632 | addr_chk_timer.expires = next_sched; | ||
| 3633 | add_timer(&addr_chk_timer); | ||
| 3634 | spin_unlock(&addrconf_verify_lock); | ||
| 3635 | rcu_read_unlock_bh(); | 3698 | rcu_read_unlock_bh(); |
| 3636 | } | 3699 | } |
| 3637 | 3700 | ||
| 3701 | static void addrconf_verify_work(struct work_struct *w) | ||
| 3702 | { | ||
| 3703 | rtnl_lock(); | ||
| 3704 | addrconf_verify_rtnl(); | ||
| 3705 | rtnl_unlock(); | ||
| 3706 | } | ||
| 3707 | |||
| 3708 | static void addrconf_verify(void) | ||
| 3709 | { | ||
| 3710 | mod_delayed_work(addrconf_wq, &addr_chk_work, 0); | ||
| 3711 | } | ||
| 3712 | |||
| 3638 | static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local, | 3713 | static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local, |
| 3639 | struct in6_addr **peer_pfx) | 3714 | struct in6_addr **peer_pfx) |
| 3640 | { | 3715 | { |
| @@ -3691,6 +3766,8 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, | |||
| 3691 | bool was_managetempaddr; | 3766 | bool was_managetempaddr; |
| 3692 | bool had_prefixroute; | 3767 | bool had_prefixroute; |
| 3693 | 3768 | ||
| 3769 | ASSERT_RTNL(); | ||
| 3770 | |||
| 3694 | if (!valid_lft || (prefered_lft > valid_lft)) | 3771 | if (!valid_lft || (prefered_lft > valid_lft)) |
| 3695 | return -EINVAL; | 3772 | return -EINVAL; |
| 3696 | 3773 | ||
| @@ -3756,7 +3833,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, | |||
| 3756 | !was_managetempaddr, jiffies); | 3833 | !was_managetempaddr, jiffies); |
| 3757 | } | 3834 | } |
| 3758 | 3835 | ||
| 3759 | addrconf_verify(0); | 3836 | addrconf_verify_rtnl(); |
| 3760 | 3837 | ||
| 3761 | return 0; | 3838 | return 0; |
| 3762 | } | 3839 | } |
| @@ -4386,6 +4463,8 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) | |||
| 4386 | bool update_rs = false; | 4463 | bool update_rs = false; |
| 4387 | struct in6_addr ll_addr; | 4464 | struct in6_addr ll_addr; |
| 4388 | 4465 | ||
| 4466 | ASSERT_RTNL(); | ||
| 4467 | |||
| 4389 | if (token == NULL) | 4468 | if (token == NULL) |
| 4390 | return -EINVAL; | 4469 | return -EINVAL; |
| 4391 | if (ipv6_addr_any(token)) | 4470 | if (ipv6_addr_any(token)) |
| @@ -4434,7 +4513,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) | |||
| 4434 | } | 4513 | } |
| 4435 | 4514 | ||
| 4436 | write_unlock_bh(&idev->lock); | 4515 | write_unlock_bh(&idev->lock); |
| 4437 | addrconf_verify(0); | 4516 | addrconf_verify_rtnl(); |
| 4438 | return 0; | 4517 | return 0; |
| 4439 | } | 4518 | } |
| 4440 | 4519 | ||
| @@ -4636,6 +4715,9 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
| 4636 | { | 4715 | { |
| 4637 | struct net *net = dev_net(ifp->idev->dev); | 4716 | struct net *net = dev_net(ifp->idev->dev); |
| 4638 | 4717 | ||
| 4718 | if (event) | ||
| 4719 | ASSERT_RTNL(); | ||
| 4720 | |||
| 4639 | inet6_ifa_notify(event ? : RTM_NEWADDR, ifp); | 4721 | inet6_ifa_notify(event ? : RTM_NEWADDR, ifp); |
| 4640 | 4722 | ||
| 4641 | switch (event) { | 4723 | switch (event) { |
| @@ -5244,6 +5326,12 @@ int __init addrconf_init(void) | |||
| 5244 | if (err < 0) | 5326 | if (err < 0) |
| 5245 | goto out_addrlabel; | 5327 | goto out_addrlabel; |
| 5246 | 5328 | ||
| 5329 | addrconf_wq = create_workqueue("ipv6_addrconf"); | ||
| 5330 | if (!addrconf_wq) { | ||
| 5331 | err = -ENOMEM; | ||
| 5332 | goto out_nowq; | ||
| 5333 | } | ||
| 5334 | |||
| 5247 | /* The addrconf netdev notifier requires that loopback_dev | 5335 | /* The addrconf netdev notifier requires that loopback_dev |
| 5248 | * has it's ipv6 private information allocated and setup | 5336 | * has it's ipv6 private information allocated and setup |
| 5249 | * before it can bring up and give link-local addresses | 5337 | * before it can bring up and give link-local addresses |
| @@ -5274,7 +5362,7 @@ int __init addrconf_init(void) | |||
| 5274 | 5362 | ||
| 5275 | register_netdevice_notifier(&ipv6_dev_notf); | 5363 | register_netdevice_notifier(&ipv6_dev_notf); |
| 5276 | 5364 | ||
| 5277 | addrconf_verify(0); | 5365 | addrconf_verify(); |
| 5278 | 5366 | ||
| 5279 | rtnl_af_register(&inet6_ops); | 5367 | rtnl_af_register(&inet6_ops); |
| 5280 | 5368 | ||
| @@ -5302,6 +5390,8 @@ errout: | |||
| 5302 | rtnl_af_unregister(&inet6_ops); | 5390 | rtnl_af_unregister(&inet6_ops); |
| 5303 | unregister_netdevice_notifier(&ipv6_dev_notf); | 5391 | unregister_netdevice_notifier(&ipv6_dev_notf); |
| 5304 | errlo: | 5392 | errlo: |
| 5393 | destroy_workqueue(addrconf_wq); | ||
| 5394 | out_nowq: | ||
| 5305 | unregister_pernet_subsys(&addrconf_ops); | 5395 | unregister_pernet_subsys(&addrconf_ops); |
| 5306 | out_addrlabel: | 5396 | out_addrlabel: |
| 5307 | ipv6_addr_label_cleanup(); | 5397 | ipv6_addr_label_cleanup(); |
| @@ -5337,7 +5427,8 @@ void addrconf_cleanup(void) | |||
| 5337 | for (i = 0; i < IN6_ADDR_HSIZE; i++) | 5427 | for (i = 0; i < IN6_ADDR_HSIZE; i++) |
| 5338 | WARN_ON(!hlist_empty(&inet6_addr_lst[i])); | 5428 | WARN_ON(!hlist_empty(&inet6_addr_lst[i])); |
| 5339 | spin_unlock_bh(&addrconf_hash_lock); | 5429 | spin_unlock_bh(&addrconf_hash_lock); |
| 5340 | 5430 | cancel_delayed_work(&addr_chk_work); | |
| 5341 | del_timer(&addr_chk_timer); | ||
| 5342 | rtnl_unlock(); | 5431 | rtnl_unlock(); |
| 5432 | |||
| 5433 | destroy_workqueue(addrconf_wq); | ||
| 5343 | } | 5434 | } |
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c index f072fe803510..108120f216b1 100644 --- a/net/netfilter/nfnetlink_queue_core.c +++ b/net/netfilter/nfnetlink_queue_core.c | |||
| @@ -354,13 +354,16 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, | |||
| 354 | 354 | ||
| 355 | skb = nfnetlink_alloc_skb(net, size, queue->peer_portid, | 355 | skb = nfnetlink_alloc_skb(net, size, queue->peer_portid, |
| 356 | GFP_ATOMIC); | 356 | GFP_ATOMIC); |
| 357 | if (!skb) | 357 | if (!skb) { |
| 358 | skb_tx_error(entskb); | ||
| 358 | return NULL; | 359 | return NULL; |
| 360 | } | ||
| 359 | 361 | ||
| 360 | nlh = nlmsg_put(skb, 0, 0, | 362 | nlh = nlmsg_put(skb, 0, 0, |
| 361 | NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET, | 363 | NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET, |
| 362 | sizeof(struct nfgenmsg), 0); | 364 | sizeof(struct nfgenmsg), 0); |
| 363 | if (!nlh) { | 365 | if (!nlh) { |
| 366 | skb_tx_error(entskb); | ||
| 364 | kfree_skb(skb); | 367 | kfree_skb(skb); |
| 365 | return NULL; | 368 | return NULL; |
| 366 | } | 369 | } |
| @@ -488,13 +491,15 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, | |||
| 488 | nla->nla_type = NFQA_PAYLOAD; | 491 | nla->nla_type = NFQA_PAYLOAD; |
| 489 | nla->nla_len = nla_attr_size(data_len); | 492 | nla->nla_len = nla_attr_size(data_len); |
| 490 | 493 | ||
| 491 | skb_zerocopy(skb, entskb, data_len, hlen); | 494 | if (skb_zerocopy(skb, entskb, data_len, hlen)) |
| 495 | goto nla_put_failure; | ||
| 492 | } | 496 | } |
| 493 | 497 | ||
| 494 | nlh->nlmsg_len = skb->len; | 498 | nlh->nlmsg_len = skb->len; |
| 495 | return skb; | 499 | return skb; |
| 496 | 500 | ||
| 497 | nla_put_failure: | 501 | nla_put_failure: |
| 502 | skb_tx_error(entskb); | ||
| 498 | kfree_skb(skb); | 503 | kfree_skb(skb); |
| 499 | net_err_ratelimited("nf_queue: error creating packet message\n"); | 504 | net_err_ratelimited("nf_queue: error creating packet message\n"); |
| 500 | return NULL; | 505 | return NULL; |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 8601b320b443..270b77dfac30 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
| @@ -464,7 +464,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, | |||
| 464 | } | 464 | } |
| 465 | nla->nla_len = nla_attr_size(skb->len); | 465 | nla->nla_len = nla_attr_size(skb->len); |
| 466 | 466 | ||
| 467 | skb_zerocopy(user_skb, skb, skb->len, hlen); | 467 | err = skb_zerocopy(user_skb, skb, skb->len, hlen); |
| 468 | if (err) | ||
| 469 | goto out; | ||
| 468 | 470 | ||
| 469 | /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */ | 471 | /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */ |
| 470 | if (!(dp->user_features & OVS_DP_F_UNALIGNED)) { | 472 | if (!(dp->user_features & OVS_DP_F_UNALIGNED)) { |
| @@ -478,6 +480,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, | |||
| 478 | 480 | ||
| 479 | err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); | 481 | err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); |
| 480 | out: | 482 | out: |
| 483 | if (err) | ||
| 484 | skb_tx_error(skb); | ||
| 481 | kfree_skb(nskb); | 485 | kfree_skb(nskb); |
| 482 | return err; | 486 | return err; |
| 483 | } | 487 | } |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index dda451f4429c..2998989e76db 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
| @@ -103,30 +103,24 @@ static void stats_read(struct flow_stats *stats, | |||
| 103 | void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats, | 103 | void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats, |
| 104 | unsigned long *used, __be16 *tcp_flags) | 104 | unsigned long *used, __be16 *tcp_flags) |
| 105 | { | 105 | { |
| 106 | int cpu, cur_cpu; | 106 | int cpu; |
| 107 | 107 | ||
| 108 | *used = 0; | 108 | *used = 0; |
| 109 | *tcp_flags = 0; | 109 | *tcp_flags = 0; |
| 110 | memset(ovs_stats, 0, sizeof(*ovs_stats)); | 110 | memset(ovs_stats, 0, sizeof(*ovs_stats)); |
| 111 | 111 | ||
| 112 | local_bh_disable(); | ||
| 112 | if (!flow->stats.is_percpu) { | 113 | if (!flow->stats.is_percpu) { |
| 113 | stats_read(flow->stats.stat, ovs_stats, used, tcp_flags); | 114 | stats_read(flow->stats.stat, ovs_stats, used, tcp_flags); |
| 114 | } else { | 115 | } else { |
| 115 | cur_cpu = get_cpu(); | ||
| 116 | for_each_possible_cpu(cpu) { | 116 | for_each_possible_cpu(cpu) { |
| 117 | struct flow_stats *stats; | 117 | struct flow_stats *stats; |
| 118 | 118 | ||
| 119 | if (cpu == cur_cpu) | ||
| 120 | local_bh_disable(); | ||
| 121 | |||
| 122 | stats = per_cpu_ptr(flow->stats.cpu_stats, cpu); | 119 | stats = per_cpu_ptr(flow->stats.cpu_stats, cpu); |
| 123 | stats_read(stats, ovs_stats, used, tcp_flags); | 120 | stats_read(stats, ovs_stats, used, tcp_flags); |
| 124 | |||
| 125 | if (cpu == cur_cpu) | ||
| 126 | local_bh_enable(); | ||
| 127 | } | 121 | } |
| 128 | put_cpu(); | ||
| 129 | } | 122 | } |
| 123 | local_bh_enable(); | ||
| 130 | } | 124 | } |
| 131 | 125 | ||
| 132 | static void stats_reset(struct flow_stats *stats) | 126 | static void stats_reset(struct flow_stats *stats) |
| @@ -141,25 +135,17 @@ static void stats_reset(struct flow_stats *stats) | |||
| 141 | 135 | ||
| 142 | void ovs_flow_stats_clear(struct sw_flow *flow) | 136 | void ovs_flow_stats_clear(struct sw_flow *flow) |
| 143 | { | 137 | { |
| 144 | int cpu, cur_cpu; | 138 | int cpu; |
| 145 | 139 | ||
| 140 | local_bh_disable(); | ||
| 146 | if (!flow->stats.is_percpu) { | 141 | if (!flow->stats.is_percpu) { |
| 147 | stats_reset(flow->stats.stat); | 142 | stats_reset(flow->stats.stat); |
| 148 | } else { | 143 | } else { |
| 149 | cur_cpu = get_cpu(); | ||
| 150 | |||
| 151 | for_each_possible_cpu(cpu) { | 144 | for_each_possible_cpu(cpu) { |
| 152 | |||
| 153 | if (cpu == cur_cpu) | ||
| 154 | local_bh_disable(); | ||
| 155 | |||
| 156 | stats_reset(per_cpu_ptr(flow->stats.cpu_stats, cpu)); | 145 | stats_reset(per_cpu_ptr(flow->stats.cpu_stats, cpu)); |
| 157 | |||
| 158 | if (cpu == cur_cpu) | ||
| 159 | local_bh_enable(); | ||
| 160 | } | 146 | } |
| 161 | put_cpu(); | ||
| 162 | } | 147 | } |
| 148 | local_bh_enable(); | ||
| 163 | } | 149 | } |
| 164 | 150 | ||
| 165 | static int check_header(struct sk_buff *skb, int len) | 151 | static int check_header(struct sk_buff *skb, int len) |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index ce6ec6c2f4de..94404f19f9de 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -1787,8 +1787,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1787 | goto out; | 1787 | goto out; |
| 1788 | 1788 | ||
| 1789 | err = mutex_lock_interruptible(&u->readlock); | 1789 | err = mutex_lock_interruptible(&u->readlock); |
| 1790 | if (err) { | 1790 | if (unlikely(err)) { |
| 1791 | err = sock_intr_errno(sock_rcvtimeo(sk, noblock)); | 1791 | /* recvmsg() in non blocking mode is supposed to return -EAGAIN |
| 1792 | * sk_rcvtimeo is not honored by mutex_lock_interruptible() | ||
| 1793 | */ | ||
| 1794 | err = noblock ? -EAGAIN : -ERESTARTSYS; | ||
| 1792 | goto out; | 1795 | goto out; |
| 1793 | } | 1796 | } |
| 1794 | 1797 | ||
| @@ -1913,6 +1916,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1913 | struct unix_sock *u = unix_sk(sk); | 1916 | struct unix_sock *u = unix_sk(sk); |
| 1914 | DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name); | 1917 | DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name); |
| 1915 | int copied = 0; | 1918 | int copied = 0; |
| 1919 | int noblock = flags & MSG_DONTWAIT; | ||
| 1916 | int check_creds = 0; | 1920 | int check_creds = 0; |
| 1917 | int target; | 1921 | int target; |
| 1918 | int err = 0; | 1922 | int err = 0; |
| @@ -1928,7 +1932,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1928 | goto out; | 1932 | goto out; |
| 1929 | 1933 | ||
| 1930 | target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); | 1934 | target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); |
| 1931 | timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); | 1935 | timeo = sock_rcvtimeo(sk, noblock); |
| 1932 | 1936 | ||
| 1933 | /* Lock the socket to prevent queue disordering | 1937 | /* Lock the socket to prevent queue disordering |
| 1934 | * while sleeps in memcpy_tomsg | 1938 | * while sleeps in memcpy_tomsg |
| @@ -1940,8 +1944,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1940 | } | 1944 | } |
| 1941 | 1945 | ||
| 1942 | err = mutex_lock_interruptible(&u->readlock); | 1946 | err = mutex_lock_interruptible(&u->readlock); |
| 1943 | if (err) { | 1947 | if (unlikely(err)) { |
| 1944 | err = sock_intr_errno(timeo); | 1948 | /* recvmsg() in non blocking mode is supposed to return -EAGAIN |
| 1949 | * sk_rcvtimeo is not honored by mutex_lock_interruptible() | ||
| 1950 | */ | ||
| 1951 | err = noblock ? -EAGAIN : -ERESTARTSYS; | ||
| 1945 | goto out; | 1952 | goto out; |
| 1946 | } | 1953 | } |
| 1947 | 1954 | ||
