diff options
Diffstat (limited to 'net')
112 files changed, 1074 insertions, 669 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 762896ebfcf5..47c908f1f626 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -530,6 +530,23 @@ static const struct header_ops vlan_header_ops = { | |||
530 | .parse = eth_header_parse, | 530 | .parse = eth_header_parse, |
531 | }; | 531 | }; |
532 | 532 | ||
533 | static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev, | ||
534 | unsigned short type, | ||
535 | const void *daddr, const void *saddr, | ||
536 | unsigned int len) | ||
537 | { | ||
538 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | ||
539 | struct net_device *real_dev = vlan->real_dev; | ||
540 | |||
541 | return dev_hard_header(skb, real_dev, type, daddr, saddr, len); | ||
542 | } | ||
543 | |||
544 | static const struct header_ops vlan_passthru_header_ops = { | ||
545 | .create = vlan_passthru_hard_header, | ||
546 | .rebuild = dev_rebuild_header, | ||
547 | .parse = eth_header_parse, | ||
548 | }; | ||
549 | |||
533 | static struct device_type vlan_type = { | 550 | static struct device_type vlan_type = { |
534 | .name = "vlan", | 551 | .name = "vlan", |
535 | }; | 552 | }; |
@@ -573,7 +590,7 @@ static int vlan_dev_init(struct net_device *dev) | |||
573 | 590 | ||
574 | dev->needed_headroom = real_dev->needed_headroom; | 591 | dev->needed_headroom = real_dev->needed_headroom; |
575 | if (real_dev->features & NETIF_F_HW_VLAN_CTAG_TX) { | 592 | if (real_dev->features & NETIF_F_HW_VLAN_CTAG_TX) { |
576 | dev->header_ops = real_dev->header_ops; | 593 | dev->header_ops = &vlan_passthru_header_ops; |
577 | dev->hard_header_len = real_dev->hard_header_len; | 594 | dev->hard_header_len = real_dev->hard_header_len; |
578 | } else { | 595 | } else { |
579 | dev->header_ops = &vlan_header_ops; | 596 | dev->header_ops = &vlan_header_ops; |
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index a2b480a90872..b9c8a6eedf45 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -307,9 +307,9 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) | |||
307 | hard_iface->bat_iv.ogm_buff = ogm_buff; | 307 | hard_iface->bat_iv.ogm_buff = ogm_buff; |
308 | 308 | ||
309 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; | 309 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; |
310 | batadv_ogm_packet->header.packet_type = BATADV_IV_OGM; | 310 | batadv_ogm_packet->packet_type = BATADV_IV_OGM; |
311 | batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION; | 311 | batadv_ogm_packet->version = BATADV_COMPAT_VERSION; |
312 | batadv_ogm_packet->header.ttl = 2; | 312 | batadv_ogm_packet->ttl = 2; |
313 | batadv_ogm_packet->flags = BATADV_NO_FLAGS; | 313 | batadv_ogm_packet->flags = BATADV_NO_FLAGS; |
314 | batadv_ogm_packet->reserved = 0; | 314 | batadv_ogm_packet->reserved = 0; |
315 | batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; | 315 | batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; |
@@ -346,7 +346,7 @@ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) | |||
346 | 346 | ||
347 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; | 347 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; |
348 | batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP; | 348 | batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP; |
349 | batadv_ogm_packet->header.ttl = BATADV_TTL; | 349 | batadv_ogm_packet->ttl = BATADV_TTL; |
350 | } | 350 | } |
351 | 351 | ||
352 | /* when do we schedule our own ogm to be sent */ | 352 | /* when do we schedule our own ogm to be sent */ |
@@ -435,7 +435,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, | |||
435 | fwd_str, (packet_num > 0 ? "aggregated " : ""), | 435 | fwd_str, (packet_num > 0 ? "aggregated " : ""), |
436 | batadv_ogm_packet->orig, | 436 | batadv_ogm_packet->orig, |
437 | ntohl(batadv_ogm_packet->seqno), | 437 | ntohl(batadv_ogm_packet->seqno), |
438 | batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl, | 438 | batadv_ogm_packet->tq, batadv_ogm_packet->ttl, |
439 | (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? | 439 | (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? |
440 | "on" : "off"), | 440 | "on" : "off"), |
441 | hard_iface->net_dev->name, | 441 | hard_iface->net_dev->name, |
@@ -491,7 +491,7 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet) | |||
491 | /* multihomed peer assumed | 491 | /* multihomed peer assumed |
492 | * non-primary OGMs are only broadcasted on their interface | 492 | * non-primary OGMs are only broadcasted on their interface |
493 | */ | 493 | */ |
494 | if ((directlink && (batadv_ogm_packet->header.ttl == 1)) || | 494 | if ((directlink && (batadv_ogm_packet->ttl == 1)) || |
495 | (forw_packet->own && (forw_packet->if_incoming != primary_if))) { | 495 | (forw_packet->own && (forw_packet->if_incoming != primary_if))) { |
496 | /* FIXME: what about aggregated packets ? */ | 496 | /* FIXME: what about aggregated packets ? */ |
497 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 497 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
@@ -499,7 +499,7 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet) | |||
499 | (forw_packet->own ? "Sending own" : "Forwarding"), | 499 | (forw_packet->own ? "Sending own" : "Forwarding"), |
500 | batadv_ogm_packet->orig, | 500 | batadv_ogm_packet->orig, |
501 | ntohl(batadv_ogm_packet->seqno), | 501 | ntohl(batadv_ogm_packet->seqno), |
502 | batadv_ogm_packet->header.ttl, | 502 | batadv_ogm_packet->ttl, |
503 | forw_packet->if_incoming->net_dev->name, | 503 | forw_packet->if_incoming->net_dev->name, |
504 | forw_packet->if_incoming->net_dev->dev_addr); | 504 | forw_packet->if_incoming->net_dev->dev_addr); |
505 | 505 | ||
@@ -572,7 +572,7 @@ batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet, | |||
572 | */ | 572 | */ |
573 | if ((!directlink) && | 573 | if ((!directlink) && |
574 | (!(batadv_ogm_packet->flags & BATADV_DIRECTLINK)) && | 574 | (!(batadv_ogm_packet->flags & BATADV_DIRECTLINK)) && |
575 | (batadv_ogm_packet->header.ttl != 1) && | 575 | (batadv_ogm_packet->ttl != 1) && |
576 | 576 | ||
577 | /* own packets originating non-primary | 577 | /* own packets originating non-primary |
578 | * interfaces leave only that interface | 578 | * interfaces leave only that interface |
@@ -587,7 +587,7 @@ batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet, | |||
587 | * interface only - we still can aggregate | 587 | * interface only - we still can aggregate |
588 | */ | 588 | */ |
589 | if ((directlink) && | 589 | if ((directlink) && |
590 | (new_bat_ogm_packet->header.ttl == 1) && | 590 | (new_bat_ogm_packet->ttl == 1) && |
591 | (forw_packet->if_incoming == if_incoming) && | 591 | (forw_packet->if_incoming == if_incoming) && |
592 | 592 | ||
593 | /* packets from direct neighbors or | 593 | /* packets from direct neighbors or |
@@ -778,7 +778,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node, | |||
778 | struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); | 778 | struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); |
779 | uint16_t tvlv_len; | 779 | uint16_t tvlv_len; |
780 | 780 | ||
781 | if (batadv_ogm_packet->header.ttl <= 1) { | 781 | if (batadv_ogm_packet->ttl <= 1) { |
782 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n"); | 782 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n"); |
783 | return; | 783 | return; |
784 | } | 784 | } |
@@ -798,7 +798,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node, | |||
798 | 798 | ||
799 | tvlv_len = ntohs(batadv_ogm_packet->tvlv_len); | 799 | tvlv_len = ntohs(batadv_ogm_packet->tvlv_len); |
800 | 800 | ||
801 | batadv_ogm_packet->header.ttl--; | 801 | batadv_ogm_packet->ttl--; |
802 | memcpy(batadv_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); | 802 | memcpy(batadv_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); |
803 | 803 | ||
804 | /* apply hop penalty */ | 804 | /* apply hop penalty */ |
@@ -807,7 +807,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node, | |||
807 | 807 | ||
808 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 808 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
809 | "Forwarding packet: tq: %i, ttl: %i\n", | 809 | "Forwarding packet: tq: %i, ttl: %i\n", |
810 | batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl); | 810 | batadv_ogm_packet->tq, batadv_ogm_packet->ttl); |
811 | 811 | ||
812 | /* switch of primaries first hop flag when forwarding */ | 812 | /* switch of primaries first hop flag when forwarding */ |
813 | batadv_ogm_packet->flags &= ~BATADV_PRIMARIES_FIRST_HOP; | 813 | batadv_ogm_packet->flags &= ~BATADV_PRIMARIES_FIRST_HOP; |
@@ -972,8 +972,8 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, | |||
972 | spin_unlock_bh(&neigh_node->bat_iv.lq_update_lock); | 972 | spin_unlock_bh(&neigh_node->bat_iv.lq_update_lock); |
973 | 973 | ||
974 | if (dup_status == BATADV_NO_DUP) { | 974 | if (dup_status == BATADV_NO_DUP) { |
975 | orig_node->last_ttl = batadv_ogm_packet->header.ttl; | 975 | orig_node->last_ttl = batadv_ogm_packet->ttl; |
976 | neigh_node->last_ttl = batadv_ogm_packet->header.ttl; | 976 | neigh_node->last_ttl = batadv_ogm_packet->ttl; |
977 | } | 977 | } |
978 | 978 | ||
979 | batadv_bonding_candidate_add(bat_priv, orig_node, neigh_node); | 979 | batadv_bonding_candidate_add(bat_priv, orig_node, neigh_node); |
@@ -1247,7 +1247,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1247 | * packet in an aggregation. Here we expect that the padding | 1247 | * packet in an aggregation. Here we expect that the padding |
1248 | * is always zero (or not 0x01) | 1248 | * is always zero (or not 0x01) |
1249 | */ | 1249 | */ |
1250 | if (batadv_ogm_packet->header.packet_type != BATADV_IV_OGM) | 1250 | if (batadv_ogm_packet->packet_type != BATADV_IV_OGM) |
1251 | return; | 1251 | return; |
1252 | 1252 | ||
1253 | /* could be changed by schedule_own_packet() */ | 1253 | /* could be changed by schedule_own_packet() */ |
@@ -1267,8 +1267,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1267 | if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig, | 1267 | if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig, |
1268 | batadv_ogm_packet->prev_sender, | 1268 | batadv_ogm_packet->prev_sender, |
1269 | ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->tq, | 1269 | ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->tq, |
1270 | batadv_ogm_packet->header.ttl, | 1270 | batadv_ogm_packet->ttl, |
1271 | batadv_ogm_packet->header.version, has_directlink_flag); | 1271 | batadv_ogm_packet->version, has_directlink_flag); |
1272 | 1272 | ||
1273 | rcu_read_lock(); | 1273 | rcu_read_lock(); |
1274 | list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { | 1274 | list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { |
@@ -1433,7 +1433,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1433 | * seqno and similar ttl as the non-duplicate | 1433 | * seqno and similar ttl as the non-duplicate |
1434 | */ | 1434 | */ |
1435 | sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno); | 1435 | sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno); |
1436 | similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl; | 1436 | similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->ttl; |
1437 | if (is_bidirect && ((dup_status == BATADV_NO_DUP) || | 1437 | if (is_bidirect && ((dup_status == BATADV_NO_DUP) || |
1438 | (sameseq && similar_ttl))) | 1438 | (sameseq && similar_ttl))) |
1439 | batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, | 1439 | batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, |
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 6c8c3934bd7b..b316a4cb6f14 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c | |||
@@ -349,7 +349,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
349 | 349 | ||
350 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | 350 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; |
351 | 351 | ||
352 | switch (unicast_4addr_packet->u.header.packet_type) { | 352 | switch (unicast_4addr_packet->u.packet_type) { |
353 | case BATADV_UNICAST: | 353 | case BATADV_UNICAST: |
354 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 354 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
355 | "* encapsulated within a UNICAST packet\n"); | 355 | "* encapsulated within a UNICAST packet\n"); |
@@ -374,7 +374,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
374 | break; | 374 | break; |
375 | default: | 375 | default: |
376 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: Unknown (%u)!\n", | 376 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: Unknown (%u)!\n", |
377 | unicast_4addr_packet->u.header.packet_type); | 377 | unicast_4addr_packet->u.packet_type); |
378 | } | 378 | } |
379 | break; | 379 | break; |
380 | case BATADV_BCAST: | 380 | case BATADV_BCAST: |
@@ -387,7 +387,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
387 | default: | 387 | default: |
388 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 388 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
389 | "* encapsulated within an unknown packet type (0x%x)\n", | 389 | "* encapsulated within an unknown packet type (0x%x)\n", |
390 | unicast_4addr_packet->u.header.packet_type); | 390 | unicast_4addr_packet->u.packet_type); |
391 | } | 391 | } |
392 | } | 392 | } |
393 | 393 | ||
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index 271d321b3a04..6ddb6145ffb5 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
@@ -355,7 +355,7 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb, | |||
355 | batadv_add_counter(bat_priv, BATADV_CNT_FRAG_FWD_BYTES, | 355 | batadv_add_counter(bat_priv, BATADV_CNT_FRAG_FWD_BYTES, |
356 | skb->len + ETH_HLEN); | 356 | skb->len + ETH_HLEN); |
357 | 357 | ||
358 | packet->header.ttl--; | 358 | packet->ttl--; |
359 | batadv_send_skb_packet(skb, neigh_node->if_incoming, | 359 | batadv_send_skb_packet(skb, neigh_node->if_incoming, |
360 | neigh_node->addr); | 360 | neigh_node->addr); |
361 | ret = true; | 361 | ret = true; |
@@ -444,9 +444,9 @@ bool batadv_frag_send_packet(struct sk_buff *skb, | |||
444 | goto out_err; | 444 | goto out_err; |
445 | 445 | ||
446 | /* Create one header to be copied to all fragments */ | 446 | /* Create one header to be copied to all fragments */ |
447 | frag_header.header.packet_type = BATADV_UNICAST_FRAG; | 447 | frag_header.packet_type = BATADV_UNICAST_FRAG; |
448 | frag_header.header.version = BATADV_COMPAT_VERSION; | 448 | frag_header.version = BATADV_COMPAT_VERSION; |
449 | frag_header.header.ttl = BATADV_TTL; | 449 | frag_header.ttl = BATADV_TTL; |
450 | frag_header.seqno = htons(atomic_inc_return(&bat_priv->frag_seqno)); | 450 | frag_header.seqno = htons(atomic_inc_return(&bat_priv->frag_seqno)); |
451 | frag_header.reserved = 0; | 451 | frag_header.reserved = 0; |
452 | frag_header.no = 0; | 452 | frag_header.no = 0; |
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 29ae4efe3543..130cc3217e2b 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c | |||
@@ -194,7 +194,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, | |||
194 | goto free_skb; | 194 | goto free_skb; |
195 | } | 195 | } |
196 | 196 | ||
197 | if (icmp_header->header.packet_type != BATADV_ICMP) { | 197 | if (icmp_header->packet_type != BATADV_ICMP) { |
198 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 198 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
199 | "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); | 199 | "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); |
200 | len = -EINVAL; | 200 | len = -EINVAL; |
@@ -243,9 +243,9 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, | |||
243 | 243 | ||
244 | icmp_header->uid = socket_client->index; | 244 | icmp_header->uid = socket_client->index; |
245 | 245 | ||
246 | if (icmp_header->header.version != BATADV_COMPAT_VERSION) { | 246 | if (icmp_header->version != BATADV_COMPAT_VERSION) { |
247 | icmp_header->msg_type = BATADV_PARAMETER_PROBLEM; | 247 | icmp_header->msg_type = BATADV_PARAMETER_PROBLEM; |
248 | icmp_header->header.version = BATADV_COMPAT_VERSION; | 248 | icmp_header->version = BATADV_COMPAT_VERSION; |
249 | batadv_socket_add_packet(socket_client, icmp_header, | 249 | batadv_socket_add_packet(socket_client, icmp_header, |
250 | packet_len); | 250 | packet_len); |
251 | goto free_skb; | 251 | goto free_skb; |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index c51a5e568f0a..1511f64a6cea 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -383,17 +383,17 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
383 | 383 | ||
384 | batadv_ogm_packet = (struct batadv_ogm_packet *)skb->data; | 384 | batadv_ogm_packet = (struct batadv_ogm_packet *)skb->data; |
385 | 385 | ||
386 | if (batadv_ogm_packet->header.version != BATADV_COMPAT_VERSION) { | 386 | if (batadv_ogm_packet->version != BATADV_COMPAT_VERSION) { |
387 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 387 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
388 | "Drop packet: incompatible batman version (%i)\n", | 388 | "Drop packet: incompatible batman version (%i)\n", |
389 | batadv_ogm_packet->header.version); | 389 | batadv_ogm_packet->version); |
390 | goto err_free; | 390 | goto err_free; |
391 | } | 391 | } |
392 | 392 | ||
393 | /* all receive handlers return whether they received or reused | 393 | /* all receive handlers return whether they received or reused |
394 | * the supplied skb. if not, we have to free the skb. | 394 | * the supplied skb. if not, we have to free the skb. |
395 | */ | 395 | */ |
396 | idx = batadv_ogm_packet->header.packet_type; | 396 | idx = batadv_ogm_packet->packet_type; |
397 | ret = (*batadv_rx_handler[idx])(skb, hard_iface); | 397 | ret = (*batadv_rx_handler[idx])(skb, hard_iface); |
398 | 398 | ||
399 | if (ret == NET_RX_DROP) | 399 | if (ret == NET_RX_DROP) |
@@ -426,8 +426,8 @@ static void batadv_recv_handler_init(void) | |||
426 | BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4); | 426 | BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4); |
427 | BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4); | 427 | BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4); |
428 | BUILD_BUG_ON(offsetof(struct batadv_frag_packet, dest) != 4); | 428 | BUILD_BUG_ON(offsetof(struct batadv_frag_packet, dest) != 4); |
429 | BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, icmph.dst) != 4); | 429 | BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, dst) != 4); |
430 | BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, icmph.dst) != 4); | 430 | BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, dst) != 4); |
431 | 431 | ||
432 | /* broadcast packet */ | 432 | /* broadcast packet */ |
433 | batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet; | 433 | batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet; |
@@ -1119,9 +1119,9 @@ void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src, | |||
1119 | skb_reserve(skb, ETH_HLEN); | 1119 | skb_reserve(skb, ETH_HLEN); |
1120 | tvlv_buff = skb_put(skb, sizeof(*unicast_tvlv_packet) + tvlv_len); | 1120 | tvlv_buff = skb_put(skb, sizeof(*unicast_tvlv_packet) + tvlv_len); |
1121 | unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)tvlv_buff; | 1121 | unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)tvlv_buff; |
1122 | unicast_tvlv_packet->header.packet_type = BATADV_UNICAST_TVLV; | 1122 | unicast_tvlv_packet->packet_type = BATADV_UNICAST_TVLV; |
1123 | unicast_tvlv_packet->header.version = BATADV_COMPAT_VERSION; | 1123 | unicast_tvlv_packet->version = BATADV_COMPAT_VERSION; |
1124 | unicast_tvlv_packet->header.ttl = BATADV_TTL; | 1124 | unicast_tvlv_packet->ttl = BATADV_TTL; |
1125 | unicast_tvlv_packet->reserved = 0; | 1125 | unicast_tvlv_packet->reserved = 0; |
1126 | unicast_tvlv_packet->tvlv_len = htons(tvlv_len); | 1126 | unicast_tvlv_packet->tvlv_len = htons(tvlv_len); |
1127 | unicast_tvlv_packet->align = 0; | 1127 | unicast_tvlv_packet->align = 0; |
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 351e199bc0af..511d7e1eea38 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c | |||
@@ -722,7 +722,7 @@ static bool batadv_can_nc_with_orig(struct batadv_priv *bat_priv, | |||
722 | { | 722 | { |
723 | if (orig_node->last_real_seqno != ntohl(ogm_packet->seqno)) | 723 | if (orig_node->last_real_seqno != ntohl(ogm_packet->seqno)) |
724 | return false; | 724 | return false; |
725 | if (orig_node->last_ttl != ogm_packet->header.ttl + 1) | 725 | if (orig_node->last_ttl != ogm_packet->ttl + 1) |
726 | return false; | 726 | return false; |
727 | if (!batadv_compare_eth(ogm_packet->orig, ogm_packet->prev_sender)) | 727 | if (!batadv_compare_eth(ogm_packet->orig, ogm_packet->prev_sender)) |
728 | return false; | 728 | return false; |
@@ -1082,9 +1082,9 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv, | |||
1082 | coded_packet = (struct batadv_coded_packet *)skb_dest->data; | 1082 | coded_packet = (struct batadv_coded_packet *)skb_dest->data; |
1083 | skb_reset_mac_header(skb_dest); | 1083 | skb_reset_mac_header(skb_dest); |
1084 | 1084 | ||
1085 | coded_packet->header.packet_type = BATADV_CODED; | 1085 | coded_packet->packet_type = BATADV_CODED; |
1086 | coded_packet->header.version = BATADV_COMPAT_VERSION; | 1086 | coded_packet->version = BATADV_COMPAT_VERSION; |
1087 | coded_packet->header.ttl = packet1->header.ttl; | 1087 | coded_packet->ttl = packet1->ttl; |
1088 | 1088 | ||
1089 | /* Info about first unicast packet */ | 1089 | /* Info about first unicast packet */ |
1090 | memcpy(coded_packet->first_source, first_source, ETH_ALEN); | 1090 | memcpy(coded_packet->first_source, first_source, ETH_ALEN); |
@@ -1097,7 +1097,7 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv, | |||
1097 | memcpy(coded_packet->second_source, second_source, ETH_ALEN); | 1097 | memcpy(coded_packet->second_source, second_source, ETH_ALEN); |
1098 | memcpy(coded_packet->second_orig_dest, packet2->dest, ETH_ALEN); | 1098 | memcpy(coded_packet->second_orig_dest, packet2->dest, ETH_ALEN); |
1099 | coded_packet->second_crc = packet_id2; | 1099 | coded_packet->second_crc = packet_id2; |
1100 | coded_packet->second_ttl = packet2->header.ttl; | 1100 | coded_packet->second_ttl = packet2->ttl; |
1101 | coded_packet->second_ttvn = packet2->ttvn; | 1101 | coded_packet->second_ttvn = packet2->ttvn; |
1102 | coded_packet->coded_len = htons(coding_len); | 1102 | coded_packet->coded_len = htons(coding_len); |
1103 | 1103 | ||
@@ -1452,7 +1452,7 @@ bool batadv_nc_skb_forward(struct sk_buff *skb, | |||
1452 | /* We only handle unicast packets */ | 1452 | /* We only handle unicast packets */ |
1453 | payload = skb_network_header(skb); | 1453 | payload = skb_network_header(skb); |
1454 | packet = (struct batadv_unicast_packet *)payload; | 1454 | packet = (struct batadv_unicast_packet *)payload; |
1455 | if (packet->header.packet_type != BATADV_UNICAST) | 1455 | if (packet->packet_type != BATADV_UNICAST) |
1456 | goto out; | 1456 | goto out; |
1457 | 1457 | ||
1458 | /* Try to find a coding opportunity and send the skb if one is found */ | 1458 | /* Try to find a coding opportunity and send the skb if one is found */ |
@@ -1505,7 +1505,7 @@ void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv, | |||
1505 | /* Check for supported packet type */ | 1505 | /* Check for supported packet type */ |
1506 | payload = skb_network_header(skb); | 1506 | payload = skb_network_header(skb); |
1507 | packet = (struct batadv_unicast_packet *)payload; | 1507 | packet = (struct batadv_unicast_packet *)payload; |
1508 | if (packet->header.packet_type != BATADV_UNICAST) | 1508 | if (packet->packet_type != BATADV_UNICAST) |
1509 | goto out; | 1509 | goto out; |
1510 | 1510 | ||
1511 | /* Find existing nc_path or create a new */ | 1511 | /* Find existing nc_path or create a new */ |
@@ -1623,7 +1623,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
1623 | ttvn = coded_packet_tmp.second_ttvn; | 1623 | ttvn = coded_packet_tmp.second_ttvn; |
1624 | } else { | 1624 | } else { |
1625 | orig_dest = coded_packet_tmp.first_orig_dest; | 1625 | orig_dest = coded_packet_tmp.first_orig_dest; |
1626 | ttl = coded_packet_tmp.header.ttl; | 1626 | ttl = coded_packet_tmp.ttl; |
1627 | ttvn = coded_packet_tmp.first_ttvn; | 1627 | ttvn = coded_packet_tmp.first_ttvn; |
1628 | } | 1628 | } |
1629 | 1629 | ||
@@ -1648,9 +1648,9 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
1648 | 1648 | ||
1649 | /* Create decoded unicast packet */ | 1649 | /* Create decoded unicast packet */ |
1650 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 1650 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
1651 | unicast_packet->header.packet_type = BATADV_UNICAST; | 1651 | unicast_packet->packet_type = BATADV_UNICAST; |
1652 | unicast_packet->header.version = BATADV_COMPAT_VERSION; | 1652 | unicast_packet->version = BATADV_COMPAT_VERSION; |
1653 | unicast_packet->header.ttl = ttl; | 1653 | unicast_packet->ttl = ttl; |
1654 | memcpy(unicast_packet->dest, orig_dest, ETH_ALEN); | 1654 | memcpy(unicast_packet->dest, orig_dest, ETH_ALEN); |
1655 | unicast_packet->ttvn = ttvn; | 1655 | unicast_packet->ttvn = ttvn; |
1656 | 1656 | ||
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 207459b62966..2dd8f2422550 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h | |||
@@ -155,6 +155,7 @@ enum batadv_tvlv_type { | |||
155 | BATADV_TVLV_ROAM = 0x05, | 155 | BATADV_TVLV_ROAM = 0x05, |
156 | }; | 156 | }; |
157 | 157 | ||
158 | #pragma pack(2) | ||
158 | /* the destination hardware field in the ARP frame is used to | 159 | /* the destination hardware field in the ARP frame is used to |
159 | * transport the claim type and the group id | 160 | * transport the claim type and the group id |
160 | */ | 161 | */ |
@@ -163,24 +164,20 @@ struct batadv_bla_claim_dst { | |||
163 | uint8_t type; /* bla_claimframe */ | 164 | uint8_t type; /* bla_claimframe */ |
164 | __be16 group; /* group id */ | 165 | __be16 group; /* group id */ |
165 | }; | 166 | }; |
166 | 167 | #pragma pack() | |
167 | struct batadv_header { | ||
168 | uint8_t packet_type; | ||
169 | uint8_t version; /* batman version field */ | ||
170 | uint8_t ttl; | ||
171 | /* the parent struct has to add a byte after the header to make | ||
172 | * everything 4 bytes aligned again | ||
173 | */ | ||
174 | }; | ||
175 | 168 | ||
176 | /** | 169 | /** |
177 | * struct batadv_ogm_packet - ogm (routing protocol) packet | 170 | * struct batadv_ogm_packet - ogm (routing protocol) packet |
178 | * @header: common batman packet header | 171 | * @packet_type: batman-adv packet type, part of the general header |
172 | * @version: batman-adv protocol version, part of the genereal header | ||
173 | * @ttl: time to live for this packet, part of the genereal header | ||
179 | * @flags: contains routing relevant flags - see enum batadv_iv_flags | 174 | * @flags: contains routing relevant flags - see enum batadv_iv_flags |
180 | * @tvlv_len: length of tvlv data following the ogm header | 175 | * @tvlv_len: length of tvlv data following the ogm header |
181 | */ | 176 | */ |
182 | struct batadv_ogm_packet { | 177 | struct batadv_ogm_packet { |
183 | struct batadv_header header; | 178 | uint8_t packet_type; |
179 | uint8_t version; | ||
180 | uint8_t ttl; | ||
184 | uint8_t flags; | 181 | uint8_t flags; |
185 | __be32 seqno; | 182 | __be32 seqno; |
186 | uint8_t orig[ETH_ALEN]; | 183 | uint8_t orig[ETH_ALEN]; |
@@ -196,29 +193,51 @@ struct batadv_ogm_packet { | |||
196 | #define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) | 193 | #define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) |
197 | 194 | ||
198 | /** | 195 | /** |
199 | * batadv_icmp_header - common ICMP header | 196 | * batadv_icmp_header - common members among all the ICMP packets |
200 | * @header: common batman header | 197 | * @packet_type: batman-adv packet type, part of the general header |
198 | * @version: batman-adv protocol version, part of the genereal header | ||
199 | * @ttl: time to live for this packet, part of the genereal header | ||
201 | * @msg_type: ICMP packet type | 200 | * @msg_type: ICMP packet type |
202 | * @dst: address of the destination node | 201 | * @dst: address of the destination node |
203 | * @orig: address of the source node | 202 | * @orig: address of the source node |
204 | * @uid: local ICMP socket identifier | 203 | * @uid: local ICMP socket identifier |
204 | * @align: not used - useful for alignment purposes only | ||
205 | * | ||
206 | * This structure is used for ICMP packets parsing only and it is never sent | ||
207 | * over the wire. The alignment field at the end is there to ensure that | ||
208 | * members are padded the same way as they are in real packets. | ||
205 | */ | 209 | */ |
206 | struct batadv_icmp_header { | 210 | struct batadv_icmp_header { |
207 | struct batadv_header header; | 211 | uint8_t packet_type; |
212 | uint8_t version; | ||
213 | uint8_t ttl; | ||
208 | uint8_t msg_type; /* see ICMP message types above */ | 214 | uint8_t msg_type; /* see ICMP message types above */ |
209 | uint8_t dst[ETH_ALEN]; | 215 | uint8_t dst[ETH_ALEN]; |
210 | uint8_t orig[ETH_ALEN]; | 216 | uint8_t orig[ETH_ALEN]; |
211 | uint8_t uid; | 217 | uint8_t uid; |
218 | uint8_t align[3]; | ||
212 | }; | 219 | }; |
213 | 220 | ||
214 | /** | 221 | /** |
215 | * batadv_icmp_packet - ICMP packet | 222 | * batadv_icmp_packet - ICMP packet |
216 | * @icmph: common ICMP header | 223 | * @packet_type: batman-adv packet type, part of the general header |
224 | * @version: batman-adv protocol version, part of the genereal header | ||
225 | * @ttl: time to live for this packet, part of the genereal header | ||
226 | * @msg_type: ICMP packet type | ||
227 | * @dst: address of the destination node | ||
228 | * @orig: address of the source node | ||
229 | * @uid: local ICMP socket identifier | ||
217 | * @reserved: not used - useful for alignment | 230 | * @reserved: not used - useful for alignment |
218 | * @seqno: ICMP sequence number | 231 | * @seqno: ICMP sequence number |
219 | */ | 232 | */ |
220 | struct batadv_icmp_packet { | 233 | struct batadv_icmp_packet { |
221 | struct batadv_icmp_header icmph; | 234 | uint8_t packet_type; |
235 | uint8_t version; | ||
236 | uint8_t ttl; | ||
237 | uint8_t msg_type; /* see ICMP message types above */ | ||
238 | uint8_t dst[ETH_ALEN]; | ||
239 | uint8_t orig[ETH_ALEN]; | ||
240 | uint8_t uid; | ||
222 | uint8_t reserved; | 241 | uint8_t reserved; |
223 | __be16 seqno; | 242 | __be16 seqno; |
224 | }; | 243 | }; |
@@ -227,13 +246,25 @@ struct batadv_icmp_packet { | |||
227 | 246 | ||
228 | /** | 247 | /** |
229 | * batadv_icmp_packet_rr - ICMP RouteRecord packet | 248 | * batadv_icmp_packet_rr - ICMP RouteRecord packet |
230 | * @icmph: common ICMP header | 249 | * @packet_type: batman-adv packet type, part of the general header |
250 | * @version: batman-adv protocol version, part of the genereal header | ||
251 | * @ttl: time to live for this packet, part of the genereal header | ||
252 | * @msg_type: ICMP packet type | ||
253 | * @dst: address of the destination node | ||
254 | * @orig: address of the source node | ||
255 | * @uid: local ICMP socket identifier | ||
231 | * @rr_cur: number of entries the rr array | 256 | * @rr_cur: number of entries the rr array |
232 | * @seqno: ICMP sequence number | 257 | * @seqno: ICMP sequence number |
233 | * @rr: route record array | 258 | * @rr: route record array |
234 | */ | 259 | */ |
235 | struct batadv_icmp_packet_rr { | 260 | struct batadv_icmp_packet_rr { |
236 | struct batadv_icmp_header icmph; | 261 | uint8_t packet_type; |
262 | uint8_t version; | ||
263 | uint8_t ttl; | ||
264 | uint8_t msg_type; /* see ICMP message types above */ | ||
265 | uint8_t dst[ETH_ALEN]; | ||
266 | uint8_t orig[ETH_ALEN]; | ||
267 | uint8_t uid; | ||
237 | uint8_t rr_cur; | 268 | uint8_t rr_cur; |
238 | __be16 seqno; | 269 | __be16 seqno; |
239 | uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; | 270 | uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; |
@@ -253,8 +284,18 @@ struct batadv_icmp_packet_rr { | |||
253 | */ | 284 | */ |
254 | #pragma pack(2) | 285 | #pragma pack(2) |
255 | 286 | ||
287 | /** | ||
288 | * struct batadv_unicast_packet - unicast packet for network payload | ||
289 | * @packet_type: batman-adv packet type, part of the general header | ||
290 | * @version: batman-adv protocol version, part of the genereal header | ||
291 | * @ttl: time to live for this packet, part of the genereal header | ||
292 | * @ttvn: translation table version number | ||
293 | * @dest: originator destination of the unicast packet | ||
294 | */ | ||
256 | struct batadv_unicast_packet { | 295 | struct batadv_unicast_packet { |
257 | struct batadv_header header; | 296 | uint8_t packet_type; |
297 | uint8_t version; | ||
298 | uint8_t ttl; | ||
258 | uint8_t ttvn; /* destination translation table version number */ | 299 | uint8_t ttvn; /* destination translation table version number */ |
259 | uint8_t dest[ETH_ALEN]; | 300 | uint8_t dest[ETH_ALEN]; |
260 | /* "4 bytes boundary + 2 bytes" long to make the payload after the | 301 | /* "4 bytes boundary + 2 bytes" long to make the payload after the |
@@ -280,7 +321,9 @@ struct batadv_unicast_4addr_packet { | |||
280 | 321 | ||
281 | /** | 322 | /** |
282 | * struct batadv_frag_packet - fragmented packet | 323 | * struct batadv_frag_packet - fragmented packet |
283 | * @header: common batman packet header with type, compatversion, and ttl | 324 | * @packet_type: batman-adv packet type, part of the general header |
325 | * @version: batman-adv protocol version, part of the genereal header | ||
326 | * @ttl: time to live for this packet, part of the genereal header | ||
284 | * @dest: final destination used when routing fragments | 327 | * @dest: final destination used when routing fragments |
285 | * @orig: originator of the fragment used when merging the packet | 328 | * @orig: originator of the fragment used when merging the packet |
286 | * @no: fragment number within this sequence | 329 | * @no: fragment number within this sequence |
@@ -289,7 +332,9 @@ struct batadv_unicast_4addr_packet { | |||
289 | * @total_size: size of the merged packet | 332 | * @total_size: size of the merged packet |
290 | */ | 333 | */ |
291 | struct batadv_frag_packet { | 334 | struct batadv_frag_packet { |
292 | struct batadv_header header; | 335 | uint8_t packet_type; |
336 | uint8_t version; /* batman version field */ | ||
337 | uint8_t ttl; | ||
293 | #if defined(__BIG_ENDIAN_BITFIELD) | 338 | #if defined(__BIG_ENDIAN_BITFIELD) |
294 | uint8_t no:4; | 339 | uint8_t no:4; |
295 | uint8_t reserved:4; | 340 | uint8_t reserved:4; |
@@ -305,8 +350,19 @@ struct batadv_frag_packet { | |||
305 | __be16 total_size; | 350 | __be16 total_size; |
306 | }; | 351 | }; |
307 | 352 | ||
353 | /** | ||
354 | * struct batadv_bcast_packet - broadcast packet for network payload | ||
355 | * @packet_type: batman-adv packet type, part of the general header | ||
356 | * @version: batman-adv protocol version, part of the genereal header | ||
357 | * @ttl: time to live for this packet, part of the genereal header | ||
358 | * @reserved: reserved byte for alignment | ||
359 | * @seqno: sequence identification | ||
360 | * @orig: originator of the broadcast packet | ||
361 | */ | ||
308 | struct batadv_bcast_packet { | 362 | struct batadv_bcast_packet { |
309 | struct batadv_header header; | 363 | uint8_t packet_type; |
364 | uint8_t version; /* batman version field */ | ||
365 | uint8_t ttl; | ||
310 | uint8_t reserved; | 366 | uint8_t reserved; |
311 | __be32 seqno; | 367 | __be32 seqno; |
312 | uint8_t orig[ETH_ALEN]; | 368 | uint8_t orig[ETH_ALEN]; |
@@ -315,11 +371,11 @@ struct batadv_bcast_packet { | |||
315 | */ | 371 | */ |
316 | }; | 372 | }; |
317 | 373 | ||
318 | #pragma pack() | ||
319 | |||
320 | /** | 374 | /** |
321 | * struct batadv_coded_packet - network coded packet | 375 | * struct batadv_coded_packet - network coded packet |
322 | * @header: common batman packet header and ttl of first included packet | 376 | * @packet_type: batman-adv packet type, part of the general header |
377 | * @version: batman-adv protocol version, part of the genereal header | ||
378 | * @ttl: time to live for this packet, part of the genereal header | ||
323 | * @reserved: Align following fields to 2-byte boundaries | 379 | * @reserved: Align following fields to 2-byte boundaries |
324 | * @first_source: original source of first included packet | 380 | * @first_source: original source of first included packet |
325 | * @first_orig_dest: original destinal of first included packet | 381 | * @first_orig_dest: original destinal of first included packet |
@@ -334,7 +390,9 @@ struct batadv_bcast_packet { | |||
334 | * @coded_len: length of network coded part of the payload | 390 | * @coded_len: length of network coded part of the payload |
335 | */ | 391 | */ |
336 | struct batadv_coded_packet { | 392 | struct batadv_coded_packet { |
337 | struct batadv_header header; | 393 | uint8_t packet_type; |
394 | uint8_t version; /* batman version field */ | ||
395 | uint8_t ttl; | ||
338 | uint8_t first_ttvn; | 396 | uint8_t first_ttvn; |
339 | /* uint8_t first_dest[ETH_ALEN]; - saved in mac header destination */ | 397 | /* uint8_t first_dest[ETH_ALEN]; - saved in mac header destination */ |
340 | uint8_t first_source[ETH_ALEN]; | 398 | uint8_t first_source[ETH_ALEN]; |
@@ -349,9 +407,13 @@ struct batadv_coded_packet { | |||
349 | __be16 coded_len; | 407 | __be16 coded_len; |
350 | }; | 408 | }; |
351 | 409 | ||
410 | #pragma pack() | ||
411 | |||
352 | /** | 412 | /** |
353 | * struct batadv_unicast_tvlv - generic unicast packet with tvlv payload | 413 | * struct batadv_unicast_tvlv - generic unicast packet with tvlv payload |
354 | * @header: common batman packet header | 414 | * @packet_type: batman-adv packet type, part of the general header |
415 | * @version: batman-adv protocol version, part of the genereal header | ||
416 | * @ttl: time to live for this packet, part of the genereal header | ||
355 | * @reserved: reserved field (for packet alignment) | 417 | * @reserved: reserved field (for packet alignment) |
356 | * @src: address of the source | 418 | * @src: address of the source |
357 | * @dst: address of the destination | 419 | * @dst: address of the destination |
@@ -359,7 +421,9 @@ struct batadv_coded_packet { | |||
359 | * @align: 2 bytes to align the header to a 4 byte boundry | 421 | * @align: 2 bytes to align the header to a 4 byte boundry |
360 | */ | 422 | */ |
361 | struct batadv_unicast_tvlv_packet { | 423 | struct batadv_unicast_tvlv_packet { |
362 | struct batadv_header header; | 424 | uint8_t packet_type; |
425 | uint8_t version; /* batman version field */ | ||
426 | uint8_t ttl; | ||
363 | uint8_t reserved; | 427 | uint8_t reserved; |
364 | uint8_t dst[ETH_ALEN]; | 428 | uint8_t dst[ETH_ALEN]; |
365 | uint8_t src[ETH_ALEN]; | 429 | uint8_t src[ETH_ALEN]; |
@@ -420,13 +484,13 @@ struct batadv_tvlv_tt_vlan_data { | |||
420 | * struct batadv_tvlv_tt_change - translation table diff data | 484 | * struct batadv_tvlv_tt_change - translation table diff data |
421 | * @flags: status indicators concerning the non-mesh client (see | 485 | * @flags: status indicators concerning the non-mesh client (see |
422 | * batadv_tt_client_flags) | 486 | * batadv_tt_client_flags) |
423 | * @reserved: reserved field | 487 | * @reserved: reserved field - useful for alignment purposes only |
424 | * @addr: mac address of non-mesh client that triggered this tt change | 488 | * @addr: mac address of non-mesh client that triggered this tt change |
425 | * @vid: VLAN identifier | 489 | * @vid: VLAN identifier |
426 | */ | 490 | */ |
427 | struct batadv_tvlv_tt_change { | 491 | struct batadv_tvlv_tt_change { |
428 | uint8_t flags; | 492 | uint8_t flags; |
429 | uint8_t reserved; | 493 | uint8_t reserved[3]; |
430 | uint8_t addr[ETH_ALEN]; | 494 | uint8_t addr[ETH_ALEN]; |
431 | __be16 vid; | 495 | __be16 vid; |
432 | }; | 496 | }; |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index d4114d775ad6..46278bfb8fdb 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -308,7 +308,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, | |||
308 | memcpy(icmph->dst, icmph->orig, ETH_ALEN); | 308 | memcpy(icmph->dst, icmph->orig, ETH_ALEN); |
309 | memcpy(icmph->orig, primary_if->net_dev->dev_addr, ETH_ALEN); | 309 | memcpy(icmph->orig, primary_if->net_dev->dev_addr, ETH_ALEN); |
310 | icmph->msg_type = BATADV_ECHO_REPLY; | 310 | icmph->msg_type = BATADV_ECHO_REPLY; |
311 | icmph->header.ttl = BATADV_TTL; | 311 | icmph->ttl = BATADV_TTL; |
312 | 312 | ||
313 | res = batadv_send_skb_to_orig(skb, orig_node, NULL); | 313 | res = batadv_send_skb_to_orig(skb, orig_node, NULL); |
314 | if (res != NET_XMIT_DROP) | 314 | if (res != NET_XMIT_DROP) |
@@ -338,9 +338,9 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv, | |||
338 | icmp_packet = (struct batadv_icmp_packet *)skb->data; | 338 | icmp_packet = (struct batadv_icmp_packet *)skb->data; |
339 | 339 | ||
340 | /* send TTL exceeded if packet is an echo request (traceroute) */ | 340 | /* send TTL exceeded if packet is an echo request (traceroute) */ |
341 | if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) { | 341 | if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { |
342 | pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", | 342 | pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", |
343 | icmp_packet->icmph.orig, icmp_packet->icmph.dst); | 343 | icmp_packet->orig, icmp_packet->dst); |
344 | goto out; | 344 | goto out; |
345 | } | 345 | } |
346 | 346 | ||
@@ -349,7 +349,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv, | |||
349 | goto out; | 349 | goto out; |
350 | 350 | ||
351 | /* get routing information */ | 351 | /* get routing information */ |
352 | orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig); | 352 | orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); |
353 | if (!orig_node) | 353 | if (!orig_node) |
354 | goto out; | 354 | goto out; |
355 | 355 | ||
@@ -359,11 +359,11 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv, | |||
359 | 359 | ||
360 | icmp_packet = (struct batadv_icmp_packet *)skb->data; | 360 | icmp_packet = (struct batadv_icmp_packet *)skb->data; |
361 | 361 | ||
362 | memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN); | 362 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); |
363 | memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr, | 363 | memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, |
364 | ETH_ALEN); | 364 | ETH_ALEN); |
365 | icmp_packet->icmph.msg_type = BATADV_TTL_EXCEEDED; | 365 | icmp_packet->msg_type = BATADV_TTL_EXCEEDED; |
366 | icmp_packet->icmph.header.ttl = BATADV_TTL; | 366 | icmp_packet->ttl = BATADV_TTL; |
367 | 367 | ||
368 | if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) | 368 | if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) |
369 | ret = NET_RX_SUCCESS; | 369 | ret = NET_RX_SUCCESS; |
@@ -434,7 +434,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, | |||
434 | return batadv_recv_my_icmp_packet(bat_priv, skb); | 434 | return batadv_recv_my_icmp_packet(bat_priv, skb); |
435 | 435 | ||
436 | /* TTL exceeded */ | 436 | /* TTL exceeded */ |
437 | if (icmph->header.ttl < 2) | 437 | if (icmph->ttl < 2) |
438 | return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); | 438 | return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); |
439 | 439 | ||
440 | /* get routing information */ | 440 | /* get routing information */ |
@@ -449,7 +449,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, | |||
449 | icmph = (struct batadv_icmp_header *)skb->data; | 449 | icmph = (struct batadv_icmp_header *)skb->data; |
450 | 450 | ||
451 | /* decrement ttl */ | 451 | /* decrement ttl */ |
452 | icmph->header.ttl--; | 452 | icmph->ttl--; |
453 | 453 | ||
454 | /* route it */ | 454 | /* route it */ |
455 | if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP) | 455 | if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP) |
@@ -709,7 +709,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, | |||
709 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 709 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
710 | 710 | ||
711 | /* TTL exceeded */ | 711 | /* TTL exceeded */ |
712 | if (unicast_packet->header.ttl < 2) { | 712 | if (unicast_packet->ttl < 2) { |
713 | pr_debug("Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n", | 713 | pr_debug("Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n", |
714 | ethhdr->h_source, unicast_packet->dest); | 714 | ethhdr->h_source, unicast_packet->dest); |
715 | goto out; | 715 | goto out; |
@@ -727,9 +727,9 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, | |||
727 | 727 | ||
728 | /* decrement ttl */ | 728 | /* decrement ttl */ |
729 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 729 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
730 | unicast_packet->header.ttl--; | 730 | unicast_packet->ttl--; |
731 | 731 | ||
732 | switch (unicast_packet->header.packet_type) { | 732 | switch (unicast_packet->packet_type) { |
733 | case BATADV_UNICAST_4ADDR: | 733 | case BATADV_UNICAST_4ADDR: |
734 | hdr_len = sizeof(struct batadv_unicast_4addr_packet); | 734 | hdr_len = sizeof(struct batadv_unicast_4addr_packet); |
735 | break; | 735 | break; |
@@ -970,7 +970,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
970 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 970 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
971 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | 971 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; |
972 | 972 | ||
973 | is4addr = unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR; | 973 | is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR; |
974 | /* the caller function should have already pulled 2 bytes */ | 974 | /* the caller function should have already pulled 2 bytes */ |
975 | if (is4addr) | 975 | if (is4addr) |
976 | hdr_size = sizeof(*unicast_4addr_packet); | 976 | hdr_size = sizeof(*unicast_4addr_packet); |
@@ -1160,7 +1160,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, | |||
1160 | if (batadv_is_my_mac(bat_priv, bcast_packet->orig)) | 1160 | if (batadv_is_my_mac(bat_priv, bcast_packet->orig)) |
1161 | goto out; | 1161 | goto out; |
1162 | 1162 | ||
1163 | if (bcast_packet->header.ttl < 2) | 1163 | if (bcast_packet->ttl < 2) |
1164 | goto out; | 1164 | goto out; |
1165 | 1165 | ||
1166 | orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig); | 1166 | orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig); |
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index c83be5ebaa28..fba4dcfcfac2 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c | |||
@@ -161,11 +161,11 @@ batadv_send_skb_push_fill_unicast(struct sk_buff *skb, int hdr_size, | |||
161 | return false; | 161 | return false; |
162 | 162 | ||
163 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 163 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
164 | unicast_packet->header.version = BATADV_COMPAT_VERSION; | 164 | unicast_packet->version = BATADV_COMPAT_VERSION; |
165 | /* batman packet type: unicast */ | 165 | /* batman packet type: unicast */ |
166 | unicast_packet->header.packet_type = BATADV_UNICAST; | 166 | unicast_packet->packet_type = BATADV_UNICAST; |
167 | /* set unicast ttl */ | 167 | /* set unicast ttl */ |
168 | unicast_packet->header.ttl = BATADV_TTL; | 168 | unicast_packet->ttl = BATADV_TTL; |
169 | /* copy the destination for faster routing */ | 169 | /* copy the destination for faster routing */ |
170 | memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); | 170 | memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); |
171 | /* set the destination tt version number */ | 171 | /* set the destination tt version number */ |
@@ -221,7 +221,7 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv, | |||
221 | goto out; | 221 | goto out; |
222 | 222 | ||
223 | uc_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | 223 | uc_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; |
224 | uc_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR; | 224 | uc_4addr_packet->u.packet_type = BATADV_UNICAST_4ADDR; |
225 | memcpy(uc_4addr_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN); | 225 | memcpy(uc_4addr_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN); |
226 | uc_4addr_packet->subtype = packet_subtype; | 226 | uc_4addr_packet->subtype = packet_subtype; |
227 | uc_4addr_packet->reserved = 0; | 227 | uc_4addr_packet->reserved = 0; |
@@ -436,7 +436,7 @@ int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, | |||
436 | 436 | ||
437 | /* as we have a copy now, it is safe to decrease the TTL */ | 437 | /* as we have a copy now, it is safe to decrease the TTL */ |
438 | bcast_packet = (struct batadv_bcast_packet *)newskb->data; | 438 | bcast_packet = (struct batadv_bcast_packet *)newskb->data; |
439 | bcast_packet->header.ttl--; | 439 | bcast_packet->ttl--; |
440 | 440 | ||
441 | skb_reset_mac_header(newskb); | 441 | skb_reset_mac_header(newskb); |
442 | 442 | ||
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 36f050876f82..a8f99d1486c0 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -264,11 +264,11 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
264 | goto dropped; | 264 | goto dropped; |
265 | 265 | ||
266 | bcast_packet = (struct batadv_bcast_packet *)skb->data; | 266 | bcast_packet = (struct batadv_bcast_packet *)skb->data; |
267 | bcast_packet->header.version = BATADV_COMPAT_VERSION; | 267 | bcast_packet->version = BATADV_COMPAT_VERSION; |
268 | bcast_packet->header.ttl = BATADV_TTL; | 268 | bcast_packet->ttl = BATADV_TTL; |
269 | 269 | ||
270 | /* batman packet type: broadcast */ | 270 | /* batman packet type: broadcast */ |
271 | bcast_packet->header.packet_type = BATADV_BCAST; | 271 | bcast_packet->packet_type = BATADV_BCAST; |
272 | bcast_packet->reserved = 0; | 272 | bcast_packet->reserved = 0; |
273 | 273 | ||
274 | /* hw address of first interface is the orig mac because only | 274 | /* hw address of first interface is the orig mac because only |
@@ -328,7 +328,7 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
328 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, | 328 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, |
329 | int hdr_size, struct batadv_orig_node *orig_node) | 329 | int hdr_size, struct batadv_orig_node *orig_node) |
330 | { | 330 | { |
331 | struct batadv_header *batadv_header = (struct batadv_header *)skb->data; | 331 | struct batadv_bcast_packet *batadv_bcast_packet; |
332 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 332 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
333 | __be16 ethertype = htons(ETH_P_BATMAN); | 333 | __be16 ethertype = htons(ETH_P_BATMAN); |
334 | struct vlan_ethhdr *vhdr; | 334 | struct vlan_ethhdr *vhdr; |
@@ -336,7 +336,8 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
336 | unsigned short vid; | 336 | unsigned short vid; |
337 | bool is_bcast; | 337 | bool is_bcast; |
338 | 338 | ||
339 | is_bcast = (batadv_header->packet_type == BATADV_BCAST); | 339 | batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; |
340 | is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); | ||
340 | 341 | ||
341 | /* check if enough space is available for pulling, and pull */ | 342 | /* check if enough space is available for pulling, and pull */ |
342 | if (!pskb_may_pull(skb, hdr_size)) | 343 | if (!pskb_may_pull(skb, hdr_size)) |
@@ -345,7 +346,12 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
345 | skb_pull_rcsum(skb, hdr_size); | 346 | skb_pull_rcsum(skb, hdr_size); |
346 | skb_reset_mac_header(skb); | 347 | skb_reset_mac_header(skb); |
347 | 348 | ||
348 | vid = batadv_get_vid(skb, hdr_size); | 349 | /* clean the netfilter state now that the batman-adv header has been |
350 | * removed | ||
351 | */ | ||
352 | nf_reset(skb); | ||
353 | |||
354 | vid = batadv_get_vid(skb, 0); | ||
349 | ethhdr = eth_hdr(skb); | 355 | ethhdr = eth_hdr(skb); |
350 | 356 | ||
351 | switch (ntohs(ethhdr->h_proto)) { | 357 | switch (ntohs(ethhdr->h_proto)) { |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 4add57d4857f..ff625fedbc5e 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -333,7 +333,8 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv, | |||
333 | return; | 333 | return; |
334 | 334 | ||
335 | tt_change_node->change.flags = flags; | 335 | tt_change_node->change.flags = flags; |
336 | tt_change_node->change.reserved = 0; | 336 | memset(tt_change_node->change.reserved, 0, |
337 | sizeof(tt_change_node->change.reserved)); | ||
337 | memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN); | 338 | memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN); |
338 | tt_change_node->change.vid = htons(common->vid); | 339 | tt_change_node->change.vid = htons(common->vid); |
339 | 340 | ||
@@ -2221,7 +2222,8 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, | |||
2221 | ETH_ALEN); | 2222 | ETH_ALEN); |
2222 | tt_change->flags = tt_common_entry->flags; | 2223 | tt_change->flags = tt_common_entry->flags; |
2223 | tt_change->vid = htons(tt_common_entry->vid); | 2224 | tt_change->vid = htons(tt_common_entry->vid); |
2224 | tt_change->reserved = 0; | 2225 | memset(tt_change->reserved, 0, |
2226 | sizeof(tt_change->reserved)); | ||
2225 | 2227 | ||
2226 | tt_num_entries++; | 2228 | tt_num_entries++; |
2227 | tt_change++; | 2229 | tt_change++; |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 6a6c8bb4fd72..7552f9e3089c 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -940,8 +940,22 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
940 | bt_cb(skb)->pkt_type = *((unsigned char *) skb->data); | 940 | bt_cb(skb)->pkt_type = *((unsigned char *) skb->data); |
941 | skb_pull(skb, 1); | 941 | skb_pull(skb, 1); |
942 | 942 | ||
943 | if (hci_pi(sk)->channel == HCI_CHANNEL_RAW && | 943 | if (hci_pi(sk)->channel == HCI_CHANNEL_USER) { |
944 | bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { | 944 | /* No permission check is needed for user channel |
945 | * since that gets enforced when binding the socket. | ||
946 | * | ||
947 | * However check that the packet type is valid. | ||
948 | */ | ||
949 | if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT && | ||
950 | bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT && | ||
951 | bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) { | ||
952 | err = -EINVAL; | ||
953 | goto drop; | ||
954 | } | ||
955 | |||
956 | skb_queue_tail(&hdev->raw_q, skb); | ||
957 | queue_work(hdev->workqueue, &hdev->tx_work); | ||
958 | } else if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { | ||
945 | u16 opcode = get_unaligned_le16(skb->data); | 959 | u16 opcode = get_unaligned_le16(skb->data); |
946 | u16 ogf = hci_opcode_ogf(opcode); | 960 | u16 ogf = hci_opcode_ogf(opcode); |
947 | u16 ocf = hci_opcode_ocf(opcode); | 961 | u16 ocf = hci_opcode_ocf(opcode); |
@@ -972,14 +986,6 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
972 | goto drop; | 986 | goto drop; |
973 | } | 987 | } |
974 | 988 | ||
975 | if (hci_pi(sk)->channel == HCI_CHANNEL_USER && | ||
976 | bt_cb(skb)->pkt_type != HCI_COMMAND_PKT && | ||
977 | bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT && | ||
978 | bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) { | ||
979 | err = -EINVAL; | ||
980 | goto drop; | ||
981 | } | ||
982 | |||
983 | skb_queue_tail(&hdev->raw_q, skb); | 989 | skb_queue_tail(&hdev->raw_q, skb); |
984 | queue_work(hdev->workqueue, &hdev->tx_work); | 990 | queue_work(hdev->workqueue, &hdev->tx_work); |
985 | } | 991 | } |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 4c214b2b88ef..ef66365b7354 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1998,7 +1998,7 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) | |||
1998 | u32 old; | 1998 | u32 old; |
1999 | struct net_bridge_mdb_htable *mdb; | 1999 | struct net_bridge_mdb_htable *mdb; |
2000 | 2000 | ||
2001 | spin_lock(&br->multicast_lock); | 2001 | spin_lock_bh(&br->multicast_lock); |
2002 | if (!netif_running(br->dev)) | 2002 | if (!netif_running(br->dev)) |
2003 | goto unlock; | 2003 | goto unlock; |
2004 | 2004 | ||
@@ -2030,7 +2030,7 @@ rollback: | |||
2030 | } | 2030 | } |
2031 | 2031 | ||
2032 | unlock: | 2032 | unlock: |
2033 | spin_unlock(&br->multicast_lock); | 2033 | spin_unlock_bh(&br->multicast_lock); |
2034 | 2034 | ||
2035 | return err; | 2035 | return err; |
2036 | } | 2036 | } |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 229d820bdf0b..045d56eaeca2 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -426,6 +426,16 @@ netdev_features_t br_features_recompute(struct net_bridge *br, | |||
426 | int br_handle_frame_finish(struct sk_buff *skb); | 426 | int br_handle_frame_finish(struct sk_buff *skb); |
427 | rx_handler_result_t br_handle_frame(struct sk_buff **pskb); | 427 | rx_handler_result_t br_handle_frame(struct sk_buff **pskb); |
428 | 428 | ||
429 | static inline bool br_rx_handler_check_rcu(const struct net_device *dev) | ||
430 | { | ||
431 | return rcu_dereference(dev->rx_handler) == br_handle_frame; | ||
432 | } | ||
433 | |||
434 | static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev) | ||
435 | { | ||
436 | return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL; | ||
437 | } | ||
438 | |||
429 | /* br_ioctl.c */ | 439 | /* br_ioctl.c */ |
430 | int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 440 | int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
431 | int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, | 441 | int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 8660ea3be705..bdb459d21ad8 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
@@ -153,7 +153,7 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, | |||
153 | if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) | 153 | if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) |
154 | goto err; | 154 | goto err; |
155 | 155 | ||
156 | p = br_port_get_rcu(dev); | 156 | p = br_port_get_check_rcu(dev); |
157 | if (!p) | 157 | if (!p) |
158 | goto err; | 158 | goto err; |
159 | 159 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index ba3b7ea5ebb3..0ce469e5ec80 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2539,7 +2539,7 @@ static inline int skb_needs_linearize(struct sk_buff *skb, | |||
2539 | } | 2539 | } |
2540 | 2540 | ||
2541 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | 2541 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, |
2542 | struct netdev_queue *txq, void *accel_priv) | 2542 | struct netdev_queue *txq) |
2543 | { | 2543 | { |
2544 | const struct net_device_ops *ops = dev->netdev_ops; | 2544 | const struct net_device_ops *ops = dev->netdev_ops; |
2545 | int rc = NETDEV_TX_OK; | 2545 | int rc = NETDEV_TX_OK; |
@@ -2605,13 +2605,10 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2605 | dev_queue_xmit_nit(skb, dev); | 2605 | dev_queue_xmit_nit(skb, dev); |
2606 | 2606 | ||
2607 | skb_len = skb->len; | 2607 | skb_len = skb->len; |
2608 | if (accel_priv) | ||
2609 | rc = ops->ndo_dfwd_start_xmit(skb, dev, accel_priv); | ||
2610 | else | ||
2611 | rc = ops->ndo_start_xmit(skb, dev); | 2608 | rc = ops->ndo_start_xmit(skb, dev); |
2612 | 2609 | ||
2613 | trace_net_dev_xmit(skb, rc, dev, skb_len); | 2610 | trace_net_dev_xmit(skb, rc, dev, skb_len); |
2614 | if (rc == NETDEV_TX_OK && txq) | 2611 | if (rc == NETDEV_TX_OK) |
2615 | txq_trans_update(txq); | 2612 | txq_trans_update(txq); |
2616 | return rc; | 2613 | return rc; |
2617 | } | 2614 | } |
@@ -2627,10 +2624,7 @@ gso: | |||
2627 | dev_queue_xmit_nit(nskb, dev); | 2624 | dev_queue_xmit_nit(nskb, dev); |
2628 | 2625 | ||
2629 | skb_len = nskb->len; | 2626 | skb_len = nskb->len; |
2630 | if (accel_priv) | 2627 | rc = ops->ndo_start_xmit(nskb, dev); |
2631 | rc = ops->ndo_dfwd_start_xmit(nskb, dev, accel_priv); | ||
2632 | else | ||
2633 | rc = ops->ndo_start_xmit(nskb, dev); | ||
2634 | trace_net_dev_xmit(nskb, rc, dev, skb_len); | 2628 | trace_net_dev_xmit(nskb, rc, dev, skb_len); |
2635 | if (unlikely(rc != NETDEV_TX_OK)) { | 2629 | if (unlikely(rc != NETDEV_TX_OK)) { |
2636 | if (rc & ~NETDEV_TX_MASK) | 2630 | if (rc & ~NETDEV_TX_MASK) |
@@ -2811,7 +2805,7 @@ EXPORT_SYMBOL(dev_loopback_xmit); | |||
2811 | * the BH enable code must have IRQs enabled so that it will not deadlock. | 2805 | * the BH enable code must have IRQs enabled so that it will not deadlock. |
2812 | * --BLG | 2806 | * --BLG |
2813 | */ | 2807 | */ |
2814 | int dev_queue_xmit(struct sk_buff *skb) | 2808 | int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) |
2815 | { | 2809 | { |
2816 | struct net_device *dev = skb->dev; | 2810 | struct net_device *dev = skb->dev; |
2817 | struct netdev_queue *txq; | 2811 | struct netdev_queue *txq; |
@@ -2827,7 +2821,7 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
2827 | 2821 | ||
2828 | skb_update_prio(skb); | 2822 | skb_update_prio(skb); |
2829 | 2823 | ||
2830 | txq = netdev_pick_tx(dev, skb); | 2824 | txq = netdev_pick_tx(dev, skb, accel_priv); |
2831 | q = rcu_dereference_bh(txq->qdisc); | 2825 | q = rcu_dereference_bh(txq->qdisc); |
2832 | 2826 | ||
2833 | #ifdef CONFIG_NET_CLS_ACT | 2827 | #ifdef CONFIG_NET_CLS_ACT |
@@ -2863,7 +2857,7 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
2863 | 2857 | ||
2864 | if (!netif_xmit_stopped(txq)) { | 2858 | if (!netif_xmit_stopped(txq)) { |
2865 | __this_cpu_inc(xmit_recursion); | 2859 | __this_cpu_inc(xmit_recursion); |
2866 | rc = dev_hard_start_xmit(skb, dev, txq, NULL); | 2860 | rc = dev_hard_start_xmit(skb, dev, txq); |
2867 | __this_cpu_dec(xmit_recursion); | 2861 | __this_cpu_dec(xmit_recursion); |
2868 | if (dev_xmit_complete(rc)) { | 2862 | if (dev_xmit_complete(rc)) { |
2869 | HARD_TX_UNLOCK(dev, txq); | 2863 | HARD_TX_UNLOCK(dev, txq); |
@@ -2892,8 +2886,19 @@ out: | |||
2892 | rcu_read_unlock_bh(); | 2886 | rcu_read_unlock_bh(); |
2893 | return rc; | 2887 | return rc; |
2894 | } | 2888 | } |
2889 | |||
2890 | int dev_queue_xmit(struct sk_buff *skb) | ||
2891 | { | ||
2892 | return __dev_queue_xmit(skb, NULL); | ||
2893 | } | ||
2895 | EXPORT_SYMBOL(dev_queue_xmit); | 2894 | EXPORT_SYMBOL(dev_queue_xmit); |
2896 | 2895 | ||
2896 | int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv) | ||
2897 | { | ||
2898 | return __dev_queue_xmit(skb, accel_priv); | ||
2899 | } | ||
2900 | EXPORT_SYMBOL(dev_queue_xmit_accel); | ||
2901 | |||
2897 | 2902 | ||
2898 | /*======================================================================= | 2903 | /*======================================================================= |
2899 | Receiver routines | 2904 | Receiver routines |
@@ -4500,7 +4505,7 @@ struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev, | |||
4500 | { | 4505 | { |
4501 | struct netdev_adjacent *upper; | 4506 | struct netdev_adjacent *upper; |
4502 | 4507 | ||
4503 | WARN_ON_ONCE(!rcu_read_lock_held()); | 4508 | WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held()); |
4504 | 4509 | ||
4505 | upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); | 4510 | upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); |
4506 | 4511 | ||
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 95897183226e..e70301eb7a4a 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
@@ -64,7 +64,6 @@ static struct genl_family net_drop_monitor_family = { | |||
64 | .hdrsize = 0, | 64 | .hdrsize = 0, |
65 | .name = "NET_DM", | 65 | .name = "NET_DM", |
66 | .version = 2, | 66 | .version = 2, |
67 | .maxattr = NET_DM_CMD_MAX, | ||
68 | }; | 67 | }; |
69 | 68 | ||
70 | static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); | 69 | static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); |
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index d6ef17322500..2fc5beaf5783 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
@@ -395,17 +395,21 @@ u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb) | |||
395 | EXPORT_SYMBOL(__netdev_pick_tx); | 395 | EXPORT_SYMBOL(__netdev_pick_tx); |
396 | 396 | ||
397 | struct netdev_queue *netdev_pick_tx(struct net_device *dev, | 397 | struct netdev_queue *netdev_pick_tx(struct net_device *dev, |
398 | struct sk_buff *skb) | 398 | struct sk_buff *skb, |
399 | void *accel_priv) | ||
399 | { | 400 | { |
400 | int queue_index = 0; | 401 | int queue_index = 0; |
401 | 402 | ||
402 | if (dev->real_num_tx_queues != 1) { | 403 | if (dev->real_num_tx_queues != 1) { |
403 | const struct net_device_ops *ops = dev->netdev_ops; | 404 | const struct net_device_ops *ops = dev->netdev_ops; |
404 | if (ops->ndo_select_queue) | 405 | if (ops->ndo_select_queue) |
405 | queue_index = ops->ndo_select_queue(dev, skb); | 406 | queue_index = ops->ndo_select_queue(dev, skb, |
407 | accel_priv); | ||
406 | else | 408 | else |
407 | queue_index = __netdev_pick_tx(dev, skb); | 409 | queue_index = __netdev_pick_tx(dev, skb); |
408 | queue_index = dev_cap_txqueue(dev, queue_index); | 410 | |
411 | if (!accel_priv) | ||
412 | queue_index = dev_cap_txqueue(dev, queue_index); | ||
409 | } | 413 | } |
410 | 414 | ||
411 | skb_set_queue_mapping(skb, queue_index); | 415 | skb_set_queue_mapping(skb, queue_index); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index ca15f32821fb..932c6d7cf666 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1161,6 +1161,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1161 | neigh->parms->reachable_time : | 1161 | neigh->parms->reachable_time : |
1162 | 0))); | 1162 | 0))); |
1163 | neigh->nud_state = new; | 1163 | neigh->nud_state = new; |
1164 | notify = 1; | ||
1164 | } | 1165 | } |
1165 | 1166 | ||
1166 | if (lladdr != neigh->ha) { | 1167 | if (lladdr != neigh->ha) { |
@@ -1274,7 +1275,7 @@ int neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb) | |||
1274 | 1275 | ||
1275 | if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, | 1276 | if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, |
1276 | skb->len) < 0 && | 1277 | skb->len) < 0 && |
1277 | dev->header_ops->rebuild(skb)) | 1278 | dev_rebuild_header(skb)) |
1278 | return 0; | 1279 | return 0; |
1279 | 1280 | ||
1280 | return dev_queue_xmit(skb); | 1281 | return dev_queue_xmit(skb); |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 8f971990677c..19fe9c717ced 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -375,7 +375,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
375 | if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) { | 375 | if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) { |
376 | struct netdev_queue *txq; | 376 | struct netdev_queue *txq; |
377 | 377 | ||
378 | txq = netdev_pick_tx(dev, skb); | 378 | txq = netdev_pick_tx(dev, skb, NULL); |
379 | 379 | ||
380 | /* try until next clock tick */ | 380 | /* try until next clock tick */ |
381 | for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; | 381 | for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; |
@@ -386,8 +386,14 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
386 | !vlan_hw_offload_capable(netif_skb_features(skb), | 386 | !vlan_hw_offload_capable(netif_skb_features(skb), |
387 | skb->vlan_proto)) { | 387 | skb->vlan_proto)) { |
388 | skb = __vlan_put_tag(skb, skb->vlan_proto, vlan_tx_tag_get(skb)); | 388 | skb = __vlan_put_tag(skb, skb->vlan_proto, vlan_tx_tag_get(skb)); |
389 | if (unlikely(!skb)) | 389 | if (unlikely(!skb)) { |
390 | break; | 390 | /* This is actually a packet drop, but we |
391 | * don't want the code at the end of this | ||
392 | * function to try and re-queue a NULL skb. | ||
393 | */ | ||
394 | status = NETDEV_TX_OK; | ||
395 | goto unlock_txq; | ||
396 | } | ||
391 | skb->vlan_tci = 0; | 397 | skb->vlan_tci = 0; |
392 | } | 398 | } |
393 | 399 | ||
@@ -395,6 +401,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
395 | if (status == NETDEV_TX_OK) | 401 | if (status == NETDEV_TX_OK) |
396 | txq_trans_update(txq); | 402 | txq_trans_update(txq); |
397 | } | 403 | } |
404 | unlock_txq: | ||
398 | __netif_tx_unlock(txq); | 405 | __netif_tx_unlock(txq); |
399 | 406 | ||
400 | if (status == NETDEV_TX_OK) | 407 | if (status == NETDEV_TX_OK) |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2718fed53d8c..06e72d3cdf60 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3584,6 +3584,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
3584 | skb->tstamp.tv64 = 0; | 3584 | skb->tstamp.tv64 = 0; |
3585 | skb->pkt_type = PACKET_HOST; | 3585 | skb->pkt_type = PACKET_HOST; |
3586 | skb->skb_iif = 0; | 3586 | skb->skb_iif = 0; |
3587 | skb->local_df = 0; | ||
3587 | skb_dst_drop(skb); | 3588 | skb_dst_drop(skb); |
3588 | skb->mark = 0; | 3589 | skb->mark = 0; |
3589 | secpath_reset(skb); | 3590 | secpath_reset(skb); |
diff --git a/net/core/sock.c b/net/core/sock.c index ab20ed9b0f31..5393b4b719d7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -882,7 +882,7 @@ set_rcvbuf: | |||
882 | 882 | ||
883 | case SO_PEEK_OFF: | 883 | case SO_PEEK_OFF: |
884 | if (sock->ops->set_peek_off) | 884 | if (sock->ops->set_peek_off) |
885 | sock->ops->set_peek_off(sk, val); | 885 | ret = sock->ops->set_peek_off(sk, val); |
886 | else | 886 | else |
887 | ret = -EOPNOTSUPP; | 887 | ret = -EOPNOTSUPP; |
888 | break; | 888 | break; |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 4ac71ff7c2e4..2b90a786e475 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -851,7 +851,6 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
851 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 851 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
852 | if (flowlabel == NULL) | 852 | if (flowlabel == NULL) |
853 | return -EINVAL; | 853 | return -EINVAL; |
854 | usin->sin6_addr = flowlabel->dst; | ||
855 | fl6_sock_release(flowlabel); | 854 | fl6_sock_release(flowlabel); |
856 | } | 855 | } |
857 | } | 856 | } |
diff --git a/net/dccp/probe.c b/net/dccp/probe.c index 4c6bdf97a657..595ddf0459db 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c | |||
@@ -152,17 +152,6 @@ static const struct file_operations dccpprobe_fops = { | |||
152 | .llseek = noop_llseek, | 152 | .llseek = noop_llseek, |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static __init int setup_jprobe(void) | ||
156 | { | ||
157 | int ret = register_jprobe(&dccp_send_probe); | ||
158 | |||
159 | if (ret) { | ||
160 | request_module("dccp"); | ||
161 | ret = register_jprobe(&dccp_send_probe); | ||
162 | } | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static __init int dccpprobe_init(void) | 155 | static __init int dccpprobe_init(void) |
167 | { | 156 | { |
168 | int ret = -ENOMEM; | 157 | int ret = -ENOMEM; |
@@ -174,7 +163,13 @@ static __init int dccpprobe_init(void) | |||
174 | if (!proc_create(procname, S_IRUSR, init_net.proc_net, &dccpprobe_fops)) | 163 | if (!proc_create(procname, S_IRUSR, init_net.proc_net, &dccpprobe_fops)) |
175 | goto err0; | 164 | goto err0; |
176 | 165 | ||
177 | ret = setup_jprobe(); | 166 | ret = register_jprobe(&dccp_send_probe); |
167 | if (ret) { | ||
168 | ret = request_module("dccp"); | ||
169 | if (!ret) | ||
170 | ret = register_jprobe(&dccp_send_probe); | ||
171 | } | ||
172 | |||
178 | if (ret) | 173 | if (ret) |
179 | goto err1; | 174 | goto err1; |
180 | 175 | ||
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 459e200c08a4..a2d2456a557a 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -547,7 +547,7 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
547 | hc06_ptr += 3; | 547 | hc06_ptr += 3; |
548 | } else { | 548 | } else { |
549 | /* compress nothing */ | 549 | /* compress nothing */ |
550 | memcpy(hc06_ptr, &hdr, 4); | 550 | memcpy(hc06_ptr, hdr, 4); |
551 | /* replace the top byte with new ECN | DSCP format */ | 551 | /* replace the top byte with new ECN | DSCP format */ |
552 | *hc06_ptr = tmp; | 552 | *hc06_ptr = tmp; |
553 | hc06_ptr += 4; | 553 | hc06_ptr += 4; |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 523be38e37de..f2e15738534d 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -104,7 +104,10 @@ errout: | |||
104 | static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) | 104 | static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) |
105 | { | 105 | { |
106 | struct fib_result *result = (struct fib_result *) arg->result; | 106 | struct fib_result *result = (struct fib_result *) arg->result; |
107 | struct net_device *dev = result->fi->fib_dev; | 107 | struct net_device *dev = NULL; |
108 | |||
109 | if (result->fi) | ||
110 | dev = result->fi->fib_dev; | ||
108 | 111 | ||
109 | /* do not accept result if the route does | 112 | /* do not accept result if the route does |
110 | * not meet the required prefix length | 113 | * not meet the required prefix length |
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index e5d436188464..2cd02f32f99f 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c | |||
@@ -28,6 +28,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, | |||
28 | netdev_features_t enc_features; | 28 | netdev_features_t enc_features; |
29 | int ghl = GRE_HEADER_SECTION; | 29 | int ghl = GRE_HEADER_SECTION; |
30 | struct gre_base_hdr *greh; | 30 | struct gre_base_hdr *greh; |
31 | u16 mac_offset = skb->mac_header; | ||
31 | int mac_len = skb->mac_len; | 32 | int mac_len = skb->mac_len; |
32 | __be16 protocol = skb->protocol; | 33 | __be16 protocol = skb->protocol; |
33 | int tnl_hlen; | 34 | int tnl_hlen; |
@@ -58,13 +59,13 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, | |||
58 | } else | 59 | } else |
59 | csum = false; | 60 | csum = false; |
60 | 61 | ||
62 | if (unlikely(!pskb_may_pull(skb, ghl))) | ||
63 | goto out; | ||
64 | |||
61 | /* setup inner skb. */ | 65 | /* setup inner skb. */ |
62 | skb->protocol = greh->protocol; | 66 | skb->protocol = greh->protocol; |
63 | skb->encapsulation = 0; | 67 | skb->encapsulation = 0; |
64 | 68 | ||
65 | if (unlikely(!pskb_may_pull(skb, ghl))) | ||
66 | goto out; | ||
67 | |||
68 | __skb_pull(skb, ghl); | 69 | __skb_pull(skb, ghl); |
69 | skb_reset_mac_header(skb); | 70 | skb_reset_mac_header(skb); |
70 | skb_set_network_header(skb, skb_inner_network_offset(skb)); | 71 | skb_set_network_header(skb, skb_inner_network_offset(skb)); |
@@ -73,8 +74,10 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, | |||
73 | /* segment inner packet. */ | 74 | /* segment inner packet. */ |
74 | enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); | 75 | enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); |
75 | segs = skb_mac_gso_segment(skb, enc_features); | 76 | segs = skb_mac_gso_segment(skb, enc_features); |
76 | if (!segs || IS_ERR(segs)) | 77 | if (!segs || IS_ERR(segs)) { |
78 | skb_gso_error_unwind(skb, protocol, ghl, mac_offset, mac_len); | ||
77 | goto out; | 79 | goto out; |
80 | } | ||
78 | 81 | ||
79 | skb = segs; | 82 | skb = segs; |
80 | tnl_hlen = skb_tnl_header_len(skb); | 83 | tnl_hlen = skb_tnl_header_len(skb); |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 56a964a553d2..a0f52dac8940 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -106,6 +106,10 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
106 | 106 | ||
107 | r->id.idiag_sport = inet->inet_sport; | 107 | r->id.idiag_sport = inet->inet_sport; |
108 | r->id.idiag_dport = inet->inet_dport; | 108 | r->id.idiag_dport = inet->inet_dport; |
109 | |||
110 | memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src)); | ||
111 | memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst)); | ||
112 | |||
109 | r->id.idiag_src[0] = inet->inet_rcv_saddr; | 113 | r->id.idiag_src[0] = inet->inet_rcv_saddr; |
110 | r->id.idiag_dst[0] = inet->inet_daddr; | 114 | r->id.idiag_dst[0] = inet->inet_daddr; |
111 | 115 | ||
@@ -240,12 +244,19 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | |||
240 | 244 | ||
241 | r->idiag_family = tw->tw_family; | 245 | r->idiag_family = tw->tw_family; |
242 | r->idiag_retrans = 0; | 246 | r->idiag_retrans = 0; |
247 | |||
243 | r->id.idiag_if = tw->tw_bound_dev_if; | 248 | r->id.idiag_if = tw->tw_bound_dev_if; |
244 | sock_diag_save_cookie(tw, r->id.idiag_cookie); | 249 | sock_diag_save_cookie(tw, r->id.idiag_cookie); |
250 | |||
245 | r->id.idiag_sport = tw->tw_sport; | 251 | r->id.idiag_sport = tw->tw_sport; |
246 | r->id.idiag_dport = tw->tw_dport; | 252 | r->id.idiag_dport = tw->tw_dport; |
253 | |||
254 | memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src)); | ||
255 | memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst)); | ||
256 | |||
247 | r->id.idiag_src[0] = tw->tw_rcv_saddr; | 257 | r->id.idiag_src[0] = tw->tw_rcv_saddr; |
248 | r->id.idiag_dst[0] = tw->tw_daddr; | 258 | r->id.idiag_dst[0] = tw->tw_daddr; |
259 | |||
249 | r->idiag_state = tw->tw_substate; | 260 | r->idiag_state = tw->tw_substate; |
250 | r->idiag_timer = 3; | 261 | r->idiag_timer = 3; |
251 | r->idiag_expires = jiffies_to_msecs(tmo); | 262 | r->idiag_expires = jiffies_to_msecs(tmo); |
@@ -726,8 +737,13 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
726 | 737 | ||
727 | r->id.idiag_sport = inet->inet_sport; | 738 | r->id.idiag_sport = inet->inet_sport; |
728 | r->id.idiag_dport = ireq->ir_rmt_port; | 739 | r->id.idiag_dport = ireq->ir_rmt_port; |
740 | |||
741 | memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src)); | ||
742 | memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst)); | ||
743 | |||
729 | r->id.idiag_src[0] = ireq->ir_loc_addr; | 744 | r->id.idiag_src[0] = ireq->ir_loc_addr; |
730 | r->id.idiag_dst[0] = ireq->ir_rmt_addr; | 745 | r->id.idiag_dst[0] = ireq->ir_rmt_addr; |
746 | |||
731 | r->idiag_expires = jiffies_to_msecs(tmo); | 747 | r->idiag_expires = jiffies_to_msecs(tmo); |
732 | r->idiag_rqueue = 0; | 748 | r->idiag_rqueue = 0; |
733 | r->idiag_wqueue = 0; | 749 | r->idiag_wqueue = 0; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index d7aea4c5b940..e560ef34cf4b 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -217,6 +217,7 @@ static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) | |||
217 | iph->saddr, iph->daddr, tpi->key); | 217 | iph->saddr, iph->daddr, tpi->key); |
218 | 218 | ||
219 | if (tunnel) { | 219 | if (tunnel) { |
220 | skb_pop_mac_header(skb); | ||
220 | ip_tunnel_rcv(tunnel, skb, tpi, log_ecn_error); | 221 | ip_tunnel_rcv(tunnel, skb, tpi, log_ecn_error); |
221 | return PACKET_RCVD; | 222 | return PACKET_RCVD; |
222 | } | 223 | } |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 912402752f2f..df184616493f 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -828,7 +828,7 @@ static int __ip_append_data(struct sock *sk, | |||
828 | 828 | ||
829 | if (cork->length + length > maxnonfragsize - fragheaderlen) { | 829 | if (cork->length + length > maxnonfragsize - fragheaderlen) { |
830 | ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, | 830 | ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, |
831 | mtu-exthdrlen); | 831 | mtu - (opt ? opt->optlen : 0)); |
832 | return -EMSGSIZE; | 832 | return -EMSGSIZE; |
833 | } | 833 | } |
834 | 834 | ||
@@ -1151,7 +1151,8 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page, | |||
1151 | mtu : 0xFFFF; | 1151 | mtu : 0xFFFF; |
1152 | 1152 | ||
1153 | if (cork->length + size > maxnonfragsize - fragheaderlen) { | 1153 | if (cork->length + size > maxnonfragsize - fragheaderlen) { |
1154 | ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, mtu); | 1154 | ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, |
1155 | mtu - (opt ? opt->optlen : 0)); | ||
1155 | return -EMSGSIZE; | 1156 | return -EMSGSIZE; |
1156 | } | 1157 | } |
1157 | 1158 | ||
diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index f13bd91d9a56..a313c3fbeb46 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c | |||
@@ -423,6 +423,7 @@ static void synproxy_tg4_destroy(const struct xt_tgdtor_param *par) | |||
423 | static struct xt_target synproxy_tg4_reg __read_mostly = { | 423 | static struct xt_target synproxy_tg4_reg __read_mostly = { |
424 | .name = "SYNPROXY", | 424 | .name = "SYNPROXY", |
425 | .family = NFPROTO_IPV4, | 425 | .family = NFPROTO_IPV4, |
426 | .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD), | ||
426 | .target = synproxy_tg4, | 427 | .target = synproxy_tg4, |
427 | .targetsize = sizeof(struct xt_synproxy_info), | 428 | .targetsize = sizeof(struct xt_synproxy_info), |
428 | .checkentry = synproxy_tg4_check, | 429 | .checkentry = synproxy_tg4_check, |
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c index fff5ba1a33b7..4a5e94ac314a 100644 --- a/net/ipv4/netfilter/nft_reject_ipv4.c +++ b/net/ipv4/netfilter/nft_reject_ipv4.c | |||
@@ -72,7 +72,7 @@ static int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr) | |||
72 | { | 72 | { |
73 | const struct nft_reject *priv = nft_expr_priv(expr); | 73 | const struct nft_reject *priv = nft_expr_priv(expr); |
74 | 74 | ||
75 | if (nla_put_be32(skb, NFTA_REJECT_TYPE, priv->type)) | 75 | if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type))) |
76 | goto nla_put_failure; | 76 | goto nla_put_failure; |
77 | 77 | ||
78 | switch (priv->type) { | 78 | switch (priv->type) { |
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index 269a89ecd2f4..f7e522c558ba 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c | |||
@@ -6,13 +6,6 @@ | |||
6 | #include <linux/memcontrol.h> | 6 | #include <linux/memcontrol.h> |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | 8 | ||
9 | static void memcg_tcp_enter_memory_pressure(struct sock *sk) | ||
10 | { | ||
11 | if (sk->sk_cgrp->memory_pressure) | ||
12 | sk->sk_cgrp->memory_pressure = 1; | ||
13 | } | ||
14 | EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure); | ||
15 | |||
16 | int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) | 9 | int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) |
17 | { | 10 | { |
18 | /* | 11 | /* |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 44f6a20fa29d..a7e4729e974b 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -560,15 +560,11 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb, | |||
560 | __be16 sport, __be16 dport, | 560 | __be16 sport, __be16 dport, |
561 | struct udp_table *udptable) | 561 | struct udp_table *udptable) |
562 | { | 562 | { |
563 | struct sock *sk; | ||
564 | const struct iphdr *iph = ip_hdr(skb); | 563 | const struct iphdr *iph = ip_hdr(skb); |
565 | 564 | ||
566 | if (unlikely(sk = skb_steal_sock(skb))) | 565 | return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport, |
567 | return sk; | 566 | iph->daddr, dport, inet_iif(skb), |
568 | else | 567 | udptable); |
569 | return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport, | ||
570 | iph->daddr, dport, inet_iif(skb), | ||
571 | udptable); | ||
572 | } | 568 | } |
573 | 569 | ||
574 | struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, | 570 | struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, |
@@ -1603,12 +1599,16 @@ static void flush_stack(struct sock **stack, unsigned int count, | |||
1603 | kfree_skb(skb1); | 1599 | kfree_skb(skb1); |
1604 | } | 1600 | } |
1605 | 1601 | ||
1606 | static void udp_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) | 1602 | /* For TCP sockets, sk_rx_dst is protected by socket lock |
1603 | * For UDP, we use xchg() to guard against concurrent changes. | ||
1604 | */ | ||
1605 | static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) | ||
1607 | { | 1606 | { |
1608 | struct dst_entry *dst = skb_dst(skb); | 1607 | struct dst_entry *old; |
1609 | 1608 | ||
1610 | dst_hold(dst); | 1609 | dst_hold(dst); |
1611 | sk->sk_rx_dst = dst; | 1610 | old = xchg(&sk->sk_rx_dst, dst); |
1611 | dst_release(old); | ||
1612 | } | 1612 | } |
1613 | 1613 | ||
1614 | /* | 1614 | /* |
@@ -1739,15 +1739,16 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
1739 | if (udp4_csum_init(skb, uh, proto)) | 1739 | if (udp4_csum_init(skb, uh, proto)) |
1740 | goto csum_error; | 1740 | goto csum_error; |
1741 | 1741 | ||
1742 | if (skb->sk) { | 1742 | sk = skb_steal_sock(skb); |
1743 | if (sk) { | ||
1744 | struct dst_entry *dst = skb_dst(skb); | ||
1743 | int ret; | 1745 | int ret; |
1744 | sk = skb->sk; | ||
1745 | 1746 | ||
1746 | if (unlikely(sk->sk_rx_dst == NULL)) | 1747 | if (unlikely(sk->sk_rx_dst != dst)) |
1747 | udp_sk_rx_dst_set(sk, skb); | 1748 | udp_sk_rx_dst_set(sk, dst); |
1748 | 1749 | ||
1749 | ret = udp_queue_rcv_skb(sk, skb); | 1750 | ret = udp_queue_rcv_skb(sk, skb); |
1750 | 1751 | sock_put(sk); | |
1751 | /* a return value > 0 means to resubmit the input, but | 1752 | /* a return value > 0 means to resubmit the input, but |
1752 | * it wants the return to be -protocol, or 0 | 1753 | * it wants the return to be -protocol, or 0 |
1753 | */ | 1754 | */ |
@@ -1913,17 +1914,20 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net, | |||
1913 | 1914 | ||
1914 | void udp_v4_early_demux(struct sk_buff *skb) | 1915 | void udp_v4_early_demux(struct sk_buff *skb) |
1915 | { | 1916 | { |
1916 | const struct iphdr *iph = ip_hdr(skb); | 1917 | struct net *net = dev_net(skb->dev); |
1917 | const struct udphdr *uh = udp_hdr(skb); | 1918 | const struct iphdr *iph; |
1919 | const struct udphdr *uh; | ||
1918 | struct sock *sk; | 1920 | struct sock *sk; |
1919 | struct dst_entry *dst; | 1921 | struct dst_entry *dst; |
1920 | struct net *net = dev_net(skb->dev); | ||
1921 | int dif = skb->dev->ifindex; | 1922 | int dif = skb->dev->ifindex; |
1922 | 1923 | ||
1923 | /* validate the packet */ | 1924 | /* validate the packet */ |
1924 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) | 1925 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) |
1925 | return; | 1926 | return; |
1926 | 1927 | ||
1928 | iph = ip_hdr(skb); | ||
1929 | uh = udp_hdr(skb); | ||
1930 | |||
1927 | if (skb->pkt_type == PACKET_BROADCAST || | 1931 | if (skb->pkt_type == PACKET_BROADCAST || |
1928 | skb->pkt_type == PACKET_MULTICAST) | 1932 | skb->pkt_type == PACKET_MULTICAST) |
1929 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, | 1933 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, |
@@ -2474,6 +2478,7 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, | |||
2474 | netdev_features_t features) | 2478 | netdev_features_t features) |
2475 | { | 2479 | { |
2476 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 2480 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
2481 | u16 mac_offset = skb->mac_header; | ||
2477 | int mac_len = skb->mac_len; | 2482 | int mac_len = skb->mac_len; |
2478 | int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); | 2483 | int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); |
2479 | __be16 protocol = skb->protocol; | 2484 | __be16 protocol = skb->protocol; |
@@ -2493,8 +2498,11 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, | |||
2493 | /* segment inner packet. */ | 2498 | /* segment inner packet. */ |
2494 | enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); | 2499 | enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); |
2495 | segs = skb_mac_gso_segment(skb, enc_features); | 2500 | segs = skb_mac_gso_segment(skb, enc_features); |
2496 | if (!segs || IS_ERR(segs)) | 2501 | if (!segs || IS_ERR(segs)) { |
2502 | skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset, | ||
2503 | mac_len); | ||
2497 | goto out; | 2504 | goto out; |
2505 | } | ||
2498 | 2506 | ||
2499 | outer_hlen = skb_tnl_header_len(skb); | 2507 | outer_hlen = skb_tnl_header_len(skb); |
2500 | skb = segs; | 2508 | skb = segs; |
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 83206de2bc76..79c62bdcd3c5 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c | |||
@@ -41,6 +41,14 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, | |||
41 | { | 41 | { |
42 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 42 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
43 | unsigned int mss; | 43 | unsigned int mss; |
44 | int offset; | ||
45 | __wsum csum; | ||
46 | |||
47 | if (skb->encapsulation && | ||
48 | skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) { | ||
49 | segs = skb_udp_tunnel_segment(skb, features); | ||
50 | goto out; | ||
51 | } | ||
44 | 52 | ||
45 | mss = skb_shinfo(skb)->gso_size; | 53 | mss = skb_shinfo(skb)->gso_size; |
46 | if (unlikely(skb->len <= mss)) | 54 | if (unlikely(skb->len <= mss)) |
@@ -63,27 +71,20 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, | |||
63 | goto out; | 71 | goto out; |
64 | } | 72 | } |
65 | 73 | ||
74 | /* Do software UFO. Complete and fill in the UDP checksum as | ||
75 | * HW cannot do checksum of UDP packets sent as multiple | ||
76 | * IP fragments. | ||
77 | */ | ||
78 | offset = skb_checksum_start_offset(skb); | ||
79 | csum = skb_checksum(skb, offset, skb->len - offset, 0); | ||
80 | offset += skb->csum_offset; | ||
81 | *(__sum16 *)(skb->data + offset) = csum_fold(csum); | ||
82 | skb->ip_summed = CHECKSUM_NONE; | ||
83 | |||
66 | /* Fragment the skb. IP headers of the fragments are updated in | 84 | /* Fragment the skb. IP headers of the fragments are updated in |
67 | * inet_gso_segment() | 85 | * inet_gso_segment() |
68 | */ | 86 | */ |
69 | if (skb->encapsulation && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) | 87 | segs = skb_segment(skb, features); |
70 | segs = skb_udp_tunnel_segment(skb, features); | ||
71 | else { | ||
72 | int offset; | ||
73 | __wsum csum; | ||
74 | |||
75 | /* Do software UFO. Complete and fill in the UDP checksum as | ||
76 | * HW cannot do checksum of UDP packets sent as multiple | ||
77 | * IP fragments. | ||
78 | */ | ||
79 | offset = skb_checksum_start_offset(skb); | ||
80 | csum = skb_checksum(skb, offset, skb->len - offset, 0); | ||
81 | offset += skb->csum_offset; | ||
82 | *(__sum16 *)(skb->data + offset) = csum_fold(csum); | ||
83 | skb->ip_summed = CHECKSUM_NONE; | ||
84 | |||
85 | segs = skb_segment(skb, features); | ||
86 | } | ||
87 | out: | 88 | out: |
88 | return segs; | 89 | return segs; |
89 | } | 90 | } |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 12c97d8aa6bb..abe46a4228ce 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1671,7 +1671,7 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | |||
1671 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | 1671 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) |
1672 | { | 1672 | { |
1673 | struct in6_addr addr; | 1673 | struct in6_addr addr; |
1674 | if (ifp->prefix_len == 127) /* RFC 6164 */ | 1674 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
1675 | return; | 1675 | return; |
1676 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1676 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
1677 | if (ipv6_addr_any(&addr)) | 1677 | if (ipv6_addr_any(&addr)) |
@@ -1682,7 +1682,7 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | |||
1682 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) | 1682 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) |
1683 | { | 1683 | { |
1684 | struct in6_addr addr; | 1684 | struct in6_addr addr; |
1685 | if (ifp->prefix_len == 127) /* RFC 6164 */ | 1685 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
1686 | return; | 1686 | return; |
1687 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1687 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
1688 | if (ipv6_addr_any(&addr)) | 1688 | if (ipv6_addr_any(&addr)) |
@@ -2509,7 +2509,8 @@ static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr, | |||
2509 | struct inet6_ifaddr *ifp; | 2509 | struct inet6_ifaddr *ifp; |
2510 | 2510 | ||
2511 | ifp = ipv6_add_addr(idev, addr, NULL, plen, | 2511 | ifp = ipv6_add_addr(idev, addr, NULL, plen, |
2512 | scope, IFA_F_PERMANENT, 0, 0); | 2512 | scope, IFA_F_PERMANENT, |
2513 | INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | ||
2513 | if (!IS_ERR(ifp)) { | 2514 | if (!IS_ERR(ifp)) { |
2514 | spin_lock_bh(&ifp->lock); | 2515 | spin_lock_bh(&ifp->lock); |
2515 | ifp->flags &= ~IFA_F_TENTATIVE; | 2516 | ifp->flags &= ~IFA_F_TENTATIVE; |
@@ -2613,7 +2614,7 @@ static void init_loopback(struct net_device *dev) | |||
2613 | if (sp_ifa->rt) | 2614 | if (sp_ifa->rt) |
2614 | continue; | 2615 | continue; |
2615 | 2616 | ||
2616 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); | 2617 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false); |
2617 | 2618 | ||
2618 | /* Failure cases are ignored */ | 2619 | /* Failure cases are ignored */ |
2619 | if (!IS_ERR(sp_rt)) { | 2620 | if (!IS_ERR(sp_rt)) { |
@@ -2637,7 +2638,8 @@ static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr | |||
2637 | #endif | 2638 | #endif |
2638 | 2639 | ||
2639 | 2640 | ||
2640 | ifp = ipv6_add_addr(idev, addr, NULL, 64, IFA_LINK, addr_flags, 0, 0); | 2641 | ifp = ipv6_add_addr(idev, addr, NULL, 64, IFA_LINK, addr_flags, |
2642 | INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | ||
2641 | if (!IS_ERR(ifp)) { | 2643 | if (!IS_ERR(ifp)) { |
2642 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, idev->dev, 0, 0); | 2644 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, idev->dev, 0, 0); |
2643 | addrconf_dad_start(ifp); | 2645 | addrconf_dad_start(ifp); |
@@ -3456,7 +3458,12 @@ restart: | |||
3456 | &inet6_addr_lst[i], addr_lst) { | 3458 | &inet6_addr_lst[i], addr_lst) { |
3457 | unsigned long age; | 3459 | unsigned long age; |
3458 | 3460 | ||
3459 | if (ifp->flags & IFA_F_PERMANENT) | 3461 | /* When setting preferred_lft to a value not zero or |
3462 | * infinity, while valid_lft is infinity | ||
3463 | * IFA_F_PERMANENT has a non-infinity life time. | ||
3464 | */ | ||
3465 | if ((ifp->flags & IFA_F_PERMANENT) && | ||
3466 | (ifp->prefered_lft == INFINITY_LIFE_TIME)) | ||
3460 | continue; | 3467 | continue; |
3461 | 3468 | ||
3462 | spin_lock(&ifp->lock); | 3469 | spin_lock(&ifp->lock); |
@@ -3481,7 +3488,8 @@ restart: | |||
3481 | ifp->flags |= IFA_F_DEPRECATED; | 3488 | ifp->flags |= IFA_F_DEPRECATED; |
3482 | } | 3489 | } |
3483 | 3490 | ||
3484 | if (time_before(ifp->tstamp + ifp->valid_lft * HZ, next)) | 3491 | if ((ifp->valid_lft != INFINITY_LIFE_TIME) && |
3492 | (time_before(ifp->tstamp + ifp->valid_lft * HZ, next))) | ||
3485 | next = ifp->tstamp + ifp->valid_lft * HZ; | 3493 | next = ifp->tstamp + ifp->valid_lft * HZ; |
3486 | 3494 | ||
3487 | spin_unlock(&ifp->lock); | 3495 | spin_unlock(&ifp->lock); |
@@ -3761,7 +3769,8 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | |||
3761 | put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), | 3769 | put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), |
3762 | ifa->idev->dev->ifindex); | 3770 | ifa->idev->dev->ifindex); |
3763 | 3771 | ||
3764 | if (!(ifa->flags&IFA_F_PERMANENT)) { | 3772 | if (!((ifa->flags&IFA_F_PERMANENT) && |
3773 | (ifa->prefered_lft == INFINITY_LIFE_TIME))) { | ||
3765 | preferred = ifa->prefered_lft; | 3774 | preferred = ifa->prefered_lft; |
3766 | valid = ifa->valid_lft; | 3775 | valid = ifa->valid_lft; |
3767 | if (preferred != INFINITY_LIFE_TIME) { | 3776 | if (preferred != INFINITY_LIFE_TIME) { |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 8dfe1f4d3c1a..93b1aa34c432 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -73,7 +73,6 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
73 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 73 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
74 | if (flowlabel == NULL) | 74 | if (flowlabel == NULL) |
75 | return -EINVAL; | 75 | return -EINVAL; |
76 | usin->sin6_addr = flowlabel->dst; | ||
77 | } | 76 | } |
78 | } | 77 | } |
79 | 78 | ||
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index e27591635f92..3fd0a578329e 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -122,7 +122,11 @@ out: | |||
122 | static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) | 122 | static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) |
123 | { | 123 | { |
124 | struct rt6_info *rt = (struct rt6_info *) arg->result; | 124 | struct rt6_info *rt = (struct rt6_info *) arg->result; |
125 | struct net_device *dev = rt->rt6i_idev->dev; | 125 | struct net_device *dev = NULL; |
126 | |||
127 | if (rt->rt6i_idev) | ||
128 | dev = rt->rt6i_idev->dev; | ||
129 | |||
126 | /* do not accept result if the route does | 130 | /* do not accept result if the route does |
127 | * not meet the required prefix length | 131 | * not meet the required prefix length |
128 | */ | 132 | */ |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4acdb63495db..e6f931997996 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1193,11 +1193,35 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1193 | 1193 | ||
1194 | fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + | 1194 | fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + |
1195 | (opt ? opt->opt_nflen : 0); | 1195 | (opt ? opt->opt_nflen : 0); |
1196 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); | 1196 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - |
1197 | sizeof(struct frag_hdr); | ||
1197 | 1198 | ||
1198 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { | 1199 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { |
1199 | if (cork->length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { | 1200 | unsigned int maxnonfragsize, headersize; |
1200 | ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen); | 1201 | |
1202 | headersize = sizeof(struct ipv6hdr) + | ||
1203 | (opt ? opt->tot_len : 0) + | ||
1204 | (dst_allfrag(&rt->dst) ? | ||
1205 | sizeof(struct frag_hdr) : 0) + | ||
1206 | rt->rt6i_nfheader_len; | ||
1207 | |||
1208 | maxnonfragsize = (np->pmtudisc >= IPV6_PMTUDISC_DO) ? | ||
1209 | mtu : sizeof(struct ipv6hdr) + IPV6_MAXPLEN; | ||
1210 | |||
1211 | /* dontfrag active */ | ||
1212 | if ((cork->length + length > mtu - headersize) && dontfrag && | ||
1213 | (sk->sk_protocol == IPPROTO_UDP || | ||
1214 | sk->sk_protocol == IPPROTO_RAW)) { | ||
1215 | ipv6_local_rxpmtu(sk, fl6, mtu - headersize + | ||
1216 | sizeof(struct ipv6hdr)); | ||
1217 | goto emsgsize; | ||
1218 | } | ||
1219 | |||
1220 | if (cork->length + length > maxnonfragsize - headersize) { | ||
1221 | emsgsize: | ||
1222 | ipv6_local_error(sk, EMSGSIZE, fl6, | ||
1223 | mtu - headersize + | ||
1224 | sizeof(struct ipv6hdr)); | ||
1201 | return -EMSGSIZE; | 1225 | return -EMSGSIZE; |
1202 | } | 1226 | } |
1203 | } | 1227 | } |
@@ -1222,12 +1246,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1222 | * --yoshfuji | 1246 | * --yoshfuji |
1223 | */ | 1247 | */ |
1224 | 1248 | ||
1225 | if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP || | ||
1226 | sk->sk_protocol == IPPROTO_RAW)) { | ||
1227 | ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); | ||
1228 | return -EMSGSIZE; | ||
1229 | } | ||
1230 | |||
1231 | skb = skb_peek_tail(&sk->sk_write_queue); | 1249 | skb = skb_peek_tail(&sk->sk_write_queue); |
1232 | cork->length += length; | 1250 | cork->length += length; |
1233 | if (((length > mtu) || | 1251 | if (((length > mtu) || |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index d6062325db08..7881965a8248 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -103,16 +103,25 @@ struct ip6_tnl_net { | |||
103 | 103 | ||
104 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) | 104 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) |
105 | { | 105 | { |
106 | struct pcpu_tstats sum = { 0 }; | 106 | struct pcpu_tstats tmp, sum = { 0 }; |
107 | int i; | 107 | int i; |
108 | 108 | ||
109 | for_each_possible_cpu(i) { | 109 | for_each_possible_cpu(i) { |
110 | unsigned int start; | ||
110 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); | 111 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); |
111 | 112 | ||
112 | sum.rx_packets += tstats->rx_packets; | 113 | do { |
113 | sum.rx_bytes += tstats->rx_bytes; | 114 | start = u64_stats_fetch_begin_bh(&tstats->syncp); |
114 | sum.tx_packets += tstats->tx_packets; | 115 | tmp.rx_packets = tstats->rx_packets; |
115 | sum.tx_bytes += tstats->tx_bytes; | 116 | tmp.rx_bytes = tstats->rx_bytes; |
117 | tmp.tx_packets = tstats->tx_packets; | ||
118 | tmp.tx_bytes = tstats->tx_bytes; | ||
119 | } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); | ||
120 | |||
121 | sum.rx_packets += tmp.rx_packets; | ||
122 | sum.rx_bytes += tmp.rx_bytes; | ||
123 | sum.tx_packets += tmp.tx_packets; | ||
124 | sum.tx_bytes += tmp.tx_bytes; | ||
116 | } | 125 | } |
117 | dev->stats.rx_packets = sum.rx_packets; | 126 | dev->stats.rx_packets = sum.rx_packets; |
118 | dev->stats.rx_bytes = sum.rx_bytes; | 127 | dev->stats.rx_bytes = sum.rx_bytes; |
@@ -824,8 +833,10 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, | |||
824 | } | 833 | } |
825 | 834 | ||
826 | tstats = this_cpu_ptr(t->dev->tstats); | 835 | tstats = this_cpu_ptr(t->dev->tstats); |
836 | u64_stats_update_begin(&tstats->syncp); | ||
827 | tstats->rx_packets++; | 837 | tstats->rx_packets++; |
828 | tstats->rx_bytes += skb->len; | 838 | tstats->rx_bytes += skb->len; |
839 | u64_stats_update_end(&tstats->syncp); | ||
829 | 840 | ||
830 | netif_rx(skb); | 841 | netif_rx(skb); |
831 | 842 | ||
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index ed94ba61dda0..7b42d5ef868d 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -75,26 +75,6 @@ struct vti6_net { | |||
75 | struct ip6_tnl __rcu **tnls[2]; | 75 | struct ip6_tnl __rcu **tnls[2]; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct net_device_stats *vti6_get_stats(struct net_device *dev) | ||
79 | { | ||
80 | struct pcpu_tstats sum = { 0 }; | ||
81 | int i; | ||
82 | |||
83 | for_each_possible_cpu(i) { | ||
84 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); | ||
85 | |||
86 | sum.rx_packets += tstats->rx_packets; | ||
87 | sum.rx_bytes += tstats->rx_bytes; | ||
88 | sum.tx_packets += tstats->tx_packets; | ||
89 | sum.tx_bytes += tstats->tx_bytes; | ||
90 | } | ||
91 | dev->stats.rx_packets = sum.rx_packets; | ||
92 | dev->stats.rx_bytes = sum.rx_bytes; | ||
93 | dev->stats.tx_packets = sum.tx_packets; | ||
94 | dev->stats.tx_bytes = sum.tx_bytes; | ||
95 | return &dev->stats; | ||
96 | } | ||
97 | |||
98 | #define for_each_vti6_tunnel_rcu(start) \ | 78 | #define for_each_vti6_tunnel_rcu(start) \ |
99 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) | 79 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) |
100 | 80 | ||
@@ -331,8 +311,10 @@ static int vti6_rcv(struct sk_buff *skb) | |||
331 | } | 311 | } |
332 | 312 | ||
333 | tstats = this_cpu_ptr(t->dev->tstats); | 313 | tstats = this_cpu_ptr(t->dev->tstats); |
314 | u64_stats_update_begin(&tstats->syncp); | ||
334 | tstats->rx_packets++; | 315 | tstats->rx_packets++; |
335 | tstats->rx_bytes += skb->len; | 316 | tstats->rx_bytes += skb->len; |
317 | u64_stats_update_end(&tstats->syncp); | ||
336 | 318 | ||
337 | skb->mark = 0; | 319 | skb->mark = 0; |
338 | secpath_reset(skb); | 320 | secpath_reset(skb); |
@@ -716,7 +698,7 @@ static const struct net_device_ops vti6_netdev_ops = { | |||
716 | .ndo_start_xmit = vti6_tnl_xmit, | 698 | .ndo_start_xmit = vti6_tnl_xmit, |
717 | .ndo_do_ioctl = vti6_ioctl, | 699 | .ndo_do_ioctl = vti6_ioctl, |
718 | .ndo_change_mtu = vti6_change_mtu, | 700 | .ndo_change_mtu = vti6_change_mtu, |
719 | .ndo_get_stats = vti6_get_stats, | 701 | .ndo_get_stats64 = ip_tunnel_get_stats64, |
720 | }; | 702 | }; |
721 | 703 | ||
722 | /** | 704 | /** |
@@ -750,12 +732,18 @@ static void vti6_dev_setup(struct net_device *dev) | |||
750 | static inline int vti6_dev_init_gen(struct net_device *dev) | 732 | static inline int vti6_dev_init_gen(struct net_device *dev) |
751 | { | 733 | { |
752 | struct ip6_tnl *t = netdev_priv(dev); | 734 | struct ip6_tnl *t = netdev_priv(dev); |
735 | int i; | ||
753 | 736 | ||
754 | t->dev = dev; | 737 | t->dev = dev; |
755 | t->net = dev_net(dev); | 738 | t->net = dev_net(dev); |
756 | dev->tstats = alloc_percpu(struct pcpu_tstats); | 739 | dev->tstats = alloc_percpu(struct pcpu_tstats); |
757 | if (!dev->tstats) | 740 | if (!dev->tstats) |
758 | return -ENOMEM; | 741 | return -ENOMEM; |
742 | for_each_possible_cpu(i) { | ||
743 | struct pcpu_tstats *stats; | ||
744 | stats = per_cpu_ptr(dev->tstats, i); | ||
745 | u64_stats_init(&stats->syncp); | ||
746 | } | ||
759 | return 0; | 747 | return 0; |
760 | } | 748 | } |
761 | 749 | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 3512177deb4d..300865171394 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1277,6 +1277,9 @@ skip_linkparms: | |||
1277 | ri->prefix_len == 0) | 1277 | ri->prefix_len == 0) |
1278 | continue; | 1278 | continue; |
1279 | #endif | 1279 | #endif |
1280 | if (ri->prefix_len == 0 && | ||
1281 | !in6_dev->cnf.accept_ra_defrtr) | ||
1282 | continue; | ||
1280 | if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) | 1283 | if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) |
1281 | continue; | 1284 | continue; |
1282 | rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, | 1285 | rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, |
diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index f78f41aca8e9..a0d17270117c 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c | |||
@@ -446,6 +446,7 @@ static void synproxy_tg6_destroy(const struct xt_tgdtor_param *par) | |||
446 | static struct xt_target synproxy_tg6_reg __read_mostly = { | 446 | static struct xt_target synproxy_tg6_reg __read_mostly = { |
447 | .name = "SYNPROXY", | 447 | .name = "SYNPROXY", |
448 | .family = NFPROTO_IPV6, | 448 | .family = NFPROTO_IPV6, |
449 | .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD), | ||
449 | .target = synproxy_tg6, | 450 | .target = synproxy_tg6, |
450 | .targetsize = sizeof(struct xt_synproxy_info), | 451 | .targetsize = sizeof(struct xt_synproxy_info), |
451 | .checkentry = synproxy_tg6_check, | 452 | .checkentry = synproxy_tg6_check, |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 7fb4e14c467f..b6bb87e55805 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -792,7 +792,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
792 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 792 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
793 | if (flowlabel == NULL) | 793 | if (flowlabel == NULL) |
794 | return -EINVAL; | 794 | return -EINVAL; |
795 | daddr = &flowlabel->dst; | ||
796 | } | 795 | } |
797 | } | 796 | } |
798 | 797 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7faa9d5e1503..4b4944c3e4c4 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -84,6 +84,8 @@ static int ip6_dst_gc(struct dst_ops *ops); | |||
84 | 84 | ||
85 | static int ip6_pkt_discard(struct sk_buff *skb); | 85 | static int ip6_pkt_discard(struct sk_buff *skb); |
86 | static int ip6_pkt_discard_out(struct sk_buff *skb); | 86 | static int ip6_pkt_discard_out(struct sk_buff *skb); |
87 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
88 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
87 | static void ip6_link_failure(struct sk_buff *skb); | 89 | static void ip6_link_failure(struct sk_buff *skb); |
88 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 90 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
89 | struct sk_buff *skb, u32 mtu); | 91 | struct sk_buff *skb, u32 mtu); |
@@ -234,9 +236,6 @@ static const struct rt6_info ip6_null_entry_template = { | |||
234 | 236 | ||
235 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 237 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
236 | 238 | ||
237 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
238 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
239 | |||
240 | static const struct rt6_info ip6_prohibit_entry_template = { | 239 | static const struct rt6_info ip6_prohibit_entry_template = { |
241 | .dst = { | 240 | .dst = { |
242 | .__refcnt = ATOMIC_INIT(1), | 241 | .__refcnt = ATOMIC_INIT(1), |
@@ -1565,21 +1564,24 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1565 | goto out; | 1564 | goto out; |
1566 | } | 1565 | } |
1567 | } | 1566 | } |
1568 | rt->dst.output = ip6_pkt_discard_out; | ||
1569 | rt->dst.input = ip6_pkt_discard; | ||
1570 | rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; | 1567 | rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; |
1571 | switch (cfg->fc_type) { | 1568 | switch (cfg->fc_type) { |
1572 | case RTN_BLACKHOLE: | 1569 | case RTN_BLACKHOLE: |
1573 | rt->dst.error = -EINVAL; | 1570 | rt->dst.error = -EINVAL; |
1571 | rt->dst.output = dst_discard; | ||
1572 | rt->dst.input = dst_discard; | ||
1574 | break; | 1573 | break; |
1575 | case RTN_PROHIBIT: | 1574 | case RTN_PROHIBIT: |
1576 | rt->dst.error = -EACCES; | 1575 | rt->dst.error = -EACCES; |
1576 | rt->dst.output = ip6_pkt_prohibit_out; | ||
1577 | rt->dst.input = ip6_pkt_prohibit; | ||
1577 | break; | 1578 | break; |
1578 | case RTN_THROW: | 1579 | case RTN_THROW: |
1579 | rt->dst.error = -EAGAIN; | ||
1580 | break; | ||
1581 | default: | 1580 | default: |
1582 | rt->dst.error = -ENETUNREACH; | 1581 | rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN |
1582 | : -ENETUNREACH; | ||
1583 | rt->dst.output = ip6_pkt_discard_out; | ||
1584 | rt->dst.input = ip6_pkt_discard; | ||
1583 | break; | 1585 | break; |
1584 | } | 1586 | } |
1585 | goto install_route; | 1587 | goto install_route; |
@@ -1903,9 +1905,7 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, | |||
1903 | else | 1905 | else |
1904 | rt->rt6i_gateway = *dest; | 1906 | rt->rt6i_gateway = *dest; |
1905 | rt->rt6i_flags = ort->rt6i_flags; | 1907 | rt->rt6i_flags = ort->rt6i_flags; |
1906 | if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == | 1908 | rt6_set_from(rt, ort); |
1907 | (RTF_DEFAULT | RTF_ADDRCONF)) | ||
1908 | rt6_set_from(rt, ort); | ||
1909 | rt->rt6i_metric = 0; | 1909 | rt->rt6i_metric = 0; |
1910 | 1910 | ||
1911 | #ifdef CONFIG_IPV6_SUBTREES | 1911 | #ifdef CONFIG_IPV6_SUBTREES |
@@ -2144,8 +2144,6 @@ static int ip6_pkt_discard_out(struct sk_buff *skb) | |||
2144 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); | 2144 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); |
2145 | } | 2145 | } |
2146 | 2146 | ||
2147 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
2148 | |||
2149 | static int ip6_pkt_prohibit(struct sk_buff *skb) | 2147 | static int ip6_pkt_prohibit(struct sk_buff *skb) |
2150 | { | 2148 | { |
2151 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); | 2149 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); |
@@ -2157,8 +2155,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb) | |||
2157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); | 2155 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); |
2158 | } | 2156 | } |
2159 | 2157 | ||
2160 | #endif | ||
2161 | |||
2162 | /* | 2158 | /* |
2163 | * Allocate a dst for local (unicast / anycast) address. | 2159 | * Allocate a dst for local (unicast / anycast) address. |
2164 | */ | 2160 | */ |
@@ -2168,12 +2164,10 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
2168 | bool anycast) | 2164 | bool anycast) |
2169 | { | 2165 | { |
2170 | struct net *net = dev_net(idev->dev); | 2166 | struct net *net = dev_net(idev->dev); |
2171 | struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); | 2167 | struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, |
2172 | 2168 | DST_NOCOUNT, NULL); | |
2173 | if (!rt) { | 2169 | if (!rt) |
2174 | net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); | ||
2175 | return ERR_PTR(-ENOMEM); | 2170 | return ERR_PTR(-ENOMEM); |
2176 | } | ||
2177 | 2171 | ||
2178 | in6_dev_hold(idev); | 2172 | in6_dev_hold(idev); |
2179 | 2173 | ||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 366fbba3359a..d3005b34476a 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -702,8 +702,10 @@ static int ipip6_rcv(struct sk_buff *skb) | |||
702 | } | 702 | } |
703 | 703 | ||
704 | tstats = this_cpu_ptr(tunnel->dev->tstats); | 704 | tstats = this_cpu_ptr(tunnel->dev->tstats); |
705 | u64_stats_update_begin(&tstats->syncp); | ||
705 | tstats->rx_packets++; | 706 | tstats->rx_packets++; |
706 | tstats->rx_bytes += skb->len; | 707 | tstats->rx_bytes += skb->len; |
708 | u64_stats_update_end(&tstats->syncp); | ||
707 | 709 | ||
708 | netif_rx(skb); | 710 | netif_rx(skb); |
709 | 711 | ||
@@ -924,7 +926,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
924 | if (tunnel->parms.iph.daddr && skb_dst(skb)) | 926 | if (tunnel->parms.iph.daddr && skb_dst(skb)) |
925 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 927 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); |
926 | 928 | ||
927 | if (skb->len > mtu) { | 929 | if (skb->len > mtu && !skb_is_gso(skb)) { |
928 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 930 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
929 | ip_rt_put(rt); | 931 | ip_rt_put(rt); |
930 | goto tx_error; | 932 | goto tx_error; |
@@ -966,8 +968,10 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
966 | tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); | 968 | tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); |
967 | 969 | ||
968 | skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT); | 970 | skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT); |
969 | if (IS_ERR(skb)) | 971 | if (IS_ERR(skb)) { |
972 | ip_rt_put(rt); | ||
970 | goto out; | 973 | goto out; |
974 | } | ||
971 | 975 | ||
972 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, | 976 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, |
973 | ttl, df, !net_eq(tunnel->net, dev_net(dev))); | 977 | ttl, df, !net_eq(tunnel->net, dev_net(dev))); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 0740f93a114a..f67033b4bb66 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -156,7 +156,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
156 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 156 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
157 | if (flowlabel == NULL) | 157 | if (flowlabel == NULL) |
158 | return -EINVAL; | 158 | return -EINVAL; |
159 | usin->sin6_addr = flowlabel->dst; | ||
160 | fl6_sock_release(flowlabel); | 159 | fl6_sock_release(flowlabel); |
161 | } | 160 | } |
162 | } | 161 | } |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index bcd5699313c3..089c741a3992 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1140,7 +1140,6 @@ do_udp_sendmsg: | |||
1140 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 1140 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
1141 | if (flowlabel == NULL) | 1141 | if (flowlabel == NULL) |
1142 | return -EINVAL; | 1142 | return -EINVAL; |
1143 | daddr = &flowlabel->dst; | ||
1144 | } | 1143 | } |
1145 | } | 1144 | } |
1146 | 1145 | ||
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index d9b437e55007..bb6e206ea70b 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -528,7 +528,6 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
528 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 528 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
529 | if (flowlabel == NULL) | 529 | if (flowlabel == NULL) |
530 | return -EINVAL; | 530 | return -EINVAL; |
531 | daddr = &flowlabel->dst; | ||
532 | } | 531 | } |
533 | } | 532 | } |
534 | 533 | ||
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 7b01b9f5846c..c71b699eb555 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -715,7 +715,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
715 | unsigned long cpu_flags; | 715 | unsigned long cpu_flags; |
716 | size_t copied = 0; | 716 | size_t copied = 0; |
717 | u32 peek_seq = 0; | 717 | u32 peek_seq = 0; |
718 | u32 *seq; | 718 | u32 *seq, skb_len; |
719 | unsigned long used; | 719 | unsigned long used; |
720 | int target; /* Read at least this many bytes */ | 720 | int target; /* Read at least this many bytes */ |
721 | long timeo; | 721 | long timeo; |
@@ -812,6 +812,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
812 | } | 812 | } |
813 | continue; | 813 | continue; |
814 | found_ok_skb: | 814 | found_ok_skb: |
815 | skb_len = skb->len; | ||
815 | /* Ok so how much can we use? */ | 816 | /* Ok so how much can we use? */ |
816 | used = skb->len - offset; | 817 | used = skb->len - offset; |
817 | if (len < used) | 818 | if (len < used) |
@@ -844,7 +845,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
844 | } | 845 | } |
845 | 846 | ||
846 | /* Partial read */ | 847 | /* Partial read */ |
847 | if (used + offset < skb->len) | 848 | if (used + offset < skb_len) |
848 | continue; | 849 | continue; |
849 | } while (len > 0); | 850 | } while (len > 0); |
850 | 851 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 95667b088c5b..364ce0c5962f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1368,7 +1368,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1368 | changed |= | 1368 | changed |= |
1369 | ieee80211_mps_set_sta_local_pm(sta, | 1369 | ieee80211_mps_set_sta_local_pm(sta, |
1370 | params->local_pm); | 1370 | params->local_pm); |
1371 | ieee80211_bss_info_change_notify(sdata, changed); | 1371 | ieee80211_mbss_info_change_notify(sdata, changed); |
1372 | #endif | 1372 | #endif |
1373 | } | 1373 | } |
1374 | 1374 | ||
@@ -2488,8 +2488,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
2488 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2488 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2489 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2489 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2490 | 2490 | ||
2491 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 2491 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
2492 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
2493 | return -EOPNOTSUPP; | 2492 | return -EOPNOTSUPP; |
2494 | 2493 | ||
2495 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) | 2494 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) |
@@ -3120,9 +3119,17 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
3120 | params->chandef.chan->band) | 3119 | params->chandef.chan->band) |
3121 | return -EINVAL; | 3120 | return -EINVAL; |
3122 | 3121 | ||
3122 | ifmsh->chsw_init = true; | ||
3123 | if (!ifmsh->pre_value) | ||
3124 | ifmsh->pre_value = 1; | ||
3125 | else | ||
3126 | ifmsh->pre_value++; | ||
3127 | |||
3123 | err = ieee80211_mesh_csa_beacon(sdata, params, true); | 3128 | err = ieee80211_mesh_csa_beacon(sdata, params, true); |
3124 | if (err < 0) | 3129 | if (err < 0) { |
3130 | ifmsh->chsw_init = false; | ||
3125 | return err; | 3131 | return err; |
3132 | } | ||
3126 | break; | 3133 | break; |
3127 | #endif | 3134 | #endif |
3128 | default: | 3135 | default: |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 531be040b9ae..27a39de89679 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -823,6 +823,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
823 | if (err) | 823 | if (err) |
824 | return false; | 824 | return false; |
825 | 825 | ||
826 | /* channel switch is not supported, disconnect */ | ||
827 | if (!(sdata->local->hw.wiphy->flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) | ||
828 | goto disconnect; | ||
829 | |||
826 | params.count = csa_ie.count; | 830 | params.count = csa_ie.count; |
827 | params.chandef = csa_ie.chandef; | 831 | params.chandef = csa_ie.chandef; |
828 | 832 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 29dc505be125..4aea4e791113 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1228,6 +1228,7 @@ struct ieee80211_csa_ie { | |||
1228 | u8 mode; | 1228 | u8 mode; |
1229 | u8 count; | 1229 | u8 count; |
1230 | u8 ttl; | 1230 | u8 ttl; |
1231 | u16 pre_value; | ||
1231 | }; | 1232 | }; |
1232 | 1233 | ||
1233 | /* Parsed Information Elements */ | 1234 | /* Parsed Information Elements */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ff101ea1d9ae..a0757913046e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1061,7 +1061,8 @@ static void ieee80211_uninit(struct net_device *dev) | |||
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | static u16 ieee80211_netdev_select_queue(struct net_device *dev, | 1063 | static u16 ieee80211_netdev_select_queue(struct net_device *dev, |
1064 | struct sk_buff *skb) | 1064 | struct sk_buff *skb, |
1065 | void *accel_priv) | ||
1065 | { | 1066 | { |
1066 | return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); | 1067 | return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); |
1067 | } | 1068 | } |
@@ -1078,7 +1079,8 @@ static const struct net_device_ops ieee80211_dataif_ops = { | |||
1078 | }; | 1079 | }; |
1079 | 1080 | ||
1080 | static u16 ieee80211_monitor_select_queue(struct net_device *dev, | 1081 | static u16 ieee80211_monitor_select_queue(struct net_device *dev, |
1081 | struct sk_buff *skb) | 1082 | struct sk_buff *skb, |
1083 | void *accel_priv) | ||
1082 | { | 1084 | { |
1083 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1085 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1084 | struct ieee80211_local *local = sdata->local; | 1086 | struct ieee80211_local *local = sdata->local; |
@@ -1325,7 +1327,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1325 | sdata->vif.bss_conf.bssid = NULL; | 1327 | sdata->vif.bss_conf.bssid = NULL; |
1326 | break; | 1328 | break; |
1327 | case NL80211_IFTYPE_AP_VLAN: | 1329 | case NL80211_IFTYPE_AP_VLAN: |
1328 | break; | ||
1329 | case NL80211_IFTYPE_P2P_DEVICE: | 1330 | case NL80211_IFTYPE_P2P_DEVICE: |
1330 | sdata->vif.bss_conf.bssid = sdata->vif.addr; | 1331 | sdata->vif.bss_conf.bssid = sdata->vif.addr; |
1331 | break; | 1332 | break; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 21d5d44444d0..7d1c3ac48ed9 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -940,6 +940,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
940 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", | 940 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", |
941 | result); | 941 | result); |
942 | 942 | ||
943 | local->hw.conf.flags = IEEE80211_CONF_IDLE; | ||
944 | |||
943 | ieee80211_led_init(local); | 945 | ieee80211_led_init(local); |
944 | 946 | ||
945 | rtnl_lock(); | 947 | rtnl_lock(); |
@@ -1047,6 +1049,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1047 | 1049 | ||
1048 | cancel_work_sync(&local->restart_work); | 1050 | cancel_work_sync(&local->restart_work); |
1049 | cancel_work_sync(&local->reconfig_filter); | 1051 | cancel_work_sync(&local->reconfig_filter); |
1052 | flush_work(&local->sched_scan_stopped_work); | ||
1050 | 1053 | ||
1051 | ieee80211_clear_tx_pending(local); | 1054 | ieee80211_clear_tx_pending(local); |
1052 | rate_control_deinitialize(local); | 1055 | rate_control_deinitialize(local); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 896fe3bd599e..ba105257d03f 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -943,14 +943,19 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, | |||
943 | params.chandef.chan->center_freq); | 943 | params.chandef.chan->center_freq); |
944 | 944 | ||
945 | params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT; | 945 | params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT; |
946 | if (beacon) | 946 | if (beacon) { |
947 | ifmsh->chsw_ttl = csa_ie.ttl - 1; | 947 | ifmsh->chsw_ttl = csa_ie.ttl - 1; |
948 | else | 948 | if (ifmsh->pre_value >= csa_ie.pre_value) |
949 | ifmsh->chsw_ttl = 0; | 949 | return false; |
950 | ifmsh->pre_value = csa_ie.pre_value; | ||
951 | } | ||
950 | 952 | ||
951 | if (ifmsh->chsw_ttl > 0) | 953 | if (ifmsh->chsw_ttl < ifmsh->mshcfg.dot11MeshTTL) { |
952 | if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0) | 954 | if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0) |
953 | return false; | 955 | return false; |
956 | } else { | ||
957 | return false; | ||
958 | } | ||
954 | 959 | ||
955 | sdata->csa_radar_required = params.radar_required; | 960 | sdata->csa_radar_required = params.radar_required; |
956 | 961 | ||
@@ -1163,7 +1168,6 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
1163 | offset_ttl = (len < 42) ? 7 : 10; | 1168 | offset_ttl = (len < 42) ? 7 : 10; |
1164 | *(pos + offset_ttl) -= 1; | 1169 | *(pos + offset_ttl) -= 1; |
1165 | *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; | 1170 | *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; |
1166 | sdata->u.mesh.chsw_ttl = *(pos + offset_ttl); | ||
1167 | 1171 | ||
1168 | memcpy(mgmt_fwd, mgmt, len); | 1172 | memcpy(mgmt_fwd, mgmt, len); |
1169 | eth_broadcast_addr(mgmt_fwd->da); | 1173 | eth_broadcast_addr(mgmt_fwd->da); |
@@ -1182,7 +1186,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
1182 | u16 pre_value; | 1186 | u16 pre_value; |
1183 | bool fwd_csa = true; | 1187 | bool fwd_csa = true; |
1184 | size_t baselen; | 1188 | size_t baselen; |
1185 | u8 *pos, ttl; | 1189 | u8 *pos; |
1186 | 1190 | ||
1187 | if (mgmt->u.action.u.measurement.action_code != | 1191 | if (mgmt->u.action.u.measurement.action_code != |
1188 | WLAN_ACTION_SPCT_CHL_SWITCH) | 1192 | WLAN_ACTION_SPCT_CHL_SWITCH) |
@@ -1193,8 +1197,8 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
1193 | u.action.u.chan_switch.variable); | 1197 | u.action.u.chan_switch.variable); |
1194 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); | 1198 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); |
1195 | 1199 | ||
1196 | ttl = elems.mesh_chansw_params_ie->mesh_ttl; | 1200 | ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; |
1197 | if (!--ttl) | 1201 | if (!--ifmsh->chsw_ttl) |
1198 | fwd_csa = false; | 1202 | fwd_csa = false; |
1199 | 1203 | ||
1200 | pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); | 1204 | pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d7504ab61a34..b3a3ce316656 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1910,6 +1910,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
1910 | if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) | 1910 | if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) |
1911 | already = true; | 1911 | already = true; |
1912 | 1912 | ||
1913 | ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL; | ||
1914 | |||
1913 | mutex_unlock(&sdata->local->mtx); | 1915 | mutex_unlock(&sdata->local->mtx); |
1914 | 1916 | ||
1915 | if (already) | 1917 | if (already) |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 5d60779a0c1b..4096ff6cc24f 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -226,7 +226,7 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) | |||
226 | nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); | 226 | nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); |
227 | 227 | ||
228 | nsecs += minstrel_mcs_groups[group].duration[rate]; | 228 | nsecs += minstrel_mcs_groups[group].duration[rate]; |
229 | tp = 1000000 * ((mr->probability * 1000) / nsecs); | 229 | tp = 1000000 * ((prob * 1000) / nsecs); |
230 | 230 | ||
231 | mr->cur_tp = MINSTREL_TRUNC(tp); | 231 | mr->cur_tp = MINSTREL_TRUNC(tp); |
232 | } | 232 | } |
@@ -277,13 +277,15 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
277 | if (!(mg->supported & BIT(i))) | 277 | if (!(mg->supported & BIT(i))) |
278 | continue; | 278 | continue; |
279 | 279 | ||
280 | index = MCS_GROUP_RATES * group + i; | ||
281 | |||
280 | /* initialize rates selections starting indexes */ | 282 | /* initialize rates selections starting indexes */ |
281 | if (!mg_rates_valid) { | 283 | if (!mg_rates_valid) { |
282 | mg->max_tp_rate = mg->max_tp_rate2 = | 284 | mg->max_tp_rate = mg->max_tp_rate2 = |
283 | mg->max_prob_rate = i; | 285 | mg->max_prob_rate = i; |
284 | if (!mi_rates_valid) { | 286 | if (!mi_rates_valid) { |
285 | mi->max_tp_rate = mi->max_tp_rate2 = | 287 | mi->max_tp_rate = mi->max_tp_rate2 = |
286 | mi->max_prob_rate = i; | 288 | mi->max_prob_rate = index; |
287 | mi_rates_valid = true; | 289 | mi_rates_valid = true; |
288 | } | 290 | } |
289 | mg_rates_valid = true; | 291 | mg_rates_valid = true; |
@@ -291,7 +293,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
291 | 293 | ||
292 | mr = &mg->rates[i]; | 294 | mr = &mg->rates[i]; |
293 | mr->retry_updated = false; | 295 | mr->retry_updated = false; |
294 | index = MCS_GROUP_RATES * group + i; | ||
295 | minstrel_calc_rate_ewma(mr); | 296 | minstrel_calc_rate_ewma(mr); |
296 | minstrel_ht_calc_tp(mi, group, i); | 297 | minstrel_ht_calc_tp(mi, group, i); |
297 | 298 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index caecef870c0e..2b0debb0422b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -911,7 +911,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, | |||
911 | u16 sc; | 911 | u16 sc; |
912 | u8 tid, ack_policy; | 912 | u8 tid, ack_policy; |
913 | 913 | ||
914 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 914 | if (!ieee80211_is_data_qos(hdr->frame_control) || |
915 | is_multicast_ether_addr(hdr->addr1)) | ||
915 | goto dont_reorder; | 916 | goto dont_reorder; |
916 | 917 | ||
917 | /* | 918 | /* |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 5ad66a83ef7f..bcc4833d7542 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -1088,6 +1088,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) | |||
1088 | 1088 | ||
1089 | trace_api_sched_scan_stopped(local); | 1089 | trace_api_sched_scan_stopped(local); |
1090 | 1090 | ||
1091 | ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work); | 1091 | schedule_work(&local->sched_scan_stopped_work); |
1092 | } | 1092 | } |
1093 | EXPORT_SYMBOL(ieee80211_sched_scan_stopped); | 1093 | EXPORT_SYMBOL(ieee80211_sched_scan_stopped); |
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index a40da20b32e0..6ab009070084 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
@@ -78,6 +78,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
78 | if (elems->mesh_chansw_params_ie) { | 78 | if (elems->mesh_chansw_params_ie) { |
79 | csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl; | 79 | csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl; |
80 | csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; | 80 | csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; |
81 | csa_ie->pre_value = le16_to_cpu( | ||
82 | elems->mesh_chansw_params_ie->mesh_pre_value); | ||
81 | } | 83 | } |
82 | 84 | ||
83 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); | 85 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c558b246ef00..ca7fa7f0613d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -463,7 +463,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
463 | { | 463 | { |
464 | struct sta_info *sta = tx->sta; | 464 | struct sta_info *sta = tx->sta; |
465 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 465 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
466 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
467 | struct ieee80211_local *local = tx->local; | 466 | struct ieee80211_local *local = tx->local; |
468 | 467 | ||
469 | if (unlikely(!sta)) | 468 | if (unlikely(!sta)) |
@@ -474,15 +473,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
474 | !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) { | 473 | !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) { |
475 | int ac = skb_get_queue_mapping(tx->skb); | 474 | int ac = skb_get_queue_mapping(tx->skb); |
476 | 475 | ||
477 | /* only deauth, disassoc and action are bufferable MMPDUs */ | ||
478 | if (ieee80211_is_mgmt(hdr->frame_control) && | ||
479 | !ieee80211_is_deauth(hdr->frame_control) && | ||
480 | !ieee80211_is_disassoc(hdr->frame_control) && | ||
481 | !ieee80211_is_action(hdr->frame_control)) { | ||
482 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; | ||
483 | return TX_CONTINUE; | ||
484 | } | ||
485 | |||
486 | ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n", | 476 | ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n", |
487 | sta->sta.addr, sta->sta.aid, ac); | 477 | sta->sta.addr, sta->sta.aid, ac); |
488 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 478 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
@@ -525,9 +515,22 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
525 | static ieee80211_tx_result debug_noinline | 515 | static ieee80211_tx_result debug_noinline |
526 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | 516 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) |
527 | { | 517 | { |
518 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
519 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
520 | |||
528 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) | 521 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) |
529 | return TX_CONTINUE; | 522 | return TX_CONTINUE; |
530 | 523 | ||
524 | /* only deauth, disassoc and action are bufferable MMPDUs */ | ||
525 | if (ieee80211_is_mgmt(hdr->frame_control) && | ||
526 | !ieee80211_is_deauth(hdr->frame_control) && | ||
527 | !ieee80211_is_disassoc(hdr->frame_control) && | ||
528 | !ieee80211_is_action(hdr->frame_control)) { | ||
529 | if (tx->flags & IEEE80211_TX_UNICAST) | ||
530 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; | ||
531 | return TX_CONTINUE; | ||
532 | } | ||
533 | |||
531 | if (tx->flags & IEEE80211_TX_UNICAST) | 534 | if (tx->flags & IEEE80211_TX_UNICAST) |
532 | return ieee80211_tx_h_unicast_ps_buf(tx); | 535 | return ieee80211_tx_h_unicast_ps_buf(tx); |
533 | else | 536 | else |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 592a18171f95..9f9b9bd3fd44 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2278,17 +2278,15 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work) | |||
2278 | { | 2278 | { |
2279 | struct ieee80211_local *local = | 2279 | struct ieee80211_local *local = |
2280 | container_of(work, struct ieee80211_local, radar_detected_work); | 2280 | container_of(work, struct ieee80211_local, radar_detected_work); |
2281 | struct cfg80211_chan_def chandef; | 2281 | struct cfg80211_chan_def chandef = local->hw.conf.chandef; |
2282 | 2282 | ||
2283 | ieee80211_dfs_cac_cancel(local); | 2283 | ieee80211_dfs_cac_cancel(local); |
2284 | 2284 | ||
2285 | if (local->use_chanctx) | 2285 | if (local->use_chanctx) |
2286 | /* currently not handled */ | 2286 | /* currently not handled */ |
2287 | WARN_ON(1); | 2287 | WARN_ON(1); |
2288 | else { | 2288 | else |
2289 | chandef = local->hw.conf.chandef; | ||
2290 | cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); | 2289 | cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); |
2291 | } | ||
2292 | } | 2290 | } |
2293 | 2291 | ||
2294 | void ieee80211_radar_detected(struct ieee80211_hw *hw) | 2292 | void ieee80211_radar_detected(struct ieee80211_hw *hw) |
@@ -2459,14 +2457,9 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | |||
2459 | WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; | 2457 | WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; |
2460 | put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ | 2458 | put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ |
2461 | pos += 2; | 2459 | pos += 2; |
2462 | if (!ifmsh->pre_value) | ||
2463 | ifmsh->pre_value = 1; | ||
2464 | else | ||
2465 | ifmsh->pre_value++; | ||
2466 | pre_value = cpu_to_le16(ifmsh->pre_value); | 2460 | pre_value = cpu_to_le16(ifmsh->pre_value); |
2467 | memcpy(pos, &pre_value, 2); /* Precedence Value */ | 2461 | memcpy(pos, &pre_value, 2); /* Precedence Value */ |
2468 | pos += 2; | 2462 | pos += 2; |
2469 | ifmsh->chsw_init = true; | ||
2470 | } | 2463 | } |
2471 | 2464 | ||
2472 | ieee80211_tx_skb(sdata, skb); | 2465 | ieee80211_tx_skb(sdata, skb); |
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c index 2bc2dec20b00..6226803fc490 100644 --- a/net/netfilter/ipset/ip_set_hash_netnet.c +++ b/net/netfilter/ipset/ip_set_hash_netnet.c | |||
@@ -59,7 +59,7 @@ hash_netnet4_data_equal(const struct hash_netnet4_elem *ip1, | |||
59 | u32 *multi) | 59 | u32 *multi) |
60 | { | 60 | { |
61 | return ip1->ipcmp == ip2->ipcmp && | 61 | return ip1->ipcmp == ip2->ipcmp && |
62 | ip2->ccmp == ip2->ccmp; | 62 | ip1->ccmp == ip2->ccmp; |
63 | } | 63 | } |
64 | 64 | ||
65 | static inline int | 65 | static inline int |
diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c index c8beafd401aa..5a355a46d1dc 100644 --- a/net/netfilter/ipvs/ip_vs_nfct.c +++ b/net/netfilter/ipvs/ip_vs_nfct.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <net/ip_vs.h> | 63 | #include <net/ip_vs.h> |
64 | #include <net/netfilter/nf_conntrack_core.h> | 64 | #include <net/netfilter/nf_conntrack_core.h> |
65 | #include <net/netfilter/nf_conntrack_expect.h> | 65 | #include <net/netfilter/nf_conntrack_expect.h> |
66 | #include <net/netfilter/nf_conntrack_seqadj.h> | ||
66 | #include <net/netfilter/nf_conntrack_helper.h> | 67 | #include <net/netfilter/nf_conntrack_helper.h> |
67 | #include <net/netfilter/nf_conntrack_zones.h> | 68 | #include <net/netfilter/nf_conntrack_zones.h> |
68 | 69 | ||
@@ -97,6 +98,11 @@ ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) | |||
97 | if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) | 98 | if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) |
98 | return; | 99 | return; |
99 | 100 | ||
101 | /* Applications may adjust TCP seqs */ | ||
102 | if (cp->app && nf_ct_protonum(ct) == IPPROTO_TCP && | ||
103 | !nfct_seqadj(ct) && !nfct_seqadj_ext_add(ct)) | ||
104 | return; | ||
105 | |||
100 | /* | 106 | /* |
101 | * The connection is not yet in the hashtable, so we update it. | 107 | * The connection is not yet in the hashtable, so we update it. |
102 | * CIP->VIP will remain the same, so leave the tuple in | 108 | * CIP->VIP will remain the same, so leave the tuple in |
diff --git a/net/netfilter/nf_conntrack_seqadj.c b/net/netfilter/nf_conntrack_seqadj.c index 17c1bcb182c6..f6e2ae91a80b 100644 --- a/net/netfilter/nf_conntrack_seqadj.c +++ b/net/netfilter/nf_conntrack_seqadj.c | |||
@@ -36,6 +36,11 @@ int nf_ct_seqadj_set(struct nf_conn *ct, enum ip_conntrack_info ctinfo, | |||
36 | if (off == 0) | 36 | if (off == 0) |
37 | return 0; | 37 | return 0; |
38 | 38 | ||
39 | if (unlikely(!seqadj)) { | ||
40 | WARN_ONCE(1, "Missing nfct_seqadj_ext_add() setup call\n"); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
39 | set_bit(IPS_SEQ_ADJUST_BIT, &ct->status); | 44 | set_bit(IPS_SEQ_ADJUST_BIT, &ct->status); |
40 | 45 | ||
41 | spin_lock_bh(&ct->lock); | 46 | spin_lock_bh(&ct->lock); |
diff --git a/net/netfilter/nf_conntrack_timestamp.c b/net/netfilter/nf_conntrack_timestamp.c index 902fb0a6b38a..7a394df0deb7 100644 --- a/net/netfilter/nf_conntrack_timestamp.c +++ b/net/netfilter/nf_conntrack_timestamp.c | |||
@@ -97,7 +97,6 @@ int nf_conntrack_tstamp_pernet_init(struct net *net) | |||
97 | void nf_conntrack_tstamp_pernet_fini(struct net *net) | 97 | void nf_conntrack_tstamp_pernet_fini(struct net *net) |
98 | { | 98 | { |
99 | nf_conntrack_tstamp_fini_sysctl(net); | 99 | nf_conntrack_tstamp_fini_sysctl(net); |
100 | nf_ct_extend_unregister(&tstamp_extend); | ||
101 | } | 100 | } |
102 | 101 | ||
103 | int nf_conntrack_tstamp_init(void) | 102 | int nf_conntrack_tstamp_init(void) |
diff --git a/net/netfilter/nf_nat_irc.c b/net/netfilter/nf_nat_irc.c index f02b3605823e..1fb2258c3535 100644 --- a/net/netfilter/nf_nat_irc.c +++ b/net/netfilter/nf_nat_irc.c | |||
@@ -34,10 +34,14 @@ static unsigned int help(struct sk_buff *skb, | |||
34 | struct nf_conntrack_expect *exp) | 34 | struct nf_conntrack_expect *exp) |
35 | { | 35 | { |
36 | char buffer[sizeof("4294967296 65635")]; | 36 | char buffer[sizeof("4294967296 65635")]; |
37 | struct nf_conn *ct = exp->master; | ||
38 | union nf_inet_addr newaddr; | ||
37 | u_int16_t port; | 39 | u_int16_t port; |
38 | unsigned int ret; | 40 | unsigned int ret; |
39 | 41 | ||
40 | /* Reply comes from server. */ | 42 | /* Reply comes from server. */ |
43 | newaddr = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3; | ||
44 | |||
41 | exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; | 45 | exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; |
42 | exp->dir = IP_CT_DIR_REPLY; | 46 | exp->dir = IP_CT_DIR_REPLY; |
43 | exp->expectfn = nf_nat_follow_master; | 47 | exp->expectfn = nf_nat_follow_master; |
@@ -57,17 +61,35 @@ static unsigned int help(struct sk_buff *skb, | |||
57 | } | 61 | } |
58 | 62 | ||
59 | if (port == 0) { | 63 | if (port == 0) { |
60 | nf_ct_helper_log(skb, exp->master, "all ports in use"); | 64 | nf_ct_helper_log(skb, ct, "all ports in use"); |
61 | return NF_DROP; | 65 | return NF_DROP; |
62 | } | 66 | } |
63 | 67 | ||
64 | ret = nf_nat_mangle_tcp_packet(skb, exp->master, ctinfo, | 68 | /* strlen("\1DCC CHAT chat AAAAAAAA P\1\n")=27 |
65 | protoff, matchoff, matchlen, buffer, | 69 | * strlen("\1DCC SCHAT chat AAAAAAAA P\1\n")=28 |
66 | strlen(buffer)); | 70 | * strlen("\1DCC SEND F AAAAAAAA P S\1\n")=26 |
71 | * strlen("\1DCC MOVE F AAAAAAAA P S\1\n")=26 | ||
72 | * strlen("\1DCC TSEND F AAAAAAAA P S\1\n")=27 | ||
73 | * | ||
74 | * AAAAAAAAA: bound addr (1.0.0.0==16777216, min 8 digits, | ||
75 | * 255.255.255.255==4294967296, 10 digits) | ||
76 | * P: bound port (min 1 d, max 5d (65635)) | ||
77 | * F: filename (min 1 d ) | ||
78 | * S: size (min 1 d ) | ||
79 | * 0x01, \n: terminators | ||
80 | */ | ||
81 | /* AAA = "us", ie. where server normally talks to. */ | ||
82 | snprintf(buffer, sizeof(buffer), "%u %u", ntohl(newaddr.ip), port); | ||
83 | pr_debug("nf_nat_irc: inserting '%s' == %pI4, port %u\n", | ||
84 | buffer, &newaddr.ip, port); | ||
85 | |||
86 | ret = nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff, matchoff, | ||
87 | matchlen, buffer, strlen(buffer)); | ||
67 | if (ret != NF_ACCEPT) { | 88 | if (ret != NF_ACCEPT) { |
68 | nf_ct_helper_log(skb, exp->master, "cannot mangle packet"); | 89 | nf_ct_helper_log(skb, ct, "cannot mangle packet"); |
69 | nf_ct_unexpect_related(exp); | 90 | nf_ct_unexpect_related(exp); |
70 | } | 91 | } |
92 | |||
71 | return ret; | 93 | return ret; |
72 | } | 94 | } |
73 | 95 | ||
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index dcddc49c0e08..71a9f49a768b 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -312,6 +312,9 @@ static int nf_tables_table_enable(struct nft_table *table) | |||
312 | int err, i = 0; | 312 | int err, i = 0; |
313 | 313 | ||
314 | list_for_each_entry(chain, &table->chains, list) { | 314 | list_for_each_entry(chain, &table->chains, list) { |
315 | if (!(chain->flags & NFT_BASE_CHAIN)) | ||
316 | continue; | ||
317 | |||
315 | err = nf_register_hook(&nft_base_chain(chain)->ops); | 318 | err = nf_register_hook(&nft_base_chain(chain)->ops); |
316 | if (err < 0) | 319 | if (err < 0) |
317 | goto err; | 320 | goto err; |
@@ -321,6 +324,9 @@ static int nf_tables_table_enable(struct nft_table *table) | |||
321 | return 0; | 324 | return 0; |
322 | err: | 325 | err: |
323 | list_for_each_entry(chain, &table->chains, list) { | 326 | list_for_each_entry(chain, &table->chains, list) { |
327 | if (!(chain->flags & NFT_BASE_CHAIN)) | ||
328 | continue; | ||
329 | |||
324 | if (i-- <= 0) | 330 | if (i-- <= 0) |
325 | break; | 331 | break; |
326 | 332 | ||
@@ -333,8 +339,10 @@ static int nf_tables_table_disable(struct nft_table *table) | |||
333 | { | 339 | { |
334 | struct nft_chain *chain; | 340 | struct nft_chain *chain; |
335 | 341 | ||
336 | list_for_each_entry(chain, &table->chains, list) | 342 | list_for_each_entry(chain, &table->chains, list) { |
337 | nf_unregister_hook(&nft_base_chain(chain)->ops); | 343 | if (chain->flags & NFT_BASE_CHAIN) |
344 | nf_unregister_hook(&nft_base_chain(chain)->ops); | ||
345 | } | ||
338 | 346 | ||
339 | return 0; | 347 | return 0; |
340 | } | 348 | } |
@@ -1717,6 +1725,19 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule) | |||
1717 | return -ENOENT; | 1725 | return -ENOENT; |
1718 | } | 1726 | } |
1719 | 1727 | ||
1728 | static int nf_table_delrule_by_chain(struct nft_ctx *ctx) | ||
1729 | { | ||
1730 | struct nft_rule *rule; | ||
1731 | int err; | ||
1732 | |||
1733 | list_for_each_entry(rule, &ctx->chain->rules, list) { | ||
1734 | err = nf_tables_delrule_one(ctx, rule); | ||
1735 | if (err < 0) | ||
1736 | return err; | ||
1737 | } | ||
1738 | return 0; | ||
1739 | } | ||
1740 | |||
1720 | static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | 1741 | static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, |
1721 | const struct nlmsghdr *nlh, | 1742 | const struct nlmsghdr *nlh, |
1722 | const struct nlattr * const nla[]) | 1743 | const struct nlattr * const nla[]) |
@@ -1725,8 +1746,8 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | |||
1725 | const struct nft_af_info *afi; | 1746 | const struct nft_af_info *afi; |
1726 | struct net *net = sock_net(skb->sk); | 1747 | struct net *net = sock_net(skb->sk); |
1727 | const struct nft_table *table; | 1748 | const struct nft_table *table; |
1728 | struct nft_chain *chain; | 1749 | struct nft_chain *chain = NULL; |
1729 | struct nft_rule *rule, *tmp; | 1750 | struct nft_rule *rule; |
1730 | int family = nfmsg->nfgen_family, err = 0; | 1751 | int family = nfmsg->nfgen_family, err = 0; |
1731 | struct nft_ctx ctx; | 1752 | struct nft_ctx ctx; |
1732 | 1753 | ||
@@ -1738,22 +1759,29 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | |||
1738 | if (IS_ERR(table)) | 1759 | if (IS_ERR(table)) |
1739 | return PTR_ERR(table); | 1760 | return PTR_ERR(table); |
1740 | 1761 | ||
1741 | chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); | 1762 | if (nla[NFTA_RULE_CHAIN]) { |
1742 | if (IS_ERR(chain)) | 1763 | chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); |
1743 | return PTR_ERR(chain); | 1764 | if (IS_ERR(chain)) |
1765 | return PTR_ERR(chain); | ||
1766 | } | ||
1744 | 1767 | ||
1745 | nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); | 1768 | nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); |
1746 | 1769 | ||
1747 | if (nla[NFTA_RULE_HANDLE]) { | 1770 | if (chain) { |
1748 | rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]); | 1771 | if (nla[NFTA_RULE_HANDLE]) { |
1749 | if (IS_ERR(rule)) | 1772 | rule = nf_tables_rule_lookup(chain, |
1750 | return PTR_ERR(rule); | 1773 | nla[NFTA_RULE_HANDLE]); |
1774 | if (IS_ERR(rule)) | ||
1775 | return PTR_ERR(rule); | ||
1751 | 1776 | ||
1752 | err = nf_tables_delrule_one(&ctx, rule); | ||
1753 | } else { | ||
1754 | /* Remove all rules in this chain */ | ||
1755 | list_for_each_entry_safe(rule, tmp, &chain->rules, list) { | ||
1756 | err = nf_tables_delrule_one(&ctx, rule); | 1777 | err = nf_tables_delrule_one(&ctx, rule); |
1778 | } else { | ||
1779 | err = nf_table_delrule_by_chain(&ctx); | ||
1780 | } | ||
1781 | } else { | ||
1782 | list_for_each_entry(chain, &table->chains, list) { | ||
1783 | ctx.chain = chain; | ||
1784 | err = nf_table_delrule_by_chain(&ctx); | ||
1757 | if (err < 0) | 1785 | if (err < 0) |
1758 | break; | 1786 | break; |
1759 | } | 1787 | } |
@@ -2078,17 +2106,21 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, | |||
2078 | struct netlink_callback *cb) | 2106 | struct netlink_callback *cb) |
2079 | { | 2107 | { |
2080 | const struct nft_set *set; | 2108 | const struct nft_set *set; |
2081 | unsigned int idx = 0, s_idx = cb->args[0]; | 2109 | unsigned int idx, s_idx = cb->args[0]; |
2082 | struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; | 2110 | struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; |
2083 | 2111 | ||
2084 | if (cb->args[1]) | 2112 | if (cb->args[1]) |
2085 | return skb->len; | 2113 | return skb->len; |
2086 | 2114 | ||
2087 | list_for_each_entry(table, &ctx->afi->tables, list) { | 2115 | list_for_each_entry(table, &ctx->afi->tables, list) { |
2088 | if (cur_table && cur_table != table) | 2116 | if (cur_table) { |
2089 | continue; | 2117 | if (cur_table != table) |
2118 | continue; | ||
2090 | 2119 | ||
2120 | cur_table = NULL; | ||
2121 | } | ||
2091 | ctx->table = table; | 2122 | ctx->table = table; |
2123 | idx = 0; | ||
2092 | list_for_each_entry(set, &ctx->table->sets, list) { | 2124 | list_for_each_entry(set, &ctx->table->sets, list) { |
2093 | if (idx < s_idx) | 2125 | if (idx < s_idx) |
2094 | goto cont; | 2126 | goto cont; |
@@ -2350,7 +2382,9 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx, | |||
2350 | enum nft_registers dreg; | 2382 | enum nft_registers dreg; |
2351 | 2383 | ||
2352 | dreg = nft_type_to_reg(set->dtype); | 2384 | dreg = nft_type_to_reg(set->dtype); |
2353 | return nft_validate_data_load(ctx, dreg, &elem->data, set->dtype); | 2385 | return nft_validate_data_load(ctx, dreg, &elem->data, |
2386 | set->dtype == NFT_DATA_VERDICT ? | ||
2387 | NFT_DATA_VERDICT : NFT_DATA_VALUE); | ||
2354 | } | 2388 | } |
2355 | 2389 | ||
2356 | int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, | 2390 | int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 3c4b69e5fe17..a155d19a225e 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -1053,6 +1053,7 @@ static void __net_exit nfnl_log_net_exit(struct net *net) | |||
1053 | #ifdef CONFIG_PROC_FS | 1053 | #ifdef CONFIG_PROC_FS |
1054 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); | 1054 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); |
1055 | #endif | 1055 | #endif |
1056 | nf_log_unset(net, &nfulnl_logger); | ||
1056 | } | 1057 | } |
1057 | 1058 | ||
1058 | static struct pernet_operations nfnl_log_net_ops = { | 1059 | static struct pernet_operations nfnl_log_net_ops = { |
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index 8e0bb75e7c51..55c939f5371f 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c | |||
@@ -31,7 +31,7 @@ static void nft_exthdr_eval(const struct nft_expr *expr, | |||
31 | { | 31 | { |
32 | struct nft_exthdr *priv = nft_expr_priv(expr); | 32 | struct nft_exthdr *priv = nft_expr_priv(expr); |
33 | struct nft_data *dest = &data[priv->dreg]; | 33 | struct nft_data *dest = &data[priv->dreg]; |
34 | unsigned int offset; | 34 | unsigned int offset = 0; |
35 | int err; | 35 | int err; |
36 | 36 | ||
37 | err = ipv6_find_hdr(pkt->skb, &offset, priv->type, NULL, NULL); | 37 | err = ipv6_find_hdr(pkt->skb, &offset, priv->type, NULL, NULL); |
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 9ff035c71403..a3910fc2122b 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
@@ -325,21 +325,24 @@ static void htable_gc(unsigned long htlong) | |||
325 | add_timer(&ht->timer); | 325 | add_timer(&ht->timer); |
326 | } | 326 | } |
327 | 327 | ||
328 | static void htable_destroy(struct xt_hashlimit_htable *hinfo) | 328 | static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo) |
329 | { | 329 | { |
330 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(hinfo->net); | 330 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(hinfo->net); |
331 | struct proc_dir_entry *parent; | 331 | struct proc_dir_entry *parent; |
332 | 332 | ||
333 | del_timer_sync(&hinfo->timer); | ||
334 | |||
335 | if (hinfo->family == NFPROTO_IPV4) | 333 | if (hinfo->family == NFPROTO_IPV4) |
336 | parent = hashlimit_net->ipt_hashlimit; | 334 | parent = hashlimit_net->ipt_hashlimit; |
337 | else | 335 | else |
338 | parent = hashlimit_net->ip6t_hashlimit; | 336 | parent = hashlimit_net->ip6t_hashlimit; |
339 | 337 | ||
340 | if(parent != NULL) | 338 | if (parent != NULL) |
341 | remove_proc_entry(hinfo->name, parent); | 339 | remove_proc_entry(hinfo->name, parent); |
340 | } | ||
342 | 341 | ||
342 | static void htable_destroy(struct xt_hashlimit_htable *hinfo) | ||
343 | { | ||
344 | del_timer_sync(&hinfo->timer); | ||
345 | htable_remove_proc_entry(hinfo); | ||
343 | htable_selective_cleanup(hinfo, select_all); | 346 | htable_selective_cleanup(hinfo, select_all); |
344 | kfree(hinfo->name); | 347 | kfree(hinfo->name); |
345 | vfree(hinfo); | 348 | vfree(hinfo); |
@@ -883,21 +886,15 @@ static int __net_init hashlimit_proc_net_init(struct net *net) | |||
883 | static void __net_exit hashlimit_proc_net_exit(struct net *net) | 886 | static void __net_exit hashlimit_proc_net_exit(struct net *net) |
884 | { | 887 | { |
885 | struct xt_hashlimit_htable *hinfo; | 888 | struct xt_hashlimit_htable *hinfo; |
886 | struct proc_dir_entry *pde; | ||
887 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); | 889 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); |
888 | 890 | ||
889 | /* recent_net_exit() is called before recent_mt_destroy(). Make sure | 891 | /* hashlimit_net_exit() is called before hashlimit_mt_destroy(). |
890 | * that the parent xt_recent proc entry is is empty before trying to | 892 | * Make sure that the parent ipt_hashlimit and ip6t_hashlimit proc |
891 | * remove it. | 893 | * entries is empty before trying to remove it. |
892 | */ | 894 | */ |
893 | mutex_lock(&hashlimit_mutex); | 895 | mutex_lock(&hashlimit_mutex); |
894 | pde = hashlimit_net->ipt_hashlimit; | ||
895 | if (pde == NULL) | ||
896 | pde = hashlimit_net->ip6t_hashlimit; | ||
897 | |||
898 | hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) | 896 | hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) |
899 | remove_proc_entry(hinfo->name, pde); | 897 | htable_remove_proc_entry(hinfo); |
900 | |||
901 | hashlimit_net->ipt_hashlimit = NULL; | 898 | hashlimit_net->ipt_hashlimit = NULL; |
902 | hashlimit_net->ip6t_hashlimit = NULL; | 899 | hashlimit_net->ip6t_hashlimit = NULL; |
903 | mutex_unlock(&hashlimit_mutex); | 900 | mutex_unlock(&hashlimit_mutex); |
diff --git a/net/nfc/core.c b/net/nfc/core.c index 872529105abc..83b9927e7d19 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -384,7 +384,7 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, | |||
384 | { | 384 | { |
385 | dev->dep_link_up = true; | 385 | dev->dep_link_up = true; |
386 | 386 | ||
387 | if (!dev->active_target) { | 387 | if (!dev->active_target && rf_mode == NFC_RF_INITIATOR) { |
388 | struct nfc_target *target; | 388 | struct nfc_target *target; |
389 | 389 | ||
390 | target = nfc_find_target(dev, target_idx); | 390 | target = nfc_find_target(dev, target_idx); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ba2548bd85bf..88cfbc189558 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -237,6 +237,30 @@ struct packet_skb_cb { | |||
237 | static void __fanout_unlink(struct sock *sk, struct packet_sock *po); | 237 | static void __fanout_unlink(struct sock *sk, struct packet_sock *po); |
238 | static void __fanout_link(struct sock *sk, struct packet_sock *po); | 238 | static void __fanout_link(struct sock *sk, struct packet_sock *po); |
239 | 239 | ||
240 | static struct net_device *packet_cached_dev_get(struct packet_sock *po) | ||
241 | { | ||
242 | struct net_device *dev; | ||
243 | |||
244 | rcu_read_lock(); | ||
245 | dev = rcu_dereference(po->cached_dev); | ||
246 | if (likely(dev)) | ||
247 | dev_hold(dev); | ||
248 | rcu_read_unlock(); | ||
249 | |||
250 | return dev; | ||
251 | } | ||
252 | |||
253 | static void packet_cached_dev_assign(struct packet_sock *po, | ||
254 | struct net_device *dev) | ||
255 | { | ||
256 | rcu_assign_pointer(po->cached_dev, dev); | ||
257 | } | ||
258 | |||
259 | static void packet_cached_dev_reset(struct packet_sock *po) | ||
260 | { | ||
261 | RCU_INIT_POINTER(po->cached_dev, NULL); | ||
262 | } | ||
263 | |||
240 | /* register_prot_hook must be invoked with the po->bind_lock held, | 264 | /* register_prot_hook must be invoked with the po->bind_lock held, |
241 | * or from a context in which asynchronous accesses to the packet | 265 | * or from a context in which asynchronous accesses to the packet |
242 | * socket is not possible (packet_create()). | 266 | * socket is not possible (packet_create()). |
@@ -246,12 +270,10 @@ static void register_prot_hook(struct sock *sk) | |||
246 | struct packet_sock *po = pkt_sk(sk); | 270 | struct packet_sock *po = pkt_sk(sk); |
247 | 271 | ||
248 | if (!po->running) { | 272 | if (!po->running) { |
249 | if (po->fanout) { | 273 | if (po->fanout) |
250 | __fanout_link(sk, po); | 274 | __fanout_link(sk, po); |
251 | } else { | 275 | else |
252 | dev_add_pack(&po->prot_hook); | 276 | dev_add_pack(&po->prot_hook); |
253 | rcu_assign_pointer(po->cached_dev, po->prot_hook.dev); | ||
254 | } | ||
255 | 277 | ||
256 | sock_hold(sk); | 278 | sock_hold(sk); |
257 | po->running = 1; | 279 | po->running = 1; |
@@ -270,12 +292,11 @@ static void __unregister_prot_hook(struct sock *sk, bool sync) | |||
270 | struct packet_sock *po = pkt_sk(sk); | 292 | struct packet_sock *po = pkt_sk(sk); |
271 | 293 | ||
272 | po->running = 0; | 294 | po->running = 0; |
273 | if (po->fanout) { | 295 | |
296 | if (po->fanout) | ||
274 | __fanout_unlink(sk, po); | 297 | __fanout_unlink(sk, po); |
275 | } else { | 298 | else |
276 | __dev_remove_pack(&po->prot_hook); | 299 | __dev_remove_pack(&po->prot_hook); |
277 | RCU_INIT_POINTER(po->cached_dev, NULL); | ||
278 | } | ||
279 | 300 | ||
280 | __sock_put(sk); | 301 | __sock_put(sk); |
281 | 302 | ||
@@ -2059,19 +2080,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
2059 | return tp_len; | 2080 | return tp_len; |
2060 | } | 2081 | } |
2061 | 2082 | ||
2062 | static struct net_device *packet_cached_dev_get(struct packet_sock *po) | ||
2063 | { | ||
2064 | struct net_device *dev; | ||
2065 | |||
2066 | rcu_read_lock(); | ||
2067 | dev = rcu_dereference(po->cached_dev); | ||
2068 | if (dev) | ||
2069 | dev_hold(dev); | ||
2070 | rcu_read_unlock(); | ||
2071 | |||
2072 | return dev; | ||
2073 | } | ||
2074 | |||
2075 | static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | 2083 | static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
2076 | { | 2084 | { |
2077 | struct sk_buff *skb; | 2085 | struct sk_buff *skb; |
@@ -2088,7 +2096,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2088 | 2096 | ||
2089 | mutex_lock(&po->pg_vec_lock); | 2097 | mutex_lock(&po->pg_vec_lock); |
2090 | 2098 | ||
2091 | if (saddr == NULL) { | 2099 | if (likely(saddr == NULL)) { |
2092 | dev = packet_cached_dev_get(po); | 2100 | dev = packet_cached_dev_get(po); |
2093 | proto = po->num; | 2101 | proto = po->num; |
2094 | addr = NULL; | 2102 | addr = NULL; |
@@ -2242,7 +2250,7 @@ static int packet_snd(struct socket *sock, | |||
2242 | * Get and verify the address. | 2250 | * Get and verify the address. |
2243 | */ | 2251 | */ |
2244 | 2252 | ||
2245 | if (saddr == NULL) { | 2253 | if (likely(saddr == NULL)) { |
2246 | dev = packet_cached_dev_get(po); | 2254 | dev = packet_cached_dev_get(po); |
2247 | proto = po->num; | 2255 | proto = po->num; |
2248 | addr = NULL; | 2256 | addr = NULL; |
@@ -2451,6 +2459,8 @@ static int packet_release(struct socket *sock) | |||
2451 | 2459 | ||
2452 | spin_lock(&po->bind_lock); | 2460 | spin_lock(&po->bind_lock); |
2453 | unregister_prot_hook(sk, false); | 2461 | unregister_prot_hook(sk, false); |
2462 | packet_cached_dev_reset(po); | ||
2463 | |||
2454 | if (po->prot_hook.dev) { | 2464 | if (po->prot_hook.dev) { |
2455 | dev_put(po->prot_hook.dev); | 2465 | dev_put(po->prot_hook.dev); |
2456 | po->prot_hook.dev = NULL; | 2466 | po->prot_hook.dev = NULL; |
@@ -2506,14 +2516,17 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc | |||
2506 | 2516 | ||
2507 | spin_lock(&po->bind_lock); | 2517 | spin_lock(&po->bind_lock); |
2508 | unregister_prot_hook(sk, true); | 2518 | unregister_prot_hook(sk, true); |
2519 | |||
2509 | po->num = protocol; | 2520 | po->num = protocol; |
2510 | po->prot_hook.type = protocol; | 2521 | po->prot_hook.type = protocol; |
2511 | if (po->prot_hook.dev) | 2522 | if (po->prot_hook.dev) |
2512 | dev_put(po->prot_hook.dev); | 2523 | dev_put(po->prot_hook.dev); |
2513 | po->prot_hook.dev = dev; | ||
2514 | 2524 | ||
2525 | po->prot_hook.dev = dev; | ||
2515 | po->ifindex = dev ? dev->ifindex : 0; | 2526 | po->ifindex = dev ? dev->ifindex : 0; |
2516 | 2527 | ||
2528 | packet_cached_dev_assign(po, dev); | ||
2529 | |||
2517 | if (protocol == 0) | 2530 | if (protocol == 0) |
2518 | goto out_unlock; | 2531 | goto out_unlock; |
2519 | 2532 | ||
@@ -2626,7 +2639,8 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, | |||
2626 | po = pkt_sk(sk); | 2639 | po = pkt_sk(sk); |
2627 | sk->sk_family = PF_PACKET; | 2640 | sk->sk_family = PF_PACKET; |
2628 | po->num = proto; | 2641 | po->num = proto; |
2629 | RCU_INIT_POINTER(po->cached_dev, NULL); | 2642 | |
2643 | packet_cached_dev_reset(po); | ||
2630 | 2644 | ||
2631 | sk->sk_destruct = packet_sock_destruct; | 2645 | sk->sk_destruct = packet_sock_destruct; |
2632 | sk_refcnt_debug_inc(sk); | 2646 | sk_refcnt_debug_inc(sk); |
@@ -3337,6 +3351,7 @@ static int packet_notifier(struct notifier_block *this, | |||
3337 | sk->sk_error_report(sk); | 3351 | sk->sk_error_report(sk); |
3338 | } | 3352 | } |
3339 | if (msg == NETDEV_UNREGISTER) { | 3353 | if (msg == NETDEV_UNREGISTER) { |
3354 | packet_cached_dev_reset(po); | ||
3340 | po->ifindex = -1; | 3355 | po->ifindex = -1; |
3341 | if (po->prot_hook.dev) | 3356 | if (po->prot_hook.dev) |
3342 | dev_put(po->prot_hook.dev); | 3357 | dev_put(po->prot_hook.dev); |
diff --git a/net/rds/ib.c b/net/rds/ib.c index b4c8b0022fee..ba2dffeff608 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c | |||
@@ -338,7 +338,8 @@ static int rds_ib_laddr_check(__be32 addr) | |||
338 | ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin); | 338 | ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin); |
339 | /* due to this, we will claim to support iWARP devices unless we | 339 | /* due to this, we will claim to support iWARP devices unless we |
340 | check node_type. */ | 340 | check node_type. */ |
341 | if (ret || cm_id->device->node_type != RDMA_NODE_IB_CA) | 341 | if (ret || !cm_id->device || |
342 | cm_id->device->node_type != RDMA_NODE_IB_CA) | ||
342 | ret = -EADDRNOTAVAIL; | 343 | ret = -EADDRNOTAVAIL; |
343 | 344 | ||
344 | rdsdebug("addr %pI4 ret %d node type %d\n", | 345 | rdsdebug("addr %pI4 ret %d node type %d\n", |
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index e59094981175..37be6e226d1b 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c | |||
@@ -552,9 +552,8 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, | |||
552 | && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { | 552 | && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { |
553 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); | 553 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); |
554 | scat = &rm->data.op_sg[sg]; | 554 | scat = &rm->data.op_sg[sg]; |
555 | ret = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; | 555 | ret = max_t(int, RDS_CONG_MAP_BYTES, scat->length); |
556 | ret = min_t(int, ret, scat->length - conn->c_xmit_data_off); | 556 | return sizeof(struct rds_header) + ret; |
557 | return ret; | ||
558 | } | 557 | } |
559 | 558 | ||
560 | /* FIXME we may overallocate here */ | 559 | /* FIXME we may overallocate here */ |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 33af77246bfe..62ced6516c58 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -1253,6 +1253,7 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1253 | 1253 | ||
1254 | if (msg->msg_name) { | 1254 | if (msg->msg_name) { |
1255 | struct sockaddr_rose *srose; | 1255 | struct sockaddr_rose *srose; |
1256 | struct full_sockaddr_rose *full_srose = msg->msg_name; | ||
1256 | 1257 | ||
1257 | memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose)); | 1258 | memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose)); |
1258 | srose = msg->msg_name; | 1259 | srose = msg->msg_name; |
@@ -1260,18 +1261,9 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1260 | srose->srose_addr = rose->dest_addr; | 1261 | srose->srose_addr = rose->dest_addr; |
1261 | srose->srose_call = rose->dest_call; | 1262 | srose->srose_call = rose->dest_call; |
1262 | srose->srose_ndigis = rose->dest_ndigis; | 1263 | srose->srose_ndigis = rose->dest_ndigis; |
1263 | if (msg->msg_namelen >= sizeof(struct full_sockaddr_rose)) { | 1264 | for (n = 0 ; n < rose->dest_ndigis ; n++) |
1264 | struct full_sockaddr_rose *full_srose = (struct full_sockaddr_rose *)msg->msg_name; | 1265 | full_srose->srose_digis[n] = rose->dest_digis[n]; |
1265 | for (n = 0 ; n < rose->dest_ndigis ; n++) | 1266 | msg->msg_namelen = sizeof(struct full_sockaddr_rose); |
1266 | full_srose->srose_digis[n] = rose->dest_digis[n]; | ||
1267 | msg->msg_namelen = sizeof(struct full_sockaddr_rose); | ||
1268 | } else { | ||
1269 | if (rose->dest_ndigis >= 1) { | ||
1270 | srose->srose_ndigis = 1; | ||
1271 | srose->srose_digi = rose->dest_digis[0]; | ||
1272 | } | ||
1273 | msg->msg_namelen = sizeof(struct sockaddr_rose); | ||
1274 | } | ||
1275 | } | 1267 | } |
1276 | 1268 | ||
1277 | skb_free_datagram(sk, skb); | 1269 | skb_free_datagram(sk, skb); |
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index fd7072827a40..69cb848e8345 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -270,6 +270,16 @@ int tcf_register_action(struct tc_action_ops *act) | |||
270 | { | 270 | { |
271 | struct tc_action_ops *a, **ap; | 271 | struct tc_action_ops *a, **ap; |
272 | 272 | ||
273 | /* Must supply act, dump, cleanup and init */ | ||
274 | if (!act->act || !act->dump || !act->cleanup || !act->init) | ||
275 | return -EINVAL; | ||
276 | |||
277 | /* Supply defaults */ | ||
278 | if (!act->lookup) | ||
279 | act->lookup = tcf_hash_search; | ||
280 | if (!act->walk) | ||
281 | act->walk = tcf_generic_walker; | ||
282 | |||
273 | write_lock(&act_mod_lock); | 283 | write_lock(&act_mod_lock); |
274 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { | 284 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { |
275 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { | 285 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { |
@@ -381,7 +391,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act, | |||
381 | } | 391 | } |
382 | while ((a = act) != NULL) { | 392 | while ((a = act) != NULL) { |
383 | repeat: | 393 | repeat: |
384 | if (a->ops && a->ops->act) { | 394 | if (a->ops) { |
385 | ret = a->ops->act(skb, a, res); | 395 | ret = a->ops->act(skb, a, res); |
386 | if (TC_MUNGED & skb->tc_verd) { | 396 | if (TC_MUNGED & skb->tc_verd) { |
387 | /* copied already, allow trampling */ | 397 | /* copied already, allow trampling */ |
@@ -405,7 +415,7 @@ void tcf_action_destroy(struct tc_action *act, int bind) | |||
405 | struct tc_action *a; | 415 | struct tc_action *a; |
406 | 416 | ||
407 | for (a = act; a; a = act) { | 417 | for (a = act; a; a = act) { |
408 | if (a->ops && a->ops->cleanup) { | 418 | if (a->ops) { |
409 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) | 419 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) |
410 | module_put(a->ops->owner); | 420 | module_put(a->ops->owner); |
411 | act = act->next; | 421 | act = act->next; |
@@ -424,7 +434,7 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
424 | { | 434 | { |
425 | int err = -EINVAL; | 435 | int err = -EINVAL; |
426 | 436 | ||
427 | if (a->ops == NULL || a->ops->dump == NULL) | 437 | if (a->ops == NULL) |
428 | return err; | 438 | return err; |
429 | return a->ops->dump(skb, a, bind, ref); | 439 | return a->ops->dump(skb, a, bind, ref); |
430 | } | 440 | } |
@@ -436,7 +446,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
436 | unsigned char *b = skb_tail_pointer(skb); | 446 | unsigned char *b = skb_tail_pointer(skb); |
437 | struct nlattr *nest; | 447 | struct nlattr *nest; |
438 | 448 | ||
439 | if (a->ops == NULL || a->ops->dump == NULL) | 449 | if (a->ops == NULL) |
440 | return err; | 450 | return err; |
441 | 451 | ||
442 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) | 452 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) |
@@ -723,8 +733,6 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) | |||
723 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); | 733 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); |
724 | if (a->ops == NULL) | 734 | if (a->ops == NULL) |
725 | goto err_free; | 735 | goto err_free; |
726 | if (a->ops->lookup == NULL) | ||
727 | goto err_mod; | ||
728 | err = -ENOENT; | 736 | err = -ENOENT; |
729 | if (a->ops->lookup(a, index) == 0) | 737 | if (a->ops->lookup(a, index) == 0) |
730 | goto err_mod; | 738 | goto err_mod; |
@@ -1084,12 +1092,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) | |||
1084 | memset(&a, 0, sizeof(struct tc_action)); | 1092 | memset(&a, 0, sizeof(struct tc_action)); |
1085 | a.ops = a_o; | 1093 | a.ops = a_o; |
1086 | 1094 | ||
1087 | if (a_o->walk == NULL) { | ||
1088 | WARN(1, "tc_dump_action: %s !capable of dumping table\n", | ||
1089 | a_o->kind); | ||
1090 | goto out_module_put; | ||
1091 | } | ||
1092 | |||
1093 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 1095 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
1094 | cb->nlh->nlmsg_type, sizeof(*t), 0); | 1096 | cb->nlh->nlmsg_type, sizeof(*t), 0); |
1095 | if (!nlh) | 1097 | if (!nlh) |
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 3a4c0caa1f7d..11fe1a416433 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
@@ -77,16 +77,16 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, | |||
77 | &csum_idx_gen, &csum_hash_info); | 77 | &csum_idx_gen, &csum_hash_info); |
78 | if (IS_ERR(pc)) | 78 | if (IS_ERR(pc)) |
79 | return PTR_ERR(pc); | 79 | return PTR_ERR(pc); |
80 | p = to_tcf_csum(pc); | ||
81 | ret = ACT_P_CREATED; | 80 | ret = ACT_P_CREATED; |
82 | } else { | 81 | } else { |
83 | p = to_tcf_csum(pc); | 82 | if (bind)/* dont override defaults */ |
84 | if (!ovr) { | 83 | return 0; |
85 | tcf_hash_release(pc, bind, &csum_hash_info); | 84 | tcf_hash_release(pc, bind, &csum_hash_info); |
85 | if (!ovr) | ||
86 | return -EEXIST; | 86 | return -EEXIST; |
87 | } | ||
88 | } | 87 | } |
89 | 88 | ||
89 | p = to_tcf_csum(pc); | ||
90 | spin_lock_bh(&p->tcf_lock); | 90 | spin_lock_bh(&p->tcf_lock); |
91 | p->tcf_action = parm->action; | 91 | p->tcf_action = parm->action; |
92 | p->update_flags = parm->update_flags; | 92 | p->update_flags = parm->update_flags; |
@@ -585,9 +585,7 @@ static struct tc_action_ops act_csum_ops = { | |||
585 | .act = tcf_csum, | 585 | .act = tcf_csum, |
586 | .dump = tcf_csum_dump, | 586 | .dump = tcf_csum_dump, |
587 | .cleanup = tcf_csum_cleanup, | 587 | .cleanup = tcf_csum_cleanup, |
588 | .lookup = tcf_hash_search, | ||
589 | .init = tcf_csum_init, | 588 | .init = tcf_csum_init, |
590 | .walk = tcf_generic_walker | ||
591 | }; | 589 | }; |
592 | 590 | ||
593 | MODULE_DESCRIPTION("Checksum updating actions"); | 591 | MODULE_DESCRIPTION("Checksum updating actions"); |
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index fd2b3cff5fa2..eb9ba60ebab4 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
@@ -102,10 +102,11 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, | |||
102 | return PTR_ERR(pc); | 102 | return PTR_ERR(pc); |
103 | ret = ACT_P_CREATED; | 103 | ret = ACT_P_CREATED; |
104 | } else { | 104 | } else { |
105 | if (!ovr) { | 105 | if (bind)/* dont override defaults */ |
106 | tcf_hash_release(pc, bind, &gact_hash_info); | 106 | return 0; |
107 | tcf_hash_release(pc, bind, &gact_hash_info); | ||
108 | if (!ovr) | ||
107 | return -EEXIST; | 109 | return -EEXIST; |
108 | } | ||
109 | } | 110 | } |
110 | 111 | ||
111 | gact = to_gact(pc); | 112 | gact = to_gact(pc); |
@@ -206,9 +207,7 @@ static struct tc_action_ops act_gact_ops = { | |||
206 | .act = tcf_gact, | 207 | .act = tcf_gact, |
207 | .dump = tcf_gact_dump, | 208 | .dump = tcf_gact_dump, |
208 | .cleanup = tcf_gact_cleanup, | 209 | .cleanup = tcf_gact_cleanup, |
209 | .lookup = tcf_hash_search, | ||
210 | .init = tcf_gact_init, | 210 | .init = tcf_gact_init, |
211 | .walk = tcf_generic_walker | ||
212 | }; | 211 | }; |
213 | 212 | ||
214 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); | 213 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 60d88b6b9560..dcbfe8ce04a6 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -141,10 +141,12 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
141 | return PTR_ERR(pc); | 141 | return PTR_ERR(pc); |
142 | ret = ACT_P_CREATED; | 142 | ret = ACT_P_CREATED; |
143 | } else { | 143 | } else { |
144 | if (!ovr) { | 144 | if (bind)/* dont override defaults */ |
145 | tcf_ipt_release(to_ipt(pc), bind); | 145 | return 0; |
146 | tcf_ipt_release(to_ipt(pc), bind); | ||
147 | |||
148 | if (!ovr) | ||
146 | return -EEXIST; | 149 | return -EEXIST; |
147 | } | ||
148 | } | 150 | } |
149 | ipt = to_ipt(pc); | 151 | ipt = to_ipt(pc); |
150 | 152 | ||
@@ -298,9 +300,7 @@ static struct tc_action_ops act_ipt_ops = { | |||
298 | .act = tcf_ipt, | 300 | .act = tcf_ipt, |
299 | .dump = tcf_ipt_dump, | 301 | .dump = tcf_ipt_dump, |
300 | .cleanup = tcf_ipt_cleanup, | 302 | .cleanup = tcf_ipt_cleanup, |
301 | .lookup = tcf_hash_search, | ||
302 | .init = tcf_ipt_init, | 303 | .init = tcf_ipt_init, |
303 | .walk = tcf_generic_walker | ||
304 | }; | 304 | }; |
305 | 305 | ||
306 | static struct tc_action_ops act_xt_ops = { | 306 | static struct tc_action_ops act_xt_ops = { |
@@ -312,9 +312,7 @@ static struct tc_action_ops act_xt_ops = { | |||
312 | .act = tcf_ipt, | 312 | .act = tcf_ipt, |
313 | .dump = tcf_ipt_dump, | 313 | .dump = tcf_ipt_dump, |
314 | .cleanup = tcf_ipt_cleanup, | 314 | .cleanup = tcf_ipt_cleanup, |
315 | .lookup = tcf_hash_search, | ||
316 | .init = tcf_ipt_init, | 315 | .init = tcf_ipt_init, |
317 | .walk = tcf_generic_walker | ||
318 | }; | 316 | }; |
319 | 317 | ||
320 | MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); | 318 | MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 977c10e0631b..252378121ce7 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -271,9 +271,7 @@ static struct tc_action_ops act_mirred_ops = { | |||
271 | .act = tcf_mirred, | 271 | .act = tcf_mirred, |
272 | .dump = tcf_mirred_dump, | 272 | .dump = tcf_mirred_dump, |
273 | .cleanup = tcf_mirred_cleanup, | 273 | .cleanup = tcf_mirred_cleanup, |
274 | .lookup = tcf_hash_search, | ||
275 | .init = tcf_mirred_init, | 274 | .init = tcf_mirred_init, |
276 | .walk = tcf_generic_walker | ||
277 | }; | 275 | }; |
278 | 276 | ||
279 | MODULE_AUTHOR("Jamal Hadi Salim(2002)"); | 277 | MODULE_AUTHOR("Jamal Hadi Salim(2002)"); |
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 876f0ef29694..76869538d028 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
@@ -70,15 +70,15 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
70 | &nat_idx_gen, &nat_hash_info); | 70 | &nat_idx_gen, &nat_hash_info); |
71 | if (IS_ERR(pc)) | 71 | if (IS_ERR(pc)) |
72 | return PTR_ERR(pc); | 72 | return PTR_ERR(pc); |
73 | p = to_tcf_nat(pc); | ||
74 | ret = ACT_P_CREATED; | 73 | ret = ACT_P_CREATED; |
75 | } else { | 74 | } else { |
76 | p = to_tcf_nat(pc); | 75 | if (bind) |
77 | if (!ovr) { | 76 | return 0; |
78 | tcf_hash_release(pc, bind, &nat_hash_info); | 77 | tcf_hash_release(pc, bind, &nat_hash_info); |
78 | if (!ovr) | ||
79 | return -EEXIST; | 79 | return -EEXIST; |
80 | } | ||
81 | } | 80 | } |
81 | p = to_tcf_nat(pc); | ||
82 | 82 | ||
83 | spin_lock_bh(&p->tcf_lock); | 83 | spin_lock_bh(&p->tcf_lock); |
84 | p->old_addr = parm->old_addr; | 84 | p->old_addr = parm->old_addr; |
@@ -308,9 +308,7 @@ static struct tc_action_ops act_nat_ops = { | |||
308 | .act = tcf_nat, | 308 | .act = tcf_nat, |
309 | .dump = tcf_nat_dump, | 309 | .dump = tcf_nat_dump, |
310 | .cleanup = tcf_nat_cleanup, | 310 | .cleanup = tcf_nat_cleanup, |
311 | .lookup = tcf_hash_search, | ||
312 | .init = tcf_nat_init, | 311 | .init = tcf_nat_init, |
313 | .walk = tcf_generic_walker | ||
314 | }; | 312 | }; |
315 | 313 | ||
316 | MODULE_DESCRIPTION("Stateless NAT actions"); | 314 | MODULE_DESCRIPTION("Stateless NAT actions"); |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 7ed78c9e505c..7aa2dcd989f8 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
@@ -84,10 +84,12 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, | |||
84 | ret = ACT_P_CREATED; | 84 | ret = ACT_P_CREATED; |
85 | } else { | 85 | } else { |
86 | p = to_pedit(pc); | 86 | p = to_pedit(pc); |
87 | if (!ovr) { | 87 | tcf_hash_release(pc, bind, &pedit_hash_info); |
88 | tcf_hash_release(pc, bind, &pedit_hash_info); | 88 | if (bind) |
89 | return 0; | ||
90 | if (!ovr) | ||
89 | return -EEXIST; | 91 | return -EEXIST; |
90 | } | 92 | |
91 | if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) { | 93 | if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) { |
92 | keys = kmalloc(ksize, GFP_KERNEL); | 94 | keys = kmalloc(ksize, GFP_KERNEL); |
93 | if (keys == NULL) | 95 | if (keys == NULL) |
@@ -243,9 +245,7 @@ static struct tc_action_ops act_pedit_ops = { | |||
243 | .act = tcf_pedit, | 245 | .act = tcf_pedit, |
244 | .dump = tcf_pedit_dump, | 246 | .dump = tcf_pedit_dump, |
245 | .cleanup = tcf_pedit_cleanup, | 247 | .cleanup = tcf_pedit_cleanup, |
246 | .lookup = tcf_hash_search, | ||
247 | .init = tcf_pedit_init, | 248 | .init = tcf_pedit_init, |
248 | .walk = tcf_generic_walker | ||
249 | }; | 249 | }; |
250 | 250 | ||
251 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); | 251 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 272d8e924cf6..ef246d87e68b 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -177,10 +177,12 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, | |||
177 | if (bind) { | 177 | if (bind) { |
178 | police->tcf_bindcnt += 1; | 178 | police->tcf_bindcnt += 1; |
179 | police->tcf_refcnt += 1; | 179 | police->tcf_refcnt += 1; |
180 | return 0; | ||
180 | } | 181 | } |
181 | if (ovr) | 182 | if (ovr) |
182 | goto override; | 183 | goto override; |
183 | return ret; | 184 | /* not replacing */ |
185 | return -EEXIST; | ||
184 | } | 186 | } |
185 | } | 187 | } |
186 | 188 | ||
@@ -407,7 +409,6 @@ static struct tc_action_ops act_police_ops = { | |||
407 | .act = tcf_act_police, | 409 | .act = tcf_act_police, |
408 | .dump = tcf_act_police_dump, | 410 | .dump = tcf_act_police_dump, |
409 | .cleanup = tcf_act_police_cleanup, | 411 | .cleanup = tcf_act_police_cleanup, |
410 | .lookup = tcf_hash_search, | ||
411 | .init = tcf_act_police_locate, | 412 | .init = tcf_act_police_locate, |
412 | .walk = tcf_act_police_walker | 413 | .walk = tcf_act_police_walker |
413 | }; | 414 | }; |
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 7725eb4ab756..f7b45ab85388 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
@@ -142,10 +142,13 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
142 | ret = ACT_P_CREATED; | 142 | ret = ACT_P_CREATED; |
143 | } else { | 143 | } else { |
144 | d = to_defact(pc); | 144 | d = to_defact(pc); |
145 | if (!ovr) { | 145 | |
146 | tcf_simp_release(d, bind); | 146 | if (bind) |
147 | return 0; | ||
148 | tcf_simp_release(d, bind); | ||
149 | if (!ovr) | ||
147 | return -EEXIST; | 150 | return -EEXIST; |
148 | } | 151 | |
149 | reset_policy(d, defdata, parm); | 152 | reset_policy(d, defdata, parm); |
150 | } | 153 | } |
151 | 154 | ||
@@ -201,7 +204,6 @@ static struct tc_action_ops act_simp_ops = { | |||
201 | .dump = tcf_simp_dump, | 204 | .dump = tcf_simp_dump, |
202 | .cleanup = tcf_simp_cleanup, | 205 | .cleanup = tcf_simp_cleanup, |
203 | .init = tcf_simp_init, | 206 | .init = tcf_simp_init, |
204 | .walk = tcf_generic_walker, | ||
205 | }; | 207 | }; |
206 | 208 | ||
207 | MODULE_AUTHOR("Jamal Hadi Salim(2005)"); | 209 | MODULE_AUTHOR("Jamal Hadi Salim(2005)"); |
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index cb4221171f93..8fe9d25c3008 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
@@ -120,10 +120,11 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
120 | ret = ACT_P_CREATED; | 120 | ret = ACT_P_CREATED; |
121 | } else { | 121 | } else { |
122 | d = to_skbedit(pc); | 122 | d = to_skbedit(pc); |
123 | if (!ovr) { | 123 | if (bind) |
124 | tcf_hash_release(pc, bind, &skbedit_hash_info); | 124 | return 0; |
125 | tcf_hash_release(pc, bind, &skbedit_hash_info); | ||
126 | if (!ovr) | ||
125 | return -EEXIST; | 127 | return -EEXIST; |
126 | } | ||
127 | } | 128 | } |
128 | 129 | ||
129 | spin_lock_bh(&d->tcf_lock); | 130 | spin_lock_bh(&d->tcf_lock); |
@@ -203,7 +204,6 @@ static struct tc_action_ops act_skbedit_ops = { | |||
203 | .dump = tcf_skbedit_dump, | 204 | .dump = tcf_skbedit_dump, |
204 | .cleanup = tcf_skbedit_cleanup, | 205 | .cleanup = tcf_skbedit_cleanup, |
205 | .init = tcf_skbedit_init, | 206 | .init = tcf_skbedit_init, |
206 | .walk = tcf_generic_walker, | ||
207 | }; | 207 | }; |
208 | 208 | ||
209 | MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>"); | 209 | MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>"); |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 922a09406ba7..7fc899a943a8 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -126,7 +126,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, | |||
126 | 126 | ||
127 | HARD_TX_LOCK(dev, txq, smp_processor_id()); | 127 | HARD_TX_LOCK(dev, txq, smp_processor_id()); |
128 | if (!netif_xmit_frozen_or_stopped(txq)) | 128 | if (!netif_xmit_frozen_or_stopped(txq)) |
129 | ret = dev_hard_start_xmit(skb, dev, txq, NULL); | 129 | ret = dev_hard_start_xmit(skb, dev, txq); |
130 | 130 | ||
131 | HARD_TX_UNLOCK(dev, txq); | 131 | HARD_TX_UNLOCK(dev, txq); |
132 | 132 | ||
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 0e1e38b40025..717b2108f852 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -1477,11 +1477,22 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1477 | sch_tree_lock(sch); | 1477 | sch_tree_lock(sch); |
1478 | } | 1478 | } |
1479 | 1479 | ||
1480 | rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0; | ||
1481 | |||
1482 | ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0; | ||
1483 | |||
1484 | psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64); | ||
1485 | psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64); | ||
1486 | |||
1480 | /* it used to be a nasty bug here, we have to check that node | 1487 | /* it used to be a nasty bug here, we have to check that node |
1481 | * is really leaf before changing cl->un.leaf ! | 1488 | * is really leaf before changing cl->un.leaf ! |
1482 | */ | 1489 | */ |
1483 | if (!cl->level) { | 1490 | if (!cl->level) { |
1484 | cl->quantum = hopt->rate.rate / q->rate2quantum; | 1491 | u64 quantum = cl->rate.rate_bytes_ps; |
1492 | |||
1493 | do_div(quantum, q->rate2quantum); | ||
1494 | cl->quantum = min_t(u64, quantum, INT_MAX); | ||
1495 | |||
1485 | if (!hopt->quantum && cl->quantum < 1000) { | 1496 | if (!hopt->quantum && cl->quantum < 1000) { |
1486 | pr_warning( | 1497 | pr_warning( |
1487 | "HTB: quantum of class %X is small. Consider r2q change.\n", | 1498 | "HTB: quantum of class %X is small. Consider r2q change.\n", |
@@ -1500,13 +1511,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1500 | cl->prio = TC_HTB_NUMPRIO - 1; | 1511 | cl->prio = TC_HTB_NUMPRIO - 1; |
1501 | } | 1512 | } |
1502 | 1513 | ||
1503 | rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0; | ||
1504 | |||
1505 | ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0; | ||
1506 | |||
1507 | psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64); | ||
1508 | psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64); | ||
1509 | |||
1510 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); | 1514 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); |
1511 | cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); | 1515 | cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); |
1512 | 1516 | ||
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index a6090051c5db..887e672f9d7d 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
@@ -118,6 +118,32 @@ struct tbf_sched_data { | |||
118 | }; | 118 | }; |
119 | 119 | ||
120 | 120 | ||
121 | /* Time to Length, convert time in ns to length in bytes | ||
122 | * to determinate how many bytes can be sent in given time. | ||
123 | */ | ||
124 | static u64 psched_ns_t2l(const struct psched_ratecfg *r, | ||
125 | u64 time_in_ns) | ||
126 | { | ||
127 | /* The formula is : | ||
128 | * len = (time_in_ns * r->rate_bytes_ps) / NSEC_PER_SEC | ||
129 | */ | ||
130 | u64 len = time_in_ns * r->rate_bytes_ps; | ||
131 | |||
132 | do_div(len, NSEC_PER_SEC); | ||
133 | |||
134 | if (unlikely(r->linklayer == TC_LINKLAYER_ATM)) { | ||
135 | do_div(len, 53); | ||
136 | len = len * 48; | ||
137 | } | ||
138 | |||
139 | if (len > r->overhead) | ||
140 | len -= r->overhead; | ||
141 | else | ||
142 | len = 0; | ||
143 | |||
144 | return len; | ||
145 | } | ||
146 | |||
121 | /* | 147 | /* |
122 | * Return length of individual segments of a gso packet, | 148 | * Return length of individual segments of a gso packet, |
123 | * including all headers (MAC, IP, TCP/UDP) | 149 | * including all headers (MAC, IP, TCP/UDP) |
@@ -289,10 +315,11 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
289 | struct tbf_sched_data *q = qdisc_priv(sch); | 315 | struct tbf_sched_data *q = qdisc_priv(sch); |
290 | struct nlattr *tb[TCA_TBF_MAX + 1]; | 316 | struct nlattr *tb[TCA_TBF_MAX + 1]; |
291 | struct tc_tbf_qopt *qopt; | 317 | struct tc_tbf_qopt *qopt; |
292 | struct qdisc_rate_table *rtab = NULL; | ||
293 | struct qdisc_rate_table *ptab = NULL; | ||
294 | struct Qdisc *child = NULL; | 318 | struct Qdisc *child = NULL; |
295 | int max_size, n; | 319 | struct psched_ratecfg rate; |
320 | struct psched_ratecfg peak; | ||
321 | u64 max_size; | ||
322 | s64 buffer, mtu; | ||
296 | u64 rate64 = 0, prate64 = 0; | 323 | u64 rate64 = 0, prate64 = 0; |
297 | 324 | ||
298 | err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy); | 325 | err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy); |
@@ -304,38 +331,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
304 | goto done; | 331 | goto done; |
305 | 332 | ||
306 | qopt = nla_data(tb[TCA_TBF_PARMS]); | 333 | qopt = nla_data(tb[TCA_TBF_PARMS]); |
307 | rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]); | 334 | if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE) |
308 | if (rtab == NULL) | 335 | qdisc_put_rtab(qdisc_get_rtab(&qopt->rate, |
309 | goto done; | 336 | tb[TCA_TBF_RTAB])); |
310 | |||
311 | if (qopt->peakrate.rate) { | ||
312 | if (qopt->peakrate.rate > qopt->rate.rate) | ||
313 | ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]); | ||
314 | if (ptab == NULL) | ||
315 | goto done; | ||
316 | } | ||
317 | |||
318 | for (n = 0; n < 256; n++) | ||
319 | if (rtab->data[n] > qopt->buffer) | ||
320 | break; | ||
321 | max_size = (n << qopt->rate.cell_log) - 1; | ||
322 | if (ptab) { | ||
323 | int size; | ||
324 | |||
325 | for (n = 0; n < 256; n++) | ||
326 | if (ptab->data[n] > qopt->mtu) | ||
327 | break; | ||
328 | size = (n << qopt->peakrate.cell_log) - 1; | ||
329 | if (size < max_size) | ||
330 | max_size = size; | ||
331 | } | ||
332 | if (max_size < 0) | ||
333 | goto done; | ||
334 | 337 | ||
335 | if (max_size < psched_mtu(qdisc_dev(sch))) | 338 | if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE) |
336 | pr_warn_ratelimited("sch_tbf: burst %u is lower than device %s mtu (%u) !\n", | 339 | qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate, |
337 | max_size, qdisc_dev(sch)->name, | 340 | tb[TCA_TBF_PTAB])); |
338 | psched_mtu(qdisc_dev(sch))); | ||
339 | 341 | ||
340 | if (q->qdisc != &noop_qdisc) { | 342 | if (q->qdisc != &noop_qdisc) { |
341 | err = fifo_set_limit(q->qdisc, qopt->limit); | 343 | err = fifo_set_limit(q->qdisc, qopt->limit); |
@@ -349,6 +351,39 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
349 | } | 351 | } |
350 | } | 352 | } |
351 | 353 | ||
354 | buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U); | ||
355 | mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U); | ||
356 | |||
357 | if (tb[TCA_TBF_RATE64]) | ||
358 | rate64 = nla_get_u64(tb[TCA_TBF_RATE64]); | ||
359 | psched_ratecfg_precompute(&rate, &qopt->rate, rate64); | ||
360 | |||
361 | max_size = min_t(u64, psched_ns_t2l(&rate, buffer), ~0U); | ||
362 | |||
363 | if (qopt->peakrate.rate) { | ||
364 | if (tb[TCA_TBF_PRATE64]) | ||
365 | prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]); | ||
366 | psched_ratecfg_precompute(&peak, &qopt->peakrate, prate64); | ||
367 | if (peak.rate_bytes_ps <= rate.rate_bytes_ps) { | ||
368 | pr_warn_ratelimited("sch_tbf: peakrate %llu is lower than or equals to rate %llu !\n", | ||
369 | peak.rate_bytes_ps, rate.rate_bytes_ps); | ||
370 | err = -EINVAL; | ||
371 | goto done; | ||
372 | } | ||
373 | |||
374 | max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu)); | ||
375 | } | ||
376 | |||
377 | if (max_size < psched_mtu(qdisc_dev(sch))) | ||
378 | pr_warn_ratelimited("sch_tbf: burst %llu is lower than device %s mtu (%u) !\n", | ||
379 | max_size, qdisc_dev(sch)->name, | ||
380 | psched_mtu(qdisc_dev(sch))); | ||
381 | |||
382 | if (!max_size) { | ||
383 | err = -EINVAL; | ||
384 | goto done; | ||
385 | } | ||
386 | |||
352 | sch_tree_lock(sch); | 387 | sch_tree_lock(sch); |
353 | if (child) { | 388 | if (child) { |
354 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); | 389 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); |
@@ -362,13 +397,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
362 | q->tokens = q->buffer; | 397 | q->tokens = q->buffer; |
363 | q->ptokens = q->mtu; | 398 | q->ptokens = q->mtu; |
364 | 399 | ||
365 | if (tb[TCA_TBF_RATE64]) | 400 | memcpy(&q->rate, &rate, sizeof(struct psched_ratecfg)); |
366 | rate64 = nla_get_u64(tb[TCA_TBF_RATE64]); | 401 | if (qopt->peakrate.rate) { |
367 | psched_ratecfg_precompute(&q->rate, &rtab->rate, rate64); | 402 | memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg)); |
368 | if (ptab) { | ||
369 | if (tb[TCA_TBF_PRATE64]) | ||
370 | prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]); | ||
371 | psched_ratecfg_precompute(&q->peak, &ptab->rate, prate64); | ||
372 | q->peak_present = true; | 403 | q->peak_present = true; |
373 | } else { | 404 | } else { |
374 | q->peak_present = false; | 405 | q->peak_present = false; |
@@ -377,10 +408,6 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
377 | sch_tree_unlock(sch); | 408 | sch_tree_unlock(sch); |
378 | err = 0; | 409 | err = 0; |
379 | done: | 410 | done: |
380 | if (rtab) | ||
381 | qdisc_put_rtab(rtab); | ||
382 | if (ptab) | ||
383 | qdisc_put_rtab(ptab); | ||
384 | return err; | 411 | return err; |
385 | } | 412 | } |
386 | 413 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 68a27f9796d2..31ed008c8e13 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -154,8 +154,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
154 | 154 | ||
155 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; | 155 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; |
156 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; | 156 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; |
157 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | 157 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; |
158 | min_t(unsigned long, sp->autoclose, net->sctp.max_autoclose) * HZ; | ||
159 | 158 | ||
160 | /* Initializes the timers */ | 159 | /* Initializes the timers */ |
161 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) | 160 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) |
@@ -291,8 +290,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
291 | asoc->peer.ipv6_address = 1; | 290 | asoc->peer.ipv6_address = 1; |
292 | INIT_LIST_HEAD(&asoc->asocs); | 291 | INIT_LIST_HEAD(&asoc->asocs); |
293 | 292 | ||
294 | asoc->autoclose = sp->autoclose; | ||
295 | |||
296 | asoc->default_stream = sp->default_stream; | 293 | asoc->default_stream = sp->default_stream; |
297 | asoc->default_ppid = sp->default_ppid; | 294 | asoc->default_ppid = sp->default_ppid; |
298 | asoc->default_flags = sp->default_flags; | 295 | asoc->default_flags = sp->default_flags; |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 0e2644d0a773..0fb140f8f088 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -581,7 +581,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
581 | unsigned long timeout; | 581 | unsigned long timeout; |
582 | 582 | ||
583 | /* Restart the AUTOCLOSE timer when sending data. */ | 583 | /* Restart the AUTOCLOSE timer when sending data. */ |
584 | if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) { | 584 | if (sctp_state(asoc, ESTABLISHED) && |
585 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { | ||
585 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 586 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; |
586 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 587 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; |
587 | 588 | ||
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index f51ba985a36e..59268f6e2c36 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -208,8 +208,6 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) | |||
208 | INIT_LIST_HEAD(&q->retransmit); | 208 | INIT_LIST_HEAD(&q->retransmit); |
209 | INIT_LIST_HEAD(&q->sacked); | 209 | INIT_LIST_HEAD(&q->sacked); |
210 | INIT_LIST_HEAD(&q->abandoned); | 210 | INIT_LIST_HEAD(&q->abandoned); |
211 | |||
212 | q->empty = 1; | ||
213 | } | 211 | } |
214 | 212 | ||
215 | /* Free the outqueue structure and any related pending chunks. | 213 | /* Free the outqueue structure and any related pending chunks. |
@@ -332,7 +330,6 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk) | |||
332 | SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS); | 330 | SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS); |
333 | else | 331 | else |
334 | SCTP_INC_STATS(net, SCTP_MIB_OUTORDERCHUNKS); | 332 | SCTP_INC_STATS(net, SCTP_MIB_OUTORDERCHUNKS); |
335 | q->empty = 0; | ||
336 | break; | 333 | break; |
337 | } | 334 | } |
338 | } else { | 335 | } else { |
@@ -654,7 +651,6 @@ redo: | |||
654 | if (chunk->fast_retransmit == SCTP_NEED_FRTX) | 651 | if (chunk->fast_retransmit == SCTP_NEED_FRTX) |
655 | chunk->fast_retransmit = SCTP_DONT_FRTX; | 652 | chunk->fast_retransmit = SCTP_DONT_FRTX; |
656 | 653 | ||
657 | q->empty = 0; | ||
658 | q->asoc->stats.rtxchunks++; | 654 | q->asoc->stats.rtxchunks++; |
659 | break; | 655 | break; |
660 | } | 656 | } |
@@ -1065,8 +1061,6 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
1065 | 1061 | ||
1066 | sctp_transport_reset_timers(transport); | 1062 | sctp_transport_reset_timers(transport); |
1067 | 1063 | ||
1068 | q->empty = 0; | ||
1069 | |||
1070 | /* Only let one DATA chunk get bundled with a | 1064 | /* Only let one DATA chunk get bundled with a |
1071 | * COOKIE-ECHO chunk. | 1065 | * COOKIE-ECHO chunk. |
1072 | */ | 1066 | */ |
@@ -1275,29 +1269,17 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk) | |||
1275 | "advertised peer ack point:0x%x\n", __func__, asoc, ctsn, | 1269 | "advertised peer ack point:0x%x\n", __func__, asoc, ctsn, |
1276 | asoc->adv_peer_ack_point); | 1270 | asoc->adv_peer_ack_point); |
1277 | 1271 | ||
1278 | /* See if all chunks are acked. | 1272 | return sctp_outq_is_empty(q); |
1279 | * Make sure the empty queue handler will get run later. | ||
1280 | */ | ||
1281 | q->empty = (list_empty(&q->out_chunk_list) && | ||
1282 | list_empty(&q->retransmit)); | ||
1283 | if (!q->empty) | ||
1284 | goto finish; | ||
1285 | |||
1286 | list_for_each_entry(transport, transport_list, transports) { | ||
1287 | q->empty = q->empty && list_empty(&transport->transmitted); | ||
1288 | if (!q->empty) | ||
1289 | goto finish; | ||
1290 | } | ||
1291 | |||
1292 | pr_debug("%s: sack queue is empty\n", __func__); | ||
1293 | finish: | ||
1294 | return q->empty; | ||
1295 | } | 1273 | } |
1296 | 1274 | ||
1297 | /* Is the outqueue empty? */ | 1275 | /* Is the outqueue empty? |
1276 | * The queue is empty when we have not pending data, no in-flight data | ||
1277 | * and nothing pending retransmissions. | ||
1278 | */ | ||
1298 | int sctp_outq_is_empty(const struct sctp_outq *q) | 1279 | int sctp_outq_is_empty(const struct sctp_outq *q) |
1299 | { | 1280 | { |
1300 | return q->empty; | 1281 | return q->out_qlen == 0 && q->outstanding_bytes == 0 && |
1282 | list_empty(&q->retransmit); | ||
1301 | } | 1283 | } |
1302 | 1284 | ||
1303 | /******************************************************************** | 1285 | /******************************************************************** |
diff --git a/net/sctp/probe.c b/net/sctp/probe.c index 53c452efb40b..5e68b94ee640 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <net/sctp/sctp.h> | 38 | #include <net/sctp/sctp.h> |
39 | #include <net/sctp/sm.h> | 39 | #include <net/sctp/sm.h> |
40 | 40 | ||
41 | MODULE_SOFTDEP("pre: sctp"); | ||
41 | MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>"); | 42 | MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>"); |
42 | MODULE_DESCRIPTION("SCTP snooper"); | 43 | MODULE_DESCRIPTION("SCTP snooper"); |
43 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
@@ -182,6 +183,20 @@ static struct jprobe sctp_recv_probe = { | |||
182 | .entry = jsctp_sf_eat_sack, | 183 | .entry = jsctp_sf_eat_sack, |
183 | }; | 184 | }; |
184 | 185 | ||
186 | static __init int sctp_setup_jprobe(void) | ||
187 | { | ||
188 | int ret = register_jprobe(&sctp_recv_probe); | ||
189 | |||
190 | if (ret) { | ||
191 | if (request_module("sctp")) | ||
192 | goto out; | ||
193 | ret = register_jprobe(&sctp_recv_probe); | ||
194 | } | ||
195 | |||
196 | out: | ||
197 | return ret; | ||
198 | } | ||
199 | |||
185 | static __init int sctpprobe_init(void) | 200 | static __init int sctpprobe_init(void) |
186 | { | 201 | { |
187 | int ret = -ENOMEM; | 202 | int ret = -ENOMEM; |
@@ -202,7 +217,7 @@ static __init int sctpprobe_init(void) | |||
202 | &sctpprobe_fops)) | 217 | &sctpprobe_fops)) |
203 | goto free_kfifo; | 218 | goto free_kfifo; |
204 | 219 | ||
205 | ret = register_jprobe(&sctp_recv_probe); | 220 | ret = sctp_setup_jprobe(); |
206 | if (ret) | 221 | if (ret) |
207 | goto remove_proc; | 222 | goto remove_proc; |
208 | 223 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index dfe3f36ff2aa..a26065be7289 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -820,7 +820,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | |||
820 | SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); | 820 | SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); |
821 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | 821 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); |
822 | 822 | ||
823 | if (new_asoc->autoclose) | 823 | if (new_asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
824 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 824 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
825 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 825 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
826 | 826 | ||
@@ -908,7 +908,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net, | |||
908 | SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); | 908 | SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); |
909 | SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); | 909 | SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); |
910 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | 910 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); |
911 | if (asoc->autoclose) | 911 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
912 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 912 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
913 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 913 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
914 | 914 | ||
@@ -2970,7 +2970,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net, | |||
2970 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) | 2970 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) |
2971 | force = SCTP_FORCE(); | 2971 | force = SCTP_FORCE(); |
2972 | 2972 | ||
2973 | if (asoc->autoclose) { | 2973 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
2974 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 2974 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
2975 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 2975 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
2976 | } | 2976 | } |
@@ -3878,7 +3878,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net, | |||
3878 | SCTP_CHUNK(chunk)); | 3878 | SCTP_CHUNK(chunk)); |
3879 | 3879 | ||
3880 | /* Count this as receiving DATA. */ | 3880 | /* Count this as receiving DATA. */ |
3881 | if (asoc->autoclose) { | 3881 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
3882 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 3882 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
3883 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 3883 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
3884 | } | 3884 | } |
@@ -5267,7 +5267,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( | |||
5267 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 5267 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
5268 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 5268 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
5269 | 5269 | ||
5270 | if (asoc->autoclose) | 5270 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
5271 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 5271 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
5272 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 5272 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
5273 | 5273 | ||
@@ -5346,7 +5346,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack( | |||
5346 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 5346 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
5347 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); | 5347 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); |
5348 | 5348 | ||
5349 | if (asoc->autoclose) | 5349 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
5350 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 5350 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
5351 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 5351 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
5352 | 5352 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 72046b9729a8..42b709c95cf3 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2196,6 +2196,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
2196 | unsigned int optlen) | 2196 | unsigned int optlen) |
2197 | { | 2197 | { |
2198 | struct sctp_sock *sp = sctp_sk(sk); | 2198 | struct sctp_sock *sp = sctp_sk(sk); |
2199 | struct net *net = sock_net(sk); | ||
2199 | 2200 | ||
2200 | /* Applicable to UDP-style socket only */ | 2201 | /* Applicable to UDP-style socket only */ |
2201 | if (sctp_style(sk, TCP)) | 2202 | if (sctp_style(sk, TCP)) |
@@ -2205,6 +2206,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
2205 | if (copy_from_user(&sp->autoclose, optval, optlen)) | 2206 | if (copy_from_user(&sp->autoclose, optval, optlen)) |
2206 | return -EFAULT; | 2207 | return -EFAULT; |
2207 | 2208 | ||
2209 | if (sp->autoclose > net->sctp.max_autoclose) | ||
2210 | sp->autoclose = net->sctp.max_autoclose; | ||
2211 | |||
2208 | return 0; | 2212 | return 0; |
2209 | } | 2213 | } |
2210 | 2214 | ||
@@ -2811,6 +2815,8 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne | |||
2811 | { | 2815 | { |
2812 | struct sctp_rtoinfo rtoinfo; | 2816 | struct sctp_rtoinfo rtoinfo; |
2813 | struct sctp_association *asoc; | 2817 | struct sctp_association *asoc; |
2818 | unsigned long rto_min, rto_max; | ||
2819 | struct sctp_sock *sp = sctp_sk(sk); | ||
2814 | 2820 | ||
2815 | if (optlen != sizeof (struct sctp_rtoinfo)) | 2821 | if (optlen != sizeof (struct sctp_rtoinfo)) |
2816 | return -EINVAL; | 2822 | return -EINVAL; |
@@ -2824,26 +2830,36 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne | |||
2824 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) | 2830 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) |
2825 | return -EINVAL; | 2831 | return -EINVAL; |
2826 | 2832 | ||
2833 | rto_max = rtoinfo.srto_max; | ||
2834 | rto_min = rtoinfo.srto_min; | ||
2835 | |||
2836 | if (rto_max) | ||
2837 | rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max; | ||
2838 | else | ||
2839 | rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max; | ||
2840 | |||
2841 | if (rto_min) | ||
2842 | rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min; | ||
2843 | else | ||
2844 | rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min; | ||
2845 | |||
2846 | if (rto_min > rto_max) | ||
2847 | return -EINVAL; | ||
2848 | |||
2827 | if (asoc) { | 2849 | if (asoc) { |
2828 | if (rtoinfo.srto_initial != 0) | 2850 | if (rtoinfo.srto_initial != 0) |
2829 | asoc->rto_initial = | 2851 | asoc->rto_initial = |
2830 | msecs_to_jiffies(rtoinfo.srto_initial); | 2852 | msecs_to_jiffies(rtoinfo.srto_initial); |
2831 | if (rtoinfo.srto_max != 0) | 2853 | asoc->rto_max = rto_max; |
2832 | asoc->rto_max = msecs_to_jiffies(rtoinfo.srto_max); | 2854 | asoc->rto_min = rto_min; |
2833 | if (rtoinfo.srto_min != 0) | ||
2834 | asoc->rto_min = msecs_to_jiffies(rtoinfo.srto_min); | ||
2835 | } else { | 2855 | } else { |
2836 | /* If there is no association or the association-id = 0 | 2856 | /* If there is no association or the association-id = 0 |
2837 | * set the values to the endpoint. | 2857 | * set the values to the endpoint. |
2838 | */ | 2858 | */ |
2839 | struct sctp_sock *sp = sctp_sk(sk); | ||
2840 | |||
2841 | if (rtoinfo.srto_initial != 0) | 2859 | if (rtoinfo.srto_initial != 0) |
2842 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; | 2860 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; |
2843 | if (rtoinfo.srto_max != 0) | 2861 | sp->rtoinfo.srto_max = rto_max; |
2844 | sp->rtoinfo.srto_max = rtoinfo.srto_max; | 2862 | sp->rtoinfo.srto_min = rto_min; |
2845 | if (rtoinfo.srto_min != 0) | ||
2846 | sp->rtoinfo.srto_min = rtoinfo.srto_min; | ||
2847 | } | 2863 | } |
2848 | 2864 | ||
2849 | return 0; | 2865 | return 0; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 6b36561a1b3b..b0565afb61c7 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -56,11 +56,16 @@ extern long sysctl_sctp_mem[3]; | |||
56 | extern int sysctl_sctp_rmem[3]; | 56 | extern int sysctl_sctp_rmem[3]; |
57 | extern int sysctl_sctp_wmem[3]; | 57 | extern int sysctl_sctp_wmem[3]; |
58 | 58 | ||
59 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 59 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
60 | int write, | 60 | void __user *buffer, size_t *lenp, |
61 | loff_t *ppos); | ||
62 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
63 | void __user *buffer, size_t *lenp, | ||
64 | loff_t *ppos); | ||
65 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
61 | void __user *buffer, size_t *lenp, | 66 | void __user *buffer, size_t *lenp, |
62 | |||
63 | loff_t *ppos); | 67 | loff_t *ppos); |
68 | |||
64 | static struct ctl_table sctp_table[] = { | 69 | static struct ctl_table sctp_table[] = { |
65 | { | 70 | { |
66 | .procname = "sctp_mem", | 71 | .procname = "sctp_mem", |
@@ -102,17 +107,17 @@ static struct ctl_table sctp_net_table[] = { | |||
102 | .data = &init_net.sctp.rto_min, | 107 | .data = &init_net.sctp.rto_min, |
103 | .maxlen = sizeof(unsigned int), | 108 | .maxlen = sizeof(unsigned int), |
104 | .mode = 0644, | 109 | .mode = 0644, |
105 | .proc_handler = proc_dointvec_minmax, | 110 | .proc_handler = proc_sctp_do_rto_min, |
106 | .extra1 = &one, | 111 | .extra1 = &one, |
107 | .extra2 = &timer_max | 112 | .extra2 = &init_net.sctp.rto_max |
108 | }, | 113 | }, |
109 | { | 114 | { |
110 | .procname = "rto_max", | 115 | .procname = "rto_max", |
111 | .data = &init_net.sctp.rto_max, | 116 | .data = &init_net.sctp.rto_max, |
112 | .maxlen = sizeof(unsigned int), | 117 | .maxlen = sizeof(unsigned int), |
113 | .mode = 0644, | 118 | .mode = 0644, |
114 | .proc_handler = proc_dointvec_minmax, | 119 | .proc_handler = proc_sctp_do_rto_max, |
115 | .extra1 = &one, | 120 | .extra1 = &init_net.sctp.rto_min, |
116 | .extra2 = &timer_max | 121 | .extra2 = &timer_max |
117 | }, | 122 | }, |
118 | { | 123 | { |
@@ -294,8 +299,7 @@ static struct ctl_table sctp_net_table[] = { | |||
294 | { /* sentinel */ } | 299 | { /* sentinel */ } |
295 | }; | 300 | }; |
296 | 301 | ||
297 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 302 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
298 | int write, | ||
299 | void __user *buffer, size_t *lenp, | 303 | void __user *buffer, size_t *lenp, |
300 | loff_t *ppos) | 304 | loff_t *ppos) |
301 | { | 305 | { |
@@ -342,6 +346,60 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | |||
342 | return ret; | 346 | return ret; |
343 | } | 347 | } |
344 | 348 | ||
349 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
350 | void __user *buffer, size_t *lenp, | ||
351 | loff_t *ppos) | ||
352 | { | ||
353 | struct net *net = current->nsproxy->net_ns; | ||
354 | int new_value; | ||
355 | struct ctl_table tbl; | ||
356 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
357 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
358 | int ret; | ||
359 | |||
360 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
361 | tbl.maxlen = sizeof(unsigned int); | ||
362 | |||
363 | if (write) | ||
364 | tbl.data = &new_value; | ||
365 | else | ||
366 | tbl.data = &net->sctp.rto_min; | ||
367 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
368 | if (write) { | ||
369 | if (ret || new_value > max || new_value < min) | ||
370 | return -EINVAL; | ||
371 | net->sctp.rto_min = new_value; | ||
372 | } | ||
373 | return ret; | ||
374 | } | ||
375 | |||
376 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
377 | void __user *buffer, size_t *lenp, | ||
378 | loff_t *ppos) | ||
379 | { | ||
380 | struct net *net = current->nsproxy->net_ns; | ||
381 | int new_value; | ||
382 | struct ctl_table tbl; | ||
383 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
384 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
385 | int ret; | ||
386 | |||
387 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
388 | tbl.maxlen = sizeof(unsigned int); | ||
389 | |||
390 | if (write) | ||
391 | tbl.data = &new_value; | ||
392 | else | ||
393 | tbl.data = &net->sctp.rto_max; | ||
394 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
395 | if (write) { | ||
396 | if (ret || new_value > max || new_value < min) | ||
397 | return -EINVAL; | ||
398 | net->sctp.rto_max = new_value; | ||
399 | } | ||
400 | return ret; | ||
401 | } | ||
402 | |||
345 | int sctp_sysctl_net_register(struct net *net) | 403 | int sctp_sysctl_net_register(struct net *net) |
346 | { | 404 | { |
347 | struct ctl_table *table; | 405 | struct ctl_table *table; |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index e332efb124cc..efc46ffed1fd 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -573,7 +573,7 @@ void sctp_transport_burst_limited(struct sctp_transport *t) | |||
573 | u32 old_cwnd = t->cwnd; | 573 | u32 old_cwnd = t->cwnd; |
574 | u32 max_burst_bytes; | 574 | u32 max_burst_bytes; |
575 | 575 | ||
576 | if (t->burst_limited) | 576 | if (t->burst_limited || asoc->max_burst == 0) |
577 | return; | 577 | return; |
578 | 578 | ||
579 | max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); | 579 | max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 97912b40c254..42fdfc634e56 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1517,7 +1517,7 @@ out: | |||
1517 | static int | 1517 | static int |
1518 | gss_refresh_null(struct rpc_task *task) | 1518 | gss_refresh_null(struct rpc_task *task) |
1519 | { | 1519 | { |
1520 | return -EACCES; | 1520 | return 0; |
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | static __be32 * | 1523 | static __be32 * |
diff --git a/net/tipc/core.c b/net/tipc/core.c index fd4eeeaa972a..c6d3f75a9e1b 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
@@ -113,7 +113,6 @@ err: | |||
113 | static void tipc_core_stop(void) | 113 | static void tipc_core_stop(void) |
114 | { | 114 | { |
115 | tipc_netlink_stop(); | 115 | tipc_netlink_stop(); |
116 | tipc_handler_stop(); | ||
117 | tipc_cfg_stop(); | 116 | tipc_cfg_stop(); |
118 | tipc_subscr_stop(); | 117 | tipc_subscr_stop(); |
119 | tipc_nametbl_stop(); | 118 | tipc_nametbl_stop(); |
@@ -146,9 +145,10 @@ static int tipc_core_start(void) | |||
146 | res = tipc_subscr_start(); | 145 | res = tipc_subscr_start(); |
147 | if (!res) | 146 | if (!res) |
148 | res = tipc_cfg_init(); | 147 | res = tipc_cfg_init(); |
149 | if (res) | 148 | if (res) { |
149 | tipc_handler_stop(); | ||
150 | tipc_core_stop(); | 150 | tipc_core_stop(); |
151 | 151 | } | |
152 | return res; | 152 | return res; |
153 | } | 153 | } |
154 | 154 | ||
@@ -178,6 +178,7 @@ static int __init tipc_init(void) | |||
178 | 178 | ||
179 | static void __exit tipc_exit(void) | 179 | static void __exit tipc_exit(void) |
180 | { | 180 | { |
181 | tipc_handler_stop(); | ||
181 | tipc_core_stop_net(); | 182 | tipc_core_stop_net(); |
182 | tipc_core_stop(); | 183 | tipc_core_stop(); |
183 | pr_info("Deactivated\n"); | 184 | pr_info("Deactivated\n"); |
diff --git a/net/tipc/handler.c b/net/tipc/handler.c index b36f0fcd9bdf..e4bc8a296744 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c | |||
@@ -56,12 +56,13 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument) | |||
56 | { | 56 | { |
57 | struct queue_item *item; | 57 | struct queue_item *item; |
58 | 58 | ||
59 | spin_lock_bh(&qitem_lock); | ||
59 | if (!handler_enabled) { | 60 | if (!handler_enabled) { |
60 | pr_err("Signal request ignored by handler\n"); | 61 | pr_err("Signal request ignored by handler\n"); |
62 | spin_unlock_bh(&qitem_lock); | ||
61 | return -ENOPROTOOPT; | 63 | return -ENOPROTOOPT; |
62 | } | 64 | } |
63 | 65 | ||
64 | spin_lock_bh(&qitem_lock); | ||
65 | item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); | 66 | item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); |
66 | if (!item) { | 67 | if (!item) { |
67 | pr_err("Signal queue out of memory\n"); | 68 | pr_err("Signal queue out of memory\n"); |
@@ -112,10 +113,14 @@ void tipc_handler_stop(void) | |||
112 | struct list_head *l, *n; | 113 | struct list_head *l, *n; |
113 | struct queue_item *item; | 114 | struct queue_item *item; |
114 | 115 | ||
115 | if (!handler_enabled) | 116 | spin_lock_bh(&qitem_lock); |
117 | if (!handler_enabled) { | ||
118 | spin_unlock_bh(&qitem_lock); | ||
116 | return; | 119 | return; |
117 | 120 | } | |
118 | handler_enabled = 0; | 121 | handler_enabled = 0; |
122 | spin_unlock_bh(&qitem_lock); | ||
123 | |||
119 | tasklet_kill(&tipc_tasklet); | 124 | tasklet_kill(&tipc_tasklet); |
120 | 125 | ||
121 | spin_lock_bh(&qitem_lock); | 126 | spin_lock_bh(&qitem_lock); |
diff --git a/net/tipc/link.c b/net/tipc/link.c index 69cd9bf3f561..13b987745820 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -1498,6 +1498,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr) | |||
1498 | int type; | 1498 | int type; |
1499 | 1499 | ||
1500 | head = head->next; | 1500 | head = head->next; |
1501 | buf->next = NULL; | ||
1501 | 1502 | ||
1502 | /* Ensure bearer is still enabled */ | 1503 | /* Ensure bearer is still enabled */ |
1503 | if (unlikely(!b_ptr->active)) | 1504 | if (unlikely(!b_ptr->active)) |
diff --git a/net/tipc/port.c b/net/tipc/port.c index c081a7632302..d43f3182b1d4 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -251,18 +251,15 @@ struct tipc_port *tipc_createport(struct sock *sk, | |||
251 | return p_ptr; | 251 | return p_ptr; |
252 | } | 252 | } |
253 | 253 | ||
254 | int tipc_deleteport(u32 ref) | 254 | int tipc_deleteport(struct tipc_port *p_ptr) |
255 | { | 255 | { |
256 | struct tipc_port *p_ptr; | ||
257 | struct sk_buff *buf = NULL; | 256 | struct sk_buff *buf = NULL; |
258 | 257 | ||
259 | tipc_withdraw(ref, 0, NULL); | 258 | tipc_withdraw(p_ptr, 0, NULL); |
260 | p_ptr = tipc_port_lock(ref); | ||
261 | if (!p_ptr) | ||
262 | return -EINVAL; | ||
263 | 259 | ||
264 | tipc_ref_discard(ref); | 260 | spin_lock_bh(p_ptr->lock); |
265 | tipc_port_unlock(p_ptr); | 261 | tipc_ref_discard(p_ptr->ref); |
262 | spin_unlock_bh(p_ptr->lock); | ||
266 | 263 | ||
267 | k_cancel_timer(&p_ptr->timer); | 264 | k_cancel_timer(&p_ptr->timer); |
268 | if (p_ptr->connected) { | 265 | if (p_ptr->connected) { |
@@ -704,47 +701,36 @@ int tipc_set_portimportance(u32 ref, unsigned int imp) | |||
704 | } | 701 | } |
705 | 702 | ||
706 | 703 | ||
707 | int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | 704 | int tipc_publish(struct tipc_port *p_ptr, unsigned int scope, |
705 | struct tipc_name_seq const *seq) | ||
708 | { | 706 | { |
709 | struct tipc_port *p_ptr; | ||
710 | struct publication *publ; | 707 | struct publication *publ; |
711 | u32 key; | 708 | u32 key; |
712 | int res = -EINVAL; | ||
713 | 709 | ||
714 | p_ptr = tipc_port_lock(ref); | 710 | if (p_ptr->connected) |
715 | if (!p_ptr) | ||
716 | return -EINVAL; | 711 | return -EINVAL; |
712 | key = p_ptr->ref + p_ptr->pub_count + 1; | ||
713 | if (key == p_ptr->ref) | ||
714 | return -EADDRINUSE; | ||
717 | 715 | ||
718 | if (p_ptr->connected) | ||
719 | goto exit; | ||
720 | key = ref + p_ptr->pub_count + 1; | ||
721 | if (key == ref) { | ||
722 | res = -EADDRINUSE; | ||
723 | goto exit; | ||
724 | } | ||
725 | publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, | 716 | publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, |
726 | scope, p_ptr->ref, key); | 717 | scope, p_ptr->ref, key); |
727 | if (publ) { | 718 | if (publ) { |
728 | list_add(&publ->pport_list, &p_ptr->publications); | 719 | list_add(&publ->pport_list, &p_ptr->publications); |
729 | p_ptr->pub_count++; | 720 | p_ptr->pub_count++; |
730 | p_ptr->published = 1; | 721 | p_ptr->published = 1; |
731 | res = 0; | 722 | return 0; |
732 | } | 723 | } |
733 | exit: | 724 | return -EINVAL; |
734 | tipc_port_unlock(p_ptr); | ||
735 | return res; | ||
736 | } | 725 | } |
737 | 726 | ||
738 | int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | 727 | int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope, |
728 | struct tipc_name_seq const *seq) | ||
739 | { | 729 | { |
740 | struct tipc_port *p_ptr; | ||
741 | struct publication *publ; | 730 | struct publication *publ; |
742 | struct publication *tpubl; | 731 | struct publication *tpubl; |
743 | int res = -EINVAL; | 732 | int res = -EINVAL; |
744 | 733 | ||
745 | p_ptr = tipc_port_lock(ref); | ||
746 | if (!p_ptr) | ||
747 | return -EINVAL; | ||
748 | if (!seq) { | 734 | if (!seq) { |
749 | list_for_each_entry_safe(publ, tpubl, | 735 | list_for_each_entry_safe(publ, tpubl, |
750 | &p_ptr->publications, pport_list) { | 736 | &p_ptr->publications, pport_list) { |
@@ -771,7 +757,6 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
771 | } | 757 | } |
772 | if (list_empty(&p_ptr->publications)) | 758 | if (list_empty(&p_ptr->publications)) |
773 | p_ptr->published = 0; | 759 | p_ptr->published = 0; |
774 | tipc_port_unlock(p_ptr); | ||
775 | return res; | 760 | return res; |
776 | } | 761 | } |
777 | 762 | ||
diff --git a/net/tipc/port.h b/net/tipc/port.h index 912253597343..34f12bd4074e 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h | |||
@@ -116,7 +116,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err); | |||
116 | 116 | ||
117 | void tipc_acknowledge(u32 port_ref, u32 ack); | 117 | void tipc_acknowledge(u32 port_ref, u32 ack); |
118 | 118 | ||
119 | int tipc_deleteport(u32 portref); | 119 | int tipc_deleteport(struct tipc_port *p_ptr); |
120 | 120 | ||
121 | int tipc_portimportance(u32 portref, unsigned int *importance); | 121 | int tipc_portimportance(u32 portref, unsigned int *importance); |
122 | int tipc_set_portimportance(u32 portref, unsigned int importance); | 122 | int tipc_set_portimportance(u32 portref, unsigned int importance); |
@@ -127,9 +127,9 @@ int tipc_set_portunreliable(u32 portref, unsigned int isunreliable); | |||
127 | int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); | 127 | int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); |
128 | int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); | 128 | int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); |
129 | 129 | ||
130 | int tipc_publish(u32 portref, unsigned int scope, | 130 | int tipc_publish(struct tipc_port *p_ptr, unsigned int scope, |
131 | struct tipc_name_seq const *name_seq); | 131 | struct tipc_name_seq const *name_seq); |
132 | int tipc_withdraw(u32 portref, unsigned int scope, | 132 | int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope, |
133 | struct tipc_name_seq const *name_seq); | 133 | struct tipc_name_seq const *name_seq); |
134 | 134 | ||
135 | int tipc_connect(u32 portref, struct tipc_portid const *port); | 135 | int tipc_connect(u32 portref, struct tipc_portid const *port); |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3b61851bb927..e741416d1d24 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -354,7 +354,7 @@ static int release(struct socket *sock) | |||
354 | * Delete TIPC port; this ensures no more messages are queued | 354 | * Delete TIPC port; this ensures no more messages are queued |
355 | * (also disconnects an active connection & sends a 'FIN-' to peer) | 355 | * (also disconnects an active connection & sends a 'FIN-' to peer) |
356 | */ | 356 | */ |
357 | res = tipc_deleteport(tport->ref); | 357 | res = tipc_deleteport(tport); |
358 | 358 | ||
359 | /* Discard any remaining (connection-based) messages in receive queue */ | 359 | /* Discard any remaining (connection-based) messages in receive queue */ |
360 | __skb_queue_purge(&sk->sk_receive_queue); | 360 | __skb_queue_purge(&sk->sk_receive_queue); |
@@ -386,30 +386,46 @@ static int release(struct socket *sock) | |||
386 | */ | 386 | */ |
387 | static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | 387 | static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) |
388 | { | 388 | { |
389 | struct sock *sk = sock->sk; | ||
389 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 390 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; |
390 | u32 portref = tipc_sk_port(sock->sk)->ref; | 391 | struct tipc_port *tport = tipc_sk_port(sock->sk); |
392 | int res = -EINVAL; | ||
391 | 393 | ||
392 | if (unlikely(!uaddr_len)) | 394 | lock_sock(sk); |
393 | return tipc_withdraw(portref, 0, NULL); | 395 | if (unlikely(!uaddr_len)) { |
396 | res = tipc_withdraw(tport, 0, NULL); | ||
397 | goto exit; | ||
398 | } | ||
394 | 399 | ||
395 | if (uaddr_len < sizeof(struct sockaddr_tipc)) | 400 | if (uaddr_len < sizeof(struct sockaddr_tipc)) { |
396 | return -EINVAL; | 401 | res = -EINVAL; |
397 | if (addr->family != AF_TIPC) | 402 | goto exit; |
398 | return -EAFNOSUPPORT; | 403 | } |
404 | if (addr->family != AF_TIPC) { | ||
405 | res = -EAFNOSUPPORT; | ||
406 | goto exit; | ||
407 | } | ||
399 | 408 | ||
400 | if (addr->addrtype == TIPC_ADDR_NAME) | 409 | if (addr->addrtype == TIPC_ADDR_NAME) |
401 | addr->addr.nameseq.upper = addr->addr.nameseq.lower; | 410 | addr->addr.nameseq.upper = addr->addr.nameseq.lower; |
402 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) | 411 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) { |
403 | return -EAFNOSUPPORT; | 412 | res = -EAFNOSUPPORT; |
413 | goto exit; | ||
414 | } | ||
404 | 415 | ||
405 | if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && | 416 | if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && |
406 | (addr->addr.nameseq.type != TIPC_TOP_SRV) && | 417 | (addr->addr.nameseq.type != TIPC_TOP_SRV) && |
407 | (addr->addr.nameseq.type != TIPC_CFG_SRV)) | 418 | (addr->addr.nameseq.type != TIPC_CFG_SRV)) { |
408 | return -EACCES; | 419 | res = -EACCES; |
420 | goto exit; | ||
421 | } | ||
409 | 422 | ||
410 | return (addr->scope > 0) ? | 423 | res = (addr->scope > 0) ? |
411 | tipc_publish(portref, addr->scope, &addr->addr.nameseq) : | 424 | tipc_publish(tport, addr->scope, &addr->addr.nameseq) : |
412 | tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq); | 425 | tipc_withdraw(tport, -addr->scope, &addr->addr.nameseq); |
426 | exit: | ||
427 | release_sock(sk); | ||
428 | return res; | ||
413 | } | 429 | } |
414 | 430 | ||
415 | /** | 431 | /** |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 01625ccc3ae6..a427623ee574 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -530,13 +530,17 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, | |||
530 | static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, | 530 | static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, |
531 | struct msghdr *, size_t, int); | 531 | struct msghdr *, size_t, int); |
532 | 532 | ||
533 | static void unix_set_peek_off(struct sock *sk, int val) | 533 | static int unix_set_peek_off(struct sock *sk, int val) |
534 | { | 534 | { |
535 | struct unix_sock *u = unix_sk(sk); | 535 | struct unix_sock *u = unix_sk(sk); |
536 | 536 | ||
537 | mutex_lock(&u->readlock); | 537 | if (mutex_lock_interruptible(&u->readlock)) |
538 | return -EINTR; | ||
539 | |||
538 | sk->sk_peek_off = val; | 540 | sk->sk_peek_off = val; |
539 | mutex_unlock(&u->readlock); | 541 | mutex_unlock(&u->readlock); |
542 | |||
543 | return 0; | ||
540 | } | 544 | } |
541 | 545 | ||
542 | 546 | ||
@@ -714,7 +718,9 @@ static int unix_autobind(struct socket *sock) | |||
714 | int err; | 718 | int err; |
715 | unsigned int retries = 0; | 719 | unsigned int retries = 0; |
716 | 720 | ||
717 | mutex_lock(&u->readlock); | 721 | err = mutex_lock_interruptible(&u->readlock); |
722 | if (err) | ||
723 | return err; | ||
718 | 724 | ||
719 | err = 0; | 725 | err = 0; |
720 | if (u->addr) | 726 | if (u->addr) |
@@ -873,7 +879,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
873 | goto out; | 879 | goto out; |
874 | addr_len = err; | 880 | addr_len = err; |
875 | 881 | ||
876 | mutex_lock(&u->readlock); | 882 | err = mutex_lock_interruptible(&u->readlock); |
883 | if (err) | ||
884 | goto out; | ||
877 | 885 | ||
878 | err = -EINVAL; | 886 | err = -EINVAL; |
879 | if (u->addr) | 887 | if (u->addr) |
diff --git a/net/wireless/core.c b/net/wireless/core.c index aff959e5a1b3..52b865fb7351 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -451,6 +451,15 @@ int wiphy_register(struct wiphy *wiphy) | |||
451 | int i; | 451 | int i; |
452 | u16 ifmodes = wiphy->interface_modes; | 452 | u16 ifmodes = wiphy->interface_modes; |
453 | 453 | ||
454 | /* support for 5/10 MHz is broken due to nl80211 API mess - disable */ | ||
455 | wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ; | ||
456 | |||
457 | /* | ||
458 | * There are major locking problems in nl80211/mac80211 for CSA, | ||
459 | * disable for all drivers until this has been reworked. | ||
460 | */ | ||
461 | wiphy->flags &= ~WIPHY_FLAG_HAS_CHANNEL_SWITCH; | ||
462 | |||
454 | #ifdef CONFIG_PM | 463 | #ifdef CONFIG_PM |
455 | if (WARN_ON(wiphy->wowlan && | 464 | if (WARN_ON(wiphy->wowlan && |
456 | (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && | 465 | (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 9d797df56649..89737ee2669a 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -262,7 +262,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
262 | 262 | ||
263 | /* try to find an IBSS channel if none requested ... */ | 263 | /* try to find an IBSS channel if none requested ... */ |
264 | if (!wdev->wext.ibss.chandef.chan) { | 264 | if (!wdev->wext.ibss.chandef.chan) { |
265 | wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | 265 | struct ieee80211_channel *new_chan = NULL; |
266 | 266 | ||
267 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 267 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
268 | struct ieee80211_supported_band *sband; | 268 | struct ieee80211_supported_band *sband; |
@@ -278,18 +278,19 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
278 | continue; | 278 | continue; |
279 | if (chan->flags & IEEE80211_CHAN_DISABLED) | 279 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
280 | continue; | 280 | continue; |
281 | wdev->wext.ibss.chandef.chan = chan; | 281 | new_chan = chan; |
282 | wdev->wext.ibss.chandef.center_freq1 = | ||
283 | chan->center_freq; | ||
284 | break; | 282 | break; |
285 | } | 283 | } |
286 | 284 | ||
287 | if (wdev->wext.ibss.chandef.chan) | 285 | if (new_chan) |
288 | break; | 286 | break; |
289 | } | 287 | } |
290 | 288 | ||
291 | if (!wdev->wext.ibss.chandef.chan) | 289 | if (!new_chan) |
292 | return -EINVAL; | 290 | return -EINVAL; |
291 | |||
292 | cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan, | ||
293 | NL80211_CHAN_NO_HT); | ||
293 | } | 294 | } |
294 | 295 | ||
295 | /* don't join -- SSID is not there */ | 296 | /* don't join -- SSID is not there */ |
@@ -363,9 +364,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
363 | return err; | 364 | return err; |
364 | 365 | ||
365 | if (chan) { | 366 | if (chan) { |
366 | wdev->wext.ibss.chandef.chan = chan; | 367 | cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan, |
367 | wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | 368 | NL80211_CHAN_NO_HT); |
368 | wdev->wext.ibss.chandef.center_freq1 = freq; | ||
369 | wdev->wext.ibss.channel_fixed = true; | 369 | wdev->wext.ibss.channel_fixed = true; |
370 | } else { | 370 | } else { |
371 | /* cfg80211_ibss_wext_join will pick one if needed */ | 371 | /* cfg80211_ibss_wext_join will pick one if needed */ |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a1eb21073176..138dc3bb8b67 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2687,7 +2687,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
2687 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 2687 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
2688 | NL80211_CMD_NEW_KEY); | 2688 | NL80211_CMD_NEW_KEY); |
2689 | if (!hdr) | 2689 | if (!hdr) |
2690 | return -ENOBUFS; | 2690 | goto nla_put_failure; |
2691 | 2691 | ||
2692 | cookie.msg = msg; | 2692 | cookie.msg = msg; |
2693 | cookie.idx = key_idx; | 2693 | cookie.idx = key_idx; |
@@ -5349,6 +5349,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
5349 | err = -EINVAL; | 5349 | err = -EINVAL; |
5350 | goto out_free; | 5350 | goto out_free; |
5351 | } | 5351 | } |
5352 | |||
5353 | if (!wiphy->bands[band]) | ||
5354 | continue; | ||
5355 | |||
5352 | err = ieee80211_get_ratemask(wiphy->bands[band], | 5356 | err = ieee80211_get_ratemask(wiphy->bands[band], |
5353 | nla_data(attr), | 5357 | nla_data(attr), |
5354 | nla_len(attr), | 5358 | nla_len(attr), |
@@ -9633,8 +9637,9 @@ static int nl80211_add_scan_req(struct sk_buff *msg, | |||
9633 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) | 9637 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) |
9634 | goto nla_put_failure; | 9638 | goto nla_put_failure; |
9635 | 9639 | ||
9636 | if (req->flags) | 9640 | if (req->flags && |
9637 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags); | 9641 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags)) |
9642 | goto nla_put_failure; | ||
9638 | 9643 | ||
9639 | return 0; | 9644 | return 0; |
9640 | nla_put_failure: | 9645 | nla_put_failure: |
@@ -11093,6 +11098,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
11093 | struct nlattr *reasons; | 11098 | struct nlattr *reasons; |
11094 | 11099 | ||
11095 | reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); | 11100 | reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); |
11101 | if (!reasons) | ||
11102 | goto free_msg; | ||
11096 | 11103 | ||
11097 | if (wakeup->disconnect && | 11104 | if (wakeup->disconnect && |
11098 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) | 11105 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) |
@@ -11118,16 +11125,18 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
11118 | wakeup->pattern_idx)) | 11125 | wakeup->pattern_idx)) |
11119 | goto free_msg; | 11126 | goto free_msg; |
11120 | 11127 | ||
11121 | if (wakeup->tcp_match) | 11128 | if (wakeup->tcp_match && |
11122 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH); | 11129 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH)) |
11130 | goto free_msg; | ||
11123 | 11131 | ||
11124 | if (wakeup->tcp_connlost) | 11132 | if (wakeup->tcp_connlost && |
11125 | nla_put_flag(msg, | 11133 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST)) |
11126 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST); | 11134 | goto free_msg; |
11127 | 11135 | ||
11128 | if (wakeup->tcp_nomoretokens) | 11136 | if (wakeup->tcp_nomoretokens && |
11129 | nla_put_flag(msg, | 11137 | nla_put_flag(msg, |
11130 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS); | 11138 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS)) |
11139 | goto free_msg; | ||
11131 | 11140 | ||
11132 | if (wakeup->packet) { | 11141 | if (wakeup->packet) { |
11133 | u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211; | 11142 | u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211; |
@@ -11263,24 +11272,29 @@ void cfg80211_ft_event(struct net_device *netdev, | |||
11263 | return; | 11272 | return; |
11264 | 11273 | ||
11265 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT); | 11274 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT); |
11266 | if (!hdr) { | 11275 | if (!hdr) |
11267 | nlmsg_free(msg); | 11276 | goto out; |
11268 | return; | ||
11269 | } | ||
11270 | 11277 | ||
11271 | nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | 11278 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
11272 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 11279 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
11273 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap); | 11280 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap)) |
11274 | if (ft_event->ies) | 11281 | goto out; |
11275 | nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies); | 11282 | |
11276 | if (ft_event->ric_ies) | 11283 | if (ft_event->ies && |
11277 | nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, | 11284 | nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies)) |
11278 | ft_event->ric_ies); | 11285 | goto out; |
11286 | if (ft_event->ric_ies && | ||
11287 | nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, | ||
11288 | ft_event->ric_ies)) | ||
11289 | goto out; | ||
11279 | 11290 | ||
11280 | genlmsg_end(msg, hdr); | 11291 | genlmsg_end(msg, hdr); |
11281 | 11292 | ||
11282 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 11293 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
11283 | NL80211_MCGRP_MLME, GFP_KERNEL); | 11294 | NL80211_MCGRP_MLME, GFP_KERNEL); |
11295 | return; | ||
11296 | out: | ||
11297 | nlmsg_free(msg); | ||
11284 | } | 11298 | } |
11285 | EXPORT_SYMBOL(cfg80211_ft_event); | 11299 | EXPORT_SYMBOL(cfg80211_ft_event); |
11286 | 11300 | ||
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index a271c27fac77..722da616438c 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c | |||
@@ -124,6 +124,10 @@ int ieee80211_radiotap_iterator_init( | |||
124 | /* find payload start allowing for extended bitmap(s) */ | 124 | /* find payload start allowing for extended bitmap(s) */ |
125 | 125 | ||
126 | if (iterator->_bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT)) { | 126 | if (iterator->_bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT)) { |
127 | if ((unsigned long)iterator->_arg - | ||
128 | (unsigned long)iterator->_rtheader + sizeof(uint32_t) > | ||
129 | (unsigned long)iterator->_max_length) | ||
130 | return -EINVAL; | ||
127 | while (get_unaligned_le32(iterator->_arg) & | 131 | while (get_unaligned_le32(iterator->_arg) & |
128 | (1 << IEEE80211_RADIOTAP_EXT)) { | 132 | (1 << IEEE80211_RADIOTAP_EXT)) { |
129 | iterator->_arg += sizeof(uint32_t); | 133 | iterator->_arg += sizeof(uint32_t); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 65f800890d70..d3c5bd7c6b51 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -632,6 +632,16 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
632 | } | 632 | } |
633 | #endif | 633 | #endif |
634 | 634 | ||
635 | if (!bss && (status == WLAN_STATUS_SUCCESS)) { | ||
636 | WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect); | ||
637 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | ||
638 | wdev->ssid, wdev->ssid_len, | ||
639 | WLAN_CAPABILITY_ESS, | ||
640 | WLAN_CAPABILITY_ESS); | ||
641 | if (bss) | ||
642 | cfg80211_hold_bss(bss_from_pub(bss)); | ||
643 | } | ||
644 | |||
635 | if (wdev->current_bss) { | 645 | if (wdev->current_bss) { |
636 | cfg80211_unhold_bss(wdev->current_bss); | 646 | cfg80211_unhold_bss(wdev->current_bss); |
637 | cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); | 647 | cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); |
@@ -649,16 +659,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
649 | return; | 659 | return; |
650 | } | 660 | } |
651 | 661 | ||
652 | if (!bss) { | 662 | if (WARN_ON(!bss)) |
653 | WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect); | 663 | return; |
654 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | ||
655 | wdev->ssid, wdev->ssid_len, | ||
656 | WLAN_CAPABILITY_ESS, | ||
657 | WLAN_CAPABILITY_ESS); | ||
658 | if (WARN_ON(!bss)) | ||
659 | return; | ||
660 | cfg80211_hold_bss(bss_from_pub(bss)); | ||
661 | } | ||
662 | 664 | ||
663 | wdev->current_bss = bss_from_pub(bss); | 665 | wdev->current_bss = bss_from_pub(bss); |
664 | 666 | ||