diff options
| author | David S. Miller <davem@davemloft.net> | 2014-01-06 17:37:45 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-01-06 17:37:45 -0500 |
| commit | 56a4342dfe3145cd66f766adccb28fd9b571606d (patch) | |
| tree | d1593764488ff8cbb0b83cb9ae35fd968bf81760 /net | |
| parent | 805c1f4aedaba1bc8d839e7c27b128083dd5c2f0 (diff) | |
| parent | fe0d692bbc645786bce1a98439e548ae619269f5 (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
ipv6 tunnel statistic bug fixes conflicting with consolidation into
generic sw per-cpu net stats.
qlogic conflict between queue counting bug fix and the addition
of multiple MAC address support.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
54 files changed, 499 insertions, 338 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 06506e6f9006..19bc42f8b8be 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/core/dev.c b/net/core/dev.c index 153ee2f8c33e..e5e23d785454 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -4446,7 +4446,7 @@ struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev, | |||
| 4446 | { | 4446 | { |
| 4447 | struct netdev_adjacent *upper; | 4447 | struct netdev_adjacent *upper; |
| 4448 | 4448 | ||
| 4449 | WARN_ON_ONCE(!rcu_read_lock_held()); | 4449 | WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held()); |
| 4450 | 4450 | ||
| 4451 | upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); | 4451 | upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); |
| 4452 | 4452 | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index a666740051dc..ea97361f0e9b 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -1298,7 +1298,7 @@ int neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb) | |||
| 1298 | 1298 | ||
| 1299 | if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, | 1299 | if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, |
| 1300 | skb->len) < 0 && | 1300 | skb->len) < 0 && |
| 1301 | dev->header_ops->rebuild(skb)) | 1301 | dev_rebuild_header(skb)) |
| 1302 | return 0; | 1302 | return 0; |
| 1303 | 1303 | ||
| 1304 | return dev_queue_xmit(skb); | 1304 | return dev_queue_xmit(skb); |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 8f971990677c..303097874633 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -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/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/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/udp.c b/net/ipv4/udp.c index d5d24ecde6a5..80f649fbee63 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -2478,6 +2478,7 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, | |||
| 2478 | netdev_features_t features) | 2478 | netdev_features_t features) |
| 2479 | { | 2479 | { |
| 2480 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 2480 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
| 2481 | u16 mac_offset = skb->mac_header; | ||
| 2481 | int mac_len = skb->mac_len; | 2482 | int mac_len = skb->mac_len; |
| 2482 | 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); |
| 2483 | __be16 protocol = skb->protocol; | 2484 | __be16 protocol = skb->protocol; |
| @@ -2497,8 +2498,11 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, | |||
| 2497 | /* segment inner packet. */ | 2498 | /* segment inner packet. */ |
| 2498 | enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); | 2499 | enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); |
| 2499 | segs = skb_mac_gso_segment(skb, enc_features); | 2500 | segs = skb_mac_gso_segment(skb, enc_features); |
| 2500 | 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); | ||
| 2501 | goto out; | 2504 | goto out; |
| 2505 | } | ||
| 2502 | 2506 | ||
| 2503 | outer_hlen = skb_tnl_header_len(skb); | 2507 | outer_hlen = skb_tnl_header_len(skb); |
| 2504 | 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 6c1634507ec2..31f75ea9cb60 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -1677,7 +1677,7 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | |||
| 1677 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | 1677 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) |
| 1678 | { | 1678 | { |
| 1679 | struct in6_addr addr; | 1679 | struct in6_addr addr; |
| 1680 | if (ifp->prefix_len == 127) /* RFC 6164 */ | 1680 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
| 1681 | return; | 1681 | return; |
| 1682 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1682 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
| 1683 | if (ipv6_addr_any(&addr)) | 1683 | if (ipv6_addr_any(&addr)) |
| @@ -1688,7 +1688,7 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | |||
| 1688 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) | 1688 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) |
| 1689 | { | 1689 | { |
| 1690 | struct in6_addr addr; | 1690 | struct in6_addr addr; |
| 1691 | if (ifp->prefix_len == 127) /* RFC 6164 */ | 1691 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
| 1692 | return; | 1692 | return; |
| 1693 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1693 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
| 1694 | if (ipv6_addr_any(&addr)) | 1694 | if (ipv6_addr_any(&addr)) |
| @@ -3476,7 +3476,12 @@ restart: | |||
| 3476 | &inet6_addr_lst[i], addr_lst) { | 3476 | &inet6_addr_lst[i], addr_lst) { |
| 3477 | unsigned long age; | 3477 | unsigned long age; |
| 3478 | 3478 | ||
| 3479 | if (ifp->flags & IFA_F_PERMANENT) | 3479 | /* When setting preferred_lft to a value not zero or |
| 3480 | * infinity, while valid_lft is infinity | ||
| 3481 | * IFA_F_PERMANENT has a non-infinity life time. | ||
| 3482 | */ | ||
| 3483 | if ((ifp->flags & IFA_F_PERMANENT) && | ||
| 3484 | (ifp->prefered_lft == INFINITY_LIFE_TIME)) | ||
| 3480 | continue; | 3485 | continue; |
| 3481 | 3486 | ||
| 3482 | spin_lock(&ifp->lock); | 3487 | spin_lock(&ifp->lock); |
| @@ -3501,7 +3506,8 @@ restart: | |||
| 3501 | ifp->flags |= IFA_F_DEPRECATED; | 3506 | ifp->flags |= IFA_F_DEPRECATED; |
| 3502 | } | 3507 | } |
| 3503 | 3508 | ||
| 3504 | if (time_before(ifp->tstamp + ifp->valid_lft * HZ, next)) | 3509 | if ((ifp->valid_lft != INFINITY_LIFE_TIME) && |
| 3510 | (time_before(ifp->tstamp + ifp->valid_lft * HZ, next))) | ||
| 3505 | next = ifp->tstamp + ifp->valid_lft * HZ; | 3511 | next = ifp->tstamp + ifp->valid_lft * HZ; |
| 3506 | 3512 | ||
| 3507 | spin_unlock(&ifp->lock); | 3513 | spin_unlock(&ifp->lock); |
| @@ -3801,7 +3807,8 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | |||
| 3801 | put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), | 3807 | put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), |
| 3802 | ifa->idev->dev->ifindex); | 3808 | ifa->idev->dev->ifindex); |
| 3803 | 3809 | ||
| 3804 | if (!(ifa->flags&IFA_F_PERMANENT)) { | 3810 | if (!((ifa->flags&IFA_F_PERMANENT) && |
| 3811 | (ifa->prefered_lft == INFINITY_LIFE_TIME))) { | ||
| 3805 | preferred = ifa->prefered_lft; | 3812 | preferred = ifa->prefered_lft; |
| 3806 | valid = ifa->valid_lft; | 3813 | valid = ifa->valid_lft; |
| 3807 | if (preferred != INFINITY_LIFE_TIME) { | 3814 | if (preferred != INFINITY_LIFE_TIME) { |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 788c01a53593..d1de9560c421 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -1188,11 +1188,35 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
| 1188 | 1188 | ||
| 1189 | fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + | 1189 | fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + |
| 1190 | (opt ? opt->opt_nflen : 0); | 1190 | (opt ? opt->opt_nflen : 0); |
| 1191 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); | 1191 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - |
| 1192 | sizeof(struct frag_hdr); | ||
| 1192 | 1193 | ||
| 1193 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { | 1194 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { |
| 1194 | if (cork->length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { | 1195 | unsigned int maxnonfragsize, headersize; |
| 1195 | ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen); | 1196 | |
| 1197 | headersize = sizeof(struct ipv6hdr) + | ||
| 1198 | (opt ? opt->tot_len : 0) + | ||
| 1199 | (dst_allfrag(&rt->dst) ? | ||
| 1200 | sizeof(struct frag_hdr) : 0) + | ||
| 1201 | rt->rt6i_nfheader_len; | ||
| 1202 | |||
| 1203 | maxnonfragsize = (np->pmtudisc >= IPV6_PMTUDISC_DO) ? | ||
| 1204 | mtu : sizeof(struct ipv6hdr) + IPV6_MAXPLEN; | ||
| 1205 | |||
| 1206 | /* dontfrag active */ | ||
| 1207 | if ((cork->length + length > mtu - headersize) && dontfrag && | ||
| 1208 | (sk->sk_protocol == IPPROTO_UDP || | ||
| 1209 | sk->sk_protocol == IPPROTO_RAW)) { | ||
| 1210 | ipv6_local_rxpmtu(sk, fl6, mtu - headersize + | ||
| 1211 | sizeof(struct ipv6hdr)); | ||
| 1212 | goto emsgsize; | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | if (cork->length + length > maxnonfragsize - headersize) { | ||
| 1216 | emsgsize: | ||
| 1217 | ipv6_local_error(sk, EMSGSIZE, fl6, | ||
| 1218 | mtu - headersize + | ||
| 1219 | sizeof(struct ipv6hdr)); | ||
| 1196 | return -EMSGSIZE; | 1220 | return -EMSGSIZE; |
| 1197 | } | 1221 | } |
| 1198 | } | 1222 | } |
| @@ -1217,12 +1241,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
| 1217 | * --yoshfuji | 1241 | * --yoshfuji |
| 1218 | */ | 1242 | */ |
| 1219 | 1243 | ||
| 1220 | if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP || | ||
| 1221 | sk->sk_protocol == IPPROTO_RAW)) { | ||
| 1222 | ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); | ||
| 1223 | return -EMSGSIZE; | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | skb = skb_peek_tail(&sk->sk_write_queue); | 1244 | skb = skb_peek_tail(&sk->sk_write_queue); |
| 1227 | cork->length += length; | 1245 | cork->length += length; |
| 1228 | if (((length > mtu) || | 1246 | if (((length > mtu) || |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 02894216a46d..1e5e2404f1af 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
| @@ -101,17 +101,26 @@ struct ip6_tnl_net { | |||
| 101 | 101 | ||
| 102 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) | 102 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) |
| 103 | { | 103 | { |
| 104 | struct pcpu_sw_netstats sum = { 0 }; | 104 | struct pcpu_sw_netstats tmp, sum = { 0 }; |
| 105 | int i; | 105 | int i; |
| 106 | 106 | ||
| 107 | for_each_possible_cpu(i) { | 107 | for_each_possible_cpu(i) { |
| 108 | unsigned int start; | ||
| 108 | const struct pcpu_sw_netstats *tstats = | 109 | const struct pcpu_sw_netstats *tstats = |
| 109 | per_cpu_ptr(dev->tstats, i); | 110 | per_cpu_ptr(dev->tstats, i); |
| 110 | 111 | ||
| 111 | sum.rx_packets += tstats->rx_packets; | 112 | do { |
| 112 | sum.rx_bytes += tstats->rx_bytes; | 113 | start = u64_stats_fetch_begin_bh(&tstats->syncp); |
| 113 | sum.tx_packets += tstats->tx_packets; | 114 | tmp.rx_packets = tstats->rx_packets; |
| 114 | sum.tx_bytes += tstats->tx_bytes; | 115 | tmp.rx_bytes = tstats->rx_bytes; |
| 116 | tmp.tx_packets = tstats->tx_packets; | ||
| 117 | tmp.tx_bytes = tstats->tx_bytes; | ||
| 118 | } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); | ||
| 119 | |||
| 120 | sum.rx_packets += tmp.rx_packets; | ||
| 121 | sum.rx_bytes += tmp.rx_bytes; | ||
| 122 | sum.tx_packets += tmp.tx_packets; | ||
| 123 | sum.tx_bytes += tmp.tx_bytes; | ||
| 115 | } | 124 | } |
| 116 | dev->stats.rx_packets = sum.rx_packets; | 125 | dev->stats.rx_packets = sum.rx_packets; |
| 117 | dev->stats.rx_bytes = sum.rx_bytes; | 126 | dev->stats.rx_bytes = sum.rx_bytes; |
| @@ -823,8 +832,10 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, | |||
| 823 | } | 832 | } |
| 824 | 833 | ||
| 825 | tstats = this_cpu_ptr(t->dev->tstats); | 834 | tstats = this_cpu_ptr(t->dev->tstats); |
| 835 | u64_stats_update_begin(&tstats->syncp); | ||
| 826 | tstats->rx_packets++; | 836 | tstats->rx_packets++; |
| 827 | tstats->rx_bytes += skb->len; | 837 | tstats->rx_bytes += skb->len; |
| 838 | u64_stats_update_end(&tstats->syncp); | ||
| 828 | 839 | ||
| 829 | netif_rx(skb); | 840 | netif_rx(skb); |
| 830 | 841 | ||
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index da1d9e4d62ca..b50acd5e75d2 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
| @@ -74,27 +74,6 @@ struct vti6_net { | |||
| 74 | struct ip6_tnl __rcu **tnls[2]; | 74 | struct ip6_tnl __rcu **tnls[2]; |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | static struct net_device_stats *vti6_get_stats(struct net_device *dev) | ||
| 78 | { | ||
| 79 | struct pcpu_sw_netstats sum = { 0 }; | ||
| 80 | int i; | ||
| 81 | |||
| 82 | for_each_possible_cpu(i) { | ||
| 83 | const struct pcpu_sw_netstats *tstats = | ||
| 84 | 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) \ | 77 | #define for_each_vti6_tunnel_rcu(start) \ |
| 99 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) | 78 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) |
| 100 | 79 | ||
| @@ -331,8 +310,10 @@ static int vti6_rcv(struct sk_buff *skb) | |||
| 331 | } | 310 | } |
| 332 | 311 | ||
| 333 | tstats = this_cpu_ptr(t->dev->tstats); | 312 | tstats = this_cpu_ptr(t->dev->tstats); |
| 313 | u64_stats_update_begin(&tstats->syncp); | ||
| 334 | tstats->rx_packets++; | 314 | tstats->rx_packets++; |
| 335 | tstats->rx_bytes += skb->len; | 315 | tstats->rx_bytes += skb->len; |
| 316 | u64_stats_update_end(&tstats->syncp); | ||
| 336 | 317 | ||
| 337 | skb->mark = 0; | 318 | skb->mark = 0; |
| 338 | secpath_reset(skb); | 319 | secpath_reset(skb); |
| @@ -716,7 +697,7 @@ static const struct net_device_ops vti6_netdev_ops = { | |||
| 716 | .ndo_start_xmit = vti6_tnl_xmit, | 697 | .ndo_start_xmit = vti6_tnl_xmit, |
| 717 | .ndo_do_ioctl = vti6_ioctl, | 698 | .ndo_do_ioctl = vti6_ioctl, |
| 718 | .ndo_change_mtu = vti6_change_mtu, | 699 | .ndo_change_mtu = vti6_change_mtu, |
| 719 | .ndo_get_stats = vti6_get_stats, | 700 | .ndo_get_stats64 = ip_tunnel_get_stats64, |
| 720 | }; | 701 | }; |
| 721 | 702 | ||
| 722 | /** | 703 | /** |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 266f110cb6f7..11dac21e6586 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -1923,9 +1923,7 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, | |||
| 1923 | else | 1923 | else |
| 1924 | rt->rt6i_gateway = *dest; | 1924 | rt->rt6i_gateway = *dest; |
| 1925 | rt->rt6i_flags = ort->rt6i_flags; | 1925 | rt->rt6i_flags = ort->rt6i_flags; |
| 1926 | if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == | 1926 | rt6_set_from(rt, ort); |
| 1927 | (RTF_DEFAULT | RTF_ADDRCONF)) | ||
| 1928 | rt6_set_from(rt, ort); | ||
| 1929 | rt->rt6i_metric = 0; | 1927 | rt->rt6i_metric = 0; |
| 1930 | 1928 | ||
| 1931 | #ifdef CONFIG_IPV6_SUBTREES | 1929 | #ifdef CONFIG_IPV6_SUBTREES |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 9937b2616713..3dfbcf1dcb1c 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/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/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c index d5f41514f577..5882bbfd198c 100644 --- a/net/netfilter/ipvs/ip_vs_nfct.c +++ b/net/netfilter/ipvs/ip_vs_nfct.c | |||
| @@ -62,6 +62,7 @@ | |||
| 62 | #include <net/ip_vs.h> | 62 | #include <net/ip_vs.h> |
| 63 | #include <net/netfilter/nf_conntrack_core.h> | 63 | #include <net/netfilter/nf_conntrack_core.h> |
| 64 | #include <net/netfilter/nf_conntrack_expect.h> | 64 | #include <net/netfilter/nf_conntrack_expect.h> |
| 65 | #include <net/netfilter/nf_conntrack_seqadj.h> | ||
| 65 | #include <net/netfilter/nf_conntrack_helper.h> | 66 | #include <net/netfilter/nf_conntrack_helper.h> |
| 66 | #include <net/netfilter/nf_conntrack_zones.h> | 67 | #include <net/netfilter/nf_conntrack_zones.h> |
| 67 | 68 | ||
| @@ -96,6 +97,11 @@ ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) | |||
| 96 | if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) | 97 | if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) |
| 97 | return; | 98 | return; |
| 98 | 99 | ||
| 100 | /* Applications may adjust TCP seqs */ | ||
| 101 | if (cp->app && nf_ct_protonum(ct) == IPPROTO_TCP && | ||
| 102 | !nfct_seqadj(ct) && !nfct_seqadj_ext_add(ct)) | ||
| 103 | return; | ||
| 104 | |||
| 99 | /* | 105 | /* |
| 100 | * The connection is not yet in the hashtable, so we update it. | 106 | * The connection is not yet in the hashtable, so we update it. |
| 101 | * CIP->VIP will remain the same, so leave the tuple in | 107 | * 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..b2d38da67822 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(1, "Wrong seqadj usage, missing nfct_seqadj_ext_add()\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_tables_api.c b/net/netfilter/nf_tables_api.c index 629b6da98318..1fcef1ec1dc1 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -313,6 +313,9 @@ static int nf_tables_table_enable(struct nft_table *table) | |||
| 313 | int err, i = 0; | 313 | int err, i = 0; |
| 314 | 314 | ||
| 315 | list_for_each_entry(chain, &table->chains, list) { | 315 | list_for_each_entry(chain, &table->chains, list) { |
| 316 | if (!(chain->flags & NFT_BASE_CHAIN)) | ||
| 317 | continue; | ||
| 318 | |||
| 316 | err = nf_register_hook(&nft_base_chain(chain)->ops); | 319 | err = nf_register_hook(&nft_base_chain(chain)->ops); |
| 317 | if (err < 0) | 320 | if (err < 0) |
| 318 | goto err; | 321 | goto err; |
| @@ -322,6 +325,9 @@ static int nf_tables_table_enable(struct nft_table *table) | |||
| 322 | return 0; | 325 | return 0; |
| 323 | err: | 326 | err: |
| 324 | list_for_each_entry(chain, &table->chains, list) { | 327 | list_for_each_entry(chain, &table->chains, list) { |
| 328 | if (!(chain->flags & NFT_BASE_CHAIN)) | ||
| 329 | continue; | ||
| 330 | |||
| 325 | if (i-- <= 0) | 331 | if (i-- <= 0) |
| 326 | break; | 332 | break; |
| 327 | 333 | ||
| @@ -334,8 +340,10 @@ static int nf_tables_table_disable(struct nft_table *table) | |||
| 334 | { | 340 | { |
| 335 | struct nft_chain *chain; | 341 | struct nft_chain *chain; |
| 336 | 342 | ||
| 337 | list_for_each_entry(chain, &table->chains, list) | 343 | list_for_each_entry(chain, &table->chains, list) { |
| 338 | nf_unregister_hook(&nft_base_chain(chain)->ops); | 344 | if (chain->flags & NFT_BASE_CHAIN) |
| 345 | nf_unregister_hook(&nft_base_chain(chain)->ops); | ||
| 346 | } | ||
| 339 | 347 | ||
| 340 | return 0; | 348 | return 0; |
| 341 | } | 349 | } |
| @@ -2104,17 +2112,21 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb, | |||
| 2104 | struct netlink_callback *cb) | 2112 | struct netlink_callback *cb) |
| 2105 | { | 2113 | { |
| 2106 | const struct nft_set *set; | 2114 | const struct nft_set *set; |
| 2107 | unsigned int idx = 0, s_idx = cb->args[0]; | 2115 | unsigned int idx, s_idx = cb->args[0]; |
| 2108 | struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; | 2116 | struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; |
| 2109 | 2117 | ||
| 2110 | if (cb->args[1]) | 2118 | if (cb->args[1]) |
| 2111 | return skb->len; | 2119 | return skb->len; |
| 2112 | 2120 | ||
| 2113 | list_for_each_entry(table, &ctx->afi->tables, list) { | 2121 | list_for_each_entry(table, &ctx->afi->tables, list) { |
| 2114 | if (cur_table && cur_table != table) | 2122 | if (cur_table) { |
| 2115 | continue; | 2123 | if (cur_table != table) |
| 2124 | continue; | ||
| 2116 | 2125 | ||
| 2126 | cur_table = NULL; | ||
| 2127 | } | ||
| 2117 | ctx->table = table; | 2128 | ctx->table = table; |
| 2129 | idx = 0; | ||
| 2118 | list_for_each_entry(set, &ctx->table->sets, list) { | 2130 | list_for_each_entry(set, &ctx->table->sets, list) { |
| 2119 | if (idx < s_idx) | 2131 | if (idx < s_idx) |
| 2120 | goto cont; | 2132 | goto cont; |
| @@ -2443,7 +2455,9 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx, | |||
| 2443 | enum nft_registers dreg; | 2455 | enum nft_registers dreg; |
| 2444 | 2456 | ||
| 2445 | dreg = nft_type_to_reg(set->dtype); | 2457 | dreg = nft_type_to_reg(set->dtype); |
| 2446 | return nft_validate_data_load(ctx, dreg, &elem->data, set->dtype); | 2458 | return nft_validate_data_load(ctx, dreg, &elem->data, |
| 2459 | set->dtype == NFT_DATA_VERDICT ? | ||
| 2460 | NFT_DATA_VERDICT : NFT_DATA_VALUE); | ||
| 2447 | } | 2461 | } |
| 2448 | 2462 | ||
| 2449 | int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, | 2463 | 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 7d4254b0dc6b..d292c8d286eb 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
| @@ -1050,6 +1050,7 @@ static void __net_exit nfnl_log_net_exit(struct net *net) | |||
| 1050 | #ifdef CONFIG_PROC_FS | 1050 | #ifdef CONFIG_PROC_FS |
| 1051 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); | 1051 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); |
| 1052 | #endif | 1052 | #endif |
| 1053 | nf_log_unset(net, &nfulnl_logger); | ||
| 1053 | } | 1054 | } |
| 1054 | 1055 | ||
| 1055 | static struct pernet_operations nfnl_log_net_ops = { | 1056 | 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/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/rose/af_rose.c b/net/rose/af_rose.c index 81f94b1ae1c7..d080eb4b0d29 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_csum.c b/net/sched/act_csum.c index 9cc6717c5f19..8b1d65772a8d 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
| @@ -70,16 +70,16 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, | |||
| 70 | &csum_idx_gen, &csum_hash_info); | 70 | &csum_idx_gen, &csum_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_csum(pc); | ||
| 74 | ret = ACT_P_CREATED; | 73 | ret = ACT_P_CREATED; |
| 75 | } else { | 74 | } else { |
| 76 | p = to_tcf_csum(pc); | 75 | if (bind)/* dont override defaults */ |
| 77 | if (!ovr) { | 76 | return 0; |
| 78 | tcf_hash_release(pc, bind, &csum_hash_info); | 77 | tcf_hash_release(pc, bind, &csum_hash_info); |
| 78 | if (!ovr) | ||
| 79 | return -EEXIST; | 79 | return -EEXIST; |
| 80 | } | ||
| 81 | } | 80 | } |
| 82 | 81 | ||
| 82 | p = to_tcf_csum(pc); | ||
| 83 | spin_lock_bh(&p->tcf_lock); | 83 | spin_lock_bh(&p->tcf_lock); |
| 84 | p->tcf_action = parm->action; | 84 | p->tcf_action = parm->action; |
| 85 | p->update_flags = parm->update_flags; | 85 | p->update_flags = parm->update_flags; |
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index dea927343bf4..af5641c290fa 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
| @@ -95,10 +95,11 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, | |||
| 95 | return PTR_ERR(pc); | 95 | return PTR_ERR(pc); |
| 96 | ret = ACT_P_CREATED; | 96 | ret = ACT_P_CREATED; |
| 97 | } else { | 97 | } else { |
| 98 | if (!ovr) { | 98 | if (bind)/* dont override defaults */ |
| 99 | tcf_hash_release(pc, bind, &gact_hash_info); | 99 | return 0; |
| 100 | tcf_hash_release(pc, bind, &gact_hash_info); | ||
| 101 | if (!ovr) | ||
| 100 | return -EEXIST; | 102 | return -EEXIST; |
| 101 | } | ||
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | gact = to_gact(pc); | 105 | gact = to_gact(pc); |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index e13ecbbfe8c4..242636950ea5 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
| @@ -134,10 +134,12 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
| 134 | return PTR_ERR(pc); | 134 | return PTR_ERR(pc); |
| 135 | ret = ACT_P_CREATED; | 135 | ret = ACT_P_CREATED; |
| 136 | } else { | 136 | } else { |
| 137 | if (!ovr) { | 137 | if (bind)/* dont override defaults */ |
| 138 | tcf_ipt_release(to_ipt(pc), bind); | 138 | return 0; |
| 139 | tcf_ipt_release(to_ipt(pc), bind); | ||
| 140 | |||
| 141 | if (!ovr) | ||
| 139 | return -EEXIST; | 142 | return -EEXIST; |
| 140 | } | ||
| 141 | } | 143 | } |
| 142 | ipt = to_ipt(pc); | 144 | ipt = to_ipt(pc); |
| 143 | 145 | ||
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 921fea43fca2..584e65503edb 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
| @@ -64,15 +64,15 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
| 64 | &nat_idx_gen, &nat_hash_info); | 64 | &nat_idx_gen, &nat_hash_info); |
| 65 | if (IS_ERR(pc)) | 65 | if (IS_ERR(pc)) |
| 66 | return PTR_ERR(pc); | 66 | return PTR_ERR(pc); |
| 67 | p = to_tcf_nat(pc); | ||
| 68 | ret = ACT_P_CREATED; | 67 | ret = ACT_P_CREATED; |
| 69 | } else { | 68 | } else { |
| 70 | p = to_tcf_nat(pc); | 69 | if (bind) |
| 71 | if (!ovr) { | 70 | return 0; |
| 72 | tcf_hash_release(pc, bind, &nat_hash_info); | 71 | tcf_hash_release(pc, bind, &nat_hash_info); |
| 72 | if (!ovr) | ||
| 73 | return -EEXIST; | 73 | return -EEXIST; |
| 74 | } | ||
| 75 | } | 74 | } |
| 75 | p = to_tcf_nat(pc); | ||
| 76 | 76 | ||
| 77 | spin_lock_bh(&p->tcf_lock); | 77 | spin_lock_bh(&p->tcf_lock); |
| 78 | p->old_addr = parm->old_addr; | 78 | p->old_addr = parm->old_addr; |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index e2520e90a10d..729189341933 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
| @@ -78,10 +78,12 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, | |||
| 78 | ret = ACT_P_CREATED; | 78 | ret = ACT_P_CREATED; |
| 79 | } else { | 79 | } else { |
| 80 | p = to_pedit(pc); | 80 | p = to_pedit(pc); |
| 81 | if (!ovr) { | 81 | tcf_hash_release(pc, bind, &pedit_hash_info); |
| 82 | tcf_hash_release(pc, bind, &pedit_hash_info); | 82 | if (bind) |
| 83 | return 0; | ||
| 84 | if (!ovr) | ||
| 83 | return -EEXIST; | 85 | return -EEXIST; |
| 84 | } | 86 | |
| 85 | if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) { | 87 | if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) { |
| 86 | keys = kmalloc(ksize, GFP_KERNEL); | 88 | keys = kmalloc(ksize, GFP_KERNEL); |
| 87 | if (keys == NULL) | 89 | if (keys == NULL) |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 819a9a4d1987..9295b86d5319 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
| @@ -162,10 +162,12 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, | |||
| 162 | if (bind) { | 162 | if (bind) { |
| 163 | police->tcf_bindcnt += 1; | 163 | police->tcf_bindcnt += 1; |
| 164 | police->tcf_refcnt += 1; | 164 | police->tcf_refcnt += 1; |
| 165 | return 0; | ||
| 165 | } | 166 | } |
| 166 | if (ovr) | 167 | if (ovr) |
| 167 | goto override; | 168 | goto override; |
| 168 | return ret; | 169 | /* not replacing */ |
| 170 | return -EEXIST; | ||
| 169 | } | 171 | } |
| 170 | } | 172 | } |
| 171 | 173 | ||
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 81aebc162e5c..b44491e3ec17 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
| @@ -135,10 +135,13 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
| 135 | ret = ACT_P_CREATED; | 135 | ret = ACT_P_CREATED; |
| 136 | } else { | 136 | } else { |
| 137 | d = to_defact(pc); | 137 | d = to_defact(pc); |
| 138 | if (!ovr) { | 138 | |
| 139 | tcf_simp_release(d, bind); | 139 | if (bind) |
| 140 | return 0; | ||
| 141 | tcf_simp_release(d, bind); | ||
| 142 | if (!ovr) | ||
| 140 | return -EEXIST; | 143 | return -EEXIST; |
| 141 | } | 144 | |
| 142 | reset_policy(d, defdata, parm); | 145 | reset_policy(d, defdata, parm); |
| 143 | } | 146 | } |
| 144 | 147 | ||
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index aa0a4c056f31..0fa1aad6e204 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
| @@ -112,10 +112,11 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
| 112 | ret = ACT_P_CREATED; | 112 | ret = ACT_P_CREATED; |
| 113 | } else { | 113 | } else { |
| 114 | d = to_skbedit(pc); | 114 | d = to_skbedit(pc); |
| 115 | if (!ovr) { | 115 | if (bind) |
| 116 | tcf_hash_release(pc, bind, &skbedit_hash_info); | 116 | return 0; |
| 117 | tcf_hash_release(pc, bind, &skbedit_hash_info); | ||
| 118 | if (!ovr) | ||
| 117 | return -EEXIST; | 119 | return -EEXIST; |
| 118 | } | ||
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | spin_lock_bh(&d->tcf_lock); | 122 | spin_lock_bh(&d->tcf_lock); |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 111516c3d34c..9c77947c0597 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
| @@ -207,8 +207,6 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) | |||
| 207 | INIT_LIST_HEAD(&q->retransmit); | 207 | INIT_LIST_HEAD(&q->retransmit); |
| 208 | INIT_LIST_HEAD(&q->sacked); | 208 | INIT_LIST_HEAD(&q->sacked); |
| 209 | INIT_LIST_HEAD(&q->abandoned); | 209 | INIT_LIST_HEAD(&q->abandoned); |
| 210 | |||
| 211 | q->empty = 1; | ||
| 212 | } | 210 | } |
| 213 | 211 | ||
| 214 | /* Free the outqueue structure and any related pending chunks. | 212 | /* Free the outqueue structure and any related pending chunks. |
| @@ -331,7 +329,6 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk) | |||
| 331 | SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS); | 329 | SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS); |
| 332 | else | 330 | else |
| 333 | SCTP_INC_STATS(net, SCTP_MIB_OUTORDERCHUNKS); | 331 | SCTP_INC_STATS(net, SCTP_MIB_OUTORDERCHUNKS); |
| 334 | q->empty = 0; | ||
| 335 | break; | 332 | break; |
| 336 | } | 333 | } |
| 337 | } else { | 334 | } else { |
| @@ -653,7 +650,6 @@ redo: | |||
| 653 | if (chunk->fast_retransmit == SCTP_NEED_FRTX) | 650 | if (chunk->fast_retransmit == SCTP_NEED_FRTX) |
| 654 | chunk->fast_retransmit = SCTP_DONT_FRTX; | 651 | chunk->fast_retransmit = SCTP_DONT_FRTX; |
| 655 | 652 | ||
| 656 | q->empty = 0; | ||
| 657 | q->asoc->stats.rtxchunks++; | 653 | q->asoc->stats.rtxchunks++; |
| 658 | break; | 654 | break; |
| 659 | } | 655 | } |
| @@ -1064,8 +1060,6 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
| 1064 | 1060 | ||
| 1065 | sctp_transport_reset_timers(transport); | 1061 | sctp_transport_reset_timers(transport); |
| 1066 | 1062 | ||
| 1067 | q->empty = 0; | ||
| 1068 | |||
| 1069 | /* Only let one DATA chunk get bundled with a | 1063 | /* Only let one DATA chunk get bundled with a |
| 1070 | * COOKIE-ECHO chunk. | 1064 | * COOKIE-ECHO chunk. |
| 1071 | */ | 1065 | */ |
| @@ -1274,29 +1268,17 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk) | |||
| 1274 | "advertised peer ack point:0x%x\n", __func__, asoc, ctsn, | 1268 | "advertised peer ack point:0x%x\n", __func__, asoc, ctsn, |
| 1275 | asoc->adv_peer_ack_point); | 1269 | asoc->adv_peer_ack_point); |
| 1276 | 1270 | ||
| 1277 | /* See if all chunks are acked. | 1271 | return sctp_outq_is_empty(q); |
| 1278 | * Make sure the empty queue handler will get run later. | ||
| 1279 | */ | ||
| 1280 | q->empty = (list_empty(&q->out_chunk_list) && | ||
| 1281 | list_empty(&q->retransmit)); | ||
| 1282 | if (!q->empty) | ||
| 1283 | goto finish; | ||
| 1284 | |||
| 1285 | list_for_each_entry(transport, transport_list, transports) { | ||
| 1286 | q->empty = q->empty && list_empty(&transport->transmitted); | ||
| 1287 | if (!q->empty) | ||
| 1288 | goto finish; | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | pr_debug("%s: sack queue is empty\n", __func__); | ||
| 1292 | finish: | ||
| 1293 | return q->empty; | ||
| 1294 | } | 1272 | } |
| 1295 | 1273 | ||
| 1296 | /* Is the outqueue empty? */ | 1274 | /* Is the outqueue empty? |
| 1275 | * The queue is empty when we have not pending data, no in-flight data | ||
| 1276 | * and nothing pending retransmissions. | ||
| 1277 | */ | ||
| 1297 | int sctp_outq_is_empty(const struct sctp_outq *q) | 1278 | int sctp_outq_is_empty(const struct sctp_outq *q) |
| 1298 | { | 1279 | { |
| 1299 | return q->empty; | 1280 | return q->out_qlen == 0 && q->outstanding_bytes == 0 && |
| 1281 | list_empty(&q->retransmit); | ||
| 1300 | } | 1282 | } |
| 1301 | 1283 | ||
| 1302 | /******************************************************************** | 1284 | /******************************************************************** |
diff --git a/net/tipc/port.c b/net/tipc/port.c index 5fd4c8cec08e..b742b2654525 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 5efdeef06f9d..c8341d1f995e 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -351,7 +351,7 @@ static int release(struct socket *sock) | |||
| 351 | * Delete TIPC port; this ensures no more messages are queued | 351 | * Delete TIPC port; this ensures no more messages are queued |
| 352 | * (also disconnects an active connection & sends a 'FIN-' to peer) | 352 | * (also disconnects an active connection & sends a 'FIN-' to peer) |
| 353 | */ | 353 | */ |
| 354 | res = tipc_deleteport(tport->ref); | 354 | res = tipc_deleteport(tport); |
| 355 | 355 | ||
| 356 | /* Discard any remaining (connection-based) messages in receive queue */ | 356 | /* Discard any remaining (connection-based) messages in receive queue */ |
| 357 | __skb_queue_purge(&sk->sk_receive_queue); | 357 | __skb_queue_purge(&sk->sk_receive_queue); |
| @@ -383,30 +383,46 @@ static int release(struct socket *sock) | |||
| 383 | */ | 383 | */ |
| 384 | static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | 384 | static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) |
| 385 | { | 385 | { |
| 386 | struct sock *sk = sock->sk; | ||
| 386 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 387 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; |
| 387 | u32 portref = tipc_sk_port(sock->sk)->ref; | 388 | struct tipc_port *tport = tipc_sk_port(sock->sk); |
| 389 | int res = -EINVAL; | ||
| 388 | 390 | ||
| 389 | if (unlikely(!uaddr_len)) | 391 | lock_sock(sk); |
| 390 | return tipc_withdraw(portref, 0, NULL); | 392 | if (unlikely(!uaddr_len)) { |
| 393 | res = tipc_withdraw(tport, 0, NULL); | ||
| 394 | goto exit; | ||
| 395 | } | ||
| 391 | 396 | ||
| 392 | if (uaddr_len < sizeof(struct sockaddr_tipc)) | 397 | if (uaddr_len < sizeof(struct sockaddr_tipc)) { |
| 393 | return -EINVAL; | 398 | res = -EINVAL; |
| 394 | if (addr->family != AF_TIPC) | 399 | goto exit; |
| 395 | return -EAFNOSUPPORT; | 400 | } |
| 401 | if (addr->family != AF_TIPC) { | ||
| 402 | res = -EAFNOSUPPORT; | ||
| 403 | goto exit; | ||
| 404 | } | ||
| 396 | 405 | ||
| 397 | if (addr->addrtype == TIPC_ADDR_NAME) | 406 | if (addr->addrtype == TIPC_ADDR_NAME) |
| 398 | addr->addr.nameseq.upper = addr->addr.nameseq.lower; | 407 | addr->addr.nameseq.upper = addr->addr.nameseq.lower; |
| 399 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) | 408 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) { |
| 400 | return -EAFNOSUPPORT; | 409 | res = -EAFNOSUPPORT; |
| 410 | goto exit; | ||
| 411 | } | ||
| 401 | 412 | ||
| 402 | if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && | 413 | if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && |
| 403 | (addr->addr.nameseq.type != TIPC_TOP_SRV) && | 414 | (addr->addr.nameseq.type != TIPC_TOP_SRV) && |
| 404 | (addr->addr.nameseq.type != TIPC_CFG_SRV)) | 415 | (addr->addr.nameseq.type != TIPC_CFG_SRV)) { |
| 405 | return -EACCES; | 416 | res = -EACCES; |
| 417 | goto exit; | ||
| 418 | } | ||
| 406 | 419 | ||
| 407 | return (addr->scope > 0) ? | 420 | res = (addr->scope > 0) ? |
| 408 | tipc_publish(portref, addr->scope, &addr->addr.nameseq) : | 421 | tipc_publish(tport, addr->scope, &addr->addr.nameseq) : |
| 409 | tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq); | 422 | tipc_withdraw(tport, -addr->scope, &addr->addr.nameseq); |
| 423 | exit: | ||
| 424 | release_sock(sk); | ||
| 425 | return res; | ||
| 410 | } | 426 | } |
| 411 | 427 | ||
| 412 | /** | 428 | /** |
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 | ||
