diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/datagram.c | 26 | ||||
-rw-r--r-- | net/core/dev.c | 122 | ||||
-rw-r--r-- | net/core/dev_addr_lists.c | 210 | ||||
-rw-r--r-- | net/core/dst.c | 9 | ||||
-rw-r--r-- | net/core/ethtool.c | 31 | ||||
-rw-r--r-- | net/core/fib_rules.c | 4 | ||||
-rw-r--r-- | net/core/filter.c | 5 | ||||
-rw-r--r-- | net/core/flow.c | 42 | ||||
-rw-r--r-- | net/core/flow_dissector.c | 68 | ||||
-rw-r--r-- | net/core/neighbour.c | 57 | ||||
-rw-r--r-- | net/core/net-procfs.c | 2 | ||||
-rw-r--r-- | net/core/net_namespace.c | 7 | ||||
-rw-r--r-- | net/core/netpoll.c | 22 | ||||
-rw-r--r-- | net/core/pktgen.c | 54 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 178 | ||||
-rw-r--r-- | net/core/scm.c | 20 | ||||
-rw-r--r-- | net/core/secure_seq.c | 4 | ||||
-rw-r--r-- | net/core/skbuff.c | 93 | ||||
-rw-r--r-- | net/core/sock.c | 22 | ||||
-rw-r--r-- | net/core/sock_diag.c | 33 | ||||
-rw-r--r-- | net/core/utils.c | 5 |
21 files changed, 667 insertions, 347 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c index 368f9c3f9dc6..b71423db7785 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -78,9 +78,10 @@ static int receiver_wake_function(wait_queue_t *wait, unsigned int mode, int syn | |||
78 | return autoremove_wake_function(wait, mode, sync, key); | 78 | return autoremove_wake_function(wait, mode, sync, key); |
79 | } | 79 | } |
80 | /* | 80 | /* |
81 | * Wait for a packet.. | 81 | * Wait for the last received packet to be different from skb |
82 | */ | 82 | */ |
83 | static int wait_for_packet(struct sock *sk, int *err, long *timeo_p) | 83 | static int wait_for_more_packets(struct sock *sk, int *err, long *timeo_p, |
84 | const struct sk_buff *skb) | ||
84 | { | 85 | { |
85 | int error; | 86 | int error; |
86 | DEFINE_WAIT_FUNC(wait, receiver_wake_function); | 87 | DEFINE_WAIT_FUNC(wait, receiver_wake_function); |
@@ -92,7 +93,7 @@ static int wait_for_packet(struct sock *sk, int *err, long *timeo_p) | |||
92 | if (error) | 93 | if (error) |
93 | goto out_err; | 94 | goto out_err; |
94 | 95 | ||
95 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 96 | if (sk->sk_receive_queue.prev != skb) |
96 | goto out; | 97 | goto out; |
97 | 98 | ||
98 | /* Socket shut down? */ | 99 | /* Socket shut down? */ |
@@ -131,9 +132,9 @@ out_noerr: | |||
131 | * __skb_recv_datagram - Receive a datagram skbuff | 132 | * __skb_recv_datagram - Receive a datagram skbuff |
132 | * @sk: socket | 133 | * @sk: socket |
133 | * @flags: MSG_ flags | 134 | * @flags: MSG_ flags |
135 | * @peeked: returns non-zero if this packet has been seen before | ||
134 | * @off: an offset in bytes to peek skb from. Returns an offset | 136 | * @off: an offset in bytes to peek skb from. Returns an offset |
135 | * within an skb where data actually starts | 137 | * within an skb where data actually starts |
136 | * @peeked: returns non-zero if this packet has been seen before | ||
137 | * @err: error code returned | 138 | * @err: error code returned |
138 | * | 139 | * |
139 | * Get a datagram skbuff, understands the peeking, nonblocking wakeups | 140 | * Get a datagram skbuff, understands the peeking, nonblocking wakeups |
@@ -161,7 +162,7 @@ out_noerr: | |||
161 | struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, | 162 | struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, |
162 | int *peeked, int *off, int *err) | 163 | int *peeked, int *off, int *err) |
163 | { | 164 | { |
164 | struct sk_buff *skb; | 165 | struct sk_buff *skb, *last; |
165 | long timeo; | 166 | long timeo; |
166 | /* | 167 | /* |
167 | * Caller is allowed not to check sk->sk_err before skb_recv_datagram() | 168 | * Caller is allowed not to check sk->sk_err before skb_recv_datagram() |
@@ -182,13 +183,17 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, | |||
182 | */ | 183 | */ |
183 | unsigned long cpu_flags; | 184 | unsigned long cpu_flags; |
184 | struct sk_buff_head *queue = &sk->sk_receive_queue; | 185 | struct sk_buff_head *queue = &sk->sk_receive_queue; |
186 | int _off = *off; | ||
185 | 187 | ||
188 | last = (struct sk_buff *)queue; | ||
186 | spin_lock_irqsave(&queue->lock, cpu_flags); | 189 | spin_lock_irqsave(&queue->lock, cpu_flags); |
187 | skb_queue_walk(queue, skb) { | 190 | skb_queue_walk(queue, skb) { |
191 | last = skb; | ||
188 | *peeked = skb->peeked; | 192 | *peeked = skb->peeked; |
189 | if (flags & MSG_PEEK) { | 193 | if (flags & MSG_PEEK) { |
190 | if (*off >= skb->len && skb->len) { | 194 | if (_off >= skb->len && (skb->len || _off || |
191 | *off -= skb->len; | 195 | skb->peeked)) { |
196 | _off -= skb->len; | ||
192 | continue; | 197 | continue; |
193 | } | 198 | } |
194 | skb->peeked = 1; | 199 | skb->peeked = 1; |
@@ -197,6 +202,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, | |||
197 | __skb_unlink(skb, queue); | 202 | __skb_unlink(skb, queue); |
198 | 203 | ||
199 | spin_unlock_irqrestore(&queue->lock, cpu_flags); | 204 | spin_unlock_irqrestore(&queue->lock, cpu_flags); |
205 | *off = _off; | ||
200 | return skb; | 206 | return skb; |
201 | } | 207 | } |
202 | spin_unlock_irqrestore(&queue->lock, cpu_flags); | 208 | spin_unlock_irqrestore(&queue->lock, cpu_flags); |
@@ -206,7 +212,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, | |||
206 | if (!timeo) | 212 | if (!timeo) |
207 | goto no_packet; | 213 | goto no_packet; |
208 | 214 | ||
209 | } while (!wait_for_packet(sk, err, &timeo)); | 215 | } while (!wait_for_more_packets(sk, err, &timeo, last)); |
210 | 216 | ||
211 | return NULL; | 217 | return NULL; |
212 | 218 | ||
@@ -749,7 +755,9 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, | |||
749 | 755 | ||
750 | /* exceptional events? */ | 756 | /* exceptional events? */ |
751 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | 757 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) |
752 | mask |= POLLERR; | 758 | mask |= POLLERR | |
759 | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0); | ||
760 | |||
753 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 761 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
754 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; | 762 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
755 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 763 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
diff --git a/net/core/dev.c b/net/core/dev.c index b24ab0e98eb4..40b1fadaf637 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -200,7 +200,7 @@ static inline void rps_unlock(struct softnet_data *sd) | |||
200 | } | 200 | } |
201 | 201 | ||
202 | /* Device list insertion */ | 202 | /* Device list insertion */ |
203 | static int list_netdevice(struct net_device *dev) | 203 | static void list_netdevice(struct net_device *dev) |
204 | { | 204 | { |
205 | struct net *net = dev_net(dev); | 205 | struct net *net = dev_net(dev); |
206 | 206 | ||
@@ -214,8 +214,6 @@ static int list_netdevice(struct net_device *dev) | |||
214 | write_unlock_bh(&dev_base_lock); | 214 | write_unlock_bh(&dev_base_lock); |
215 | 215 | ||
216 | dev_base_seq_inc(net); | 216 | dev_base_seq_inc(net); |
217 | |||
218 | return 0; | ||
219 | } | 217 | } |
220 | 218 | ||
221 | /* Device list removal | 219 | /* Device list removal |
@@ -2210,30 +2208,40 @@ out: | |||
2210 | } | 2208 | } |
2211 | EXPORT_SYMBOL(skb_checksum_help); | 2209 | EXPORT_SYMBOL(skb_checksum_help); |
2212 | 2210 | ||
2213 | /** | 2211 | __be16 skb_network_protocol(struct sk_buff *skb) |
2214 | * skb_mac_gso_segment - mac layer segmentation handler. | ||
2215 | * @skb: buffer to segment | ||
2216 | * @features: features for the output path (see dev->features) | ||
2217 | */ | ||
2218 | struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb, | ||
2219 | netdev_features_t features) | ||
2220 | { | 2212 | { |
2221 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); | ||
2222 | struct packet_offload *ptype; | ||
2223 | __be16 type = skb->protocol; | 2213 | __be16 type = skb->protocol; |
2224 | int vlan_depth = ETH_HLEN; | 2214 | int vlan_depth = ETH_HLEN; |
2225 | 2215 | ||
2226 | while (type == htons(ETH_P_8021Q)) { | 2216 | while (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) { |
2227 | struct vlan_hdr *vh; | 2217 | struct vlan_hdr *vh; |
2228 | 2218 | ||
2229 | if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN))) | 2219 | if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN))) |
2230 | return ERR_PTR(-EINVAL); | 2220 | return 0; |
2231 | 2221 | ||
2232 | vh = (struct vlan_hdr *)(skb->data + vlan_depth); | 2222 | vh = (struct vlan_hdr *)(skb->data + vlan_depth); |
2233 | type = vh->h_vlan_encapsulated_proto; | 2223 | type = vh->h_vlan_encapsulated_proto; |
2234 | vlan_depth += VLAN_HLEN; | 2224 | vlan_depth += VLAN_HLEN; |
2235 | } | 2225 | } |
2236 | 2226 | ||
2227 | return type; | ||
2228 | } | ||
2229 | |||
2230 | /** | ||
2231 | * skb_mac_gso_segment - mac layer segmentation handler. | ||
2232 | * @skb: buffer to segment | ||
2233 | * @features: features for the output path (see dev->features) | ||
2234 | */ | ||
2235 | struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb, | ||
2236 | netdev_features_t features) | ||
2237 | { | ||
2238 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); | ||
2239 | struct packet_offload *ptype; | ||
2240 | __be16 type = skb_network_protocol(skb); | ||
2241 | |||
2242 | if (unlikely(!type)) | ||
2243 | return ERR_PTR(-EINVAL); | ||
2244 | |||
2237 | __skb_pull(skb, skb->mac_len); | 2245 | __skb_pull(skb, skb->mac_len); |
2238 | 2246 | ||
2239 | rcu_read_lock(); | 2247 | rcu_read_lock(); |
@@ -2400,24 +2408,12 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features) | |||
2400 | return 0; | 2408 | return 0; |
2401 | } | 2409 | } |
2402 | 2410 | ||
2403 | static bool can_checksum_protocol(netdev_features_t features, __be16 protocol) | ||
2404 | { | ||
2405 | return ((features & NETIF_F_GEN_CSUM) || | ||
2406 | ((features & NETIF_F_V4_CSUM) && | ||
2407 | protocol == htons(ETH_P_IP)) || | ||
2408 | ((features & NETIF_F_V6_CSUM) && | ||
2409 | protocol == htons(ETH_P_IPV6)) || | ||
2410 | ((features & NETIF_F_FCOE_CRC) && | ||
2411 | protocol == htons(ETH_P_FCOE))); | ||
2412 | } | ||
2413 | |||
2414 | static netdev_features_t harmonize_features(struct sk_buff *skb, | 2411 | static netdev_features_t harmonize_features(struct sk_buff *skb, |
2415 | __be16 protocol, netdev_features_t features) | 2412 | __be16 protocol, netdev_features_t features) |
2416 | { | 2413 | { |
2417 | if (skb->ip_summed != CHECKSUM_NONE && | 2414 | if (skb->ip_summed != CHECKSUM_NONE && |
2418 | !can_checksum_protocol(features, protocol)) { | 2415 | !can_checksum_protocol(features, protocol)) { |
2419 | features &= ~NETIF_F_ALL_CSUM; | 2416 | features &= ~NETIF_F_ALL_CSUM; |
2420 | features &= ~NETIF_F_SG; | ||
2421 | } else if (illegal_highdma(skb->dev, skb)) { | 2417 | } else if (illegal_highdma(skb->dev, skb)) { |
2422 | features &= ~NETIF_F_SG; | 2418 | features &= ~NETIF_F_SG; |
2423 | } | 2419 | } |
@@ -2433,20 +2429,22 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
2433 | if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs) | 2429 | if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs) |
2434 | features &= ~NETIF_F_GSO_MASK; | 2430 | features &= ~NETIF_F_GSO_MASK; |
2435 | 2431 | ||
2436 | if (protocol == htons(ETH_P_8021Q)) { | 2432 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { |
2437 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2433 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
2438 | protocol = veh->h_vlan_encapsulated_proto; | 2434 | protocol = veh->h_vlan_encapsulated_proto; |
2439 | } else if (!vlan_tx_tag_present(skb)) { | 2435 | } else if (!vlan_tx_tag_present(skb)) { |
2440 | return harmonize_features(skb, protocol, features); | 2436 | return harmonize_features(skb, protocol, features); |
2441 | } | 2437 | } |
2442 | 2438 | ||
2443 | features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_TX); | 2439 | features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | |
2440 | NETIF_F_HW_VLAN_STAG_TX); | ||
2444 | 2441 | ||
2445 | if (protocol != htons(ETH_P_8021Q)) { | 2442 | if (protocol != htons(ETH_P_8021Q) && protocol != htons(ETH_P_8021AD)) { |
2446 | return harmonize_features(skb, protocol, features); | 2443 | return harmonize_features(skb, protocol, features); |
2447 | } else { | 2444 | } else { |
2448 | features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | | 2445 | features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | |
2449 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_TX; | 2446 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | |
2447 | NETIF_F_HW_VLAN_STAG_TX; | ||
2450 | return harmonize_features(skb, protocol, features); | 2448 | return harmonize_features(skb, protocol, features); |
2451 | } | 2449 | } |
2452 | } | 2450 | } |
@@ -2458,7 +2456,7 @@ EXPORT_SYMBOL(netif_skb_features); | |||
2458 | * 2. skb is fragmented and the device does not support SG. | 2456 | * 2. skb is fragmented and the device does not support SG. |
2459 | */ | 2457 | */ |
2460 | static inline int skb_needs_linearize(struct sk_buff *skb, | 2458 | static inline int skb_needs_linearize(struct sk_buff *skb, |
2461 | int features) | 2459 | netdev_features_t features) |
2462 | { | 2460 | { |
2463 | return skb_is_nonlinear(skb) && | 2461 | return skb_is_nonlinear(skb) && |
2464 | ((skb_has_frag_list(skb) && | 2462 | ((skb_has_frag_list(skb) && |
@@ -2487,8 +2485,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2487 | features = netif_skb_features(skb); | 2485 | features = netif_skb_features(skb); |
2488 | 2486 | ||
2489 | if (vlan_tx_tag_present(skb) && | 2487 | if (vlan_tx_tag_present(skb) && |
2490 | !(features & NETIF_F_HW_VLAN_TX)) { | 2488 | !vlan_hw_offload_capable(features, skb->vlan_proto)) { |
2491 | skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); | 2489 | skb = __vlan_put_tag(skb, skb->vlan_proto, |
2490 | vlan_tx_tag_get(skb)); | ||
2492 | if (unlikely(!skb)) | 2491 | if (unlikely(!skb)) |
2493 | goto out; | 2492 | goto out; |
2494 | 2493 | ||
@@ -2547,13 +2546,6 @@ gso: | |||
2547 | skb->next = nskb->next; | 2546 | skb->next = nskb->next; |
2548 | nskb->next = NULL; | 2547 | nskb->next = NULL; |
2549 | 2548 | ||
2550 | /* | ||
2551 | * If device doesn't need nskb->dst, release it right now while | ||
2552 | * its hot in this cpu cache | ||
2553 | */ | ||
2554 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) | ||
2555 | skb_dst_drop(nskb); | ||
2556 | |||
2557 | if (!list_empty(&ptype_all)) | 2549 | if (!list_empty(&ptype_all)) |
2558 | dev_queue_xmit_nit(nskb, dev); | 2550 | dev_queue_xmit_nit(nskb, dev); |
2559 | 2551 | ||
@@ -2573,8 +2565,11 @@ gso: | |||
2573 | } while (skb->next); | 2565 | } while (skb->next); |
2574 | 2566 | ||
2575 | out_kfree_gso_skb: | 2567 | out_kfree_gso_skb: |
2576 | if (likely(skb->next == NULL)) | 2568 | if (likely(skb->next == NULL)) { |
2577 | skb->destructor = DEV_GSO_CB(skb)->destructor; | 2569 | skb->destructor = DEV_GSO_CB(skb)->destructor; |
2570 | consume_skb(skb); | ||
2571 | return rc; | ||
2572 | } | ||
2578 | out_kfree_skb: | 2573 | out_kfree_skb: |
2579 | kfree_skb(skb); | 2574 | kfree_skb(skb); |
2580 | out: | 2575 | out: |
@@ -2592,6 +2587,7 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) | |||
2592 | */ | 2587 | */ |
2593 | if (shinfo->gso_size) { | 2588 | if (shinfo->gso_size) { |
2594 | unsigned int hdr_len; | 2589 | unsigned int hdr_len; |
2590 | u16 gso_segs = shinfo->gso_segs; | ||
2595 | 2591 | ||
2596 | /* mac layer + network layer */ | 2592 | /* mac layer + network layer */ |
2597 | hdr_len = skb_transport_header(skb) - skb_mac_header(skb); | 2593 | hdr_len = skb_transport_header(skb) - skb_mac_header(skb); |
@@ -2601,7 +2597,12 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) | |||
2601 | hdr_len += tcp_hdrlen(skb); | 2597 | hdr_len += tcp_hdrlen(skb); |
2602 | else | 2598 | else |
2603 | hdr_len += sizeof(struct udphdr); | 2599 | hdr_len += sizeof(struct udphdr); |
2604 | qdisc_skb_cb(skb)->pkt_len += (shinfo->gso_segs - 1) * hdr_len; | 2600 | |
2601 | if (shinfo->gso_type & SKB_GSO_DODGY) | ||
2602 | gso_segs = DIV_ROUND_UP(skb->len - hdr_len, | ||
2603 | shinfo->gso_size); | ||
2604 | |||
2605 | qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len; | ||
2605 | } | 2606 | } |
2606 | } | 2607 | } |
2607 | 2608 | ||
@@ -3329,7 +3330,7 @@ EXPORT_SYMBOL_GPL(netdev_rx_handler_register); | |||
3329 | * netdev_rx_handler_unregister - unregister receive handler | 3330 | * netdev_rx_handler_unregister - unregister receive handler |
3330 | * @dev: device to unregister a handler from | 3331 | * @dev: device to unregister a handler from |
3331 | * | 3332 | * |
3332 | * Unregister a receive hander from a device. | 3333 | * Unregister a receive handler from a device. |
3333 | * | 3334 | * |
3334 | * The caller must hold the rtnl_mutex. | 3335 | * The caller must hold the rtnl_mutex. |
3335 | */ | 3336 | */ |
@@ -3358,6 +3359,7 @@ static bool skb_pfmemalloc_protocol(struct sk_buff *skb) | |||
3358 | case __constant_htons(ETH_P_IP): | 3359 | case __constant_htons(ETH_P_IP): |
3359 | case __constant_htons(ETH_P_IPV6): | 3360 | case __constant_htons(ETH_P_IPV6): |
3360 | case __constant_htons(ETH_P_8021Q): | 3361 | case __constant_htons(ETH_P_8021Q): |
3362 | case __constant_htons(ETH_P_8021AD): | ||
3361 | return true; | 3363 | return true; |
3362 | default: | 3364 | default: |
3363 | return false; | 3365 | return false; |
@@ -3398,7 +3400,8 @@ another_round: | |||
3398 | 3400 | ||
3399 | __this_cpu_inc(softnet_data.processed); | 3401 | __this_cpu_inc(softnet_data.processed); |
3400 | 3402 | ||
3401 | if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { | 3403 | if (skb->protocol == cpu_to_be16(ETH_P_8021Q) || |
3404 | skb->protocol == cpu_to_be16(ETH_P_8021AD)) { | ||
3402 | skb = vlan_untag(skb); | 3405 | skb = vlan_untag(skb); |
3403 | if (unlikely(!skb)) | 3406 | if (unlikely(!skb)) |
3404 | goto unlock; | 3407 | goto unlock; |
@@ -4066,6 +4069,9 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi, | |||
4066 | napi->gro_list = NULL; | 4069 | napi->gro_list = NULL; |
4067 | napi->skb = NULL; | 4070 | napi->skb = NULL; |
4068 | napi->poll = poll; | 4071 | napi->poll = poll; |
4072 | if (weight > NAPI_POLL_WEIGHT) | ||
4073 | pr_err_once("netif_napi_add() called with weight %d on device %s\n", | ||
4074 | weight, dev->name); | ||
4069 | napi->weight = weight; | 4075 | napi->weight = weight; |
4070 | list_add(&napi->dev_list, &dev->napi_list); | 4076 | list_add(&napi->dev_list, &dev->napi_list); |
4071 | napi->dev = dev; | 4077 | napi->dev = dev; |
@@ -4927,20 +4933,25 @@ static netdev_features_t netdev_fix_features(struct net_device *dev, | |||
4927 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); | 4933 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); |
4928 | } | 4934 | } |
4929 | 4935 | ||
4930 | /* Fix illegal SG+CSUM combinations. */ | ||
4931 | if ((features & NETIF_F_SG) && | ||
4932 | !(features & NETIF_F_ALL_CSUM)) { | ||
4933 | netdev_dbg(dev, | ||
4934 | "Dropping NETIF_F_SG since no checksum feature.\n"); | ||
4935 | features &= ~NETIF_F_SG; | ||
4936 | } | ||
4937 | |||
4938 | /* TSO requires that SG is present as well. */ | 4936 | /* TSO requires that SG is present as well. */ |
4939 | if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) { | 4937 | if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) { |
4940 | netdev_dbg(dev, "Dropping TSO features since no SG feature.\n"); | 4938 | netdev_dbg(dev, "Dropping TSO features since no SG feature.\n"); |
4941 | features &= ~NETIF_F_ALL_TSO; | 4939 | features &= ~NETIF_F_ALL_TSO; |
4942 | } | 4940 | } |
4943 | 4941 | ||
4942 | if ((features & NETIF_F_TSO) && !(features & NETIF_F_HW_CSUM) && | ||
4943 | !(features & NETIF_F_IP_CSUM)) { | ||
4944 | netdev_dbg(dev, "Dropping TSO features since no CSUM feature.\n"); | ||
4945 | features &= ~NETIF_F_TSO; | ||
4946 | features &= ~NETIF_F_TSO_ECN; | ||
4947 | } | ||
4948 | |||
4949 | if ((features & NETIF_F_TSO6) && !(features & NETIF_F_HW_CSUM) && | ||
4950 | !(features & NETIF_F_IPV6_CSUM)) { | ||
4951 | netdev_dbg(dev, "Dropping TSO6 features since no CSUM feature.\n"); | ||
4952 | features &= ~NETIF_F_TSO6; | ||
4953 | } | ||
4954 | |||
4944 | /* TSO ECN requires that TSO is present as well. */ | 4955 | /* TSO ECN requires that TSO is present as well. */ |
4945 | if ((features & NETIF_F_ALL_TSO) == NETIF_F_TSO_ECN) | 4956 | if ((features & NETIF_F_ALL_TSO) == NETIF_F_TSO_ECN) |
4946 | features &= ~NETIF_F_TSO_ECN; | 4957 | features &= ~NETIF_F_TSO_ECN; |
@@ -5171,7 +5182,8 @@ int register_netdevice(struct net_device *dev) | |||
5171 | } | 5182 | } |
5172 | } | 5183 | } |
5173 | 5184 | ||
5174 | if (((dev->hw_features | dev->features) & NETIF_F_HW_VLAN_FILTER) && | 5185 | if (((dev->hw_features | dev->features) & |
5186 | NETIF_F_HW_VLAN_CTAG_FILTER) && | ||
5175 | (!dev->netdev_ops->ndo_vlan_rx_add_vid || | 5187 | (!dev->netdev_ops->ndo_vlan_rx_add_vid || |
5176 | !dev->netdev_ops->ndo_vlan_rx_kill_vid)) { | 5188 | !dev->netdev_ops->ndo_vlan_rx_kill_vid)) { |
5177 | netdev_WARN(dev, "Buggy VLAN acceleration in driver!\n"); | 5189 | netdev_WARN(dev, "Buggy VLAN acceleration in driver!\n"); |
@@ -5208,6 +5220,10 @@ int register_netdevice(struct net_device *dev) | |||
5208 | */ | 5220 | */ |
5209 | dev->vlan_features |= NETIF_F_HIGHDMA; | 5221 | dev->vlan_features |= NETIF_F_HIGHDMA; |
5210 | 5222 | ||
5223 | /* Make NETIF_F_SG inheritable to tunnel devices. | ||
5224 | */ | ||
5225 | dev->hw_enc_features |= NETIF_F_SG; | ||
5226 | |||
5211 | ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev); | 5227 | ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev); |
5212 | ret = notifier_to_errno(ret); | 5228 | ret = notifier_to_errno(ret); |
5213 | if (ret) | 5229 | if (ret) |
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index abdc9e6ef33e..c013f38482a1 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c | |||
@@ -22,7 +22,8 @@ | |||
22 | 22 | ||
23 | static int __hw_addr_create_ex(struct netdev_hw_addr_list *list, | 23 | static int __hw_addr_create_ex(struct netdev_hw_addr_list *list, |
24 | const unsigned char *addr, int addr_len, | 24 | const unsigned char *addr, int addr_len, |
25 | unsigned char addr_type, bool global) | 25 | unsigned char addr_type, bool global, |
26 | bool sync) | ||
26 | { | 27 | { |
27 | struct netdev_hw_addr *ha; | 28 | struct netdev_hw_addr *ha; |
28 | int alloc_size; | 29 | int alloc_size; |
@@ -37,7 +38,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list, | |||
37 | ha->type = addr_type; | 38 | ha->type = addr_type; |
38 | ha->refcount = 1; | 39 | ha->refcount = 1; |
39 | ha->global_use = global; | 40 | ha->global_use = global; |
40 | ha->synced = 0; | 41 | ha->synced = sync; |
41 | list_add_tail_rcu(&ha->list, &list->list); | 42 | list_add_tail_rcu(&ha->list, &list->list); |
42 | list->count++; | 43 | list->count++; |
43 | 44 | ||
@@ -46,7 +47,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list, | |||
46 | 47 | ||
47 | static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, | 48 | static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, |
48 | const unsigned char *addr, int addr_len, | 49 | const unsigned char *addr, int addr_len, |
49 | unsigned char addr_type, bool global) | 50 | unsigned char addr_type, bool global, bool sync) |
50 | { | 51 | { |
51 | struct netdev_hw_addr *ha; | 52 | struct netdev_hw_addr *ha; |
52 | 53 | ||
@@ -63,43 +64,62 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, | |||
63 | else | 64 | else |
64 | ha->global_use = true; | 65 | ha->global_use = true; |
65 | } | 66 | } |
67 | if (sync) { | ||
68 | if (ha->synced) | ||
69 | return 0; | ||
70 | else | ||
71 | ha->synced = true; | ||
72 | } | ||
66 | ha->refcount++; | 73 | ha->refcount++; |
67 | return 0; | 74 | return 0; |
68 | } | 75 | } |
69 | } | 76 | } |
70 | 77 | ||
71 | return __hw_addr_create_ex(list, addr, addr_len, addr_type, global); | 78 | return __hw_addr_create_ex(list, addr, addr_len, addr_type, global, |
79 | sync); | ||
72 | } | 80 | } |
73 | 81 | ||
74 | static int __hw_addr_add(struct netdev_hw_addr_list *list, | 82 | static int __hw_addr_add(struct netdev_hw_addr_list *list, |
75 | const unsigned char *addr, int addr_len, | 83 | const unsigned char *addr, int addr_len, |
76 | unsigned char addr_type) | 84 | unsigned char addr_type) |
77 | { | 85 | { |
78 | return __hw_addr_add_ex(list, addr, addr_len, addr_type, false); | 86 | return __hw_addr_add_ex(list, addr, addr_len, addr_type, false, false); |
87 | } | ||
88 | |||
89 | static int __hw_addr_del_entry(struct netdev_hw_addr_list *list, | ||
90 | struct netdev_hw_addr *ha, bool global, | ||
91 | bool sync) | ||
92 | { | ||
93 | if (global && !ha->global_use) | ||
94 | return -ENOENT; | ||
95 | |||
96 | if (sync && !ha->synced) | ||
97 | return -ENOENT; | ||
98 | |||
99 | if (global) | ||
100 | ha->global_use = false; | ||
101 | |||
102 | if (sync) | ||
103 | ha->synced = false; | ||
104 | |||
105 | if (--ha->refcount) | ||
106 | return 0; | ||
107 | list_del_rcu(&ha->list); | ||
108 | kfree_rcu(ha, rcu_head); | ||
109 | list->count--; | ||
110 | return 0; | ||
79 | } | 111 | } |
80 | 112 | ||
81 | static int __hw_addr_del_ex(struct netdev_hw_addr_list *list, | 113 | static int __hw_addr_del_ex(struct netdev_hw_addr_list *list, |
82 | const unsigned char *addr, int addr_len, | 114 | const unsigned char *addr, int addr_len, |
83 | unsigned char addr_type, bool global) | 115 | unsigned char addr_type, bool global, bool sync) |
84 | { | 116 | { |
85 | struct netdev_hw_addr *ha; | 117 | struct netdev_hw_addr *ha; |
86 | 118 | ||
87 | list_for_each_entry(ha, &list->list, list) { | 119 | list_for_each_entry(ha, &list->list, list) { |
88 | if (!memcmp(ha->addr, addr, addr_len) && | 120 | if (!memcmp(ha->addr, addr, addr_len) && |
89 | (ha->type == addr_type || !addr_type)) { | 121 | (ha->type == addr_type || !addr_type)) |
90 | if (global) { | 122 | return __hw_addr_del_entry(list, ha, global, sync); |
91 | if (!ha->global_use) | ||
92 | break; | ||
93 | else | ||
94 | ha->global_use = false; | ||
95 | } | ||
96 | if (--ha->refcount) | ||
97 | return 0; | ||
98 | list_del_rcu(&ha->list); | ||
99 | kfree_rcu(ha, rcu_head); | ||
100 | list->count--; | ||
101 | return 0; | ||
102 | } | ||
103 | } | 123 | } |
104 | return -ENOENT; | 124 | return -ENOENT; |
105 | } | 125 | } |
@@ -108,7 +128,57 @@ static int __hw_addr_del(struct netdev_hw_addr_list *list, | |||
108 | const unsigned char *addr, int addr_len, | 128 | const unsigned char *addr, int addr_len, |
109 | unsigned char addr_type) | 129 | unsigned char addr_type) |
110 | { | 130 | { |
111 | return __hw_addr_del_ex(list, addr, addr_len, addr_type, false); | 131 | return __hw_addr_del_ex(list, addr, addr_len, addr_type, false, false); |
132 | } | ||
133 | |||
134 | static int __hw_addr_sync_one(struct netdev_hw_addr_list *to_list, | ||
135 | struct netdev_hw_addr *ha, | ||
136 | int addr_len) | ||
137 | { | ||
138 | int err; | ||
139 | |||
140 | err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type, | ||
141 | false, true); | ||
142 | if (err) | ||
143 | return err; | ||
144 | ha->sync_cnt++; | ||
145 | ha->refcount++; | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list, | ||
151 | struct netdev_hw_addr_list *from_list, | ||
152 | struct netdev_hw_addr *ha, | ||
153 | int addr_len) | ||
154 | { | ||
155 | int err; | ||
156 | |||
157 | err = __hw_addr_del_ex(to_list, ha->addr, addr_len, ha->type, | ||
158 | false, true); | ||
159 | if (err) | ||
160 | return; | ||
161 | ha->sync_cnt--; | ||
162 | __hw_addr_del_entry(from_list, ha, false, true); | ||
163 | } | ||
164 | |||
165 | static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list, | ||
166 | struct netdev_hw_addr_list *from_list, | ||
167 | int addr_len) | ||
168 | { | ||
169 | int err = 0; | ||
170 | struct netdev_hw_addr *ha, *tmp; | ||
171 | |||
172 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { | ||
173 | if (ha->sync_cnt == ha->refcount) { | ||
174 | __hw_addr_unsync_one(to_list, from_list, ha, addr_len); | ||
175 | } else { | ||
176 | err = __hw_addr_sync_one(to_list, ha, addr_len); | ||
177 | if (err) | ||
178 | break; | ||
179 | } | ||
180 | } | ||
181 | return err; | ||
112 | } | 182 | } |
113 | 183 | ||
114 | int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, | 184 | int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, |
@@ -152,6 +222,11 @@ void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, | |||
152 | } | 222 | } |
153 | EXPORT_SYMBOL(__hw_addr_del_multiple); | 223 | EXPORT_SYMBOL(__hw_addr_del_multiple); |
154 | 224 | ||
225 | /* This function only works where there is a strict 1-1 relationship | ||
226 | * between source and destionation of they synch. If you ever need to | ||
227 | * sync addresses to more then 1 destination, you need to use | ||
228 | * __hw_addr_sync_multiple(). | ||
229 | */ | ||
155 | int __hw_addr_sync(struct netdev_hw_addr_list *to_list, | 230 | int __hw_addr_sync(struct netdev_hw_addr_list *to_list, |
156 | struct netdev_hw_addr_list *from_list, | 231 | struct netdev_hw_addr_list *from_list, |
157 | int addr_len) | 232 | int addr_len) |
@@ -160,17 +235,12 @@ int __hw_addr_sync(struct netdev_hw_addr_list *to_list, | |||
160 | struct netdev_hw_addr *ha, *tmp; | 235 | struct netdev_hw_addr *ha, *tmp; |
161 | 236 | ||
162 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { | 237 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { |
163 | if (!ha->synced) { | 238 | if (!ha->sync_cnt) { |
164 | err = __hw_addr_add(to_list, ha->addr, | 239 | err = __hw_addr_sync_one(to_list, ha, addr_len); |
165 | addr_len, ha->type); | ||
166 | if (err) | 240 | if (err) |
167 | break; | 241 | break; |
168 | ha->synced++; | 242 | } else if (ha->refcount == 1) |
169 | ha->refcount++; | 243 | __hw_addr_unsync_one(to_list, from_list, ha, addr_len); |
170 | } else if (ha->refcount == 1) { | ||
171 | __hw_addr_del(to_list, ha->addr, addr_len, ha->type); | ||
172 | __hw_addr_del(from_list, ha->addr, addr_len, ha->type); | ||
173 | } | ||
174 | } | 244 | } |
175 | return err; | 245 | return err; |
176 | } | 246 | } |
@@ -183,13 +253,8 @@ void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, | |||
183 | struct netdev_hw_addr *ha, *tmp; | 253 | struct netdev_hw_addr *ha, *tmp; |
184 | 254 | ||
185 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { | 255 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { |
186 | if (ha->synced) { | 256 | if (ha->sync_cnt) |
187 | __hw_addr_del(to_list, ha->addr, | 257 | __hw_addr_unsync_one(to_list, from_list, ha, addr_len); |
188 | addr_len, ha->type); | ||
189 | ha->synced--; | ||
190 | __hw_addr_del(from_list, ha->addr, | ||
191 | addr_len, ha->type); | ||
192 | } | ||
193 | } | 258 | } |
194 | } | 259 | } |
195 | EXPORT_SYMBOL(__hw_addr_unsync); | 260 | EXPORT_SYMBOL(__hw_addr_unsync); |
@@ -406,7 +471,7 @@ int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr) | |||
406 | } | 471 | } |
407 | } | 472 | } |
408 | err = __hw_addr_create_ex(&dev->uc, addr, dev->addr_len, | 473 | err = __hw_addr_create_ex(&dev->uc, addr, dev->addr_len, |
409 | NETDEV_HW_ADDR_T_UNICAST, true); | 474 | NETDEV_HW_ADDR_T_UNICAST, true, false); |
410 | if (!err) | 475 | if (!err) |
411 | __dev_set_rx_mode(dev); | 476 | __dev_set_rx_mode(dev); |
412 | out: | 477 | out: |
@@ -469,7 +534,8 @@ EXPORT_SYMBOL(dev_uc_del); | |||
469 | * locked by netif_addr_lock_bh. | 534 | * locked by netif_addr_lock_bh. |
470 | * | 535 | * |
471 | * This function is intended to be called from the dev->set_rx_mode | 536 | * This function is intended to be called from the dev->set_rx_mode |
472 | * function of layered software devices. | 537 | * function of layered software devices. This function assumes that |
538 | * addresses will only ever be synced to the @to devices and no other. | ||
473 | */ | 539 | */ |
474 | int dev_uc_sync(struct net_device *to, struct net_device *from) | 540 | int dev_uc_sync(struct net_device *to, struct net_device *from) |
475 | { | 541 | { |
@@ -488,6 +554,36 @@ int dev_uc_sync(struct net_device *to, struct net_device *from) | |||
488 | EXPORT_SYMBOL(dev_uc_sync); | 554 | EXPORT_SYMBOL(dev_uc_sync); |
489 | 555 | ||
490 | /** | 556 | /** |
557 | * dev_uc_sync_multiple - Synchronize device's unicast list to another | ||
558 | * device, but allow for multiple calls to sync to multiple devices. | ||
559 | * @to: destination device | ||
560 | * @from: source device | ||
561 | * | ||
562 | * Add newly added addresses to the destination device and release | ||
563 | * addresses that have been deleted from the source. The source device | ||
564 | * must be locked by netif_addr_lock_bh. | ||
565 | * | ||
566 | * This function is intended to be called from the dev->set_rx_mode | ||
567 | * function of layered software devices. It allows for a single source | ||
568 | * device to be synced to multiple destination devices. | ||
569 | */ | ||
570 | int dev_uc_sync_multiple(struct net_device *to, struct net_device *from) | ||
571 | { | ||
572 | int err = 0; | ||
573 | |||
574 | if (to->addr_len != from->addr_len) | ||
575 | return -EINVAL; | ||
576 | |||
577 | netif_addr_lock_nested(to); | ||
578 | err = __hw_addr_sync_multiple(&to->uc, &from->uc, to->addr_len); | ||
579 | if (!err) | ||
580 | __dev_set_rx_mode(to); | ||
581 | netif_addr_unlock(to); | ||
582 | return err; | ||
583 | } | ||
584 | EXPORT_SYMBOL(dev_uc_sync_multiple); | ||
585 | |||
586 | /** | ||
491 | * dev_uc_unsync - Remove synchronized addresses from the destination device | 587 | * dev_uc_unsync - Remove synchronized addresses from the destination device |
492 | * @to: destination device | 588 | * @to: destination device |
493 | * @from: source device | 589 | * @from: source device |
@@ -559,7 +655,7 @@ int dev_mc_add_excl(struct net_device *dev, const unsigned char *addr) | |||
559 | } | 655 | } |
560 | } | 656 | } |
561 | err = __hw_addr_create_ex(&dev->mc, addr, dev->addr_len, | 657 | err = __hw_addr_create_ex(&dev->mc, addr, dev->addr_len, |
562 | NETDEV_HW_ADDR_T_MULTICAST, true); | 658 | NETDEV_HW_ADDR_T_MULTICAST, true, false); |
563 | if (!err) | 659 | if (!err) |
564 | __dev_set_rx_mode(dev); | 660 | __dev_set_rx_mode(dev); |
565 | out: | 661 | out: |
@@ -575,7 +671,7 @@ static int __dev_mc_add(struct net_device *dev, const unsigned char *addr, | |||
575 | 671 | ||
576 | netif_addr_lock_bh(dev); | 672 | netif_addr_lock_bh(dev); |
577 | err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len, | 673 | err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len, |
578 | NETDEV_HW_ADDR_T_MULTICAST, global); | 674 | NETDEV_HW_ADDR_T_MULTICAST, global, false); |
579 | if (!err) | 675 | if (!err) |
580 | __dev_set_rx_mode(dev); | 676 | __dev_set_rx_mode(dev); |
581 | netif_addr_unlock_bh(dev); | 677 | netif_addr_unlock_bh(dev); |
@@ -615,7 +711,7 @@ static int __dev_mc_del(struct net_device *dev, const unsigned char *addr, | |||
615 | 711 | ||
616 | netif_addr_lock_bh(dev); | 712 | netif_addr_lock_bh(dev); |
617 | err = __hw_addr_del_ex(&dev->mc, addr, dev->addr_len, | 713 | err = __hw_addr_del_ex(&dev->mc, addr, dev->addr_len, |
618 | NETDEV_HW_ADDR_T_MULTICAST, global); | 714 | NETDEV_HW_ADDR_T_MULTICAST, global, false); |
619 | if (!err) | 715 | if (!err) |
620 | __dev_set_rx_mode(dev); | 716 | __dev_set_rx_mode(dev); |
621 | netif_addr_unlock_bh(dev); | 717 | netif_addr_unlock_bh(dev); |
@@ -679,6 +775,36 @@ int dev_mc_sync(struct net_device *to, struct net_device *from) | |||
679 | EXPORT_SYMBOL(dev_mc_sync); | 775 | EXPORT_SYMBOL(dev_mc_sync); |
680 | 776 | ||
681 | /** | 777 | /** |
778 | * dev_mc_sync_multiple - Synchronize device's unicast list to another | ||
779 | * device, but allow for multiple calls to sync to multiple devices. | ||
780 | * @to: destination device | ||
781 | * @from: source device | ||
782 | * | ||
783 | * Add newly added addresses to the destination device and release | ||
784 | * addresses that have no users left. The source device must be | ||
785 | * locked by netif_addr_lock_bh. | ||
786 | * | ||
787 | * This function is intended to be called from the ndo_set_rx_mode | ||
788 | * function of layered software devices. It allows for a single | ||
789 | * source device to be synced to multiple destination devices. | ||
790 | */ | ||
791 | int dev_mc_sync_multiple(struct net_device *to, struct net_device *from) | ||
792 | { | ||
793 | int err = 0; | ||
794 | |||
795 | if (to->addr_len != from->addr_len) | ||
796 | return -EINVAL; | ||
797 | |||
798 | netif_addr_lock_nested(to); | ||
799 | err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); | ||
800 | if (!err) | ||
801 | __dev_set_rx_mode(to); | ||
802 | netif_addr_unlock(to); | ||
803 | return err; | ||
804 | } | ||
805 | EXPORT_SYMBOL(dev_mc_sync_multiple); | ||
806 | |||
807 | /** | ||
682 | * dev_mc_unsync - Remove synchronized addresses from the destination device | 808 | * dev_mc_unsync - Remove synchronized addresses from the destination device |
683 | * @to: destination device | 809 | * @to: destination device |
684 | * @from: source device | 810 | * @from: source device |
diff --git a/net/core/dst.c b/net/core/dst.c index 35fd12f1a69c..df9cc810ec8e 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -320,27 +320,28 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old) | |||
320 | EXPORT_SYMBOL(__dst_destroy_metrics_generic); | 320 | EXPORT_SYMBOL(__dst_destroy_metrics_generic); |
321 | 321 | ||
322 | /** | 322 | /** |
323 | * skb_dst_set_noref - sets skb dst, without a reference | 323 | * __skb_dst_set_noref - sets skb dst, without a reference |
324 | * @skb: buffer | 324 | * @skb: buffer |
325 | * @dst: dst entry | 325 | * @dst: dst entry |
326 | * @force: if force is set, use noref version even for DST_NOCACHE entries | ||
326 | * | 327 | * |
327 | * Sets skb dst, assuming a reference was not taken on dst | 328 | * Sets skb dst, assuming a reference was not taken on dst |
328 | * skb_dst_drop() should not dst_release() this dst | 329 | * skb_dst_drop() should not dst_release() this dst |
329 | */ | 330 | */ |
330 | void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst) | 331 | void __skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst, bool force) |
331 | { | 332 | { |
332 | WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); | 333 | WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); |
333 | /* If dst not in cache, we must take a reference, because | 334 | /* If dst not in cache, we must take a reference, because |
334 | * dst_release() will destroy dst as soon as its refcount becomes zero | 335 | * dst_release() will destroy dst as soon as its refcount becomes zero |
335 | */ | 336 | */ |
336 | if (unlikely(dst->flags & DST_NOCACHE)) { | 337 | if (unlikely((dst->flags & DST_NOCACHE) && !force)) { |
337 | dst_hold(dst); | 338 | dst_hold(dst); |
338 | skb_dst_set(skb, dst); | 339 | skb_dst_set(skb, dst); |
339 | } else { | 340 | } else { |
340 | skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF; | 341 | skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF; |
341 | } | 342 | } |
342 | } | 343 | } |
343 | EXPORT_SYMBOL(skb_dst_set_noref); | 344 | EXPORT_SYMBOL(__skb_dst_set_noref); |
344 | 345 | ||
345 | /* Dirty hack. We did it in 2.2 (in __dst_free), | 346 | /* Dirty hack. We did it in 2.2 (in __dst_free), |
346 | * we have _very_ good reasons not to repeat | 347 | * we have _very_ good reasons not to repeat |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 3e9b2c3e30f0..22efdaa76ebf 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -60,10 +60,13 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] | |||
60 | [NETIF_F_IPV6_CSUM_BIT] = "tx-checksum-ipv6", | 60 | [NETIF_F_IPV6_CSUM_BIT] = "tx-checksum-ipv6", |
61 | [NETIF_F_HIGHDMA_BIT] = "highdma", | 61 | [NETIF_F_HIGHDMA_BIT] = "highdma", |
62 | [NETIF_F_FRAGLIST_BIT] = "tx-scatter-gather-fraglist", | 62 | [NETIF_F_FRAGLIST_BIT] = "tx-scatter-gather-fraglist", |
63 | [NETIF_F_HW_VLAN_TX_BIT] = "tx-vlan-hw-insert", | 63 | [NETIF_F_HW_VLAN_CTAG_TX_BIT] = "tx-vlan-ctag-hw-insert", |
64 | 64 | ||
65 | [NETIF_F_HW_VLAN_RX_BIT] = "rx-vlan-hw-parse", | 65 | [NETIF_F_HW_VLAN_CTAG_RX_BIT] = "rx-vlan-ctag-hw-parse", |
66 | [NETIF_F_HW_VLAN_FILTER_BIT] = "rx-vlan-filter", | 66 | [NETIF_F_HW_VLAN_CTAG_FILTER_BIT] = "rx-vlan-ctag-filter", |
67 | [NETIF_F_HW_VLAN_STAG_TX_BIT] = "tx-vlan-stag-hw-insert", | ||
68 | [NETIF_F_HW_VLAN_STAG_RX_BIT] = "rx-vlan-stag-hw-parse", | ||
69 | [NETIF_F_HW_VLAN_STAG_FILTER_BIT] = "rx-vlan-stag-filter", | ||
67 | [NETIF_F_VLAN_CHALLENGED_BIT] = "vlan-challenged", | 70 | [NETIF_F_VLAN_CHALLENGED_BIT] = "vlan-challenged", |
68 | [NETIF_F_GSO_BIT] = "tx-generic-segmentation", | 71 | [NETIF_F_GSO_BIT] = "tx-generic-segmentation", |
69 | [NETIF_F_LLTX_BIT] = "tx-lockless", | 72 | [NETIF_F_LLTX_BIT] = "tx-lockless", |
@@ -78,6 +81,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] | |||
78 | [NETIF_F_TSO6_BIT] = "tx-tcp6-segmentation", | 81 | [NETIF_F_TSO6_BIT] = "tx-tcp6-segmentation", |
79 | [NETIF_F_FSO_BIT] = "tx-fcoe-segmentation", | 82 | [NETIF_F_FSO_BIT] = "tx-fcoe-segmentation", |
80 | [NETIF_F_GSO_GRE_BIT] = "tx-gre-segmentation", | 83 | [NETIF_F_GSO_GRE_BIT] = "tx-gre-segmentation", |
84 | [NETIF_F_GSO_UDP_TUNNEL_BIT] = "tx-udp_tnl-segmentation", | ||
81 | 85 | ||
82 | [NETIF_F_FCOE_CRC_BIT] = "tx-checksum-fcoe-crc", | 86 | [NETIF_F_FCOE_CRC_BIT] = "tx-checksum-fcoe-crc", |
83 | [NETIF_F_SCTP_CSUM_BIT] = "tx-checksum-sctp", | 87 | [NETIF_F_SCTP_CSUM_BIT] = "tx-checksum-sctp", |
@@ -266,18 +270,19 @@ static int ethtool_set_one_feature(struct net_device *dev, | |||
266 | 270 | ||
267 | #define ETH_ALL_FLAGS (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | \ | 271 | #define ETH_ALL_FLAGS (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | \ |
268 | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH) | 272 | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH) |
269 | #define ETH_ALL_FEATURES (NETIF_F_LRO | NETIF_F_HW_VLAN_RX | \ | 273 | #define ETH_ALL_FEATURES (NETIF_F_LRO | NETIF_F_HW_VLAN_CTAG_RX | \ |
270 | NETIF_F_HW_VLAN_TX | NETIF_F_NTUPLE | NETIF_F_RXHASH) | 274 | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_NTUPLE | \ |
275 | NETIF_F_RXHASH) | ||
271 | 276 | ||
272 | static u32 __ethtool_get_flags(struct net_device *dev) | 277 | static u32 __ethtool_get_flags(struct net_device *dev) |
273 | { | 278 | { |
274 | u32 flags = 0; | 279 | u32 flags = 0; |
275 | 280 | ||
276 | if (dev->features & NETIF_F_LRO) flags |= ETH_FLAG_LRO; | 281 | if (dev->features & NETIF_F_LRO) flags |= ETH_FLAG_LRO; |
277 | if (dev->features & NETIF_F_HW_VLAN_RX) flags |= ETH_FLAG_RXVLAN; | 282 | if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) flags |= ETH_FLAG_RXVLAN; |
278 | if (dev->features & NETIF_F_HW_VLAN_TX) flags |= ETH_FLAG_TXVLAN; | 283 | if (dev->features & NETIF_F_HW_VLAN_CTAG_TX) flags |= ETH_FLAG_TXVLAN; |
279 | if (dev->features & NETIF_F_NTUPLE) flags |= ETH_FLAG_NTUPLE; | 284 | if (dev->features & NETIF_F_NTUPLE) flags |= ETH_FLAG_NTUPLE; |
280 | if (dev->features & NETIF_F_RXHASH) flags |= ETH_FLAG_RXHASH; | 285 | if (dev->features & NETIF_F_RXHASH) flags |= ETH_FLAG_RXHASH; |
281 | 286 | ||
282 | return flags; | 287 | return flags; |
283 | } | 288 | } |
@@ -290,8 +295,8 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data) | |||
290 | return -EINVAL; | 295 | return -EINVAL; |
291 | 296 | ||
292 | if (data & ETH_FLAG_LRO) features |= NETIF_F_LRO; | 297 | if (data & ETH_FLAG_LRO) features |= NETIF_F_LRO; |
293 | if (data & ETH_FLAG_RXVLAN) features |= NETIF_F_HW_VLAN_RX; | 298 | if (data & ETH_FLAG_RXVLAN) features |= NETIF_F_HW_VLAN_CTAG_RX; |
294 | if (data & ETH_FLAG_TXVLAN) features |= NETIF_F_HW_VLAN_TX; | 299 | if (data & ETH_FLAG_TXVLAN) features |= NETIF_F_HW_VLAN_CTAG_TX; |
295 | if (data & ETH_FLAG_NTUPLE) features |= NETIF_F_NTUPLE; | 300 | if (data & ETH_FLAG_NTUPLE) features |= NETIF_F_NTUPLE; |
296 | if (data & ETH_FLAG_RXHASH) features |= NETIF_F_RXHASH; | 301 | if (data & ETH_FLAG_RXHASH) features |= NETIF_F_RXHASH; |
297 | 302 | ||
@@ -1416,7 +1421,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1416 | void __user *useraddr = ifr->ifr_data; | 1421 | void __user *useraddr = ifr->ifr_data; |
1417 | u32 ethcmd; | 1422 | u32 ethcmd; |
1418 | int rc; | 1423 | int rc; |
1419 | u32 old_features; | 1424 | netdev_features_t old_features; |
1420 | 1425 | ||
1421 | if (!dev || !netif_device_present(dev)) | 1426 | if (!dev || !netif_device_present(dev)) |
1422 | return -ENODEV; | 1427 | return -ENODEV; |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 58a4ba27dfe3..d5a9f8ead0d8 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -266,7 +266,7 @@ errout: | |||
266 | return err; | 266 | return err; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 269 | static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh) |
270 | { | 270 | { |
271 | struct net *net = sock_net(skb->sk); | 271 | struct net *net = sock_net(skb->sk); |
272 | struct fib_rule_hdr *frh = nlmsg_data(nlh); | 272 | struct fib_rule_hdr *frh = nlmsg_data(nlh); |
@@ -415,7 +415,7 @@ errout: | |||
415 | return err; | 415 | return err; |
416 | } | 416 | } |
417 | 417 | ||
418 | static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 418 | static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh) |
419 | { | 419 | { |
420 | struct net *net = sock_net(skb->sk); | 420 | struct net *net = sock_net(skb->sk); |
421 | struct fib_rule_hdr *frh = nlmsg_data(nlh); | 421 | struct fib_rule_hdr *frh = nlmsg_data(nlh); |
diff --git a/net/core/filter.c b/net/core/filter.c index 2e20b55a7830..dad2a178f9f8 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -348,6 +348,9 @@ load_b: | |||
348 | case BPF_S_ANC_VLAN_TAG_PRESENT: | 348 | case BPF_S_ANC_VLAN_TAG_PRESENT: |
349 | A = !!vlan_tx_tag_present(skb); | 349 | A = !!vlan_tx_tag_present(skb); |
350 | continue; | 350 | continue; |
351 | case BPF_S_ANC_PAY_OFFSET: | ||
352 | A = __skb_get_poff(skb); | ||
353 | continue; | ||
351 | case BPF_S_ANC_NLATTR: { | 354 | case BPF_S_ANC_NLATTR: { |
352 | struct nlattr *nla; | 355 | struct nlattr *nla; |
353 | 356 | ||
@@ -612,6 +615,7 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen) | |||
612 | ANCILLARY(ALU_XOR_X); | 615 | ANCILLARY(ALU_XOR_X); |
613 | ANCILLARY(VLAN_TAG); | 616 | ANCILLARY(VLAN_TAG); |
614 | ANCILLARY(VLAN_TAG_PRESENT); | 617 | ANCILLARY(VLAN_TAG_PRESENT); |
618 | ANCILLARY(PAY_OFFSET); | ||
615 | } | 619 | } |
616 | 620 | ||
617 | /* ancillary operation unknown or unsupported */ | 621 | /* ancillary operation unknown or unsupported */ |
@@ -814,6 +818,7 @@ static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) | |||
814 | [BPF_S_ANC_SECCOMP_LD_W] = BPF_LD|BPF_B|BPF_ABS, | 818 | [BPF_S_ANC_SECCOMP_LD_W] = BPF_LD|BPF_B|BPF_ABS, |
815 | [BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS, | 819 | [BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS, |
816 | [BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS, | 820 | [BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS, |
821 | [BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS, | ||
817 | [BPF_S_LD_W_LEN] = BPF_LD|BPF_W|BPF_LEN, | 822 | [BPF_S_LD_W_LEN] = BPF_LD|BPF_W|BPF_LEN, |
818 | [BPF_S_LD_W_IND] = BPF_LD|BPF_W|BPF_IND, | 823 | [BPF_S_LD_W_IND] = BPF_LD|BPF_W|BPF_IND, |
819 | [BPF_S_LD_H_IND] = BPF_LD|BPF_H|BPF_IND, | 824 | [BPF_S_LD_H_IND] = BPF_LD|BPF_H|BPF_IND, |
diff --git a/net/core/flow.c b/net/core/flow.c index 2bfd081c59f7..7102f166482d 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -323,6 +323,24 @@ static void flow_cache_flush_tasklet(unsigned long data) | |||
323 | complete(&info->completion); | 323 | complete(&info->completion); |
324 | } | 324 | } |
325 | 325 | ||
326 | /* | ||
327 | * Return whether a cpu needs flushing. Conservatively, we assume | ||
328 | * the presence of any entries means the core may require flushing, | ||
329 | * since the flow_cache_ops.check() function may assume it's running | ||
330 | * on the same core as the per-cpu cache component. | ||
331 | */ | ||
332 | static int flow_cache_percpu_empty(struct flow_cache *fc, int cpu) | ||
333 | { | ||
334 | struct flow_cache_percpu *fcp; | ||
335 | int i; | ||
336 | |||
337 | fcp = per_cpu_ptr(fc->percpu, cpu); | ||
338 | for (i = 0; i < flow_cache_hash_size(fc); i++) | ||
339 | if (!hlist_empty(&fcp->hash_table[i])) | ||
340 | return 0; | ||
341 | return 1; | ||
342 | } | ||
343 | |||
326 | static void flow_cache_flush_per_cpu(void *data) | 344 | static void flow_cache_flush_per_cpu(void *data) |
327 | { | 345 | { |
328 | struct flow_flush_info *info = data; | 346 | struct flow_flush_info *info = data; |
@@ -337,22 +355,40 @@ void flow_cache_flush(void) | |||
337 | { | 355 | { |
338 | struct flow_flush_info info; | 356 | struct flow_flush_info info; |
339 | static DEFINE_MUTEX(flow_flush_sem); | 357 | static DEFINE_MUTEX(flow_flush_sem); |
358 | cpumask_var_t mask; | ||
359 | int i, self; | ||
360 | |||
361 | /* Track which cpus need flushing to avoid disturbing all cores. */ | ||
362 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | ||
363 | return; | ||
364 | cpumask_clear(mask); | ||
340 | 365 | ||
341 | /* Don't want cpus going down or up during this. */ | 366 | /* Don't want cpus going down or up during this. */ |
342 | get_online_cpus(); | 367 | get_online_cpus(); |
343 | mutex_lock(&flow_flush_sem); | 368 | mutex_lock(&flow_flush_sem); |
344 | info.cache = &flow_cache_global; | 369 | info.cache = &flow_cache_global; |
345 | atomic_set(&info.cpuleft, num_online_cpus()); | 370 | for_each_online_cpu(i) |
371 | if (!flow_cache_percpu_empty(info.cache, i)) | ||
372 | cpumask_set_cpu(i, mask); | ||
373 | atomic_set(&info.cpuleft, cpumask_weight(mask)); | ||
374 | if (atomic_read(&info.cpuleft) == 0) | ||
375 | goto done; | ||
376 | |||
346 | init_completion(&info.completion); | 377 | init_completion(&info.completion); |
347 | 378 | ||
348 | local_bh_disable(); | 379 | local_bh_disable(); |
349 | smp_call_function(flow_cache_flush_per_cpu, &info, 0); | 380 | self = cpumask_test_and_clear_cpu(smp_processor_id(), mask); |
350 | flow_cache_flush_tasklet((unsigned long)&info); | 381 | on_each_cpu_mask(mask, flow_cache_flush_per_cpu, &info, 0); |
382 | if (self) | ||
383 | flow_cache_flush_tasklet((unsigned long)&info); | ||
351 | local_bh_enable(); | 384 | local_bh_enable(); |
352 | 385 | ||
353 | wait_for_completion(&info.completion); | 386 | wait_for_completion(&info.completion); |
387 | |||
388 | done: | ||
354 | mutex_unlock(&flow_flush_sem); | 389 | mutex_unlock(&flow_flush_sem); |
355 | put_online_cpus(); | 390 | put_online_cpus(); |
391 | free_cpumask_var(mask); | ||
356 | } | 392 | } |
357 | 393 | ||
358 | static void flow_cache_flush_task(struct work_struct *work) | 394 | static void flow_cache_flush_task(struct work_struct *work) |
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index e187bf06d673..00ee068efc1c 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
@@ -5,6 +5,10 @@ | |||
5 | #include <linux/if_vlan.h> | 5 | #include <linux/if_vlan.h> |
6 | #include <net/ip.h> | 6 | #include <net/ip.h> |
7 | #include <net/ipv6.h> | 7 | #include <net/ipv6.h> |
8 | #include <linux/igmp.h> | ||
9 | #include <linux/icmp.h> | ||
10 | #include <linux/sctp.h> | ||
11 | #include <linux/dccp.h> | ||
8 | #include <linux/if_tunnel.h> | 12 | #include <linux/if_tunnel.h> |
9 | #include <linux/if_pppox.h> | 13 | #include <linux/if_pppox.h> |
10 | #include <linux/ppp_defs.h> | 14 | #include <linux/ppp_defs.h> |
@@ -119,6 +123,17 @@ ipv6: | |||
119 | nhoff += 4; | 123 | nhoff += 4; |
120 | if (hdr->flags & GRE_SEQ) | 124 | if (hdr->flags & GRE_SEQ) |
121 | nhoff += 4; | 125 | nhoff += 4; |
126 | if (proto == htons(ETH_P_TEB)) { | ||
127 | const struct ethhdr *eth; | ||
128 | struct ethhdr _eth; | ||
129 | |||
130 | eth = skb_header_pointer(skb, nhoff, | ||
131 | sizeof(_eth), &_eth); | ||
132 | if (!eth) | ||
133 | return false; | ||
134 | proto = eth->h_proto; | ||
135 | nhoff += sizeof(*eth); | ||
136 | } | ||
122 | goto again; | 137 | goto again; |
123 | } | 138 | } |
124 | break; | 139 | break; |
@@ -217,6 +232,59 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, | |||
217 | } | 232 | } |
218 | EXPORT_SYMBOL(__skb_tx_hash); | 233 | EXPORT_SYMBOL(__skb_tx_hash); |
219 | 234 | ||
235 | /* __skb_get_poff() returns the offset to the payload as far as it could | ||
236 | * be dissected. The main user is currently BPF, so that we can dynamically | ||
237 | * truncate packets without needing to push actual payload to the user | ||
238 | * space and can analyze headers only, instead. | ||
239 | */ | ||
240 | u32 __skb_get_poff(const struct sk_buff *skb) | ||
241 | { | ||
242 | struct flow_keys keys; | ||
243 | u32 poff = 0; | ||
244 | |||
245 | if (!skb_flow_dissect(skb, &keys)) | ||
246 | return 0; | ||
247 | |||
248 | poff += keys.thoff; | ||
249 | switch (keys.ip_proto) { | ||
250 | case IPPROTO_TCP: { | ||
251 | const struct tcphdr *tcph; | ||
252 | struct tcphdr _tcph; | ||
253 | |||
254 | tcph = skb_header_pointer(skb, poff, sizeof(_tcph), &_tcph); | ||
255 | if (!tcph) | ||
256 | return poff; | ||
257 | |||
258 | poff += max_t(u32, sizeof(struct tcphdr), tcph->doff * 4); | ||
259 | break; | ||
260 | } | ||
261 | case IPPROTO_UDP: | ||
262 | case IPPROTO_UDPLITE: | ||
263 | poff += sizeof(struct udphdr); | ||
264 | break; | ||
265 | /* For the rest, we do not really care about header | ||
266 | * extensions at this point for now. | ||
267 | */ | ||
268 | case IPPROTO_ICMP: | ||
269 | poff += sizeof(struct icmphdr); | ||
270 | break; | ||
271 | case IPPROTO_ICMPV6: | ||
272 | poff += sizeof(struct icmp6hdr); | ||
273 | break; | ||
274 | case IPPROTO_IGMP: | ||
275 | poff += sizeof(struct igmphdr); | ||
276 | break; | ||
277 | case IPPROTO_DCCP: | ||
278 | poff += sizeof(struct dccp_hdr); | ||
279 | break; | ||
280 | case IPPROTO_SCTP: | ||
281 | poff += sizeof(struct sctphdr); | ||
282 | break; | ||
283 | } | ||
284 | |||
285 | return poff; | ||
286 | } | ||
287 | |||
220 | static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) | 288 | static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) |
221 | { | 289 | { |
222 | if (unlikely(queue_index >= dev->real_num_tx_queues)) { | 290 | if (unlikely(queue_index >= dev->real_num_tx_queues)) { |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 3863b8f639c5..5c56b217b999 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -39,21 +39,13 @@ | |||
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/log2.h> | 40 | #include <linux/log2.h> |
41 | 41 | ||
42 | #define DEBUG | ||
42 | #define NEIGH_DEBUG 1 | 43 | #define NEIGH_DEBUG 1 |
43 | 44 | #define neigh_dbg(level, fmt, ...) \ | |
44 | #define NEIGH_PRINTK(x...) printk(x) | 45 | do { \ |
45 | #define NEIGH_NOPRINTK(x...) do { ; } while(0) | 46 | if (level <= NEIGH_DEBUG) \ |
46 | #define NEIGH_PRINTK1 NEIGH_NOPRINTK | 47 | pr_debug(fmt, ##__VA_ARGS__); \ |
47 | #define NEIGH_PRINTK2 NEIGH_NOPRINTK | 48 | } while (0) |
48 | |||
49 | #if NEIGH_DEBUG >= 1 | ||
50 | #undef NEIGH_PRINTK1 | ||
51 | #define NEIGH_PRINTK1 NEIGH_PRINTK | ||
52 | #endif | ||
53 | #if NEIGH_DEBUG >= 2 | ||
54 | #undef NEIGH_PRINTK2 | ||
55 | #define NEIGH_PRINTK2 NEIGH_PRINTK | ||
56 | #endif | ||
57 | 49 | ||
58 | #define PNEIGH_HASHMASK 0xF | 50 | #define PNEIGH_HASHMASK 0xF |
59 | 51 | ||
@@ -246,7 +238,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) | |||
246 | n->nud_state = NUD_NOARP; | 238 | n->nud_state = NUD_NOARP; |
247 | else | 239 | else |
248 | n->nud_state = NUD_NONE; | 240 | n->nud_state = NUD_NONE; |
249 | NEIGH_PRINTK2("neigh %p is stray.\n", n); | 241 | neigh_dbg(2, "neigh %p is stray\n", n); |
250 | } | 242 | } |
251 | write_unlock(&n->lock); | 243 | write_unlock(&n->lock); |
252 | neigh_cleanup_and_release(n); | 244 | neigh_cleanup_and_release(n); |
@@ -542,7 +534,7 @@ struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey, | |||
542 | lockdep_is_held(&tbl->lock))); | 534 | lockdep_is_held(&tbl->lock))); |
543 | rcu_assign_pointer(nht->hash_buckets[hash_val], n); | 535 | rcu_assign_pointer(nht->hash_buckets[hash_val], n); |
544 | write_unlock_bh(&tbl->lock); | 536 | write_unlock_bh(&tbl->lock); |
545 | NEIGH_PRINTK2("neigh %p is created.\n", n); | 537 | neigh_dbg(2, "neigh %p is created\n", n); |
546 | rc = n; | 538 | rc = n; |
547 | out: | 539 | out: |
548 | return rc; | 540 | return rc; |
@@ -725,7 +717,7 @@ void neigh_destroy(struct neighbour *neigh) | |||
725 | dev_put(dev); | 717 | dev_put(dev); |
726 | neigh_parms_put(neigh->parms); | 718 | neigh_parms_put(neigh->parms); |
727 | 719 | ||
728 | NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh); | 720 | neigh_dbg(2, "neigh %p is destroyed\n", neigh); |
729 | 721 | ||
730 | atomic_dec(&neigh->tbl->entries); | 722 | atomic_dec(&neigh->tbl->entries); |
731 | kfree_rcu(neigh, rcu); | 723 | kfree_rcu(neigh, rcu); |
@@ -739,7 +731,7 @@ EXPORT_SYMBOL(neigh_destroy); | |||
739 | */ | 731 | */ |
740 | static void neigh_suspect(struct neighbour *neigh) | 732 | static void neigh_suspect(struct neighbour *neigh) |
741 | { | 733 | { |
742 | NEIGH_PRINTK2("neigh %p is suspected.\n", neigh); | 734 | neigh_dbg(2, "neigh %p is suspected\n", neigh); |
743 | 735 | ||
744 | neigh->output = neigh->ops->output; | 736 | neigh->output = neigh->ops->output; |
745 | } | 737 | } |
@@ -751,7 +743,7 @@ static void neigh_suspect(struct neighbour *neigh) | |||
751 | */ | 743 | */ |
752 | static void neigh_connect(struct neighbour *neigh) | 744 | static void neigh_connect(struct neighbour *neigh) |
753 | { | 745 | { |
754 | NEIGH_PRINTK2("neigh %p is connected.\n", neigh); | 746 | neigh_dbg(2, "neigh %p is connected\n", neigh); |
755 | 747 | ||
756 | neigh->output = neigh->ops->connected_output; | 748 | neigh->output = neigh->ops->connected_output; |
757 | } | 749 | } |
@@ -852,7 +844,7 @@ static void neigh_invalidate(struct neighbour *neigh) | |||
852 | struct sk_buff *skb; | 844 | struct sk_buff *skb; |
853 | 845 | ||
854 | NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); | 846 | NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); |
855 | NEIGH_PRINTK2("neigh %p is failed.\n", neigh); | 847 | neigh_dbg(2, "neigh %p is failed\n", neigh); |
856 | neigh->updated = jiffies; | 848 | neigh->updated = jiffies; |
857 | 849 | ||
858 | /* It is very thin place. report_unreachable is very complicated | 850 | /* It is very thin place. report_unreachable is very complicated |
@@ -904,17 +896,17 @@ static void neigh_timer_handler(unsigned long arg) | |||
904 | if (state & NUD_REACHABLE) { | 896 | if (state & NUD_REACHABLE) { |
905 | if (time_before_eq(now, | 897 | if (time_before_eq(now, |
906 | neigh->confirmed + neigh->parms->reachable_time)) { | 898 | neigh->confirmed + neigh->parms->reachable_time)) { |
907 | NEIGH_PRINTK2("neigh %p is still alive.\n", neigh); | 899 | neigh_dbg(2, "neigh %p is still alive\n", neigh); |
908 | next = neigh->confirmed + neigh->parms->reachable_time; | 900 | next = neigh->confirmed + neigh->parms->reachable_time; |
909 | } else if (time_before_eq(now, | 901 | } else if (time_before_eq(now, |
910 | neigh->used + neigh->parms->delay_probe_time)) { | 902 | neigh->used + neigh->parms->delay_probe_time)) { |
911 | NEIGH_PRINTK2("neigh %p is delayed.\n", neigh); | 903 | neigh_dbg(2, "neigh %p is delayed\n", neigh); |
912 | neigh->nud_state = NUD_DELAY; | 904 | neigh->nud_state = NUD_DELAY; |
913 | neigh->updated = jiffies; | 905 | neigh->updated = jiffies; |
914 | neigh_suspect(neigh); | 906 | neigh_suspect(neigh); |
915 | next = now + neigh->parms->delay_probe_time; | 907 | next = now + neigh->parms->delay_probe_time; |
916 | } else { | 908 | } else { |
917 | NEIGH_PRINTK2("neigh %p is suspected.\n", neigh); | 909 | neigh_dbg(2, "neigh %p is suspected\n", neigh); |
918 | neigh->nud_state = NUD_STALE; | 910 | neigh->nud_state = NUD_STALE; |
919 | neigh->updated = jiffies; | 911 | neigh->updated = jiffies; |
920 | neigh_suspect(neigh); | 912 | neigh_suspect(neigh); |
@@ -923,14 +915,14 @@ static void neigh_timer_handler(unsigned long arg) | |||
923 | } else if (state & NUD_DELAY) { | 915 | } else if (state & NUD_DELAY) { |
924 | if (time_before_eq(now, | 916 | if (time_before_eq(now, |
925 | neigh->confirmed + neigh->parms->delay_probe_time)) { | 917 | neigh->confirmed + neigh->parms->delay_probe_time)) { |
926 | NEIGH_PRINTK2("neigh %p is now reachable.\n", neigh); | 918 | neigh_dbg(2, "neigh %p is now reachable\n", neigh); |
927 | neigh->nud_state = NUD_REACHABLE; | 919 | neigh->nud_state = NUD_REACHABLE; |
928 | neigh->updated = jiffies; | 920 | neigh->updated = jiffies; |
929 | neigh_connect(neigh); | 921 | neigh_connect(neigh); |
930 | notify = 1; | 922 | notify = 1; |
931 | next = neigh->confirmed + neigh->parms->reachable_time; | 923 | next = neigh->confirmed + neigh->parms->reachable_time; |
932 | } else { | 924 | } else { |
933 | NEIGH_PRINTK2("neigh %p is probed.\n", neigh); | 925 | neigh_dbg(2, "neigh %p is probed\n", neigh); |
934 | neigh->nud_state = NUD_PROBE; | 926 | neigh->nud_state = NUD_PROBE; |
935 | neigh->updated = jiffies; | 927 | neigh->updated = jiffies; |
936 | atomic_set(&neigh->probes, 0); | 928 | atomic_set(&neigh->probes, 0); |
@@ -997,7 +989,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | |||
997 | return 1; | 989 | return 1; |
998 | } | 990 | } |
999 | } else if (neigh->nud_state & NUD_STALE) { | 991 | } else if (neigh->nud_state & NUD_STALE) { |
1000 | NEIGH_PRINTK2("neigh %p is delayed.\n", neigh); | 992 | neigh_dbg(2, "neigh %p is delayed\n", neigh); |
1001 | neigh->nud_state = NUD_DELAY; | 993 | neigh->nud_state = NUD_DELAY; |
1002 | neigh->updated = jiffies; | 994 | neigh->updated = jiffies; |
1003 | neigh_add_timer(neigh, | 995 | neigh_add_timer(neigh, |
@@ -1320,8 +1312,7 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) | |||
1320 | out: | 1312 | out: |
1321 | return rc; | 1313 | return rc; |
1322 | discard: | 1314 | discard: |
1323 | NEIGH_PRINTK1("neigh_resolve_output: dst=%p neigh=%p\n", | 1315 | neigh_dbg(1, "%s: dst=%p neigh=%p\n", __func__, dst, neigh); |
1324 | dst, neigh); | ||
1325 | out_kfree_skb: | 1316 | out_kfree_skb: |
1326 | rc = -EINVAL; | 1317 | rc = -EINVAL; |
1327 | kfree_skb(skb); | 1318 | kfree_skb(skb); |
@@ -1498,7 +1489,7 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) | |||
1498 | } | 1489 | } |
1499 | } | 1490 | } |
1500 | write_unlock_bh(&tbl->lock); | 1491 | write_unlock_bh(&tbl->lock); |
1501 | NEIGH_PRINTK1("neigh_parms_release: not found\n"); | 1492 | neigh_dbg(1, "%s: not found\n", __func__); |
1502 | } | 1493 | } |
1503 | EXPORT_SYMBOL(neigh_parms_release); | 1494 | EXPORT_SYMBOL(neigh_parms_release); |
1504 | 1495 | ||
@@ -1613,7 +1604,7 @@ int neigh_table_clear(struct neigh_table *tbl) | |||
1613 | } | 1604 | } |
1614 | EXPORT_SYMBOL(neigh_table_clear); | 1605 | EXPORT_SYMBOL(neigh_table_clear); |
1615 | 1606 | ||
1616 | static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1607 | static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh) |
1617 | { | 1608 | { |
1618 | struct net *net = sock_net(skb->sk); | 1609 | struct net *net = sock_net(skb->sk); |
1619 | struct ndmsg *ndm; | 1610 | struct ndmsg *ndm; |
@@ -1677,7 +1668,7 @@ out: | |||
1677 | return err; | 1668 | return err; |
1678 | } | 1669 | } |
1679 | 1670 | ||
1680 | static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1671 | static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh) |
1681 | { | 1672 | { |
1682 | struct net *net = sock_net(skb->sk); | 1673 | struct net *net = sock_net(skb->sk); |
1683 | struct ndmsg *ndm; | 1674 | struct ndmsg *ndm; |
@@ -1955,7 +1946,7 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { | |||
1955 | [NDTPA_LOCKTIME] = { .type = NLA_U64 }, | 1946 | [NDTPA_LOCKTIME] = { .type = NLA_U64 }, |
1956 | }; | 1947 | }; |
1957 | 1948 | ||
1958 | static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1949 | static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh) |
1959 | { | 1950 | { |
1960 | struct net *net = sock_net(skb->sk); | 1951 | struct net *net = sock_net(skb->sk); |
1961 | struct neigh_table *tbl; | 1952 | struct neigh_table *tbl; |
@@ -2714,7 +2705,7 @@ static int neigh_stat_seq_open(struct inode *inode, struct file *file) | |||
2714 | 2705 | ||
2715 | if (!ret) { | 2706 | if (!ret) { |
2716 | struct seq_file *sf = file->private_data; | 2707 | struct seq_file *sf = file->private_data; |
2717 | sf->private = PDE(inode)->data; | 2708 | sf->private = PDE_DATA(inode); |
2718 | } | 2709 | } |
2719 | return ret; | 2710 | return ret; |
2720 | }; | 2711 | }; |
diff --git a/net/core/net-procfs.c b/net/core/net-procfs.c index 3174f1998ee6..569d355fec3e 100644 --- a/net/core/net-procfs.c +++ b/net/core/net-procfs.c | |||
@@ -271,7 +271,7 @@ static int ptype_seq_show(struct seq_file *seq, void *v) | |||
271 | else | 271 | else |
272 | seq_printf(seq, "%04x", ntohs(pt->type)); | 272 | seq_printf(seq, "%04x", ntohs(pt->type)); |
273 | 273 | ||
274 | seq_printf(seq, " %-8s %pF\n", | 274 | seq_printf(seq, " %-8s %pf\n", |
275 | pt->dev ? pt->dev->name : "", pt->func); | 275 | pt->dev ? pt->dev->name : "", pt->func); |
276 | } | 276 | } |
277 | 277 | ||
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 80e271d9e64b..f97652036754 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -10,7 +10,8 @@ | |||
10 | #include <linux/idr.h> | 10 | #include <linux/idr.h> |
11 | #include <linux/rculist.h> | 11 | #include <linux/rculist.h> |
12 | #include <linux/nsproxy.h> | 12 | #include <linux/nsproxy.h> |
13 | #include <linux/proc_fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/proc_ns.h> | ||
14 | #include <linux/file.h> | 15 | #include <linux/file.h> |
15 | #include <linux/export.h> | 16 | #include <linux/export.h> |
16 | #include <linux/user_namespace.h> | 17 | #include <linux/user_namespace.h> |
@@ -336,7 +337,7 @@ EXPORT_SYMBOL_GPL(__put_net); | |||
336 | 337 | ||
337 | struct net *get_net_ns_by_fd(int fd) | 338 | struct net *get_net_ns_by_fd(int fd) |
338 | { | 339 | { |
339 | struct proc_inode *ei; | 340 | struct proc_ns *ei; |
340 | struct file *file; | 341 | struct file *file; |
341 | struct net *net; | 342 | struct net *net; |
342 | 343 | ||
@@ -344,7 +345,7 @@ struct net *get_net_ns_by_fd(int fd) | |||
344 | if (IS_ERR(file)) | 345 | if (IS_ERR(file)) |
345 | return ERR_CAST(file); | 346 | return ERR_CAST(file); |
346 | 347 | ||
347 | ei = PROC_I(file_inode(file)); | 348 | ei = get_proc_ns(file_inode(file)); |
348 | if (ei->ns_ops == &netns_operations) | 349 | if (ei->ns_ops == &netns_operations) |
349 | net = get_net(ei->ns); | 350 | net = get_net(ei->ns); |
350 | else | 351 | else |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index fa32899006a2..a5802a8b652f 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -47,7 +47,7 @@ static struct sk_buff_head skb_pool; | |||
47 | 47 | ||
48 | static atomic_t trapped; | 48 | static atomic_t trapped; |
49 | 49 | ||
50 | static struct srcu_struct netpoll_srcu; | 50 | DEFINE_STATIC_SRCU(netpoll_srcu); |
51 | 51 | ||
52 | #define USEC_PER_POLL 50 | 52 | #define USEC_PER_POLL 50 |
53 | #define NETPOLL_RX_ENABLED 1 | 53 | #define NETPOLL_RX_ENABLED 1 |
@@ -206,17 +206,17 @@ static void netpoll_poll_dev(struct net_device *dev) | |||
206 | * the dev_open/close paths use this to block netpoll activity | 206 | * the dev_open/close paths use this to block netpoll activity |
207 | * while changing device state | 207 | * while changing device state |
208 | */ | 208 | */ |
209 | if (!mutex_trylock(&ni->dev_lock)) | 209 | if (!down_trylock(&ni->dev_lock)) |
210 | return; | 210 | return; |
211 | 211 | ||
212 | if (!netif_running(dev)) { | 212 | if (!netif_running(dev)) { |
213 | mutex_unlock(&ni->dev_lock); | 213 | up(&ni->dev_lock); |
214 | return; | 214 | return; |
215 | } | 215 | } |
216 | 216 | ||
217 | ops = dev->netdev_ops; | 217 | ops = dev->netdev_ops; |
218 | if (!ops->ndo_poll_controller) { | 218 | if (!ops->ndo_poll_controller) { |
219 | mutex_unlock(&ni->dev_lock); | 219 | up(&ni->dev_lock); |
220 | return; | 220 | return; |
221 | } | 221 | } |
222 | 222 | ||
@@ -225,7 +225,7 @@ static void netpoll_poll_dev(struct net_device *dev) | |||
225 | 225 | ||
226 | poll_napi(dev); | 226 | poll_napi(dev); |
227 | 227 | ||
228 | mutex_unlock(&ni->dev_lock); | 228 | up(&ni->dev_lock); |
229 | 229 | ||
230 | if (dev->flags & IFF_SLAVE) { | 230 | if (dev->flags & IFF_SLAVE) { |
231 | if (ni) { | 231 | if (ni) { |
@@ -255,7 +255,7 @@ int netpoll_rx_disable(struct net_device *dev) | |||
255 | idx = srcu_read_lock(&netpoll_srcu); | 255 | idx = srcu_read_lock(&netpoll_srcu); |
256 | ni = srcu_dereference(dev->npinfo, &netpoll_srcu); | 256 | ni = srcu_dereference(dev->npinfo, &netpoll_srcu); |
257 | if (ni) | 257 | if (ni) |
258 | mutex_lock(&ni->dev_lock); | 258 | down(&ni->dev_lock); |
259 | srcu_read_unlock(&netpoll_srcu, idx); | 259 | srcu_read_unlock(&netpoll_srcu, idx); |
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
@@ -267,7 +267,7 @@ void netpoll_rx_enable(struct net_device *dev) | |||
267 | rcu_read_lock(); | 267 | rcu_read_lock(); |
268 | ni = rcu_dereference(dev->npinfo); | 268 | ni = rcu_dereference(dev->npinfo); |
269 | if (ni) | 269 | if (ni) |
270 | mutex_unlock(&ni->dev_lock); | 270 | up(&ni->dev_lock); |
271 | rcu_read_unlock(); | 271 | rcu_read_unlock(); |
272 | } | 272 | } |
273 | EXPORT_SYMBOL(netpoll_rx_enable); | 273 | EXPORT_SYMBOL(netpoll_rx_enable); |
@@ -383,8 +383,9 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
383 | if (__netif_tx_trylock(txq)) { | 383 | if (__netif_tx_trylock(txq)) { |
384 | if (!netif_xmit_stopped(txq)) { | 384 | if (!netif_xmit_stopped(txq)) { |
385 | if (vlan_tx_tag_present(skb) && | 385 | if (vlan_tx_tag_present(skb) && |
386 | !(netif_skb_features(skb) & NETIF_F_HW_VLAN_TX)) { | 386 | !vlan_hw_offload_capable(netif_skb_features(skb), |
387 | skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); | 387 | skb->vlan_proto)) { |
388 | skb = __vlan_put_tag(skb, skb->vlan_proto, vlan_tx_tag_get(skb)); | ||
388 | if (unlikely(!skb)) | 389 | if (unlikely(!skb)) |
389 | break; | 390 | break; |
390 | skb->vlan_tci = 0; | 391 | skb->vlan_tci = 0; |
@@ -1046,7 +1047,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp) | |||
1046 | INIT_LIST_HEAD(&npinfo->rx_np); | 1047 | INIT_LIST_HEAD(&npinfo->rx_np); |
1047 | 1048 | ||
1048 | spin_lock_init(&npinfo->rx_lock); | 1049 | spin_lock_init(&npinfo->rx_lock); |
1049 | mutex_init(&npinfo->dev_lock); | 1050 | sema_init(&npinfo->dev_lock, 1); |
1050 | skb_queue_head_init(&npinfo->neigh_tx); | 1051 | skb_queue_head_init(&npinfo->neigh_tx); |
1051 | skb_queue_head_init(&npinfo->txq); | 1052 | skb_queue_head_init(&npinfo->txq); |
1052 | INIT_DELAYED_WORK(&npinfo->tx_work, queue_process); | 1053 | INIT_DELAYED_WORK(&npinfo->tx_work, queue_process); |
@@ -1212,7 +1213,6 @@ EXPORT_SYMBOL(netpoll_setup); | |||
1212 | static int __init netpoll_init(void) | 1213 | static int __init netpoll_init(void) |
1213 | { | 1214 | { |
1214 | skb_queue_head_init(&skb_pool); | 1215 | skb_queue_head_init(&skb_pool); |
1215 | init_srcu_struct(&netpoll_srcu); | ||
1216 | return 0; | 1216 | return 0; |
1217 | } | 1217 | } |
1218 | core_initcall(netpoll_init); | 1218 | core_initcall(netpoll_init); |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 6048fc1da1c2..11f2704c3810 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -508,7 +508,7 @@ out: | |||
508 | 508 | ||
509 | static int pgctrl_open(struct inode *inode, struct file *file) | 509 | static int pgctrl_open(struct inode *inode, struct file *file) |
510 | { | 510 | { |
511 | return single_open(file, pgctrl_show, PDE(inode)->data); | 511 | return single_open(file, pgctrl_show, PDE_DATA(inode)); |
512 | } | 512 | } |
513 | 513 | ||
514 | static const struct file_operations pktgen_fops = { | 514 | static const struct file_operations pktgen_fops = { |
@@ -1685,7 +1685,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1685 | 1685 | ||
1686 | static int pktgen_if_open(struct inode *inode, struct file *file) | 1686 | static int pktgen_if_open(struct inode *inode, struct file *file) |
1687 | { | 1687 | { |
1688 | return single_open(file, pktgen_if_show, PDE(inode)->data); | 1688 | return single_open(file, pktgen_if_show, PDE_DATA(inode)); |
1689 | } | 1689 | } |
1690 | 1690 | ||
1691 | static const struct file_operations pktgen_if_fops = { | 1691 | static const struct file_operations pktgen_if_fops = { |
@@ -1823,7 +1823,7 @@ out: | |||
1823 | 1823 | ||
1824 | static int pktgen_thread_open(struct inode *inode, struct file *file) | 1824 | static int pktgen_thread_open(struct inode *inode, struct file *file) |
1825 | { | 1825 | { |
1826 | return single_open(file, pktgen_thread_show, PDE(inode)->data); | 1826 | return single_open(file, pktgen_thread_show, PDE_DATA(inode)); |
1827 | } | 1827 | } |
1828 | 1828 | ||
1829 | static const struct file_operations pktgen_thread_fops = { | 1829 | static const struct file_operations pktgen_thread_fops = { |
@@ -1904,7 +1904,7 @@ static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *d | |||
1904 | if (pkt_dev->odev != dev) | 1904 | if (pkt_dev->odev != dev) |
1905 | continue; | 1905 | continue; |
1906 | 1906 | ||
1907 | remove_proc_entry(pkt_dev->entry->name, pn->proc_dir); | 1907 | proc_remove(pkt_dev->entry); |
1908 | 1908 | ||
1909 | pkt_dev->entry = proc_create_data(dev->name, 0600, | 1909 | pkt_dev->entry = proc_create_data(dev->name, 0600, |
1910 | pn->proc_dir, | 1910 | pn->proc_dir, |
@@ -2198,7 +2198,7 @@ static inline int f_pick(struct pktgen_dev *pkt_dev) | |||
2198 | pkt_dev->curfl = 0; /*reset */ | 2198 | pkt_dev->curfl = 0; /*reset */ |
2199 | } | 2199 | } |
2200 | } else { | 2200 | } else { |
2201 | flow = random32() % pkt_dev->cflows; | 2201 | flow = prandom_u32() % pkt_dev->cflows; |
2202 | pkt_dev->curfl = flow; | 2202 | pkt_dev->curfl = flow; |
2203 | 2203 | ||
2204 | if (pkt_dev->flows[flow].count > pkt_dev->lflow) { | 2204 | if (pkt_dev->flows[flow].count > pkt_dev->lflow) { |
@@ -2246,7 +2246,7 @@ static void set_cur_queue_map(struct pktgen_dev *pkt_dev) | |||
2246 | else if (pkt_dev->queue_map_min <= pkt_dev->queue_map_max) { | 2246 | else if (pkt_dev->queue_map_min <= pkt_dev->queue_map_max) { |
2247 | __u16 t; | 2247 | __u16 t; |
2248 | if (pkt_dev->flags & F_QUEUE_MAP_RND) { | 2248 | if (pkt_dev->flags & F_QUEUE_MAP_RND) { |
2249 | t = random32() % | 2249 | t = prandom_u32() % |
2250 | (pkt_dev->queue_map_max - | 2250 | (pkt_dev->queue_map_max - |
2251 | pkt_dev->queue_map_min + 1) | 2251 | pkt_dev->queue_map_min + 1) |
2252 | + pkt_dev->queue_map_min; | 2252 | + pkt_dev->queue_map_min; |
@@ -2278,7 +2278,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2278 | __u32 tmp; | 2278 | __u32 tmp; |
2279 | 2279 | ||
2280 | if (pkt_dev->flags & F_MACSRC_RND) | 2280 | if (pkt_dev->flags & F_MACSRC_RND) |
2281 | mc = random32() % pkt_dev->src_mac_count; | 2281 | mc = prandom_u32() % pkt_dev->src_mac_count; |
2282 | else { | 2282 | else { |
2283 | mc = pkt_dev->cur_src_mac_offset++; | 2283 | mc = pkt_dev->cur_src_mac_offset++; |
2284 | if (pkt_dev->cur_src_mac_offset >= | 2284 | if (pkt_dev->cur_src_mac_offset >= |
@@ -2304,7 +2304,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2304 | __u32 tmp; | 2304 | __u32 tmp; |
2305 | 2305 | ||
2306 | if (pkt_dev->flags & F_MACDST_RND) | 2306 | if (pkt_dev->flags & F_MACDST_RND) |
2307 | mc = random32() % pkt_dev->dst_mac_count; | 2307 | mc = prandom_u32() % pkt_dev->dst_mac_count; |
2308 | 2308 | ||
2309 | else { | 2309 | else { |
2310 | mc = pkt_dev->cur_dst_mac_offset++; | 2310 | mc = pkt_dev->cur_dst_mac_offset++; |
@@ -2331,21 +2331,21 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2331 | for (i = 0; i < pkt_dev->nr_labels; i++) | 2331 | for (i = 0; i < pkt_dev->nr_labels; i++) |
2332 | if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM) | 2332 | if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM) |
2333 | pkt_dev->labels[i] = MPLS_STACK_BOTTOM | | 2333 | pkt_dev->labels[i] = MPLS_STACK_BOTTOM | |
2334 | ((__force __be32)random32() & | 2334 | ((__force __be32)prandom_u32() & |
2335 | htonl(0x000fffff)); | 2335 | htonl(0x000fffff)); |
2336 | } | 2336 | } |
2337 | 2337 | ||
2338 | if ((pkt_dev->flags & F_VID_RND) && (pkt_dev->vlan_id != 0xffff)) { | 2338 | if ((pkt_dev->flags & F_VID_RND) && (pkt_dev->vlan_id != 0xffff)) { |
2339 | pkt_dev->vlan_id = random32() & (4096-1); | 2339 | pkt_dev->vlan_id = prandom_u32() & (4096 - 1); |
2340 | } | 2340 | } |
2341 | 2341 | ||
2342 | if ((pkt_dev->flags & F_SVID_RND) && (pkt_dev->svlan_id != 0xffff)) { | 2342 | if ((pkt_dev->flags & F_SVID_RND) && (pkt_dev->svlan_id != 0xffff)) { |
2343 | pkt_dev->svlan_id = random32() & (4096 - 1); | 2343 | pkt_dev->svlan_id = prandom_u32() & (4096 - 1); |
2344 | } | 2344 | } |
2345 | 2345 | ||
2346 | if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) { | 2346 | if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) { |
2347 | if (pkt_dev->flags & F_UDPSRC_RND) | 2347 | if (pkt_dev->flags & F_UDPSRC_RND) |
2348 | pkt_dev->cur_udp_src = random32() % | 2348 | pkt_dev->cur_udp_src = prandom_u32() % |
2349 | (pkt_dev->udp_src_max - pkt_dev->udp_src_min) | 2349 | (pkt_dev->udp_src_max - pkt_dev->udp_src_min) |
2350 | + pkt_dev->udp_src_min; | 2350 | + pkt_dev->udp_src_min; |
2351 | 2351 | ||
@@ -2358,7 +2358,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2358 | 2358 | ||
2359 | if (pkt_dev->udp_dst_min < pkt_dev->udp_dst_max) { | 2359 | if (pkt_dev->udp_dst_min < pkt_dev->udp_dst_max) { |
2360 | if (pkt_dev->flags & F_UDPDST_RND) { | 2360 | if (pkt_dev->flags & F_UDPDST_RND) { |
2361 | pkt_dev->cur_udp_dst = random32() % | 2361 | pkt_dev->cur_udp_dst = prandom_u32() % |
2362 | (pkt_dev->udp_dst_max - pkt_dev->udp_dst_min) | 2362 | (pkt_dev->udp_dst_max - pkt_dev->udp_dst_min) |
2363 | + pkt_dev->udp_dst_min; | 2363 | + pkt_dev->udp_dst_min; |
2364 | } else { | 2364 | } else { |
@@ -2375,7 +2375,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2375 | if (imn < imx) { | 2375 | if (imn < imx) { |
2376 | __u32 t; | 2376 | __u32 t; |
2377 | if (pkt_dev->flags & F_IPSRC_RND) | 2377 | if (pkt_dev->flags & F_IPSRC_RND) |
2378 | t = random32() % (imx - imn) + imn; | 2378 | t = prandom_u32() % (imx - imn) + imn; |
2379 | else { | 2379 | else { |
2380 | t = ntohl(pkt_dev->cur_saddr); | 2380 | t = ntohl(pkt_dev->cur_saddr); |
2381 | t++; | 2381 | t++; |
@@ -2396,17 +2396,15 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2396 | __be32 s; | 2396 | __be32 s; |
2397 | if (pkt_dev->flags & F_IPDST_RND) { | 2397 | if (pkt_dev->flags & F_IPDST_RND) { |
2398 | 2398 | ||
2399 | t = random32() % (imx - imn) + imn; | 2399 | do { |
2400 | s = htonl(t); | 2400 | t = prandom_u32() % |
2401 | 2401 | (imx - imn) + imn; | |
2402 | while (ipv4_is_loopback(s) || | ||
2403 | ipv4_is_multicast(s) || | ||
2404 | ipv4_is_lbcast(s) || | ||
2405 | ipv4_is_zeronet(s) || | ||
2406 | ipv4_is_local_multicast(s)) { | ||
2407 | t = random32() % (imx - imn) + imn; | ||
2408 | s = htonl(t); | 2402 | s = htonl(t); |
2409 | } | 2403 | } while (ipv4_is_loopback(s) || |
2404 | ipv4_is_multicast(s) || | ||
2405 | ipv4_is_lbcast(s) || | ||
2406 | ipv4_is_zeronet(s) || | ||
2407 | ipv4_is_local_multicast(s)); | ||
2410 | pkt_dev->cur_daddr = s; | 2408 | pkt_dev->cur_daddr = s; |
2411 | } else { | 2409 | } else { |
2412 | t = ntohl(pkt_dev->cur_daddr); | 2410 | t = ntohl(pkt_dev->cur_daddr); |
@@ -2437,7 +2435,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2437 | 2435 | ||
2438 | for (i = 0; i < 4; i++) { | 2436 | for (i = 0; i < 4; i++) { |
2439 | pkt_dev->cur_in6_daddr.s6_addr32[i] = | 2437 | pkt_dev->cur_in6_daddr.s6_addr32[i] = |
2440 | (((__force __be32)random32() | | 2438 | (((__force __be32)prandom_u32() | |
2441 | pkt_dev->min_in6_daddr.s6_addr32[i]) & | 2439 | pkt_dev->min_in6_daddr.s6_addr32[i]) & |
2442 | pkt_dev->max_in6_daddr.s6_addr32[i]); | 2440 | pkt_dev->max_in6_daddr.s6_addr32[i]); |
2443 | } | 2441 | } |
@@ -2447,7 +2445,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2447 | if (pkt_dev->min_pkt_size < pkt_dev->max_pkt_size) { | 2445 | if (pkt_dev->min_pkt_size < pkt_dev->max_pkt_size) { |
2448 | __u32 t; | 2446 | __u32 t; |
2449 | if (pkt_dev->flags & F_TXSIZE_RND) { | 2447 | if (pkt_dev->flags & F_TXSIZE_RND) { |
2450 | t = random32() % | 2448 | t = prandom_u32() % |
2451 | (pkt_dev->max_pkt_size - pkt_dev->min_pkt_size) | 2449 | (pkt_dev->max_pkt_size - pkt_dev->min_pkt_size) |
2452 | + pkt_dev->min_pkt_size; | 2450 | + pkt_dev->min_pkt_size; |
2453 | } else { | 2451 | } else { |
@@ -3576,8 +3574,6 @@ static void _rem_dev_from_if_list(struct pktgen_thread *t, | |||
3576 | static int pktgen_remove_device(struct pktgen_thread *t, | 3574 | static int pktgen_remove_device(struct pktgen_thread *t, |
3577 | struct pktgen_dev *pkt_dev) | 3575 | struct pktgen_dev *pkt_dev) |
3578 | { | 3576 | { |
3579 | struct pktgen_net *pn = t->net; | ||
3580 | |||
3581 | pr_debug("remove_device pkt_dev=%p\n", pkt_dev); | 3577 | pr_debug("remove_device pkt_dev=%p\n", pkt_dev); |
3582 | 3578 | ||
3583 | if (pkt_dev->running) { | 3579 | if (pkt_dev->running) { |
@@ -3597,7 +3593,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, | |||
3597 | _rem_dev_from_if_list(t, pkt_dev); | 3593 | _rem_dev_from_if_list(t, pkt_dev); |
3598 | 3594 | ||
3599 | if (pkt_dev->entry) | 3595 | if (pkt_dev->entry) |
3600 | remove_proc_entry(pkt_dev->entry->name, pn->proc_dir); | 3596 | proc_remove(pkt_dev->entry); |
3601 | 3597 | ||
3602 | #ifdef CONFIG_XFRM | 3598 | #ifdef CONFIG_XFRM |
3603 | free_SAs(pkt_dev); | 3599 | free_SAs(pkt_dev); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 23854b51a259..a08bd2b7fe3f 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -517,32 +517,6 @@ out: | |||
517 | return err; | 517 | return err; |
518 | } | 518 | } |
519 | 519 | ||
520 | static const int rtm_min[RTM_NR_FAMILIES] = | ||
521 | { | ||
522 | [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), | ||
523 | [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), | ||
524 | [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), | ||
525 | [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)), | ||
526 | [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | ||
527 | [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | ||
528 | [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | ||
529 | [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)), | ||
530 | [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
531 | [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
532 | }; | ||
533 | |||
534 | static const int rta_max[RTM_NR_FAMILIES] = | ||
535 | { | ||
536 | [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, | ||
537 | [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, | ||
538 | [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, | ||
539 | [RTM_FAM(RTM_NEWRULE)] = FRA_MAX, | ||
540 | [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, | ||
541 | [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, | ||
542 | [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, | ||
543 | [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, | ||
544 | }; | ||
545 | |||
546 | int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group, int echo) | 520 | int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group, int echo) |
547 | { | 521 | { |
548 | struct sock *rtnl = net->rtnl; | 522 | struct sock *rtnl = net->rtnl; |
@@ -1539,7 +1513,7 @@ errout: | |||
1539 | return err; | 1513 | return err; |
1540 | } | 1514 | } |
1541 | 1515 | ||
1542 | static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1516 | static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) |
1543 | { | 1517 | { |
1544 | struct net *net = sock_net(skb->sk); | 1518 | struct net *net = sock_net(skb->sk); |
1545 | struct ifinfomsg *ifm; | 1519 | struct ifinfomsg *ifm; |
@@ -1580,7 +1554,7 @@ errout: | |||
1580 | return err; | 1554 | return err; |
1581 | } | 1555 | } |
1582 | 1556 | ||
1583 | static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1557 | static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) |
1584 | { | 1558 | { |
1585 | struct net *net = sock_net(skb->sk); | 1559 | struct net *net = sock_net(skb->sk); |
1586 | const struct rtnl_link_ops *ops; | 1560 | const struct rtnl_link_ops *ops; |
@@ -1711,7 +1685,7 @@ static int rtnl_group_changelink(struct net *net, int group, | |||
1711 | return 0; | 1685 | return 0; |
1712 | } | 1686 | } |
1713 | 1687 | ||
1714 | static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1688 | static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh) |
1715 | { | 1689 | { |
1716 | struct net *net = sock_net(skb->sk); | 1690 | struct net *net = sock_net(skb->sk); |
1717 | const struct rtnl_link_ops *ops; | 1691 | const struct rtnl_link_ops *ops; |
@@ -1866,7 +1840,7 @@ out: | |||
1866 | } | 1840 | } |
1867 | } | 1841 | } |
1868 | 1842 | ||
1869 | static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 1843 | static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh) |
1870 | { | 1844 | { |
1871 | struct net *net = sock_net(skb->sk); | 1845 | struct net *net = sock_net(skb->sk); |
1872 | struct ifinfomsg *ifm; | 1846 | struct ifinfomsg *ifm; |
@@ -1957,8 +1931,11 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) | |||
1957 | if (rtnl_msg_handlers[idx] == NULL || | 1931 | if (rtnl_msg_handlers[idx] == NULL || |
1958 | rtnl_msg_handlers[idx][type].dumpit == NULL) | 1932 | rtnl_msg_handlers[idx][type].dumpit == NULL) |
1959 | continue; | 1933 | continue; |
1960 | if (idx > s_idx) | 1934 | if (idx > s_idx) { |
1961 | memset(&cb->args[0], 0, sizeof(cb->args)); | 1935 | memset(&cb->args[0], 0, sizeof(cb->args)); |
1936 | cb->prev_seq = 0; | ||
1937 | cb->seq = 0; | ||
1938 | } | ||
1962 | if (rtnl_msg_handlers[idx][type].dumpit(skb, cb)) | 1939 | if (rtnl_msg_handlers[idx][type].dumpit(skb, cb)) |
1963 | break; | 1940 | break; |
1964 | } | 1941 | } |
@@ -2051,7 +2028,39 @@ errout: | |||
2051 | rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); | 2028 | rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); |
2052 | } | 2029 | } |
2053 | 2030 | ||
2054 | static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 2031 | /** |
2032 | * ndo_dflt_fdb_add - default netdevice operation to add an FDB entry | ||
2033 | */ | ||
2034 | int ndo_dflt_fdb_add(struct ndmsg *ndm, | ||
2035 | struct nlattr *tb[], | ||
2036 | struct net_device *dev, | ||
2037 | const unsigned char *addr, | ||
2038 | u16 flags) | ||
2039 | { | ||
2040 | int err = -EINVAL; | ||
2041 | |||
2042 | /* If aging addresses are supported device will need to | ||
2043 | * implement its own handler for this. | ||
2044 | */ | ||
2045 | if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) { | ||
2046 | pr_info("%s: FDB only supports static addresses\n", dev->name); | ||
2047 | return err; | ||
2048 | } | ||
2049 | |||
2050 | if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) | ||
2051 | err = dev_uc_add_excl(dev, addr); | ||
2052 | else if (is_multicast_ether_addr(addr)) | ||
2053 | err = dev_mc_add_excl(dev, addr); | ||
2054 | |||
2055 | /* Only return duplicate errors if NLM_F_EXCL is set */ | ||
2056 | if (err == -EEXIST && !(flags & NLM_F_EXCL)) | ||
2057 | err = 0; | ||
2058 | |||
2059 | return err; | ||
2060 | } | ||
2061 | EXPORT_SYMBOL(ndo_dflt_fdb_add); | ||
2062 | |||
2063 | static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) | ||
2055 | { | 2064 | { |
2056 | struct net *net = sock_net(skb->sk); | 2065 | struct net *net = sock_net(skb->sk); |
2057 | struct ndmsg *ndm; | 2066 | struct ndmsg *ndm; |
@@ -2082,7 +2091,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2082 | } | 2091 | } |
2083 | 2092 | ||
2084 | addr = nla_data(tb[NDA_LLADDR]); | 2093 | addr = nla_data(tb[NDA_LLADDR]); |
2085 | if (!is_valid_ether_addr(addr)) { | 2094 | if (is_zero_ether_addr(addr)) { |
2086 | pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ether address\n"); | 2095 | pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ether address\n"); |
2087 | return -EINVAL; | 2096 | return -EINVAL; |
2088 | } | 2097 | } |
@@ -2103,10 +2112,13 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2103 | } | 2112 | } |
2104 | 2113 | ||
2105 | /* Embedded bridge, macvlan, and any other device support */ | 2114 | /* Embedded bridge, macvlan, and any other device support */ |
2106 | if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_add) { | 2115 | if ((ndm->ndm_flags & NTF_SELF)) { |
2107 | err = dev->netdev_ops->ndo_fdb_add(ndm, tb, | 2116 | if (dev->netdev_ops->ndo_fdb_add) |
2108 | dev, addr, | 2117 | err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr, |
2109 | nlh->nlmsg_flags); | 2118 | nlh->nlmsg_flags); |
2119 | else | ||
2120 | err = ndo_dflt_fdb_add(ndm, tb, dev, addr, | ||
2121 | nlh->nlmsg_flags); | ||
2110 | 2122 | ||
2111 | if (!err) { | 2123 | if (!err) { |
2112 | rtnl_fdb_notify(dev, addr, RTM_NEWNEIGH); | 2124 | rtnl_fdb_notify(dev, addr, RTM_NEWNEIGH); |
@@ -2117,7 +2129,36 @@ out: | |||
2117 | return err; | 2129 | return err; |
2118 | } | 2130 | } |
2119 | 2131 | ||
2120 | static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 2132 | /** |
2133 | * ndo_dflt_fdb_del - default netdevice operation to delete an FDB entry | ||
2134 | */ | ||
2135 | int ndo_dflt_fdb_del(struct ndmsg *ndm, | ||
2136 | struct nlattr *tb[], | ||
2137 | struct net_device *dev, | ||
2138 | const unsigned char *addr) | ||
2139 | { | ||
2140 | int err = -EOPNOTSUPP; | ||
2141 | |||
2142 | /* If aging addresses are supported device will need to | ||
2143 | * implement its own handler for this. | ||
2144 | */ | ||
2145 | if (ndm->ndm_state & NUD_PERMANENT) { | ||
2146 | pr_info("%s: FDB only supports static addresses\n", dev->name); | ||
2147 | return -EINVAL; | ||
2148 | } | ||
2149 | |||
2150 | if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) | ||
2151 | err = dev_uc_del(dev, addr); | ||
2152 | else if (is_multicast_ether_addr(addr)) | ||
2153 | err = dev_mc_del(dev, addr); | ||
2154 | else | ||
2155 | err = -EINVAL; | ||
2156 | |||
2157 | return err; | ||
2158 | } | ||
2159 | EXPORT_SYMBOL(ndo_dflt_fdb_del); | ||
2160 | |||
2161 | static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) | ||
2121 | { | 2162 | { |
2122 | struct net *net = sock_net(skb->sk); | 2163 | struct net *net = sock_net(skb->sk); |
2123 | struct ndmsg *ndm; | 2164 | struct ndmsg *ndm; |
@@ -2151,7 +2192,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2151 | } | 2192 | } |
2152 | 2193 | ||
2153 | addr = nla_data(tb[NDA_LLADDR]); | 2194 | addr = nla_data(tb[NDA_LLADDR]); |
2154 | if (!is_valid_ether_addr(addr)) { | 2195 | if (is_zero_ether_addr(addr)) { |
2155 | pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ether address\n"); | 2196 | pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ether address\n"); |
2156 | return -EINVAL; | 2197 | return -EINVAL; |
2157 | } | 2198 | } |
@@ -2174,8 +2215,11 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2174 | } | 2215 | } |
2175 | 2216 | ||
2176 | /* Embedded bridge, macvlan, and any other device support */ | 2217 | /* Embedded bridge, macvlan, and any other device support */ |
2177 | if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) { | 2218 | if (ndm->ndm_flags & NTF_SELF) { |
2178 | err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr); | 2219 | if (dev->netdev_ops->ndo_fdb_del) |
2220 | err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr); | ||
2221 | else | ||
2222 | err = ndo_dflt_fdb_del(ndm, tb, dev, addr); | ||
2179 | 2223 | ||
2180 | if (!err) { | 2224 | if (!err) { |
2181 | rtnl_fdb_notify(dev, addr, RTM_DELNEIGH); | 2225 | rtnl_fdb_notify(dev, addr, RTM_DELNEIGH); |
@@ -2220,7 +2264,7 @@ skip: | |||
2220 | * @dev: netdevice | 2264 | * @dev: netdevice |
2221 | * | 2265 | * |
2222 | * Default netdevice operation to dump the existing unicast address list. | 2266 | * Default netdevice operation to dump the existing unicast address list. |
2223 | * Returns zero on success. | 2267 | * Returns number of addresses from list put in skb. |
2224 | */ | 2268 | */ |
2225 | int ndo_dflt_fdb_dump(struct sk_buff *skb, | 2269 | int ndo_dflt_fdb_dump(struct sk_buff *skb, |
2226 | struct netlink_callback *cb, | 2270 | struct netlink_callback *cb, |
@@ -2260,6 +2304,8 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
2260 | 2304 | ||
2261 | if (dev->netdev_ops->ndo_fdb_dump) | 2305 | if (dev->netdev_ops->ndo_fdb_dump) |
2262 | idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx); | 2306 | idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx); |
2307 | else | ||
2308 | idx = ndo_dflt_fdb_dump(skb, cb, dev, idx); | ||
2263 | } | 2309 | } |
2264 | rcu_read_unlock(); | 2310 | rcu_read_unlock(); |
2265 | 2311 | ||
@@ -2411,8 +2457,7 @@ errout: | |||
2411 | return err; | 2457 | return err; |
2412 | } | 2458 | } |
2413 | 2459 | ||
2414 | static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, | 2460 | static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) |
2415 | void *arg) | ||
2416 | { | 2461 | { |
2417 | struct net *net = sock_net(skb->sk); | 2462 | struct net *net = sock_net(skb->sk); |
2418 | struct ifinfomsg *ifm; | 2463 | struct ifinfomsg *ifm; |
@@ -2482,8 +2527,7 @@ out: | |||
2482 | return err; | 2527 | return err; |
2483 | } | 2528 | } |
2484 | 2529 | ||
2485 | static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, | 2530 | static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) |
2486 | void *arg) | ||
2487 | { | 2531 | { |
2488 | struct net *net = sock_net(skb->sk); | 2532 | struct net *net = sock_net(skb->sk); |
2489 | struct ifinfomsg *ifm; | 2533 | struct ifinfomsg *ifm; |
@@ -2553,10 +2597,6 @@ out: | |||
2553 | return err; | 2597 | return err; |
2554 | } | 2598 | } |
2555 | 2599 | ||
2556 | /* Protected by RTNL sempahore. */ | ||
2557 | static struct rtattr **rta_buf; | ||
2558 | static int rtattr_max; | ||
2559 | |||
2560 | /* Process one rtnetlink message. */ | 2600 | /* Process one rtnetlink message. */ |
2561 | 2601 | ||
2562 | static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 2602 | static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
@@ -2564,7 +2604,6 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2564 | struct net *net = sock_net(skb->sk); | 2604 | struct net *net = sock_net(skb->sk); |
2565 | rtnl_doit_func doit; | 2605 | rtnl_doit_func doit; |
2566 | int sz_idx, kind; | 2606 | int sz_idx, kind; |
2567 | int min_len; | ||
2568 | int family; | 2607 | int family; |
2569 | int type; | 2608 | int type; |
2570 | int err; | 2609 | int err; |
@@ -2576,10 +2615,10 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2576 | type -= RTM_BASE; | 2615 | type -= RTM_BASE; |
2577 | 2616 | ||
2578 | /* All the messages must have at least 1 byte length */ | 2617 | /* All the messages must have at least 1 byte length */ |
2579 | if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtgenmsg))) | 2618 | if (nlmsg_len(nlh) < sizeof(struct rtgenmsg)) |
2580 | return 0; | 2619 | return 0; |
2581 | 2620 | ||
2582 | family = ((struct rtgenmsg *)NLMSG_DATA(nlh))->rtgen_family; | 2621 | family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; |
2583 | sz_idx = type>>2; | 2622 | sz_idx = type>>2; |
2584 | kind = type&3; | 2623 | kind = type&3; |
2585 | 2624 | ||
@@ -2612,32 +2651,11 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2612 | return err; | 2651 | return err; |
2613 | } | 2652 | } |
2614 | 2653 | ||
2615 | memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); | ||
2616 | |||
2617 | min_len = rtm_min[sz_idx]; | ||
2618 | if (nlh->nlmsg_len < min_len) | ||
2619 | return -EINVAL; | ||
2620 | |||
2621 | if (nlh->nlmsg_len > min_len) { | ||
2622 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); | ||
2623 | struct rtattr *attr = (void *)nlh + NLMSG_ALIGN(min_len); | ||
2624 | |||
2625 | while (RTA_OK(attr, attrlen)) { | ||
2626 | unsigned int flavor = attr->rta_type & NLA_TYPE_MASK; | ||
2627 | if (flavor) { | ||
2628 | if (flavor > rta_max[sz_idx]) | ||
2629 | return -EINVAL; | ||
2630 | rta_buf[flavor-1] = attr; | ||
2631 | } | ||
2632 | attr = RTA_NEXT(attr, attrlen); | ||
2633 | } | ||
2634 | } | ||
2635 | |||
2636 | doit = rtnl_get_doit(family, type); | 2654 | doit = rtnl_get_doit(family, type); |
2637 | if (doit == NULL) | 2655 | if (doit == NULL) |
2638 | return -EOPNOTSUPP; | 2656 | return -EOPNOTSUPP; |
2639 | 2657 | ||
2640 | return doit(skb, nlh, (void *)&rta_buf[0]); | 2658 | return doit(skb, nlh); |
2641 | } | 2659 | } |
2642 | 2660 | ||
2643 | static void rtnetlink_rcv(struct sk_buff *skb) | 2661 | static void rtnetlink_rcv(struct sk_buff *skb) |
@@ -2707,16 +2725,6 @@ static struct pernet_operations rtnetlink_net_ops = { | |||
2707 | 2725 | ||
2708 | void __init rtnetlink_init(void) | 2726 | void __init rtnetlink_init(void) |
2709 | { | 2727 | { |
2710 | int i; | ||
2711 | |||
2712 | rtattr_max = 0; | ||
2713 | for (i = 0; i < ARRAY_SIZE(rta_max); i++) | ||
2714 | if (rta_max[i] > rtattr_max) | ||
2715 | rtattr_max = rta_max[i]; | ||
2716 | rta_buf = kmalloc(rtattr_max * sizeof(struct rtattr *), GFP_KERNEL); | ||
2717 | if (!rta_buf) | ||
2718 | panic("rtnetlink_init: cannot allocate rta_buf\n"); | ||
2719 | |||
2720 | if (register_pernet_subsys(&rtnetlink_net_ops)) | 2728 | if (register_pernet_subsys(&rtnetlink_net_ops)) |
2721 | panic("rtnetlink_init: cannot initialize rtnetlink\n"); | 2729 | panic("rtnetlink_init: cannot initialize rtnetlink\n"); |
2722 | 2730 | ||
diff --git a/net/core/scm.c b/net/core/scm.c index 2dc6cdaaae8a..03795d0147f2 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -187,22 +187,6 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
187 | 187 | ||
188 | p->creds.uid = uid; | 188 | p->creds.uid = uid; |
189 | p->creds.gid = gid; | 189 | p->creds.gid = gid; |
190 | |||
191 | if (!p->cred || | ||
192 | !uid_eq(p->cred->euid, uid) || | ||
193 | !gid_eq(p->cred->egid, gid)) { | ||
194 | struct cred *cred; | ||
195 | err = -ENOMEM; | ||
196 | cred = prepare_creds(); | ||
197 | if (!cred) | ||
198 | goto error; | ||
199 | |||
200 | cred->uid = cred->euid = uid; | ||
201 | cred->gid = cred->egid = gid; | ||
202 | if (p->cred) | ||
203 | put_cred(p->cred); | ||
204 | p->cred = cred; | ||
205 | } | ||
206 | break; | 190 | break; |
207 | } | 191 | } |
208 | default: | 192 | default: |
@@ -306,8 +290,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | |||
306 | /* Bump the usage count and install the file. */ | 290 | /* Bump the usage count and install the file. */ |
307 | sock = sock_from_file(fp[i], &err); | 291 | sock = sock_from_file(fp[i], &err); |
308 | if (sock) { | 292 | if (sock) { |
309 | sock_update_netprioidx(sock->sk, current); | 293 | sock_update_netprioidx(sock->sk); |
310 | sock_update_classid(sock->sk, current); | 294 | sock_update_classid(sock->sk); |
311 | } | 295 | } |
312 | fd_install(new_fd, get_file(fp[i])); | 296 | fd_install(new_fd, get_file(fp[i])); |
313 | } | 297 | } |
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c index e61a8bb7fce7..6a2f13cee86a 100644 --- a/net/core/secure_seq.c +++ b/net/core/secure_seq.c | |||
@@ -12,12 +12,10 @@ | |||
12 | 12 | ||
13 | static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; | 13 | static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; |
14 | 14 | ||
15 | static int __init net_secret_init(void) | 15 | void net_secret_init(void) |
16 | { | 16 | { |
17 | get_random_bytes(net_secret, sizeof(net_secret)); | 17 | get_random_bytes(net_secret, sizeof(net_secret)); |
18 | return 0; | ||
19 | } | 18 | } |
20 | late_initcall(net_secret_init); | ||
21 | 19 | ||
22 | #ifdef CONFIG_INET | 20 | #ifdef CONFIG_INET |
23 | static u32 seq_scale(u32 seq) | 21 | static u32 seq_scale(u32 seq) |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 33245ef54c3b..af9185d0be6a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -179,6 +179,33 @@ out: | |||
179 | * | 179 | * |
180 | */ | 180 | */ |
181 | 181 | ||
182 | struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) | ||
183 | { | ||
184 | struct sk_buff *skb; | ||
185 | |||
186 | /* Get the HEAD */ | ||
187 | skb = kmem_cache_alloc_node(skbuff_head_cache, | ||
188 | gfp_mask & ~__GFP_DMA, node); | ||
189 | if (!skb) | ||
190 | goto out; | ||
191 | |||
192 | /* | ||
193 | * Only clear those fields we need to clear, not those that we will | ||
194 | * actually initialise below. Hence, don't put any more fields after | ||
195 | * the tail pointer in struct sk_buff! | ||
196 | */ | ||
197 | memset(skb, 0, offsetof(struct sk_buff, tail)); | ||
198 | skb->data = NULL; | ||
199 | skb->truesize = sizeof(struct sk_buff); | ||
200 | atomic_set(&skb->users, 1); | ||
201 | |||
202 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
203 | skb->mac_header = ~0U; | ||
204 | #endif | ||
205 | out: | ||
206 | return skb; | ||
207 | } | ||
208 | |||
182 | /** | 209 | /** |
183 | * __alloc_skb - allocate a network buffer | 210 | * __alloc_skb - allocate a network buffer |
184 | * @size: size to allocate | 211 | * @size: size to allocate |
@@ -584,7 +611,8 @@ static void skb_release_head_state(struct sk_buff *skb) | |||
584 | static void skb_release_all(struct sk_buff *skb) | 611 | static void skb_release_all(struct sk_buff *skb) |
585 | { | 612 | { |
586 | skb_release_head_state(skb); | 613 | skb_release_head_state(skb); |
587 | skb_release_data(skb); | 614 | if (likely(skb->data)) |
615 | skb_release_data(skb); | ||
588 | } | 616 | } |
589 | 617 | ||
590 | /** | 618 | /** |
@@ -673,6 +701,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
673 | new->mac_header = old->mac_header; | 701 | new->mac_header = old->mac_header; |
674 | new->inner_transport_header = old->inner_transport_header; | 702 | new->inner_transport_header = old->inner_transport_header; |
675 | new->inner_network_header = old->inner_network_header; | 703 | new->inner_network_header = old->inner_network_header; |
704 | new->inner_mac_header = old->inner_mac_header; | ||
676 | skb_dst_copy(new, old); | 705 | skb_dst_copy(new, old); |
677 | new->rxhash = old->rxhash; | 706 | new->rxhash = old->rxhash; |
678 | new->ooo_okay = old->ooo_okay; | 707 | new->ooo_okay = old->ooo_okay; |
@@ -706,6 +735,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
706 | new->tc_verd = old->tc_verd; | 735 | new->tc_verd = old->tc_verd; |
707 | #endif | 736 | #endif |
708 | #endif | 737 | #endif |
738 | new->vlan_proto = old->vlan_proto; | ||
709 | new->vlan_tci = old->vlan_tci; | 739 | new->vlan_tci = old->vlan_tci; |
710 | 740 | ||
711 | skb_copy_secmark(new, old); | 741 | skb_copy_secmark(new, old); |
@@ -867,6 +897,18 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) | |||
867 | } | 897 | } |
868 | EXPORT_SYMBOL(skb_clone); | 898 | EXPORT_SYMBOL(skb_clone); |
869 | 899 | ||
900 | static void skb_headers_offset_update(struct sk_buff *skb, int off) | ||
901 | { | ||
902 | /* {transport,network,mac}_header and tail are relative to skb->head */ | ||
903 | skb->transport_header += off; | ||
904 | skb->network_header += off; | ||
905 | if (skb_mac_header_was_set(skb)) | ||
906 | skb->mac_header += off; | ||
907 | skb->inner_transport_header += off; | ||
908 | skb->inner_network_header += off; | ||
909 | skb->inner_mac_header += off; | ||
910 | } | ||
911 | |||
870 | static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | 912 | static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) |
871 | { | 913 | { |
872 | #ifndef NET_SKBUFF_DATA_USES_OFFSET | 914 | #ifndef NET_SKBUFF_DATA_USES_OFFSET |
@@ -879,13 +921,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
879 | __copy_skb_header(new, old); | 921 | __copy_skb_header(new, old); |
880 | 922 | ||
881 | #ifndef NET_SKBUFF_DATA_USES_OFFSET | 923 | #ifndef NET_SKBUFF_DATA_USES_OFFSET |
882 | /* {transport,network,mac}_header are relative to skb->head */ | 924 | skb_headers_offset_update(new, offset); |
883 | new->transport_header += offset; | ||
884 | new->network_header += offset; | ||
885 | if (skb_mac_header_was_set(new)) | ||
886 | new->mac_header += offset; | ||
887 | new->inner_transport_header += offset; | ||
888 | new->inner_network_header += offset; | ||
889 | #endif | 925 | #endif |
890 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; | 926 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; |
891 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; | 927 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; |
@@ -1077,14 +1113,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
1077 | #else | 1113 | #else |
1078 | skb->end = skb->head + size; | 1114 | skb->end = skb->head + size; |
1079 | #endif | 1115 | #endif |
1080 | /* {transport,network,mac}_header and tail are relative to skb->head */ | ||
1081 | skb->tail += off; | 1116 | skb->tail += off; |
1082 | skb->transport_header += off; | 1117 | skb_headers_offset_update(skb, off); |
1083 | skb->network_header += off; | ||
1084 | if (skb_mac_header_was_set(skb)) | ||
1085 | skb->mac_header += off; | ||
1086 | skb->inner_transport_header += off; | ||
1087 | skb->inner_network_header += off; | ||
1088 | /* Only adjust this if it actually is csum_start rather than csum */ | 1118 | /* Only adjust this if it actually is csum_start rather than csum */ |
1089 | if (skb->ip_summed == CHECKSUM_PARTIAL) | 1119 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
1090 | skb->csum_start += nhead; | 1120 | skb->csum_start += nhead; |
@@ -1180,12 +1210,7 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | |||
1180 | if (n->ip_summed == CHECKSUM_PARTIAL) | 1210 | if (n->ip_summed == CHECKSUM_PARTIAL) |
1181 | n->csum_start += off; | 1211 | n->csum_start += off; |
1182 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 1212 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
1183 | n->transport_header += off; | 1213 | skb_headers_offset_update(n, off); |
1184 | n->network_header += off; | ||
1185 | if (skb_mac_header_was_set(skb)) | ||
1186 | n->mac_header += off; | ||
1187 | n->inner_transport_header += off; | ||
1188 | n->inner_network_header += off; | ||
1189 | #endif | 1214 | #endif |
1190 | 1215 | ||
1191 | return n; | 1216 | return n; |
@@ -2741,12 +2766,19 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
2741 | unsigned int tnl_hlen = skb_tnl_header_len(skb); | 2766 | unsigned int tnl_hlen = skb_tnl_header_len(skb); |
2742 | unsigned int headroom; | 2767 | unsigned int headroom; |
2743 | unsigned int len; | 2768 | unsigned int len; |
2769 | __be16 proto; | ||
2770 | bool csum; | ||
2744 | int sg = !!(features & NETIF_F_SG); | 2771 | int sg = !!(features & NETIF_F_SG); |
2745 | int nfrags = skb_shinfo(skb)->nr_frags; | 2772 | int nfrags = skb_shinfo(skb)->nr_frags; |
2746 | int err = -ENOMEM; | 2773 | int err = -ENOMEM; |
2747 | int i = 0; | 2774 | int i = 0; |
2748 | int pos; | 2775 | int pos; |
2749 | 2776 | ||
2777 | proto = skb_network_protocol(skb); | ||
2778 | if (unlikely(!proto)) | ||
2779 | return ERR_PTR(-EINVAL); | ||
2780 | |||
2781 | csum = !!can_checksum_protocol(features, proto); | ||
2750 | __skb_push(skb, doffset); | 2782 | __skb_push(skb, doffset); |
2751 | headroom = skb_headroom(skb); | 2783 | headroom = skb_headroom(skb); |
2752 | pos = skb_headlen(skb); | 2784 | pos = skb_headlen(skb); |
@@ -2884,6 +2916,12 @@ skip_fraglist: | |||
2884 | nskb->data_len = len - hsize; | 2916 | nskb->data_len = len - hsize; |
2885 | nskb->len += nskb->data_len; | 2917 | nskb->len += nskb->data_len; |
2886 | nskb->truesize += nskb->data_len; | 2918 | nskb->truesize += nskb->data_len; |
2919 | |||
2920 | if (!csum) { | ||
2921 | nskb->csum = skb_checksum(nskb, doffset, | ||
2922 | nskb->len - doffset, 0); | ||
2923 | nskb->ip_summed = CHECKSUM_NONE; | ||
2924 | } | ||
2887 | } while ((offset += len) < skb->len); | 2925 | } while ((offset += len) < skb->len); |
2888 | 2926 | ||
2889 | return segs; | 2927 | return segs; |
@@ -3289,12 +3327,8 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3289 | if (!sk) | 3327 | if (!sk) |
3290 | return; | 3328 | return; |
3291 | 3329 | ||
3292 | skb = skb_clone(orig_skb, GFP_ATOMIC); | ||
3293 | if (!skb) | ||
3294 | return; | ||
3295 | |||
3296 | if (hwtstamps) { | 3330 | if (hwtstamps) { |
3297 | *skb_hwtstamps(skb) = | 3331 | *skb_hwtstamps(orig_skb) = |
3298 | *hwtstamps; | 3332 | *hwtstamps; |
3299 | } else { | 3333 | } else { |
3300 | /* | 3334 | /* |
@@ -3302,9 +3336,13 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3302 | * so keep the shared tx_flags and only | 3336 | * so keep the shared tx_flags and only |
3303 | * store software time stamp | 3337 | * store software time stamp |
3304 | */ | 3338 | */ |
3305 | skb->tstamp = ktime_get_real(); | 3339 | orig_skb->tstamp = ktime_get_real(); |
3306 | } | 3340 | } |
3307 | 3341 | ||
3342 | skb = skb_clone(orig_skb, GFP_ATOMIC); | ||
3343 | if (!skb) | ||
3344 | return; | ||
3345 | |||
3308 | serr = SKB_EXT_ERR(skb); | 3346 | serr = SKB_EXT_ERR(skb); |
3309 | memset(serr, 0, sizeof(*serr)); | 3347 | memset(serr, 0, sizeof(*serr)); |
3310 | serr->ee.ee_errno = ENOMSG; | 3348 | serr->ee.ee_errno = ENOMSG; |
@@ -3361,6 +3399,7 @@ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) | |||
3361 | skb->ip_summed = CHECKSUM_PARTIAL; | 3399 | skb->ip_summed = CHECKSUM_PARTIAL; |
3362 | skb->csum_start = skb_headroom(skb) + start; | 3400 | skb->csum_start = skb_headroom(skb) + start; |
3363 | skb->csum_offset = off; | 3401 | skb->csum_offset = off; |
3402 | skb_set_transport_header(skb, start); | ||
3364 | return true; | 3403 | return true; |
3365 | } | 3404 | } |
3366 | EXPORT_SYMBOL_GPL(skb_partial_csum_set); | 3405 | EXPORT_SYMBOL_GPL(skb_partial_csum_set); |
diff --git a/net/core/sock.c b/net/core/sock.c index b261a7977746..d4f4cea726e7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -907,6 +907,10 @@ set_rcvbuf: | |||
907 | sock_valbool_flag(sk, SOCK_NOFCS, valbool); | 907 | sock_valbool_flag(sk, SOCK_NOFCS, valbool); |
908 | break; | 908 | break; |
909 | 909 | ||
910 | case SO_SELECT_ERR_QUEUE: | ||
911 | sock_valbool_flag(sk, SOCK_SELECT_ERR_QUEUE, valbool); | ||
912 | break; | ||
913 | |||
910 | default: | 914 | default: |
911 | ret = -ENOPROTOOPT; | 915 | ret = -ENOPROTOOPT; |
912 | break; | 916 | break; |
@@ -1160,6 +1164,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
1160 | v.val = sock_flag(sk, SOCK_FILTER_LOCKED); | 1164 | v.val = sock_flag(sk, SOCK_FILTER_LOCKED); |
1161 | break; | 1165 | break; |
1162 | 1166 | ||
1167 | case SO_SELECT_ERR_QUEUE: | ||
1168 | v.val = sock_flag(sk, SOCK_SELECT_ERR_QUEUE); | ||
1169 | break; | ||
1170 | |||
1163 | default: | 1171 | default: |
1164 | return -ENOPROTOOPT; | 1172 | return -ENOPROTOOPT; |
1165 | } | 1173 | } |
@@ -1298,13 +1306,12 @@ static void sk_prot_free(struct proto *prot, struct sock *sk) | |||
1298 | module_put(owner); | 1306 | module_put(owner); |
1299 | } | 1307 | } |
1300 | 1308 | ||
1301 | #ifdef CONFIG_CGROUPS | ||
1302 | #if IS_ENABLED(CONFIG_NET_CLS_CGROUP) | 1309 | #if IS_ENABLED(CONFIG_NET_CLS_CGROUP) |
1303 | void sock_update_classid(struct sock *sk, struct task_struct *task) | 1310 | void sock_update_classid(struct sock *sk) |
1304 | { | 1311 | { |
1305 | u32 classid; | 1312 | u32 classid; |
1306 | 1313 | ||
1307 | classid = task_cls_classid(task); | 1314 | classid = task_cls_classid(current); |
1308 | if (classid != sk->sk_classid) | 1315 | if (classid != sk->sk_classid) |
1309 | sk->sk_classid = classid; | 1316 | sk->sk_classid = classid; |
1310 | } | 1317 | } |
@@ -1312,16 +1319,15 @@ EXPORT_SYMBOL(sock_update_classid); | |||
1312 | #endif | 1319 | #endif |
1313 | 1320 | ||
1314 | #if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | 1321 | #if IS_ENABLED(CONFIG_NETPRIO_CGROUP) |
1315 | void sock_update_netprioidx(struct sock *sk, struct task_struct *task) | 1322 | void sock_update_netprioidx(struct sock *sk) |
1316 | { | 1323 | { |
1317 | if (in_interrupt()) | 1324 | if (in_interrupt()) |
1318 | return; | 1325 | return; |
1319 | 1326 | ||
1320 | sk->sk_cgrp_prioidx = task_netprioidx(task); | 1327 | sk->sk_cgrp_prioidx = task_netprioidx(current); |
1321 | } | 1328 | } |
1322 | EXPORT_SYMBOL_GPL(sock_update_netprioidx); | 1329 | EXPORT_SYMBOL_GPL(sock_update_netprioidx); |
1323 | #endif | 1330 | #endif |
1324 | #endif | ||
1325 | 1331 | ||
1326 | /** | 1332 | /** |
1327 | * sk_alloc - All socket objects are allocated here | 1333 | * sk_alloc - All socket objects are allocated here |
@@ -1347,8 +1353,8 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1347 | sock_net_set(sk, get_net(net)); | 1353 | sock_net_set(sk, get_net(net)); |
1348 | atomic_set(&sk->sk_wmem_alloc, 1); | 1354 | atomic_set(&sk->sk_wmem_alloc, 1); |
1349 | 1355 | ||
1350 | sock_update_classid(sk, current); | 1356 | sock_update_classid(sk); |
1351 | sock_update_netprioidx(sk, current); | 1357 | sock_update_netprioidx(sk); |
1352 | } | 1358 | } |
1353 | 1359 | ||
1354 | return sk; | 1360 | return sk; |
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index a29e90cf36b7..d5bef0b0f639 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
@@ -49,6 +49,39 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype) | |||
49 | } | 49 | } |
50 | EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); | 50 | EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); |
51 | 51 | ||
52 | int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, | ||
53 | struct sk_buff *skb, int attrtype) | ||
54 | { | ||
55 | struct nlattr *attr; | ||
56 | struct sk_filter *filter; | ||
57 | unsigned int len; | ||
58 | int err = 0; | ||
59 | |||
60 | if (!ns_capable(user_ns, CAP_NET_ADMIN)) { | ||
61 | nla_reserve(skb, attrtype, 0); | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | rcu_read_lock(); | ||
66 | |||
67 | filter = rcu_dereference(sk->sk_filter); | ||
68 | len = filter ? filter->len * sizeof(struct sock_filter) : 0; | ||
69 | |||
70 | attr = nla_reserve(skb, attrtype, len); | ||
71 | if (attr == NULL) { | ||
72 | err = -EMSGSIZE; | ||
73 | goto out; | ||
74 | } | ||
75 | |||
76 | if (filter) | ||
77 | memcpy(nla_data(attr), filter->insns, len); | ||
78 | |||
79 | out: | ||
80 | rcu_read_unlock(); | ||
81 | return err; | ||
82 | } | ||
83 | EXPORT_SYMBOL(sock_diag_put_filterinfo); | ||
84 | |||
52 | void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)) | 85 | void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)) |
53 | { | 86 | { |
54 | mutex_lock(&sock_diag_table_mutex); | 87 | mutex_lock(&sock_diag_table_mutex); |
diff --git a/net/core/utils.c b/net/core/utils.c index e3487e461939..3c7f5b51b979 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/ctype.h> | ||
20 | #include <linux/inet.h> | 21 | #include <linux/inet.h> |
21 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
22 | #include <linux/net.h> | 23 | #include <linux/net.h> |
@@ -348,9 +349,7 @@ int mac_pton(const char *s, u8 *mac) | |||
348 | 349 | ||
349 | /* Don't dirty result unless string is valid MAC. */ | 350 | /* Don't dirty result unless string is valid MAC. */ |
350 | for (i = 0; i < ETH_ALEN; i++) { | 351 | for (i = 0; i < ETH_ALEN; i++) { |
351 | if (!strchr("0123456789abcdefABCDEF", s[i * 3])) | 352 | if (!isxdigit(s[i * 3]) || !isxdigit(s[i * 3 + 1])) |
352 | return 0; | ||
353 | if (!strchr("0123456789abcdefABCDEF", s[i * 3 + 1])) | ||
354 | return 0; | 353 | return 0; |
355 | if (i != ETH_ALEN - 1 && s[i * 3 + 2] != ':') | 354 | if (i != ETH_ALEN - 1 && s[i * 3 + 2] != ':') |
356 | return 0; | 355 | return 0; |