diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 103 | ||||
-rw-r--r-- | net/core/dst.c | 15 | ||||
-rw-r--r-- | net/core/filter.c | 25 | ||||
-rw-r--r-- | net/core/neighbour.c | 4 | ||||
-rw-r--r-- | net/core/net_namespace.c | 2 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 86 | ||||
-rw-r--r-- | net/core/skbuff.c | 4 | ||||
-rw-r--r-- | net/core/sock.c | 49 | ||||
-rw-r--r-- | net/core/sock_diag.c | 4 | ||||
-rw-r--r-- | net/core/utils.c | 8 |
10 files changed, 239 insertions, 61 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 14dac0654f28..9abc503b19b7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2284,7 +2284,7 @@ EXPORT_SYMBOL(skb_checksum_help); | |||
2284 | __be16 skb_network_protocol(struct sk_buff *skb, int *depth) | 2284 | __be16 skb_network_protocol(struct sk_buff *skb, int *depth) |
2285 | { | 2285 | { |
2286 | __be16 type = skb->protocol; | 2286 | __be16 type = skb->protocol; |
2287 | int vlan_depth = ETH_HLEN; | 2287 | int vlan_depth = skb->mac_len; |
2288 | 2288 | ||
2289 | /* Tunnel gso handlers can set protocol to ethernet. */ | 2289 | /* Tunnel gso handlers can set protocol to ethernet. */ |
2290 | if (type == htons(ETH_P_TEB)) { | 2290 | if (type == htons(ETH_P_TEB)) { |
@@ -2418,7 +2418,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault); | |||
2418 | * 2. No high memory really exists on this machine. | 2418 | * 2. No high memory really exists on this machine. |
2419 | */ | 2419 | */ |
2420 | 2420 | ||
2421 | static int illegal_highdma(const struct net_device *dev, struct sk_buff *skb) | 2421 | static int illegal_highdma(struct net_device *dev, struct sk_buff *skb) |
2422 | { | 2422 | { |
2423 | #ifdef CONFIG_HIGHMEM | 2423 | #ifdef CONFIG_HIGHMEM |
2424 | int i; | 2424 | int i; |
@@ -2493,38 +2493,36 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features) | |||
2493 | } | 2493 | } |
2494 | 2494 | ||
2495 | static netdev_features_t harmonize_features(struct sk_buff *skb, | 2495 | static netdev_features_t harmonize_features(struct sk_buff *skb, |
2496 | const struct net_device *dev, | 2496 | netdev_features_t features) |
2497 | netdev_features_t features) | ||
2498 | { | 2497 | { |
2499 | int tmp; | 2498 | int tmp; |
2500 | 2499 | ||
2501 | if (skb->ip_summed != CHECKSUM_NONE && | 2500 | if (skb->ip_summed != CHECKSUM_NONE && |
2502 | !can_checksum_protocol(features, skb_network_protocol(skb, &tmp))) { | 2501 | !can_checksum_protocol(features, skb_network_protocol(skb, &tmp))) { |
2503 | features &= ~NETIF_F_ALL_CSUM; | 2502 | features &= ~NETIF_F_ALL_CSUM; |
2504 | } else if (illegal_highdma(dev, skb)) { | 2503 | } else if (illegal_highdma(skb->dev, skb)) { |
2505 | features &= ~NETIF_F_SG; | 2504 | features &= ~NETIF_F_SG; |
2506 | } | 2505 | } |
2507 | 2506 | ||
2508 | return features; | 2507 | return features; |
2509 | } | 2508 | } |
2510 | 2509 | ||
2511 | netdev_features_t netif_skb_dev_features(struct sk_buff *skb, | 2510 | netdev_features_t netif_skb_features(struct sk_buff *skb) |
2512 | const struct net_device *dev) | ||
2513 | { | 2511 | { |
2514 | __be16 protocol = skb->protocol; | 2512 | __be16 protocol = skb->protocol; |
2515 | netdev_features_t features = dev->features; | 2513 | netdev_features_t features = skb->dev->features; |
2516 | 2514 | ||
2517 | if (skb_shinfo(skb)->gso_segs > dev->gso_max_segs) | 2515 | if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs) |
2518 | features &= ~NETIF_F_GSO_MASK; | 2516 | features &= ~NETIF_F_GSO_MASK; |
2519 | 2517 | ||
2520 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { | 2518 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { |
2521 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2519 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
2522 | protocol = veh->h_vlan_encapsulated_proto; | 2520 | protocol = veh->h_vlan_encapsulated_proto; |
2523 | } else if (!vlan_tx_tag_present(skb)) { | 2521 | } else if (!vlan_tx_tag_present(skb)) { |
2524 | return harmonize_features(skb, dev, features); | 2522 | return harmonize_features(skb, features); |
2525 | } | 2523 | } |
2526 | 2524 | ||
2527 | features &= (dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | | 2525 | features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | |
2528 | NETIF_F_HW_VLAN_STAG_TX); | 2526 | NETIF_F_HW_VLAN_STAG_TX); |
2529 | 2527 | ||
2530 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) | 2528 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) |
@@ -2532,9 +2530,9 @@ netdev_features_t netif_skb_dev_features(struct sk_buff *skb, | |||
2532 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | | 2530 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | |
2533 | NETIF_F_HW_VLAN_STAG_TX; | 2531 | NETIF_F_HW_VLAN_STAG_TX; |
2534 | 2532 | ||
2535 | return harmonize_features(skb, dev, features); | 2533 | return harmonize_features(skb, features); |
2536 | } | 2534 | } |
2537 | EXPORT_SYMBOL(netif_skb_dev_features); | 2535 | EXPORT_SYMBOL(netif_skb_features); |
2538 | 2536 | ||
2539 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | 2537 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, |
2540 | struct netdev_queue *txq) | 2538 | struct netdev_queue *txq) |
@@ -3953,6 +3951,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff | |||
3953 | } | 3951 | } |
3954 | NAPI_GRO_CB(skb)->count = 1; | 3952 | NAPI_GRO_CB(skb)->count = 1; |
3955 | NAPI_GRO_CB(skb)->age = jiffies; | 3953 | NAPI_GRO_CB(skb)->age = jiffies; |
3954 | NAPI_GRO_CB(skb)->last = skb; | ||
3956 | skb_shinfo(skb)->gso_size = skb_gro_len(skb); | 3955 | skb_shinfo(skb)->gso_size = skb_gro_len(skb); |
3957 | skb->next = napi->gro_list; | 3956 | skb->next = napi->gro_list; |
3958 | napi->gro_list = skb; | 3957 | napi->gro_list = skb; |
@@ -4543,6 +4542,32 @@ void *netdev_adjacent_get_private(struct list_head *adj_list) | |||
4543 | EXPORT_SYMBOL(netdev_adjacent_get_private); | 4542 | EXPORT_SYMBOL(netdev_adjacent_get_private); |
4544 | 4543 | ||
4545 | /** | 4544 | /** |
4545 | * netdev_upper_get_next_dev_rcu - Get the next dev from upper list | ||
4546 | * @dev: device | ||
4547 | * @iter: list_head ** of the current position | ||
4548 | * | ||
4549 | * Gets the next device from the dev's upper list, starting from iter | ||
4550 | * position. The caller must hold RCU read lock. | ||
4551 | */ | ||
4552 | struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, | ||
4553 | struct list_head **iter) | ||
4554 | { | ||
4555 | struct netdev_adjacent *upper; | ||
4556 | |||
4557 | WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held()); | ||
4558 | |||
4559 | upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); | ||
4560 | |||
4561 | if (&upper->list == &dev->adj_list.upper) | ||
4562 | return NULL; | ||
4563 | |||
4564 | *iter = &upper->list; | ||
4565 | |||
4566 | return upper->dev; | ||
4567 | } | ||
4568 | EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu); | ||
4569 | |||
4570 | /** | ||
4546 | * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list | 4571 | * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list |
4547 | * @dev: device | 4572 | * @dev: device |
4548 | * @iter: list_head ** of the current position | 4573 | * @iter: list_head ** of the current position |
@@ -4624,6 +4649,32 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev, | |||
4624 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); | 4649 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); |
4625 | 4650 | ||
4626 | /** | 4651 | /** |
4652 | * netdev_lower_get_next - Get the next device from the lower neighbour | ||
4653 | * list | ||
4654 | * @dev: device | ||
4655 | * @iter: list_head ** of the current position | ||
4656 | * | ||
4657 | * Gets the next netdev_adjacent from the dev's lower neighbour | ||
4658 | * list, starting from iter position. The caller must hold RTNL lock or | ||
4659 | * its own locking that guarantees that the neighbour lower | ||
4660 | * list will remain unchainged. | ||
4661 | */ | ||
4662 | void *netdev_lower_get_next(struct net_device *dev, struct list_head **iter) | ||
4663 | { | ||
4664 | struct netdev_adjacent *lower; | ||
4665 | |||
4666 | lower = list_entry((*iter)->next, struct netdev_adjacent, list); | ||
4667 | |||
4668 | if (&lower->list == &dev->adj_list.lower) | ||
4669 | return NULL; | ||
4670 | |||
4671 | *iter = &lower->list; | ||
4672 | |||
4673 | return lower->dev; | ||
4674 | } | ||
4675 | EXPORT_SYMBOL(netdev_lower_get_next); | ||
4676 | |||
4677 | /** | ||
4627 | * netdev_lower_get_first_private_rcu - Get the first ->private from the | 4678 | * netdev_lower_get_first_private_rcu - Get the first ->private from the |
4628 | * lower neighbour list, RCU | 4679 | * lower neighbour list, RCU |
4629 | * variant | 4680 | * variant |
@@ -5073,6 +5124,30 @@ void *netdev_lower_dev_get_private(struct net_device *dev, | |||
5073 | } | 5124 | } |
5074 | EXPORT_SYMBOL(netdev_lower_dev_get_private); | 5125 | EXPORT_SYMBOL(netdev_lower_dev_get_private); |
5075 | 5126 | ||
5127 | |||
5128 | int dev_get_nest_level(struct net_device *dev, | ||
5129 | bool (*type_check)(struct net_device *dev)) | ||
5130 | { | ||
5131 | struct net_device *lower = NULL; | ||
5132 | struct list_head *iter; | ||
5133 | int max_nest = -1; | ||
5134 | int nest; | ||
5135 | |||
5136 | ASSERT_RTNL(); | ||
5137 | |||
5138 | netdev_for_each_lower_dev(dev, lower, iter) { | ||
5139 | nest = dev_get_nest_level(lower, type_check); | ||
5140 | if (max_nest < nest) | ||
5141 | max_nest = nest; | ||
5142 | } | ||
5143 | |||
5144 | if (type_check(dev)) | ||
5145 | max_nest++; | ||
5146 | |||
5147 | return max_nest; | ||
5148 | } | ||
5149 | EXPORT_SYMBOL(dev_get_nest_level); | ||
5150 | |||
5076 | static void dev_change_rx_flags(struct net_device *dev, int flags) | 5151 | static void dev_change_rx_flags(struct net_device *dev, int flags) |
5077 | { | 5152 | { |
5078 | const struct net_device_ops *ops = dev->netdev_ops; | 5153 | const struct net_device_ops *ops = dev->netdev_ops; |
@@ -5542,7 +5617,7 @@ static int dev_new_index(struct net *net) | |||
5542 | 5617 | ||
5543 | /* Delayed registration/unregisteration */ | 5618 | /* Delayed registration/unregisteration */ |
5544 | static LIST_HEAD(net_todo_list); | 5619 | static LIST_HEAD(net_todo_list); |
5545 | static DECLARE_WAIT_QUEUE_HEAD(netdev_unregistering_wq); | 5620 | DECLARE_WAIT_QUEUE_HEAD(netdev_unregistering_wq); |
5546 | 5621 | ||
5547 | static void net_set_todo(struct net_device *dev) | 5622 | static void net_set_todo(struct net_device *dev) |
5548 | { | 5623 | { |
diff --git a/net/core/dst.c b/net/core/dst.c index ca4231ec7347..80d6286c8b62 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -142,12 +142,12 @@ loop: | |||
142 | mutex_unlock(&dst_gc_mutex); | 142 | mutex_unlock(&dst_gc_mutex); |
143 | } | 143 | } |
144 | 144 | ||
145 | int dst_discard(struct sk_buff *skb) | 145 | int dst_discard_sk(struct sock *sk, struct sk_buff *skb) |
146 | { | 146 | { |
147 | kfree_skb(skb); | 147 | kfree_skb(skb); |
148 | return 0; | 148 | return 0; |
149 | } | 149 | } |
150 | EXPORT_SYMBOL(dst_discard); | 150 | EXPORT_SYMBOL(dst_discard_sk); |
151 | 151 | ||
152 | const u32 dst_default_metrics[RTAX_MAX + 1] = { | 152 | const u32 dst_default_metrics[RTAX_MAX + 1] = { |
153 | /* This initializer is needed to force linker to place this variable | 153 | /* This initializer is needed to force linker to place this variable |
@@ -184,7 +184,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, | |||
184 | dst->xfrm = NULL; | 184 | dst->xfrm = NULL; |
185 | #endif | 185 | #endif |
186 | dst->input = dst_discard; | 186 | dst->input = dst_discard; |
187 | dst->output = dst_discard; | 187 | dst->output = dst_discard_sk; |
188 | dst->error = 0; | 188 | dst->error = 0; |
189 | dst->obsolete = initial_obsolete; | 189 | dst->obsolete = initial_obsolete; |
190 | dst->header_len = 0; | 190 | dst->header_len = 0; |
@@ -209,8 +209,10 @@ static void ___dst_free(struct dst_entry *dst) | |||
209 | /* The first case (dev==NULL) is required, when | 209 | /* The first case (dev==NULL) is required, when |
210 | protocol module is unloaded. | 210 | protocol module is unloaded. |
211 | */ | 211 | */ |
212 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) | 212 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { |
213 | dst->input = dst->output = dst_discard; | 213 | dst->input = dst_discard; |
214 | dst->output = dst_discard_sk; | ||
215 | } | ||
214 | dst->obsolete = DST_OBSOLETE_DEAD; | 216 | dst->obsolete = DST_OBSOLETE_DEAD; |
215 | } | 217 | } |
216 | 218 | ||
@@ -361,7 +363,8 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
361 | return; | 363 | return; |
362 | 364 | ||
363 | if (!unregister) { | 365 | if (!unregister) { |
364 | dst->input = dst->output = dst_discard; | 366 | dst->input = dst_discard; |
367 | dst->output = dst_discard_sk; | ||
365 | } else { | 368 | } else { |
366 | dst->dev = dev_net(dst->dev)->loopback_dev; | 369 | dst->dev = dev_net(dst->dev)->loopback_dev; |
367 | dev_hold(dst->dev); | 370 | dev_hold(dst->dev); |
diff --git a/net/core/filter.c b/net/core/filter.c index e08b3822c72a..9d79ca0a6e8e 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -122,6 +122,13 @@ noinline u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | |||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | /* Register mappings for user programs. */ | ||
126 | #define A_REG 0 | ||
127 | #define X_REG 7 | ||
128 | #define TMP_REG 8 | ||
129 | #define ARG2_REG 2 | ||
130 | #define ARG3_REG 3 | ||
131 | |||
125 | /** | 132 | /** |
126 | * __sk_run_filter - run a filter on a given context | 133 | * __sk_run_filter - run a filter on a given context |
127 | * @ctx: buffer to run the filter on | 134 | * @ctx: buffer to run the filter on |
@@ -242,6 +249,8 @@ unsigned int __sk_run_filter(void *ctx, const struct sock_filter_int *insn) | |||
242 | 249 | ||
243 | regs[FP_REG] = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; | 250 | regs[FP_REG] = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; |
244 | regs[ARG1_REG] = (u64) (unsigned long) ctx; | 251 | regs[ARG1_REG] = (u64) (unsigned long) ctx; |
252 | regs[A_REG] = 0; | ||
253 | regs[X_REG] = 0; | ||
245 | 254 | ||
246 | select_insn: | 255 | select_insn: |
247 | goto *jumptable[insn->code]; | 256 | goto *jumptable[insn->code]; |
@@ -600,6 +609,9 @@ static u64 __skb_get_nlattr(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) | |||
600 | if (skb_is_nonlinear(skb)) | 609 | if (skb_is_nonlinear(skb)) |
601 | return 0; | 610 | return 0; |
602 | 611 | ||
612 | if (skb->len < sizeof(struct nlattr)) | ||
613 | return 0; | ||
614 | |||
603 | if (A > skb->len - sizeof(struct nlattr)) | 615 | if (A > skb->len - sizeof(struct nlattr)) |
604 | return 0; | 616 | return 0; |
605 | 617 | ||
@@ -618,11 +630,14 @@ static u64 __skb_get_nlattr_nest(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) | |||
618 | if (skb_is_nonlinear(skb)) | 630 | if (skb_is_nonlinear(skb)) |
619 | return 0; | 631 | return 0; |
620 | 632 | ||
633 | if (skb->len < sizeof(struct nlattr)) | ||
634 | return 0; | ||
635 | |||
621 | if (A > skb->len - sizeof(struct nlattr)) | 636 | if (A > skb->len - sizeof(struct nlattr)) |
622 | return 0; | 637 | return 0; |
623 | 638 | ||
624 | nla = (struct nlattr *) &skb->data[A]; | 639 | nla = (struct nlattr *) &skb->data[A]; |
625 | if (nla->nla_len > A - skb->len) | 640 | if (nla->nla_len > skb->len - A) |
626 | return 0; | 641 | return 0; |
627 | 642 | ||
628 | nla = nla_find_nested(nla, X); | 643 | nla = nla_find_nested(nla, X); |
@@ -637,13 +652,6 @@ static u64 __get_raw_cpu_id(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) | |||
637 | return raw_smp_processor_id(); | 652 | return raw_smp_processor_id(); |
638 | } | 653 | } |
639 | 654 | ||
640 | /* Register mappings for user programs. */ | ||
641 | #define A_REG 0 | ||
642 | #define X_REG 7 | ||
643 | #define TMP_REG 8 | ||
644 | #define ARG2_REG 2 | ||
645 | #define ARG3_REG 3 | ||
646 | |||
647 | static bool convert_bpf_extensions(struct sock_filter *fp, | 655 | static bool convert_bpf_extensions(struct sock_filter *fp, |
648 | struct sock_filter_int **insnp) | 656 | struct sock_filter_int **insnp) |
649 | { | 657 | { |
@@ -1737,7 +1745,6 @@ void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) | |||
1737 | [BPF_S_ANC_RXHASH] = BPF_LD|BPF_B|BPF_ABS, | 1745 | [BPF_S_ANC_RXHASH] = BPF_LD|BPF_B|BPF_ABS, |
1738 | [BPF_S_ANC_CPU] = BPF_LD|BPF_B|BPF_ABS, | 1746 | [BPF_S_ANC_CPU] = BPF_LD|BPF_B|BPF_ABS, |
1739 | [BPF_S_ANC_ALU_XOR_X] = BPF_LD|BPF_B|BPF_ABS, | 1747 | [BPF_S_ANC_ALU_XOR_X] = BPF_LD|BPF_B|BPF_ABS, |
1740 | [BPF_S_ANC_SECCOMP_LD_W] = BPF_LD|BPF_B|BPF_ABS, | ||
1741 | [BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS, | 1748 | [BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS, |
1742 | [BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS, | 1749 | [BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS, |
1743 | [BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS, | 1750 | [BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS, |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8f8a96ef9f3f..32d872eec7f5 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1248,8 +1248,8 @@ void __neigh_set_probe_once(struct neighbour *neigh) | |||
1248 | neigh->updated = jiffies; | 1248 | neigh->updated = jiffies; |
1249 | if (!(neigh->nud_state & NUD_FAILED)) | 1249 | if (!(neigh->nud_state & NUD_FAILED)) |
1250 | return; | 1250 | return; |
1251 | neigh->nud_state = NUD_PROBE; | 1251 | neigh->nud_state = NUD_INCOMPLETE; |
1252 | atomic_set(&neigh->probes, NEIGH_VAR(neigh->parms, UCAST_PROBES)); | 1252 | atomic_set(&neigh->probes, neigh_max_probes(neigh)); |
1253 | neigh_add_timer(neigh, | 1253 | neigh_add_timer(neigh, |
1254 | jiffies + NEIGH_VAR(neigh->parms, RETRANS_TIME)); | 1254 | jiffies + NEIGH_VAR(neigh->parms, RETRANS_TIME)); |
1255 | } | 1255 | } |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 81d3a9a08453..7c8ffd974961 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | static LIST_HEAD(pernet_list); | 25 | static LIST_HEAD(pernet_list); |
26 | static struct list_head *first_device = &pernet_list; | 26 | static struct list_head *first_device = &pernet_list; |
27 | static DEFINE_MUTEX(net_mutex); | 27 | DEFINE_MUTEX(net_mutex); |
28 | 28 | ||
29 | LIST_HEAD(net_namespace_list); | 29 | LIST_HEAD(net_namespace_list); |
30 | EXPORT_SYMBOL_GPL(net_namespace_list); | 30 | EXPORT_SYMBOL_GPL(net_namespace_list); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d4ff41739b0f..2d8d8fcfa060 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -353,15 +353,46 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops) | |||
353 | } | 353 | } |
354 | EXPORT_SYMBOL_GPL(__rtnl_link_unregister); | 354 | EXPORT_SYMBOL_GPL(__rtnl_link_unregister); |
355 | 355 | ||
356 | /* Return with the rtnl_lock held when there are no network | ||
357 | * devices unregistering in any network namespace. | ||
358 | */ | ||
359 | static void rtnl_lock_unregistering_all(void) | ||
360 | { | ||
361 | struct net *net; | ||
362 | bool unregistering; | ||
363 | DEFINE_WAIT(wait); | ||
364 | |||
365 | for (;;) { | ||
366 | prepare_to_wait(&netdev_unregistering_wq, &wait, | ||
367 | TASK_UNINTERRUPTIBLE); | ||
368 | unregistering = false; | ||
369 | rtnl_lock(); | ||
370 | for_each_net(net) { | ||
371 | if (net->dev_unreg_count > 0) { | ||
372 | unregistering = true; | ||
373 | break; | ||
374 | } | ||
375 | } | ||
376 | if (!unregistering) | ||
377 | break; | ||
378 | __rtnl_unlock(); | ||
379 | schedule(); | ||
380 | } | ||
381 | finish_wait(&netdev_unregistering_wq, &wait); | ||
382 | } | ||
383 | |||
356 | /** | 384 | /** |
357 | * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. | 385 | * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. |
358 | * @ops: struct rtnl_link_ops * to unregister | 386 | * @ops: struct rtnl_link_ops * to unregister |
359 | */ | 387 | */ |
360 | void rtnl_link_unregister(struct rtnl_link_ops *ops) | 388 | void rtnl_link_unregister(struct rtnl_link_ops *ops) |
361 | { | 389 | { |
362 | rtnl_lock(); | 390 | /* Close the race with cleanup_net() */ |
391 | mutex_lock(&net_mutex); | ||
392 | rtnl_lock_unregistering_all(); | ||
363 | __rtnl_link_unregister(ops); | 393 | __rtnl_link_unregister(ops); |
364 | rtnl_unlock(); | 394 | rtnl_unlock(); |
395 | mutex_unlock(&net_mutex); | ||
365 | } | 396 | } |
366 | EXPORT_SYMBOL_GPL(rtnl_link_unregister); | 397 | EXPORT_SYMBOL_GPL(rtnl_link_unregister); |
367 | 398 | ||
@@ -774,7 +805,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, | |||
774 | return 0; | 805 | return 0; |
775 | } | 806 | } |
776 | 807 | ||
777 | static size_t rtnl_port_size(const struct net_device *dev) | 808 | static size_t rtnl_port_size(const struct net_device *dev, |
809 | u32 ext_filter_mask) | ||
778 | { | 810 | { |
779 | size_t port_size = nla_total_size(4) /* PORT_VF */ | 811 | size_t port_size = nla_total_size(4) /* PORT_VF */ |
780 | + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */ | 812 | + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */ |
@@ -790,7 +822,8 @@ static size_t rtnl_port_size(const struct net_device *dev) | |||
790 | size_t port_self_size = nla_total_size(sizeof(struct nlattr)) | 822 | size_t port_self_size = nla_total_size(sizeof(struct nlattr)) |
791 | + port_size; | 823 | + port_size; |
792 | 824 | ||
793 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent) | 825 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent || |
826 | !(ext_filter_mask & RTEXT_FILTER_VF)) | ||
794 | return 0; | 827 | return 0; |
795 | if (dev_num_vf(dev->dev.parent)) | 828 | if (dev_num_vf(dev->dev.parent)) |
796 | return port_self_size + vf_ports_size + | 829 | return port_self_size + vf_ports_size + |
@@ -826,7 +859,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, | |||
826 | + nla_total_size(ext_filter_mask | 859 | + nla_total_size(ext_filter_mask |
827 | & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ | 860 | & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ |
828 | + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ | 861 | + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ |
829 | + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ | 862 | + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ |
830 | + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ | 863 | + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ |
831 | + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */ | 864 | + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */ |
832 | + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */ | 865 | + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */ |
@@ -888,11 +921,13 @@ static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev) | |||
888 | return 0; | 921 | return 0; |
889 | } | 922 | } |
890 | 923 | ||
891 | static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev) | 924 | static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev, |
925 | u32 ext_filter_mask) | ||
892 | { | 926 | { |
893 | int err; | 927 | int err; |
894 | 928 | ||
895 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent) | 929 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent || |
930 | !(ext_filter_mask & RTEXT_FILTER_VF)) | ||
896 | return 0; | 931 | return 0; |
897 | 932 | ||
898 | err = rtnl_port_self_fill(skb, dev); | 933 | err = rtnl_port_self_fill(skb, dev); |
@@ -1079,7 +1114,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
1079 | nla_nest_end(skb, vfinfo); | 1114 | nla_nest_end(skb, vfinfo); |
1080 | } | 1115 | } |
1081 | 1116 | ||
1082 | if (rtnl_port_fill(skb, dev)) | 1117 | if (rtnl_port_fill(skb, dev, ext_filter_mask)) |
1083 | goto nla_put_failure; | 1118 | goto nla_put_failure; |
1084 | 1119 | ||
1085 | if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) { | 1120 | if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) { |
@@ -1198,6 +1233,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1198 | struct hlist_head *head; | 1233 | struct hlist_head *head; |
1199 | struct nlattr *tb[IFLA_MAX+1]; | 1234 | struct nlattr *tb[IFLA_MAX+1]; |
1200 | u32 ext_filter_mask = 0; | 1235 | u32 ext_filter_mask = 0; |
1236 | int err; | ||
1201 | 1237 | ||
1202 | s_h = cb->args[0]; | 1238 | s_h = cb->args[0]; |
1203 | s_idx = cb->args[1]; | 1239 | s_idx = cb->args[1]; |
@@ -1218,11 +1254,17 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1218 | hlist_for_each_entry_rcu(dev, head, index_hlist) { | 1254 | hlist_for_each_entry_rcu(dev, head, index_hlist) { |
1219 | if (idx < s_idx) | 1255 | if (idx < s_idx) |
1220 | goto cont; | 1256 | goto cont; |
1221 | if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, | 1257 | err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
1222 | NETLINK_CB(cb->skb).portid, | 1258 | NETLINK_CB(cb->skb).portid, |
1223 | cb->nlh->nlmsg_seq, 0, | 1259 | cb->nlh->nlmsg_seq, 0, |
1224 | NLM_F_MULTI, | 1260 | NLM_F_MULTI, |
1225 | ext_filter_mask) <= 0) | 1261 | ext_filter_mask); |
1262 | /* If we ran out of room on the first message, | ||
1263 | * we're in trouble | ||
1264 | */ | ||
1265 | WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); | ||
1266 | |||
1267 | if (err <= 0) | ||
1226 | goto out; | 1268 | goto out; |
1227 | 1269 | ||
1228 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | 1270 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
@@ -1395,7 +1437,8 @@ static int do_set_master(struct net_device *dev, int ifindex) | |||
1395 | return 0; | 1437 | return 0; |
1396 | } | 1438 | } |
1397 | 1439 | ||
1398 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | 1440 | static int do_setlink(const struct sk_buff *skb, |
1441 | struct net_device *dev, struct ifinfomsg *ifm, | ||
1399 | struct nlattr **tb, char *ifname, int modified) | 1442 | struct nlattr **tb, char *ifname, int modified) |
1400 | { | 1443 | { |
1401 | const struct net_device_ops *ops = dev->netdev_ops; | 1444 | const struct net_device_ops *ops = dev->netdev_ops; |
@@ -1407,7 +1450,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
1407 | err = PTR_ERR(net); | 1450 | err = PTR_ERR(net); |
1408 | goto errout; | 1451 | goto errout; |
1409 | } | 1452 | } |
1410 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) { | 1453 | if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { |
1411 | err = -EPERM; | 1454 | err = -EPERM; |
1412 | goto errout; | 1455 | goto errout; |
1413 | } | 1456 | } |
@@ -1661,7 +1704,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1661 | if (err < 0) | 1704 | if (err < 0) |
1662 | goto errout; | 1705 | goto errout; |
1663 | 1706 | ||
1664 | err = do_setlink(dev, ifm, tb, ifname, 0); | 1707 | err = do_setlink(skb, dev, ifm, tb, ifname, 0); |
1665 | errout: | 1708 | errout: |
1666 | return err; | 1709 | return err; |
1667 | } | 1710 | } |
@@ -1778,7 +1821,8 @@ err: | |||
1778 | } | 1821 | } |
1779 | EXPORT_SYMBOL(rtnl_create_link); | 1822 | EXPORT_SYMBOL(rtnl_create_link); |
1780 | 1823 | ||
1781 | static int rtnl_group_changelink(struct net *net, int group, | 1824 | static int rtnl_group_changelink(const struct sk_buff *skb, |
1825 | struct net *net, int group, | ||
1782 | struct ifinfomsg *ifm, | 1826 | struct ifinfomsg *ifm, |
1783 | struct nlattr **tb) | 1827 | struct nlattr **tb) |
1784 | { | 1828 | { |
@@ -1787,7 +1831,7 @@ static int rtnl_group_changelink(struct net *net, int group, | |||
1787 | 1831 | ||
1788 | for_each_netdev(net, dev) { | 1832 | for_each_netdev(net, dev) { |
1789 | if (dev->group == group) { | 1833 | if (dev->group == group) { |
1790 | err = do_setlink(dev, ifm, tb, NULL, 0); | 1834 | err = do_setlink(skb, dev, ifm, tb, NULL, 0); |
1791 | if (err < 0) | 1835 | if (err < 0) |
1792 | return err; | 1836 | return err; |
1793 | } | 1837 | } |
@@ -1929,12 +1973,12 @@ replay: | |||
1929 | modified = 1; | 1973 | modified = 1; |
1930 | } | 1974 | } |
1931 | 1975 | ||
1932 | return do_setlink(dev, ifm, tb, ifname, modified); | 1976 | return do_setlink(skb, dev, ifm, tb, ifname, modified); |
1933 | } | 1977 | } |
1934 | 1978 | ||
1935 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { | 1979 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { |
1936 | if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) | 1980 | if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) |
1937 | return rtnl_group_changelink(net, | 1981 | return rtnl_group_changelink(skb, net, |
1938 | nla_get_u32(tb[IFLA_GROUP]), | 1982 | nla_get_u32(tb[IFLA_GROUP]), |
1939 | ifm, tb); | 1983 | ifm, tb); |
1940 | return -ENODEV; | 1984 | return -ENODEV; |
@@ -2321,7 +2365,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2321 | int err = -EINVAL; | 2365 | int err = -EINVAL; |
2322 | __u8 *addr; | 2366 | __u8 *addr; |
2323 | 2367 | ||
2324 | if (!capable(CAP_NET_ADMIN)) | 2368 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
2325 | return -EPERM; | 2369 | return -EPERM; |
2326 | 2370 | ||
2327 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); | 2371 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); |
@@ -2773,7 +2817,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2773 | sz_idx = type>>2; | 2817 | sz_idx = type>>2; |
2774 | kind = type&3; | 2818 | kind = type&3; |
2775 | 2819 | ||
2776 | if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN)) | 2820 | if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) |
2777 | return -EPERM; | 2821 | return -EPERM; |
2778 | 2822 | ||
2779 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 2823 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1b62343f5837..8383b2bddeb9 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3076,7 +3076,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
3076 | if (unlikely(p->len + len >= 65536)) | 3076 | if (unlikely(p->len + len >= 65536)) |
3077 | return -E2BIG; | 3077 | return -E2BIG; |
3078 | 3078 | ||
3079 | lp = NAPI_GRO_CB(p)->last ?: p; | 3079 | lp = NAPI_GRO_CB(p)->last; |
3080 | pinfo = skb_shinfo(lp); | 3080 | pinfo = skb_shinfo(lp); |
3081 | 3081 | ||
3082 | if (headlen <= offset) { | 3082 | if (headlen <= offset) { |
@@ -3192,7 +3192,7 @@ merge: | |||
3192 | 3192 | ||
3193 | __skb_pull(skb, offset); | 3193 | __skb_pull(skb, offset); |
3194 | 3194 | ||
3195 | if (!NAPI_GRO_CB(p)->last) | 3195 | if (NAPI_GRO_CB(p)->last == p) |
3196 | skb_shinfo(p)->frag_list = skb; | 3196 | skb_shinfo(p)->frag_list = skb; |
3197 | else | 3197 | else |
3198 | NAPI_GRO_CB(p)->last->next = skb; | 3198 | NAPI_GRO_CB(p)->last->next = skb; |
diff --git a/net/core/sock.c b/net/core/sock.c index b4fff008136f..664ee4295b6f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -145,6 +145,55 @@ | |||
145 | static DEFINE_MUTEX(proto_list_mutex); | 145 | static DEFINE_MUTEX(proto_list_mutex); |
146 | static LIST_HEAD(proto_list); | 146 | static LIST_HEAD(proto_list); |
147 | 147 | ||
148 | /** | ||
149 | * sk_ns_capable - General socket capability test | ||
150 | * @sk: Socket to use a capability on or through | ||
151 | * @user_ns: The user namespace of the capability to use | ||
152 | * @cap: The capability to use | ||
153 | * | ||
154 | * Test to see if the opener of the socket had when the socket was | ||
155 | * created and the current process has the capability @cap in the user | ||
156 | * namespace @user_ns. | ||
157 | */ | ||
158 | bool sk_ns_capable(const struct sock *sk, | ||
159 | struct user_namespace *user_ns, int cap) | ||
160 | { | ||
161 | return file_ns_capable(sk->sk_socket->file, user_ns, cap) && | ||
162 | ns_capable(user_ns, cap); | ||
163 | } | ||
164 | EXPORT_SYMBOL(sk_ns_capable); | ||
165 | |||
166 | /** | ||
167 | * sk_capable - Socket global capability test | ||
168 | * @sk: Socket to use a capability on or through | ||
169 | * @cap: The global capbility to use | ||
170 | * | ||
171 | * Test to see if the opener of the socket had when the socket was | ||
172 | * created and the current process has the capability @cap in all user | ||
173 | * namespaces. | ||
174 | */ | ||
175 | bool sk_capable(const struct sock *sk, int cap) | ||
176 | { | ||
177 | return sk_ns_capable(sk, &init_user_ns, cap); | ||
178 | } | ||
179 | EXPORT_SYMBOL(sk_capable); | ||
180 | |||
181 | /** | ||
182 | * sk_net_capable - Network namespace socket capability test | ||
183 | * @sk: Socket to use a capability on or through | ||
184 | * @cap: The capability to use | ||
185 | * | ||
186 | * Test to see if the opener of the socket had when the socke was created | ||
187 | * and the current process has the capability @cap over the network namespace | ||
188 | * the socket is a member of. | ||
189 | */ | ||
190 | bool sk_net_capable(const struct sock *sk, int cap) | ||
191 | { | ||
192 | return sk_ns_capable(sk, sock_net(sk)->user_ns, cap); | ||
193 | } | ||
194 | EXPORT_SYMBOL(sk_net_capable); | ||
195 | |||
196 | |||
148 | #ifdef CONFIG_MEMCG_KMEM | 197 | #ifdef CONFIG_MEMCG_KMEM |
149 | int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) | 198 | int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) |
150 | { | 199 | { |
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index d7af18859322..a4216a4c9572 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
@@ -49,7 +49,7 @@ 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, | 52 | int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk, |
53 | struct sk_buff *skb, int attrtype) | 53 | struct sk_buff *skb, int attrtype) |
54 | { | 54 | { |
55 | struct sock_fprog_kern *fprog; | 55 | struct sock_fprog_kern *fprog; |
@@ -58,7 +58,7 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, | |||
58 | unsigned int flen; | 58 | unsigned int flen; |
59 | int err = 0; | 59 | int err = 0; |
60 | 60 | ||
61 | if (!ns_capable(user_ns, CAP_NET_ADMIN)) { | 61 | if (!may_report_filterinfo) { |
62 | nla_reserve(skb, attrtype, 0); | 62 | nla_reserve(skb, attrtype, 0); |
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
diff --git a/net/core/utils.c b/net/core/utils.c index 2f737bf90b3f..eed34338736c 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -348,8 +348,8 @@ static void __net_random_once_deferred(struct work_struct *w) | |||
348 | { | 348 | { |
349 | struct __net_random_once_work *work = | 349 | struct __net_random_once_work *work = |
350 | container_of(w, struct __net_random_once_work, work); | 350 | container_of(w, struct __net_random_once_work, work); |
351 | if (!static_key_enabled(work->key)) | 351 | BUG_ON(!static_key_enabled(work->key)); |
352 | static_key_slow_inc(work->key); | 352 | static_key_slow_dec(work->key); |
353 | kfree(work); | 353 | kfree(work); |
354 | } | 354 | } |
355 | 355 | ||
@@ -367,7 +367,7 @@ static void __net_random_once_disable_jump(struct static_key *key) | |||
367 | } | 367 | } |
368 | 368 | ||
369 | bool __net_get_random_once(void *buf, int nbytes, bool *done, | 369 | bool __net_get_random_once(void *buf, int nbytes, bool *done, |
370 | struct static_key *done_key) | 370 | struct static_key *once_key) |
371 | { | 371 | { |
372 | static DEFINE_SPINLOCK(lock); | 372 | static DEFINE_SPINLOCK(lock); |
373 | unsigned long flags; | 373 | unsigned long flags; |
@@ -382,7 +382,7 @@ bool __net_get_random_once(void *buf, int nbytes, bool *done, | |||
382 | *done = true; | 382 | *done = true; |
383 | spin_unlock_irqrestore(&lock, flags); | 383 | spin_unlock_irqrestore(&lock, flags); |
384 | 384 | ||
385 | __net_random_once_disable_jump(done_key); | 385 | __net_random_once_disable_jump(once_key); |
386 | 386 | ||
387 | return true; | 387 | return true; |
388 | } | 388 | } |