diff options
Diffstat (limited to 'net')
124 files changed, 831 insertions, 542 deletions
diff --git a/net/Kconfig b/net/Kconfig index 0715db64a5c3..d334678c0bd8 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
| @@ -224,7 +224,7 @@ source "net/hsr/Kconfig" | |||
| 224 | 224 | ||
| 225 | config RPS | 225 | config RPS |
| 226 | boolean | 226 | boolean |
| 227 | depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS | 227 | depends on SMP && SYSFS |
| 228 | default y | 228 | default y |
| 229 | 229 | ||
| 230 | config RFS_ACCEL | 230 | config RFS_ACCEL |
| @@ -235,7 +235,7 @@ config RFS_ACCEL | |||
| 235 | 235 | ||
| 236 | config XPS | 236 | config XPS |
| 237 | boolean | 237 | boolean |
| 238 | depends on SMP && USE_GENERIC_SMP_HELPERS | 238 | depends on SMP |
| 239 | default y | 239 | default y |
| 240 | 240 | ||
| 241 | config NETPRIO_CGROUP | 241 | config NETPRIO_CGROUP |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 7fee50d637f9..7d424ac6e760 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
| @@ -1735,7 +1735,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
| 1735 | size_t size, int flags) | 1735 | size_t size, int flags) |
| 1736 | { | 1736 | { |
| 1737 | struct sock *sk = sock->sk; | 1737 | struct sock *sk = sock->sk; |
| 1738 | struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; | ||
| 1739 | struct ddpehdr *ddp; | 1738 | struct ddpehdr *ddp; |
| 1740 | int copied = 0; | 1739 | int copied = 0; |
| 1741 | int offset = 0; | 1740 | int offset = 0; |
| @@ -1764,14 +1763,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
| 1764 | } | 1763 | } |
| 1765 | err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); | 1764 | err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); |
| 1766 | 1765 | ||
| 1767 | if (!err) { | 1766 | if (!err && msg->msg_name) { |
| 1768 | if (sat) { | 1767 | struct sockaddr_at *sat = msg->msg_name; |
| 1769 | sat->sat_family = AF_APPLETALK; | 1768 | sat->sat_family = AF_APPLETALK; |
| 1770 | sat->sat_port = ddp->deh_sport; | 1769 | sat->sat_port = ddp->deh_sport; |
| 1771 | sat->sat_addr.s_node = ddp->deh_snode; | 1770 | sat->sat_addr.s_node = ddp->deh_snode; |
| 1772 | sat->sat_addr.s_net = ddp->deh_snet; | 1771 | sat->sat_addr.s_net = ddp->deh_snet; |
| 1773 | } | 1772 | msg->msg_namelen = sizeof(*sat); |
| 1774 | msg->msg_namelen = sizeof(*sat); | ||
| 1775 | } | 1773 | } |
| 1776 | 1774 | ||
| 1777 | skb_free_datagram(sk, skb); /* Free the datagram. */ | 1775 | skb_free_datagram(sk, skb); /* Free the datagram. */ |
diff --git a/net/atm/common.c b/net/atm/common.c index 737bef59ce89..7b491006eaf4 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
| @@ -531,8 +531,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 531 | struct sk_buff *skb; | 531 | struct sk_buff *skb; |
| 532 | int copied, error = -EINVAL; | 532 | int copied, error = -EINVAL; |
| 533 | 533 | ||
| 534 | msg->msg_namelen = 0; | ||
| 535 | |||
| 536 | if (sock->state != SS_CONNECTED) | 534 | if (sock->state != SS_CONNECTED) |
| 537 | return -ENOTCONN; | 535 | return -ENOTCONN; |
| 538 | 536 | ||
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index a00123ebb0ae..7bb1605bdfd9 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
| @@ -1636,11 +1636,11 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1636 | 1636 | ||
| 1637 | skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 1637 | skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); |
| 1638 | 1638 | ||
| 1639 | if (msg->msg_namelen != 0) { | 1639 | if (msg->msg_name) { |
| 1640 | struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name; | ||
| 1641 | ax25_digi digi; | 1640 | ax25_digi digi; |
| 1642 | ax25_address src; | 1641 | ax25_address src; |
| 1643 | const unsigned char *mac = skb_mac_header(skb); | 1642 | const unsigned char *mac = skb_mac_header(skb); |
| 1643 | struct sockaddr_ax25 *sax = msg->msg_name; | ||
| 1644 | 1644 | ||
| 1645 | memset(sax, 0, sizeof(struct full_sockaddr_ax25)); | 1645 | memset(sax, 0, sizeof(struct full_sockaddr_ax25)); |
| 1646 | ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL, | 1646 | ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL, |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index f6a1671ea2ff..56ca494621c6 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
| @@ -224,10 +224,9 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 224 | 224 | ||
| 225 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 225 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
| 226 | if (!skb) { | 226 | if (!skb) { |
| 227 | if (sk->sk_shutdown & RCV_SHUTDOWN) { | 227 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
| 228 | msg->msg_namelen = 0; | ||
| 229 | return 0; | 228 | return 0; |
| 230 | } | 229 | |
| 231 | return err; | 230 | return err; |
| 232 | } | 231 | } |
| 233 | 232 | ||
| @@ -245,8 +244,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 245 | if (bt_sk(sk)->skb_msg_name) | 244 | if (bt_sk(sk)->skb_msg_name) |
| 246 | bt_sk(sk)->skb_msg_name(skb, msg->msg_name, | 245 | bt_sk(sk)->skb_msg_name(skb, msg->msg_name, |
| 247 | &msg->msg_namelen); | 246 | &msg->msg_namelen); |
| 248 | else | ||
| 249 | msg->msg_namelen = 0; | ||
| 250 | } | 247 | } |
| 251 | 248 | ||
| 252 | skb_free_datagram(sk, skb); | 249 | skb_free_datagram(sk, skb); |
| @@ -295,8 +292,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 295 | if (flags & MSG_OOB) | 292 | if (flags & MSG_OOB) |
| 296 | return -EOPNOTSUPP; | 293 | return -EOPNOTSUPP; |
| 297 | 294 | ||
| 298 | msg->msg_namelen = 0; | ||
| 299 | |||
| 300 | BT_DBG("sk %p size %zu", sk, size); | 295 | BT_DBG("sk %p size %zu", sk, size); |
| 301 | 296 | ||
| 302 | lock_sock(sk); | 297 | lock_sock(sk); |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 71f0be173080..6a6c8bb4fd72 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
| @@ -856,8 +856,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 856 | if (!skb) | 856 | if (!skb) |
| 857 | return err; | 857 | return err; |
| 858 | 858 | ||
| 859 | msg->msg_namelen = 0; | ||
| 860 | |||
| 861 | copied = skb->len; | 859 | copied = skb->len; |
| 862 | if (len < copied) { | 860 | if (len < copied) { |
| 863 | msg->msg_flags |= MSG_TRUNC; | 861 | msg->msg_flags |= MSG_TRUNC; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 0cef67707838..4af3821df880 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -2439,6 +2439,9 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, | |||
| 2439 | int err; | 2439 | int err; |
| 2440 | struct sk_buff_head seg_queue; | 2440 | struct sk_buff_head seg_queue; |
| 2441 | 2441 | ||
| 2442 | if (!chan->conn) | ||
| 2443 | return -ENOTCONN; | ||
| 2444 | |||
| 2442 | /* Connectionless channel */ | 2445 | /* Connectionless channel */ |
| 2443 | if (chan->chan_type == L2CAP_CHAN_CONN_LESS) { | 2446 | if (chan->chan_type == L2CAP_CHAN_CONN_LESS) { |
| 2444 | skb = l2cap_create_connless_pdu(chan, msg, len, priority); | 2447 | skb = l2cap_create_connless_pdu(chan, msg, len, priority); |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 94d06cbfbc18..facd8a79c038 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
| @@ -694,6 +694,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, | |||
| 694 | addr.l2_family = AF_BLUETOOTH; | 694 | addr.l2_family = AF_BLUETOOTH; |
| 695 | addr.l2_psm = 0; | 695 | addr.l2_psm = 0; |
| 696 | addr.l2_cid = 0; | 696 | addr.l2_cid = 0; |
| 697 | addr.l2_bdaddr_type = BDADDR_BREDR; | ||
| 697 | *err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); | 698 | *err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); |
| 698 | if (*err < 0) | 699 | if (*err < 0) |
| 699 | goto failed; | 700 | goto failed; |
| @@ -719,6 +720,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, | |||
| 719 | addr.l2_family = AF_BLUETOOTH; | 720 | addr.l2_family = AF_BLUETOOTH; |
| 720 | addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); | 721 | addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); |
| 721 | addr.l2_cid = 0; | 722 | addr.l2_cid = 0; |
| 723 | addr.l2_bdaddr_type = BDADDR_BREDR; | ||
| 722 | *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK); | 724 | *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK); |
| 723 | if (*err == 0 || *err == -EINPROGRESS) | 725 | if (*err == 0 || *err == -EINPROGRESS) |
| 724 | return s; | 726 | return s; |
| @@ -1983,6 +1985,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) | |||
| 1983 | addr.l2_family = AF_BLUETOOTH; | 1985 | addr.l2_family = AF_BLUETOOTH; |
| 1984 | addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); | 1986 | addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); |
| 1985 | addr.l2_cid = 0; | 1987 | addr.l2_cid = 0; |
| 1988 | addr.l2_bdaddr_type = BDADDR_BREDR; | ||
| 1986 | err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); | 1989 | err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); |
| 1987 | if (err < 0) { | 1990 | if (err < 0) { |
| 1988 | BT_ERR("Bind failed %d", err); | 1991 | BT_ERR("Bind failed %d", err); |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index c4d3d423f89b..3c2d3e4aa2f5 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
| @@ -615,7 +615,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 615 | 615 | ||
| 616 | if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { | 616 | if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { |
| 617 | rfcomm_dlc_accept(d); | 617 | rfcomm_dlc_accept(d); |
| 618 | msg->msg_namelen = 0; | ||
| 619 | return 0; | 618 | return 0; |
| 620 | } | 619 | } |
| 621 | 620 | ||
| @@ -739,8 +738,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c | |||
| 739 | static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) | 738 | static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) |
| 740 | { | 739 | { |
| 741 | struct sock *sk = sock->sk; | 740 | struct sock *sk = sock->sk; |
| 741 | struct sock *l2cap_sk; | ||
| 742 | struct l2cap_conn *conn; | ||
| 742 | struct rfcomm_conninfo cinfo; | 743 | struct rfcomm_conninfo cinfo; |
| 743 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; | ||
| 744 | int len, err = 0; | 744 | int len, err = 0; |
| 745 | u32 opt; | 745 | u32 opt; |
| 746 | 746 | ||
| @@ -783,6 +783,9 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
| 783 | break; | 783 | break; |
| 784 | } | 784 | } |
| 785 | 785 | ||
| 786 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; | ||
| 787 | conn = l2cap_pi(l2cap_sk)->chan->conn; | ||
| 788 | |||
| 786 | memset(&cinfo, 0, sizeof(cinfo)); | 789 | memset(&cinfo, 0, sizeof(cinfo)); |
| 787 | cinfo.hci_handle = conn->hcon->handle; | 790 | cinfo.hci_handle = conn->hcon->handle; |
| 788 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); | 791 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 12a0e51e21e1..24fa3964b3c8 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -711,7 +711,6 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 711 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { | 711 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { |
| 712 | sco_conn_defer_accept(pi->conn->hcon, pi->setting); | 712 | sco_conn_defer_accept(pi->conn->hcon, pi->setting); |
| 713 | sk->sk_state = BT_CONFIG; | 713 | sk->sk_state = BT_CONFIG; |
| 714 | msg->msg_namelen = 0; | ||
| 715 | 714 | ||
| 716 | release_sock(sk); | 715 | release_sock(sk); |
| 717 | return 0; | 716 | return 0; |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 85a2796cac61..4b07acb8293c 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
| @@ -742,6 +742,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
| 742 | 742 | ||
| 743 | BT_DBG("conn %p", conn); | 743 | BT_DBG("conn %p", conn); |
| 744 | 744 | ||
| 745 | if (!(conn->hcon->link_mode & HCI_LM_MASTER)) | ||
| 746 | return SMP_CMD_NOTSUPP; | ||
| 747 | |||
| 745 | hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); | 748 | hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); |
| 746 | 749 | ||
| 747 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) | 750 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 6e6194fcd88e..4bf02adb5dc2 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -172,6 +172,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) | |||
| 172 | del_nbp(p); | 172 | del_nbp(p); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | br_fdb_delete_by_port(br, NULL, 1); | ||
| 176 | |||
| 175 | br_vlan_flush(br); | 177 | br_vlan_flush(br); |
| 176 | del_timer_sync(&br->gc_timer); | 178 | del_timer_sync(&br->gc_timer); |
| 177 | 179 | ||
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 229d820bdf0b..045d56eaeca2 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
| @@ -426,6 +426,16 @@ netdev_features_t br_features_recompute(struct net_bridge *br, | |||
| 426 | int br_handle_frame_finish(struct sk_buff *skb); | 426 | int br_handle_frame_finish(struct sk_buff *skb); |
| 427 | rx_handler_result_t br_handle_frame(struct sk_buff **pskb); | 427 | rx_handler_result_t br_handle_frame(struct sk_buff **pskb); |
| 428 | 428 | ||
| 429 | static inline bool br_rx_handler_check_rcu(const struct net_device *dev) | ||
| 430 | { | ||
| 431 | return rcu_dereference(dev->rx_handler) == br_handle_frame; | ||
| 432 | } | ||
| 433 | |||
| 434 | static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev) | ||
| 435 | { | ||
| 436 | return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL; | ||
| 437 | } | ||
| 438 | |||
| 429 | /* br_ioctl.c */ | 439 | /* br_ioctl.c */ |
| 430 | int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 440 | int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
| 431 | int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, | 441 | int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 8660ea3be705..bdb459d21ad8 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
| @@ -153,7 +153,7 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, | |||
| 153 | if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) | 153 | if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) |
| 154 | goto err; | 154 | goto err; |
| 155 | 155 | ||
| 156 | p = br_port_get_rcu(dev); | 156 | p = br_port_get_check_rcu(dev); |
| 157 | if (!p) | 157 | if (!p) |
| 158 | goto err; | 158 | goto err; |
| 159 | 159 | ||
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c index 99c85668f551..17fd5f2cb4b8 100644 --- a/net/bridge/netfilter/ebt_ip6.c +++ b/net/bridge/netfilter/ebt_ip6.c | |||
| @@ -48,10 +48,12 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 48 | if (info->bitmask & EBT_IP6_TCLASS && | 48 | if (info->bitmask & EBT_IP6_TCLASS && |
| 49 | FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS)) | 49 | FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS)) |
| 50 | return false; | 50 | return false; |
| 51 | if (FWINV(ipv6_masked_addr_cmp(&ih6->saddr, &info->smsk, | 51 | if ((info->bitmask & EBT_IP6_SOURCE && |
| 52 | &info->saddr), EBT_IP6_SOURCE) || | 52 | FWINV(ipv6_masked_addr_cmp(&ih6->saddr, &info->smsk, |
| 53 | &info->saddr), EBT_IP6_SOURCE)) || | ||
| 54 | (info->bitmask & EBT_IP6_DEST && | ||
| 53 | FWINV(ipv6_masked_addr_cmp(&ih6->daddr, &info->dmsk, | 55 | FWINV(ipv6_masked_addr_cmp(&ih6->daddr, &info->dmsk, |
| 54 | &info->daddr), EBT_IP6_DEST)) | 56 | &info->daddr), EBT_IP6_DEST))) |
| 55 | return false; | 57 | return false; |
| 56 | if (info->bitmask & EBT_IP6_PROTO) { | 58 | if (info->bitmask & EBT_IP6_PROTO) { |
| 57 | uint8_t nexthdr = ih6->nexthdr; | 59 | uint8_t nexthdr = ih6->nexthdr; |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 05a41c7ec304..d6be3edb7a43 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
| @@ -286,8 +286,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 286 | if (m->msg_flags&MSG_OOB) | 286 | if (m->msg_flags&MSG_OOB) |
| 287 | goto read_error; | 287 | goto read_error; |
| 288 | 288 | ||
| 289 | m->msg_namelen = 0; | ||
| 290 | |||
| 291 | skb = skb_recv_datagram(sk, flags, 0 , &ret); | 289 | skb = skb_recv_datagram(sk, flags, 0 , &ret); |
| 292 | if (!skb) | 290 | if (!skb) |
| 293 | goto read_error; | 291 | goto read_error; |
| @@ -361,8 +359,6 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 361 | if (flags&MSG_OOB) | 359 | if (flags&MSG_OOB) |
| 362 | goto out; | 360 | goto out; |
| 363 | 361 | ||
| 364 | msg->msg_namelen = 0; | ||
| 365 | |||
| 366 | /* | 362 | /* |
| 367 | * Lock the socket to prevent queue disordering | 363 | * Lock the socket to prevent queue disordering |
| 368 | * while sleeps in memcpy_tomsg | 364 | * while sleeps in memcpy_tomsg |
diff --git a/net/compat.c b/net/compat.c index 89032580bd1d..dd32e34c1e2c 100644 --- a/net/compat.c +++ b/net/compat.c | |||
| @@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) | |||
| 72 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) | 72 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) |
| 73 | return -EFAULT; | 73 | return -EFAULT; |
| 74 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) | 74 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) |
| 75 | return -EINVAL; | 75 | kmsg->msg_namelen = sizeof(struct sockaddr_storage); |
| 76 | kmsg->msg_name = compat_ptr(tmp1); | 76 | kmsg->msg_name = compat_ptr(tmp1); |
| 77 | kmsg->msg_iov = compat_ptr(tmp2); | 77 | kmsg->msg_iov = compat_ptr(tmp2); |
| 78 | kmsg->msg_control = compat_ptr(tmp3); | 78 | kmsg->msg_control = compat_ptr(tmp3); |
| @@ -93,7 +93,8 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, | |||
| 93 | if (err < 0) | 93 | if (err < 0) |
| 94 | return err; | 94 | return err; |
| 95 | } | 95 | } |
| 96 | kern_msg->msg_name = kern_address; | 96 | if (kern_msg->msg_name) |
| 97 | kern_msg->msg_name = kern_address; | ||
| 97 | } else | 98 | } else |
| 98 | kern_msg->msg_name = NULL; | 99 | kern_msg->msg_name = NULL; |
| 99 | 100 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 7e00a7342ee6..ba3b7ea5ebb3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -4996,7 +4996,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags) | |||
| 4996 | { | 4996 | { |
| 4997 | const struct net_device_ops *ops = dev->netdev_ops; | 4997 | const struct net_device_ops *ops = dev->netdev_ops; |
| 4998 | 4998 | ||
| 4999 | if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags) | 4999 | if (ops->ndo_change_rx_flags) |
| 5000 | ops->ndo_change_rx_flags(dev, flags); | 5000 | ops->ndo_change_rx_flags(dev, flags); |
| 5001 | } | 5001 | } |
| 5002 | 5002 | ||
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 95897183226e..e70301eb7a4a 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
| @@ -64,7 +64,6 @@ static struct genl_family net_drop_monitor_family = { | |||
| 64 | .hdrsize = 0, | 64 | .hdrsize = 0, |
| 65 | .name = "NET_DM", | 65 | .name = "NET_DM", |
| 66 | .version = 2, | 66 | .version = 2, |
| 67 | .maxattr = NET_DM_CMD_MAX, | ||
| 68 | }; | 67 | }; |
| 69 | 68 | ||
| 70 | static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); | 69 | static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); |
diff --git a/net/core/iovec.c b/net/core/iovec.c index 4cdb7c48dad6..b61869429f4c 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
| @@ -48,7 +48,8 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a | |||
| 48 | if (err < 0) | 48 | if (err < 0) |
| 49 | return err; | 49 | return err; |
| 50 | } | 50 | } |
| 51 | m->msg_name = address; | 51 | if (m->msg_name) |
| 52 | m->msg_name = address; | ||
| 52 | } else { | 53 | } else { |
| 53 | m->msg_name = NULL; | 54 | m->msg_name = NULL; |
| 54 | } | 55 | } |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 261357a66300..a797fff7f222 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -2527,6 +2527,8 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, | |||
| 2527 | if (x) { | 2527 | if (x) { |
| 2528 | int ret; | 2528 | int ret; |
| 2529 | __u8 *eth; | 2529 | __u8 *eth; |
| 2530 | struct iphdr *iph; | ||
| 2531 | |||
| 2530 | nhead = x->props.header_len - skb_headroom(skb); | 2532 | nhead = x->props.header_len - skb_headroom(skb); |
| 2531 | if (nhead > 0) { | 2533 | if (nhead > 0) { |
| 2532 | ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); | 2534 | ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); |
| @@ -2548,6 +2550,11 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, | |||
| 2548 | eth = (__u8 *) skb_push(skb, ETH_HLEN); | 2550 | eth = (__u8 *) skb_push(skb, ETH_HLEN); |
| 2549 | memcpy(eth, pkt_dev->hh, 12); | 2551 | memcpy(eth, pkt_dev->hh, 12); |
| 2550 | *(u16 *) ð[12] = protocol; | 2552 | *(u16 *) ð[12] = protocol; |
| 2553 | |||
| 2554 | /* Update IPv4 header len as well as checksum value */ | ||
| 2555 | iph = ip_hdr(skb); | ||
| 2556 | iph->tot_len = htons(skb->len - ETH_HLEN); | ||
| 2557 | ip_send_check(iph); | ||
| 2551 | } | 2558 | } |
| 2552 | } | 2559 | } |
| 2553 | return 1; | 2560 | return 1; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 8cec1e6b844d..06e72d3cdf60 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -2796,6 +2796,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2796 | struct sk_buff *segs = NULL; | 2796 | struct sk_buff *segs = NULL; |
| 2797 | struct sk_buff *tail = NULL; | 2797 | struct sk_buff *tail = NULL; |
| 2798 | struct sk_buff *fskb = skb_shinfo(skb)->frag_list; | 2798 | struct sk_buff *fskb = skb_shinfo(skb)->frag_list; |
| 2799 | skb_frag_t *skb_frag = skb_shinfo(skb)->frags; | ||
| 2799 | unsigned int mss = skb_shinfo(skb)->gso_size; | 2800 | unsigned int mss = skb_shinfo(skb)->gso_size; |
| 2800 | unsigned int doffset = skb->data - skb_mac_header(skb); | 2801 | unsigned int doffset = skb->data - skb_mac_header(skb); |
| 2801 | unsigned int offset = doffset; | 2802 | unsigned int offset = doffset; |
| @@ -2835,16 +2836,38 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2835 | if (hsize > len || !sg) | 2836 | if (hsize > len || !sg) |
| 2836 | hsize = len; | 2837 | hsize = len; |
| 2837 | 2838 | ||
| 2838 | if (!hsize && i >= nfrags) { | 2839 | if (!hsize && i >= nfrags && skb_headlen(fskb) && |
| 2839 | BUG_ON(fskb->len != len); | 2840 | (skb_headlen(fskb) == len || sg)) { |
| 2841 | BUG_ON(skb_headlen(fskb) > len); | ||
| 2842 | |||
| 2843 | i = 0; | ||
| 2844 | nfrags = skb_shinfo(fskb)->nr_frags; | ||
| 2845 | skb_frag = skb_shinfo(fskb)->frags; | ||
| 2846 | pos += skb_headlen(fskb); | ||
| 2847 | |||
| 2848 | while (pos < offset + len) { | ||
| 2849 | BUG_ON(i >= nfrags); | ||
| 2850 | |||
| 2851 | size = skb_frag_size(skb_frag); | ||
| 2852 | if (pos + size > offset + len) | ||
| 2853 | break; | ||
| 2854 | |||
| 2855 | i++; | ||
| 2856 | pos += size; | ||
| 2857 | skb_frag++; | ||
| 2858 | } | ||
| 2840 | 2859 | ||
| 2841 | pos += len; | ||
| 2842 | nskb = skb_clone(fskb, GFP_ATOMIC); | 2860 | nskb = skb_clone(fskb, GFP_ATOMIC); |
| 2843 | fskb = fskb->next; | 2861 | fskb = fskb->next; |
| 2844 | 2862 | ||
| 2845 | if (unlikely(!nskb)) | 2863 | if (unlikely(!nskb)) |
| 2846 | goto err; | 2864 | goto err; |
| 2847 | 2865 | ||
| 2866 | if (unlikely(pskb_trim(nskb, len))) { | ||
| 2867 | kfree_skb(nskb); | ||
| 2868 | goto err; | ||
| 2869 | } | ||
| 2870 | |||
| 2848 | hsize = skb_end_offset(nskb); | 2871 | hsize = skb_end_offset(nskb); |
| 2849 | if (skb_cow_head(nskb, doffset + headroom)) { | 2872 | if (skb_cow_head(nskb, doffset + headroom)) { |
| 2850 | kfree_skb(nskb); | 2873 | kfree_skb(nskb); |
| @@ -2881,7 +2904,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2881 | nskb->data - tnl_hlen, | 2904 | nskb->data - tnl_hlen, |
| 2882 | doffset + tnl_hlen); | 2905 | doffset + tnl_hlen); |
| 2883 | 2906 | ||
| 2884 | if (fskb != skb_shinfo(skb)->frag_list) | 2907 | if (nskb->len == len + doffset) |
| 2885 | goto perform_csum_check; | 2908 | goto perform_csum_check; |
| 2886 | 2909 | ||
| 2887 | if (!sg) { | 2910 | if (!sg) { |
| @@ -2899,8 +2922,28 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2899 | 2922 | ||
| 2900 | skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; | 2923 | skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; |
| 2901 | 2924 | ||
| 2902 | while (pos < offset + len && i < nfrags) { | 2925 | while (pos < offset + len) { |
| 2903 | *frag = skb_shinfo(skb)->frags[i]; | 2926 | if (i >= nfrags) { |
| 2927 | BUG_ON(skb_headlen(fskb)); | ||
| 2928 | |||
| 2929 | i = 0; | ||
| 2930 | nfrags = skb_shinfo(fskb)->nr_frags; | ||
| 2931 | skb_frag = skb_shinfo(fskb)->frags; | ||
| 2932 | |||
| 2933 | BUG_ON(!nfrags); | ||
| 2934 | |||
| 2935 | fskb = fskb->next; | ||
| 2936 | } | ||
| 2937 | |||
| 2938 | if (unlikely(skb_shinfo(nskb)->nr_frags >= | ||
| 2939 | MAX_SKB_FRAGS)) { | ||
| 2940 | net_warn_ratelimited( | ||
| 2941 | "skb_segment: too many frags: %u %u\n", | ||
| 2942 | pos, mss); | ||
| 2943 | goto err; | ||
| 2944 | } | ||
| 2945 | |||
| 2946 | *frag = *skb_frag; | ||
| 2904 | __skb_frag_ref(frag); | 2947 | __skb_frag_ref(frag); |
| 2905 | size = skb_frag_size(frag); | 2948 | size = skb_frag_size(frag); |
| 2906 | 2949 | ||
| @@ -2913,6 +2956,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2913 | 2956 | ||
| 2914 | if (pos + size <= offset + len) { | 2957 | if (pos + size <= offset + len) { |
| 2915 | i++; | 2958 | i++; |
| 2959 | skb_frag++; | ||
| 2916 | pos += size; | 2960 | pos += size; |
| 2917 | } else { | 2961 | } else { |
| 2918 | skb_frag_size_sub(frag, pos + size - (offset + len)); | 2962 | skb_frag_size_sub(frag, pos + size - (offset + len)); |
| @@ -2922,25 +2966,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2922 | frag++; | 2966 | frag++; |
| 2923 | } | 2967 | } |
| 2924 | 2968 | ||
| 2925 | if (pos < offset + len) { | ||
| 2926 | struct sk_buff *fskb2 = fskb; | ||
| 2927 | |||
| 2928 | BUG_ON(pos + fskb->len != offset + len); | ||
| 2929 | |||
| 2930 | pos += fskb->len; | ||
| 2931 | fskb = fskb->next; | ||
| 2932 | |||
| 2933 | if (fskb2->next) { | ||
| 2934 | fskb2 = skb_clone(fskb2, GFP_ATOMIC); | ||
| 2935 | if (!fskb2) | ||
| 2936 | goto err; | ||
| 2937 | } else | ||
| 2938 | skb_get(fskb2); | ||
| 2939 | |||
| 2940 | SKB_FRAG_ASSERT(nskb); | ||
| 2941 | skb_shinfo(nskb)->frag_list = fskb2; | ||
| 2942 | } | ||
| 2943 | |||
| 2944 | skip_fraglist: | 2969 | skip_fraglist: |
| 2945 | nskb->data_len = len - hsize; | 2970 | nskb->data_len = len - hsize; |
| 2946 | nskb->len += nskb->data_len; | 2971 | nskb->len += nskb->data_len; |
| @@ -3559,6 +3584,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
| 3559 | skb->tstamp.tv64 = 0; | 3584 | skb->tstamp.tv64 = 0; |
| 3560 | skb->pkt_type = PACKET_HOST; | 3585 | skb->pkt_type = PACKET_HOST; |
| 3561 | skb->skb_iif = 0; | 3586 | skb->skb_iif = 0; |
| 3587 | skb->local_df = 0; | ||
| 3562 | skb_dst_drop(skb); | 3588 | skb_dst_drop(skb); |
| 3563 | skb->mark = 0; | 3589 | skb->mark = 0; |
| 3564 | secpath_reset(skb); | 3590 | secpath_reset(skb); |
diff --git a/net/core/sock.c b/net/core/sock.c index ab20ed9b0f31..5393b4b719d7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -882,7 +882,7 @@ set_rcvbuf: | |||
| 882 | 882 | ||
| 883 | case SO_PEEK_OFF: | 883 | case SO_PEEK_OFF: |
| 884 | if (sock->ops->set_peek_off) | 884 | if (sock->ops->set_peek_off) |
| 885 | sock->ops->set_peek_off(sk, val); | 885 | ret = sock->ops->set_peek_off(sk, val); |
| 886 | else | 886 | else |
| 887 | ret = -EOPNOTSUPP; | 887 | ret = -EOPNOTSUPP; |
| 888 | break; | 888 | break; |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 4ac71ff7c2e4..2b90a786e475 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
| @@ -851,7 +851,6 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
| 851 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 851 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 852 | if (flowlabel == NULL) | 852 | if (flowlabel == NULL) |
| 853 | return -EINVAL; | 853 | return -EINVAL; |
| 854 | usin->sin6_addr = flowlabel->dst; | ||
| 855 | fl6_sock_release(flowlabel); | 854 | fl6_sock_release(flowlabel); |
| 856 | } | 855 | } |
| 857 | } | 856 | } |
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 003f5bb3acd2..4bdab1521878 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c | |||
| @@ -288,7 +288,8 @@ void hsr_addr_subst_dest(struct hsr_priv *hsr_priv, struct ethhdr *ethhdr, | |||
| 288 | static bool seq_nr_after(u16 a, u16 b) | 288 | static bool seq_nr_after(u16 a, u16 b) |
| 289 | { | 289 | { |
| 290 | /* Remove inconsistency where | 290 | /* Remove inconsistency where |
| 291 | * seq_nr_after(a, b) == seq_nr_before(a, b) */ | 291 | * seq_nr_after(a, b) == seq_nr_before(a, b) |
| 292 | */ | ||
| 292 | if ((int) b - a == 32768) | 293 | if ((int) b - a == 32768) |
| 293 | return false; | 294 | return false; |
| 294 | 295 | ||
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c index 5325af85eea6..01a5261ac7a5 100644 --- a/net/hsr/hsr_netlink.c +++ b/net/hsr/hsr_netlink.c | |||
| @@ -23,6 +23,8 @@ static const struct nla_policy hsr_policy[IFLA_HSR_MAX + 1] = { | |||
| 23 | [IFLA_HSR_SLAVE1] = { .type = NLA_U32 }, | 23 | [IFLA_HSR_SLAVE1] = { .type = NLA_U32 }, |
| 24 | [IFLA_HSR_SLAVE2] = { .type = NLA_U32 }, | 24 | [IFLA_HSR_SLAVE2] = { .type = NLA_U32 }, |
| 25 | [IFLA_HSR_MULTICAST_SPEC] = { .type = NLA_U8 }, | 25 | [IFLA_HSR_MULTICAST_SPEC] = { .type = NLA_U8 }, |
| 26 | [IFLA_HSR_SUPERVISION_ADDR] = { .type = NLA_BINARY, .len = ETH_ALEN }, | ||
| 27 | [IFLA_HSR_SEQ_NR] = { .type = NLA_U16 }, | ||
| 26 | }; | 28 | }; |
| 27 | 29 | ||
| 28 | 30 | ||
| @@ -59,6 +61,31 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev, | |||
| 59 | return hsr_dev_finalize(dev, link, multicast_spec); | 61 | return hsr_dev_finalize(dev, link, multicast_spec); |
| 60 | } | 62 | } |
| 61 | 63 | ||
| 64 | static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
| 65 | { | ||
| 66 | struct hsr_priv *hsr_priv; | ||
| 67 | |||
| 68 | hsr_priv = netdev_priv(dev); | ||
| 69 | |||
| 70 | if (hsr_priv->slave[0]) | ||
| 71 | if (nla_put_u32(skb, IFLA_HSR_SLAVE1, hsr_priv->slave[0]->ifindex)) | ||
| 72 | goto nla_put_failure; | ||
| 73 | |||
| 74 | if (hsr_priv->slave[1]) | ||
| 75 | if (nla_put_u32(skb, IFLA_HSR_SLAVE2, hsr_priv->slave[1]->ifindex)) | ||
| 76 | goto nla_put_failure; | ||
| 77 | |||
| 78 | if (nla_put(skb, IFLA_HSR_SUPERVISION_ADDR, ETH_ALEN, | ||
| 79 | hsr_priv->sup_multicast_addr) || | ||
| 80 | nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr_priv->sequence_nr)) | ||
| 81 | goto nla_put_failure; | ||
| 82 | |||
| 83 | return 0; | ||
| 84 | |||
| 85 | nla_put_failure: | ||
| 86 | return -EMSGSIZE; | ||
| 87 | } | ||
| 88 | |||
| 62 | static struct rtnl_link_ops hsr_link_ops __read_mostly = { | 89 | static struct rtnl_link_ops hsr_link_ops __read_mostly = { |
| 63 | .kind = "hsr", | 90 | .kind = "hsr", |
| 64 | .maxtype = IFLA_HSR_MAX, | 91 | .maxtype = IFLA_HSR_MAX, |
| @@ -66,6 +93,7 @@ static struct rtnl_link_ops hsr_link_ops __read_mostly = { | |||
| 66 | .priv_size = sizeof(struct hsr_priv), | 93 | .priv_size = sizeof(struct hsr_priv), |
| 67 | .setup = hsr_dev_setup, | 94 | .setup = hsr_dev_setup, |
| 68 | .newlink = hsr_newlink, | 95 | .newlink = hsr_newlink, |
| 96 | .fill_info = hsr_fill_info, | ||
| 69 | }; | 97 | }; |
| 70 | 98 | ||
| 71 | 99 | ||
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 523be38e37de..f2e15738534d 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
| @@ -104,7 +104,10 @@ errout: | |||
| 104 | static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) | 104 | static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) |
| 105 | { | 105 | { |
| 106 | struct fib_result *result = (struct fib_result *) arg->result; | 106 | struct fib_result *result = (struct fib_result *) arg->result; |
| 107 | struct net_device *dev = result->fi->fib_dev; | 107 | struct net_device *dev = NULL; |
| 108 | |||
| 109 | if (result->fi) | ||
| 110 | dev = result->fi->fib_dev; | ||
| 108 | 111 | ||
| 109 | /* do not accept result if the route does | 112 | /* do not accept result if the route does |
| 110 | * not meet the required prefix length | 113 | * not meet the required prefix length |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 3f858266fa7e..ddf32a6bc415 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -386,7 +386,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf | |||
| 386 | /* | 386 | /* |
| 387 | * Handle MSG_ERRQUEUE | 387 | * Handle MSG_ERRQUEUE |
| 388 | */ | 388 | */ |
| 389 | int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) | 389 | int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
| 390 | { | 390 | { |
| 391 | struct sock_exterr_skb *serr; | 391 | struct sock_exterr_skb *serr; |
| 392 | struct sk_buff *skb, *skb2; | 392 | struct sk_buff *skb, *skb2; |
| @@ -423,6 +423,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
| 423 | serr->addr_offset); | 423 | serr->addr_offset); |
| 424 | sin->sin_port = serr->port; | 424 | sin->sin_port = serr->port; |
| 425 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); | 425 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
| 426 | *addr_len = sizeof(*sin); | ||
| 426 | } | 427 | } |
| 427 | 428 | ||
| 428 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); | 429 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 01cffeaa0085..f13bd91d9a56 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c | |||
| @@ -244,6 +244,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet, | |||
| 244 | 244 | ||
| 245 | this_cpu_inc(snet->stats->cookie_valid); | 245 | this_cpu_inc(snet->stats->cookie_valid); |
| 246 | opts->mss = mss; | 246 | opts->mss = mss; |
| 247 | opts->options |= XT_SYNPROXY_OPT_MSS; | ||
| 247 | 248 | ||
| 248 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) | 249 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) |
| 249 | synproxy_check_timestamp_cookie(opts); | 250 | synproxy_check_timestamp_cookie(opts); |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 876c6ca2d8f9..242e7f4ed6f4 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -772,7 +772,7 @@ int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 772 | err = PTR_ERR(rt); | 772 | err = PTR_ERR(rt); |
| 773 | rt = NULL; | 773 | rt = NULL; |
| 774 | if (err == -ENETUNREACH) | 774 | if (err == -ENETUNREACH) |
| 775 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); | 775 | IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); |
| 776 | goto out; | 776 | goto out; |
| 777 | } | 777 | } |
| 778 | 778 | ||
| @@ -841,10 +841,11 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 841 | 841 | ||
| 842 | if (flags & MSG_ERRQUEUE) { | 842 | if (flags & MSG_ERRQUEUE) { |
| 843 | if (family == AF_INET) { | 843 | if (family == AF_INET) { |
| 844 | return ip_recv_error(sk, msg, len); | 844 | return ip_recv_error(sk, msg, len, addr_len); |
| 845 | #if IS_ENABLED(CONFIG_IPV6) | 845 | #if IS_ENABLED(CONFIG_IPV6) |
| 846 | } else if (family == AF_INET6) { | 846 | } else if (family == AF_INET6) { |
| 847 | return pingv6_ops.ipv6_recv_error(sk, msg, len); | 847 | return pingv6_ops.ipv6_recv_error(sk, msg, len, |
| 848 | addr_len); | ||
| 848 | #endif | 849 | #endif |
| 849 | } | 850 | } |
| 850 | } | 851 | } |
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index ce848461acbb..46d6a1c923a8 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c | |||
| @@ -31,10 +31,6 @@ | |||
| 31 | const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly; | 31 | const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly; |
| 32 | const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly; | 32 | const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly; |
| 33 | 33 | ||
| 34 | /* | ||
| 35 | * Add a protocol handler to the hash tables | ||
| 36 | */ | ||
| 37 | |||
| 38 | int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) | 34 | int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) |
| 39 | { | 35 | { |
| 40 | if (!prot->netns_ok) { | 36 | if (!prot->netns_ok) { |
| @@ -55,10 +51,6 @@ int inet_add_offload(const struct net_offload *prot, unsigned char protocol) | |||
| 55 | } | 51 | } |
| 56 | EXPORT_SYMBOL(inet_add_offload); | 52 | EXPORT_SYMBOL(inet_add_offload); |
| 57 | 53 | ||
| 58 | /* | ||
| 59 | * Remove a protocol from the hash tables. | ||
| 60 | */ | ||
| 61 | |||
| 62 | int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) | 54 | int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) |
| 63 | { | 55 | { |
| 64 | int ret; | 56 | int ret; |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 5cb8ddb505ee..23c3e5b5bb53 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -697,7 +697,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 697 | goto out; | 697 | goto out; |
| 698 | 698 | ||
| 699 | if (flags & MSG_ERRQUEUE) { | 699 | if (flags & MSG_ERRQUEUE) { |
| 700 | err = ip_recv_error(sk, msg, len); | 700 | err = ip_recv_error(sk, msg, len, addr_len); |
| 701 | goto out; | 701 | goto out; |
| 702 | } | 702 | } |
| 703 | 703 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index f428935c50db..f8da28278014 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1776,8 +1776,12 @@ local_input: | |||
| 1776 | rth->dst.error= -err; | 1776 | rth->dst.error= -err; |
| 1777 | rth->rt_flags &= ~RTCF_LOCAL; | 1777 | rth->rt_flags &= ~RTCF_LOCAL; |
| 1778 | } | 1778 | } |
| 1779 | if (do_cache) | 1779 | if (do_cache) { |
| 1780 | rt_cache_route(&FIB_RES_NH(res), rth); | 1780 | if (unlikely(!rt_cache_route(&FIB_RES_NH(res), rth))) { |
| 1781 | rth->dst.flags |= DST_NOCACHE; | ||
| 1782 | rt_add_uncached_list(rth); | ||
| 1783 | } | ||
| 1784 | } | ||
| 1781 | skb_dst_set(skb, &rth->dst); | 1785 | skb_dst_set(skb, &rth->dst); |
| 1782 | err = 0; | 1786 | err = 0; |
| 1783 | goto out; | 1787 | goto out; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 3dc0c6cf02a8..c4638e6f0238 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1425,7 +1425,7 @@ static void tcp_service_net_dma(struct sock *sk, bool wait) | |||
| 1425 | do { | 1425 | do { |
| 1426 | if (dma_async_is_tx_complete(tp->ucopy.dma_chan, | 1426 | if (dma_async_is_tx_complete(tp->ucopy.dma_chan, |
| 1427 | last_issued, &done, | 1427 | last_issued, &done, |
| 1428 | &used) == DMA_SUCCESS) { | 1428 | &used) == DMA_COMPLETE) { |
| 1429 | /* Safe to free early-copied skbs now */ | 1429 | /* Safe to free early-copied skbs now */ |
| 1430 | __skb_queue_purge(&sk->sk_async_wait_queue); | 1430 | __skb_queue_purge(&sk->sk_async_wait_queue); |
| 1431 | break; | 1431 | break; |
| @@ -1433,7 +1433,7 @@ static void tcp_service_net_dma(struct sock *sk, bool wait) | |||
| 1433 | struct sk_buff *skb; | 1433 | struct sk_buff *skb; |
| 1434 | while ((skb = skb_peek(&sk->sk_async_wait_queue)) && | 1434 | while ((skb = skb_peek(&sk->sk_async_wait_queue)) && |
| 1435 | (dma_async_is_complete(skb->dma_cookie, done, | 1435 | (dma_async_is_complete(skb->dma_cookie, done, |
| 1436 | used) == DMA_SUCCESS)) { | 1436 | used) == DMA_COMPLETE)) { |
| 1437 | __skb_dequeue(&sk->sk_async_wait_queue); | 1437 | __skb_dequeue(&sk->sk_async_wait_queue); |
| 1438 | kfree_skb(skb); | 1438 | kfree_skb(skb); |
| 1439 | } | 1439 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 59a6f8b90cd9..067213924751 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -177,7 +177,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
| 177 | if (IS_ERR(rt)) { | 177 | if (IS_ERR(rt)) { |
| 178 | err = PTR_ERR(rt); | 178 | err = PTR_ERR(rt); |
| 179 | if (err == -ENETUNREACH) | 179 | if (err == -ENETUNREACH) |
| 180 | IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); | 180 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
| 181 | return err; | 181 | return err; |
| 182 | } | 182 | } |
| 183 | 183 | ||
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index 03e9154f7e68..f7e522c558ba 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c | |||
| @@ -6,13 +6,6 @@ | |||
| 6 | #include <linux/memcontrol.h> | 6 | #include <linux/memcontrol.h> |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | 8 | ||
| 9 | static void memcg_tcp_enter_memory_pressure(struct sock *sk) | ||
| 10 | { | ||
| 11 | if (sk->sk_cgrp->memory_pressure) | ||
| 12 | sk->sk_cgrp->memory_pressure = 1; | ||
| 13 | } | ||
| 14 | EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure); | ||
| 15 | |||
| 16 | int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) | 9 | int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) |
| 17 | { | 10 | { |
| 18 | /* | 11 | /* |
| @@ -60,7 +53,6 @@ EXPORT_SYMBOL(tcp_destroy_cgroup); | |||
| 60 | static int tcp_update_limit(struct mem_cgroup *memcg, u64 val) | 53 | static int tcp_update_limit(struct mem_cgroup *memcg, u64 val) |
| 61 | { | 54 | { |
| 62 | struct cg_proto *cg_proto; | 55 | struct cg_proto *cg_proto; |
| 63 | u64 old_lim; | ||
| 64 | int i; | 56 | int i; |
| 65 | int ret; | 57 | int ret; |
| 66 | 58 | ||
| @@ -71,7 +63,6 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val) | |||
| 71 | if (val > RES_COUNTER_MAX) | 63 | if (val > RES_COUNTER_MAX) |
| 72 | val = RES_COUNTER_MAX; | 64 | val = RES_COUNTER_MAX; |
| 73 | 65 | ||
| 74 | old_lim = res_counter_read_u64(&cg_proto->memory_allocated, RES_LIMIT); | ||
| 75 | ret = res_counter_set_limit(&cg_proto->memory_allocated, val); | 66 | ret = res_counter_set_limit(&cg_proto->memory_allocated, val); |
| 76 | if (ret) | 67 | if (ret) |
| 77 | return ret; | 68 | return ret; |
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c index a2b68a108eae..05606353c7e7 100644 --- a/net/ipv4/tcp_offload.c +++ b/net/ipv4/tcp_offload.c | |||
| @@ -274,33 +274,32 @@ static struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff * | |||
| 274 | { | 274 | { |
| 275 | const struct iphdr *iph = skb_gro_network_header(skb); | 275 | const struct iphdr *iph = skb_gro_network_header(skb); |
| 276 | __wsum wsum; | 276 | __wsum wsum; |
| 277 | __sum16 sum; | 277 | |
| 278 | /* Don't bother verifying checksum if we're going to flush anyway. */ | ||
| 279 | if (NAPI_GRO_CB(skb)->flush) | ||
| 280 | goto skip_csum; | ||
| 281 | |||
| 282 | wsum = skb->csum; | ||
| 278 | 283 | ||
| 279 | switch (skb->ip_summed) { | 284 | switch (skb->ip_summed) { |
| 285 | case CHECKSUM_NONE: | ||
| 286 | wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb), | ||
| 287 | 0); | ||
| 288 | |||
| 289 | /* fall through */ | ||
| 290 | |||
| 280 | case CHECKSUM_COMPLETE: | 291 | case CHECKSUM_COMPLETE: |
| 281 | if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr, | 292 | if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr, |
| 282 | skb->csum)) { | 293 | wsum)) { |
| 283 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 294 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 284 | break; | 295 | break; |
| 285 | } | 296 | } |
| 286 | flush: | 297 | |
| 287 | NAPI_GRO_CB(skb)->flush = 1; | 298 | NAPI_GRO_CB(skb)->flush = 1; |
| 288 | return NULL; | 299 | return NULL; |
| 289 | |||
| 290 | case CHECKSUM_NONE: | ||
| 291 | wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr, | ||
| 292 | skb_gro_len(skb), IPPROTO_TCP, 0); | ||
| 293 | sum = csum_fold(skb_checksum(skb, | ||
| 294 | skb_gro_offset(skb), | ||
| 295 | skb_gro_len(skb), | ||
| 296 | wsum)); | ||
| 297 | if (sum) | ||
| 298 | goto flush; | ||
| 299 | |||
| 300 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 301 | break; | ||
| 302 | } | 300 | } |
| 303 | 301 | ||
| 302 | skip_csum: | ||
| 304 | return tcp_gro_receive(head, skb); | 303 | return tcp_gro_receive(head, skb); |
| 305 | } | 304 | } |
| 306 | 305 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5944d7d668dd..62c19fdd102d 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -560,15 +560,11 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb, | |||
| 560 | __be16 sport, __be16 dport, | 560 | __be16 sport, __be16 dport, |
| 561 | struct udp_table *udptable) | 561 | struct udp_table *udptable) |
| 562 | { | 562 | { |
| 563 | struct sock *sk; | ||
| 564 | const struct iphdr *iph = ip_hdr(skb); | 563 | const struct iphdr *iph = ip_hdr(skb); |
| 565 | 564 | ||
| 566 | if (unlikely(sk = skb_steal_sock(skb))) | 565 | return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport, |
| 567 | return sk; | 566 | iph->daddr, dport, inet_iif(skb), |
| 568 | else | 567 | udptable); |
| 569 | return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport, | ||
| 570 | iph->daddr, dport, inet_iif(skb), | ||
| 571 | udptable); | ||
| 572 | } | 568 | } |
| 573 | 569 | ||
| 574 | struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, | 570 | struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, |
| @@ -999,7 +995,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 999 | err = PTR_ERR(rt); | 995 | err = PTR_ERR(rt); |
| 1000 | rt = NULL; | 996 | rt = NULL; |
| 1001 | if (err == -ENETUNREACH) | 997 | if (err == -ENETUNREACH) |
| 1002 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); | 998 | IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); |
| 1003 | goto out; | 999 | goto out; |
| 1004 | } | 1000 | } |
| 1005 | 1001 | ||
| @@ -1098,6 +1094,9 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset, | |||
| 1098 | struct udp_sock *up = udp_sk(sk); | 1094 | struct udp_sock *up = udp_sk(sk); |
| 1099 | int ret; | 1095 | int ret; |
| 1100 | 1096 | ||
| 1097 | if (flags & MSG_SENDPAGE_NOTLAST) | ||
| 1098 | flags |= MSG_MORE; | ||
| 1099 | |||
| 1101 | if (!up->pending) { | 1100 | if (!up->pending) { |
| 1102 | struct msghdr msg = { .msg_flags = flags|MSG_MORE }; | 1101 | struct msghdr msg = { .msg_flags = flags|MSG_MORE }; |
| 1103 | 1102 | ||
| @@ -1236,7 +1235,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1236 | bool slow; | 1235 | bool slow; |
| 1237 | 1236 | ||
| 1238 | if (flags & MSG_ERRQUEUE) | 1237 | if (flags & MSG_ERRQUEUE) |
| 1239 | return ip_recv_error(sk, msg, len); | 1238 | return ip_recv_error(sk, msg, len, addr_len); |
| 1240 | 1239 | ||
| 1241 | try_again: | 1240 | try_again: |
| 1242 | skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), | 1241 | skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), |
| @@ -1600,12 +1599,21 @@ static void flush_stack(struct sock **stack, unsigned int count, | |||
| 1600 | kfree_skb(skb1); | 1599 | kfree_skb(skb1); |
| 1601 | } | 1600 | } |
| 1602 | 1601 | ||
| 1603 | static void udp_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) | 1602 | /* For TCP sockets, sk_rx_dst is protected by socket lock |
| 1603 | * For UDP, we use sk_dst_lock to guard against concurrent changes. | ||
| 1604 | */ | ||
| 1605 | static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) | ||
| 1604 | { | 1606 | { |
| 1605 | struct dst_entry *dst = skb_dst(skb); | 1607 | struct dst_entry *old; |
| 1606 | 1608 | ||
| 1607 | dst_hold(dst); | 1609 | spin_lock(&sk->sk_dst_lock); |
| 1608 | sk->sk_rx_dst = dst; | 1610 | old = sk->sk_rx_dst; |
| 1611 | if (likely(old != dst)) { | ||
| 1612 | dst_hold(dst); | ||
| 1613 | sk->sk_rx_dst = dst; | ||
| 1614 | dst_release(old); | ||
| 1615 | } | ||
| 1616 | spin_unlock(&sk->sk_dst_lock); | ||
| 1609 | } | 1617 | } |
| 1610 | 1618 | ||
| 1611 | /* | 1619 | /* |
| @@ -1736,15 +1744,16 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
| 1736 | if (udp4_csum_init(skb, uh, proto)) | 1744 | if (udp4_csum_init(skb, uh, proto)) |
| 1737 | goto csum_error; | 1745 | goto csum_error; |
| 1738 | 1746 | ||
| 1739 | if (skb->sk) { | 1747 | sk = skb_steal_sock(skb); |
| 1748 | if (sk) { | ||
| 1749 | struct dst_entry *dst = skb_dst(skb); | ||
| 1740 | int ret; | 1750 | int ret; |
| 1741 | sk = skb->sk; | ||
| 1742 | 1751 | ||
| 1743 | if (unlikely(sk->sk_rx_dst == NULL)) | 1752 | if (unlikely(sk->sk_rx_dst != dst)) |
| 1744 | udp_sk_rx_dst_set(sk, skb); | 1753 | udp_sk_rx_dst_set(sk, dst); |
| 1745 | 1754 | ||
| 1746 | ret = udp_queue_rcv_skb(sk, skb); | 1755 | ret = udp_queue_rcv_skb(sk, skb); |
| 1747 | 1756 | sock_put(sk); | |
| 1748 | /* a return value > 0 means to resubmit the input, but | 1757 | /* a return value > 0 means to resubmit the input, but |
| 1749 | * it wants the return to be -protocol, or 0 | 1758 | * it wants the return to be -protocol, or 0 |
| 1750 | */ | 1759 | */ |
| @@ -1910,17 +1919,20 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net, | |||
| 1910 | 1919 | ||
| 1911 | void udp_v4_early_demux(struct sk_buff *skb) | 1920 | void udp_v4_early_demux(struct sk_buff *skb) |
| 1912 | { | 1921 | { |
| 1913 | const struct iphdr *iph = ip_hdr(skb); | 1922 | struct net *net = dev_net(skb->dev); |
| 1914 | const struct udphdr *uh = udp_hdr(skb); | 1923 | const struct iphdr *iph; |
| 1924 | const struct udphdr *uh; | ||
| 1915 | struct sock *sk; | 1925 | struct sock *sk; |
| 1916 | struct dst_entry *dst; | 1926 | struct dst_entry *dst; |
| 1917 | struct net *net = dev_net(skb->dev); | ||
| 1918 | int dif = skb->dev->ifindex; | 1927 | int dif = skb->dev->ifindex; |
| 1919 | 1928 | ||
| 1920 | /* validate the packet */ | 1929 | /* validate the packet */ |
| 1921 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) | 1930 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) |
| 1922 | return; | 1931 | return; |
| 1923 | 1932 | ||
| 1933 | iph = ip_hdr(skb); | ||
| 1934 | uh = udp_hdr(skb); | ||
| 1935 | |||
| 1924 | if (skb->pkt_type == PACKET_BROADCAST || | 1936 | if (skb->pkt_type == PACKET_BROADCAST || |
| 1925 | skb->pkt_type == PACKET_MULTICAST) | 1937 | skb->pkt_type == PACKET_MULTICAST) |
| 1926 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, | 1938 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 12c97d8aa6bb..d5fa5b8c443e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2613,7 +2613,7 @@ static void init_loopback(struct net_device *dev) | |||
| 2613 | if (sp_ifa->rt) | 2613 | if (sp_ifa->rt) |
| 2614 | continue; | 2614 | continue; |
| 2615 | 2615 | ||
| 2616 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); | 2616 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false); |
| 2617 | 2617 | ||
| 2618 | /* Failure cases are ignored */ | 2618 | /* Failure cases are ignored */ |
| 2619 | if (!IS_ERR(sp_rt)) { | 2619 | if (!IS_ERR(sp_rt)) { |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index a454b0ff57c7..93b1aa34c432 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
| @@ -73,7 +73,6 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
| 73 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 73 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 74 | if (flowlabel == NULL) | 74 | if (flowlabel == NULL) |
| 75 | return -EINVAL; | 75 | return -EINVAL; |
| 76 | usin->sin6_addr = flowlabel->dst; | ||
| 77 | } | 76 | } |
| 78 | } | 77 | } |
| 79 | 78 | ||
| @@ -318,7 +317,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) | |||
| 318 | /* | 317 | /* |
| 319 | * Handle MSG_ERRQUEUE | 318 | * Handle MSG_ERRQUEUE |
| 320 | */ | 319 | */ |
| 321 | int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | 320 | int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
| 322 | { | 321 | { |
| 323 | struct ipv6_pinfo *np = inet6_sk(sk); | 322 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 324 | struct sock_exterr_skb *serr; | 323 | struct sock_exterr_skb *serr; |
| @@ -369,6 +368,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
| 369 | &sin->sin6_addr); | 368 | &sin->sin6_addr); |
| 370 | sin->sin6_scope_id = 0; | 369 | sin->sin6_scope_id = 0; |
| 371 | } | 370 | } |
| 371 | *addr_len = sizeof(*sin); | ||
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); | 374 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
| @@ -377,6 +377,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
| 377 | if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { | 377 | if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { |
| 378 | sin->sin6_family = AF_INET6; | 378 | sin->sin6_family = AF_INET6; |
| 379 | sin->sin6_flowinfo = 0; | 379 | sin->sin6_flowinfo = 0; |
| 380 | sin->sin6_port = 0; | ||
| 380 | if (skb->protocol == htons(ETH_P_IPV6)) { | 381 | if (skb->protocol == htons(ETH_P_IPV6)) { |
| 381 | sin->sin6_addr = ipv6_hdr(skb)->saddr; | 382 | sin->sin6_addr = ipv6_hdr(skb)->saddr; |
| 382 | if (np->rxopt.all) | 383 | if (np->rxopt.all) |
| @@ -423,7 +424,8 @@ EXPORT_SYMBOL_GPL(ipv6_recv_error); | |||
| 423 | /* | 424 | /* |
| 424 | * Handle IPV6_RECVPATHMTU | 425 | * Handle IPV6_RECVPATHMTU |
| 425 | */ | 426 | */ |
| 426 | int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) | 427 | int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len, |
| 428 | int *addr_len) | ||
| 427 | { | 429 | { |
| 428 | struct ipv6_pinfo *np = inet6_sk(sk); | 430 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 429 | struct sk_buff *skb; | 431 | struct sk_buff *skb; |
| @@ -457,6 +459,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) | |||
| 457 | sin->sin6_port = 0; | 459 | sin->sin6_port = 0; |
| 458 | sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id; | 460 | sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id; |
| 459 | sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr; | 461 | sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr; |
| 462 | *addr_len = sizeof(*sin); | ||
| 460 | } | 463 | } |
| 461 | 464 | ||
| 462 | put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info); | 465 | put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info); |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index e27591635f92..3fd0a578329e 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
| @@ -122,7 +122,11 @@ out: | |||
| 122 | static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) | 122 | static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) |
| 123 | { | 123 | { |
| 124 | struct rt6_info *rt = (struct rt6_info *) arg->result; | 124 | struct rt6_info *rt = (struct rt6_info *) arg->result; |
| 125 | struct net_device *dev = rt->rt6i_idev->dev; | 125 | struct net_device *dev = NULL; |
| 126 | |||
| 127 | if (rt->rt6i_idev) | ||
| 128 | dev = rt->rt6i_idev->dev; | ||
| 129 | |||
| 126 | /* do not accept result if the route does | 130 | /* do not accept result if the route does |
| 127 | * not meet the required prefix length | 131 | * not meet the required prefix length |
| 128 | */ | 132 | */ |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 59df872e2f4d..4acdb63495db 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -116,8 +116,8 @@ static int ip6_finish_output2(struct sk_buff *skb) | |||
| 116 | } | 116 | } |
| 117 | rcu_read_unlock_bh(); | 117 | rcu_read_unlock_bh(); |
| 118 | 118 | ||
| 119 | IP6_INC_STATS_BH(dev_net(dst->dev), | 119 | IP6_INC_STATS(dev_net(dst->dev), |
| 120 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | 120 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
| 121 | kfree_skb(skb); | 121 | kfree_skb(skb); |
| 122 | return -EINVAL; | 122 | return -EINVAL; |
| 123 | } | 123 | } |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 3512177deb4d..300865171394 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1277,6 +1277,9 @@ skip_linkparms: | |||
| 1277 | ri->prefix_len == 0) | 1277 | ri->prefix_len == 0) |
| 1278 | continue; | 1278 | continue; |
| 1279 | #endif | 1279 | #endif |
| 1280 | if (ri->prefix_len == 0 && | ||
| 1281 | !in6_dev->cnf.accept_ra_defrtr) | ||
| 1282 | continue; | ||
| 1280 | if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) | 1283 | if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) |
| 1281 | continue; | 1284 | continue; |
| 1282 | rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, | 1285 | rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, |
diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index bf9f612c1bc2..f78f41aca8e9 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c | |||
| @@ -259,6 +259,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet, | |||
| 259 | 259 | ||
| 260 | this_cpu_inc(snet->stats->cookie_valid); | 260 | this_cpu_inc(snet->stats->cookie_valid); |
| 261 | opts->mss = mss; | 261 | opts->mss = mss; |
| 262 | opts->options |= XT_SYNPROXY_OPT_MSS; | ||
| 262 | 263 | ||
| 263 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) | 264 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) |
| 264 | synproxy_check_timestamp_cookie(opts); | 265 | synproxy_check_timestamp_cookie(opts); |
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 8815e31a87fe..a83243c3d656 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
| @@ -57,7 +57,8 @@ static struct inet_protosw pingv6_protosw = { | |||
| 57 | 57 | ||
| 58 | 58 | ||
| 59 | /* Compatibility glue so we can support IPv6 when it's compiled as a module */ | 59 | /* Compatibility glue so we can support IPv6 when it's compiled as a module */ |
| 60 | static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | 60 | static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, |
| 61 | int *addr_len) | ||
| 61 | { | 62 | { |
| 62 | return -EAFNOSUPPORT; | 63 | return -EAFNOSUPPORT; |
| 63 | } | 64 | } |
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 22d1bd4670da..e048cf1bb6a2 100644 --- a/net/ipv6/protocol.c +++ b/net/ipv6/protocol.c | |||
| @@ -36,10 +36,6 @@ int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol | |||
| 36 | } | 36 | } |
| 37 | EXPORT_SYMBOL(inet6_add_protocol); | 37 | EXPORT_SYMBOL(inet6_add_protocol); |
| 38 | 38 | ||
| 39 | /* | ||
| 40 | * Remove a protocol from the hash tables. | ||
| 41 | */ | ||
| 42 | |||
| 43 | int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol) | 39 | int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol) |
| 44 | { | 40 | { |
| 45 | int ret; | 41 | int ret; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index e24ff1df0401..b6bb87e55805 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -466,10 +466,10 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 466 | return -EOPNOTSUPP; | 466 | return -EOPNOTSUPP; |
| 467 | 467 | ||
| 468 | if (flags & MSG_ERRQUEUE) | 468 | if (flags & MSG_ERRQUEUE) |
| 469 | return ipv6_recv_error(sk, msg, len); | 469 | return ipv6_recv_error(sk, msg, len, addr_len); |
| 470 | 470 | ||
| 471 | if (np->rxpmtu && np->rxopt.bits.rxpmtu) | 471 | if (np->rxpmtu && np->rxopt.bits.rxpmtu) |
| 472 | return ipv6_recv_rxpmtu(sk, msg, len); | 472 | return ipv6_recv_rxpmtu(sk, msg, len, addr_len); |
| 473 | 473 | ||
| 474 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 474 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
| 475 | if (!skb) | 475 | if (!skb) |
| @@ -792,7 +792,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 792 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 792 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 793 | if (flowlabel == NULL) | 793 | if (flowlabel == NULL) |
| 794 | return -EINVAL; | 794 | return -EINVAL; |
| 795 | daddr = &flowlabel->dst; | ||
| 796 | } | 795 | } |
| 797 | } | 796 | } |
| 798 | 797 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7faa9d5e1503..a0a48ac3403f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -84,6 +84,8 @@ static int ip6_dst_gc(struct dst_ops *ops); | |||
| 84 | 84 | ||
| 85 | static int ip6_pkt_discard(struct sk_buff *skb); | 85 | static int ip6_pkt_discard(struct sk_buff *skb); |
| 86 | static int ip6_pkt_discard_out(struct sk_buff *skb); | 86 | static int ip6_pkt_discard_out(struct sk_buff *skb); |
| 87 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
| 88 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
| 87 | static void ip6_link_failure(struct sk_buff *skb); | 89 | static void ip6_link_failure(struct sk_buff *skb); |
| 88 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 90 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 89 | struct sk_buff *skb, u32 mtu); | 91 | struct sk_buff *skb, u32 mtu); |
| @@ -234,9 +236,6 @@ static const struct rt6_info ip6_null_entry_template = { | |||
| 234 | 236 | ||
| 235 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 237 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 236 | 238 | ||
| 237 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
| 238 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
| 239 | |||
| 240 | static const struct rt6_info ip6_prohibit_entry_template = { | 239 | static const struct rt6_info ip6_prohibit_entry_template = { |
| 241 | .dst = { | 240 | .dst = { |
| 242 | .__refcnt = ATOMIC_INIT(1), | 241 | .__refcnt = ATOMIC_INIT(1), |
| @@ -1565,21 +1564,24 @@ int ip6_route_add(struct fib6_config *cfg) | |||
| 1565 | goto out; | 1564 | goto out; |
| 1566 | } | 1565 | } |
| 1567 | } | 1566 | } |
| 1568 | rt->dst.output = ip6_pkt_discard_out; | ||
| 1569 | rt->dst.input = ip6_pkt_discard; | ||
| 1570 | rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; | 1567 | rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; |
| 1571 | switch (cfg->fc_type) { | 1568 | switch (cfg->fc_type) { |
| 1572 | case RTN_BLACKHOLE: | 1569 | case RTN_BLACKHOLE: |
| 1573 | rt->dst.error = -EINVAL; | 1570 | rt->dst.error = -EINVAL; |
| 1571 | rt->dst.output = dst_discard; | ||
| 1572 | rt->dst.input = dst_discard; | ||
| 1574 | break; | 1573 | break; |
| 1575 | case RTN_PROHIBIT: | 1574 | case RTN_PROHIBIT: |
| 1576 | rt->dst.error = -EACCES; | 1575 | rt->dst.error = -EACCES; |
| 1576 | rt->dst.output = ip6_pkt_prohibit_out; | ||
| 1577 | rt->dst.input = ip6_pkt_prohibit; | ||
| 1577 | break; | 1578 | break; |
| 1578 | case RTN_THROW: | 1579 | case RTN_THROW: |
| 1579 | rt->dst.error = -EAGAIN; | ||
| 1580 | break; | ||
| 1581 | default: | 1580 | default: |
| 1582 | rt->dst.error = -ENETUNREACH; | 1581 | rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN |
| 1582 | : -ENETUNREACH; | ||
| 1583 | rt->dst.output = ip6_pkt_discard_out; | ||
| 1584 | rt->dst.input = ip6_pkt_discard; | ||
| 1583 | break; | 1585 | break; |
| 1584 | } | 1586 | } |
| 1585 | goto install_route; | 1587 | goto install_route; |
| @@ -2144,8 +2146,6 @@ static int ip6_pkt_discard_out(struct sk_buff *skb) | |||
| 2144 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); | 2146 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); |
| 2145 | } | 2147 | } |
| 2146 | 2148 | ||
| 2147 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
| 2148 | |||
| 2149 | static int ip6_pkt_prohibit(struct sk_buff *skb) | 2149 | static int ip6_pkt_prohibit(struct sk_buff *skb) |
| 2150 | { | 2150 | { |
| 2151 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); | 2151 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); |
| @@ -2157,8 +2157,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb) | |||
| 2157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); | 2157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); |
| 2158 | } | 2158 | } |
| 2159 | 2159 | ||
| 2160 | #endif | ||
| 2161 | |||
| 2162 | /* | 2160 | /* |
| 2163 | * Allocate a dst for local (unicast / anycast) address. | 2161 | * Allocate a dst for local (unicast / anycast) address. |
| 2164 | */ | 2162 | */ |
| @@ -2168,12 +2166,10 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
| 2168 | bool anycast) | 2166 | bool anycast) |
| 2169 | { | 2167 | { |
| 2170 | struct net *net = dev_net(idev->dev); | 2168 | struct net *net = dev_net(idev->dev); |
| 2171 | struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); | 2169 | struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, |
| 2172 | 2170 | DST_NOCOUNT, NULL); | |
| 2173 | if (!rt) { | 2171 | if (!rt) |
| 2174 | net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); | ||
| 2175 | return ERR_PTR(-ENOMEM); | 2172 | return ERR_PTR(-ENOMEM); |
| 2176 | } | ||
| 2177 | 2173 | ||
| 2178 | in6_dev_hold(idev); | 2174 | in6_dev_hold(idev); |
| 2179 | 2175 | ||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1b4a4a953675..366fbba3359a 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -478,14 +478,44 @@ static void ipip6_tunnel_uninit(struct net_device *dev) | |||
| 478 | dev_put(dev); | 478 | dev_put(dev); |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | /* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH | ||
| 482 | * if sufficient data bytes are available | ||
| 483 | */ | ||
| 484 | static int ipip6_err_gen_icmpv6_unreach(struct sk_buff *skb) | ||
| 485 | { | ||
| 486 | const struct iphdr *iph = (const struct iphdr *) skb->data; | ||
| 487 | struct rt6_info *rt; | ||
| 488 | struct sk_buff *skb2; | ||
| 489 | |||
| 490 | if (!pskb_may_pull(skb, iph->ihl * 4 + sizeof(struct ipv6hdr) + 8)) | ||
| 491 | return 1; | ||
| 492 | |||
| 493 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
| 494 | |||
| 495 | if (!skb2) | ||
| 496 | return 1; | ||
| 497 | |||
| 498 | skb_dst_drop(skb2); | ||
| 499 | skb_pull(skb2, iph->ihl * 4); | ||
| 500 | skb_reset_network_header(skb2); | ||
| 501 | |||
| 502 | rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0); | ||
| 503 | |||
| 504 | if (rt && rt->dst.dev) | ||
| 505 | skb2->dev = rt->dst.dev; | ||
| 506 | |||
| 507 | icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); | ||
| 508 | |||
| 509 | if (rt) | ||
| 510 | ip6_rt_put(rt); | ||
| 511 | |||
| 512 | kfree_skb(skb2); | ||
| 513 | |||
| 514 | return 0; | ||
| 515 | } | ||
| 481 | 516 | ||
| 482 | static int ipip6_err(struct sk_buff *skb, u32 info) | 517 | static int ipip6_err(struct sk_buff *skb, u32 info) |
| 483 | { | 518 | { |
| 484 | |||
| 485 | /* All the routers (except for Linux) return only | ||
| 486 | 8 bytes of packet payload. It means, that precise relaying of | ||
| 487 | ICMP in the real Internet is absolutely infeasible. | ||
| 488 | */ | ||
| 489 | const struct iphdr *iph = (const struct iphdr *)skb->data; | 519 | const struct iphdr *iph = (const struct iphdr *)skb->data; |
| 490 | const int type = icmp_hdr(skb)->type; | 520 | const int type = icmp_hdr(skb)->type; |
| 491 | const int code = icmp_hdr(skb)->code; | 521 | const int code = icmp_hdr(skb)->code; |
| @@ -500,7 +530,6 @@ static int ipip6_err(struct sk_buff *skb, u32 info) | |||
| 500 | case ICMP_DEST_UNREACH: | 530 | case ICMP_DEST_UNREACH: |
| 501 | switch (code) { | 531 | switch (code) { |
| 502 | case ICMP_SR_FAILED: | 532 | case ICMP_SR_FAILED: |
| 503 | case ICMP_PORT_UNREACH: | ||
| 504 | /* Impossible event. */ | 533 | /* Impossible event. */ |
| 505 | return 0; | 534 | return 0; |
| 506 | default: | 535 | default: |
| @@ -545,6 +574,9 @@ static int ipip6_err(struct sk_buff *skb, u32 info) | |||
| 545 | goto out; | 574 | goto out; |
| 546 | 575 | ||
| 547 | err = 0; | 576 | err = 0; |
| 577 | if (!ipip6_err_gen_icmpv6_unreach(skb)) | ||
| 578 | goto out; | ||
| 579 | |||
| 548 | if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) | 580 | if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) |
| 549 | goto out; | 581 | goto out; |
| 550 | 582 | ||
| @@ -919,7 +951,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 919 | if (!new_skb) { | 951 | if (!new_skb) { |
| 920 | ip_rt_put(rt); | 952 | ip_rt_put(rt); |
| 921 | dev->stats.tx_dropped++; | 953 | dev->stats.tx_dropped++; |
| 922 | dev_kfree_skb(skb); | 954 | kfree_skb(skb); |
| 923 | return NETDEV_TX_OK; | 955 | return NETDEV_TX_OK; |
| 924 | } | 956 | } |
| 925 | if (skb->sk) | 957 | if (skb->sk) |
| @@ -945,7 +977,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 945 | tx_error_icmp: | 977 | tx_error_icmp: |
| 946 | dst_link_failure(skb); | 978 | dst_link_failure(skb); |
| 947 | tx_error: | 979 | tx_error: |
| 948 | dev_kfree_skb(skb); | 980 | kfree_skb(skb); |
| 949 | out: | 981 | out: |
| 950 | dev->stats.tx_errors++; | 982 | dev->stats.tx_errors++; |
| 951 | return NETDEV_TX_OK; | 983 | return NETDEV_TX_OK; |
| @@ -985,7 +1017,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb, | |||
| 985 | 1017 | ||
| 986 | tx_err: | 1018 | tx_err: |
| 987 | dev->stats.tx_errors++; | 1019 | dev->stats.tx_errors++; |
| 988 | dev_kfree_skb(skb); | 1020 | kfree_skb(skb); |
| 989 | return NETDEV_TX_OK; | 1021 | return NETDEV_TX_OK; |
| 990 | 1022 | ||
| 991 | } | 1023 | } |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 0740f93a114a..f67033b4bb66 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -156,7 +156,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
| 156 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 156 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 157 | if (flowlabel == NULL) | 157 | if (flowlabel == NULL) |
| 158 | return -EINVAL; | 158 | return -EINVAL; |
| 159 | usin->sin6_addr = flowlabel->dst; | ||
| 160 | fl6_sock_release(flowlabel); | 159 | fl6_sock_release(flowlabel); |
| 161 | } | 160 | } |
| 162 | } | 161 | } |
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c index c1097c798900..6d18157dc32c 100644 --- a/net/ipv6/tcpv6_offload.c +++ b/net/ipv6/tcpv6_offload.c | |||
| @@ -37,34 +37,32 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, | |||
| 37 | { | 37 | { |
| 38 | const struct ipv6hdr *iph = skb_gro_network_header(skb); | 38 | const struct ipv6hdr *iph = skb_gro_network_header(skb); |
| 39 | __wsum wsum; | 39 | __wsum wsum; |
| 40 | __sum16 sum; | 40 | |
| 41 | /* Don't bother verifying checksum if we're going to flush anyway. */ | ||
| 42 | if (NAPI_GRO_CB(skb)->flush) | ||
| 43 | goto skip_csum; | ||
| 44 | |||
| 45 | wsum = skb->csum; | ||
| 41 | 46 | ||
| 42 | switch (skb->ip_summed) { | 47 | switch (skb->ip_summed) { |
| 48 | case CHECKSUM_NONE: | ||
| 49 | wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb), | ||
| 50 | wsum); | ||
| 51 | |||
| 52 | /* fall through */ | ||
| 53 | |||
| 43 | case CHECKSUM_COMPLETE: | 54 | case CHECKSUM_COMPLETE: |
| 44 | if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr, | 55 | if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr, |
| 45 | skb->csum)) { | 56 | wsum)) { |
| 46 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 57 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 47 | break; | 58 | break; |
| 48 | } | 59 | } |
| 49 | flush: | 60 | |
| 50 | NAPI_GRO_CB(skb)->flush = 1; | 61 | NAPI_GRO_CB(skb)->flush = 1; |
| 51 | return NULL; | 62 | return NULL; |
| 52 | |||
| 53 | case CHECKSUM_NONE: | ||
| 54 | wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr, | ||
| 55 | skb_gro_len(skb), | ||
| 56 | IPPROTO_TCP, 0)); | ||
| 57 | sum = csum_fold(skb_checksum(skb, | ||
| 58 | skb_gro_offset(skb), | ||
| 59 | skb_gro_len(skb), | ||
| 60 | wsum)); | ||
| 61 | if (sum) | ||
| 62 | goto flush; | ||
| 63 | |||
| 64 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 65 | break; | ||
| 66 | } | 63 | } |
| 67 | 64 | ||
| 65 | skip_csum: | ||
| 68 | return tcp_gro_receive(head, skb); | 66 | return tcp_gro_receive(head, skb); |
| 69 | } | 67 | } |
| 70 | 68 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 81eb8cf8389b..089c741a3992 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -393,10 +393,10 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 393 | bool slow; | 393 | bool slow; |
| 394 | 394 | ||
| 395 | if (flags & MSG_ERRQUEUE) | 395 | if (flags & MSG_ERRQUEUE) |
| 396 | return ipv6_recv_error(sk, msg, len); | 396 | return ipv6_recv_error(sk, msg, len, addr_len); |
| 397 | 397 | ||
| 398 | if (np->rxpmtu && np->rxopt.bits.rxpmtu) | 398 | if (np->rxpmtu && np->rxopt.bits.rxpmtu) |
| 399 | return ipv6_recv_rxpmtu(sk, msg, len); | 399 | return ipv6_recv_rxpmtu(sk, msg, len, addr_len); |
| 400 | 400 | ||
| 401 | try_again: | 401 | try_again: |
| 402 | skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), | 402 | skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), |
| @@ -1140,7 +1140,6 @@ do_udp_sendmsg: | |||
| 1140 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 1140 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 1141 | if (flowlabel == NULL) | 1141 | if (flowlabel == NULL) |
| 1142 | return -EINVAL; | 1142 | return -EINVAL; |
| 1143 | daddr = &flowlabel->dst; | ||
| 1144 | } | 1143 | } |
| 1145 | } | 1144 | } |
| 1146 | 1145 | ||
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 7a1e0fc1bd4d..e096025b477f 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
| @@ -1823,8 +1823,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1823 | if (skb->tstamp.tv64) | 1823 | if (skb->tstamp.tv64) |
| 1824 | sk->sk_stamp = skb->tstamp; | 1824 | sk->sk_stamp = skb->tstamp; |
| 1825 | 1825 | ||
| 1826 | msg->msg_namelen = sizeof(*sipx); | ||
| 1827 | |||
| 1828 | if (sipx) { | 1826 | if (sipx) { |
| 1829 | sipx->sipx_family = AF_IPX; | 1827 | sipx->sipx_family = AF_IPX; |
| 1830 | sipx->sipx_port = ipx->ipx_source.sock; | 1828 | sipx->sipx_port = ipx->ipx_source.sock; |
| @@ -1832,6 +1830,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1832 | sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net; | 1830 | sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net; |
| 1833 | sipx->sipx_type = ipx->ipx_type; | 1831 | sipx->sipx_type = ipx->ipx_type; |
| 1834 | sipx->sipx_zero = 0; | 1832 | sipx->sipx_zero = 0; |
| 1833 | msg->msg_namelen = sizeof(*sipx); | ||
| 1835 | } | 1834 | } |
| 1836 | rc = copied; | 1835 | rc = copied; |
| 1837 | 1836 | ||
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 0f676908d15b..de7db23049f1 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
| @@ -1385,8 +1385,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
| 1385 | 1385 | ||
| 1386 | IRDA_DEBUG(4, "%s()\n", __func__); | 1386 | IRDA_DEBUG(4, "%s()\n", __func__); |
| 1387 | 1387 | ||
| 1388 | msg->msg_namelen = 0; | ||
| 1389 | |||
| 1390 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 1388 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
| 1391 | flags & MSG_DONTWAIT, &err); | 1389 | flags & MSG_DONTWAIT, &err); |
| 1392 | if (!skb) | 1390 | if (!skb) |
| @@ -1451,8 +1449,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1451 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); | 1449 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); |
| 1452 | timeo = sock_rcvtimeo(sk, noblock); | 1450 | timeo = sock_rcvtimeo(sk, noblock); |
| 1453 | 1451 | ||
| 1454 | msg->msg_namelen = 0; | ||
| 1455 | |||
| 1456 | do { | 1452 | do { |
| 1457 | int chunk; | 1453 | int chunk; |
| 1458 | struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue); | 1454 | struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue); |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 168aff5e60de..c4b7218058b6 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
| @@ -1324,8 +1324,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1324 | int err = 0; | 1324 | int err = 0; |
| 1325 | u32 offset; | 1325 | u32 offset; |
| 1326 | 1326 | ||
| 1327 | msg->msg_namelen = 0; | ||
| 1328 | |||
| 1329 | if ((sk->sk_state == IUCV_DISCONN) && | 1327 | if ((sk->sk_state == IUCV_DISCONN) && |
| 1330 | skb_queue_empty(&iucv->backlog_skb_q) && | 1328 | skb_queue_empty(&iucv->backlog_skb_q) && |
| 1331 | skb_queue_empty(&sk->sk_receive_queue) && | 1329 | skb_queue_empty(&sk->sk_receive_queue) && |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 911ef03bf8fb..545f047868ad 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -3616,7 +3616,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb, | |||
| 3616 | if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) | 3616 | if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) |
| 3617 | goto out; | 3617 | goto out; |
| 3618 | 3618 | ||
| 3619 | msg->msg_namelen = 0; | ||
| 3620 | skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); | 3619 | skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); |
| 3621 | if (skb == NULL) | 3620 | if (skb == NULL) |
| 3622 | goto out; | 3621 | goto out; |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index cfd65304be60..bb6e206ea70b 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
| @@ -528,7 +528,6 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 528 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 528 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 529 | if (flowlabel == NULL) | 529 | if (flowlabel == NULL) |
| 530 | return -EINVAL; | 530 | return -EINVAL; |
| 531 | daddr = &flowlabel->dst; | ||
| 532 | } | 531 | } |
| 533 | } | 532 | } |
| 534 | 533 | ||
| @@ -665,7 +664,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 665 | *addr_len = sizeof(*lsa); | 664 | *addr_len = sizeof(*lsa); |
| 666 | 665 | ||
| 667 | if (flags & MSG_ERRQUEUE) | 666 | if (flags & MSG_ERRQUEUE) |
| 668 | return ipv6_recv_error(sk, msg, len); | 667 | return ipv6_recv_error(sk, msg, len, addr_len); |
| 669 | 668 | ||
| 670 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 669 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
| 671 | if (!skb) | 670 | if (!skb) |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index ffda81ef1a70..be5fadf34739 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
| @@ -197,8 +197,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 197 | if (sk->sk_state & PPPOX_BOUND) | 197 | if (sk->sk_state & PPPOX_BOUND) |
| 198 | goto end; | 198 | goto end; |
| 199 | 199 | ||
| 200 | msg->msg_namelen = 0; | ||
| 201 | |||
| 202 | err = 0; | 200 | err = 0; |
| 203 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 201 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
| 204 | flags & MSG_DONTWAIT, &err); | 202 | flags & MSG_DONTWAIT, &err); |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 6cba486353e8..7b01b9f5846c 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
| @@ -720,8 +720,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 720 | int target; /* Read at least this many bytes */ | 720 | int target; /* Read at least this many bytes */ |
| 721 | long timeo; | 721 | long timeo; |
| 722 | 722 | ||
| 723 | msg->msg_namelen = 0; | ||
| 724 | |||
| 725 | lock_sock(sk); | 723 | lock_sock(sk); |
| 726 | copied = -ENOTCONN; | 724 | copied = -ENOTCONN; |
| 727 | if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN)) | 725 | if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN)) |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 95667b088c5b..364ce0c5962f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -1368,7 +1368,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
| 1368 | changed |= | 1368 | changed |= |
| 1369 | ieee80211_mps_set_sta_local_pm(sta, | 1369 | ieee80211_mps_set_sta_local_pm(sta, |
| 1370 | params->local_pm); | 1370 | params->local_pm); |
| 1371 | ieee80211_bss_info_change_notify(sdata, changed); | 1371 | ieee80211_mbss_info_change_notify(sdata, changed); |
| 1372 | #endif | 1372 | #endif |
| 1373 | } | 1373 | } |
| 1374 | 1374 | ||
| @@ -2488,8 +2488,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
| 2488 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2488 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 2489 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2489 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 2490 | 2490 | ||
| 2491 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 2491 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
| 2492 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
| 2493 | return -EOPNOTSUPP; | 2492 | return -EOPNOTSUPP; |
| 2494 | 2493 | ||
| 2495 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) | 2494 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) |
| @@ -3120,9 +3119,17 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
| 3120 | params->chandef.chan->band) | 3119 | params->chandef.chan->band) |
| 3121 | return -EINVAL; | 3120 | return -EINVAL; |
| 3122 | 3121 | ||
| 3122 | ifmsh->chsw_init = true; | ||
| 3123 | if (!ifmsh->pre_value) | ||
| 3124 | ifmsh->pre_value = 1; | ||
| 3125 | else | ||
| 3126 | ifmsh->pre_value++; | ||
| 3127 | |||
| 3123 | err = ieee80211_mesh_csa_beacon(sdata, params, true); | 3128 | err = ieee80211_mesh_csa_beacon(sdata, params, true); |
| 3124 | if (err < 0) | 3129 | if (err < 0) { |
| 3130 | ifmsh->chsw_init = false; | ||
| 3125 | return err; | 3131 | return err; |
| 3132 | } | ||
| 3126 | break; | 3133 | break; |
| 3127 | #endif | 3134 | #endif |
| 3128 | default: | 3135 | default: |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 531be040b9ae..27a39de89679 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -823,6 +823,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
| 823 | if (err) | 823 | if (err) |
| 824 | return false; | 824 | return false; |
| 825 | 825 | ||
| 826 | /* channel switch is not supported, disconnect */ | ||
| 827 | if (!(sdata->local->hw.wiphy->flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) | ||
| 828 | goto disconnect; | ||
| 829 | |||
| 826 | params.count = csa_ie.count; | 830 | params.count = csa_ie.count; |
| 827 | params.chandef = csa_ie.chandef; | 831 | params.chandef = csa_ie.chandef; |
| 828 | 832 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 29dc505be125..4aea4e791113 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1228,6 +1228,7 @@ struct ieee80211_csa_ie { | |||
| 1228 | u8 mode; | 1228 | u8 mode; |
| 1229 | u8 count; | 1229 | u8 count; |
| 1230 | u8 ttl; | 1230 | u8 ttl; |
| 1231 | u16 pre_value; | ||
| 1231 | }; | 1232 | }; |
| 1232 | 1233 | ||
| 1233 | /* Parsed Information Elements */ | 1234 | /* Parsed Information Elements */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ff101ea1d9ae..36c3a4cbcabf 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -1325,7 +1325,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
| 1325 | sdata->vif.bss_conf.bssid = NULL; | 1325 | sdata->vif.bss_conf.bssid = NULL; |
| 1326 | break; | 1326 | break; |
| 1327 | case NL80211_IFTYPE_AP_VLAN: | 1327 | case NL80211_IFTYPE_AP_VLAN: |
| 1328 | break; | ||
| 1329 | case NL80211_IFTYPE_P2P_DEVICE: | 1328 | case NL80211_IFTYPE_P2P_DEVICE: |
| 1330 | sdata->vif.bss_conf.bssid = sdata->vif.addr; | 1329 | sdata->vif.bss_conf.bssid = sdata->vif.addr; |
| 1331 | break; | 1330 | break; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 21d5d44444d0..7d1c3ac48ed9 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -940,6 +940,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 940 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", | 940 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", |
| 941 | result); | 941 | result); |
| 942 | 942 | ||
| 943 | local->hw.conf.flags = IEEE80211_CONF_IDLE; | ||
| 944 | |||
| 943 | ieee80211_led_init(local); | 945 | ieee80211_led_init(local); |
| 944 | 946 | ||
| 945 | rtnl_lock(); | 947 | rtnl_lock(); |
| @@ -1047,6 +1049,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
| 1047 | 1049 | ||
| 1048 | cancel_work_sync(&local->restart_work); | 1050 | cancel_work_sync(&local->restart_work); |
| 1049 | cancel_work_sync(&local->reconfig_filter); | 1051 | cancel_work_sync(&local->reconfig_filter); |
| 1052 | flush_work(&local->sched_scan_stopped_work); | ||
| 1050 | 1053 | ||
| 1051 | ieee80211_clear_tx_pending(local); | 1054 | ieee80211_clear_tx_pending(local); |
| 1052 | rate_control_deinitialize(local); | 1055 | rate_control_deinitialize(local); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 896fe3bd599e..ba105257d03f 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
| @@ -943,14 +943,19 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, | |||
| 943 | params.chandef.chan->center_freq); | 943 | params.chandef.chan->center_freq); |
| 944 | 944 | ||
| 945 | params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT; | 945 | params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT; |
| 946 | if (beacon) | 946 | if (beacon) { |
| 947 | ifmsh->chsw_ttl = csa_ie.ttl - 1; | 947 | ifmsh->chsw_ttl = csa_ie.ttl - 1; |
| 948 | else | 948 | if (ifmsh->pre_value >= csa_ie.pre_value) |
| 949 | ifmsh->chsw_ttl = 0; | 949 | return false; |
| 950 | ifmsh->pre_value = csa_ie.pre_value; | ||
| 951 | } | ||
| 950 | 952 | ||
| 951 | if (ifmsh->chsw_ttl > 0) | 953 | if (ifmsh->chsw_ttl < ifmsh->mshcfg.dot11MeshTTL) { |
| 952 | if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0) | 954 | if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0) |
| 953 | return false; | 955 | return false; |
| 956 | } else { | ||
| 957 | return false; | ||
| 958 | } | ||
| 954 | 959 | ||
| 955 | sdata->csa_radar_required = params.radar_required; | 960 | sdata->csa_radar_required = params.radar_required; |
| 956 | 961 | ||
| @@ -1163,7 +1168,6 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
| 1163 | offset_ttl = (len < 42) ? 7 : 10; | 1168 | offset_ttl = (len < 42) ? 7 : 10; |
| 1164 | *(pos + offset_ttl) -= 1; | 1169 | *(pos + offset_ttl) -= 1; |
| 1165 | *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; | 1170 | *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; |
| 1166 | sdata->u.mesh.chsw_ttl = *(pos + offset_ttl); | ||
| 1167 | 1171 | ||
| 1168 | memcpy(mgmt_fwd, mgmt, len); | 1172 | memcpy(mgmt_fwd, mgmt, len); |
| 1169 | eth_broadcast_addr(mgmt_fwd->da); | 1173 | eth_broadcast_addr(mgmt_fwd->da); |
| @@ -1182,7 +1186,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
| 1182 | u16 pre_value; | 1186 | u16 pre_value; |
| 1183 | bool fwd_csa = true; | 1187 | bool fwd_csa = true; |
| 1184 | size_t baselen; | 1188 | size_t baselen; |
| 1185 | u8 *pos, ttl; | 1189 | u8 *pos; |
| 1186 | 1190 | ||
| 1187 | if (mgmt->u.action.u.measurement.action_code != | 1191 | if (mgmt->u.action.u.measurement.action_code != |
| 1188 | WLAN_ACTION_SPCT_CHL_SWITCH) | 1192 | WLAN_ACTION_SPCT_CHL_SWITCH) |
| @@ -1193,8 +1197,8 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
| 1193 | u.action.u.chan_switch.variable); | 1197 | u.action.u.chan_switch.variable); |
| 1194 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); | 1198 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); |
| 1195 | 1199 | ||
| 1196 | ttl = elems.mesh_chansw_params_ie->mesh_ttl; | 1200 | ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; |
| 1197 | if (!--ttl) | 1201 | if (!--ifmsh->chsw_ttl) |
| 1198 | fwd_csa = false; | 1202 | fwd_csa = false; |
| 1199 | 1203 | ||
| 1200 | pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); | 1204 | pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d7504ab61a34..b3a3ce316656 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1910,6 +1910,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
| 1910 | if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) | 1910 | if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) |
| 1911 | already = true; | 1911 | already = true; |
| 1912 | 1912 | ||
| 1913 | ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL; | ||
| 1914 | |||
| 1913 | mutex_unlock(&sdata->local->mtx); | 1915 | mutex_unlock(&sdata->local->mtx); |
| 1914 | 1916 | ||
| 1915 | if (already) | 1917 | if (already) |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 5d60779a0c1b..4096ff6cc24f 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
| @@ -226,7 +226,7 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) | |||
| 226 | nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); | 226 | nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); |
| 227 | 227 | ||
| 228 | nsecs += minstrel_mcs_groups[group].duration[rate]; | 228 | nsecs += minstrel_mcs_groups[group].duration[rate]; |
| 229 | tp = 1000000 * ((mr->probability * 1000) / nsecs); | 229 | tp = 1000000 * ((prob * 1000) / nsecs); |
| 230 | 230 | ||
| 231 | mr->cur_tp = MINSTREL_TRUNC(tp); | 231 | mr->cur_tp = MINSTREL_TRUNC(tp); |
| 232 | } | 232 | } |
| @@ -277,13 +277,15 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
| 277 | if (!(mg->supported & BIT(i))) | 277 | if (!(mg->supported & BIT(i))) |
| 278 | continue; | 278 | continue; |
| 279 | 279 | ||
| 280 | index = MCS_GROUP_RATES * group + i; | ||
| 281 | |||
| 280 | /* initialize rates selections starting indexes */ | 282 | /* initialize rates selections starting indexes */ |
| 281 | if (!mg_rates_valid) { | 283 | if (!mg_rates_valid) { |
| 282 | mg->max_tp_rate = mg->max_tp_rate2 = | 284 | mg->max_tp_rate = mg->max_tp_rate2 = |
| 283 | mg->max_prob_rate = i; | 285 | mg->max_prob_rate = i; |
| 284 | if (!mi_rates_valid) { | 286 | if (!mi_rates_valid) { |
| 285 | mi->max_tp_rate = mi->max_tp_rate2 = | 287 | mi->max_tp_rate = mi->max_tp_rate2 = |
| 286 | mi->max_prob_rate = i; | 288 | mi->max_prob_rate = index; |
| 287 | mi_rates_valid = true; | 289 | mi_rates_valid = true; |
| 288 | } | 290 | } |
| 289 | mg_rates_valid = true; | 291 | mg_rates_valid = true; |
| @@ -291,7 +293,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
| 291 | 293 | ||
| 292 | mr = &mg->rates[i]; | 294 | mr = &mg->rates[i]; |
| 293 | mr->retry_updated = false; | 295 | mr->retry_updated = false; |
| 294 | index = MCS_GROUP_RATES * group + i; | ||
| 295 | minstrel_calc_rate_ewma(mr); | 296 | minstrel_calc_rate_ewma(mr); |
| 296 | minstrel_ht_calc_tp(mi, group, i); | 297 | minstrel_ht_calc_tp(mi, group, i); |
| 297 | 298 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index caecef870c0e..2b0debb0422b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -911,7 +911,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, | |||
| 911 | u16 sc; | 911 | u16 sc; |
| 912 | u8 tid, ack_policy; | 912 | u8 tid, ack_policy; |
| 913 | 913 | ||
| 914 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 914 | if (!ieee80211_is_data_qos(hdr->frame_control) || |
| 915 | is_multicast_ether_addr(hdr->addr1)) | ||
| 915 | goto dont_reorder; | 916 | goto dont_reorder; |
| 916 | 917 | ||
| 917 | /* | 918 | /* |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 5ad66a83ef7f..bcc4833d7542 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -1088,6 +1088,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) | |||
| 1088 | 1088 | ||
| 1089 | trace_api_sched_scan_stopped(local); | 1089 | trace_api_sched_scan_stopped(local); |
| 1090 | 1090 | ||
| 1091 | ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work); | 1091 | schedule_work(&local->sched_scan_stopped_work); |
| 1092 | } | 1092 | } |
| 1093 | EXPORT_SYMBOL(ieee80211_sched_scan_stopped); | 1093 | EXPORT_SYMBOL(ieee80211_sched_scan_stopped); |
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index a40da20b32e0..6ab009070084 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
| @@ -78,6 +78,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
| 78 | if (elems->mesh_chansw_params_ie) { | 78 | if (elems->mesh_chansw_params_ie) { |
| 79 | csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl; | 79 | csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl; |
| 80 | csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; | 80 | csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; |
| 81 | csa_ie->pre_value = le16_to_cpu( | ||
| 82 | elems->mesh_chansw_params_ie->mesh_pre_value); | ||
| 81 | } | 83 | } |
| 82 | 84 | ||
| 83 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); | 85 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 592a18171f95..9f9b9bd3fd44 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -2278,17 +2278,15 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work) | |||
| 2278 | { | 2278 | { |
| 2279 | struct ieee80211_local *local = | 2279 | struct ieee80211_local *local = |
| 2280 | container_of(work, struct ieee80211_local, radar_detected_work); | 2280 | container_of(work, struct ieee80211_local, radar_detected_work); |
| 2281 | struct cfg80211_chan_def chandef; | 2281 | struct cfg80211_chan_def chandef = local->hw.conf.chandef; |
| 2282 | 2282 | ||
| 2283 | ieee80211_dfs_cac_cancel(local); | 2283 | ieee80211_dfs_cac_cancel(local); |
| 2284 | 2284 | ||
| 2285 | if (local->use_chanctx) | 2285 | if (local->use_chanctx) |
| 2286 | /* currently not handled */ | 2286 | /* currently not handled */ |
| 2287 | WARN_ON(1); | 2287 | WARN_ON(1); |
| 2288 | else { | 2288 | else |
| 2289 | chandef = local->hw.conf.chandef; | ||
| 2290 | cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); | 2289 | cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); |
| 2291 | } | ||
| 2292 | } | 2290 | } |
| 2293 | 2291 | ||
| 2294 | void ieee80211_radar_detected(struct ieee80211_hw *hw) | 2292 | void ieee80211_radar_detected(struct ieee80211_hw *hw) |
| @@ -2459,14 +2457,9 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | |||
| 2459 | WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; | 2457 | WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; |
| 2460 | put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ | 2458 | put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ |
| 2461 | pos += 2; | 2459 | pos += 2; |
| 2462 | if (!ifmsh->pre_value) | ||
| 2463 | ifmsh->pre_value = 1; | ||
| 2464 | else | ||
| 2465 | ifmsh->pre_value++; | ||
| 2466 | pre_value = cpu_to_le16(ifmsh->pre_value); | 2460 | pre_value = cpu_to_le16(ifmsh->pre_value); |
| 2467 | memcpy(pos, &pre_value, 2); /* Precedence Value */ | 2461 | memcpy(pos, &pre_value, 2); /* Precedence Value */ |
| 2468 | pos += 2; | 2462 | pos += 2; |
| 2469 | ifmsh->chsw_init = true; | ||
| 2470 | } | 2463 | } |
| 2471 | 2464 | ||
| 2472 | ieee80211_tx_skb(sdata, skb); | 2465 | ieee80211_tx_skb(sdata, skb); |
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 48acec17e27a..c3398cd99b94 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
| @@ -909,7 +909,7 @@ config NETFILTER_XT_MATCH_CONNLABEL | |||
| 909 | connection simultaneously. | 909 | connection simultaneously. |
| 910 | 910 | ||
| 911 | config NETFILTER_XT_MATCH_CONNLIMIT | 911 | config NETFILTER_XT_MATCH_CONNLIMIT |
| 912 | tristate '"connlimit" match support"' | 912 | tristate '"connlimit" match support' |
| 913 | depends on NF_CONNTRACK | 913 | depends on NF_CONNTRACK |
| 914 | depends on NETFILTER_ADVANCED | 914 | depends on NETFILTER_ADVANCED |
| 915 | ---help--- | 915 | ---help--- |
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c index 2bc2dec20b00..6226803fc490 100644 --- a/net/netfilter/ipset/ip_set_hash_netnet.c +++ b/net/netfilter/ipset/ip_set_hash_netnet.c | |||
| @@ -59,7 +59,7 @@ hash_netnet4_data_equal(const struct hash_netnet4_elem *ip1, | |||
| 59 | u32 *multi) | 59 | u32 *multi) |
| 60 | { | 60 | { |
| 61 | return ip1->ipcmp == ip2->ipcmp && | 61 | return ip1->ipcmp == ip2->ipcmp && |
| 62 | ip2->ccmp == ip2->ccmp; | 62 | ip1->ccmp == ip2->ccmp; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static inline int | 65 | static inline int |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index e22d950c60b3..43549eb7a7be 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -764,9 +764,10 @@ void nf_conntrack_free(struct nf_conn *ct) | |||
| 764 | struct net *net = nf_ct_net(ct); | 764 | struct net *net = nf_ct_net(ct); |
| 765 | 765 | ||
| 766 | nf_ct_ext_destroy(ct); | 766 | nf_ct_ext_destroy(ct); |
| 767 | atomic_dec(&net->ct.count); | ||
| 768 | nf_ct_ext_free(ct); | 767 | nf_ct_ext_free(ct); |
| 769 | kmem_cache_free(net->ct.nf_conntrack_cachep, ct); | 768 | kmem_cache_free(net->ct.nf_conntrack_cachep, ct); |
| 769 | smp_mb__before_atomic_dec(); | ||
| 770 | atomic_dec(&net->ct.count); | ||
| 770 | } | 771 | } |
| 771 | EXPORT_SYMBOL_GPL(nf_conntrack_free); | 772 | EXPORT_SYMBOL_GPL(nf_conntrack_free); |
| 772 | 773 | ||
diff --git a/net/netfilter/nf_conntrack_seqadj.c b/net/netfilter/nf_conntrack_seqadj.c index 5f9bfd060dea..17c1bcb182c6 100644 --- a/net/netfilter/nf_conntrack_seqadj.c +++ b/net/netfilter/nf_conntrack_seqadj.c | |||
| @@ -41,8 +41,8 @@ int nf_ct_seqadj_set(struct nf_conn *ct, enum ip_conntrack_info ctinfo, | |||
| 41 | spin_lock_bh(&ct->lock); | 41 | spin_lock_bh(&ct->lock); |
| 42 | this_way = &seqadj->seq[dir]; | 42 | this_way = &seqadj->seq[dir]; |
| 43 | if (this_way->offset_before == this_way->offset_after || | 43 | if (this_way->offset_before == this_way->offset_after || |
| 44 | before(this_way->correction_pos, seq)) { | 44 | before(this_way->correction_pos, ntohl(seq))) { |
| 45 | this_way->correction_pos = seq; | 45 | this_way->correction_pos = ntohl(seq); |
| 46 | this_way->offset_before = this_way->offset_after; | 46 | this_way->offset_before = this_way->offset_after; |
| 47 | this_way->offset_after += off; | 47 | this_way->offset_after += off; |
| 48 | } | 48 | } |
diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index cdf4567ba9b3..9858e3e51a3a 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c | |||
| @@ -151,9 +151,10 @@ void synproxy_init_timestamp_cookie(const struct xt_synproxy_info *info, | |||
| 151 | opts->tsecr = opts->tsval; | 151 | opts->tsecr = opts->tsval; |
| 152 | opts->tsval = tcp_time_stamp & ~0x3f; | 152 | opts->tsval = tcp_time_stamp & ~0x3f; |
| 153 | 153 | ||
| 154 | if (opts->options & XT_SYNPROXY_OPT_WSCALE) | 154 | if (opts->options & XT_SYNPROXY_OPT_WSCALE) { |
| 155 | opts->tsval |= info->wscale; | 155 | opts->tsval |= opts->wscale; |
| 156 | else | 156 | opts->wscale = info->wscale; |
| 157 | } else | ||
| 157 | opts->tsval |= 0xf; | 158 | opts->tsval |= 0xf; |
| 158 | 159 | ||
| 159 | if (opts->options & XT_SYNPROXY_OPT_SACK_PERM) | 160 | if (opts->options & XT_SYNPROXY_OPT_SACK_PERM) |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index dcddc49c0e08..f93b7d06f4be 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -1717,6 +1717,19 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule) | |||
| 1717 | return -ENOENT; | 1717 | return -ENOENT; |
| 1718 | } | 1718 | } |
| 1719 | 1719 | ||
| 1720 | static int nf_table_delrule_by_chain(struct nft_ctx *ctx) | ||
| 1721 | { | ||
| 1722 | struct nft_rule *rule; | ||
| 1723 | int err; | ||
| 1724 | |||
| 1725 | list_for_each_entry(rule, &ctx->chain->rules, list) { | ||
| 1726 | err = nf_tables_delrule_one(ctx, rule); | ||
| 1727 | if (err < 0) | ||
| 1728 | return err; | ||
| 1729 | } | ||
| 1730 | return 0; | ||
| 1731 | } | ||
| 1732 | |||
| 1720 | static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | 1733 | static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, |
| 1721 | const struct nlmsghdr *nlh, | 1734 | const struct nlmsghdr *nlh, |
| 1722 | const struct nlattr * const nla[]) | 1735 | const struct nlattr * const nla[]) |
| @@ -1725,8 +1738,8 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | |||
| 1725 | const struct nft_af_info *afi; | 1738 | const struct nft_af_info *afi; |
| 1726 | struct net *net = sock_net(skb->sk); | 1739 | struct net *net = sock_net(skb->sk); |
| 1727 | const struct nft_table *table; | 1740 | const struct nft_table *table; |
| 1728 | struct nft_chain *chain; | 1741 | struct nft_chain *chain = NULL; |
| 1729 | struct nft_rule *rule, *tmp; | 1742 | struct nft_rule *rule; |
| 1730 | int family = nfmsg->nfgen_family, err = 0; | 1743 | int family = nfmsg->nfgen_family, err = 0; |
| 1731 | struct nft_ctx ctx; | 1744 | struct nft_ctx ctx; |
| 1732 | 1745 | ||
| @@ -1738,22 +1751,29 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | |||
| 1738 | if (IS_ERR(table)) | 1751 | if (IS_ERR(table)) |
| 1739 | return PTR_ERR(table); | 1752 | return PTR_ERR(table); |
| 1740 | 1753 | ||
| 1741 | chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); | 1754 | if (nla[NFTA_RULE_CHAIN]) { |
| 1742 | if (IS_ERR(chain)) | 1755 | chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); |
| 1743 | return PTR_ERR(chain); | 1756 | if (IS_ERR(chain)) |
| 1757 | return PTR_ERR(chain); | ||
| 1758 | } | ||
| 1744 | 1759 | ||
| 1745 | nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); | 1760 | nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); |
| 1746 | 1761 | ||
| 1747 | if (nla[NFTA_RULE_HANDLE]) { | 1762 | if (chain) { |
| 1748 | rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]); | 1763 | if (nla[NFTA_RULE_HANDLE]) { |
| 1749 | if (IS_ERR(rule)) | 1764 | rule = nf_tables_rule_lookup(chain, |
| 1750 | return PTR_ERR(rule); | 1765 | nla[NFTA_RULE_HANDLE]); |
| 1766 | if (IS_ERR(rule)) | ||
| 1767 | return PTR_ERR(rule); | ||
| 1751 | 1768 | ||
| 1752 | err = nf_tables_delrule_one(&ctx, rule); | ||
| 1753 | } else { | ||
| 1754 | /* Remove all rules in this chain */ | ||
| 1755 | list_for_each_entry_safe(rule, tmp, &chain->rules, list) { | ||
| 1756 | err = nf_tables_delrule_one(&ctx, rule); | 1769 | err = nf_tables_delrule_one(&ctx, rule); |
| 1770 | } else { | ||
| 1771 | err = nf_table_delrule_by_chain(&ctx); | ||
| 1772 | } | ||
| 1773 | } else { | ||
| 1774 | list_for_each_entry(chain, &table->chains, list) { | ||
| 1775 | ctx.chain = chain; | ||
| 1776 | err = nf_table_delrule_by_chain(&ctx); | ||
| 1757 | if (err < 0) | 1777 | if (err < 0) |
| 1758 | break; | 1778 | break; |
| 1759 | } | 1779 | } |
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index a82667c64729..da0c1f4ada12 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c | |||
| @@ -128,7 +128,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] | |||
| 128 | [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, | 128 | [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, |
| 129 | }; | 129 | }; |
| 130 | 130 | ||
| 131 | static u8 nft_parse_compat(const struct nlattr *attr, bool *inv) | 131 | static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv) |
| 132 | { | 132 | { |
| 133 | struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; | 133 | struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; |
| 134 | u32 flags; | 134 | u32 flags; |
| @@ -148,7 +148,8 @@ static u8 nft_parse_compat(const struct nlattr *attr, bool *inv) | |||
| 148 | if (flags & NFT_RULE_COMPAT_F_INV) | 148 | if (flags & NFT_RULE_COMPAT_F_INV) |
| 149 | *inv = true; | 149 | *inv = true; |
| 150 | 150 | ||
| 151 | return ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO])); | 151 | *proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO])); |
| 152 | return 0; | ||
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | static int | 155 | static int |
| @@ -166,8 +167,11 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
| 166 | 167 | ||
| 167 | target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info); | 168 | target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info); |
| 168 | 169 | ||
| 169 | if (ctx->nla[NFTA_RULE_COMPAT]) | 170 | if (ctx->nla[NFTA_RULE_COMPAT]) { |
| 170 | proto = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &inv); | 171 | ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); |
| 172 | if (ret < 0) | ||
| 173 | goto err; | ||
| 174 | } | ||
| 171 | 175 | ||
| 172 | nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); | 176 | nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); |
| 173 | 177 | ||
| @@ -356,8 +360,11 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
| 356 | 360 | ||
| 357 | match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info); | 361 | match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info); |
| 358 | 362 | ||
| 359 | if (ctx->nla[NFTA_RULE_COMPAT]) | 363 | if (ctx->nla[NFTA_RULE_COMPAT]) { |
| 360 | proto = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &inv); | 364 | ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); |
| 365 | if (ret < 0) | ||
| 366 | goto err; | ||
| 367 | } | ||
| 361 | 368 | ||
| 362 | nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); | 369 | nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); |
| 363 | 370 | ||
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 9ff035c71403..a3910fc2122b 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
| @@ -325,21 +325,24 @@ static void htable_gc(unsigned long htlong) | |||
| 325 | add_timer(&ht->timer); | 325 | add_timer(&ht->timer); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | static void htable_destroy(struct xt_hashlimit_htable *hinfo) | 328 | static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo) |
| 329 | { | 329 | { |
| 330 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(hinfo->net); | 330 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(hinfo->net); |
| 331 | struct proc_dir_entry *parent; | 331 | struct proc_dir_entry *parent; |
| 332 | 332 | ||
| 333 | del_timer_sync(&hinfo->timer); | ||
| 334 | |||
| 335 | if (hinfo->family == NFPROTO_IPV4) | 333 | if (hinfo->family == NFPROTO_IPV4) |
| 336 | parent = hashlimit_net->ipt_hashlimit; | 334 | parent = hashlimit_net->ipt_hashlimit; |
| 337 | else | 335 | else |
| 338 | parent = hashlimit_net->ip6t_hashlimit; | 336 | parent = hashlimit_net->ip6t_hashlimit; |
| 339 | 337 | ||
| 340 | if(parent != NULL) | 338 | if (parent != NULL) |
| 341 | remove_proc_entry(hinfo->name, parent); | 339 | remove_proc_entry(hinfo->name, parent); |
| 340 | } | ||
| 342 | 341 | ||
| 342 | static void htable_destroy(struct xt_hashlimit_htable *hinfo) | ||
| 343 | { | ||
| 344 | del_timer_sync(&hinfo->timer); | ||
| 345 | htable_remove_proc_entry(hinfo); | ||
| 343 | htable_selective_cleanup(hinfo, select_all); | 346 | htable_selective_cleanup(hinfo, select_all); |
| 344 | kfree(hinfo->name); | 347 | kfree(hinfo->name); |
| 345 | vfree(hinfo); | 348 | vfree(hinfo); |
| @@ -883,21 +886,15 @@ static int __net_init hashlimit_proc_net_init(struct net *net) | |||
| 883 | static void __net_exit hashlimit_proc_net_exit(struct net *net) | 886 | static void __net_exit hashlimit_proc_net_exit(struct net *net) |
| 884 | { | 887 | { |
| 885 | struct xt_hashlimit_htable *hinfo; | 888 | struct xt_hashlimit_htable *hinfo; |
| 886 | struct proc_dir_entry *pde; | ||
| 887 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); | 889 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); |
| 888 | 890 | ||
| 889 | /* recent_net_exit() is called before recent_mt_destroy(). Make sure | 891 | /* hashlimit_net_exit() is called before hashlimit_mt_destroy(). |
| 890 | * that the parent xt_recent proc entry is is empty before trying to | 892 | * Make sure that the parent ipt_hashlimit and ip6t_hashlimit proc |
| 891 | * remove it. | 893 | * entries is empty before trying to remove it. |
| 892 | */ | 894 | */ |
| 893 | mutex_lock(&hashlimit_mutex); | 895 | mutex_lock(&hashlimit_mutex); |
| 894 | pde = hashlimit_net->ipt_hashlimit; | ||
| 895 | if (pde == NULL) | ||
| 896 | pde = hashlimit_net->ip6t_hashlimit; | ||
| 897 | |||
| 898 | hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) | 896 | hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) |
| 899 | remove_proc_entry(hinfo->name, pde); | 897 | htable_remove_proc_entry(hinfo); |
| 900 | |||
| 901 | hashlimit_net->ipt_hashlimit = NULL; | 898 | hashlimit_net->ipt_hashlimit = NULL; |
| 902 | hashlimit_net->ip6t_hashlimit = NULL; | 899 | hashlimit_net->ip6t_hashlimit = NULL; |
| 903 | mutex_unlock(&hashlimit_mutex); | 900 | mutex_unlock(&hashlimit_mutex); |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index f0176e1a5a81..bca50b95c182 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -2335,8 +2335,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2335 | } | 2335 | } |
| 2336 | #endif | 2336 | #endif |
| 2337 | 2337 | ||
| 2338 | msg->msg_namelen = 0; | ||
| 2339 | |||
| 2340 | copied = data_skb->len; | 2338 | copied = data_skb->len; |
| 2341 | if (len < copied) { | 2339 | if (len < copied) { |
| 2342 | msg->msg_flags |= MSG_TRUNC; | 2340 | msg->msg_flags |= MSG_TRUNC; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 7dbc4f732c75..713671ae45af 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
| @@ -74,9 +74,12 @@ static struct list_head family_ht[GENL_FAM_TAB_SIZE]; | |||
| 74 | * Bit 17 is marked as already used since the VFS quota code | 74 | * Bit 17 is marked as already used since the VFS quota code |
| 75 | * also abused this API and relied on family == group ID, we | 75 | * also abused this API and relied on family == group ID, we |
| 76 | * cater to that by giving it a static family and group ID. | 76 | * cater to that by giving it a static family and group ID. |
| 77 | * Bit 18 is marked as already used since the PMCRAID driver | ||
| 78 | * did the same thing as the VFS quota code (maybe copied?) | ||
| 77 | */ | 79 | */ |
| 78 | static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) | | 80 | static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) | |
| 79 | BIT(GENL_ID_VFS_DQUOT); | 81 | BIT(GENL_ID_VFS_DQUOT) | |
| 82 | BIT(GENL_ID_PMCRAID); | ||
| 80 | static unsigned long *mc_groups = &mc_group_start; | 83 | static unsigned long *mc_groups = &mc_group_start; |
| 81 | static unsigned long mc_groups_longs = 1; | 84 | static unsigned long mc_groups_longs = 1; |
| 82 | 85 | ||
| @@ -139,6 +142,7 @@ static u16 genl_generate_id(void) | |||
| 139 | 142 | ||
| 140 | for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) { | 143 | for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) { |
| 141 | if (id_gen_idx != GENL_ID_VFS_DQUOT && | 144 | if (id_gen_idx != GENL_ID_VFS_DQUOT && |
| 145 | id_gen_idx != GENL_ID_PMCRAID && | ||
| 142 | !genl_family_find_byid(id_gen_idx)) | 146 | !genl_family_find_byid(id_gen_idx)) |
| 143 | return id_gen_idx; | 147 | return id_gen_idx; |
| 144 | if (++id_gen_idx > GENL_MAX_ID) | 148 | if (++id_gen_idx > GENL_MAX_ID) |
| @@ -214,7 +218,7 @@ static int genl_validate_assign_mc_groups(struct genl_family *family) | |||
| 214 | { | 218 | { |
| 215 | int first_id; | 219 | int first_id; |
| 216 | int n_groups = family->n_mcgrps; | 220 | int n_groups = family->n_mcgrps; |
| 217 | int err, i; | 221 | int err = 0, i; |
| 218 | bool groups_allocated = false; | 222 | bool groups_allocated = false; |
| 219 | 223 | ||
| 220 | if (!n_groups) | 224 | if (!n_groups) |
| @@ -236,9 +240,12 @@ static int genl_validate_assign_mc_groups(struct genl_family *family) | |||
| 236 | } else if (strcmp(family->name, "NET_DM") == 0) { | 240 | } else if (strcmp(family->name, "NET_DM") == 0) { |
| 237 | first_id = 1; | 241 | first_id = 1; |
| 238 | BUG_ON(n_groups != 1); | 242 | BUG_ON(n_groups != 1); |
| 239 | } else if (strcmp(family->name, "VFS_DQUOT") == 0) { | 243 | } else if (family->id == GENL_ID_VFS_DQUOT) { |
| 240 | first_id = GENL_ID_VFS_DQUOT; | 244 | first_id = GENL_ID_VFS_DQUOT; |
| 241 | BUG_ON(n_groups != 1); | 245 | BUG_ON(n_groups != 1); |
| 246 | } else if (family->id == GENL_ID_PMCRAID) { | ||
| 247 | first_id = GENL_ID_PMCRAID; | ||
| 248 | BUG_ON(n_groups != 1); | ||
| 242 | } else { | 249 | } else { |
| 243 | groups_allocated = true; | 250 | groups_allocated = true; |
| 244 | err = genl_allocate_reserve_groups(n_groups, &first_id); | 251 | err = genl_allocate_reserve_groups(n_groups, &first_id); |
| @@ -1045,7 +1052,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group, | |||
| 1045 | int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb, | 1052 | int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb, |
| 1046 | u32 portid, unsigned int group, gfp_t flags) | 1053 | u32 portid, unsigned int group, gfp_t flags) |
| 1047 | { | 1054 | { |
| 1048 | if (group >= family->n_mcgrps) | 1055 | if (WARN_ON_ONCE(group >= family->n_mcgrps)) |
| 1049 | return -EINVAL; | 1056 | return -EINVAL; |
| 1050 | group = family->mcgrp_offset + group; | 1057 | group = family->mcgrp_offset + group; |
| 1051 | return genlmsg_mcast(skb, portid, group, flags); | 1058 | return genlmsg_mcast(skb, portid, group, flags); |
| @@ -1062,7 +1069,7 @@ void genl_notify(struct genl_family *family, | |||
| 1062 | if (nlh) | 1069 | if (nlh) |
| 1063 | report = nlmsg_report(nlh); | 1070 | report = nlmsg_report(nlh); |
| 1064 | 1071 | ||
| 1065 | if (group >= family->n_mcgrps) | 1072 | if (WARN_ON_ONCE(group >= family->n_mcgrps)) |
| 1066 | return; | 1073 | return; |
| 1067 | group = family->mcgrp_offset + group; | 1074 | group = family->mcgrp_offset + group; |
| 1068 | nlmsg_notify(sk, skb, portid, group, report, flags); | 1075 | nlmsg_notify(sk, skb, portid, group, report, flags); |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 698814bfa7ad..53c19a35fc6d 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
| @@ -1179,10 +1179,9 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1179 | sax->sax25_family = AF_NETROM; | 1179 | sax->sax25_family = AF_NETROM; |
| 1180 | skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, | 1180 | skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, |
| 1181 | AX25_ADDR_LEN); | 1181 | AX25_ADDR_LEN); |
| 1182 | msg->msg_namelen = sizeof(*sax); | ||
| 1182 | } | 1183 | } |
| 1183 | 1184 | ||
| 1184 | msg->msg_namelen = sizeof(*sax); | ||
| 1185 | |||
| 1186 | skb_free_datagram(sk, skb); | 1185 | skb_free_datagram(sk, skb); |
| 1187 | 1186 | ||
| 1188 | release_sock(sk); | 1187 | release_sock(sk); |
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index d308402b67d8..824c6056bf82 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c | |||
| @@ -807,8 +807,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 807 | 807 | ||
| 808 | pr_debug("%p %zu\n", sk, len); | 808 | pr_debug("%p %zu\n", sk, len); |
| 809 | 809 | ||
| 810 | msg->msg_namelen = 0; | ||
| 811 | |||
| 812 | lock_sock(sk); | 810 | lock_sock(sk); |
| 813 | 811 | ||
| 814 | if (sk->sk_state == LLCP_CLOSED && | 812 | if (sk->sk_state == LLCP_CLOSED && |
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index cd958b381f96..66bcd2eb5773 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c | |||
| @@ -244,8 +244,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 244 | if (!skb) | 244 | if (!skb) |
| 245 | return rc; | 245 | return rc; |
| 246 | 246 | ||
| 247 | msg->msg_namelen = 0; | ||
| 248 | |||
| 249 | copied = skb->len; | 247 | copied = skb->len; |
| 250 | if (len < copied) { | 248 | if (len < copied) { |
| 251 | msg->msg_flags |= MSG_TRUNC; | 249 | msg->msg_flags |= MSG_TRUNC; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 2e8286b47c28..88cfbc189558 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -237,6 +237,30 @@ struct packet_skb_cb { | |||
| 237 | static void __fanout_unlink(struct sock *sk, struct packet_sock *po); | 237 | static void __fanout_unlink(struct sock *sk, struct packet_sock *po); |
| 238 | static void __fanout_link(struct sock *sk, struct packet_sock *po); | 238 | static void __fanout_link(struct sock *sk, struct packet_sock *po); |
| 239 | 239 | ||
| 240 | static struct net_device *packet_cached_dev_get(struct packet_sock *po) | ||
| 241 | { | ||
| 242 | struct net_device *dev; | ||
| 243 | |||
| 244 | rcu_read_lock(); | ||
| 245 | dev = rcu_dereference(po->cached_dev); | ||
| 246 | if (likely(dev)) | ||
| 247 | dev_hold(dev); | ||
| 248 | rcu_read_unlock(); | ||
| 249 | |||
| 250 | return dev; | ||
| 251 | } | ||
| 252 | |||
| 253 | static void packet_cached_dev_assign(struct packet_sock *po, | ||
| 254 | struct net_device *dev) | ||
| 255 | { | ||
| 256 | rcu_assign_pointer(po->cached_dev, dev); | ||
| 257 | } | ||
| 258 | |||
| 259 | static void packet_cached_dev_reset(struct packet_sock *po) | ||
| 260 | { | ||
| 261 | RCU_INIT_POINTER(po->cached_dev, NULL); | ||
| 262 | } | ||
| 263 | |||
| 240 | /* register_prot_hook must be invoked with the po->bind_lock held, | 264 | /* register_prot_hook must be invoked with the po->bind_lock held, |
| 241 | * or from a context in which asynchronous accesses to the packet | 265 | * or from a context in which asynchronous accesses to the packet |
| 242 | * socket is not possible (packet_create()). | 266 | * socket is not possible (packet_create()). |
| @@ -244,11 +268,13 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po); | |||
| 244 | static void register_prot_hook(struct sock *sk) | 268 | static void register_prot_hook(struct sock *sk) |
| 245 | { | 269 | { |
| 246 | struct packet_sock *po = pkt_sk(sk); | 270 | struct packet_sock *po = pkt_sk(sk); |
| 271 | |||
| 247 | if (!po->running) { | 272 | if (!po->running) { |
| 248 | if (po->fanout) | 273 | if (po->fanout) |
| 249 | __fanout_link(sk, po); | 274 | __fanout_link(sk, po); |
| 250 | else | 275 | else |
| 251 | dev_add_pack(&po->prot_hook); | 276 | dev_add_pack(&po->prot_hook); |
| 277 | |||
| 252 | sock_hold(sk); | 278 | sock_hold(sk); |
| 253 | po->running = 1; | 279 | po->running = 1; |
| 254 | } | 280 | } |
| @@ -266,10 +292,12 @@ static void __unregister_prot_hook(struct sock *sk, bool sync) | |||
| 266 | struct packet_sock *po = pkt_sk(sk); | 292 | struct packet_sock *po = pkt_sk(sk); |
| 267 | 293 | ||
| 268 | po->running = 0; | 294 | po->running = 0; |
| 295 | |||
| 269 | if (po->fanout) | 296 | if (po->fanout) |
| 270 | __fanout_unlink(sk, po); | 297 | __fanout_unlink(sk, po); |
| 271 | else | 298 | else |
| 272 | __dev_remove_pack(&po->prot_hook); | 299 | __dev_remove_pack(&po->prot_hook); |
| 300 | |||
| 273 | __sock_put(sk); | 301 | __sock_put(sk); |
| 274 | 302 | ||
| 275 | if (sync) { | 303 | if (sync) { |
| @@ -432,9 +460,9 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po, | |||
| 432 | 460 | ||
| 433 | pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc; | 461 | pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc; |
| 434 | 462 | ||
| 435 | spin_lock(&rb_queue->lock); | 463 | spin_lock_bh(&rb_queue->lock); |
| 436 | pkc->delete_blk_timer = 1; | 464 | pkc->delete_blk_timer = 1; |
| 437 | spin_unlock(&rb_queue->lock); | 465 | spin_unlock_bh(&rb_queue->lock); |
| 438 | 466 | ||
| 439 | prb_del_retire_blk_timer(pkc); | 467 | prb_del_retire_blk_timer(pkc); |
| 440 | } | 468 | } |
| @@ -2057,7 +2085,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
| 2057 | struct sk_buff *skb; | 2085 | struct sk_buff *skb; |
| 2058 | struct net_device *dev; | 2086 | struct net_device *dev; |
| 2059 | __be16 proto; | 2087 | __be16 proto; |
| 2060 | bool need_rls_dev = false; | ||
| 2061 | int err, reserve = 0; | 2088 | int err, reserve = 0; |
| 2062 | void *ph; | 2089 | void *ph; |
| 2063 | struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; | 2090 | struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; |
| @@ -2069,8 +2096,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
| 2069 | 2096 | ||
| 2070 | mutex_lock(&po->pg_vec_lock); | 2097 | mutex_lock(&po->pg_vec_lock); |
| 2071 | 2098 | ||
| 2072 | if (saddr == NULL) { | 2099 | if (likely(saddr == NULL)) { |
| 2073 | dev = po->prot_hook.dev; | 2100 | dev = packet_cached_dev_get(po); |
| 2074 | proto = po->num; | 2101 | proto = po->num; |
| 2075 | addr = NULL; | 2102 | addr = NULL; |
| 2076 | } else { | 2103 | } else { |
| @@ -2084,19 +2111,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
| 2084 | proto = saddr->sll_protocol; | 2111 | proto = saddr->sll_protocol; |
| 2085 | addr = saddr->sll_addr; | 2112 | addr = saddr->sll_addr; |
| 2086 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); | 2113 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); |
| 2087 | need_rls_dev = true; | ||
| 2088 | } | 2114 | } |
| 2089 | 2115 | ||
| 2090 | err = -ENXIO; | 2116 | err = -ENXIO; |
| 2091 | if (unlikely(dev == NULL)) | 2117 | if (unlikely(dev == NULL)) |
| 2092 | goto out; | 2118 | goto out; |
| 2093 | |||
| 2094 | reserve = dev->hard_header_len; | ||
| 2095 | |||
| 2096 | err = -ENETDOWN; | 2119 | err = -ENETDOWN; |
| 2097 | if (unlikely(!(dev->flags & IFF_UP))) | 2120 | if (unlikely(!(dev->flags & IFF_UP))) |
| 2098 | goto out_put; | 2121 | goto out_put; |
| 2099 | 2122 | ||
| 2123 | reserve = dev->hard_header_len; | ||
| 2124 | |||
| 2100 | size_max = po->tx_ring.frame_size | 2125 | size_max = po->tx_ring.frame_size |
| 2101 | - (po->tp_hdrlen - sizeof(struct sockaddr_ll)); | 2126 | - (po->tp_hdrlen - sizeof(struct sockaddr_ll)); |
| 2102 | 2127 | ||
| @@ -2173,8 +2198,7 @@ out_status: | |||
| 2173 | __packet_set_status(po, ph, status); | 2198 | __packet_set_status(po, ph, status); |
| 2174 | kfree_skb(skb); | 2199 | kfree_skb(skb); |
| 2175 | out_put: | 2200 | out_put: |
| 2176 | if (need_rls_dev) | 2201 | dev_put(dev); |
| 2177 | dev_put(dev); | ||
| 2178 | out: | 2202 | out: |
| 2179 | mutex_unlock(&po->pg_vec_lock); | 2203 | mutex_unlock(&po->pg_vec_lock); |
| 2180 | return err; | 2204 | return err; |
| @@ -2212,7 +2236,6 @@ static int packet_snd(struct socket *sock, | |||
| 2212 | struct sk_buff *skb; | 2236 | struct sk_buff *skb; |
| 2213 | struct net_device *dev; | 2237 | struct net_device *dev; |
| 2214 | __be16 proto; | 2238 | __be16 proto; |
| 2215 | bool need_rls_dev = false; | ||
| 2216 | unsigned char *addr; | 2239 | unsigned char *addr; |
| 2217 | int err, reserve = 0; | 2240 | int err, reserve = 0; |
| 2218 | struct virtio_net_hdr vnet_hdr = { 0 }; | 2241 | struct virtio_net_hdr vnet_hdr = { 0 }; |
| @@ -2227,8 +2250,8 @@ static int packet_snd(struct socket *sock, | |||
| 2227 | * Get and verify the address. | 2250 | * Get and verify the address. |
| 2228 | */ | 2251 | */ |
| 2229 | 2252 | ||
| 2230 | if (saddr == NULL) { | 2253 | if (likely(saddr == NULL)) { |
| 2231 | dev = po->prot_hook.dev; | 2254 | dev = packet_cached_dev_get(po); |
| 2232 | proto = po->num; | 2255 | proto = po->num; |
| 2233 | addr = NULL; | 2256 | addr = NULL; |
| 2234 | } else { | 2257 | } else { |
| @@ -2240,19 +2263,17 @@ static int packet_snd(struct socket *sock, | |||
| 2240 | proto = saddr->sll_protocol; | 2263 | proto = saddr->sll_protocol; |
| 2241 | addr = saddr->sll_addr; | 2264 | addr = saddr->sll_addr; |
| 2242 | dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); | 2265 | dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); |
| 2243 | need_rls_dev = true; | ||
| 2244 | } | 2266 | } |
| 2245 | 2267 | ||
| 2246 | err = -ENXIO; | 2268 | err = -ENXIO; |
| 2247 | if (dev == NULL) | 2269 | if (unlikely(dev == NULL)) |
| 2248 | goto out_unlock; | 2270 | goto out_unlock; |
| 2249 | if (sock->type == SOCK_RAW) | ||
| 2250 | reserve = dev->hard_header_len; | ||
| 2251 | |||
| 2252 | err = -ENETDOWN; | 2271 | err = -ENETDOWN; |
| 2253 | if (!(dev->flags & IFF_UP)) | 2272 | if (unlikely(!(dev->flags & IFF_UP))) |
| 2254 | goto out_unlock; | 2273 | goto out_unlock; |
| 2255 | 2274 | ||
| 2275 | if (sock->type == SOCK_RAW) | ||
| 2276 | reserve = dev->hard_header_len; | ||
| 2256 | if (po->has_vnet_hdr) { | 2277 | if (po->has_vnet_hdr) { |
| 2257 | vnet_hdr_len = sizeof(vnet_hdr); | 2278 | vnet_hdr_len = sizeof(vnet_hdr); |
| 2258 | 2279 | ||
| @@ -2386,15 +2407,14 @@ static int packet_snd(struct socket *sock, | |||
| 2386 | if (err > 0 && (err = net_xmit_errno(err)) != 0) | 2407 | if (err > 0 && (err = net_xmit_errno(err)) != 0) |
| 2387 | goto out_unlock; | 2408 | goto out_unlock; |
| 2388 | 2409 | ||
| 2389 | if (need_rls_dev) | 2410 | dev_put(dev); |
| 2390 | dev_put(dev); | ||
| 2391 | 2411 | ||
| 2392 | return len; | 2412 | return len; |
| 2393 | 2413 | ||
| 2394 | out_free: | 2414 | out_free: |
| 2395 | kfree_skb(skb); | 2415 | kfree_skb(skb); |
| 2396 | out_unlock: | 2416 | out_unlock: |
| 2397 | if (dev && need_rls_dev) | 2417 | if (dev) |
| 2398 | dev_put(dev); | 2418 | dev_put(dev); |
| 2399 | out: | 2419 | out: |
| 2400 | return err; | 2420 | return err; |
| @@ -2439,6 +2459,8 @@ static int packet_release(struct socket *sock) | |||
| 2439 | 2459 | ||
| 2440 | spin_lock(&po->bind_lock); | 2460 | spin_lock(&po->bind_lock); |
| 2441 | unregister_prot_hook(sk, false); | 2461 | unregister_prot_hook(sk, false); |
| 2462 | packet_cached_dev_reset(po); | ||
| 2463 | |||
| 2442 | if (po->prot_hook.dev) { | 2464 | if (po->prot_hook.dev) { |
| 2443 | dev_put(po->prot_hook.dev); | 2465 | dev_put(po->prot_hook.dev); |
| 2444 | po->prot_hook.dev = NULL; | 2466 | po->prot_hook.dev = NULL; |
| @@ -2494,14 +2516,17 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc | |||
| 2494 | 2516 | ||
| 2495 | spin_lock(&po->bind_lock); | 2517 | spin_lock(&po->bind_lock); |
| 2496 | unregister_prot_hook(sk, true); | 2518 | unregister_prot_hook(sk, true); |
| 2519 | |||
| 2497 | po->num = protocol; | 2520 | po->num = protocol; |
| 2498 | po->prot_hook.type = protocol; | 2521 | po->prot_hook.type = protocol; |
| 2499 | if (po->prot_hook.dev) | 2522 | if (po->prot_hook.dev) |
| 2500 | dev_put(po->prot_hook.dev); | 2523 | dev_put(po->prot_hook.dev); |
| 2501 | po->prot_hook.dev = dev; | ||
| 2502 | 2524 | ||
| 2525 | po->prot_hook.dev = dev; | ||
| 2503 | po->ifindex = dev ? dev->ifindex : 0; | 2526 | po->ifindex = dev ? dev->ifindex : 0; |
| 2504 | 2527 | ||
| 2528 | packet_cached_dev_assign(po, dev); | ||
| 2529 | |||
| 2505 | if (protocol == 0) | 2530 | if (protocol == 0) |
| 2506 | goto out_unlock; | 2531 | goto out_unlock; |
| 2507 | 2532 | ||
| @@ -2615,6 +2640,8 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, | |||
| 2615 | sk->sk_family = PF_PACKET; | 2640 | sk->sk_family = PF_PACKET; |
| 2616 | po->num = proto; | 2641 | po->num = proto; |
| 2617 | 2642 | ||
| 2643 | packet_cached_dev_reset(po); | ||
| 2644 | |||
| 2618 | sk->sk_destruct = packet_sock_destruct; | 2645 | sk->sk_destruct = packet_sock_destruct; |
| 2619 | sk_refcnt_debug_inc(sk); | 2646 | sk_refcnt_debug_inc(sk); |
| 2620 | 2647 | ||
| @@ -2660,7 +2687,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 2660 | struct sock *sk = sock->sk; | 2687 | struct sock *sk = sock->sk; |
| 2661 | struct sk_buff *skb; | 2688 | struct sk_buff *skb; |
| 2662 | int copied, err; | 2689 | int copied, err; |
| 2663 | struct sockaddr_ll *sll; | ||
| 2664 | int vnet_hdr_len = 0; | 2690 | int vnet_hdr_len = 0; |
| 2665 | 2691 | ||
| 2666 | err = -EINVAL; | 2692 | err = -EINVAL; |
| @@ -2744,22 +2770,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 2744 | goto out_free; | 2770 | goto out_free; |
| 2745 | } | 2771 | } |
| 2746 | 2772 | ||
| 2747 | /* | 2773 | /* You lose any data beyond the buffer you gave. If it worries |
| 2748 | * If the address length field is there to be filled in, we fill | 2774 | * a user program they can ask the device for its MTU |
| 2749 | * it in now. | 2775 | * anyway. |
| 2750 | */ | 2776 | */ |
| 2751 | |||
| 2752 | sll = &PACKET_SKB_CB(skb)->sa.ll; | ||
| 2753 | if (sock->type == SOCK_PACKET) | ||
| 2754 | msg->msg_namelen = sizeof(struct sockaddr_pkt); | ||
| 2755 | else | ||
| 2756 | msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr); | ||
| 2757 | |||
| 2758 | /* | ||
| 2759 | * You lose any data beyond the buffer you gave. If it worries a | ||
| 2760 | * user program they can ask the device for its MTU anyway. | ||
| 2761 | */ | ||
| 2762 | |||
| 2763 | copied = skb->len; | 2777 | copied = skb->len; |
| 2764 | if (copied > len) { | 2778 | if (copied > len) { |
| 2765 | copied = len; | 2779 | copied = len; |
| @@ -2772,9 +2786,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 2772 | 2786 | ||
| 2773 | sock_recv_ts_and_drops(msg, sk, skb); | 2787 | sock_recv_ts_and_drops(msg, sk, skb); |
| 2774 | 2788 | ||
| 2775 | if (msg->msg_name) | 2789 | if (msg->msg_name) { |
| 2790 | /* If the address length field is there to be filled | ||
| 2791 | * in, we fill it in now. | ||
| 2792 | */ | ||
| 2793 | if (sock->type == SOCK_PACKET) { | ||
| 2794 | msg->msg_namelen = sizeof(struct sockaddr_pkt); | ||
| 2795 | } else { | ||
| 2796 | struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; | ||
| 2797 | msg->msg_namelen = sll->sll_halen + | ||
| 2798 | offsetof(struct sockaddr_ll, sll_addr); | ||
| 2799 | } | ||
| 2776 | memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, | 2800 | memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, |
| 2777 | msg->msg_namelen); | 2801 | msg->msg_namelen); |
| 2802 | } | ||
| 2778 | 2803 | ||
| 2779 | if (pkt_sk(sk)->auxdata) { | 2804 | if (pkt_sk(sk)->auxdata) { |
| 2780 | struct tpacket_auxdata aux; | 2805 | struct tpacket_auxdata aux; |
| @@ -3326,6 +3351,7 @@ static int packet_notifier(struct notifier_block *this, | |||
| 3326 | sk->sk_error_report(sk); | 3351 | sk->sk_error_report(sk); |
| 3327 | } | 3352 | } |
| 3328 | if (msg == NETDEV_UNREGISTER) { | 3353 | if (msg == NETDEV_UNREGISTER) { |
| 3354 | packet_cached_dev_reset(po); | ||
| 3329 | po->ifindex = -1; | 3355 | po->ifindex = -1; |
| 3330 | if (po->prot_hook.dev) | 3356 | if (po->prot_hook.dev) |
| 3331 | dev_put(po->prot_hook.dev); | 3357 | dev_put(po->prot_hook.dev); |
diff --git a/net/packet/internal.h b/net/packet/internal.h index c4e4b4561207..1035fa2d909c 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h | |||
| @@ -113,6 +113,7 @@ struct packet_sock { | |||
| 113 | unsigned int tp_loss:1; | 113 | unsigned int tp_loss:1; |
| 114 | unsigned int tp_tx_has_off:1; | 114 | unsigned int tp_tx_has_off:1; |
| 115 | unsigned int tp_tstamp; | 115 | unsigned int tp_tstamp; |
| 116 | struct net_device __rcu *cached_dev; | ||
| 116 | struct packet_type prot_hook ____cacheline_aligned_in_smp; | 117 | struct packet_type prot_hook ____cacheline_aligned_in_smp; |
| 117 | }; | 118 | }; |
| 118 | 119 | ||
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index e59094981175..37be6e226d1b 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c | |||
| @@ -552,9 +552,8 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, | |||
| 552 | && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { | 552 | && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { |
| 553 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); | 553 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); |
| 554 | scat = &rm->data.op_sg[sg]; | 554 | scat = &rm->data.op_sg[sg]; |
| 555 | ret = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; | 555 | ret = max_t(int, RDS_CONG_MAP_BYTES, scat->length); |
| 556 | ret = min_t(int, ret, scat->length - conn->c_xmit_data_off); | 556 | return sizeof(struct rds_header) + ret; |
| 557 | return ret; | ||
| 558 | } | 557 | } |
| 559 | 558 | ||
| 560 | /* FIXME we may overallocate here */ | 559 | /* FIXME we may overallocate here */ |
diff --git a/net/rds/recv.c b/net/rds/recv.c index 9f0f17cf6bf9..de339b24ca14 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
| @@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 410 | 410 | ||
| 411 | rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo); | 411 | rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo); |
| 412 | 412 | ||
| 413 | msg->msg_namelen = 0; | ||
| 414 | |||
| 415 | if (msg_flags & MSG_OOB) | 413 | if (msg_flags & MSG_OOB) |
| 416 | goto out; | 414 | goto out; |
| 417 | 415 | ||
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index e98fcfbe6007..33af77246bfe 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
| @@ -1216,7 +1216,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1216 | { | 1216 | { |
| 1217 | struct sock *sk = sock->sk; | 1217 | struct sock *sk = sock->sk; |
| 1218 | struct rose_sock *rose = rose_sk(sk); | 1218 | struct rose_sock *rose = rose_sk(sk); |
| 1219 | struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name; | ||
| 1220 | size_t copied; | 1219 | size_t copied; |
| 1221 | unsigned char *asmptr; | 1220 | unsigned char *asmptr; |
| 1222 | struct sk_buff *skb; | 1221 | struct sk_buff *skb; |
| @@ -1252,8 +1251,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1252 | 1251 | ||
| 1253 | skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 1252 | skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); |
| 1254 | 1253 | ||
| 1255 | if (srose != NULL) { | 1254 | if (msg->msg_name) { |
| 1256 | memset(srose, 0, msg->msg_namelen); | 1255 | struct sockaddr_rose *srose; |
| 1256 | |||
| 1257 | memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose)); | ||
| 1258 | srose = msg->msg_name; | ||
| 1257 | srose->srose_family = AF_ROSE; | 1259 | srose->srose_family = AF_ROSE; |
| 1258 | srose->srose_addr = rose->dest_addr; | 1260 | srose->srose_addr = rose->dest_addr; |
| 1259 | srose->srose_call = rose->dest_call; | 1261 | srose->srose_call = rose->dest_call; |
diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c index 4b48687c3890..898492a8d61b 100644 --- a/net/rxrpc/ar-recvmsg.c +++ b/net/rxrpc/ar-recvmsg.c | |||
| @@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 143 | 143 | ||
| 144 | /* copy the peer address and timestamp */ | 144 | /* copy the peer address and timestamp */ |
| 145 | if (!continue_call) { | 145 | if (!continue_call) { |
| 146 | if (msg->msg_name && msg->msg_namelen > 0) | 146 | if (msg->msg_name) { |
| 147 | size_t len = | ||
| 148 | sizeof(call->conn->trans->peer->srx); | ||
| 147 | memcpy(msg->msg_name, | 149 | memcpy(msg->msg_name, |
| 148 | &call->conn->trans->peer->srx, | 150 | &call->conn->trans->peer->srx, len); |
| 149 | sizeof(call->conn->trans->peer->srx)); | 151 | msg->msg_namelen = len; |
| 152 | } | ||
| 150 | sock_recv_ts_and_drops(msg, &rx->sk, skb); | 153 | sock_recv_ts_and_drops(msg, &rx->sk, skb); |
| 151 | } | 154 | } |
| 152 | 155 | ||
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index fd7072827a40..69cb848e8345 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
| @@ -270,6 +270,16 @@ int tcf_register_action(struct tc_action_ops *act) | |||
| 270 | { | 270 | { |
| 271 | struct tc_action_ops *a, **ap; | 271 | struct tc_action_ops *a, **ap; |
| 272 | 272 | ||
| 273 | /* Must supply act, dump, cleanup and init */ | ||
| 274 | if (!act->act || !act->dump || !act->cleanup || !act->init) | ||
| 275 | return -EINVAL; | ||
| 276 | |||
| 277 | /* Supply defaults */ | ||
| 278 | if (!act->lookup) | ||
| 279 | act->lookup = tcf_hash_search; | ||
| 280 | if (!act->walk) | ||
| 281 | act->walk = tcf_generic_walker; | ||
| 282 | |||
| 273 | write_lock(&act_mod_lock); | 283 | write_lock(&act_mod_lock); |
| 274 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { | 284 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { |
| 275 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { | 285 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { |
| @@ -381,7 +391,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act, | |||
| 381 | } | 391 | } |
| 382 | while ((a = act) != NULL) { | 392 | while ((a = act) != NULL) { |
| 383 | repeat: | 393 | repeat: |
| 384 | if (a->ops && a->ops->act) { | 394 | if (a->ops) { |
| 385 | ret = a->ops->act(skb, a, res); | 395 | ret = a->ops->act(skb, a, res); |
| 386 | if (TC_MUNGED & skb->tc_verd) { | 396 | if (TC_MUNGED & skb->tc_verd) { |
| 387 | /* copied already, allow trampling */ | 397 | /* copied already, allow trampling */ |
| @@ -405,7 +415,7 @@ void tcf_action_destroy(struct tc_action *act, int bind) | |||
| 405 | struct tc_action *a; | 415 | struct tc_action *a; |
| 406 | 416 | ||
| 407 | for (a = act; a; a = act) { | 417 | for (a = act; a; a = act) { |
| 408 | if (a->ops && a->ops->cleanup) { | 418 | if (a->ops) { |
| 409 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) | 419 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) |
| 410 | module_put(a->ops->owner); | 420 | module_put(a->ops->owner); |
| 411 | act = act->next; | 421 | act = act->next; |
| @@ -424,7 +434,7 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
| 424 | { | 434 | { |
| 425 | int err = -EINVAL; | 435 | int err = -EINVAL; |
| 426 | 436 | ||
| 427 | if (a->ops == NULL || a->ops->dump == NULL) | 437 | if (a->ops == NULL) |
| 428 | return err; | 438 | return err; |
| 429 | return a->ops->dump(skb, a, bind, ref); | 439 | return a->ops->dump(skb, a, bind, ref); |
| 430 | } | 440 | } |
| @@ -436,7 +446,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
| 436 | unsigned char *b = skb_tail_pointer(skb); | 446 | unsigned char *b = skb_tail_pointer(skb); |
| 437 | struct nlattr *nest; | 447 | struct nlattr *nest; |
| 438 | 448 | ||
| 439 | if (a->ops == NULL || a->ops->dump == NULL) | 449 | if (a->ops == NULL) |
| 440 | return err; | 450 | return err; |
| 441 | 451 | ||
| 442 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) | 452 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) |
| @@ -723,8 +733,6 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) | |||
| 723 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); | 733 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); |
| 724 | if (a->ops == NULL) | 734 | if (a->ops == NULL) |
| 725 | goto err_free; | 735 | goto err_free; |
| 726 | if (a->ops->lookup == NULL) | ||
| 727 | goto err_mod; | ||
| 728 | err = -ENOENT; | 736 | err = -ENOENT; |
| 729 | if (a->ops->lookup(a, index) == 0) | 737 | if (a->ops->lookup(a, index) == 0) |
| 730 | goto err_mod; | 738 | goto err_mod; |
| @@ -1084,12 +1092,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1084 | memset(&a, 0, sizeof(struct tc_action)); | 1092 | memset(&a, 0, sizeof(struct tc_action)); |
| 1085 | a.ops = a_o; | 1093 | a.ops = a_o; |
| 1086 | 1094 | ||
| 1087 | if (a_o->walk == NULL) { | ||
| 1088 | WARN(1, "tc_dump_action: %s !capable of dumping table\n", | ||
| 1089 | a_o->kind); | ||
| 1090 | goto out_module_put; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 1095 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
| 1094 | cb->nlh->nlmsg_type, sizeof(*t), 0); | 1096 | cb->nlh->nlmsg_type, sizeof(*t), 0); |
| 1095 | if (!nlh) | 1097 | if (!nlh) |
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 3a4c0caa1f7d..5c5edf56adbd 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
| @@ -585,9 +585,7 @@ static struct tc_action_ops act_csum_ops = { | |||
| 585 | .act = tcf_csum, | 585 | .act = tcf_csum, |
| 586 | .dump = tcf_csum_dump, | 586 | .dump = tcf_csum_dump, |
| 587 | .cleanup = tcf_csum_cleanup, | 587 | .cleanup = tcf_csum_cleanup, |
| 588 | .lookup = tcf_hash_search, | ||
| 589 | .init = tcf_csum_init, | 588 | .init = tcf_csum_init, |
| 590 | .walk = tcf_generic_walker | ||
| 591 | }; | 589 | }; |
| 592 | 590 | ||
| 593 | MODULE_DESCRIPTION("Checksum updating actions"); | 591 | MODULE_DESCRIPTION("Checksum updating actions"); |
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index fd2b3cff5fa2..5645a4d32abd 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
| @@ -206,9 +206,7 @@ static struct tc_action_ops act_gact_ops = { | |||
| 206 | .act = tcf_gact, | 206 | .act = tcf_gact, |
| 207 | .dump = tcf_gact_dump, | 207 | .dump = tcf_gact_dump, |
| 208 | .cleanup = tcf_gact_cleanup, | 208 | .cleanup = tcf_gact_cleanup, |
| 209 | .lookup = tcf_hash_search, | ||
| 210 | .init = tcf_gact_init, | 209 | .init = tcf_gact_init, |
| 211 | .walk = tcf_generic_walker | ||
| 212 | }; | 210 | }; |
| 213 | 211 | ||
| 214 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); | 212 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 60d88b6b9560..882a89762f77 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
| @@ -298,9 +298,7 @@ static struct tc_action_ops act_ipt_ops = { | |||
| 298 | .act = tcf_ipt, | 298 | .act = tcf_ipt, |
| 299 | .dump = tcf_ipt_dump, | 299 | .dump = tcf_ipt_dump, |
| 300 | .cleanup = tcf_ipt_cleanup, | 300 | .cleanup = tcf_ipt_cleanup, |
| 301 | .lookup = tcf_hash_search, | ||
| 302 | .init = tcf_ipt_init, | 301 | .init = tcf_ipt_init, |
| 303 | .walk = tcf_generic_walker | ||
| 304 | }; | 302 | }; |
| 305 | 303 | ||
| 306 | static struct tc_action_ops act_xt_ops = { | 304 | static struct tc_action_ops act_xt_ops = { |
| @@ -312,9 +310,7 @@ static struct tc_action_ops act_xt_ops = { | |||
| 312 | .act = tcf_ipt, | 310 | .act = tcf_ipt, |
| 313 | .dump = tcf_ipt_dump, | 311 | .dump = tcf_ipt_dump, |
| 314 | .cleanup = tcf_ipt_cleanup, | 312 | .cleanup = tcf_ipt_cleanup, |
| 315 | .lookup = tcf_hash_search, | ||
| 316 | .init = tcf_ipt_init, | 313 | .init = tcf_ipt_init, |
| 317 | .walk = tcf_generic_walker | ||
| 318 | }; | 314 | }; |
| 319 | 315 | ||
| 320 | MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); | 316 | MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 977c10e0631b..252378121ce7 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
| @@ -271,9 +271,7 @@ static struct tc_action_ops act_mirred_ops = { | |||
| 271 | .act = tcf_mirred, | 271 | .act = tcf_mirred, |
| 272 | .dump = tcf_mirred_dump, | 272 | .dump = tcf_mirred_dump, |
| 273 | .cleanup = tcf_mirred_cleanup, | 273 | .cleanup = tcf_mirred_cleanup, |
| 274 | .lookup = tcf_hash_search, | ||
| 275 | .init = tcf_mirred_init, | 274 | .init = tcf_mirred_init, |
| 276 | .walk = tcf_generic_walker | ||
| 277 | }; | 275 | }; |
| 278 | 276 | ||
| 279 | MODULE_AUTHOR("Jamal Hadi Salim(2002)"); | 277 | MODULE_AUTHOR("Jamal Hadi Salim(2002)"); |
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 876f0ef29694..6a15ace00241 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
| @@ -308,9 +308,7 @@ static struct tc_action_ops act_nat_ops = { | |||
| 308 | .act = tcf_nat, | 308 | .act = tcf_nat, |
| 309 | .dump = tcf_nat_dump, | 309 | .dump = tcf_nat_dump, |
| 310 | .cleanup = tcf_nat_cleanup, | 310 | .cleanup = tcf_nat_cleanup, |
| 311 | .lookup = tcf_hash_search, | ||
| 312 | .init = tcf_nat_init, | 311 | .init = tcf_nat_init, |
| 313 | .walk = tcf_generic_walker | ||
| 314 | }; | 312 | }; |
| 315 | 313 | ||
| 316 | MODULE_DESCRIPTION("Stateless NAT actions"); | 314 | MODULE_DESCRIPTION("Stateless NAT actions"); |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 7ed78c9e505c..03b67674169c 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
| @@ -243,9 +243,7 @@ static struct tc_action_ops act_pedit_ops = { | |||
| 243 | .act = tcf_pedit, | 243 | .act = tcf_pedit, |
| 244 | .dump = tcf_pedit_dump, | 244 | .dump = tcf_pedit_dump, |
| 245 | .cleanup = tcf_pedit_cleanup, | 245 | .cleanup = tcf_pedit_cleanup, |
| 246 | .lookup = tcf_hash_search, | ||
| 247 | .init = tcf_pedit_init, | 246 | .init = tcf_pedit_init, |
| 248 | .walk = tcf_generic_walker | ||
| 249 | }; | 247 | }; |
| 250 | 248 | ||
| 251 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); | 249 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 272d8e924cf6..16a62c36928a 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
| @@ -407,7 +407,6 @@ static struct tc_action_ops act_police_ops = { | |||
| 407 | .act = tcf_act_police, | 407 | .act = tcf_act_police, |
| 408 | .dump = tcf_act_police_dump, | 408 | .dump = tcf_act_police_dump, |
| 409 | .cleanup = tcf_act_police_cleanup, | 409 | .cleanup = tcf_act_police_cleanup, |
| 410 | .lookup = tcf_hash_search, | ||
| 411 | .init = tcf_act_police_locate, | 410 | .init = tcf_act_police_locate, |
| 412 | .walk = tcf_act_police_walker | 411 | .walk = tcf_act_police_walker |
| 413 | }; | 412 | }; |
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 7725eb4ab756..31157d3e729c 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
| @@ -201,7 +201,6 @@ static struct tc_action_ops act_simp_ops = { | |||
| 201 | .dump = tcf_simp_dump, | 201 | .dump = tcf_simp_dump, |
| 202 | .cleanup = tcf_simp_cleanup, | 202 | .cleanup = tcf_simp_cleanup, |
| 203 | .init = tcf_simp_init, | 203 | .init = tcf_simp_init, |
| 204 | .walk = tcf_generic_walker, | ||
| 205 | }; | 204 | }; |
| 206 | 205 | ||
| 207 | MODULE_AUTHOR("Jamal Hadi Salim(2005)"); | 206 | MODULE_AUTHOR("Jamal Hadi Salim(2005)"); |
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index cb4221171f93..35ea643b4325 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
| @@ -203,7 +203,6 @@ static struct tc_action_ops act_skbedit_ops = { | |||
| 203 | .dump = tcf_skbedit_dump, | 203 | .dump = tcf_skbedit_dump, |
| 204 | .cleanup = tcf_skbedit_cleanup, | 204 | .cleanup = tcf_skbedit_cleanup, |
| 205 | .init = tcf_skbedit_init, | 205 | .init = tcf_skbedit_init, |
| 206 | .walk = tcf_generic_walker, | ||
| 207 | }; | 206 | }; |
| 208 | 207 | ||
| 209 | MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>"); | 208 | MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>"); |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 0e1e38b40025..717b2108f852 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
| @@ -1477,11 +1477,22 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
| 1477 | sch_tree_lock(sch); | 1477 | sch_tree_lock(sch); |
| 1478 | } | 1478 | } |
| 1479 | 1479 | ||
| 1480 | rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0; | ||
| 1481 | |||
| 1482 | ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0; | ||
| 1483 | |||
| 1484 | psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64); | ||
| 1485 | psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64); | ||
| 1486 | |||
| 1480 | /* it used to be a nasty bug here, we have to check that node | 1487 | /* it used to be a nasty bug here, we have to check that node |
| 1481 | * is really leaf before changing cl->un.leaf ! | 1488 | * is really leaf before changing cl->un.leaf ! |
| 1482 | */ | 1489 | */ |
| 1483 | if (!cl->level) { | 1490 | if (!cl->level) { |
| 1484 | cl->quantum = hopt->rate.rate / q->rate2quantum; | 1491 | u64 quantum = cl->rate.rate_bytes_ps; |
| 1492 | |||
| 1493 | do_div(quantum, q->rate2quantum); | ||
| 1494 | cl->quantum = min_t(u64, quantum, INT_MAX); | ||
| 1495 | |||
| 1485 | if (!hopt->quantum && cl->quantum < 1000) { | 1496 | if (!hopt->quantum && cl->quantum < 1000) { |
| 1486 | pr_warning( | 1497 | pr_warning( |
| 1487 | "HTB: quantum of class %X is small. Consider r2q change.\n", | 1498 | "HTB: quantum of class %X is small. Consider r2q change.\n", |
| @@ -1500,13 +1511,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
| 1500 | cl->prio = TC_HTB_NUMPRIO - 1; | 1511 | cl->prio = TC_HTB_NUMPRIO - 1; |
| 1501 | } | 1512 | } |
| 1502 | 1513 | ||
| 1503 | rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0; | ||
| 1504 | |||
| 1505 | ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0; | ||
| 1506 | |||
| 1507 | psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64); | ||
| 1508 | psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64); | ||
| 1509 | |||
| 1510 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); | 1514 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); |
| 1511 | cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); | 1515 | cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); |
| 1512 | 1516 | ||
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 75c94e59a3bd..bccd52b36e97 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
| @@ -215,10 +215,10 @@ static bool loss_4state(struct netem_sched_data *q) | |||
| 215 | if (rnd < clg->a4) { | 215 | if (rnd < clg->a4) { |
| 216 | clg->state = 4; | 216 | clg->state = 4; |
| 217 | return true; | 217 | return true; |
| 218 | } else if (clg->a4 < rnd && rnd < clg->a1) { | 218 | } else if (clg->a4 < rnd && rnd < clg->a1 + clg->a4) { |
| 219 | clg->state = 3; | 219 | clg->state = 3; |
| 220 | return true; | 220 | return true; |
| 221 | } else if (clg->a1 < rnd) | 221 | } else if (clg->a1 + clg->a4 < rnd) |
| 222 | clg->state = 1; | 222 | clg->state = 1; |
| 223 | 223 | ||
| 224 | break; | 224 | break; |
| @@ -268,10 +268,11 @@ static bool loss_gilb_ell(struct netem_sched_data *q) | |||
| 268 | clg->state = 2; | 268 | clg->state = 2; |
| 269 | if (net_random() < clg->a4) | 269 | if (net_random() < clg->a4) |
| 270 | return true; | 270 | return true; |
| 271 | break; | ||
| 271 | case 2: | 272 | case 2: |
| 272 | if (net_random() < clg->a2) | 273 | if (net_random() < clg->a2) |
| 273 | clg->state = 1; | 274 | clg->state = 1; |
| 274 | if (clg->a3 > net_random()) | 275 | if (net_random() > clg->a3) |
| 275 | return true; | 276 | return true; |
| 276 | } | 277 | } |
| 277 | 278 | ||
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 68f98595819c..887e672f9d7d 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <net/netlink.h> | 21 | #include <net/netlink.h> |
| 22 | #include <net/sch_generic.h> | 22 | #include <net/sch_generic.h> |
| 23 | #include <net/pkt_sched.h> | 23 | #include <net/pkt_sched.h> |
| 24 | #include <net/tcp.h> | ||
| 24 | 25 | ||
| 25 | 26 | ||
| 26 | /* Simple Token Bucket Filter. | 27 | /* Simple Token Bucket Filter. |
| @@ -117,6 +118,48 @@ struct tbf_sched_data { | |||
| 117 | }; | 118 | }; |
| 118 | 119 | ||
| 119 | 120 | ||
| 121 | /* Time to Length, convert time in ns to length in bytes | ||
| 122 | * to determinate how many bytes can be sent in given time. | ||
| 123 | */ | ||
| 124 | static u64 psched_ns_t2l(const struct psched_ratecfg *r, | ||
| 125 | u64 time_in_ns) | ||
| 126 | { | ||
| 127 | /* The formula is : | ||
| 128 | * len = (time_in_ns * r->rate_bytes_ps) / NSEC_PER_SEC | ||
| 129 | */ | ||
| 130 | u64 len = time_in_ns * r->rate_bytes_ps; | ||
| 131 | |||
| 132 | do_div(len, NSEC_PER_SEC); | ||
| 133 | |||
| 134 | if (unlikely(r->linklayer == TC_LINKLAYER_ATM)) { | ||
| 135 | do_div(len, 53); | ||
| 136 | len = len * 48; | ||
| 137 | } | ||
| 138 | |||
| 139 | if (len > r->overhead) | ||
| 140 | len -= r->overhead; | ||
| 141 | else | ||
| 142 | len = 0; | ||
| 143 | |||
| 144 | return len; | ||
| 145 | } | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Return length of individual segments of a gso packet, | ||
| 149 | * including all headers (MAC, IP, TCP/UDP) | ||
| 150 | */ | ||
| 151 | static unsigned int skb_gso_seglen(const struct sk_buff *skb) | ||
| 152 | { | ||
| 153 | unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb); | ||
| 154 | const struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
| 155 | |||
| 156 | if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) | ||
| 157 | hdr_len += tcp_hdrlen(skb); | ||
| 158 | else | ||
| 159 | hdr_len += sizeof(struct udphdr); | ||
| 160 | return hdr_len + shinfo->gso_size; | ||
| 161 | } | ||
| 162 | |||
| 120 | /* GSO packet is too big, segment it so that tbf can transmit | 163 | /* GSO packet is too big, segment it so that tbf can transmit |
| 121 | * each segment in time | 164 | * each segment in time |
| 122 | */ | 165 | */ |
| @@ -136,12 +179,8 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch) | |||
| 136 | while (segs) { | 179 | while (segs) { |
| 137 | nskb = segs->next; | 180 | nskb = segs->next; |
| 138 | segs->next = NULL; | 181 | segs->next = NULL; |
| 139 | if (likely(segs->len <= q->max_size)) { | 182 | qdisc_skb_cb(segs)->pkt_len = segs->len; |
| 140 | qdisc_skb_cb(segs)->pkt_len = segs->len; | 183 | ret = qdisc_enqueue(segs, q->qdisc); |
| 141 | ret = qdisc_enqueue(segs, q->qdisc); | ||
| 142 | } else { | ||
| 143 | ret = qdisc_reshape_fail(skb, sch); | ||
| 144 | } | ||
| 145 | if (ret != NET_XMIT_SUCCESS) { | 184 | if (ret != NET_XMIT_SUCCESS) { |
| 146 | if (net_xmit_drop_count(ret)) | 185 | if (net_xmit_drop_count(ret)) |
| 147 | sch->qstats.drops++; | 186 | sch->qstats.drops++; |
| @@ -163,7 +202,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 163 | int ret; | 202 | int ret; |
| 164 | 203 | ||
| 165 | if (qdisc_pkt_len(skb) > q->max_size) { | 204 | if (qdisc_pkt_len(skb) > q->max_size) { |
| 166 | if (skb_is_gso(skb)) | 205 | if (skb_is_gso(skb) && skb_gso_seglen(skb) <= q->max_size) |
| 167 | return tbf_segment(skb, sch); | 206 | return tbf_segment(skb, sch); |
| 168 | return qdisc_reshape_fail(skb, sch); | 207 | return qdisc_reshape_fail(skb, sch); |
| 169 | } | 208 | } |
| @@ -276,10 +315,11 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 276 | struct tbf_sched_data *q = qdisc_priv(sch); | 315 | struct tbf_sched_data *q = qdisc_priv(sch); |
| 277 | struct nlattr *tb[TCA_TBF_MAX + 1]; | 316 | struct nlattr *tb[TCA_TBF_MAX + 1]; |
| 278 | struct tc_tbf_qopt *qopt; | 317 | struct tc_tbf_qopt *qopt; |
| 279 | struct qdisc_rate_table *rtab = NULL; | ||
| 280 | struct qdisc_rate_table *ptab = NULL; | ||
| 281 | struct Qdisc *child = NULL; | 318 | struct Qdisc *child = NULL; |
| 282 | int max_size, n; | 319 | struct psched_ratecfg rate; |
| 320 | struct psched_ratecfg peak; | ||
| 321 | u64 max_size; | ||
| 322 | s64 buffer, mtu; | ||
| 283 | u64 rate64 = 0, prate64 = 0; | 323 | u64 rate64 = 0, prate64 = 0; |
| 284 | 324 | ||
| 285 | err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy); | 325 | err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy); |
| @@ -291,33 +331,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 291 | goto done; | 331 | goto done; |
| 292 | 332 | ||
| 293 | qopt = nla_data(tb[TCA_TBF_PARMS]); | 333 | qopt = nla_data(tb[TCA_TBF_PARMS]); |
| 294 | rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]); | 334 | if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE) |
| 295 | if (rtab == NULL) | 335 | qdisc_put_rtab(qdisc_get_rtab(&qopt->rate, |
| 296 | goto done; | 336 | tb[TCA_TBF_RTAB])); |
| 297 | 337 | ||
| 298 | if (qopt->peakrate.rate) { | 338 | if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE) |
| 299 | if (qopt->peakrate.rate > qopt->rate.rate) | 339 | qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate, |
| 300 | ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]); | 340 | tb[TCA_TBF_PTAB])); |
| 301 | if (ptab == NULL) | ||
| 302 | goto done; | ||
| 303 | } | ||
| 304 | |||
| 305 | for (n = 0; n < 256; n++) | ||
| 306 | if (rtab->data[n] > qopt->buffer) | ||
| 307 | break; | ||
| 308 | max_size = (n << qopt->rate.cell_log) - 1; | ||
| 309 | if (ptab) { | ||
| 310 | int size; | ||
| 311 | |||
| 312 | for (n = 0; n < 256; n++) | ||
| 313 | if (ptab->data[n] > qopt->mtu) | ||
| 314 | break; | ||
| 315 | size = (n << qopt->peakrate.cell_log) - 1; | ||
| 316 | if (size < max_size) | ||
| 317 | max_size = size; | ||
| 318 | } | ||
| 319 | if (max_size < 0) | ||
| 320 | goto done; | ||
| 321 | 341 | ||
| 322 | if (q->qdisc != &noop_qdisc) { | 342 | if (q->qdisc != &noop_qdisc) { |
| 323 | err = fifo_set_limit(q->qdisc, qopt->limit); | 343 | err = fifo_set_limit(q->qdisc, qopt->limit); |
| @@ -331,6 +351,39 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 331 | } | 351 | } |
| 332 | } | 352 | } |
| 333 | 353 | ||
| 354 | buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U); | ||
| 355 | mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U); | ||
| 356 | |||
| 357 | if (tb[TCA_TBF_RATE64]) | ||
| 358 | rate64 = nla_get_u64(tb[TCA_TBF_RATE64]); | ||
| 359 | psched_ratecfg_precompute(&rate, &qopt->rate, rate64); | ||
| 360 | |||
| 361 | max_size = min_t(u64, psched_ns_t2l(&rate, buffer), ~0U); | ||
| 362 | |||
| 363 | if (qopt->peakrate.rate) { | ||
| 364 | if (tb[TCA_TBF_PRATE64]) | ||
| 365 | prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]); | ||
| 366 | psched_ratecfg_precompute(&peak, &qopt->peakrate, prate64); | ||
| 367 | if (peak.rate_bytes_ps <= rate.rate_bytes_ps) { | ||
| 368 | pr_warn_ratelimited("sch_tbf: peakrate %llu is lower than or equals to rate %llu !\n", | ||
| 369 | peak.rate_bytes_ps, rate.rate_bytes_ps); | ||
| 370 | err = -EINVAL; | ||
| 371 | goto done; | ||
| 372 | } | ||
| 373 | |||
| 374 | max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu)); | ||
| 375 | } | ||
| 376 | |||
| 377 | if (max_size < psched_mtu(qdisc_dev(sch))) | ||
| 378 | pr_warn_ratelimited("sch_tbf: burst %llu is lower than device %s mtu (%u) !\n", | ||
| 379 | max_size, qdisc_dev(sch)->name, | ||
| 380 | psched_mtu(qdisc_dev(sch))); | ||
| 381 | |||
| 382 | if (!max_size) { | ||
| 383 | err = -EINVAL; | ||
| 384 | goto done; | ||
| 385 | } | ||
| 386 | |||
| 334 | sch_tree_lock(sch); | 387 | sch_tree_lock(sch); |
| 335 | if (child) { | 388 | if (child) { |
| 336 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); | 389 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); |
| @@ -344,13 +397,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 344 | q->tokens = q->buffer; | 397 | q->tokens = q->buffer; |
| 345 | q->ptokens = q->mtu; | 398 | q->ptokens = q->mtu; |
| 346 | 399 | ||
| 347 | if (tb[TCA_TBF_RATE64]) | 400 | memcpy(&q->rate, &rate, sizeof(struct psched_ratecfg)); |
| 348 | rate64 = nla_get_u64(tb[TCA_TBF_RATE64]); | 401 | if (qopt->peakrate.rate) { |
| 349 | psched_ratecfg_precompute(&q->rate, &rtab->rate, rate64); | 402 | memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg)); |
| 350 | if (ptab) { | ||
| 351 | if (tb[TCA_TBF_PRATE64]) | ||
| 352 | prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]); | ||
| 353 | psched_ratecfg_precompute(&q->peak, &ptab->rate, prate64); | ||
| 354 | q->peak_present = true; | 403 | q->peak_present = true; |
| 355 | } else { | 404 | } else { |
| 356 | q->peak_present = false; | 405 | q->peak_present = false; |
| @@ -359,10 +408,6 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 359 | sch_tree_unlock(sch); | 408 | sch_tree_unlock(sch); |
| 360 | err = 0; | 409 | err = 0; |
| 361 | done: | 410 | done: |
| 362 | if (rtab) | ||
| 363 | qdisc_put_rtab(rtab); | ||
| 364 | if (ptab) | ||
| 365 | qdisc_put_rtab(ptab); | ||
| 366 | return err; | 411 | return err; |
| 367 | } | 412 | } |
| 368 | 413 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 68a27f9796d2..31ed008c8e13 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -154,8 +154,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 154 | 154 | ||
| 155 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; | 155 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; |
| 156 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; | 156 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; |
| 157 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | 157 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; |
| 158 | min_t(unsigned long, sp->autoclose, net->sctp.max_autoclose) * HZ; | ||
| 159 | 158 | ||
| 160 | /* Initializes the timers */ | 159 | /* Initializes the timers */ |
| 161 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) | 160 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) |
| @@ -291,8 +290,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 291 | asoc->peer.ipv6_address = 1; | 290 | asoc->peer.ipv6_address = 1; |
| 292 | INIT_LIST_HEAD(&asoc->asocs); | 291 | INIT_LIST_HEAD(&asoc->asocs); |
| 293 | 292 | ||
| 294 | asoc->autoclose = sp->autoclose; | ||
| 295 | |||
| 296 | asoc->default_stream = sp->default_stream; | 293 | asoc->default_stream = sp->default_stream; |
| 297 | asoc->default_ppid = sp->default_ppid; | 294 | asoc->default_ppid = sp->default_ppid; |
| 298 | asoc->default_flags = sp->default_flags; | 295 | asoc->default_flags = sp->default_flags; |
diff --git a/net/sctp/output.c b/net/sctp/output.c index e650978daf27..0fb140f8f088 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -474,10 +474,11 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 474 | * for a given destination transport address. | 474 | * for a given destination transport address. |
| 475 | */ | 475 | */ |
| 476 | 476 | ||
| 477 | if (!tp->rto_pending) { | 477 | if (!chunk->resent && !tp->rto_pending) { |
| 478 | chunk->rtt_in_progress = 1; | 478 | chunk->rtt_in_progress = 1; |
| 479 | tp->rto_pending = 1; | 479 | tp->rto_pending = 1; |
| 480 | } | 480 | } |
| 481 | |||
| 481 | has_data = 1; | 482 | has_data = 1; |
| 482 | } | 483 | } |
| 483 | 484 | ||
| @@ -580,7 +581,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 580 | unsigned long timeout; | 581 | unsigned long timeout; |
| 581 | 582 | ||
| 582 | /* Restart the AUTOCLOSE timer when sending data. */ | 583 | /* Restart the AUTOCLOSE timer when sending data. */ |
| 583 | if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) { | 584 | if (sctp_state(asoc, ESTABLISHED) && |
| 585 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { | ||
| 584 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 586 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; |
| 585 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 587 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; |
| 586 | 588 | ||
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 94df75877869..f51ba985a36e 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
| @@ -446,6 +446,8 @@ void sctp_retransmit_mark(struct sctp_outq *q, | |||
| 446 | transport->rto_pending = 0; | 446 | transport->rto_pending = 0; |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | chunk->resent = 1; | ||
| 450 | |||
| 449 | /* Move the chunk to the retransmit queue. The chunks | 451 | /* Move the chunk to the retransmit queue. The chunks |
| 450 | * on the retransmit queue are always kept in order. | 452 | * on the retransmit queue are always kept in order. |
| 451 | */ | 453 | */ |
| @@ -1375,6 +1377,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
| 1375 | * instance). | 1377 | * instance). |
| 1376 | */ | 1378 | */ |
| 1377 | if (!tchunk->tsn_gap_acked && | 1379 | if (!tchunk->tsn_gap_acked && |
| 1380 | !tchunk->resent && | ||
| 1378 | tchunk->rtt_in_progress) { | 1381 | tchunk->rtt_in_progress) { |
| 1379 | tchunk->rtt_in_progress = 0; | 1382 | tchunk->rtt_in_progress = 0; |
| 1380 | rtt = jiffies - tchunk->sent_at; | 1383 | rtt = jiffies - tchunk->sent_at; |
| @@ -1391,7 +1394,8 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
| 1391 | */ | 1394 | */ |
| 1392 | if (!tchunk->tsn_gap_acked) { | 1395 | if (!tchunk->tsn_gap_acked) { |
| 1393 | tchunk->tsn_gap_acked = 1; | 1396 | tchunk->tsn_gap_acked = 1; |
| 1394 | *highest_new_tsn_in_sack = tsn; | 1397 | if (TSN_lt(*highest_new_tsn_in_sack, tsn)) |
| 1398 | *highest_new_tsn_in_sack = tsn; | ||
| 1395 | bytes_acked += sctp_data_size(tchunk); | 1399 | bytes_acked += sctp_data_size(tchunk); |
| 1396 | if (!tchunk->transport) | 1400 | if (!tchunk->transport) |
| 1397 | migrate_bytes += sctp_data_size(tchunk); | 1401 | migrate_bytes += sctp_data_size(tchunk); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index dfe3f36ff2aa..a26065be7289 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -820,7 +820,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | |||
| 820 | SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); | 820 | SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); |
| 821 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | 821 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); |
| 822 | 822 | ||
| 823 | if (new_asoc->autoclose) | 823 | if (new_asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
| 824 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 824 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
| 825 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 825 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 826 | 826 | ||
| @@ -908,7 +908,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net, | |||
| 908 | SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); | 908 | SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); |
| 909 | SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); | 909 | SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); |
| 910 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | 910 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); |
| 911 | if (asoc->autoclose) | 911 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
| 912 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 912 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
| 913 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 913 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 914 | 914 | ||
| @@ -2970,7 +2970,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net, | |||
| 2970 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) | 2970 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) |
| 2971 | force = SCTP_FORCE(); | 2971 | force = SCTP_FORCE(); |
| 2972 | 2972 | ||
| 2973 | if (asoc->autoclose) { | 2973 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
| 2974 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 2974 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 2975 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 2975 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 2976 | } | 2976 | } |
| @@ -3878,7 +3878,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net, | |||
| 3878 | SCTP_CHUNK(chunk)); | 3878 | SCTP_CHUNK(chunk)); |
| 3879 | 3879 | ||
| 3880 | /* Count this as receiving DATA. */ | 3880 | /* Count this as receiving DATA. */ |
| 3881 | if (asoc->autoclose) { | 3881 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
| 3882 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 3882 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 3883 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 3883 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 3884 | } | 3884 | } |
| @@ -5267,7 +5267,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( | |||
| 5267 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 5267 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 5268 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 5268 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
| 5269 | 5269 | ||
| 5270 | if (asoc->autoclose) | 5270 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
| 5271 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 5271 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
| 5272 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 5272 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 5273 | 5273 | ||
| @@ -5346,7 +5346,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack( | |||
| 5346 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 5346 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 5347 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); | 5347 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); |
| 5348 | 5348 | ||
| 5349 | if (asoc->autoclose) | 5349 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
| 5350 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 5350 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
| 5351 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 5351 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 5352 | 5352 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 72046b9729a8..42b709c95cf3 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -2196,6 +2196,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
| 2196 | unsigned int optlen) | 2196 | unsigned int optlen) |
| 2197 | { | 2197 | { |
| 2198 | struct sctp_sock *sp = sctp_sk(sk); | 2198 | struct sctp_sock *sp = sctp_sk(sk); |
| 2199 | struct net *net = sock_net(sk); | ||
| 2199 | 2200 | ||
| 2200 | /* Applicable to UDP-style socket only */ | 2201 | /* Applicable to UDP-style socket only */ |
| 2201 | if (sctp_style(sk, TCP)) | 2202 | if (sctp_style(sk, TCP)) |
| @@ -2205,6 +2206,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
| 2205 | if (copy_from_user(&sp->autoclose, optval, optlen)) | 2206 | if (copy_from_user(&sp->autoclose, optval, optlen)) |
| 2206 | return -EFAULT; | 2207 | return -EFAULT; |
| 2207 | 2208 | ||
| 2209 | if (sp->autoclose > net->sctp.max_autoclose) | ||
| 2210 | sp->autoclose = net->sctp.max_autoclose; | ||
| 2211 | |||
| 2208 | return 0; | 2212 | return 0; |
| 2209 | } | 2213 | } |
| 2210 | 2214 | ||
| @@ -2811,6 +2815,8 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne | |||
| 2811 | { | 2815 | { |
| 2812 | struct sctp_rtoinfo rtoinfo; | 2816 | struct sctp_rtoinfo rtoinfo; |
| 2813 | struct sctp_association *asoc; | 2817 | struct sctp_association *asoc; |
| 2818 | unsigned long rto_min, rto_max; | ||
| 2819 | struct sctp_sock *sp = sctp_sk(sk); | ||
| 2814 | 2820 | ||
| 2815 | if (optlen != sizeof (struct sctp_rtoinfo)) | 2821 | if (optlen != sizeof (struct sctp_rtoinfo)) |
| 2816 | return -EINVAL; | 2822 | return -EINVAL; |
| @@ -2824,26 +2830,36 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne | |||
| 2824 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) | 2830 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) |
| 2825 | return -EINVAL; | 2831 | return -EINVAL; |
| 2826 | 2832 | ||
| 2833 | rto_max = rtoinfo.srto_max; | ||
| 2834 | rto_min = rtoinfo.srto_min; | ||
| 2835 | |||
| 2836 | if (rto_max) | ||
| 2837 | rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max; | ||
| 2838 | else | ||
| 2839 | rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max; | ||
| 2840 | |||
| 2841 | if (rto_min) | ||
| 2842 | rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min; | ||
| 2843 | else | ||
| 2844 | rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min; | ||
| 2845 | |||
| 2846 | if (rto_min > rto_max) | ||
| 2847 | return -EINVAL; | ||
| 2848 | |||
| 2827 | if (asoc) { | 2849 | if (asoc) { |
| 2828 | if (rtoinfo.srto_initial != 0) | 2850 | if (rtoinfo.srto_initial != 0) |
| 2829 | asoc->rto_initial = | 2851 | asoc->rto_initial = |
| 2830 | msecs_to_jiffies(rtoinfo.srto_initial); | 2852 | msecs_to_jiffies(rtoinfo.srto_initial); |
| 2831 | if (rtoinfo.srto_max != 0) | 2853 | asoc->rto_max = rto_max; |
| 2832 | asoc->rto_max = msecs_to_jiffies(rtoinfo.srto_max); | 2854 | asoc->rto_min = rto_min; |
| 2833 | if (rtoinfo.srto_min != 0) | ||
| 2834 | asoc->rto_min = msecs_to_jiffies(rtoinfo.srto_min); | ||
| 2835 | } else { | 2855 | } else { |
| 2836 | /* If there is no association or the association-id = 0 | 2856 | /* If there is no association or the association-id = 0 |
| 2837 | * set the values to the endpoint. | 2857 | * set the values to the endpoint. |
| 2838 | */ | 2858 | */ |
| 2839 | struct sctp_sock *sp = sctp_sk(sk); | ||
| 2840 | |||
| 2841 | if (rtoinfo.srto_initial != 0) | 2859 | if (rtoinfo.srto_initial != 0) |
| 2842 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; | 2860 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; |
| 2843 | if (rtoinfo.srto_max != 0) | 2861 | sp->rtoinfo.srto_max = rto_max; |
| 2844 | sp->rtoinfo.srto_max = rtoinfo.srto_max; | 2862 | sp->rtoinfo.srto_min = rto_min; |
| 2845 | if (rtoinfo.srto_min != 0) | ||
| 2846 | sp->rtoinfo.srto_min = rtoinfo.srto_min; | ||
| 2847 | } | 2863 | } |
| 2848 | 2864 | ||
| 2849 | return 0; | 2865 | return 0; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 6b36561a1b3b..b0565afb61c7 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
| @@ -56,11 +56,16 @@ extern long sysctl_sctp_mem[3]; | |||
| 56 | extern int sysctl_sctp_rmem[3]; | 56 | extern int sysctl_sctp_rmem[3]; |
| 57 | extern int sysctl_sctp_wmem[3]; | 57 | extern int sysctl_sctp_wmem[3]; |
| 58 | 58 | ||
| 59 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 59 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
| 60 | int write, | 60 | void __user *buffer, size_t *lenp, |
| 61 | loff_t *ppos); | ||
| 62 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
| 63 | void __user *buffer, size_t *lenp, | ||
| 64 | loff_t *ppos); | ||
| 65 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
| 61 | void __user *buffer, size_t *lenp, | 66 | void __user *buffer, size_t *lenp, |
| 62 | |||
| 63 | loff_t *ppos); | 67 | loff_t *ppos); |
| 68 | |||
| 64 | static struct ctl_table sctp_table[] = { | 69 | static struct ctl_table sctp_table[] = { |
| 65 | { | 70 | { |
| 66 | .procname = "sctp_mem", | 71 | .procname = "sctp_mem", |
| @@ -102,17 +107,17 @@ static struct ctl_table sctp_net_table[] = { | |||
| 102 | .data = &init_net.sctp.rto_min, | 107 | .data = &init_net.sctp.rto_min, |
| 103 | .maxlen = sizeof(unsigned int), | 108 | .maxlen = sizeof(unsigned int), |
| 104 | .mode = 0644, | 109 | .mode = 0644, |
| 105 | .proc_handler = proc_dointvec_minmax, | 110 | .proc_handler = proc_sctp_do_rto_min, |
| 106 | .extra1 = &one, | 111 | .extra1 = &one, |
| 107 | .extra2 = &timer_max | 112 | .extra2 = &init_net.sctp.rto_max |
| 108 | }, | 113 | }, |
| 109 | { | 114 | { |
| 110 | .procname = "rto_max", | 115 | .procname = "rto_max", |
| 111 | .data = &init_net.sctp.rto_max, | 116 | .data = &init_net.sctp.rto_max, |
| 112 | .maxlen = sizeof(unsigned int), | 117 | .maxlen = sizeof(unsigned int), |
| 113 | .mode = 0644, | 118 | .mode = 0644, |
| 114 | .proc_handler = proc_dointvec_minmax, | 119 | .proc_handler = proc_sctp_do_rto_max, |
| 115 | .extra1 = &one, | 120 | .extra1 = &init_net.sctp.rto_min, |
| 116 | .extra2 = &timer_max | 121 | .extra2 = &timer_max |
| 117 | }, | 122 | }, |
| 118 | { | 123 | { |
| @@ -294,8 +299,7 @@ static struct ctl_table sctp_net_table[] = { | |||
| 294 | { /* sentinel */ } | 299 | { /* sentinel */ } |
| 295 | }; | 300 | }; |
| 296 | 301 | ||
| 297 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 302 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
| 298 | int write, | ||
| 299 | void __user *buffer, size_t *lenp, | 303 | void __user *buffer, size_t *lenp, |
| 300 | loff_t *ppos) | 304 | loff_t *ppos) |
| 301 | { | 305 | { |
| @@ -342,6 +346,60 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | |||
| 342 | return ret; | 346 | return ret; |
| 343 | } | 347 | } |
| 344 | 348 | ||
| 349 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
| 350 | void __user *buffer, size_t *lenp, | ||
| 351 | loff_t *ppos) | ||
| 352 | { | ||
| 353 | struct net *net = current->nsproxy->net_ns; | ||
| 354 | int new_value; | ||
| 355 | struct ctl_table tbl; | ||
| 356 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
| 357 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
| 358 | int ret; | ||
| 359 | |||
| 360 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
| 361 | tbl.maxlen = sizeof(unsigned int); | ||
| 362 | |||
| 363 | if (write) | ||
| 364 | tbl.data = &new_value; | ||
| 365 | else | ||
| 366 | tbl.data = &net->sctp.rto_min; | ||
| 367 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
| 368 | if (write) { | ||
| 369 | if (ret || new_value > max || new_value < min) | ||
| 370 | return -EINVAL; | ||
| 371 | net->sctp.rto_min = new_value; | ||
| 372 | } | ||
| 373 | return ret; | ||
| 374 | } | ||
| 375 | |||
| 376 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
| 377 | void __user *buffer, size_t *lenp, | ||
| 378 | loff_t *ppos) | ||
| 379 | { | ||
| 380 | struct net *net = current->nsproxy->net_ns; | ||
| 381 | int new_value; | ||
| 382 | struct ctl_table tbl; | ||
| 383 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
| 384 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
| 385 | int ret; | ||
| 386 | |||
| 387 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
| 388 | tbl.maxlen = sizeof(unsigned int); | ||
| 389 | |||
| 390 | if (write) | ||
| 391 | tbl.data = &new_value; | ||
| 392 | else | ||
| 393 | tbl.data = &net->sctp.rto_max; | ||
| 394 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
| 395 | if (write) { | ||
| 396 | if (ret || new_value > max || new_value < min) | ||
| 397 | return -EINVAL; | ||
| 398 | net->sctp.rto_max = new_value; | ||
| 399 | } | ||
| 400 | return ret; | ||
| 401 | } | ||
| 402 | |||
| 345 | int sctp_sysctl_net_register(struct net *net) | 403 | int sctp_sysctl_net_register(struct net *net) |
| 346 | { | 404 | { |
| 347 | struct ctl_table *table; | 405 | struct ctl_table *table; |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index e332efb124cc..efc46ffed1fd 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -573,7 +573,7 @@ void sctp_transport_burst_limited(struct sctp_transport *t) | |||
| 573 | u32 old_cwnd = t->cwnd; | 573 | u32 old_cwnd = t->cwnd; |
| 574 | u32 max_burst_bytes; | 574 | u32 max_burst_bytes; |
| 575 | 575 | ||
| 576 | if (t->burst_limited) | 576 | if (t->burst_limited || asoc->max_burst == 0) |
| 577 | return; | 577 | return; |
| 578 | 578 | ||
| 579 | max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); | 579 | max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); |
diff --git a/net/socket.c b/net/socket.c index c226aceee65b..e83c416708af 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -221,12 +221,13 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen, | |||
| 221 | int err; | 221 | int err; |
| 222 | int len; | 222 | int len; |
| 223 | 223 | ||
| 224 | BUG_ON(klen > sizeof(struct sockaddr_storage)); | ||
| 224 | err = get_user(len, ulen); | 225 | err = get_user(len, ulen); |
| 225 | if (err) | 226 | if (err) |
| 226 | return err; | 227 | return err; |
| 227 | if (len > klen) | 228 | if (len > klen) |
| 228 | len = klen; | 229 | len = klen; |
| 229 | if (len < 0 || len > sizeof(struct sockaddr_storage)) | 230 | if (len < 0) |
| 230 | return -EINVAL; | 231 | return -EINVAL; |
| 231 | if (len) { | 232 | if (len) { |
| 232 | if (audit_sockaddr(klen, kaddr)) | 233 | if (audit_sockaddr(klen, kaddr)) |
| @@ -1840,8 +1841,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, | |||
| 1840 | msg.msg_iov = &iov; | 1841 | msg.msg_iov = &iov; |
| 1841 | iov.iov_len = size; | 1842 | iov.iov_len = size; |
| 1842 | iov.iov_base = ubuf; | 1843 | iov.iov_base = ubuf; |
| 1843 | msg.msg_name = (struct sockaddr *)&address; | 1844 | /* Save some cycles and don't copy the address if not needed */ |
| 1844 | msg.msg_namelen = sizeof(address); | 1845 | msg.msg_name = addr ? (struct sockaddr *)&address : NULL; |
| 1846 | /* We assume all kernel code knows the size of sockaddr_storage */ | ||
| 1847 | msg.msg_namelen = 0; | ||
| 1845 | if (sock->file->f_flags & O_NONBLOCK) | 1848 | if (sock->file->f_flags & O_NONBLOCK) |
| 1846 | flags |= MSG_DONTWAIT; | 1849 | flags |= MSG_DONTWAIT; |
| 1847 | err = sock_recvmsg(sock, &msg, size, flags); | 1850 | err = sock_recvmsg(sock, &msg, size, flags); |
| @@ -1970,7 +1973,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, | |||
| 1970 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) | 1973 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) |
| 1971 | return -EFAULT; | 1974 | return -EFAULT; |
| 1972 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) | 1975 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) |
| 1973 | return -EINVAL; | 1976 | kmsg->msg_namelen = sizeof(struct sockaddr_storage); |
| 1974 | return 0; | 1977 | return 0; |
| 1975 | } | 1978 | } |
| 1976 | 1979 | ||
| @@ -2221,16 +2224,14 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, | |||
| 2221 | goto out; | 2224 | goto out; |
| 2222 | } | 2225 | } |
| 2223 | 2226 | ||
| 2224 | /* | 2227 | /* Save the user-mode address (verify_iovec will change the |
| 2225 | * Save the user-mode address (verify_iovec will change the | 2228 | * kernel msghdr to use the kernel address space) |
| 2226 | * kernel msghdr to use the kernel address space) | ||
| 2227 | */ | 2229 | */ |
| 2228 | |||
| 2229 | uaddr = (__force void __user *)msg_sys->msg_name; | 2230 | uaddr = (__force void __user *)msg_sys->msg_name; |
| 2230 | uaddr_len = COMPAT_NAMELEN(msg); | 2231 | uaddr_len = COMPAT_NAMELEN(msg); |
| 2231 | if (MSG_CMSG_COMPAT & flags) { | 2232 | if (MSG_CMSG_COMPAT & flags) |
| 2232 | err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); | 2233 | err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); |
| 2233 | } else | 2234 | else |
| 2234 | err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE); | 2235 | err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE); |
| 2235 | if (err < 0) | 2236 | if (err < 0) |
| 2236 | goto out_freeiov; | 2237 | goto out_freeiov; |
| @@ -2239,6 +2240,9 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, | |||
| 2239 | cmsg_ptr = (unsigned long)msg_sys->msg_control; | 2240 | cmsg_ptr = (unsigned long)msg_sys->msg_control; |
| 2240 | msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); | 2241 | msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); |
| 2241 | 2242 | ||
| 2243 | /* We assume all kernel code knows the size of sockaddr_storage */ | ||
| 2244 | msg_sys->msg_namelen = 0; | ||
| 2245 | |||
| 2242 | if (sock->file->f_flags & O_NONBLOCK) | 2246 | if (sock->file->f_flags & O_NONBLOCK) |
| 2243 | flags |= MSG_DONTWAIT; | 2247 | flags |= MSG_DONTWAIT; |
| 2244 | err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, | 2248 | err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 97912b40c254..42fdfc634e56 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -1517,7 +1517,7 @@ out: | |||
| 1517 | static int | 1517 | static int |
| 1518 | gss_refresh_null(struct rpc_task *task) | 1518 | gss_refresh_null(struct rpc_task *task) |
| 1519 | { | 1519 | { |
| 1520 | return -EACCES; | 1520 | return 0; |
| 1521 | } | 1521 | } |
| 1522 | 1522 | ||
| 1523 | static __be32 * | 1523 | static __be32 * |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index d0d14a04dce1..bf04b30a788a 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -471,15 +471,6 @@ struct rpc_filelist { | |||
| 471 | umode_t mode; | 471 | umode_t mode; |
| 472 | }; | 472 | }; |
| 473 | 473 | ||
| 474 | static int rpc_delete_dentry(const struct dentry *dentry) | ||
| 475 | { | ||
| 476 | return 1; | ||
| 477 | } | ||
| 478 | |||
| 479 | static const struct dentry_operations rpc_dentry_operations = { | ||
| 480 | .d_delete = rpc_delete_dentry, | ||
| 481 | }; | ||
| 482 | |||
| 483 | static struct inode * | 474 | static struct inode * |
| 484 | rpc_get_inode(struct super_block *sb, umode_t mode) | 475 | rpc_get_inode(struct super_block *sb, umode_t mode) |
| 485 | { | 476 | { |
| @@ -1266,7 +1257,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1266 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 1257 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
| 1267 | sb->s_magic = RPCAUTH_GSSMAGIC; | 1258 | sb->s_magic = RPCAUTH_GSSMAGIC; |
| 1268 | sb->s_op = &s_ops; | 1259 | sb->s_op = &s_ops; |
| 1269 | sb->s_d_op = &rpc_dentry_operations; | 1260 | sb->s_d_op = &simple_dentry_operations; |
| 1270 | sb->s_time_gran = 1; | 1261 | sb->s_time_gran = 1; |
| 1271 | 1262 | ||
| 1272 | inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); | 1263 | inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); |
diff --git a/net/tipc/core.c b/net/tipc/core.c index fd4eeeaa972a..c6d3f75a9e1b 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
| @@ -113,7 +113,6 @@ err: | |||
| 113 | static void tipc_core_stop(void) | 113 | static void tipc_core_stop(void) |
| 114 | { | 114 | { |
| 115 | tipc_netlink_stop(); | 115 | tipc_netlink_stop(); |
| 116 | tipc_handler_stop(); | ||
| 117 | tipc_cfg_stop(); | 116 | tipc_cfg_stop(); |
| 118 | tipc_subscr_stop(); | 117 | tipc_subscr_stop(); |
| 119 | tipc_nametbl_stop(); | 118 | tipc_nametbl_stop(); |
| @@ -146,9 +145,10 @@ static int tipc_core_start(void) | |||
| 146 | res = tipc_subscr_start(); | 145 | res = tipc_subscr_start(); |
| 147 | if (!res) | 146 | if (!res) |
| 148 | res = tipc_cfg_init(); | 147 | res = tipc_cfg_init(); |
| 149 | if (res) | 148 | if (res) { |
| 149 | tipc_handler_stop(); | ||
| 150 | tipc_core_stop(); | 150 | tipc_core_stop(); |
| 151 | 151 | } | |
| 152 | return res; | 152 | return res; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| @@ -178,6 +178,7 @@ static int __init tipc_init(void) | |||
| 178 | 178 | ||
| 179 | static void __exit tipc_exit(void) | 179 | static void __exit tipc_exit(void) |
| 180 | { | 180 | { |
| 181 | tipc_handler_stop(); | ||
| 181 | tipc_core_stop_net(); | 182 | tipc_core_stop_net(); |
| 182 | tipc_core_stop(); | 183 | tipc_core_stop(); |
| 183 | pr_info("Deactivated\n"); | 184 | pr_info("Deactivated\n"); |
diff --git a/net/tipc/handler.c b/net/tipc/handler.c index b36f0fcd9bdf..e4bc8a296744 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c | |||
| @@ -56,12 +56,13 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument) | |||
| 56 | { | 56 | { |
| 57 | struct queue_item *item; | 57 | struct queue_item *item; |
| 58 | 58 | ||
| 59 | spin_lock_bh(&qitem_lock); | ||
| 59 | if (!handler_enabled) { | 60 | if (!handler_enabled) { |
| 60 | pr_err("Signal request ignored by handler\n"); | 61 | pr_err("Signal request ignored by handler\n"); |
| 62 | spin_unlock_bh(&qitem_lock); | ||
| 61 | return -ENOPROTOOPT; | 63 | return -ENOPROTOOPT; |
| 62 | } | 64 | } |
| 63 | 65 | ||
| 64 | spin_lock_bh(&qitem_lock); | ||
| 65 | item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); | 66 | item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); |
| 66 | if (!item) { | 67 | if (!item) { |
| 67 | pr_err("Signal queue out of memory\n"); | 68 | pr_err("Signal queue out of memory\n"); |
| @@ -112,10 +113,14 @@ void tipc_handler_stop(void) | |||
| 112 | struct list_head *l, *n; | 113 | struct list_head *l, *n; |
| 113 | struct queue_item *item; | 114 | struct queue_item *item; |
| 114 | 115 | ||
| 115 | if (!handler_enabled) | 116 | spin_lock_bh(&qitem_lock); |
| 117 | if (!handler_enabled) { | ||
| 118 | spin_unlock_bh(&qitem_lock); | ||
| 116 | return; | 119 | return; |
| 117 | 120 | } | |
| 118 | handler_enabled = 0; | 121 | handler_enabled = 0; |
| 122 | spin_unlock_bh(&qitem_lock); | ||
| 123 | |||
| 119 | tasklet_kill(&tipc_tasklet); | 124 | tasklet_kill(&tipc_tasklet); |
| 120 | 125 | ||
| 121 | spin_lock_bh(&qitem_lock); | 126 | spin_lock_bh(&qitem_lock); |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3906527259d1..3b61851bb927 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -980,9 +980,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock, | |||
| 980 | goto exit; | 980 | goto exit; |
| 981 | } | 981 | } |
| 982 | 982 | ||
| 983 | /* will be updated in set_orig_addr() if needed */ | ||
| 984 | m->msg_namelen = 0; | ||
| 985 | |||
| 986 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 983 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
| 987 | restart: | 984 | restart: |
| 988 | 985 | ||
| @@ -1091,9 +1088,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1091 | goto exit; | 1088 | goto exit; |
| 1092 | } | 1089 | } |
| 1093 | 1090 | ||
| 1094 | /* will be updated in set_orig_addr() if needed */ | ||
| 1095 | m->msg_namelen = 0; | ||
| 1096 | |||
| 1097 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); | 1091 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); |
| 1098 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 1092 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
| 1099 | 1093 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index c1f403bed683..a0ca162e5bd5 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -530,13 +530,17 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, | |||
| 530 | static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, | 530 | static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, |
| 531 | struct msghdr *, size_t, int); | 531 | struct msghdr *, size_t, int); |
| 532 | 532 | ||
| 533 | static void unix_set_peek_off(struct sock *sk, int val) | 533 | static int unix_set_peek_off(struct sock *sk, int val) |
| 534 | { | 534 | { |
| 535 | struct unix_sock *u = unix_sk(sk); | 535 | struct unix_sock *u = unix_sk(sk); |
| 536 | 536 | ||
| 537 | mutex_lock(&u->readlock); | 537 | if (mutex_lock_interruptible(&u->readlock)) |
| 538 | return -EINTR; | ||
| 539 | |||
| 538 | sk->sk_peek_off = val; | 540 | sk->sk_peek_off = val; |
| 539 | mutex_unlock(&u->readlock); | 541 | mutex_unlock(&u->readlock); |
| 542 | |||
| 543 | return 0; | ||
| 540 | } | 544 | } |
| 541 | 545 | ||
| 542 | 546 | ||
| @@ -1754,7 +1758,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk) | |||
| 1754 | { | 1758 | { |
| 1755 | struct unix_sock *u = unix_sk(sk); | 1759 | struct unix_sock *u = unix_sk(sk); |
| 1756 | 1760 | ||
| 1757 | msg->msg_namelen = 0; | ||
| 1758 | if (u->addr) { | 1761 | if (u->addr) { |
| 1759 | msg->msg_namelen = u->addr->len; | 1762 | msg->msg_namelen = u->addr->len; |
| 1760 | memcpy(msg->msg_name, u->addr->name, u->addr->len); | 1763 | memcpy(msg->msg_name, u->addr->name, u->addr->len); |
| @@ -1778,8 +1781,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1778 | if (flags&MSG_OOB) | 1781 | if (flags&MSG_OOB) |
| 1779 | goto out; | 1782 | goto out; |
| 1780 | 1783 | ||
| 1781 | msg->msg_namelen = 0; | ||
| 1782 | |||
| 1783 | err = mutex_lock_interruptible(&u->readlock); | 1784 | err = mutex_lock_interruptible(&u->readlock); |
| 1784 | if (err) { | 1785 | if (err) { |
| 1785 | err = sock_intr_errno(sock_rcvtimeo(sk, noblock)); | 1786 | err = sock_intr_errno(sock_rcvtimeo(sk, noblock)); |
| @@ -1924,8 +1925,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1924 | target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); | 1925 | target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); |
| 1925 | timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); | 1926 | timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); |
| 1926 | 1927 | ||
| 1927 | msg->msg_namelen = 0; | ||
| 1928 | |||
| 1929 | /* Lock the socket to prevent queue disordering | 1928 | /* Lock the socket to prevent queue disordering |
| 1930 | * while sleeps in memcpy_tomsg | 1929 | * while sleeps in memcpy_tomsg |
| 1931 | */ | 1930 | */ |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 545c08b8a1d4..5adfd94c5b85 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
| @@ -1662,8 +1662,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb, | |||
| 1662 | vsk = vsock_sk(sk); | 1662 | vsk = vsock_sk(sk); |
| 1663 | err = 0; | 1663 | err = 0; |
| 1664 | 1664 | ||
| 1665 | msg->msg_namelen = 0; | ||
| 1666 | |||
| 1667 | lock_sock(sk); | 1665 | lock_sock(sk); |
| 1668 | 1666 | ||
| 1669 | if (sk->sk_state != SS_CONNECTED) { | 1667 | if (sk->sk_state != SS_CONNECTED) { |
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 9d6986634e0b..687360da62d9 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c | |||
| @@ -1746,8 +1746,6 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb, | |||
| 1746 | if (flags & MSG_OOB || flags & MSG_ERRQUEUE) | 1746 | if (flags & MSG_OOB || flags & MSG_ERRQUEUE) |
| 1747 | return -EOPNOTSUPP; | 1747 | return -EOPNOTSUPP; |
| 1748 | 1748 | ||
| 1749 | msg->msg_namelen = 0; | ||
| 1750 | |||
| 1751 | /* Retrieve the head sk_buff from the socket's receive queue. */ | 1749 | /* Retrieve the head sk_buff from the socket's receive queue. */ |
| 1752 | err = 0; | 1750 | err = 0; |
| 1753 | skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err); | 1751 | skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err); |
diff --git a/net/wimax/stack.c b/net/wimax/stack.c index ef2191b969a7..ec8b577db135 100644 --- a/net/wimax/stack.c +++ b/net/wimax/stack.c | |||
| @@ -610,7 +610,6 @@ int __init wimax_subsys_init(void) | |||
| 610 | d_fnend(4, NULL, "() = 0\n"); | 610 | d_fnend(4, NULL, "() = 0\n"); |
| 611 | return 0; | 611 | return 0; |
| 612 | 612 | ||
| 613 | genl_unregister_family(&wimax_gnl_family); | ||
| 614 | error_register_family: | 613 | error_register_family: |
| 615 | d_fnend(4, NULL, "() = %d\n", result); | 614 | d_fnend(4, NULL, "() = %d\n", result); |
| 616 | return result; | 615 | return result; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index aff959e5a1b3..52b865fb7351 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -451,6 +451,15 @@ int wiphy_register(struct wiphy *wiphy) | |||
| 451 | int i; | 451 | int i; |
| 452 | u16 ifmodes = wiphy->interface_modes; | 452 | u16 ifmodes = wiphy->interface_modes; |
| 453 | 453 | ||
| 454 | /* support for 5/10 MHz is broken due to nl80211 API mess - disable */ | ||
| 455 | wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ; | ||
| 456 | |||
| 457 | /* | ||
| 458 | * There are major locking problems in nl80211/mac80211 for CSA, | ||
| 459 | * disable for all drivers until this has been reworked. | ||
| 460 | */ | ||
| 461 | wiphy->flags &= ~WIPHY_FLAG_HAS_CHANNEL_SWITCH; | ||
| 462 | |||
| 454 | #ifdef CONFIG_PM | 463 | #ifdef CONFIG_PM |
| 455 | if (WARN_ON(wiphy->wowlan && | 464 | if (WARN_ON(wiphy->wowlan && |
| 456 | (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && | 465 | (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 9d797df56649..89737ee2669a 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
| @@ -262,7 +262,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
| 262 | 262 | ||
| 263 | /* try to find an IBSS channel if none requested ... */ | 263 | /* try to find an IBSS channel if none requested ... */ |
| 264 | if (!wdev->wext.ibss.chandef.chan) { | 264 | if (!wdev->wext.ibss.chandef.chan) { |
| 265 | wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | 265 | struct ieee80211_channel *new_chan = NULL; |
| 266 | 266 | ||
| 267 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 267 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
| 268 | struct ieee80211_supported_band *sband; | 268 | struct ieee80211_supported_band *sband; |
| @@ -278,18 +278,19 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
| 278 | continue; | 278 | continue; |
| 279 | if (chan->flags & IEEE80211_CHAN_DISABLED) | 279 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
| 280 | continue; | 280 | continue; |
| 281 | wdev->wext.ibss.chandef.chan = chan; | 281 | new_chan = chan; |
| 282 | wdev->wext.ibss.chandef.center_freq1 = | ||
| 283 | chan->center_freq; | ||
| 284 | break; | 282 | break; |
| 285 | } | 283 | } |
| 286 | 284 | ||
| 287 | if (wdev->wext.ibss.chandef.chan) | 285 | if (new_chan) |
| 288 | break; | 286 | break; |
| 289 | } | 287 | } |
| 290 | 288 | ||
| 291 | if (!wdev->wext.ibss.chandef.chan) | 289 | if (!new_chan) |
| 292 | return -EINVAL; | 290 | return -EINVAL; |
| 291 | |||
| 292 | cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan, | ||
| 293 | NL80211_CHAN_NO_HT); | ||
| 293 | } | 294 | } |
| 294 | 295 | ||
| 295 | /* don't join -- SSID is not there */ | 296 | /* don't join -- SSID is not there */ |
| @@ -363,9 +364,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
| 363 | return err; | 364 | return err; |
| 364 | 365 | ||
| 365 | if (chan) { | 366 | if (chan) { |
| 366 | wdev->wext.ibss.chandef.chan = chan; | 367 | cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan, |
| 367 | wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | 368 | NL80211_CHAN_NO_HT); |
| 368 | wdev->wext.ibss.chandef.center_freq1 = freq; | ||
| 369 | wdev->wext.ibss.channel_fixed = true; | 369 | wdev->wext.ibss.channel_fixed = true; |
| 370 | } else { | 370 | } else { |
| 371 | /* cfg80211_ibss_wext_join will pick one if needed */ | 371 | /* cfg80211_ibss_wext_join will pick one if needed */ |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a1eb21073176..138dc3bb8b67 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -2687,7 +2687,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
| 2687 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 2687 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
| 2688 | NL80211_CMD_NEW_KEY); | 2688 | NL80211_CMD_NEW_KEY); |
| 2689 | if (!hdr) | 2689 | if (!hdr) |
| 2690 | return -ENOBUFS; | 2690 | goto nla_put_failure; |
| 2691 | 2691 | ||
| 2692 | cookie.msg = msg; | 2692 | cookie.msg = msg; |
| 2693 | cookie.idx = key_idx; | 2693 | cookie.idx = key_idx; |
| @@ -5349,6 +5349,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
| 5349 | err = -EINVAL; | 5349 | err = -EINVAL; |
| 5350 | goto out_free; | 5350 | goto out_free; |
| 5351 | } | 5351 | } |
| 5352 | |||
| 5353 | if (!wiphy->bands[band]) | ||
| 5354 | continue; | ||
| 5355 | |||
| 5352 | err = ieee80211_get_ratemask(wiphy->bands[band], | 5356 | err = ieee80211_get_ratemask(wiphy->bands[band], |
| 5353 | nla_data(attr), | 5357 | nla_data(attr), |
| 5354 | nla_len(attr), | 5358 | nla_len(attr), |
| @@ -9633,8 +9637,9 @@ static int nl80211_add_scan_req(struct sk_buff *msg, | |||
| 9633 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) | 9637 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) |
| 9634 | goto nla_put_failure; | 9638 | goto nla_put_failure; |
| 9635 | 9639 | ||
| 9636 | if (req->flags) | 9640 | if (req->flags && |
| 9637 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags); | 9641 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags)) |
| 9642 | goto nla_put_failure; | ||
| 9638 | 9643 | ||
| 9639 | return 0; | 9644 | return 0; |
| 9640 | nla_put_failure: | 9645 | nla_put_failure: |
| @@ -11093,6 +11098,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
| 11093 | struct nlattr *reasons; | 11098 | struct nlattr *reasons; |
| 11094 | 11099 | ||
| 11095 | reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); | 11100 | reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); |
| 11101 | if (!reasons) | ||
| 11102 | goto free_msg; | ||
| 11096 | 11103 | ||
| 11097 | if (wakeup->disconnect && | 11104 | if (wakeup->disconnect && |
| 11098 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) | 11105 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) |
| @@ -11118,16 +11125,18 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
| 11118 | wakeup->pattern_idx)) | 11125 | wakeup->pattern_idx)) |
| 11119 | goto free_msg; | 11126 | goto free_msg; |
| 11120 | 11127 | ||
| 11121 | if (wakeup->tcp_match) | 11128 | if (wakeup->tcp_match && |
| 11122 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH); | 11129 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH)) |
| 11130 | goto free_msg; | ||
| 11123 | 11131 | ||
| 11124 | if (wakeup->tcp_connlost) | 11132 | if (wakeup->tcp_connlost && |
| 11125 | nla_put_flag(msg, | 11133 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST)) |
| 11126 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST); | 11134 | goto free_msg; |
| 11127 | 11135 | ||
| 11128 | if (wakeup->tcp_nomoretokens) | 11136 | if (wakeup->tcp_nomoretokens && |
| 11129 | nla_put_flag(msg, | 11137 | nla_put_flag(msg, |
| 11130 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS); | 11138 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS)) |
| 11139 | goto free_msg; | ||
| 11131 | 11140 | ||
| 11132 | if (wakeup->packet) { | 11141 | if (wakeup->packet) { |
| 11133 | u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211; | 11142 | u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211; |
| @@ -11263,24 +11272,29 @@ void cfg80211_ft_event(struct net_device *netdev, | |||
| 11263 | return; | 11272 | return; |
| 11264 | 11273 | ||
| 11265 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT); | 11274 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT); |
| 11266 | if (!hdr) { | 11275 | if (!hdr) |
| 11267 | nlmsg_free(msg); | 11276 | goto out; |
| 11268 | return; | ||
| 11269 | } | ||
| 11270 | 11277 | ||
| 11271 | nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | 11278 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
| 11272 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 11279 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
| 11273 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap); | 11280 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap)) |
| 11274 | if (ft_event->ies) | 11281 | goto out; |
| 11275 | nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies); | 11282 | |
| 11276 | if (ft_event->ric_ies) | 11283 | if (ft_event->ies && |
| 11277 | nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, | 11284 | nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies)) |
| 11278 | ft_event->ric_ies); | 11285 | goto out; |
| 11286 | if (ft_event->ric_ies && | ||
| 11287 | nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, | ||
| 11288 | ft_event->ric_ies)) | ||
| 11289 | goto out; | ||
| 11279 | 11290 | ||
| 11280 | genlmsg_end(msg, hdr); | 11291 | genlmsg_end(msg, hdr); |
| 11281 | 11292 | ||
| 11282 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 11293 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 11283 | NL80211_MCGRP_MLME, GFP_KERNEL); | 11294 | NL80211_MCGRP_MLME, GFP_KERNEL); |
| 11295 | return; | ||
| 11296 | out: | ||
| 11297 | nlmsg_free(msg); | ||
| 11284 | } | 11298 | } |
| 11285 | EXPORT_SYMBOL(cfg80211_ft_event); | 11299 | EXPORT_SYMBOL(cfg80211_ft_event); |
| 11286 | 11300 | ||
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 45a3ab5612c1..7622789d3750 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
| @@ -1340,10 +1340,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1340 | if (sx25) { | 1340 | if (sx25) { |
| 1341 | sx25->sx25_family = AF_X25; | 1341 | sx25->sx25_family = AF_X25; |
| 1342 | sx25->sx25_addr = x25->dest_addr; | 1342 | sx25->sx25_addr = x25->dest_addr; |
| 1343 | msg->msg_namelen = sizeof(*sx25); | ||
| 1343 | } | 1344 | } |
| 1344 | 1345 | ||
| 1345 | msg->msg_namelen = sizeof(struct sockaddr_x25); | ||
| 1346 | |||
| 1347 | x25_check_rbuf(sk); | 1346 | x25_check_rbuf(sk); |
| 1348 | rc = copied; | 1347 | rc = copied; |
| 1349 | out_free_dgram: | 1348 | out_free_dgram: |
