diff options
Diffstat (limited to 'net')
93 files changed, 537 insertions, 409 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index c7a581a96894..917ecb93ea28 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -205,7 +205,7 @@ int register_vlan_dev(struct net_device *dev) | |||
| 205 | grp->nr_vlans++; | 205 | grp->nr_vlans++; |
| 206 | 206 | ||
| 207 | if (ngrp) { | 207 | if (ngrp) { |
| 208 | if (ops->ndo_vlan_rx_register) | 208 | if (ops->ndo_vlan_rx_register && (real_dev->features & NETIF_F_HW_VLAN_RX)) |
| 209 | ops->ndo_vlan_rx_register(real_dev, ngrp); | 209 | ops->ndo_vlan_rx_register(real_dev, ngrp); |
| 210 | rcu_assign_pointer(real_dev->vlgrp, ngrp); | 210 | rcu_assign_pointer(real_dev->vlgrp, ngrp); |
| 211 | } | 211 | } |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 41495dc2a4c9..fcc684678af6 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
| @@ -23,6 +23,31 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
| 23 | return false; | 23 | return false; |
| 24 | 24 | ||
| 25 | skb->dev = vlan_dev; | 25 | skb->dev = vlan_dev; |
| 26 | if (skb->pkt_type == PACKET_OTHERHOST) { | ||
| 27 | /* Our lower layer thinks this is not local, let's make sure. | ||
| 28 | * This allows the VLAN to have a different MAC than the | ||
| 29 | * underlying device, and still route correctly. */ | ||
| 30 | if (!compare_ether_addr(eth_hdr(skb)->h_dest, | ||
| 31 | vlan_dev->dev_addr)) | ||
| 32 | skb->pkt_type = PACKET_HOST; | ||
| 33 | } | ||
| 34 | |||
| 35 | if (!(vlan_dev_info(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) { | ||
| 36 | unsigned int offset = skb->data - skb_mac_header(skb); | ||
| 37 | |||
| 38 | /* | ||
| 39 | * vlan_insert_tag expect skb->data pointing to mac header. | ||
| 40 | * So change skb->data before calling it and change back to | ||
| 41 | * original position later | ||
| 42 | */ | ||
| 43 | skb_push(skb, offset); | ||
| 44 | skb = *skbp = vlan_insert_tag(skb, skb->vlan_tci); | ||
| 45 | if (!skb) | ||
| 46 | return false; | ||
| 47 | skb_pull(skb, offset + VLAN_HLEN); | ||
| 48 | skb_reset_mac_len(skb); | ||
| 49 | } | ||
| 50 | |||
| 26 | skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); | 51 | skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); |
| 27 | skb->vlan_tci = 0; | 52 | skb->vlan_tci = 0; |
| 28 | 53 | ||
| @@ -31,22 +56,8 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
| 31 | u64_stats_update_begin(&rx_stats->syncp); | 56 | u64_stats_update_begin(&rx_stats->syncp); |
| 32 | rx_stats->rx_packets++; | 57 | rx_stats->rx_packets++; |
| 33 | rx_stats->rx_bytes += skb->len; | 58 | rx_stats->rx_bytes += skb->len; |
| 34 | 59 | if (skb->pkt_type == PACKET_MULTICAST) | |
| 35 | switch (skb->pkt_type) { | ||
| 36 | case PACKET_BROADCAST: | ||
| 37 | break; | ||
| 38 | case PACKET_MULTICAST: | ||
| 39 | rx_stats->rx_multicast++; | 60 | rx_stats->rx_multicast++; |
| 40 | break; | ||
| 41 | case PACKET_OTHERHOST: | ||
| 42 | /* Our lower layer thinks this is not local, let's make sure. | ||
| 43 | * This allows the VLAN to have a different MAC than the | ||
| 44 | * underlying device, and still route correctly. */ | ||
| 45 | if (!compare_ether_addr(eth_hdr(skb)->h_dest, | ||
| 46 | vlan_dev->dev_addr)) | ||
| 47 | skb->pkt_type = PACKET_HOST; | ||
| 48 | break; | ||
| 49 | } | ||
| 50 | u64_stats_update_end(&rx_stats->syncp); | 61 | u64_stats_update_end(&rx_stats->syncp); |
| 51 | 62 | ||
| 52 | return true; | 63 | return true; |
| @@ -89,18 +100,13 @@ gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, | |||
| 89 | } | 100 | } |
| 90 | EXPORT_SYMBOL(vlan_gro_frags); | 101 | EXPORT_SYMBOL(vlan_gro_frags); |
| 91 | 102 | ||
| 92 | static struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb) | 103 | static struct sk_buff *vlan_reorder_header(struct sk_buff *skb) |
| 93 | { | 104 | { |
| 94 | if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) { | 105 | if (skb_cow(skb, skb_headroom(skb)) < 0) |
| 95 | if (skb_cow(skb, skb_headroom(skb)) < 0) | 106 | return NULL; |
| 96 | skb = NULL; | 107 | memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN); |
| 97 | if (skb) { | 108 | skb->mac_header += VLAN_HLEN; |
| 98 | /* Lifted from Gleb's VLAN code... */ | 109 | skb_reset_mac_len(skb); |
| 99 | memmove(skb->data - ETH_HLEN, | ||
| 100 | skb->data - VLAN_ETH_HLEN, 12); | ||
| 101 | skb->mac_header += VLAN_HLEN; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | return skb; | 110 | return skb; |
| 105 | } | 111 | } |
| 106 | 112 | ||
| @@ -161,7 +167,7 @@ struct sk_buff *vlan_untag(struct sk_buff *skb) | |||
| 161 | skb_pull_rcsum(skb, VLAN_HLEN); | 167 | skb_pull_rcsum(skb, VLAN_HLEN); |
| 162 | vlan_set_encap_proto(skb, vhdr); | 168 | vlan_set_encap_proto(skb, vhdr); |
| 163 | 169 | ||
| 164 | skb = vlan_check_reorder_header(skb); | 170 | skb = vlan_reorder_header(skb); |
| 165 | if (unlikely(!skb)) | 171 | if (unlikely(!skb)) |
| 166 | goto err_free; | 172 | goto err_free; |
| 167 | 173 | ||
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index f247f5bff88d..86bff9b1ac47 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -165,7 +165,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, | |||
| 165 | u64_stats_update_begin(&stats->syncp); | 165 | u64_stats_update_begin(&stats->syncp); |
| 166 | stats->tx_packets++; | 166 | stats->tx_packets++; |
| 167 | stats->tx_bytes += len; | 167 | stats->tx_bytes += len; |
| 168 | u64_stats_update_begin(&stats->syncp); | 168 | u64_stats_update_end(&stats->syncp); |
| 169 | } else { | 169 | } else { |
| 170 | this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); | 170 | this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); |
| 171 | } | 171 | } |
| @@ -586,9 +586,14 @@ static void vlan_dev_uninit(struct net_device *dev) | |||
| 586 | static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) | 586 | static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) |
| 587 | { | 587 | { |
| 588 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | 588 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 589 | u32 old_features = features; | ||
| 589 | 590 | ||
| 590 | features &= real_dev->features; | 591 | features &= real_dev->features; |
| 591 | features &= real_dev->vlan_features; | 592 | features &= real_dev->vlan_features; |
| 593 | |||
| 594 | if (old_features & NETIF_F_SOFT_FEATURES) | ||
| 595 | features |= old_features & NETIF_F_SOFT_FEATURES; | ||
| 596 | |||
| 592 | if (dev_ethtool_get_rx_csum(real_dev)) | 597 | if (dev_ethtool_get_rx_csum(real_dev)) |
| 593 | features |= NETIF_F_RXCSUM; | 598 | features |= NETIF_F_RXCSUM; |
| 594 | features |= NETIF_F_LLTX; | 599 | features |= NETIF_F_LLTX; |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 3163330cd4f1..d3a05b9ade7a 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
| @@ -608,11 +608,11 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
| 608 | goto encrypt; | 608 | goto encrypt; |
| 609 | 609 | ||
| 610 | auth: | 610 | auth: |
| 611 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 611 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
| 612 | return 0; | 612 | return 0; |
| 613 | 613 | ||
| 614 | hci_conn_auth(conn, sec_level, auth_type); | 614 | if (!hci_conn_auth(conn, sec_level, auth_type)) |
| 615 | return 0; | 615 | return 0; |
| 616 | 616 | ||
| 617 | encrypt: | 617 | encrypt: |
| 618 | if (conn->link_mode & HCI_LM_ENCRYPT) | 618 | if (conn->link_mode & HCI_LM_ENCRYPT) |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f13ddbf858ba..77930aa522e3 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -477,14 +477,16 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
| 477 | * command otherwise */ | 477 | * command otherwise */ |
| 478 | u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; | 478 | u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; |
| 479 | 479 | ||
| 480 | /* Events for 1.2 and newer controllers */ | 480 | /* CSR 1.1 dongles does not accept any bitfield so don't try to set |
| 481 | if (hdev->lmp_ver > 1) { | 481 | * any event mask for pre 1.2 devices */ |
| 482 | events[4] |= 0x01; /* Flow Specification Complete */ | 482 | if (hdev->lmp_ver <= 1) |
| 483 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | 483 | return; |
| 484 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ | 484 | |
| 485 | events[5] |= 0x08; /* Synchronous Connection Complete */ | 485 | events[4] |= 0x01; /* Flow Specification Complete */ |
| 486 | events[5] |= 0x10; /* Synchronous Connection Changed */ | 486 | events[4] |= 0x02; /* Inquiry Result with RSSI */ |
| 487 | } | 487 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ |
| 488 | events[5] |= 0x08; /* Synchronous Connection Complete */ | ||
| 489 | events[5] |= 0x10; /* Synchronous Connection Changed */ | ||
| 488 | 490 | ||
| 489 | if (hdev->features[3] & LMP_RSSI_INQ) | 491 | if (hdev->features[3] & LMP_RSSI_INQ) |
| 490 | events[4] |= 0x04; /* Inquiry Result with RSSI */ | 492 | events[4] |= 0x04; /* Inquiry Result with RSSI */ |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a86f9ba4f05c..56fdd9162da9 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -906,7 +906,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr | |||
| 906 | if (c->psm == psm) { | 906 | if (c->psm == psm) { |
| 907 | /* Exact match. */ | 907 | /* Exact match. */ |
| 908 | if (!bacmp(&bt_sk(sk)->src, src)) { | 908 | if (!bacmp(&bt_sk(sk)->src, src)) { |
| 909 | read_unlock_bh(&chan_list_lock); | 909 | read_unlock(&chan_list_lock); |
| 910 | return c; | 910 | return c; |
| 911 | } | 911 | } |
| 912 | 912 | ||
| @@ -4002,21 +4002,30 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
| 4002 | } | 4002 | } |
| 4003 | } else if (sk->sk_state == BT_CONNECT2) { | 4003 | } else if (sk->sk_state == BT_CONNECT2) { |
| 4004 | struct l2cap_conn_rsp rsp; | 4004 | struct l2cap_conn_rsp rsp; |
| 4005 | __u16 result; | 4005 | __u16 res, stat; |
| 4006 | 4006 | ||
| 4007 | if (!status) { | 4007 | if (!status) { |
| 4008 | sk->sk_state = BT_CONFIG; | 4008 | if (bt_sk(sk)->defer_setup) { |
| 4009 | result = L2CAP_CR_SUCCESS; | 4009 | struct sock *parent = bt_sk(sk)->parent; |
| 4010 | res = L2CAP_CR_PEND; | ||
| 4011 | stat = L2CAP_CS_AUTHOR_PEND; | ||
| 4012 | parent->sk_data_ready(parent, 0); | ||
| 4013 | } else { | ||
| 4014 | sk->sk_state = BT_CONFIG; | ||
| 4015 | res = L2CAP_CR_SUCCESS; | ||
| 4016 | stat = L2CAP_CS_NO_INFO; | ||
| 4017 | } | ||
| 4010 | } else { | 4018 | } else { |
| 4011 | sk->sk_state = BT_DISCONN; | 4019 | sk->sk_state = BT_DISCONN; |
| 4012 | l2cap_sock_set_timer(sk, HZ / 10); | 4020 | l2cap_sock_set_timer(sk, HZ / 10); |
| 4013 | result = L2CAP_CR_SEC_BLOCK; | 4021 | res = L2CAP_CR_SEC_BLOCK; |
| 4022 | stat = L2CAP_CS_NO_INFO; | ||
| 4014 | } | 4023 | } |
| 4015 | 4024 | ||
| 4016 | rsp.scid = cpu_to_le16(chan->dcid); | 4025 | rsp.scid = cpu_to_le16(chan->dcid); |
| 4017 | rsp.dcid = cpu_to_le16(chan->scid); | 4026 | rsp.dcid = cpu_to_le16(chan->scid); |
| 4018 | rsp.result = cpu_to_le16(result); | 4027 | rsp.result = cpu_to_le16(res); |
| 4019 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | 4028 | rsp.status = cpu_to_le16(stat); |
| 4020 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 4029 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
| 4021 | sizeof(rsp), &rsp); | 4030 | sizeof(rsp), &rsp); |
| 4022 | } | 4031 | } |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 18dc9888d8c2..8248303f44e8 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
| @@ -413,6 +413,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
| 413 | break; | 413 | break; |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | memset(&cinfo, 0, sizeof(cinfo)); | ||
| 416 | cinfo.hci_handle = chan->conn->hcon->handle; | 417 | cinfo.hci_handle = chan->conn->hcon->handle; |
| 417 | memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3); | 418 | memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3); |
| 418 | 419 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 386cfaffd4b7..1b10727ce523 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
| @@ -788,6 +788,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
| 788 | 788 | ||
| 789 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; | 789 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; |
| 790 | 790 | ||
| 791 | memset(&cinfo, 0, sizeof(cinfo)); | ||
| 791 | cinfo.hci_handle = conn->hcon->handle; | 792 | cinfo.hci_handle = conn->hcon->handle; |
| 792 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); | 793 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); |
| 793 | 794 | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 42fdffd1d76c..cb4fb7837e5c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -369,6 +369,15 @@ static void __sco_sock_close(struct sock *sk) | |||
| 369 | 369 | ||
| 370 | case BT_CONNECTED: | 370 | case BT_CONNECTED: |
| 371 | case BT_CONFIG: | 371 | case BT_CONFIG: |
| 372 | if (sco_pi(sk)->conn) { | ||
| 373 | sk->sk_state = BT_DISCONN; | ||
| 374 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); | ||
| 375 | hci_conn_put(sco_pi(sk)->conn->hcon); | ||
| 376 | sco_pi(sk)->conn->hcon = NULL; | ||
| 377 | } else | ||
| 378 | sco_chan_del(sk, ECONNRESET); | ||
| 379 | break; | ||
| 380 | |||
| 372 | case BT_CONNECT: | 381 | case BT_CONNECT: |
| 373 | case BT_DISCONN: | 382 | case BT_DISCONN: |
| 374 | sco_chan_del(sk, ECONNRESET); | 383 | sco_chan_del(sk, ECONNRESET); |
| @@ -819,7 +828,9 @@ static void sco_chan_del(struct sock *sk, int err) | |||
| 819 | conn->sk = NULL; | 828 | conn->sk = NULL; |
| 820 | sco_pi(sk)->conn = NULL; | 829 | sco_pi(sk)->conn = NULL; |
| 821 | sco_conn_unlock(conn); | 830 | sco_conn_unlock(conn); |
| 822 | hci_conn_put(conn->hcon); | 831 | |
| 832 | if (conn->hcon) | ||
| 833 | hci_conn_put(conn->hcon); | ||
| 823 | } | 834 | } |
| 824 | 835 | ||
| 825 | sk->sk_state = BT_CLOSED; | 836 | sk->sk_state = BT_CLOSED; |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index a6b2f86378c7..32b8f9f7f79e 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
| @@ -49,7 +49,9 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 49 | skb_pull(skb, ETH_HLEN); | 49 | skb_pull(skb, ETH_HLEN); |
| 50 | 50 | ||
| 51 | rcu_read_lock(); | 51 | rcu_read_lock(); |
| 52 | if (is_multicast_ether_addr(dest)) { | 52 | if (is_broadcast_ether_addr(dest)) |
| 53 | br_flood_deliver(br, skb); | ||
| 54 | else if (is_multicast_ether_addr(dest)) { | ||
| 53 | if (unlikely(netpoll_tx_running(dev))) { | 55 | if (unlikely(netpoll_tx_running(dev))) { |
| 54 | br_flood_deliver(br, skb); | 56 | br_flood_deliver(br, skb); |
| 55 | goto out; | 57 | goto out; |
| @@ -243,6 +245,7 @@ int br_netpoll_enable(struct net_bridge_port *p) | |||
| 243 | goto out; | 245 | goto out; |
| 244 | 246 | ||
| 245 | np->dev = p->dev; | 247 | np->dev = p->dev; |
| 248 | strlcpy(np->dev_name, p->dev->name, IFNAMSIZ); | ||
| 246 | 249 | ||
| 247 | err = __netpoll_setup(np); | 250 | err = __netpoll_setup(np); |
| 248 | if (err) { | 251 | if (err) { |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index f3ac1e858ee1..f06ee39c73fd 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -60,7 +60,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
| 60 | br = p->br; | 60 | br = p->br; |
| 61 | br_fdb_update(br, p, eth_hdr(skb)->h_source); | 61 | br_fdb_update(br, p, eth_hdr(skb)->h_source); |
| 62 | 62 | ||
| 63 | if (is_multicast_ether_addr(dest) && | 63 | if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && |
| 64 | br_multicast_rcv(br, p, skb)) | 64 | br_multicast_rcv(br, p, skb)) |
| 65 | goto drop; | 65 | goto drop; |
| 66 | 66 | ||
| @@ -77,7 +77,9 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
| 77 | 77 | ||
| 78 | dst = NULL; | 78 | dst = NULL; |
| 79 | 79 | ||
| 80 | if (is_multicast_ether_addr(dest)) { | 80 | if (is_broadcast_ether_addr(dest)) |
| 81 | skb2 = skb; | ||
| 82 | else if (is_multicast_ether_addr(dest)) { | ||
| 81 | mdst = br_mdb_get(br, skb); | 83 | mdst = br_mdb_get(br, skb); |
| 82 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { | 84 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { |
| 83 | if ((mdst && mdst->mglist) || | 85 | if ((mdst && mdst->mglist) || |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 2f14eafdeeab..2d85ca7111d3 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -1379,8 +1379,11 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
| 1379 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) | 1379 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) |
| 1380 | return -EINVAL; | 1380 | return -EINVAL; |
| 1381 | 1381 | ||
| 1382 | if (iph->protocol != IPPROTO_IGMP) | 1382 | if (iph->protocol != IPPROTO_IGMP) { |
| 1383 | if ((iph->daddr & IGMP_LOCAL_GROUP_MASK) != IGMP_LOCAL_GROUP) | ||
| 1384 | BR_INPUT_SKB_CB(skb)->mrouters_only = 1; | ||
| 1383 | return 0; | 1385 | return 0; |
| 1386 | } | ||
| 1384 | 1387 | ||
| 1385 | len = ntohs(iph->tot_len); | 1388 | len = ntohs(iph->tot_len); |
| 1386 | if (skb->len < len || len < ip_hdrlen(skb)) | 1389 | if (skb->len < len || len < ip_hdrlen(skb)) |
| @@ -1424,7 +1427,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
| 1424 | switch (ih->type) { | 1427 | switch (ih->type) { |
| 1425 | case IGMP_HOST_MEMBERSHIP_REPORT: | 1428 | case IGMP_HOST_MEMBERSHIP_REPORT: |
| 1426 | case IGMPV2_HOST_MEMBERSHIP_REPORT: | 1429 | case IGMPV2_HOST_MEMBERSHIP_REPORT: |
| 1427 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; | 1430 | BR_INPUT_SKB_CB(skb)->mrouters_only = 1; |
| 1428 | err = br_ip4_multicast_add_group(br, port, ih->group); | 1431 | err = br_ip4_multicast_add_group(br, port, ih->group); |
| 1429 | break; | 1432 | break; |
| 1430 | case IGMPV3_HOST_MEMBERSHIP_REPORT: | 1433 | case IGMPV3_HOST_MEMBERSHIP_REPORT: |
| @@ -1543,7 +1546,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
| 1543 | goto out; | 1546 | goto out; |
| 1544 | } | 1547 | } |
| 1545 | mld = (struct mld_msg *)skb_transport_header(skb2); | 1548 | mld = (struct mld_msg *)skb_transport_header(skb2); |
| 1546 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; | 1549 | BR_INPUT_SKB_CB(skb)->mrouters_only = 1; |
| 1547 | err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); | 1550 | err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); |
| 1548 | break; | 1551 | break; |
| 1549 | } | 1552 | } |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 3fa123185e89..56149ec36d7f 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
| @@ -104,10 +104,16 @@ static void fake_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
| 104 | { | 104 | { |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old) | ||
| 108 | { | ||
| 109 | return NULL; | ||
| 110 | } | ||
| 111 | |||
| 107 | static struct dst_ops fake_dst_ops = { | 112 | static struct dst_ops fake_dst_ops = { |
| 108 | .family = AF_INET, | 113 | .family = AF_INET, |
| 109 | .protocol = cpu_to_be16(ETH_P_IP), | 114 | .protocol = cpu_to_be16(ETH_P_IP), |
| 110 | .update_pmtu = fake_update_pmtu, | 115 | .update_pmtu = fake_update_pmtu, |
| 116 | .cow_metrics = fake_cow_metrics, | ||
| 111 | }; | 117 | }; |
| 112 | 118 | ||
| 113 | /* | 119 | /* |
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 3a66b8c10e09..c23979e79dfa 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c | |||
| @@ -255,7 +255,7 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, | |||
| 255 | 255 | ||
| 256 | if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) { | 256 | if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) { |
| 257 | 257 | ||
| 258 | if ((ctrl == _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND || | 258 | if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND || |
| 259 | ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) && | 259 | ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) && |
| 260 | layer->id != 0) { | 260 | layer->id != 0) { |
| 261 | 261 | ||
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 649ebacaf6bc..adbb424403d4 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
| @@ -139,17 +139,14 @@ static void close_work(struct work_struct *work) | |||
| 139 | struct chnl_net *dev = NULL; | 139 | struct chnl_net *dev = NULL; |
| 140 | struct list_head *list_node; | 140 | struct list_head *list_node; |
| 141 | struct list_head *_tmp; | 141 | struct list_head *_tmp; |
| 142 | /* May be called with or without RTNL lock held */ | 142 | |
| 143 | int islocked = rtnl_is_locked(); | 143 | rtnl_lock(); |
| 144 | if (!islocked) | ||
| 145 | rtnl_lock(); | ||
| 146 | list_for_each_safe(list_node, _tmp, &chnl_net_list) { | 144 | list_for_each_safe(list_node, _tmp, &chnl_net_list) { |
| 147 | dev = list_entry(list_node, struct chnl_net, list_field); | 145 | dev = list_entry(list_node, struct chnl_net, list_field); |
| 148 | if (dev->state == CAIF_SHUTDOWN) | 146 | if (dev->state == CAIF_SHUTDOWN) |
| 149 | dev_close(dev->netdev); | 147 | dev_close(dev->netdev); |
| 150 | } | 148 | } |
| 151 | if (!islocked) | 149 | rtnl_unlock(); |
| 152 | rtnl_unlock(); | ||
| 153 | } | 150 | } |
| 154 | static DECLARE_WORK(close_worker, close_work); | 151 | static DECLARE_WORK(close_worker, close_work); |
| 155 | 152 | ||
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 6ea2b892f44b..7330c2757c0c 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
| @@ -477,8 +477,9 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, | |||
| 477 | calc_layout(osdc, vino, layout, off, plen, req, ops); | 477 | calc_layout(osdc, vino, layout, off, plen, req, ops); |
| 478 | req->r_file_layout = *layout; /* keep a copy */ | 478 | req->r_file_layout = *layout; /* keep a copy */ |
| 479 | 479 | ||
| 480 | /* in case it differs from natural alignment that calc_layout | 480 | /* in case it differs from natural (file) alignment that |
| 481 | filled in for us */ | 481 | calc_layout filled in for us */ |
| 482 | req->r_num_pages = calc_pages_for(page_align, *plen); | ||
| 482 | req->r_page_alignment = page_align; | 483 | req->r_page_alignment = page_align; |
| 483 | 484 | ||
| 484 | ceph_osdc_build_request(req, off, plen, ops, | 485 | ceph_osdc_build_request(req, off, plen, ops, |
| @@ -1144,6 +1145,13 @@ static void handle_osds_timeout(struct work_struct *work) | |||
| 1144 | round_jiffies_relative(delay)); | 1145 | round_jiffies_relative(delay)); |
| 1145 | } | 1146 | } |
| 1146 | 1147 | ||
| 1148 | static void complete_request(struct ceph_osd_request *req) | ||
| 1149 | { | ||
| 1150 | if (req->r_safe_callback) | ||
| 1151 | req->r_safe_callback(req, NULL); | ||
| 1152 | complete_all(&req->r_safe_completion); /* fsync waiter */ | ||
| 1153 | } | ||
| 1154 | |||
| 1147 | /* | 1155 | /* |
| 1148 | * handle osd op reply. either call the callback if it is specified, | 1156 | * handle osd op reply. either call the callback if it is specified, |
| 1149 | * or do the completion to wake up the waiting thread. | 1157 | * or do the completion to wake up the waiting thread. |
| @@ -1226,11 +1234,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, | |||
| 1226 | else | 1234 | else |
| 1227 | complete_all(&req->r_completion); | 1235 | complete_all(&req->r_completion); |
| 1228 | 1236 | ||
| 1229 | if (flags & CEPH_OSD_FLAG_ONDISK) { | 1237 | if (flags & CEPH_OSD_FLAG_ONDISK) |
| 1230 | if (req->r_safe_callback) | 1238 | complete_request(req); |
| 1231 | req->r_safe_callback(req, msg); | ||
| 1232 | complete_all(&req->r_safe_completion); /* fsync waiter */ | ||
| 1233 | } | ||
| 1234 | 1239 | ||
| 1235 | done: | 1240 | done: |
| 1236 | dout("req=%p req->r_linger=%d\n", req, req->r_linger); | 1241 | dout("req=%p req->r_linger=%d\n", req, req->r_linger); |
| @@ -1732,6 +1737,7 @@ int ceph_osdc_wait_request(struct ceph_osd_client *osdc, | |||
| 1732 | __cancel_request(req); | 1737 | __cancel_request(req); |
| 1733 | __unregister_request(osdc, req); | 1738 | __unregister_request(osdc, req); |
| 1734 | mutex_unlock(&osdc->request_mutex); | 1739 | mutex_unlock(&osdc->request_mutex); |
| 1740 | complete_request(req); | ||
| 1735 | dout("wait_request tid %llu canceled/timed out\n", req->r_tid); | 1741 | dout("wait_request tid %llu canceled/timed out\n", req->r_tid); |
| 1736 | return rc; | 1742 | return rc; |
| 1737 | } | 1743 | } |
| @@ -2022,8 +2028,9 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, | |||
| 2022 | int want = calc_pages_for(req->r_page_alignment, data_len); | 2028 | int want = calc_pages_for(req->r_page_alignment, data_len); |
| 2023 | 2029 | ||
| 2024 | if (unlikely(req->r_num_pages < want)) { | 2030 | if (unlikely(req->r_num_pages < want)) { |
| 2025 | pr_warning("tid %lld reply %d > expected %d pages\n", | 2031 | pr_warning("tid %lld reply has %d bytes %d pages, we" |
| 2026 | tid, want, m->nr_pages); | 2032 | " had only %d pages ready\n", tid, data_len, |
| 2033 | want, req->r_num_pages); | ||
| 2027 | *skip = 1; | 2034 | *skip = 1; |
| 2028 | ceph_msg_put(m); | 2035 | ceph_msg_put(m); |
| 2029 | m = NULL; | 2036 | m = NULL; |
diff --git a/net/core/dev.c b/net/core/dev.c index c7e305d13b71..9c58c1ec41a9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2096,6 +2096,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
| 2096 | { | 2096 | { |
| 2097 | const struct net_device_ops *ops = dev->netdev_ops; | 2097 | const struct net_device_ops *ops = dev->netdev_ops; |
| 2098 | int rc = NETDEV_TX_OK; | 2098 | int rc = NETDEV_TX_OK; |
| 2099 | unsigned int skb_len; | ||
| 2099 | 2100 | ||
| 2100 | if (likely(!skb->next)) { | 2101 | if (likely(!skb->next)) { |
| 2101 | u32 features; | 2102 | u32 features; |
| @@ -2146,8 +2147,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
| 2146 | } | 2147 | } |
| 2147 | } | 2148 | } |
| 2148 | 2149 | ||
| 2150 | skb_len = skb->len; | ||
| 2149 | rc = ops->ndo_start_xmit(skb, dev); | 2151 | rc = ops->ndo_start_xmit(skb, dev); |
| 2150 | trace_net_dev_xmit(skb, rc); | 2152 | trace_net_dev_xmit(skb, rc, dev, skb_len); |
| 2151 | if (rc == NETDEV_TX_OK) | 2153 | if (rc == NETDEV_TX_OK) |
| 2152 | txq_trans_update(txq); | 2154 | txq_trans_update(txq); |
| 2153 | return rc; | 2155 | return rc; |
| @@ -2167,8 +2169,9 @@ gso: | |||
| 2167 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) | 2169 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) |
| 2168 | skb_dst_drop(nskb); | 2170 | skb_dst_drop(nskb); |
| 2169 | 2171 | ||
| 2172 | skb_len = nskb->len; | ||
| 2170 | rc = ops->ndo_start_xmit(nskb, dev); | 2173 | rc = ops->ndo_start_xmit(nskb, dev); |
| 2171 | trace_net_dev_xmit(nskb, rc); | 2174 | trace_net_dev_xmit(nskb, rc, dev, skb_len); |
| 2172 | if (unlikely(rc != NETDEV_TX_OK)) { | 2175 | if (unlikely(rc != NETDEV_TX_OK)) { |
| 2173 | if (rc & ~NETDEV_TX_MASK) | 2176 | if (rc & ~NETDEV_TX_MASK) |
| 2174 | goto out_kfree_gso_skb; | 2177 | goto out_kfree_gso_skb; |
| @@ -3111,7 +3114,7 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
| 3111 | 3114 | ||
| 3112 | skb_reset_network_header(skb); | 3115 | skb_reset_network_header(skb); |
| 3113 | skb_reset_transport_header(skb); | 3116 | skb_reset_transport_header(skb); |
| 3114 | skb->mac_len = skb->network_header - skb->mac_header; | 3117 | skb_reset_mac_len(skb); |
| 3115 | 3118 | ||
| 3116 | pt_prev = NULL; | 3119 | pt_prev = NULL; |
| 3117 | 3120 | ||
| @@ -6175,6 +6178,11 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
| 6175 | oldsd->output_queue = NULL; | 6178 | oldsd->output_queue = NULL; |
| 6176 | oldsd->output_queue_tailp = &oldsd->output_queue; | 6179 | oldsd->output_queue_tailp = &oldsd->output_queue; |
| 6177 | } | 6180 | } |
| 6181 | /* Append NAPI poll list from offline CPU. */ | ||
| 6182 | if (!list_empty(&oldsd->poll_list)) { | ||
| 6183 | list_splice_init(&oldsd->poll_list, &sd->poll_list); | ||
| 6184 | raise_softirq_irqoff(NET_RX_SOFTIRQ); | ||
| 6185 | } | ||
| 6178 | 6186 | ||
| 6179 | raise_softirq_irqoff(NET_TX_SOFTIRQ); | 6187 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
| 6180 | local_irq_enable(); | 6188 | local_irq_enable(); |
| @@ -6261,29 +6269,23 @@ err_name: | |||
| 6261 | /** | 6269 | /** |
| 6262 | * netdev_drivername - network driver for the device | 6270 | * netdev_drivername - network driver for the device |
| 6263 | * @dev: network device | 6271 | * @dev: network device |
| 6264 | * @buffer: buffer for resulting name | ||
| 6265 | * @len: size of buffer | ||
| 6266 | * | 6272 | * |
| 6267 | * Determine network driver for device. | 6273 | * Determine network driver for device. |
| 6268 | */ | 6274 | */ |
| 6269 | char *netdev_drivername(const struct net_device *dev, char *buffer, int len) | 6275 | const char *netdev_drivername(const struct net_device *dev) |
| 6270 | { | 6276 | { |
| 6271 | const struct device_driver *driver; | 6277 | const struct device_driver *driver; |
| 6272 | const struct device *parent; | 6278 | const struct device *parent; |
| 6273 | 6279 | const char *empty = ""; | |
| 6274 | if (len <= 0 || !buffer) | ||
| 6275 | return buffer; | ||
| 6276 | buffer[0] = 0; | ||
| 6277 | 6280 | ||
| 6278 | parent = dev->dev.parent; | 6281 | parent = dev->dev.parent; |
| 6279 | |||
| 6280 | if (!parent) | 6282 | if (!parent) |
| 6281 | return buffer; | 6283 | return empty; |
| 6282 | 6284 | ||
| 6283 | driver = parent->driver; | 6285 | driver = parent->driver; |
| 6284 | if (driver && driver->name) | 6286 | if (driver && driver->name) |
| 6285 | strlcpy(buffer, driver->name, len); | 6287 | return driver->name; |
| 6286 | return buffer; | 6288 | return empty; |
| 6287 | } | 6289 | } |
| 6288 | 6290 | ||
| 6289 | static int __netdev_printk(const char *level, const struct net_device *dev, | 6291 | static int __netdev_printk(const char *level, const struct net_device *dev, |
diff --git a/net/core/dst.c b/net/core/dst.c index 9ccca038444f..6135f3671692 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
| @@ -190,7 +190,8 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, | |||
| 190 | dst->lastuse = jiffies; | 190 | dst->lastuse = jiffies; |
| 191 | dst->flags = flags; | 191 | dst->flags = flags; |
| 192 | dst->next = NULL; | 192 | dst->next = NULL; |
| 193 | dst_entries_add(ops, 1); | 193 | if (!(flags & DST_NOCOUNT)) |
| 194 | dst_entries_add(ops, 1); | ||
| 194 | return dst; | 195 | return dst; |
| 195 | } | 196 | } |
| 196 | EXPORT_SYMBOL(dst_alloc); | 197 | EXPORT_SYMBOL(dst_alloc); |
| @@ -243,7 +244,8 @@ again: | |||
| 243 | neigh_release(neigh); | 244 | neigh_release(neigh); |
| 244 | } | 245 | } |
| 245 | 246 | ||
| 246 | dst_entries_add(dst->ops, -1); | 247 | if (!(dst->flags & DST_NOCOUNT)) |
| 248 | dst_entries_add(dst->ops, -1); | ||
| 247 | 249 | ||
| 248 | if (dst->ops->destroy) | 250 | if (dst->ops->destroy) |
| 249 | dst->ops->destroy(dst); | 251 | dst->ops->destroy(dst); |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 11b98bc2aa8f..33d2a1fba131 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
| @@ -1179,9 +1179,14 @@ static void remove_queue_kobjects(struct net_device *net) | |||
| 1179 | #endif | 1179 | #endif |
| 1180 | } | 1180 | } |
| 1181 | 1181 | ||
| 1182 | static const void *net_current_ns(void) | 1182 | static void *net_grab_current_ns(void) |
| 1183 | { | 1183 | { |
| 1184 | return current->nsproxy->net_ns; | 1184 | struct net *ns = current->nsproxy->net_ns; |
| 1185 | #ifdef CONFIG_NET_NS | ||
| 1186 | if (ns) | ||
| 1187 | atomic_inc(&ns->passive); | ||
| 1188 | #endif | ||
| 1189 | return ns; | ||
| 1185 | } | 1190 | } |
| 1186 | 1191 | ||
| 1187 | static const void *net_initial_ns(void) | 1192 | static const void *net_initial_ns(void) |
| @@ -1196,22 +1201,13 @@ static const void *net_netlink_ns(struct sock *sk) | |||
| 1196 | 1201 | ||
| 1197 | struct kobj_ns_type_operations net_ns_type_operations = { | 1202 | struct kobj_ns_type_operations net_ns_type_operations = { |
| 1198 | .type = KOBJ_NS_TYPE_NET, | 1203 | .type = KOBJ_NS_TYPE_NET, |
| 1199 | .current_ns = net_current_ns, | 1204 | .grab_current_ns = net_grab_current_ns, |
| 1200 | .netlink_ns = net_netlink_ns, | 1205 | .netlink_ns = net_netlink_ns, |
| 1201 | .initial_ns = net_initial_ns, | 1206 | .initial_ns = net_initial_ns, |
| 1207 | .drop_ns = net_drop_ns, | ||
| 1202 | }; | 1208 | }; |
| 1203 | EXPORT_SYMBOL_GPL(net_ns_type_operations); | 1209 | EXPORT_SYMBOL_GPL(net_ns_type_operations); |
| 1204 | 1210 | ||
| 1205 | static void net_kobj_ns_exit(struct net *net) | ||
| 1206 | { | ||
| 1207 | kobj_ns_exit(KOBJ_NS_TYPE_NET, net); | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | static struct pernet_operations kobj_net_ops = { | ||
| 1211 | .exit = net_kobj_ns_exit, | ||
| 1212 | }; | ||
| 1213 | |||
| 1214 | |||
| 1215 | #ifdef CONFIG_HOTPLUG | 1211 | #ifdef CONFIG_HOTPLUG |
| 1216 | static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) | 1212 | static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) |
| 1217 | { | 1213 | { |
| @@ -1339,6 +1335,5 @@ EXPORT_SYMBOL(netdev_class_remove_file); | |||
| 1339 | int netdev_kobject_init(void) | 1335 | int netdev_kobject_init(void) |
| 1340 | { | 1336 | { |
| 1341 | kobj_ns_type_register(&net_ns_type_operations); | 1337 | kobj_ns_type_register(&net_ns_type_operations); |
| 1342 | register_pernet_subsys(&kobj_net_ops); | ||
| 1343 | return class_register(&net_class); | 1338 | return class_register(&net_class); |
| 1344 | } | 1339 | } |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 6c6b86d0da15..ea489db1bc23 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
| @@ -128,6 +128,7 @@ static __net_init int setup_net(struct net *net) | |||
| 128 | LIST_HEAD(net_exit_list); | 128 | LIST_HEAD(net_exit_list); |
| 129 | 129 | ||
| 130 | atomic_set(&net->count, 1); | 130 | atomic_set(&net->count, 1); |
| 131 | atomic_set(&net->passive, 1); | ||
| 131 | 132 | ||
| 132 | #ifdef NETNS_REFCNT_DEBUG | 133 | #ifdef NETNS_REFCNT_DEBUG |
| 133 | atomic_set(&net->use_count, 0); | 134 | atomic_set(&net->use_count, 0); |
| @@ -210,6 +211,13 @@ static void net_free(struct net *net) | |||
| 210 | kmem_cache_free(net_cachep, net); | 211 | kmem_cache_free(net_cachep, net); |
| 211 | } | 212 | } |
| 212 | 213 | ||
| 214 | void net_drop_ns(void *p) | ||
| 215 | { | ||
| 216 | struct net *ns = p; | ||
| 217 | if (ns && atomic_dec_and_test(&ns->passive)) | ||
| 218 | net_free(ns); | ||
| 219 | } | ||
| 220 | |||
| 213 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) | 221 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) |
| 214 | { | 222 | { |
| 215 | struct net *net; | 223 | struct net *net; |
| @@ -230,7 +238,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) | |||
| 230 | } | 238 | } |
| 231 | mutex_unlock(&net_mutex); | 239 | mutex_unlock(&net_mutex); |
| 232 | if (rv < 0) { | 240 | if (rv < 0) { |
| 233 | net_free(net); | 241 | net_drop_ns(net); |
| 234 | return ERR_PTR(rv); | 242 | return ERR_PTR(rv); |
| 235 | } | 243 | } |
| 236 | return net; | 244 | return net; |
| @@ -286,7 +294,7 @@ static void cleanup_net(struct work_struct *work) | |||
| 286 | /* Finally it is safe to free my network namespace structure */ | 294 | /* Finally it is safe to free my network namespace structure */ |
| 287 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { | 295 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { |
| 288 | list_del_init(&net->exit_list); | 296 | list_del_init(&net->exit_list); |
| 289 | net_free(net); | 297 | net_drop_ns(net); |
| 290 | } | 298 | } |
| 291 | } | 299 | } |
| 292 | static DECLARE_WORK(net_cleanup_work, cleanup_net); | 300 | static DECLARE_WORK(net_cleanup_work, cleanup_net); |
| @@ -310,19 +318,17 @@ struct net *get_net_ns_by_fd(int fd) | |||
| 310 | struct file *file; | 318 | struct file *file; |
| 311 | struct net *net; | 319 | struct net *net; |
| 312 | 320 | ||
| 313 | net = ERR_PTR(-EINVAL); | ||
| 314 | file = proc_ns_fget(fd); | 321 | file = proc_ns_fget(fd); |
| 315 | if (!file) | 322 | if (IS_ERR(file)) |
| 316 | goto out; | 323 | return ERR_CAST(file); |
| 317 | 324 | ||
| 318 | ei = PROC_I(file->f_dentry->d_inode); | 325 | ei = PROC_I(file->f_dentry->d_inode); |
| 319 | if (ei->ns_ops != &netns_operations) | 326 | if (ei->ns_ops == &netns_operations) |
| 320 | goto out; | 327 | net = get_net(ei->ns); |
| 328 | else | ||
| 329 | net = ERR_PTR(-EINVAL); | ||
| 321 | 330 | ||
| 322 | net = get_net(ei->ns); | 331 | fput(file); |
| 323 | out: | ||
| 324 | if (file) | ||
| 325 | fput(file); | ||
| 326 | return net; | 332 | return net; |
| 327 | } | 333 | } |
| 328 | 334 | ||
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 2d7d6d473781..18d9cbda3a39 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -792,6 +792,13 @@ int netpoll_setup(struct netpoll *np) | |||
| 792 | return -ENODEV; | 792 | return -ENODEV; |
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | if (ndev->master) { | ||
| 796 | printk(KERN_ERR "%s: %s is a slave device, aborting.\n", | ||
| 797 | np->name, np->dev_name); | ||
| 798 | err = -EBUSY; | ||
| 799 | goto put; | ||
| 800 | } | ||
| 801 | |||
| 795 | if (!netif_running(ndev)) { | 802 | if (!netif_running(ndev)) { |
| 796 | unsigned long atmost, atleast; | 803 | unsigned long atmost, atleast; |
| 797 | 804 | ||
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index ed0eab39f531..02548b292b53 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c | |||
| @@ -44,7 +44,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid, | |||
| 44 | pr_debug("%s\n", __func__); | 44 | pr_debug("%s\n", __func__); |
| 45 | 45 | ||
| 46 | if (!buf) | 46 | if (!buf) |
| 47 | goto out; | 47 | return -EMSGSIZE; |
| 48 | 48 | ||
| 49 | hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags, | 49 | hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags, |
| 50 | IEEE802154_LIST_PHY); | 50 | IEEE802154_LIST_PHY); |
| @@ -65,6 +65,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid, | |||
| 65 | pages * sizeof(uint32_t), buf); | 65 | pages * sizeof(uint32_t), buf); |
| 66 | 66 | ||
| 67 | mutex_unlock(&phy->pib_lock); | 67 | mutex_unlock(&phy->pib_lock); |
| 68 | kfree(buf); | ||
| 68 | return genlmsg_end(msg, hdr); | 69 | return genlmsg_end(msg, hdr); |
| 69 | 70 | ||
| 70 | nla_put_failure: | 71 | nla_put_failure: |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index cc1463156cd0..ef1528af7abf 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -465,6 +465,11 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 465 | if (addr_len < sizeof(struct sockaddr_in)) | 465 | if (addr_len < sizeof(struct sockaddr_in)) |
| 466 | goto out; | 466 | goto out; |
| 467 | 467 | ||
| 468 | if (addr->sin_family != AF_INET) { | ||
| 469 | err = -EAFNOSUPPORT; | ||
| 470 | goto out; | ||
| 471 | } | ||
| 472 | |||
| 468 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); | 473 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); |
| 469 | 474 | ||
| 470 | /* Not specified by any standard per-se, however it breaks too | 475 | /* Not specified by any standard per-se, however it breaks too |
| @@ -673,6 +678,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 673 | 678 | ||
| 674 | lock_sock(sk2); | 679 | lock_sock(sk2); |
| 675 | 680 | ||
| 681 | sock_rps_record_flow(sk2); | ||
| 676 | WARN_ON(!((1 << sk2->sk_state) & | 682 | WARN_ON(!((1 << sk2->sk_state) & |
| 677 | (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE))); | 683 | (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE))); |
| 678 | 684 | ||
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 6ffe94ca5bc9..3267d3898437 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -437,7 +437,7 @@ static int valid_cc(const void *bc, int len, int cc) | |||
| 437 | return 0; | 437 | return 0; |
| 438 | if (cc == len) | 438 | if (cc == len) |
| 439 | return 1; | 439 | return 1; |
| 440 | if (op->yes < 4) | 440 | if (op->yes < 4 || op->yes & 3) |
| 441 | return 0; | 441 | return 0; |
| 442 | len -= op->yes; | 442 | len -= op->yes; |
| 443 | bc += op->yes; | 443 | bc += op->yes; |
| @@ -447,11 +447,11 @@ static int valid_cc(const void *bc, int len, int cc) | |||
| 447 | 447 | ||
| 448 | static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) | 448 | static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) |
| 449 | { | 449 | { |
| 450 | const unsigned char *bc = bytecode; | 450 | const void *bc = bytecode; |
| 451 | int len = bytecode_len; | 451 | int len = bytecode_len; |
| 452 | 452 | ||
| 453 | while (len > 0) { | 453 | while (len > 0) { |
| 454 | struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)bc; | 454 | const struct inet_diag_bc_op *op = bc; |
| 455 | 455 | ||
| 456 | //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); | 456 | //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); |
| 457 | switch (op->code) { | 457 | switch (op->code) { |
| @@ -462,22 +462,20 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) | |||
| 462 | case INET_DIAG_BC_S_LE: | 462 | case INET_DIAG_BC_S_LE: |
| 463 | case INET_DIAG_BC_D_GE: | 463 | case INET_DIAG_BC_D_GE: |
| 464 | case INET_DIAG_BC_D_LE: | 464 | case INET_DIAG_BC_D_LE: |
| 465 | if (op->yes < 4 || op->yes > len + 4) | ||
| 466 | return -EINVAL; | ||
| 467 | case INET_DIAG_BC_JMP: | 465 | case INET_DIAG_BC_JMP: |
| 468 | if (op->no < 4 || op->no > len + 4) | 466 | if (op->no < 4 || op->no > len + 4 || op->no & 3) |
| 469 | return -EINVAL; | 467 | return -EINVAL; |
| 470 | if (op->no < len && | 468 | if (op->no < len && |
| 471 | !valid_cc(bytecode, bytecode_len, len - op->no)) | 469 | !valid_cc(bytecode, bytecode_len, len - op->no)) |
| 472 | return -EINVAL; | 470 | return -EINVAL; |
| 473 | break; | 471 | break; |
| 474 | case INET_DIAG_BC_NOP: | 472 | case INET_DIAG_BC_NOP: |
| 475 | if (op->yes < 4 || op->yes > len + 4) | ||
| 476 | return -EINVAL; | ||
| 477 | break; | 473 | break; |
| 478 | default: | 474 | default: |
| 479 | return -EINVAL; | 475 | return -EINVAL; |
| 480 | } | 476 | } |
| 477 | if (op->yes < 4 || op->yes > len + 4 || op->yes & 3) | ||
| 478 | return -EINVAL; | ||
| 481 | bc += op->yes; | 479 | bc += op->yes; |
| 482 | len -= op->yes; | 480 | len -= op->yes; |
| 483 | } | 481 | } |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index c3118e1cd3bb..ec93335901dd 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
| 17 | #include <asm/unaligned.h> | ||
| 17 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
| 18 | #include <linux/ip.h> | 19 | #include <linux/ip.h> |
| 19 | #include <linux/icmp.h> | 20 | #include <linux/icmp.h> |
| @@ -350,7 +351,7 @@ int ip_options_compile(struct net *net, | |||
| 350 | goto error; | 351 | goto error; |
| 351 | } | 352 | } |
| 352 | if (optptr[2] <= optlen) { | 353 | if (optptr[2] <= optlen) { |
| 353 | __be32 *timeptr = NULL; | 354 | unsigned char *timeptr = NULL; |
| 354 | if (optptr[2]+3 > optptr[1]) { | 355 | if (optptr[2]+3 > optptr[1]) { |
| 355 | pp_ptr = optptr + 2; | 356 | pp_ptr = optptr + 2; |
| 356 | goto error; | 357 | goto error; |
| @@ -359,7 +360,7 @@ int ip_options_compile(struct net *net, | |||
| 359 | case IPOPT_TS_TSONLY: | 360 | case IPOPT_TS_TSONLY: |
| 360 | opt->ts = optptr - iph; | 361 | opt->ts = optptr - iph; |
| 361 | if (skb) | 362 | if (skb) |
| 362 | timeptr = (__be32*)&optptr[optptr[2]-1]; | 363 | timeptr = &optptr[optptr[2]-1]; |
| 363 | opt->ts_needtime = 1; | 364 | opt->ts_needtime = 1; |
| 364 | optptr[2] += 4; | 365 | optptr[2] += 4; |
| 365 | break; | 366 | break; |
| @@ -371,7 +372,7 @@ int ip_options_compile(struct net *net, | |||
| 371 | opt->ts = optptr - iph; | 372 | opt->ts = optptr - iph; |
| 372 | if (rt) { | 373 | if (rt) { |
| 373 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); | 374 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); |
| 374 | timeptr = (__be32*)&optptr[optptr[2]+3]; | 375 | timeptr = &optptr[optptr[2]+3]; |
| 375 | } | 376 | } |
| 376 | opt->ts_needaddr = 1; | 377 | opt->ts_needaddr = 1; |
| 377 | opt->ts_needtime = 1; | 378 | opt->ts_needtime = 1; |
| @@ -389,7 +390,7 @@ int ip_options_compile(struct net *net, | |||
| 389 | if (inet_addr_type(net, addr) == RTN_UNICAST) | 390 | if (inet_addr_type(net, addr) == RTN_UNICAST) |
| 390 | break; | 391 | break; |
| 391 | if (skb) | 392 | if (skb) |
| 392 | timeptr = (__be32*)&optptr[optptr[2]+3]; | 393 | timeptr = &optptr[optptr[2]+3]; |
| 393 | } | 394 | } |
| 394 | opt->ts_needtime = 1; | 395 | opt->ts_needtime = 1; |
| 395 | optptr[2] += 8; | 396 | optptr[2] += 8; |
| @@ -403,10 +404,10 @@ int ip_options_compile(struct net *net, | |||
| 403 | } | 404 | } |
| 404 | if (timeptr) { | 405 | if (timeptr) { |
| 405 | struct timespec tv; | 406 | struct timespec tv; |
| 406 | __be32 midtime; | 407 | u32 midtime; |
| 407 | getnstimeofday(&tv); | 408 | getnstimeofday(&tv); |
| 408 | midtime = htonl((tv.tv_sec % 86400) * MSEC_PER_SEC + tv.tv_nsec / NSEC_PER_MSEC); | 409 | midtime = (tv.tv_sec % 86400) * MSEC_PER_SEC + tv.tv_nsec / NSEC_PER_MSEC; |
| 409 | memcpy(timeptr, &midtime, sizeof(__be32)); | 410 | put_unaligned_be32(midtime, timeptr); |
| 410 | opt->is_changed = 1; | 411 | opt->is_changed = 1; |
| 411 | } | 412 | } |
| 412 | } else { | 413 | } else { |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 98af3697c718..84f26e8e6c60 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -799,9 +799,9 @@ static int __ip_append_data(struct sock *sk, | |||
| 799 | int csummode = CHECKSUM_NONE; | 799 | int csummode = CHECKSUM_NONE; |
| 800 | struct rtable *rt = (struct rtable *)cork->dst; | 800 | struct rtable *rt = (struct rtable *)cork->dst; |
| 801 | 801 | ||
| 802 | exthdrlen = transhdrlen ? rt->dst.header_len : 0; | 802 | skb = skb_peek_tail(queue); |
| 803 | length += exthdrlen; | 803 | |
| 804 | transhdrlen += exthdrlen; | 804 | exthdrlen = !skb ? rt->dst.header_len : 0; |
| 805 | mtu = cork->fragsize; | 805 | mtu = cork->fragsize; |
| 806 | 806 | ||
| 807 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); | 807 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); |
| @@ -825,12 +825,10 @@ static int __ip_append_data(struct sock *sk, | |||
| 825 | !exthdrlen) | 825 | !exthdrlen) |
| 826 | csummode = CHECKSUM_PARTIAL; | 826 | csummode = CHECKSUM_PARTIAL; |
| 827 | 827 | ||
| 828 | skb = skb_peek_tail(queue); | ||
| 829 | |||
| 830 | cork->length += length; | 828 | cork->length += length; |
| 831 | if (((length > mtu) || (skb && skb_is_gso(skb))) && | 829 | if (((length > mtu) || (skb && skb_is_gso(skb))) && |
| 832 | (sk->sk_protocol == IPPROTO_UDP) && | 830 | (sk->sk_protocol == IPPROTO_UDP) && |
| 833 | (rt->dst.dev->features & NETIF_F_UFO)) { | 831 | (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { |
| 834 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, | 832 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, |
| 835 | hh_len, fragheaderlen, transhdrlen, | 833 | hh_len, fragheaderlen, transhdrlen, |
| 836 | mtu, flags); | 834 | mtu, flags); |
| @@ -883,17 +881,16 @@ alloc_new_skb: | |||
| 883 | else | 881 | else |
| 884 | alloclen = fraglen; | 882 | alloclen = fraglen; |
| 885 | 883 | ||
| 884 | alloclen += exthdrlen; | ||
| 885 | |||
| 886 | /* The last fragment gets additional space at tail. | 886 | /* The last fragment gets additional space at tail. |
| 887 | * Note, with MSG_MORE we overallocate on fragments, | 887 | * Note, with MSG_MORE we overallocate on fragments, |
| 888 | * because we have no idea what fragment will be | 888 | * because we have no idea what fragment will be |
| 889 | * the last. | 889 | * the last. |
| 890 | */ | 890 | */ |
| 891 | if (datalen == length + fraggap) { | 891 | if (datalen == length + fraggap) |
| 892 | alloclen += rt->dst.trailer_len; | 892 | alloclen += rt->dst.trailer_len; |
| 893 | /* make sure mtu is not reached */ | 893 | |
| 894 | if (datalen > mtu - fragheaderlen - rt->dst.trailer_len) | ||
| 895 | datalen -= ALIGN(rt->dst.trailer_len, 8); | ||
| 896 | } | ||
| 897 | if (transhdrlen) { | 894 | if (transhdrlen) { |
| 898 | skb = sock_alloc_send_skb(sk, | 895 | skb = sock_alloc_send_skb(sk, |
| 899 | alloclen + hh_len + 15, | 896 | alloclen + hh_len + 15, |
| @@ -926,11 +923,11 @@ alloc_new_skb: | |||
| 926 | /* | 923 | /* |
| 927 | * Find where to start putting bytes. | 924 | * Find where to start putting bytes. |
| 928 | */ | 925 | */ |
| 929 | data = skb_put(skb, fraglen); | 926 | data = skb_put(skb, fraglen + exthdrlen); |
| 930 | skb_set_network_header(skb, exthdrlen); | 927 | skb_set_network_header(skb, exthdrlen); |
| 931 | skb->transport_header = (skb->network_header + | 928 | skb->transport_header = (skb->network_header + |
| 932 | fragheaderlen); | 929 | fragheaderlen); |
| 933 | data += fragheaderlen; | 930 | data += fragheaderlen + exthdrlen; |
| 934 | 931 | ||
| 935 | if (fraggap) { | 932 | if (fraggap) { |
| 936 | skb->csum = skb_copy_and_csum_bits( | 933 | skb->csum = skb_copy_and_csum_bits( |
| @@ -1064,7 +1061,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, | |||
| 1064 | */ | 1061 | */ |
| 1065 | *rtp = NULL; | 1062 | *rtp = NULL; |
| 1066 | cork->fragsize = inet->pmtudisc == IP_PMTUDISC_PROBE ? | 1063 | cork->fragsize = inet->pmtudisc == IP_PMTUDISC_PROBE ? |
| 1067 | rt->dst.dev->mtu : dst_mtu(rt->dst.path); | 1064 | rt->dst.dev->mtu : dst_mtu(&rt->dst); |
| 1068 | cork->dst = &rt->dst; | 1065 | cork->dst = &rt->dst; |
| 1069 | cork->length = 0; | 1066 | cork->length = 0; |
| 1070 | cork->tx_flags = ipc->tx_flags; | 1067 | cork->tx_flags = ipc->tx_flags; |
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 4614babdc45f..2e97e3ec1eb7 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
| @@ -17,51 +17,35 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
| 17 | const struct iphdr *iph = ip_hdr(skb); | 17 | const struct iphdr *iph = ip_hdr(skb); |
| 18 | struct rtable *rt; | 18 | struct rtable *rt; |
| 19 | struct flowi4 fl4 = {}; | 19 | struct flowi4 fl4 = {}; |
| 20 | unsigned long orefdst; | 20 | __be32 saddr = iph->saddr; |
| 21 | __u8 flags = 0; | ||
| 21 | unsigned int hh_len; | 22 | unsigned int hh_len; |
| 22 | unsigned int type; | ||
| 23 | 23 | ||
| 24 | type = inet_addr_type(net, iph->saddr); | 24 | if (!skb->sk && addr_type != RTN_LOCAL) { |
| 25 | if (skb->sk && inet_sk(skb->sk)->transparent) | 25 | if (addr_type == RTN_UNSPEC) |
| 26 | type = RTN_LOCAL; | 26 | addr_type = inet_addr_type(net, saddr); |
| 27 | if (addr_type == RTN_UNSPEC) | 27 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) |
| 28 | addr_type = type; | 28 | flags |= FLOWI_FLAG_ANYSRC; |
| 29 | else | ||
| 30 | saddr = 0; | ||
| 31 | } | ||
| 29 | 32 | ||
| 30 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause | 33 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause |
| 31 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. | 34 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. |
| 32 | */ | 35 | */ |
| 33 | if (addr_type == RTN_LOCAL) { | 36 | fl4.daddr = iph->daddr; |
| 34 | fl4.daddr = iph->daddr; | 37 | fl4.saddr = saddr; |
| 35 | if (type == RTN_LOCAL) | 38 | fl4.flowi4_tos = RT_TOS(iph->tos); |
| 36 | fl4.saddr = iph->saddr; | 39 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; |
| 37 | fl4.flowi4_tos = RT_TOS(iph->tos); | 40 | fl4.flowi4_mark = skb->mark; |
| 38 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; | 41 | fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; |
| 39 | fl4.flowi4_mark = skb->mark; | 42 | rt = ip_route_output_key(net, &fl4); |
| 40 | fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; | 43 | if (IS_ERR(rt)) |
| 41 | rt = ip_route_output_key(net, &fl4); | 44 | return -1; |
| 42 | if (IS_ERR(rt)) | ||
| 43 | return -1; | ||
| 44 | |||
| 45 | /* Drop old route. */ | ||
| 46 | skb_dst_drop(skb); | ||
| 47 | skb_dst_set(skb, &rt->dst); | ||
| 48 | } else { | ||
| 49 | /* non-local src, find valid iif to satisfy | ||
| 50 | * rp-filter when calling ip_route_input. */ | ||
| 51 | fl4.daddr = iph->saddr; | ||
| 52 | rt = ip_route_output_key(net, &fl4); | ||
| 53 | if (IS_ERR(rt)) | ||
| 54 | return -1; | ||
| 55 | 45 | ||
| 56 | orefdst = skb->_skb_refdst; | 46 | /* Drop old route. */ |
| 57 | if (ip_route_input(skb, iph->daddr, iph->saddr, | 47 | skb_dst_drop(skb); |
| 58 | RT_TOS(iph->tos), rt->dst.dev) != 0) { | 48 | skb_dst_set(skb, &rt->dst); |
| 59 | dst_release(&rt->dst); | ||
| 60 | return -1; | ||
| 61 | } | ||
| 62 | dst_release(&rt->dst); | ||
| 63 | refdst_drop(orefdst); | ||
| 64 | } | ||
| 65 | 49 | ||
| 66 | if (skb_dst(skb)->error) | 50 | if (skb_dst(skb)->error) |
| 67 | return -1; | 51 | return -1; |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index d2c1311cb28d..5c9b9d963918 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
| @@ -203,7 +203,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) | |||
| 203 | else | 203 | else |
| 204 | pmsg->outdev_name[0] = '\0'; | 204 | pmsg->outdev_name[0] = '\0'; |
| 205 | 205 | ||
| 206 | if (entry->indev && entry->skb->dev) { | 206 | if (entry->indev && entry->skb->dev && |
| 207 | entry->skb->mac_header != entry->skb->network_header) { | ||
| 207 | pmsg->hw_type = entry->skb->dev->type; | 208 | pmsg->hw_type = entry->skb->dev->type; |
| 208 | pmsg->hw_addrlen = dev_parse_header(entry->skb, | 209 | pmsg->hw_addrlen = dev_parse_header(entry->skb, |
| 209 | pmsg->hw_addr); | 210 | pmsg->hw_addr); |
| @@ -402,7 +403,8 @@ ipq_dev_drop(int ifindex) | |||
| 402 | static inline void | 403 | static inline void |
| 403 | __ipq_rcv_skb(struct sk_buff *skb) | 404 | __ipq_rcv_skb(struct sk_buff *skb) |
| 404 | { | 405 | { |
| 405 | int status, type, pid, flags, nlmsglen, skblen; | 406 | int status, type, pid, flags; |
| 407 | unsigned int nlmsglen, skblen; | ||
| 406 | struct nlmsghdr *nlh; | 408 | struct nlmsghdr *nlh; |
| 407 | 409 | ||
| 408 | skblen = skb->len; | 410 | skblen = skb->len; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 764743843503..24e556e83a3b 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
| @@ -566,7 +566,7 @@ check_entry(const struct ipt_entry *e, const char *name) | |||
| 566 | const struct xt_entry_target *t; | 566 | const struct xt_entry_target *t; |
| 567 | 567 | ||
| 568 | if (!ip_checkentry(&e->ip)) { | 568 | if (!ip_checkentry(&e->ip)) { |
| 569 | duprintf("ip check failed %p %s.\n", e, par->match->name); | 569 | duprintf("ip check failed %p %s.\n", e, name); |
| 570 | return -EINVAL; | 570 | return -EINVAL; |
| 571 | } | 571 | } |
| 572 | 572 | ||
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index d609ac3cb9a4..5c9e97c79017 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
| @@ -307,7 +307,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 307 | * error messages (RELATED) and information requests (see below) */ | 307 | * error messages (RELATED) and information requests (see below) */ |
| 308 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP && | 308 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP && |
| 309 | (ctinfo == IP_CT_RELATED || | 309 | (ctinfo == IP_CT_RELATED || |
| 310 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)) | 310 | ctinfo == IP_CT_RELATED_REPLY)) |
| 311 | return XT_CONTINUE; | 311 | return XT_CONTINUE; |
| 312 | 312 | ||
| 313 | /* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO, | 313 | /* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO, |
| @@ -321,12 +321,12 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 321 | ct->mark = hash; | 321 | ct->mark = hash; |
| 322 | break; | 322 | break; |
| 323 | case IP_CT_RELATED: | 323 | case IP_CT_RELATED: |
| 324 | case IP_CT_RELATED+IP_CT_IS_REPLY: | 324 | case IP_CT_RELATED_REPLY: |
| 325 | /* FIXME: we don't handle expectations at the | 325 | /* FIXME: we don't handle expectations at the |
| 326 | * moment. they can arrive on a different node than | 326 | * moment. they can arrive on a different node than |
| 327 | * the master connection (e.g. FTP passive mode) */ | 327 | * the master connection (e.g. FTP passive mode) */ |
| 328 | case IP_CT_ESTABLISHED: | 328 | case IP_CT_ESTABLISHED: |
| 329 | case IP_CT_ESTABLISHED+IP_CT_IS_REPLY: | 329 | case IP_CT_ESTABLISHED_REPLY: |
| 330 | break; | 330 | break; |
| 331 | default: | 331 | default: |
| 332 | break; | 332 | break; |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index d2ed9dc74ebc..9931152a78b5 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
| @@ -60,7 +60,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 60 | nat = nfct_nat(ct); | 60 | nat = nfct_nat(ct); |
| 61 | 61 | ||
| 62 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || | 62 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || |
| 63 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); | 63 | ctinfo == IP_CT_RELATED_REPLY)); |
| 64 | 64 | ||
| 65 | /* Source address is 0.0.0.0 - locally generated packet that is | 65 | /* Source address is 0.0.0.0 - locally generated packet that is |
| 66 | * probably not supposed to be masqueraded. | 66 | * probably not supposed to be masqueraded. |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 1ff79e557f96..51f13f8ec724 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
| @@ -40,7 +40,6 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
| 40 | struct iphdr *niph; | 40 | struct iphdr *niph; |
| 41 | const struct tcphdr *oth; | 41 | const struct tcphdr *oth; |
| 42 | struct tcphdr _otcph, *tcph; | 42 | struct tcphdr _otcph, *tcph; |
| 43 | unsigned int addr_type; | ||
| 44 | 43 | ||
| 45 | /* IP header checks: fragment. */ | 44 | /* IP header checks: fragment. */ |
| 46 | if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET)) | 45 | if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET)) |
| @@ -55,6 +54,9 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
| 55 | if (oth->rst) | 54 | if (oth->rst) |
| 56 | return; | 55 | return; |
| 57 | 56 | ||
| 57 | if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) | ||
| 58 | return; | ||
| 59 | |||
| 58 | /* Check checksum */ | 60 | /* Check checksum */ |
| 59 | if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP)) | 61 | if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP)) |
| 60 | return; | 62 | return; |
| @@ -101,19 +103,11 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
| 101 | nskb->csum_start = (unsigned char *)tcph - nskb->head; | 103 | nskb->csum_start = (unsigned char *)tcph - nskb->head; |
| 102 | nskb->csum_offset = offsetof(struct tcphdr, check); | 104 | nskb->csum_offset = offsetof(struct tcphdr, check); |
| 103 | 105 | ||
| 104 | addr_type = RTN_UNSPEC; | ||
| 105 | if (hook != NF_INET_FORWARD | ||
| 106 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
| 107 | || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED) | ||
| 108 | #endif | ||
| 109 | ) | ||
| 110 | addr_type = RTN_LOCAL; | ||
| 111 | |||
| 112 | /* ip_route_me_harder expects skb->dst to be set */ | 106 | /* ip_route_me_harder expects skb->dst to be set */ |
| 113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); | 107 | skb_dst_set_noref(nskb, skb_dst(oldskb)); |
| 114 | 108 | ||
| 115 | nskb->protocol = htons(ETH_P_IP); | 109 | nskb->protocol = htons(ETH_P_IP); |
| 116 | if (ip_route_me_harder(nskb, addr_type)) | 110 | if (ip_route_me_harder(nskb, RTN_UNSPEC)) |
| 117 | goto free_nskb; | 111 | goto free_nskb; |
| 118 | 112 | ||
| 119 | niph->ttl = ip4_dst_hoplimit(skb_dst(nskb)); | 113 | niph->ttl = ip4_dst_hoplimit(skb_dst(nskb)); |
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index af6e9c778345..2b57e52c746c 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
| @@ -25,7 +25,8 @@ MODULE_LICENSE("GPL"); | |||
| 25 | static inline bool match_ip(const struct sk_buff *skb, | 25 | static inline bool match_ip(const struct sk_buff *skb, |
| 26 | const struct ipt_ecn_info *einfo) | 26 | const struct ipt_ecn_info *einfo) |
| 27 | { | 27 | { |
| 28 | return (ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect; | 28 | return ((ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect) ^ |
| 29 | !!(einfo->invert & IPT_ECN_OP_MATCH_IP); | ||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | static inline bool match_tcp(const struct sk_buff *skb, | 32 | static inline bool match_tcp(const struct sk_buff *skb, |
| @@ -76,8 +77,6 @@ static bool ecn_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 76 | return false; | 77 | return false; |
| 77 | 78 | ||
| 78 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { | 79 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { |
| 79 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) | ||
| 80 | return false; | ||
| 81 | if (!match_tcp(skb, info, &par->hotdrop)) | 80 | if (!match_tcp(skb, info, &par->hotdrop)) |
| 82 | return false; | 81 | return false; |
| 83 | } | 82 | } |
| @@ -97,7 +96,7 @@ static int ecn_mt_check(const struct xt_mtchk_param *par) | |||
| 97 | return -EINVAL; | 96 | return -EINVAL; |
| 98 | 97 | ||
| 99 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && | 98 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && |
| 100 | ip->proto != IPPROTO_TCP) { | 99 | (ip->proto != IPPROTO_TCP || ip->invflags & IPT_INV_PROTO)) { |
| 101 | pr_info("cannot match TCP bits in rule for non-tcp packets\n"); | 100 | pr_info("cannot match TCP bits in rule for non-tcp packets\n"); |
| 102 | return -EINVAL; | 101 | return -EINVAL; |
| 103 | } | 102 | } |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 5a03c02af999..de9da21113a1 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
| @@ -101,7 +101,7 @@ static unsigned int ipv4_confirm(unsigned int hooknum, | |||
| 101 | 101 | ||
| 102 | /* This is where we call the helper: as the packet goes out. */ | 102 | /* This is where we call the helper: as the packet goes out. */ |
| 103 | ct = nf_ct_get(skb, &ctinfo); | 103 | ct = nf_ct_get(skb, &ctinfo); |
| 104 | if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) | 104 | if (!ct || ctinfo == IP_CT_RELATED_REPLY) |
| 105 | goto out; | 105 | goto out; |
| 106 | 106 | ||
| 107 | help = nfct_help(ct); | 107 | help = nfct_help(ct); |
| @@ -121,7 +121,9 @@ static unsigned int ipv4_confirm(unsigned int hooknum, | |||
| 121 | return ret; | 121 | return ret; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) { | 124 | /* adjust seqs for loopback traffic only in outgoing direction */ |
| 125 | if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) && | ||
| 126 | !nf_is_loopback_packet(skb)) { | ||
| 125 | typeof(nf_nat_seq_adjust_hook) seq_adjust; | 127 | typeof(nf_nat_seq_adjust_hook) seq_adjust; |
| 126 | 128 | ||
| 127 | seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); | 129 | seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 7404bde95994..ab5b27a2916f 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
| @@ -160,7 +160,7 @@ icmp_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, | |||
| 160 | /* Update skb to refer to this connection */ | 160 | /* Update skb to refer to this connection */ |
| 161 | skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general; | 161 | skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general; |
| 162 | skb->nfctinfo = *ctinfo; | 162 | skb->nfctinfo = *ctinfo; |
| 163 | return -NF_ACCEPT; | 163 | return NF_ACCEPT; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /* Small and modified version of icmp_rcv */ | 166 | /* Small and modified version of icmp_rcv */ |
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 9c71b2755ce3..3346de5d94d0 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
| @@ -433,7 +433,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, | |||
| 433 | 433 | ||
| 434 | /* Must be RELATED */ | 434 | /* Must be RELATED */ |
| 435 | NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED || | 435 | NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED || |
| 436 | skb->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY); | 436 | skb->nfctinfo == IP_CT_RELATED_REPLY); |
| 437 | 437 | ||
| 438 | /* Redirects on non-null nats must be dropped, else they'll | 438 | /* Redirects on non-null nats must be dropped, else they'll |
| 439 | start talking to each other without our translation, and be | 439 | start talking to each other without our translation, and be |
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 99cfa28b6d38..ebc5f8894f99 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
| @@ -160,7 +160,7 @@ static void nf_nat_csum(struct sk_buff *skb, const struct iphdr *iph, void *data | |||
| 160 | 160 | ||
| 161 | if (skb->ip_summed != CHECKSUM_PARTIAL) { | 161 | if (skb->ip_summed != CHECKSUM_PARTIAL) { |
| 162 | if (!(rt->rt_flags & RTCF_LOCAL) && | 162 | if (!(rt->rt_flags & RTCF_LOCAL) && |
| 163 | skb->dev->features & NETIF_F_V4_CSUM) { | 163 | (!skb->dev || skb->dev->features & NETIF_F_V4_CSUM)) { |
| 164 | skb->ip_summed = CHECKSUM_PARTIAL; | 164 | skb->ip_summed = CHECKSUM_PARTIAL; |
| 165 | skb->csum_start = skb_headroom(skb) + | 165 | skb->csum_start = skb_headroom(skb) + |
| 166 | skb_network_offset(skb) + | 166 | skb_network_offset(skb) + |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index 21c30426480b..733c9abc1cbd 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
| @@ -53,7 +53,7 @@ ipt_snat_target(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 53 | 53 | ||
| 54 | /* Connection must be valid and new. */ | 54 | /* Connection must be valid and new. */ |
| 55 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || | 55 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || |
| 56 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); | 56 | ctinfo == IP_CT_RELATED_REPLY)); |
| 57 | NF_CT_ASSERT(par->out != NULL); | 57 | NF_CT_ASSERT(par->out != NULL); |
| 58 | 58 | ||
| 59 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); | 59 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); |
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index 7317bdf1d457..483b76d042da 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c | |||
| @@ -116,7 +116,7 @@ nf_nat_fn(unsigned int hooknum, | |||
| 116 | 116 | ||
| 117 | switch (ctinfo) { | 117 | switch (ctinfo) { |
| 118 | case IP_CT_RELATED: | 118 | case IP_CT_RELATED: |
| 119 | case IP_CT_RELATED+IP_CT_IS_REPLY: | 119 | case IP_CT_RELATED_REPLY: |
| 120 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP) { | 120 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP) { |
| 121 | if (!nf_nat_icmp_reply_translation(ct, ctinfo, | 121 | if (!nf_nat_icmp_reply_translation(ct, ctinfo, |
| 122 | hooknum, skb)) | 122 | hooknum, skb)) |
| @@ -144,7 +144,7 @@ nf_nat_fn(unsigned int hooknum, | |||
| 144 | default: | 144 | default: |
| 145 | /* ESTABLISHED */ | 145 | /* ESTABLISHED */ |
| 146 | NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || | 146 | NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || |
| 147 | ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY)); | 147 | ctinfo == IP_CT_ESTABLISHED_REPLY); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | return nf_nat_packet(ct, ctinfo, hooknum, skb); | 150 | return nf_nat_packet(ct, ctinfo, hooknum, skb); |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 9aaa67165f42..39b403f854c6 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include <linux/proc_fs.h> | 41 | #include <linux/proc_fs.h> |
| 42 | #include <net/sock.h> | 42 | #include <net/sock.h> |
| 43 | #include <net/ping.h> | 43 | #include <net/ping.h> |
| 44 | #include <net/icmp.h> | ||
| 45 | #include <net/udp.h> | 44 | #include <net/udp.h> |
| 46 | #include <net/route.h> | 45 | #include <net/route.h> |
| 47 | #include <net/inet_common.h> | 46 | #include <net/inet_common.h> |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 52b0b956508b..aa13ef105110 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1316,6 +1316,23 @@ reject_redirect: | |||
| 1316 | ; | 1316 | ; |
| 1317 | } | 1317 | } |
| 1318 | 1318 | ||
| 1319 | static bool peer_pmtu_expired(struct inet_peer *peer) | ||
| 1320 | { | ||
| 1321 | unsigned long orig = ACCESS_ONCE(peer->pmtu_expires); | ||
| 1322 | |||
| 1323 | return orig && | ||
| 1324 | time_after_eq(jiffies, orig) && | ||
| 1325 | cmpxchg(&peer->pmtu_expires, orig, 0) == orig; | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | static bool peer_pmtu_cleaned(struct inet_peer *peer) | ||
| 1329 | { | ||
| 1330 | unsigned long orig = ACCESS_ONCE(peer->pmtu_expires); | ||
| 1331 | |||
| 1332 | return orig && | ||
| 1333 | cmpxchg(&peer->pmtu_expires, orig, 0) == orig; | ||
| 1334 | } | ||
| 1335 | |||
| 1319 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | 1336 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) |
| 1320 | { | 1337 | { |
| 1321 | struct rtable *rt = (struct rtable *)dst; | 1338 | struct rtable *rt = (struct rtable *)dst; |
| @@ -1331,14 +1348,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | |||
| 1331 | rt_genid(dev_net(dst->dev))); | 1348 | rt_genid(dev_net(dst->dev))); |
| 1332 | rt_del(hash, rt); | 1349 | rt_del(hash, rt); |
| 1333 | ret = NULL; | 1350 | ret = NULL; |
| 1334 | } else if (rt->peer && | 1351 | } else if (rt->peer && peer_pmtu_expired(rt->peer)) { |
| 1335 | rt->peer->pmtu_expires && | 1352 | dst_metric_set(dst, RTAX_MTU, rt->peer->pmtu_orig); |
| 1336 | time_after_eq(jiffies, rt->peer->pmtu_expires)) { | ||
| 1337 | unsigned long orig = rt->peer->pmtu_expires; | ||
| 1338 | |||
| 1339 | if (cmpxchg(&rt->peer->pmtu_expires, orig, 0) == orig) | ||
| 1340 | dst_metric_set(dst, RTAX_MTU, | ||
| 1341 | rt->peer->pmtu_orig); | ||
| 1342 | } | 1353 | } |
| 1343 | } | 1354 | } |
| 1344 | return ret; | 1355 | return ret; |
| @@ -1531,8 +1542,10 @@ unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph, | |||
| 1531 | 1542 | ||
| 1532 | static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer) | 1543 | static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer) |
| 1533 | { | 1544 | { |
| 1534 | unsigned long expires = peer->pmtu_expires; | 1545 | unsigned long expires = ACCESS_ONCE(peer->pmtu_expires); |
| 1535 | 1546 | ||
| 1547 | if (!expires) | ||
| 1548 | return; | ||
| 1536 | if (time_before(jiffies, expires)) { | 1549 | if (time_before(jiffies, expires)) { |
| 1537 | u32 orig_dst_mtu = dst_mtu(dst); | 1550 | u32 orig_dst_mtu = dst_mtu(dst); |
| 1538 | if (peer->pmtu_learned < orig_dst_mtu) { | 1551 | if (peer->pmtu_learned < orig_dst_mtu) { |
| @@ -1555,10 +1568,11 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
| 1555 | rt_bind_peer(rt, rt->rt_dst, 1); | 1568 | rt_bind_peer(rt, rt->rt_dst, 1); |
| 1556 | peer = rt->peer; | 1569 | peer = rt->peer; |
| 1557 | if (peer) { | 1570 | if (peer) { |
| 1571 | unsigned long pmtu_expires = ACCESS_ONCE(peer->pmtu_expires); | ||
| 1572 | |||
| 1558 | if (mtu < ip_rt_min_pmtu) | 1573 | if (mtu < ip_rt_min_pmtu) |
| 1559 | mtu = ip_rt_min_pmtu; | 1574 | mtu = ip_rt_min_pmtu; |
| 1560 | if (!peer->pmtu_expires || mtu < peer->pmtu_learned) { | 1575 | if (!pmtu_expires || mtu < peer->pmtu_learned) { |
| 1561 | unsigned long pmtu_expires; | ||
| 1562 | 1576 | ||
| 1563 | pmtu_expires = jiffies + ip_rt_mtu_expires; | 1577 | pmtu_expires = jiffies + ip_rt_mtu_expires; |
| 1564 | if (!pmtu_expires) | 1578 | if (!pmtu_expires) |
| @@ -1612,13 +1626,14 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | |||
| 1612 | rt_bind_peer(rt, rt->rt_dst, 0); | 1626 | rt_bind_peer(rt, rt->rt_dst, 0); |
| 1613 | 1627 | ||
| 1614 | peer = rt->peer; | 1628 | peer = rt->peer; |
| 1615 | if (peer && peer->pmtu_expires) | 1629 | if (peer) { |
| 1616 | check_peer_pmtu(dst, peer); | 1630 | check_peer_pmtu(dst, peer); |
| 1617 | 1631 | ||
| 1618 | if (peer && peer->redirect_learned.a4 && | 1632 | if (peer->redirect_learned.a4 && |
| 1619 | peer->redirect_learned.a4 != rt->rt_gateway) { | 1633 | peer->redirect_learned.a4 != rt->rt_gateway) { |
| 1620 | if (check_peer_redir(dst, peer)) | 1634 | if (check_peer_redir(dst, peer)) |
| 1621 | return NULL; | 1635 | return NULL; |
| 1636 | } | ||
| 1622 | } | 1637 | } |
| 1623 | 1638 | ||
| 1624 | rt->rt_peer_genid = rt_peer_genid(); | 1639 | rt->rt_peer_genid = rt_peer_genid(); |
| @@ -1649,14 +1664,8 @@ static void ipv4_link_failure(struct sk_buff *skb) | |||
| 1649 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); | 1664 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); |
| 1650 | 1665 | ||
| 1651 | rt = skb_rtable(skb); | 1666 | rt = skb_rtable(skb); |
| 1652 | if (rt && | 1667 | if (rt && rt->peer && peer_pmtu_cleaned(rt->peer)) |
| 1653 | rt->peer && | 1668 | dst_metric_set(&rt->dst, RTAX_MTU, rt->peer->pmtu_orig); |
| 1654 | rt->peer->pmtu_expires) { | ||
| 1655 | unsigned long orig = rt->peer->pmtu_expires; | ||
| 1656 | |||
| 1657 | if (cmpxchg(&rt->peer->pmtu_expires, orig, 0) == orig) | ||
| 1658 | dst_metric_set(&rt->dst, RTAX_MTU, rt->peer->pmtu_orig); | ||
| 1659 | } | ||
| 1660 | } | 1669 | } |
| 1661 | 1670 | ||
| 1662 | static int ip_rt_bug(struct sk_buff *skb) | 1671 | static int ip_rt_bug(struct sk_buff *skb) |
| @@ -1770,8 +1779,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, | |||
| 1770 | sizeof(u32) * RTAX_MAX); | 1779 | sizeof(u32) * RTAX_MAX); |
| 1771 | dst_init_metrics(&rt->dst, peer->metrics, false); | 1780 | dst_init_metrics(&rt->dst, peer->metrics, false); |
| 1772 | 1781 | ||
| 1773 | if (peer->pmtu_expires) | 1782 | check_peer_pmtu(&rt->dst, peer); |
| 1774 | check_peer_pmtu(&rt->dst, peer); | ||
| 1775 | if (peer->redirect_learned.a4 && | 1783 | if (peer->redirect_learned.a4 && |
| 1776 | peer->redirect_learned.a4 != rt->rt_gateway) { | 1784 | peer->redirect_learned.a4 != rt->rt_gateway) { |
| 1777 | rt->rt_gateway = peer->redirect_learned.a4; | 1785 | rt->rt_gateway = peer->redirect_learned.a4; |
| @@ -1894,9 +1902,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1894 | 1902 | ||
| 1895 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); | 1903 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); |
| 1896 | rth = rt_intern_hash(hash, rth, skb, dev->ifindex); | 1904 | rth = rt_intern_hash(hash, rth, skb, dev->ifindex); |
| 1897 | err = 0; | 1905 | return IS_ERR(rth) ? PTR_ERR(rth) : 0; |
| 1898 | if (IS_ERR(rth)) | ||
| 1899 | err = PTR_ERR(rth); | ||
| 1900 | 1906 | ||
| 1901 | e_nobufs: | 1907 | e_nobufs: |
| 1902 | return -ENOBUFS; | 1908 | return -ENOBUFS; |
| @@ -2775,7 +2781,8 @@ static int rt_fill_info(struct net *net, | |||
| 2775 | struct rtable *rt = skb_rtable(skb); | 2781 | struct rtable *rt = skb_rtable(skb); |
| 2776 | struct rtmsg *r; | 2782 | struct rtmsg *r; |
| 2777 | struct nlmsghdr *nlh; | 2783 | struct nlmsghdr *nlh; |
| 2778 | long expires; | 2784 | long expires = 0; |
| 2785 | const struct inet_peer *peer = rt->peer; | ||
| 2779 | u32 id = 0, ts = 0, tsage = 0, error; | 2786 | u32 id = 0, ts = 0, tsage = 0, error; |
| 2780 | 2787 | ||
| 2781 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); | 2788 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); |
| @@ -2823,15 +2830,16 @@ static int rt_fill_info(struct net *net, | |||
| 2823 | NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark); | 2830 | NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark); |
| 2824 | 2831 | ||
| 2825 | error = rt->dst.error; | 2832 | error = rt->dst.error; |
| 2826 | expires = (rt->peer && rt->peer->pmtu_expires) ? | 2833 | if (peer) { |
| 2827 | rt->peer->pmtu_expires - jiffies : 0; | ||
| 2828 | if (rt->peer) { | ||
| 2829 | inet_peer_refcheck(rt->peer); | 2834 | inet_peer_refcheck(rt->peer); |
| 2830 | id = atomic_read(&rt->peer->ip_id_count) & 0xffff; | 2835 | id = atomic_read(&peer->ip_id_count) & 0xffff; |
| 2831 | if (rt->peer->tcp_ts_stamp) { | 2836 | if (peer->tcp_ts_stamp) { |
| 2832 | ts = rt->peer->tcp_ts; | 2837 | ts = peer->tcp_ts; |
| 2833 | tsage = get_seconds() - rt->peer->tcp_ts_stamp; | 2838 | tsage = get_seconds() - peer->tcp_ts_stamp; |
| 2834 | } | 2839 | } |
| 2840 | expires = ACCESS_ONCE(peer->pmtu_expires); | ||
| 2841 | if (expires) | ||
| 2842 | expires -= jiffies; | ||
| 2835 | } | 2843 | } |
| 2836 | 2844 | ||
| 2837 | if (rt_is_input_route(rt)) { | 2845 | if (rt_is_input_route(rt)) { |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 054a59d21eb0..46febcacb729 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -3220,7 +3220,7 @@ __setup("thash_entries=", set_thash_entries); | |||
| 3220 | void __init tcp_init(void) | 3220 | void __init tcp_init(void) |
| 3221 | { | 3221 | { |
| 3222 | struct sk_buff *skb = NULL; | 3222 | struct sk_buff *skb = NULL; |
| 3223 | unsigned long nr_pages, limit; | 3223 | unsigned long limit; |
| 3224 | int i, max_share, cnt; | 3224 | int i, max_share, cnt; |
| 3225 | unsigned long jiffy = jiffies; | 3225 | unsigned long jiffy = jiffies; |
| 3226 | 3226 | ||
| @@ -3277,13 +3277,7 @@ void __init tcp_init(void) | |||
| 3277 | sysctl_tcp_max_orphans = cnt / 2; | 3277 | sysctl_tcp_max_orphans = cnt / 2; |
| 3278 | sysctl_max_syn_backlog = max(128, cnt / 256); | 3278 | sysctl_max_syn_backlog = max(128, cnt / 256); |
| 3279 | 3279 | ||
| 3280 | /* Set the pressure threshold to be a fraction of global memory that | 3280 | limit = nr_free_buffer_pages() / 8; |
| 3281 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | ||
| 3282 | * memory, with a floor of 128 pages. | ||
| 3283 | */ | ||
| 3284 | nr_pages = totalram_pages - totalhigh_pages; | ||
| 3285 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | ||
| 3286 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
| 3287 | limit = max(limit, 128UL); | 3281 | limit = max(limit, 128UL); |
| 3288 | sysctl_tcp_mem[0] = limit / 4 * 3; | 3282 | sysctl_tcp_mem[0] = limit / 4 * 3; |
| 3289 | sysctl_tcp_mem[1] = limit; | 3283 | sysctl_tcp_mem[1] = limit; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a7d6671e33b8..708dc203b034 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1589,6 +1589,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1589 | goto discard; | 1589 | goto discard; |
| 1590 | 1590 | ||
| 1591 | if (nsk != sk) { | 1591 | if (nsk != sk) { |
| 1592 | sock_rps_save_rxhash(nsk, skb->rxhash); | ||
| 1592 | if (tcp_child_process(sk, nsk, skb)) { | 1593 | if (tcp_child_process(sk, nsk, skb)) { |
| 1593 | rsk = nsk; | 1594 | rsk = nsk; |
| 1594 | goto reset; | 1595 | goto reset; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index abca870d8ff6..198f75b7bdd3 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -1249,6 +1249,9 @@ csum_copy_err: | |||
| 1249 | 1249 | ||
| 1250 | if (noblock) | 1250 | if (noblock) |
| 1251 | return -EAGAIN; | 1251 | return -EAGAIN; |
| 1252 | |||
| 1253 | /* starting over for a new packet */ | ||
| 1254 | msg->msg_flags &= ~MSG_TRUNC; | ||
| 1252 | goto try_again; | 1255 | goto try_again; |
| 1253 | } | 1256 | } |
| 1254 | 1257 | ||
| @@ -2206,16 +2209,10 @@ void __init udp_table_init(struct udp_table *table, const char *name) | |||
| 2206 | 2209 | ||
| 2207 | void __init udp_init(void) | 2210 | void __init udp_init(void) |
| 2208 | { | 2211 | { |
| 2209 | unsigned long nr_pages, limit; | 2212 | unsigned long limit; |
| 2210 | 2213 | ||
| 2211 | udp_table_init(&udp_table, "UDP"); | 2214 | udp_table_init(&udp_table, "UDP"); |
| 2212 | /* Set the pressure threshold up by the same strategy of TCP. It is a | 2215 | limit = nr_free_buffer_pages() / 8; |
| 2213 | * fraction of global memory that is up to 1/2 at 256 MB, decreasing | ||
| 2214 | * toward zero with the amount of memory, with a floor of 128 pages. | ||
| 2215 | */ | ||
| 2216 | nr_pages = totalram_pages - totalhigh_pages; | ||
| 2217 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | ||
| 2218 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
| 2219 | limit = max(limit, 128UL); | 2216 | limit = max(limit, 128UL); |
| 2220 | sysctl_udp_mem[0] = limit / 4 * 3; | 2217 | sysctl_udp_mem[0] = limit / 4 * 3; |
| 2221 | sysctl_udp_mem[1] = limit; | 2218 | sysctl_udp_mem[1] = limit; |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 2d51840e53a1..327a617d594c 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
| @@ -32,7 +32,12 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb) | |||
| 32 | dst = skb_dst(skb); | 32 | dst = skb_dst(skb); |
| 33 | mtu = dst_mtu(dst); | 33 | mtu = dst_mtu(dst); |
| 34 | if (skb->len > mtu) { | 34 | if (skb->len > mtu) { |
| 35 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); | 35 | if (skb->sk) |
| 36 | ip_local_error(skb->sk, EMSGSIZE, ip_hdr(skb)->daddr, | ||
| 37 | inet_sk(skb->sk)->inet_dport, mtu); | ||
| 38 | else | ||
| 39 | icmp_send(skb, ICMP_DEST_UNREACH, | ||
| 40 | ICMP_FRAG_NEEDED, htonl(mtu)); | ||
| 36 | ret = -EMSGSIZE; | 41 | ret = -EMSGSIZE; |
| 37 | } | 42 | } |
| 38 | out: | 43 | out: |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index b7919f901fbf..3b5669a2582d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -272,6 +272,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 272 | 272 | ||
| 273 | if (addr_len < SIN6_LEN_RFC2133) | 273 | if (addr_len < SIN6_LEN_RFC2133) |
| 274 | return -EINVAL; | 274 | return -EINVAL; |
| 275 | |||
| 276 | if (addr->sin6_family != AF_INET6) | ||
| 277 | return -EAFNOSUPPORT; | ||
| 278 | |||
| 275 | addr_type = ipv6_addr_type(&addr->sin6_addr); | 279 | addr_type = ipv6_addr_type(&addr->sin6_addr); |
| 276 | if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM) | 280 | if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM) |
| 277 | return -EINVAL; | 281 | return -EINVAL; |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 413ab0754e1f..249394863284 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
| @@ -204,7 +204,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) | |||
| 204 | else | 204 | else |
| 205 | pmsg->outdev_name[0] = '\0'; | 205 | pmsg->outdev_name[0] = '\0'; |
| 206 | 206 | ||
| 207 | if (entry->indev && entry->skb->dev) { | 207 | if (entry->indev && entry->skb->dev && |
| 208 | entry->skb->mac_header != entry->skb->network_header) { | ||
| 208 | pmsg->hw_type = entry->skb->dev->type; | 209 | pmsg->hw_type = entry->skb->dev->type; |
| 209 | pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr); | 210 | pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr); |
| 210 | } | 211 | } |
| @@ -403,7 +404,8 @@ ipq_dev_drop(int ifindex) | |||
| 403 | static inline void | 404 | static inline void |
| 404 | __ipq_rcv_skb(struct sk_buff *skb) | 405 | __ipq_rcv_skb(struct sk_buff *skb) |
| 405 | { | 406 | { |
| 406 | int status, type, pid, flags, nlmsglen, skblen; | 407 | int status, type, pid, flags; |
| 408 | unsigned int nlmsglen, skblen; | ||
| 407 | struct nlmsghdr *nlh; | 409 | struct nlmsghdr *nlh; |
| 408 | 410 | ||
| 409 | skblen = skb->len; | 411 | skblen = skb->len; |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index c8af58b22562..4111050a9fc5 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
| @@ -160,7 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
| 160 | 160 | ||
| 161 | /* This is where we call the helper: as the packet goes out. */ | 161 | /* This is where we call the helper: as the packet goes out. */ |
| 162 | ct = nf_ct_get(skb, &ctinfo); | 162 | ct = nf_ct_get(skb, &ctinfo); |
| 163 | if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) | 163 | if (!ct || ctinfo == IP_CT_RELATED_REPLY) |
| 164 | goto out; | 164 | goto out; |
| 165 | 165 | ||
| 166 | help = nfct_help(ct); | 166 | help = nfct_help(ct); |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 1df3c8b6bf47..7c05e7eacbc6 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
| @@ -177,7 +177,7 @@ icmpv6_error_message(struct net *net, struct nf_conn *tmpl, | |||
| 177 | /* Update skb to refer to this connection */ | 177 | /* Update skb to refer to this connection */ |
| 178 | skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general; | 178 | skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general; |
| 179 | skb->nfctinfo = *ctinfo; | 179 | skb->nfctinfo = *ctinfo; |
| 180 | return -NF_ACCEPT; | 180 | return NF_ACCEPT; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | static int | 183 | static int |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index de2b1decd786..0ef1f086feb8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -228,9 +228,10 @@ static struct rt6_info ip6_blk_hole_entry_template = { | |||
| 228 | 228 | ||
| 229 | /* allocate dst with ip6_dst_ops */ | 229 | /* allocate dst with ip6_dst_ops */ |
| 230 | static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, | 230 | static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, |
| 231 | struct net_device *dev) | 231 | struct net_device *dev, |
| 232 | int flags) | ||
| 232 | { | 233 | { |
| 233 | struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, 0); | 234 | struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags); |
| 234 | 235 | ||
| 235 | memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); | 236 | memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); |
| 236 | 237 | ||
| @@ -1042,7 +1043,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
| 1042 | if (unlikely(idev == NULL)) | 1043 | if (unlikely(idev == NULL)) |
| 1043 | return NULL; | 1044 | return NULL; |
| 1044 | 1045 | ||
| 1045 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev); | 1046 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); |
| 1046 | if (unlikely(rt == NULL)) { | 1047 | if (unlikely(rt == NULL)) { |
| 1047 | in6_dev_put(idev); | 1048 | in6_dev_put(idev); |
| 1048 | goto out; | 1049 | goto out; |
| @@ -1062,14 +1063,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
| 1062 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); | 1063 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); |
| 1063 | rt->dst.output = ip6_output; | 1064 | rt->dst.output = ip6_output; |
| 1064 | 1065 | ||
| 1065 | #if 0 /* there's no chance to use these for ndisc */ | ||
| 1066 | rt->dst.flags = ipv6_addr_type(addr) & IPV6_ADDR_UNICAST | ||
| 1067 | ? DST_HOST | ||
| 1068 | : 0; | ||
| 1069 | ipv6_addr_copy(&rt->rt6i_dst.addr, addr); | ||
| 1070 | rt->rt6i_dst.plen = 128; | ||
| 1071 | #endif | ||
| 1072 | |||
| 1073 | spin_lock_bh(&icmp6_dst_lock); | 1066 | spin_lock_bh(&icmp6_dst_lock); |
| 1074 | rt->dst.next = icmp6_dst_gc_list; | 1067 | rt->dst.next = icmp6_dst_gc_list; |
| 1075 | icmp6_dst_gc_list = &rt->dst; | 1068 | icmp6_dst_gc_list = &rt->dst; |
| @@ -1214,7 +1207,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
| 1214 | goto out; | 1207 | goto out; |
| 1215 | } | 1208 | } |
| 1216 | 1209 | ||
| 1217 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL); | 1210 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT); |
| 1218 | 1211 | ||
| 1219 | if (rt == NULL) { | 1212 | if (rt == NULL) { |
| 1220 | err = -ENOMEM; | 1213 | err = -ENOMEM; |
| @@ -1244,7 +1237,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
| 1244 | ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len); | 1237 | ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len); |
| 1245 | rt->rt6i_dst.plen = cfg->fc_dst_len; | 1238 | rt->rt6i_dst.plen = cfg->fc_dst_len; |
| 1246 | if (rt->rt6i_dst.plen == 128) | 1239 | if (rt->rt6i_dst.plen == 128) |
| 1247 | rt->dst.flags = DST_HOST; | 1240 | rt->dst.flags |= DST_HOST; |
| 1248 | 1241 | ||
| 1249 | #ifdef CONFIG_IPV6_SUBTREES | 1242 | #ifdef CONFIG_IPV6_SUBTREES |
| 1250 | ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len); | 1243 | ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len); |
| @@ -1734,7 +1727,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) | |||
| 1734 | { | 1727 | { |
| 1735 | struct net *net = dev_net(ort->rt6i_dev); | 1728 | struct net *net = dev_net(ort->rt6i_dev); |
| 1736 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, | 1729 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, |
| 1737 | ort->dst.dev); | 1730 | ort->dst.dev, 0); |
| 1738 | 1731 | ||
| 1739 | if (rt) { | 1732 | if (rt) { |
| 1740 | rt->dst.input = ort->dst.input; | 1733 | rt->dst.input = ort->dst.input; |
| @@ -2013,7 +2006,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
| 2013 | { | 2006 | { |
| 2014 | struct net *net = dev_net(idev->dev); | 2007 | struct net *net = dev_net(idev->dev); |
| 2015 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, | 2008 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, |
| 2016 | net->loopback_dev); | 2009 | net->loopback_dev, 0); |
| 2017 | struct neighbour *neigh; | 2010 | struct neighbour *neigh; |
| 2018 | 2011 | ||
| 2019 | if (rt == NULL) { | 2012 | if (rt == NULL) { |
| @@ -2025,7 +2018,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
| 2025 | 2018 | ||
| 2026 | in6_dev_hold(idev); | 2019 | in6_dev_hold(idev); |
| 2027 | 2020 | ||
| 2028 | rt->dst.flags = DST_HOST; | 2021 | rt->dst.flags |= DST_HOST; |
| 2029 | rt->dst.input = ip6_input; | 2022 | rt->dst.input = ip6_input; |
| 2030 | rt->dst.output = ip6_output; | 2023 | rt->dst.output = ip6_output; |
| 2031 | rt->rt6i_idev = idev; | 2024 | rt->rt6i_idev = idev; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index d1fd28711ba5..87551ca568cd 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1644,6 +1644,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1644 | * the new socket.. | 1644 | * the new socket.. |
| 1645 | */ | 1645 | */ |
| 1646 | if(nsk != sk) { | 1646 | if(nsk != sk) { |
| 1647 | sock_rps_save_rxhash(nsk, skb->rxhash); | ||
| 1647 | if (tcp_child_process(sk, nsk, skb)) | 1648 | if (tcp_child_process(sk, nsk, skb)) |
| 1648 | goto reset; | 1649 | goto reset; |
| 1649 | if (opt_skb) | 1650 | if (opt_skb) |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 41f8c9c08dba..328985c40883 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -453,8 +453,11 @@ csum_copy_err: | |||
| 453 | } | 453 | } |
| 454 | unlock_sock_fast(sk, slow); | 454 | unlock_sock_fast(sk, slow); |
| 455 | 455 | ||
| 456 | if (flags & MSG_DONTWAIT) | 456 | if (noblock) |
| 457 | return -EAGAIN; | 457 | return -EAGAIN; |
| 458 | |||
| 459 | /* starting over for a new packet */ | ||
| 460 | msg->msg_flags &= ~MSG_TRUNC; | ||
| 458 | goto try_again; | 461 | goto try_again; |
| 459 | } | 462 | } |
| 460 | 463 | ||
diff --git a/net/irda/iriap.c b/net/irda/iriap.c index 36477538cea8..f876eed7d4aa 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c | |||
| @@ -87,6 +87,8 @@ static inline void iriap_start_watchdog_timer(struct iriap_cb *self, | |||
| 87 | iriap_watchdog_timer_expired); | 87 | iriap_watchdog_timer_expired); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static struct lock_class_key irias_objects_key; | ||
| 91 | |||
| 90 | /* | 92 | /* |
| 91 | * Function iriap_init (void) | 93 | * Function iriap_init (void) |
| 92 | * | 94 | * |
| @@ -114,6 +116,9 @@ int __init iriap_init(void) | |||
| 114 | return -ENOMEM; | 116 | return -ENOMEM; |
| 115 | } | 117 | } |
| 116 | 118 | ||
| 119 | lockdep_set_class_and_name(&irias_objects->hb_spinlock, &irias_objects_key, | ||
| 120 | "irias_objects"); | ||
| 121 | |||
| 117 | /* | 122 | /* |
| 118 | * Register some default services for IrLMP | 123 | * Register some default services for IrLMP |
| 119 | */ | 124 | */ |
diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c index b8dbae82fab8..76130134bfa6 100644 --- a/net/l2tp/l2tp_debugfs.c +++ b/net/l2tp/l2tp_debugfs.c | |||
| @@ -258,7 +258,7 @@ static int l2tp_dfs_seq_open(struct inode *inode, struct file *file) | |||
| 258 | */ | 258 | */ |
| 259 | pd->net = get_net_ns_by_pid(current->pid); | 259 | pd->net = get_net_ns_by_pid(current->pid); |
| 260 | if (IS_ERR(pd->net)) { | 260 | if (IS_ERR(pd->net)) { |
| 261 | rc = -PTR_ERR(pd->net); | 261 | rc = PTR_ERR(pd->net); |
| 262 | goto err_free_pd; | 262 | goto err_free_pd; |
| 263 | } | 263 | } |
| 264 | 264 | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 421eaa6b0c2b..56c24cabf26d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -965,6 +965,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
| 965 | 965 | ||
| 966 | mutex_lock(&sdata->u.ibss.mtx); | 966 | mutex_lock(&sdata->u.ibss.mtx); |
| 967 | 967 | ||
| 968 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; | ||
| 969 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); | ||
| 970 | sdata->u.ibss.ssid_len = 0; | ||
| 971 | |||
| 968 | active_ibss = ieee80211_sta_active_ibss(sdata); | 972 | active_ibss = ieee80211_sta_active_ibss(sdata); |
| 969 | 973 | ||
| 970 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { | 974 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { |
| @@ -999,8 +1003,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
| 999 | kfree_skb(skb); | 1003 | kfree_skb(skb); |
| 1000 | 1004 | ||
| 1001 | skb_queue_purge(&sdata->skb_queue); | 1005 | skb_queue_purge(&sdata->skb_queue); |
| 1002 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); | ||
| 1003 | sdata->u.ibss.ssid_len = 0; | ||
| 1004 | 1006 | ||
| 1005 | del_timer_sync(&sdata->u.ibss.timer); | 1007 | del_timer_sync(&sdata->u.ibss.timer); |
| 1006 | 1008 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 2025af52b195..090b0ec1e056 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -775,9 +775,6 @@ struct ieee80211_local { | |||
| 775 | 775 | ||
| 776 | int tx_headroom; /* required headroom for hardware/radiotap */ | 776 | int tx_headroom; /* required headroom for hardware/radiotap */ |
| 777 | 777 | ||
| 778 | /* count for keys needing tailroom space allocation */ | ||
| 779 | int crypto_tx_tailroom_needed_cnt; | ||
| 780 | |||
| 781 | /* Tasklet and skb queue to process calls from IRQ mode. All frames | 778 | /* Tasklet and skb queue to process calls from IRQ mode. All frames |
| 782 | * added to skb_queue will be processed, but frames in | 779 | * added to skb_queue will be processed, but frames in |
| 783 | * skb_queue_unreliable may be dropped if the total length of these | 780 | * skb_queue_unreliable may be dropped if the total length of these |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 49d4f869e0bc..dee30aea9ab3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -1145,6 +1145,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
| 1145 | + IEEE80211_ENCRYPT_HEADROOM; | 1145 | + IEEE80211_ENCRYPT_HEADROOM; |
| 1146 | ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; | 1146 | ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; |
| 1147 | 1147 | ||
| 1148 | ret = dev_alloc_name(ndev, ndev->name); | ||
| 1149 | if (ret < 0) | ||
| 1150 | goto fail; | ||
| 1151 | |||
| 1148 | ieee80211_assign_perm_addr(local, ndev, type); | 1152 | ieee80211_assign_perm_addr(local, ndev, type); |
| 1149 | memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); | 1153 | memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); |
| 1150 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 1154 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 31afd712930d..f825e2f0a57e 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
| @@ -101,11 +101,6 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
| 101 | 101 | ||
| 102 | if (!ret) { | 102 | if (!ret) { |
| 103 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 103 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
| 104 | |||
| 105 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | ||
| 106 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | ||
| 107 | key->local->crypto_tx_tailroom_needed_cnt--; | ||
| 108 | |||
| 109 | return 0; | 104 | return 0; |
| 110 | } | 105 | } |
| 111 | 106 | ||
| @@ -161,10 +156,6 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
| 161 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); | 156 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); |
| 162 | 157 | ||
| 163 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 158 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
| 164 | |||
| 165 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | ||
| 166 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | ||
| 167 | key->local->crypto_tx_tailroom_needed_cnt++; | ||
| 168 | } | 159 | } |
| 169 | 160 | ||
| 170 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) | 161 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) |
| @@ -403,10 +394,8 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
| 403 | ieee80211_aes_key_free(key->u.ccmp.tfm); | 394 | ieee80211_aes_key_free(key->u.ccmp.tfm); |
| 404 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) | 395 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) |
| 405 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | 396 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); |
| 406 | if (key->local) { | 397 | if (key->local) |
| 407 | ieee80211_debugfs_key_remove(key); | 398 | ieee80211_debugfs_key_remove(key); |
| 408 | key->local->crypto_tx_tailroom_needed_cnt--; | ||
| 409 | } | ||
| 410 | 399 | ||
| 411 | kfree(key); | 400 | kfree(key); |
| 412 | } | 401 | } |
| @@ -468,8 +457,6 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
| 468 | 457 | ||
| 469 | ieee80211_debugfs_key_add(key); | 458 | ieee80211_debugfs_key_add(key); |
| 470 | 459 | ||
| 471 | key->local->crypto_tx_tailroom_needed_cnt++; | ||
| 472 | |||
| 473 | ret = ieee80211_key_enable_hw_accel(key); | 460 | ret = ieee80211_key_enable_hw_accel(key); |
| 474 | 461 | ||
| 475 | mutex_unlock(&sdata->local->key_mtx); | 462 | mutex_unlock(&sdata->local->key_mtx); |
| @@ -511,12 +498,8 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | |||
| 511 | 498 | ||
| 512 | mutex_lock(&sdata->local->key_mtx); | 499 | mutex_lock(&sdata->local->key_mtx); |
| 513 | 500 | ||
| 514 | sdata->local->crypto_tx_tailroom_needed_cnt = 0; | 501 | list_for_each_entry(key, &sdata->key_list, list) |
| 515 | |||
| 516 | list_for_each_entry(key, &sdata->key_list, list) { | ||
| 517 | sdata->local->crypto_tx_tailroom_needed_cnt++; | ||
| 518 | ieee80211_key_enable_hw_accel(key); | 502 | ieee80211_key_enable_hw_accel(key); |
| 519 | } | ||
| 520 | 503 | ||
| 521 | mutex_unlock(&sdata->local->key_mtx); | 504 | mutex_unlock(&sdata->local->key_mtx); |
| 522 | } | 505 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4f6b2675e41d..d595265d6c22 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1089,6 +1089,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
| 1089 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | 1089 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; |
| 1090 | config_changed |= IEEE80211_CONF_CHANGE_PS; | 1090 | config_changed |= IEEE80211_CONF_CHANGE_PS; |
| 1091 | } | 1091 | } |
| 1092 | local->ps_sdata = NULL; | ||
| 1092 | 1093 | ||
| 1093 | ieee80211_hw_config(local, config_changed); | 1094 | ieee80211_hw_config(local, config_changed); |
| 1094 | 1095 | ||
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 27af6723cb5e..58ffa7d069c7 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <linux/if_arp.h> | 15 | #include <linux/if_arp.h> |
| 16 | #include <linux/rtnetlink.h> | 16 | #include <linux/rtnetlink.h> |
| 17 | #include <linux/pm_qos_params.h> | 17 | #include <linux/pm_qos_params.h> |
| 18 | #include <linux/slab.h> | ||
| 19 | #include <net/sch_generic.h> | 18 | #include <net/sch_generic.h> |
| 20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 21 | #include <net/mac80211.h> | 20 | #include <net/mac80211.h> |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 64e0f7587e6d..3104c844b544 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1480,7 +1480,12 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
| 1480 | { | 1480 | { |
| 1481 | int tail_need = 0; | 1481 | int tail_need = 0; |
| 1482 | 1482 | ||
| 1483 | if (may_encrypt && local->crypto_tx_tailroom_needed_cnt) { | 1483 | /* |
| 1484 | * This could be optimised, devices that do full hardware | ||
| 1485 | * crypto (including TKIP MMIC) need no tailroom... But we | ||
| 1486 | * have no drivers for such devices currently. | ||
| 1487 | */ | ||
| 1488 | if (may_encrypt) { | ||
| 1484 | tail_need = IEEE80211_ENCRYPT_TAILROOM; | 1489 | tail_need = IEEE80211_ENCRYPT_TAILROOM; |
| 1485 | tail_need -= skb_tailroom(skb); | 1490 | tail_need -= skb_tailroom(skb); |
| 1486 | tail_need = max_t(int, tail_need, 0); | 1491 | tail_need = max_t(int, tail_need, 0); |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 9dc3b5f26e80..d91c1a26630d 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
| @@ -154,7 +154,13 @@ update_iv: | |||
| 154 | return RX_CONTINUE; | 154 | return RX_CONTINUE; |
| 155 | 155 | ||
| 156 | mic_fail: | 156 | mic_fail: |
| 157 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | 157 | /* |
| 158 | * In some cases the key can be unset - e.g. a multicast packet, in | ||
| 159 | * a driver that supports HW encryption. Send up the key idx only if | ||
| 160 | * the key is set. | ||
| 161 | */ | ||
| 162 | mac80211_ev_michael_mic_failure(rx->sdata, | ||
| 163 | rx->key ? rx->key->conf.keyidx : -1, | ||
| 158 | (void *) skb->data, NULL, GFP_ATOMIC); | 164 | (void *) skb->data, NULL, GFP_ATOMIC); |
| 159 | return RX_DROP_UNUSABLE; | 165 | return RX_DROP_UNUSABLE; |
| 160 | } | 166 | } |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 8041befc6555..42aa64b6b0b1 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
| @@ -767,7 +767,7 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb, | |||
| 767 | if (!attr[IPSET_ATTR_SETNAME]) { | 767 | if (!attr[IPSET_ATTR_SETNAME]) { |
| 768 | for (i = 0; i < ip_set_max; i++) { | 768 | for (i = 0; i < ip_set_max; i++) { |
| 769 | if (ip_set_list[i] != NULL && ip_set_list[i]->ref) { | 769 | if (ip_set_list[i] != NULL && ip_set_list[i]->ref) { |
| 770 | ret = IPSET_ERR_BUSY; | 770 | ret = -IPSET_ERR_BUSY; |
| 771 | goto out; | 771 | goto out; |
| 772 | } | 772 | } |
| 773 | } | 773 | } |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index 4743e5402522..565a7c5b8818 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c | |||
| @@ -146,8 +146,9 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb, | |||
| 146 | { | 146 | { |
| 147 | const struct ip_set_hash *h = set->data; | 147 | const struct ip_set_hash *h = set->data; |
| 148 | ipset_adtfn adtfn = set->variant->adt[adt]; | 148 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 149 | struct hash_ipportnet4_elem data = | 149 | struct hash_ipportnet4_elem data = { |
| 150 | { .cidr = h->nets[0].cidr || HOST_MASK }; | 150 | .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK |
| 151 | }; | ||
| 151 | 152 | ||
| 152 | if (data.cidr == 0) | 153 | if (data.cidr == 0) |
| 153 | return -EINVAL; | 154 | return -EINVAL; |
| @@ -394,8 +395,9 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb, | |||
| 394 | { | 395 | { |
| 395 | const struct ip_set_hash *h = set->data; | 396 | const struct ip_set_hash *h = set->data; |
| 396 | ipset_adtfn adtfn = set->variant->adt[adt]; | 397 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 397 | struct hash_ipportnet6_elem data = | 398 | struct hash_ipportnet6_elem data = { |
| 398 | { .cidr = h->nets[0].cidr || HOST_MASK }; | 399 | .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK |
| 400 | }; | ||
| 399 | 401 | ||
| 400 | if (data.cidr == 0) | 402 | if (data.cidr == 0) |
| 401 | return -EINVAL; | 403 | return -EINVAL; |
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index c4db202b7da4..2aeeabcd5a21 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c | |||
| @@ -131,7 +131,9 @@ hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb, | |||
| 131 | { | 131 | { |
| 132 | const struct ip_set_hash *h = set->data; | 132 | const struct ip_set_hash *h = set->data; |
| 133 | ipset_adtfn adtfn = set->variant->adt[adt]; | 133 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 134 | struct hash_net4_elem data = { .cidr = h->nets[0].cidr || HOST_MASK }; | 134 | struct hash_net4_elem data = { |
| 135 | .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK | ||
| 136 | }; | ||
| 135 | 137 | ||
| 136 | if (data.cidr == 0) | 138 | if (data.cidr == 0) |
| 137 | return -EINVAL; | 139 | return -EINVAL; |
| @@ -296,7 +298,9 @@ hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb, | |||
| 296 | { | 298 | { |
| 297 | const struct ip_set_hash *h = set->data; | 299 | const struct ip_set_hash *h = set->data; |
| 298 | ipset_adtfn adtfn = set->variant->adt[adt]; | 300 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 299 | struct hash_net6_elem data = { .cidr = h->nets[0].cidr || HOST_MASK }; | 301 | struct hash_net6_elem data = { |
| 302 | .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK | ||
| 303 | }; | ||
| 300 | 304 | ||
| 301 | if (data.cidr == 0) | 305 | if (data.cidr == 0) |
| 302 | return -EINVAL; | 306 | return -EINVAL; |
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index d2a40362dd3a..e50d9bb8820b 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c | |||
| @@ -144,7 +144,8 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb, | |||
| 144 | const struct ip_set_hash *h = set->data; | 144 | const struct ip_set_hash *h = set->data; |
| 145 | ipset_adtfn adtfn = set->variant->adt[adt]; | 145 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 146 | struct hash_netport4_elem data = { | 146 | struct hash_netport4_elem data = { |
| 147 | .cidr = h->nets[0].cidr || HOST_MASK }; | 147 | .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK |
| 148 | }; | ||
| 148 | 149 | ||
| 149 | if (data.cidr == 0) | 150 | if (data.cidr == 0) |
| 150 | return -EINVAL; | 151 | return -EINVAL; |
| @@ -357,7 +358,8 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb, | |||
| 357 | const struct ip_set_hash *h = set->data; | 358 | const struct ip_set_hash *h = set->data; |
| 358 | ipset_adtfn adtfn = set->variant->adt[adt]; | 359 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 359 | struct hash_netport6_elem data = { | 360 | struct hash_netport6_elem data = { |
| 360 | .cidr = h->nets[0].cidr || HOST_MASK }; | 361 | .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK |
| 362 | }; | ||
| 361 | 363 | ||
| 362 | if (data.cidr == 0) | 364 | if (data.cidr == 0) |
| 363 | return -EINVAL; | 365 | return -EINVAL; |
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index bf28ac2fc99b..782db275ac53 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c | |||
| @@ -776,8 +776,16 @@ static void ip_vs_conn_expire(unsigned long data) | |||
| 776 | if (cp->control) | 776 | if (cp->control) |
| 777 | ip_vs_control_del(cp); | 777 | ip_vs_control_del(cp); |
| 778 | 778 | ||
| 779 | if (cp->flags & IP_VS_CONN_F_NFCT) | 779 | if (cp->flags & IP_VS_CONN_F_NFCT) { |
| 780 | ip_vs_conn_drop_conntrack(cp); | 780 | ip_vs_conn_drop_conntrack(cp); |
| 781 | /* Do not access conntracks during subsys cleanup | ||
| 782 | * because nf_conntrack_find_get can not be used after | ||
| 783 | * conntrack cleanup for the net. | ||
| 784 | */ | ||
| 785 | smp_rmb(); | ||
| 786 | if (ipvs->enable) | ||
| 787 | ip_vs_conn_drop_conntrack(cp); | ||
| 788 | } | ||
| 781 | 789 | ||
| 782 | ip_vs_pe_put(cp->pe); | 790 | ip_vs_pe_put(cp->pe); |
| 783 | kfree(cp->pe_data); | 791 | kfree(cp->pe_data); |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index bfa808f4da13..24c28d238dcb 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
| @@ -1772,7 +1772,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
| 1772 | .owner = THIS_MODULE, | 1772 | .owner = THIS_MODULE, |
| 1773 | .pf = PF_INET, | 1773 | .pf = PF_INET, |
| 1774 | .hooknum = NF_INET_LOCAL_IN, | 1774 | .hooknum = NF_INET_LOCAL_IN, |
| 1775 | .priority = 99, | 1775 | .priority = NF_IP_PRI_NAT_SRC - 2, |
| 1776 | }, | 1776 | }, |
| 1777 | /* After packet filtering, forward packet through VS/DR, VS/TUN, | 1777 | /* After packet filtering, forward packet through VS/DR, VS/TUN, |
| 1778 | * or VS/NAT(change destination), so that filtering rules can be | 1778 | * or VS/NAT(change destination), so that filtering rules can be |
| @@ -1782,7 +1782,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
| 1782 | .owner = THIS_MODULE, | 1782 | .owner = THIS_MODULE, |
| 1783 | .pf = PF_INET, | 1783 | .pf = PF_INET, |
| 1784 | .hooknum = NF_INET_LOCAL_IN, | 1784 | .hooknum = NF_INET_LOCAL_IN, |
| 1785 | .priority = 101, | 1785 | .priority = NF_IP_PRI_NAT_SRC - 1, |
| 1786 | }, | 1786 | }, |
| 1787 | /* Before ip_vs_in, change source only for VS/NAT */ | 1787 | /* Before ip_vs_in, change source only for VS/NAT */ |
| 1788 | { | 1788 | { |
| @@ -1790,7 +1790,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
| 1790 | .owner = THIS_MODULE, | 1790 | .owner = THIS_MODULE, |
| 1791 | .pf = PF_INET, | 1791 | .pf = PF_INET, |
| 1792 | .hooknum = NF_INET_LOCAL_OUT, | 1792 | .hooknum = NF_INET_LOCAL_OUT, |
| 1793 | .priority = -99, | 1793 | .priority = NF_IP_PRI_NAT_DST + 1, |
| 1794 | }, | 1794 | }, |
| 1795 | /* After mangle, schedule and forward local requests */ | 1795 | /* After mangle, schedule and forward local requests */ |
| 1796 | { | 1796 | { |
| @@ -1798,7 +1798,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
| 1798 | .owner = THIS_MODULE, | 1798 | .owner = THIS_MODULE, |
| 1799 | .pf = PF_INET, | 1799 | .pf = PF_INET, |
| 1800 | .hooknum = NF_INET_LOCAL_OUT, | 1800 | .hooknum = NF_INET_LOCAL_OUT, |
| 1801 | .priority = -98, | 1801 | .priority = NF_IP_PRI_NAT_DST + 2, |
| 1802 | }, | 1802 | }, |
| 1803 | /* After packet filtering (but before ip_vs_out_icmp), catch icmp | 1803 | /* After packet filtering (but before ip_vs_out_icmp), catch icmp |
| 1804 | * destined for 0.0.0.0/0, which is for incoming IPVS connections */ | 1804 | * destined for 0.0.0.0/0, which is for incoming IPVS connections */ |
| @@ -1824,7 +1824,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
| 1824 | .owner = THIS_MODULE, | 1824 | .owner = THIS_MODULE, |
| 1825 | .pf = PF_INET6, | 1825 | .pf = PF_INET6, |
| 1826 | .hooknum = NF_INET_LOCAL_IN, | 1826 | .hooknum = NF_INET_LOCAL_IN, |
| 1827 | .priority = 99, | 1827 | .priority = NF_IP6_PRI_NAT_SRC - 2, |
| 1828 | }, | 1828 | }, |
| 1829 | /* After packet filtering, forward packet through VS/DR, VS/TUN, | 1829 | /* After packet filtering, forward packet through VS/DR, VS/TUN, |
| 1830 | * or VS/NAT(change destination), so that filtering rules can be | 1830 | * or VS/NAT(change destination), so that filtering rules can be |
| @@ -1834,7 +1834,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
| 1834 | .owner = THIS_MODULE, | 1834 | .owner = THIS_MODULE, |
| 1835 | .pf = PF_INET6, | 1835 | .pf = PF_INET6, |
| 1836 | .hooknum = NF_INET_LOCAL_IN, | 1836 | .hooknum = NF_INET_LOCAL_IN, |
| 1837 | .priority = 101, | 1837 | .priority = NF_IP6_PRI_NAT_SRC - 1, |
| 1838 | }, | 1838 | }, |
| 1839 | /* Before ip_vs_in, change source only for VS/NAT */ | 1839 | /* Before ip_vs_in, change source only for VS/NAT */ |
| 1840 | { | 1840 | { |
| @@ -1842,7 +1842,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
| 1842 | .owner = THIS_MODULE, | 1842 | .owner = THIS_MODULE, |
| 1843 | .pf = PF_INET, | 1843 | .pf = PF_INET, |
| 1844 | .hooknum = NF_INET_LOCAL_OUT, | 1844 | .hooknum = NF_INET_LOCAL_OUT, |
| 1845 | .priority = -99, | 1845 | .priority = NF_IP6_PRI_NAT_DST + 1, |
| 1846 | }, | 1846 | }, |
| 1847 | /* After mangle, schedule and forward local requests */ | 1847 | /* After mangle, schedule and forward local requests */ |
| 1848 | { | 1848 | { |
| @@ -1850,7 +1850,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
| 1850 | .owner = THIS_MODULE, | 1850 | .owner = THIS_MODULE, |
| 1851 | .pf = PF_INET6, | 1851 | .pf = PF_INET6, |
| 1852 | .hooknum = NF_INET_LOCAL_OUT, | 1852 | .hooknum = NF_INET_LOCAL_OUT, |
| 1853 | .priority = -98, | 1853 | .priority = NF_IP6_PRI_NAT_DST + 2, |
| 1854 | }, | 1854 | }, |
| 1855 | /* After packet filtering (but before ip_vs_out_icmp), catch icmp | 1855 | /* After packet filtering (but before ip_vs_out_icmp), catch icmp |
| 1856 | * destined for 0.0.0.0/0, which is for incoming IPVS connections */ | 1856 | * destined for 0.0.0.0/0, which is for incoming IPVS connections */ |
| @@ -1945,6 +1945,7 @@ static void __net_exit __ip_vs_dev_cleanup(struct net *net) | |||
| 1945 | { | 1945 | { |
| 1946 | EnterFunction(2); | 1946 | EnterFunction(2); |
| 1947 | net_ipvs(net)->enable = 0; /* Disable packet reception */ | 1947 | net_ipvs(net)->enable = 0; /* Disable packet reception */ |
| 1948 | smp_wmb(); | ||
| 1948 | __ip_vs_sync_cleanup(net); | 1949 | __ip_vs_sync_cleanup(net); |
| 1949 | LeaveFunction(2); | 1950 | LeaveFunction(2); |
| 1950 | } | 1951 | } |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 2e1c11f78419..f7af8b866017 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -850,7 +850,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, | |||
| 850 | 850 | ||
| 851 | /* It exists; we have (non-exclusive) reference. */ | 851 | /* It exists; we have (non-exclusive) reference. */ |
| 852 | if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) { | 852 | if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) { |
| 853 | *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY; | 853 | *ctinfo = IP_CT_ESTABLISHED_REPLY; |
| 854 | /* Please set reply bit if this packet OK */ | 854 | /* Please set reply bit if this packet OK */ |
| 855 | *set_reply = 1; | 855 | *set_reply = 1; |
| 856 | } else { | 856 | } else { |
| @@ -922,6 +922,9 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, | |||
| 922 | ret = -ret; | 922 | ret = -ret; |
| 923 | goto out; | 923 | goto out; |
| 924 | } | 924 | } |
| 925 | /* ICMP[v6] protocol trackers may assign one conntrack. */ | ||
| 926 | if (skb->nfct) | ||
| 927 | goto out; | ||
| 925 | } | 928 | } |
| 926 | 929 | ||
| 927 | ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum, | 930 | ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum, |
| @@ -1143,7 +1146,7 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb) | |||
| 1143 | /* This ICMP is in reverse direction to the packet which caused it */ | 1146 | /* This ICMP is in reverse direction to the packet which caused it */ |
| 1144 | ct = nf_ct_get(skb, &ctinfo); | 1147 | ct = nf_ct_get(skb, &ctinfo); |
| 1145 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) | 1148 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) |
| 1146 | ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY; | 1149 | ctinfo = IP_CT_RELATED_REPLY; |
| 1147 | else | 1150 | else |
| 1148 | ctinfo = IP_CT_RELATED; | 1151 | ctinfo = IP_CT_RELATED; |
| 1149 | 1152 | ||
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index e17cb7c7dd8f..6f5801eac999 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c | |||
| @@ -368,7 +368,7 @@ static int help(struct sk_buff *skb, | |||
| 368 | 368 | ||
| 369 | /* Until there's been traffic both ways, don't look in packets. */ | 369 | /* Until there's been traffic both ways, don't look in packets. */ |
| 370 | if (ctinfo != IP_CT_ESTABLISHED && | 370 | if (ctinfo != IP_CT_ESTABLISHED && |
| 371 | ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { | 371 | ctinfo != IP_CT_ESTABLISHED_REPLY) { |
| 372 | pr_debug("ftp: Conntrackinfo = %u\n", ctinfo); | 372 | pr_debug("ftp: Conntrackinfo = %u\n", ctinfo); |
| 373 | return NF_ACCEPT; | 373 | return NF_ACCEPT; |
| 374 | } | 374 | } |
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 18b2ce5c8ced..f03c2d4539f6 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c | |||
| @@ -571,10 +571,9 @@ static int h245_help(struct sk_buff *skb, unsigned int protoff, | |||
| 571 | int ret; | 571 | int ret; |
| 572 | 572 | ||
| 573 | /* Until there's been traffic both ways, don't look in packets. */ | 573 | /* Until there's been traffic both ways, don't look in packets. */ |
| 574 | if (ctinfo != IP_CT_ESTABLISHED && | 574 | if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) |
| 575 | ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { | ||
| 576 | return NF_ACCEPT; | 575 | return NF_ACCEPT; |
| 577 | } | 576 | |
| 578 | pr_debug("nf_ct_h245: skblen = %u\n", skb->len); | 577 | pr_debug("nf_ct_h245: skblen = %u\n", skb->len); |
| 579 | 578 | ||
| 580 | spin_lock_bh(&nf_h323_lock); | 579 | spin_lock_bh(&nf_h323_lock); |
| @@ -1125,10 +1124,9 @@ static int q931_help(struct sk_buff *skb, unsigned int protoff, | |||
| 1125 | int ret; | 1124 | int ret; |
| 1126 | 1125 | ||
| 1127 | /* Until there's been traffic both ways, don't look in packets. */ | 1126 | /* Until there's been traffic both ways, don't look in packets. */ |
| 1128 | if (ctinfo != IP_CT_ESTABLISHED && | 1127 | if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) |
| 1129 | ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { | ||
| 1130 | return NF_ACCEPT; | 1128 | return NF_ACCEPT; |
| 1131 | } | 1129 | |
| 1132 | pr_debug("nf_ct_q931: skblen = %u\n", skb->len); | 1130 | pr_debug("nf_ct_q931: skblen = %u\n", skb->len); |
| 1133 | 1131 | ||
| 1134 | spin_lock_bh(&nf_h323_lock); | 1132 | spin_lock_bh(&nf_h323_lock); |
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index b394aa318776..4f9390b98697 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c | |||
| @@ -125,8 +125,7 @@ static int help(struct sk_buff *skb, unsigned int protoff, | |||
| 125 | return NF_ACCEPT; | 125 | return NF_ACCEPT; |
| 126 | 126 | ||
| 127 | /* Until there's been traffic both ways, don't look in packets. */ | 127 | /* Until there's been traffic both ways, don't look in packets. */ |
| 128 | if (ctinfo != IP_CT_ESTABLISHED && | 128 | if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) |
| 129 | ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) | ||
| 130 | return NF_ACCEPT; | 129 | return NF_ACCEPT; |
| 131 | 130 | ||
| 132 | /* Not a full tcp header? */ | 131 | /* Not a full tcp header? */ |
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index 088944824e13..2fd4565144de 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c | |||
| @@ -519,8 +519,7 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff, | |||
| 519 | u_int16_t msg; | 519 | u_int16_t msg; |
| 520 | 520 | ||
| 521 | /* don't do any tracking before tcp handshake complete */ | 521 | /* don't do any tracking before tcp handshake complete */ |
| 522 | if (ctinfo != IP_CT_ESTABLISHED && | 522 | if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) |
| 523 | ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) | ||
| 524 | return NF_ACCEPT; | 523 | return NF_ACCEPT; |
| 525 | 524 | ||
| 526 | nexthdr_off = protoff; | 525 | nexthdr_off = protoff; |
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c index d9e27734b2a2..8501823b3f9b 100644 --- a/net/netfilter/nf_conntrack_sane.c +++ b/net/netfilter/nf_conntrack_sane.c | |||
| @@ -78,7 +78,7 @@ static int help(struct sk_buff *skb, | |||
| 78 | ct_sane_info = &nfct_help(ct)->help.ct_sane_info; | 78 | ct_sane_info = &nfct_help(ct)->help.ct_sane_info; |
| 79 | /* Until there's been traffic both ways, don't look in packets. */ | 79 | /* Until there's been traffic both ways, don't look in packets. */ |
| 80 | if (ctinfo != IP_CT_ESTABLISHED && | 80 | if (ctinfo != IP_CT_ESTABLISHED && |
| 81 | ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) | 81 | ctinfo != IP_CT_ESTABLISHED_REPLY) |
| 82 | return NF_ACCEPT; | 82 | return NF_ACCEPT; |
| 83 | 83 | ||
| 84 | /* Not a full tcp header? */ | 84 | /* Not a full tcp header? */ |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index cb5a28581782..93faf6a3a637 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
| @@ -1423,7 +1423,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, | |||
| 1423 | typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; | 1423 | typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; |
| 1424 | 1424 | ||
| 1425 | if (ctinfo != IP_CT_ESTABLISHED && | 1425 | if (ctinfo != IP_CT_ESTABLISHED && |
| 1426 | ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) | 1426 | ctinfo != IP_CT_ESTABLISHED_REPLY) |
| 1427 | return NF_ACCEPT; | 1427 | return NF_ACCEPT; |
| 1428 | 1428 | ||
| 1429 | /* No Data ? */ | 1429 | /* No Data ? */ |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index e0ee010935e7..2e7ccbb43ddb 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
| @@ -456,7 +456,8 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
| 456 | if (skb->mark) | 456 | if (skb->mark) |
| 457 | NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark)); | 457 | NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark)); |
| 458 | 458 | ||
| 459 | if (indev && skb->dev) { | 459 | if (indev && skb->dev && |
| 460 | skb->mac_header != skb->network_header) { | ||
| 460 | struct nfulnl_msg_packet_hw phw; | 461 | struct nfulnl_msg_packet_hw phw; |
| 461 | int len = dev_parse_header(skb, phw.hw_addr); | 462 | int len = dev_parse_header(skb, phw.hw_addr); |
| 462 | if (len > 0) { | 463 | if (len > 0) { |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index b83123f12b42..fdd2fafe0a14 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
| @@ -335,7 +335,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, | |||
| 335 | if (entskb->mark) | 335 | if (entskb->mark) |
| 336 | NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark)); | 336 | NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark)); |
| 337 | 337 | ||
| 338 | if (indev && entskb->dev) { | 338 | if (indev && entskb->dev && |
| 339 | entskb->mac_header != entskb->network_header) { | ||
| 339 | struct nfqnl_msg_packet_hw phw; | 340 | struct nfqnl_msg_packet_hw phw; |
| 340 | int len = dev_parse_header(entskb, phw.hw_addr); | 341 | int len = dev_parse_header(entskb, phw.hw_addr); |
| 341 | if (len) { | 342 | if (len) { |
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 9cc46356b577..fe39f7e913df 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c | |||
| @@ -143,9 +143,9 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, | |||
| 143 | ct = nf_ct_get(skb, &ctinfo); | 143 | ct = nf_ct_get(skb, &ctinfo); |
| 144 | if (ct && !nf_ct_is_untracked(ct) && | 144 | if (ct && !nf_ct_is_untracked(ct) && |
| 145 | ((iph->protocol != IPPROTO_ICMP && | 145 | ((iph->protocol != IPPROTO_ICMP && |
| 146 | ctinfo == IP_CT_IS_REPLY + IP_CT_ESTABLISHED) || | 146 | ctinfo == IP_CT_ESTABLISHED_REPLY) || |
| 147 | (iph->protocol == IPPROTO_ICMP && | 147 | (iph->protocol == IPPROTO_ICMP && |
| 148 | ctinfo == IP_CT_IS_REPLY + IP_CT_RELATED)) && | 148 | ctinfo == IP_CT_RELATED_REPLY)) && |
| 149 | (ct->status & IPS_SRC_NAT_DONE)) { | 149 | (ct->status & IPS_SRC_NAT_DONE)) { |
| 150 | 150 | ||
| 151 | daddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; | 151 | daddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 925f715686a5..c0c3cda19712 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -798,7 +798,13 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 798 | getnstimeofday(&ts); | 798 | getnstimeofday(&ts); |
| 799 | h.h2->tp_sec = ts.tv_sec; | 799 | h.h2->tp_sec = ts.tv_sec; |
| 800 | h.h2->tp_nsec = ts.tv_nsec; | 800 | h.h2->tp_nsec = ts.tv_nsec; |
| 801 | h.h2->tp_vlan_tci = vlan_tx_tag_get(skb); | 801 | if (vlan_tx_tag_present(skb)) { |
| 802 | h.h2->tp_vlan_tci = vlan_tx_tag_get(skb); | ||
| 803 | status |= TP_STATUS_VLAN_VALID; | ||
| 804 | } else { | ||
| 805 | h.h2->tp_vlan_tci = 0; | ||
| 806 | } | ||
| 807 | h.h2->tp_padding = 0; | ||
| 802 | hdrlen = sizeof(*h.h2); | 808 | hdrlen = sizeof(*h.h2); |
| 803 | break; | 809 | break; |
| 804 | default: | 810 | default: |
| @@ -1725,8 +1731,13 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1725 | aux.tp_snaplen = skb->len; | 1731 | aux.tp_snaplen = skb->len; |
| 1726 | aux.tp_mac = 0; | 1732 | aux.tp_mac = 0; |
| 1727 | aux.tp_net = skb_network_offset(skb); | 1733 | aux.tp_net = skb_network_offset(skb); |
| 1728 | aux.tp_vlan_tci = vlan_tx_tag_get(skb); | 1734 | if (vlan_tx_tag_present(skb)) { |
| 1729 | 1735 | aux.tp_vlan_tci = vlan_tx_tag_get(skb); | |
| 1736 | aux.tp_status |= TP_STATUS_VLAN_VALID; | ||
| 1737 | } else { | ||
| 1738 | aux.tp_vlan_tci = 0; | ||
| 1739 | } | ||
| 1740 | aux.tp_padding = 0; | ||
| 1730 | put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); | 1741 | put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); |
| 1731 | } | 1742 | } |
| 1732 | 1743 | ||
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index b1721d71c27c..b4c680900d7a 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
| @@ -251,9 +251,8 @@ static void dev_watchdog(unsigned long arg) | |||
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | if (some_queue_timedout) { | 253 | if (some_queue_timedout) { |
| 254 | char drivername[64]; | ||
| 255 | WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n", | 254 | WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n", |
| 256 | dev->name, netdev_drivername(dev, drivername, 64), i); | 255 | dev->name, netdev_drivername(dev), i); |
| 257 | dev->netdev_ops->ndo_tx_timeout(dev); | 256 | dev->netdev_ops->ndo_tx_timeout(dev); |
| 258 | } | 257 | } |
| 259 | if (!mod_timer(&dev->watchdog_timer, | 258 | if (!mod_timer(&dev->watchdog_timer, |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 525f97c467e9..4a62888f2e43 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -444,15 +444,7 @@ void sctp_association_free(struct sctp_association *asoc) | |||
| 444 | 444 | ||
| 445 | asoc->peer.transport_count = 0; | 445 | asoc->peer.transport_count = 0; |
| 446 | 446 | ||
| 447 | /* Free any cached ASCONF_ACK chunk. */ | 447 | sctp_asconf_queue_teardown(asoc); |
| 448 | sctp_assoc_free_asconf_acks(asoc); | ||
| 449 | |||
| 450 | /* Free the ASCONF queue. */ | ||
| 451 | sctp_assoc_free_asconf_queue(asoc); | ||
| 452 | |||
| 453 | /* Free any cached ASCONF chunk. */ | ||
| 454 | if (asoc->addip_last_asconf) | ||
| 455 | sctp_chunk_free(asoc->addip_last_asconf); | ||
| 456 | 448 | ||
| 457 | /* AUTH - Free the endpoint shared keys */ | 449 | /* AUTH - Free the endpoint shared keys */ |
| 458 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); | 450 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); |
| @@ -1646,3 +1638,16 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack( | |||
| 1646 | 1638 | ||
| 1647 | return NULL; | 1639 | return NULL; |
| 1648 | } | 1640 | } |
| 1641 | |||
| 1642 | void sctp_asconf_queue_teardown(struct sctp_association *asoc) | ||
| 1643 | { | ||
| 1644 | /* Free any cached ASCONF_ACK chunk. */ | ||
| 1645 | sctp_assoc_free_asconf_acks(asoc); | ||
| 1646 | |||
| 1647 | /* Free the ASCONF queue. */ | ||
| 1648 | sctp_assoc_free_asconf_queue(asoc); | ||
| 1649 | |||
| 1650 | /* Free any cached ASCONF chunk. */ | ||
| 1651 | if (asoc->addip_last_asconf) | ||
| 1652 | sctp_chunk_free(asoc->addip_last_asconf); | ||
| 1653 | } | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 67380a29e2e9..207175b2f40a 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -1058,7 +1058,6 @@ SCTP_STATIC __init int sctp_init(void) | |||
| 1058 | int status = -EINVAL; | 1058 | int status = -EINVAL; |
| 1059 | unsigned long goal; | 1059 | unsigned long goal; |
| 1060 | unsigned long limit; | 1060 | unsigned long limit; |
| 1061 | unsigned long nr_pages; | ||
| 1062 | int max_share; | 1061 | int max_share; |
| 1063 | int order; | 1062 | int order; |
| 1064 | 1063 | ||
| @@ -1148,15 +1147,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
| 1148 | /* Initialize handle used for association ids. */ | 1147 | /* Initialize handle used for association ids. */ |
| 1149 | idr_init(&sctp_assocs_id); | 1148 | idr_init(&sctp_assocs_id); |
| 1150 | 1149 | ||
| 1151 | /* Set the pressure threshold to be a fraction of global memory that | 1150 | limit = nr_free_buffer_pages() / 8; |
| 1152 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | ||
| 1153 | * memory, with a floor of 128 pages. | ||
| 1154 | * Note this initializes the data in sctpv6_prot too | ||
| 1155 | * Unabashedly stolen from tcp_init | ||
| 1156 | */ | ||
| 1157 | nr_pages = totalram_pages - totalhigh_pages; | ||
| 1158 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | ||
| 1159 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
| 1160 | limit = max(limit, 128UL); | 1151 | limit = max(limit, 128UL); |
| 1161 | sysctl_sctp_mem[0] = limit / 4 * 3; | 1152 | sysctl_sctp_mem[0] = limit / 4 * 3; |
| 1162 | sysctl_sctp_mem[1] = limit; | 1153 | sysctl_sctp_mem[1] = limit; |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index d612ca1ca6c0..534c2e5feb05 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -1670,6 +1670,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
| 1670 | case SCTP_CMD_SEND_NEXT_ASCONF: | 1670 | case SCTP_CMD_SEND_NEXT_ASCONF: |
| 1671 | sctp_cmd_send_asconf(asoc); | 1671 | sctp_cmd_send_asconf(asoc); |
| 1672 | break; | 1672 | break; |
| 1673 | case SCTP_CMD_PURGE_ASCONF_QUEUE: | ||
| 1674 | sctp_asconf_queue_teardown(asoc); | ||
| 1675 | break; | ||
| 1673 | default: | 1676 | default: |
| 1674 | pr_warn("Impossible command: %u, %p\n", | 1677 | pr_warn("Impossible command: %u, %p\n", |
| 1675 | cmd->verb, cmd->obj.ptr); | 1678 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 7f4a4f8368ee..a297283154d5 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -1718,11 +1718,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
| 1718 | return SCTP_DISPOSITION_CONSUME; | 1718 | return SCTP_DISPOSITION_CONSUME; |
| 1719 | } | 1719 | } |
| 1720 | 1720 | ||
| 1721 | /* For now, fail any unsent/unacked data. Consider the optional | 1721 | /* For now, stop pending T3-rtx and SACK timers, fail any unsent/unacked |
| 1722 | * choice of resending of this data. | 1722 | * data. Consider the optional choice of resending of this data. |
| 1723 | */ | 1723 | */ |
| 1724 | sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL()); | ||
| 1725 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
| 1726 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
| 1724 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); | 1727 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); |
| 1725 | 1728 | ||
| 1729 | /* Stop pending T4-rto timer, teardown ASCONF queue, ASCONF-ACK queue | ||
| 1730 | * and ASCONF-ACK cache. | ||
| 1731 | */ | ||
| 1732 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
| 1733 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | ||
| 1734 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL()); | ||
| 1735 | |||
| 1726 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 1736 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
| 1727 | if (!repl) | 1737 | if (!repl) |
| 1728 | goto nomem; | 1738 | goto nomem; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6766913a53e6..08c6238802de 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -2073,10 +2073,33 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, | |||
| 2073 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | 2073 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, |
| 2074 | unsigned int optlen) | 2074 | unsigned int optlen) |
| 2075 | { | 2075 | { |
| 2076 | struct sctp_association *asoc; | ||
| 2077 | struct sctp_ulpevent *event; | ||
| 2078 | |||
| 2076 | if (optlen > sizeof(struct sctp_event_subscribe)) | 2079 | if (optlen > sizeof(struct sctp_event_subscribe)) |
| 2077 | return -EINVAL; | 2080 | return -EINVAL; |
| 2078 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) | 2081 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) |
| 2079 | return -EFAULT; | 2082 | return -EFAULT; |
| 2083 | |||
| 2084 | /* | ||
| 2085 | * At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | ||
| 2086 | * if there is no data to be sent or retransmit, the stack will | ||
| 2087 | * immediately send up this notification. | ||
| 2088 | */ | ||
| 2089 | if (sctp_ulpevent_type_enabled(SCTP_SENDER_DRY_EVENT, | ||
| 2090 | &sctp_sk(sk)->subscribe)) { | ||
| 2091 | asoc = sctp_id2assoc(sk, 0); | ||
| 2092 | |||
| 2093 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { | ||
| 2094 | event = sctp_ulpevent_make_sender_dry_event(asoc, | ||
| 2095 | GFP_ATOMIC); | ||
| 2096 | if (!event) | ||
| 2097 | return -ENOMEM; | ||
| 2098 | |||
| 2099 | sctp_ulpq_tail_event(&asoc->ulpq, event); | ||
| 2100 | } | ||
| 2101 | } | ||
| 2102 | |||
| 2080 | return 0; | 2103 | return 0; |
| 2081 | } | 2104 | } |
| 2082 | 2105 | ||
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 339ba64cce1e..5daf6cc4faea 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -577,13 +577,13 @@ retry: | |||
| 577 | } | 577 | } |
| 578 | inode = &gss_msg->inode->vfs_inode; | 578 | inode = &gss_msg->inode->vfs_inode; |
| 579 | for (;;) { | 579 | for (;;) { |
| 580 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); | 580 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); |
| 581 | spin_lock(&inode->i_lock); | 581 | spin_lock(&inode->i_lock); |
| 582 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { | 582 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { |
| 583 | break; | 583 | break; |
| 584 | } | 584 | } |
| 585 | spin_unlock(&inode->i_lock); | 585 | spin_unlock(&inode->i_lock); |
| 586 | if (signalled()) { | 586 | if (fatal_signal_pending(current)) { |
| 587 | err = -ERESTARTSYS; | 587 | err = -ERESTARTSYS; |
| 588 | goto out_intr; | 588 | goto out_intr; |
| 589 | } | 589 | } |
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 0a9a2ec2e469..c3b75333b821 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <linux/sunrpc/gss_krb5.h> | 43 | #include <linux/sunrpc/gss_krb5.h> |
| 44 | #include <linux/sunrpc/xdr.h> | 44 | #include <linux/sunrpc/xdr.h> |
| 45 | #include <linux/crypto.h> | 45 | #include <linux/crypto.h> |
| 46 | #include <linux/sunrpc/gss_krb5_enctypes.h> | ||
| 46 | 47 | ||
| 47 | #ifdef RPC_DEBUG | 48 | #ifdef RPC_DEBUG |
| 48 | # define RPCDBG_FACILITY RPCDBG_AUTH | 49 | # define RPCDBG_FACILITY RPCDBG_AUTH |
| @@ -750,7 +751,7 @@ static struct gss_api_mech gss_kerberos_mech = { | |||
| 750 | .gm_ops = &gss_kerberos_ops, | 751 | .gm_ops = &gss_kerberos_ops, |
| 751 | .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), | 752 | .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), |
| 752 | .gm_pfs = gss_kerberos_pfs, | 753 | .gm_pfs = gss_kerberos_pfs, |
| 753 | .gm_upcall_enctypes = "18,17,16,23,3,1,2", | 754 | .gm_upcall_enctypes = KRB5_SUPPORTED_ENCTYPES, |
| 754 | }; | 755 | }; |
| 755 | 756 | ||
| 756 | static int __init init_kerberos_module(void) | 757 | static int __init init_kerberos_module(void) |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index b84d7395535e..8c9141583d6f 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -1061,7 +1061,7 @@ call_allocate(struct rpc_task *task) | |||
| 1061 | 1061 | ||
| 1062 | dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); | 1062 | dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); |
| 1063 | 1063 | ||
| 1064 | if (RPC_IS_ASYNC(task) || !signalled()) { | 1064 | if (RPC_IS_ASYNC(task) || !fatal_signal_pending(current)) { |
| 1065 | task->tk_action = call_allocate; | 1065 | task->tk_action = call_allocate; |
| 1066 | rpc_delay(task, HZ>>4); | 1066 | rpc_delay(task, HZ>>4); |
| 1067 | return; | 1067 | return; |
| @@ -1175,6 +1175,9 @@ call_bind_status(struct rpc_task *task) | |||
| 1175 | status = -EOPNOTSUPP; | 1175 | status = -EOPNOTSUPP; |
| 1176 | break; | 1176 | break; |
| 1177 | } | 1177 | } |
| 1178 | if (task->tk_rebind_retry == 0) | ||
| 1179 | break; | ||
| 1180 | task->tk_rebind_retry--; | ||
| 1178 | rpc_delay(task, 3*HZ); | 1181 | rpc_delay(task, 3*HZ); |
| 1179 | goto retry_timeout; | 1182 | goto retry_timeout; |
| 1180 | case -ETIMEDOUT: | 1183 | case -ETIMEDOUT: |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 6b43ee7221d5..a27406b1654f 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
| @@ -792,6 +792,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta | |||
| 792 | /* Initialize retry counters */ | 792 | /* Initialize retry counters */ |
| 793 | task->tk_garb_retry = 2; | 793 | task->tk_garb_retry = 2; |
| 794 | task->tk_cred_retry = 2; | 794 | task->tk_cred_retry = 2; |
| 795 | task->tk_rebind_retry = 2; | ||
| 795 | 796 | ||
| 796 | task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW; | 797 | task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW; |
| 797 | task->tk_owner = current->tgid; | 798 | task->tk_owner = current->tgid; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ec83f413a7ed..f07602d7bf68 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -3406,12 +3406,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
| 3406 | i = 0; | 3406 | i = 0; |
| 3407 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { | 3407 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { |
| 3408 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { | 3408 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { |
| 3409 | if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) { | 3409 | if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { |
| 3410 | err = -EINVAL; | 3410 | err = -EINVAL; |
| 3411 | goto out_free; | 3411 | goto out_free; |
| 3412 | } | 3412 | } |
| 3413 | memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); | ||
| 3414 | request->ssids[i].ssid_len = nla_len(attr); | 3413 | request->ssids[i].ssid_len = nla_len(attr); |
| 3414 | memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); | ||
| 3415 | i++; | 3415 | i++; |
| 3416 | } | 3416 | } |
| 3417 | } | 3417 | } |
| @@ -3572,14 +3572,13 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
| 3572 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { | 3572 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { |
| 3573 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], | 3573 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], |
| 3574 | tmp) { | 3574 | tmp) { |
| 3575 | if (request->ssids[i].ssid_len > | 3575 | if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { |
| 3576 | IEEE80211_MAX_SSID_LEN) { | ||
| 3577 | err = -EINVAL; | 3576 | err = -EINVAL; |
| 3578 | goto out_free; | 3577 | goto out_free; |
| 3579 | } | 3578 | } |
| 3579 | request->ssids[i].ssid_len = nla_len(attr); | ||
| 3580 | memcpy(request->ssids[i].ssid, nla_data(attr), | 3580 | memcpy(request->ssids[i].ssid, nla_data(attr), |
| 3581 | nla_len(attr)); | 3581 | nla_len(attr)); |
| 3582 | request->ssids[i].ssid_len = nla_len(attr); | ||
| 3583 | i++; | 3582 | i++; |
| 3584 | } | 3583 | } |
| 3585 | } | 3584 | } |
| @@ -6464,7 +6463,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | |||
| 6464 | if (addr) | 6463 | if (addr) |
| 6465 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); | 6464 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); |
| 6466 | NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type); | 6465 | NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type); |
| 6467 | NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id); | 6466 | if (key_id != -1) |
| 6467 | NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id); | ||
| 6468 | if (tsc) | 6468 | if (tsc) |
| 6469 | NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); | 6469 | NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); |
| 6470 | 6470 | ||
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 73a441d237b5..7a6c67667d70 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
| @@ -267,13 +267,35 @@ static bool is_bss(struct cfg80211_bss *a, | |||
| 267 | return memcmp(ssidie + 2, ssid, ssid_len) == 0; | 267 | return memcmp(ssidie + 2, ssid, ssid_len) == 0; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | static bool is_mesh_bss(struct cfg80211_bss *a) | ||
| 271 | { | ||
| 272 | const u8 *ie; | ||
| 273 | |||
| 274 | if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) | ||
| 275 | return false; | ||
| 276 | |||
| 277 | ie = cfg80211_find_ie(WLAN_EID_MESH_ID, | ||
| 278 | a->information_elements, | ||
| 279 | a->len_information_elements); | ||
| 280 | if (!ie) | ||
| 281 | return false; | ||
| 282 | |||
| 283 | ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, | ||
| 284 | a->information_elements, | ||
| 285 | a->len_information_elements); | ||
| 286 | if (!ie) | ||
| 287 | return false; | ||
| 288 | |||
| 289 | return true; | ||
| 290 | } | ||
| 291 | |||
| 270 | static bool is_mesh(struct cfg80211_bss *a, | 292 | static bool is_mesh(struct cfg80211_bss *a, |
| 271 | const u8 *meshid, size_t meshidlen, | 293 | const u8 *meshid, size_t meshidlen, |
| 272 | const u8 *meshcfg) | 294 | const u8 *meshcfg) |
| 273 | { | 295 | { |
| 274 | const u8 *ie; | 296 | const u8 *ie; |
| 275 | 297 | ||
| 276 | if (!WLAN_CAPABILITY_IS_MBSS(a->capability)) | 298 | if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) |
| 277 | return false; | 299 | return false; |
| 278 | 300 | ||
| 279 | ie = cfg80211_find_ie(WLAN_EID_MESH_ID, | 301 | ie = cfg80211_find_ie(WLAN_EID_MESH_ID, |
| @@ -311,7 +333,7 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
| 311 | if (a->channel != b->channel) | 333 | if (a->channel != b->channel) |
| 312 | return b->channel->center_freq - a->channel->center_freq; | 334 | return b->channel->center_freq - a->channel->center_freq; |
| 313 | 335 | ||
| 314 | if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) { | 336 | if (is_mesh_bss(a) && is_mesh_bss(b)) { |
| 315 | r = cmp_ies(WLAN_EID_MESH_ID, | 337 | r = cmp_ies(WLAN_EID_MESH_ID, |
| 316 | a->information_elements, | 338 | a->information_elements, |
| 317 | a->len_information_elements, | 339 | a->len_information_elements, |
| @@ -457,7 +479,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
| 457 | struct cfg80211_internal_bss *res) | 479 | struct cfg80211_internal_bss *res) |
| 458 | { | 480 | { |
| 459 | struct cfg80211_internal_bss *found = NULL; | 481 | struct cfg80211_internal_bss *found = NULL; |
| 460 | const u8 *meshid, *meshcfg; | ||
| 461 | 482 | ||
| 462 | /* | 483 | /* |
| 463 | * The reference to "res" is donated to this function. | 484 | * The reference to "res" is donated to this function. |
| @@ -470,22 +491,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
| 470 | 491 | ||
| 471 | res->ts = jiffies; | 492 | res->ts = jiffies; |
| 472 | 493 | ||
| 473 | if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) { | ||
| 474 | /* must be mesh, verify */ | ||
| 475 | meshid = cfg80211_find_ie(WLAN_EID_MESH_ID, | ||
| 476 | res->pub.information_elements, | ||
| 477 | res->pub.len_information_elements); | ||
| 478 | meshcfg = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, | ||
| 479 | res->pub.information_elements, | ||
| 480 | res->pub.len_information_elements); | ||
| 481 | if (!meshid || !meshcfg || | ||
| 482 | meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) { | ||
| 483 | /* bogus mesh */ | ||
| 484 | kref_put(&res->ref, bss_release); | ||
| 485 | return NULL; | ||
| 486 | } | ||
| 487 | } | ||
| 488 | |||
| 489 | spin_lock_bh(&dev->bss_lock); | 494 | spin_lock_bh(&dev->bss_lock); |
| 490 | 495 | ||
| 491 | found = rb_find_bss(dev, res); | 496 | found = rb_find_bss(dev, res); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9bec2e8a838c..5ce74a385525 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -50,7 +50,7 @@ static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); | |||
| 50 | static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); | 50 | static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); |
| 51 | static void xfrm_init_pmtu(struct dst_entry *dst); | 51 | static void xfrm_init_pmtu(struct dst_entry *dst); |
| 52 | static int stale_bundle(struct dst_entry *dst); | 52 | static int stale_bundle(struct dst_entry *dst); |
| 53 | static int xfrm_bundle_ok(struct xfrm_dst *xdst, int family); | 53 | static int xfrm_bundle_ok(struct xfrm_dst *xdst); |
| 54 | 54 | ||
| 55 | 55 | ||
| 56 | static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, | 56 | static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, |
| @@ -2241,7 +2241,7 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) | |||
| 2241 | 2241 | ||
| 2242 | static int stale_bundle(struct dst_entry *dst) | 2242 | static int stale_bundle(struct dst_entry *dst) |
| 2243 | { | 2243 | { |
| 2244 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, AF_UNSPEC); | 2244 | return !xfrm_bundle_ok((struct xfrm_dst *)dst); |
| 2245 | } | 2245 | } |
| 2246 | 2246 | ||
| 2247 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) | 2247 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) |
| @@ -2313,7 +2313,7 @@ static void xfrm_init_pmtu(struct dst_entry *dst) | |||
| 2313 | * still valid. | 2313 | * still valid. |
| 2314 | */ | 2314 | */ |
| 2315 | 2315 | ||
| 2316 | static int xfrm_bundle_ok(struct xfrm_dst *first, int family) | 2316 | static int xfrm_bundle_ok(struct xfrm_dst *first) |
| 2317 | { | 2317 | { |
| 2318 | struct dst_entry *dst = &first->u.dst; | 2318 | struct dst_entry *dst = &first->u.dst; |
| 2319 | struct xfrm_dst *last; | 2319 | struct xfrm_dst *last; |
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 47f1b8638df9..b11ea692bd7d 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c | |||
| @@ -265,7 +265,7 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq) | |||
| 265 | bitnr = bitnr & 0x1F; | 265 | bitnr = bitnr & 0x1F; |
| 266 | replay_esn->bmp[nr] |= (1U << bitnr); | 266 | replay_esn->bmp[nr] |= (1U << bitnr); |
| 267 | } else { | 267 | } else { |
| 268 | nr = replay_esn->replay_window >> 5; | 268 | nr = (replay_esn->replay_window - 1) >> 5; |
| 269 | for (i = 0; i <= nr; i++) | 269 | for (i = 0; i <= nr; i++) |
| 270 | replay_esn->bmp[i] = 0; | 270 | replay_esn->bmp[i] = 0; |
| 271 | 271 | ||
| @@ -471,7 +471,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq) | |||
| 471 | bitnr = bitnr & 0x1F; | 471 | bitnr = bitnr & 0x1F; |
| 472 | replay_esn->bmp[nr] |= (1U << bitnr); | 472 | replay_esn->bmp[nr] |= (1U << bitnr); |
| 473 | } else { | 473 | } else { |
| 474 | nr = replay_esn->replay_window >> 5; | 474 | nr = (replay_esn->replay_window - 1) >> 5; |
| 475 | for (i = 0; i <= nr; i++) | 475 | for (i = 0; i <= nr; i++) |
| 476 | replay_esn->bmp[i] = 0; | 476 | replay_esn->bmp[i] = 0; |
| 477 | 477 | ||
