diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-05-19 13:12:41 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-05-19 13:12:41 -0400 |
commit | 8d0bc2b456103a34c11e01305cd1aed1cde579e5 (patch) | |
tree | 5e1e6ad55cc9e2b5c5617f6f320114b8cff9e3f3 /net | |
parent | 30ba3ead05763b172acaa65ae1be71af2a878940 (diff) | |
parent | e40152ee1e1c7a63f4777791863215e3faa37a86 (diff) |
Merge commit 'v2.6.34' into next
Diffstat (limited to 'net')
40 files changed, 492 insertions, 162 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 99d68c34e4f1..9753b690a8b3 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1626,7 +1626,10 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1626 | /* Connectionless channel */ | 1626 | /* Connectionless channel */ |
1627 | if (sk->sk_type == SOCK_DGRAM) { | 1627 | if (sk->sk_type == SOCK_DGRAM) { |
1628 | skb = l2cap_create_connless_pdu(sk, msg, len); | 1628 | skb = l2cap_create_connless_pdu(sk, msg, len); |
1629 | err = l2cap_do_send(sk, skb); | 1629 | if (IS_ERR(skb)) |
1630 | err = PTR_ERR(skb); | ||
1631 | else | ||
1632 | err = l2cap_do_send(sk, skb); | ||
1630 | goto done; | 1633 | goto done; |
1631 | } | 1634 | } |
1632 | 1635 | ||
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 6980625537ca..eaa0e1bae49b 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -723,11 +723,11 @@ static int br_multicast_igmp3_report(struct net_bridge *br, | |||
723 | if (!pskb_may_pull(skb, len)) | 723 | if (!pskb_may_pull(skb, len)) |
724 | return -EINVAL; | 724 | return -EINVAL; |
725 | 725 | ||
726 | grec = (void *)(skb->data + len); | 726 | grec = (void *)(skb->data + len - sizeof(*grec)); |
727 | group = grec->grec_mca; | 727 | group = grec->grec_mca; |
728 | type = grec->grec_type; | 728 | type = grec->grec_type; |
729 | 729 | ||
730 | len += grec->grec_nsrcs * 4; | 730 | len += ntohs(grec->grec_nsrcs) * 4; |
731 | if (!pskb_may_pull(skb, len)) | 731 | if (!pskb_may_pull(skb, len)) |
732 | return -EINVAL; | 732 | return -EINVAL; |
733 | 733 | ||
@@ -957,9 +957,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
957 | unsigned offset; | 957 | unsigned offset; |
958 | int err; | 958 | int err; |
959 | 959 | ||
960 | BR_INPUT_SKB_CB(skb)->igmp = 0; | ||
961 | BR_INPUT_SKB_CB(skb)->mrouters_only = 0; | ||
962 | |||
963 | /* We treat OOM as packet loss for now. */ | 960 | /* We treat OOM as packet loss for now. */ |
964 | if (!pskb_may_pull(skb, sizeof(*iph))) | 961 | if (!pskb_may_pull(skb, sizeof(*iph))) |
965 | return -EINVAL; | 962 | return -EINVAL; |
@@ -1049,6 +1046,9 @@ err_out: | |||
1049 | int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, | 1046 | int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, |
1050 | struct sk_buff *skb) | 1047 | struct sk_buff *skb) |
1051 | { | 1048 | { |
1049 | BR_INPUT_SKB_CB(skb)->igmp = 0; | ||
1050 | BR_INPUT_SKB_CB(skb)->mrouters_only = 0; | ||
1051 | |||
1052 | if (br->multicast_disabled) | 1052 | if (br->multicast_disabled) |
1053 | return 0; | 1053 | return 0; |
1054 | 1054 | ||
diff --git a/net/can/raw.c b/net/can/raw.c index 3a7dffb6519c..da99cf153b33 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -445,7 +445,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
445 | return -EFAULT; | 445 | return -EFAULT; |
446 | } | 446 | } |
447 | } else if (count == 1) { | 447 | } else if (count == 1) { |
448 | if (copy_from_user(&sfilter, optval, optlen)) | 448 | if (copy_from_user(&sfilter, optval, sizeof(sfilter))) |
449 | return -EFAULT; | 449 | return -EFAULT; |
450 | } | 450 | } |
451 | 451 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 1c8a0ce473a8..264137fce3a2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1451,7 +1451,7 @@ static inline void net_timestamp(struct sk_buff *skb) | |||
1451 | * | 1451 | * |
1452 | * return values: | 1452 | * return values: |
1453 | * NET_RX_SUCCESS (no congestion) | 1453 | * NET_RX_SUCCESS (no congestion) |
1454 | * NET_RX_DROP (packet was dropped) | 1454 | * NET_RX_DROP (packet was dropped, but freed) |
1455 | * | 1455 | * |
1456 | * dev_forward_skb can be used for injecting an skb from the | 1456 | * dev_forward_skb can be used for injecting an skb from the |
1457 | * start_xmit function of one device into the receive queue | 1457 | * start_xmit function of one device into the receive queue |
@@ -1465,12 +1465,11 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | |||
1465 | { | 1465 | { |
1466 | skb_orphan(skb); | 1466 | skb_orphan(skb); |
1467 | 1467 | ||
1468 | if (!(dev->flags & IFF_UP)) | 1468 | if (!(dev->flags & IFF_UP) || |
1469 | return NET_RX_DROP; | 1469 | (skb->len > (dev->mtu + dev->hard_header_len))) { |
1470 | 1470 | kfree_skb(skb); | |
1471 | if (skb->len > (dev->mtu + dev->hard_header_len)) | ||
1472 | return NET_RX_DROP; | 1471 | return NET_RX_DROP; |
1473 | 1472 | } | |
1474 | skb_set_dev(skb, dev); | 1473 | skb_set_dev(skb, dev); |
1475 | skb->tstamp.tv64 = 0; | 1474 | skb->tstamp.tv64 = 0; |
1476 | skb->pkt_type = PACKET_HOST; | 1475 | skb->pkt_type = PACKET_HOST; |
@@ -1989,8 +1988,12 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
1989 | if (dev->real_num_tx_queues > 1) | 1988 | if (dev->real_num_tx_queues > 1) |
1990 | queue_index = skb_tx_hash(dev, skb); | 1989 | queue_index = skb_tx_hash(dev, skb); |
1991 | 1990 | ||
1992 | if (sk && sk->sk_dst_cache) | 1991 | if (sk) { |
1993 | sk_tx_queue_set(sk, queue_index); | 1992 | struct dst_entry *dst = rcu_dereference_bh(sk->sk_dst_cache); |
1993 | |||
1994 | if (dst && skb_dst(skb) == dst) | ||
1995 | sk_tx_queue_set(sk, queue_index); | ||
1996 | } | ||
1994 | } | 1997 | } |
1995 | } | 1998 | } |
1996 | 1999 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 4568120d8533..31e85d327aa2 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -602,12 +602,19 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | |||
602 | a->tx_compressed = b->tx_compressed; | 602 | a->tx_compressed = b->tx_compressed; |
603 | }; | 603 | }; |
604 | 604 | ||
605 | /* All VF info */ | ||
605 | static inline int rtnl_vfinfo_size(const struct net_device *dev) | 606 | static inline int rtnl_vfinfo_size(const struct net_device *dev) |
606 | { | 607 | { |
607 | if (dev->dev.parent && dev_is_pci(dev->dev.parent)) | 608 | if (dev->dev.parent && dev_is_pci(dev->dev.parent)) { |
608 | return dev_num_vf(dev->dev.parent) * | 609 | |
609 | sizeof(struct ifla_vf_info); | 610 | int num_vfs = dev_num_vf(dev->dev.parent); |
610 | else | 611 | size_t size = nlmsg_total_size(sizeof(struct nlattr)); |
612 | size += nlmsg_total_size(num_vfs * sizeof(struct nlattr)); | ||
613 | size += num_vfs * (sizeof(struct ifla_vf_mac) + | ||
614 | sizeof(struct ifla_vf_vlan) + | ||
615 | sizeof(struct ifla_vf_tx_rate)); | ||
616 | return size; | ||
617 | } else | ||
611 | return 0; | 618 | return 0; |
612 | } | 619 | } |
613 | 620 | ||
@@ -629,7 +636,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev) | |||
629 | + nla_total_size(1) /* IFLA_OPERSTATE */ | 636 | + nla_total_size(1) /* IFLA_OPERSTATE */ |
630 | + nla_total_size(1) /* IFLA_LINKMODE */ | 637 | + nla_total_size(1) /* IFLA_LINKMODE */ |
631 | + nla_total_size(4) /* IFLA_NUM_VF */ | 638 | + nla_total_size(4) /* IFLA_NUM_VF */ |
632 | + nla_total_size(rtnl_vfinfo_size(dev)) /* IFLA_VFINFO */ | 639 | + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */ |
633 | + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ | 640 | + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ |
634 | } | 641 | } |
635 | 642 | ||
@@ -700,14 +707,37 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
700 | 707 | ||
701 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { | 708 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { |
702 | int i; | 709 | int i; |
703 | struct ifla_vf_info ivi; | ||
704 | 710 | ||
705 | NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)); | 711 | struct nlattr *vfinfo, *vf; |
706 | for (i = 0; i < dev_num_vf(dev->dev.parent); i++) { | 712 | int num_vfs = dev_num_vf(dev->dev.parent); |
713 | |||
714 | NLA_PUT_U32(skb, IFLA_NUM_VF, num_vfs); | ||
715 | vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST); | ||
716 | if (!vfinfo) | ||
717 | goto nla_put_failure; | ||
718 | for (i = 0; i < num_vfs; i++) { | ||
719 | struct ifla_vf_info ivi; | ||
720 | struct ifla_vf_mac vf_mac; | ||
721 | struct ifla_vf_vlan vf_vlan; | ||
722 | struct ifla_vf_tx_rate vf_tx_rate; | ||
707 | if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi)) | 723 | if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi)) |
708 | break; | 724 | break; |
709 | NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi); | 725 | vf_mac.vf = vf_vlan.vf = vf_tx_rate.vf = ivi.vf; |
726 | memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); | ||
727 | vf_vlan.vlan = ivi.vlan; | ||
728 | vf_vlan.qos = ivi.qos; | ||
729 | vf_tx_rate.rate = ivi.tx_rate; | ||
730 | vf = nla_nest_start(skb, IFLA_VF_INFO); | ||
731 | if (!vf) { | ||
732 | nla_nest_cancel(skb, vfinfo); | ||
733 | goto nla_put_failure; | ||
734 | } | ||
735 | NLA_PUT(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac); | ||
736 | NLA_PUT(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan); | ||
737 | NLA_PUT(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), &vf_tx_rate); | ||
738 | nla_nest_end(skb, vf); | ||
710 | } | 739 | } |
740 | nla_nest_end(skb, vfinfo); | ||
711 | } | 741 | } |
712 | if (dev->rtnl_link_ops) { | 742 | if (dev->rtnl_link_ops) { |
713 | if (rtnl_link_fill(skb, dev) < 0) | 743 | if (rtnl_link_fill(skb, dev) < 0) |
@@ -769,12 +799,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { | |||
769 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, | 799 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, |
770 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, | 800 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, |
771 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, | 801 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, |
772 | [IFLA_VF_MAC] = { .type = NLA_BINARY, | 802 | [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, |
773 | .len = sizeof(struct ifla_vf_mac) }, | ||
774 | [IFLA_VF_VLAN] = { .type = NLA_BINARY, | ||
775 | .len = sizeof(struct ifla_vf_vlan) }, | ||
776 | [IFLA_VF_TX_RATE] = { .type = NLA_BINARY, | ||
777 | .len = sizeof(struct ifla_vf_tx_rate) }, | ||
778 | }; | 803 | }; |
779 | EXPORT_SYMBOL(ifla_policy); | 804 | EXPORT_SYMBOL(ifla_policy); |
780 | 805 | ||
@@ -783,6 +808,19 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { | |||
783 | [IFLA_INFO_DATA] = { .type = NLA_NESTED }, | 808 | [IFLA_INFO_DATA] = { .type = NLA_NESTED }, |
784 | }; | 809 | }; |
785 | 810 | ||
811 | static const struct nla_policy ifla_vfinfo_policy[IFLA_VF_INFO_MAX+1] = { | ||
812 | [IFLA_VF_INFO] = { .type = NLA_NESTED }, | ||
813 | }; | ||
814 | |||
815 | static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { | ||
816 | [IFLA_VF_MAC] = { .type = NLA_BINARY, | ||
817 | .len = sizeof(struct ifla_vf_mac) }, | ||
818 | [IFLA_VF_VLAN] = { .type = NLA_BINARY, | ||
819 | .len = sizeof(struct ifla_vf_vlan) }, | ||
820 | [IFLA_VF_TX_RATE] = { .type = NLA_BINARY, | ||
821 | .len = sizeof(struct ifla_vf_tx_rate) }, | ||
822 | }; | ||
823 | |||
786 | struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) | 824 | struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) |
787 | { | 825 | { |
788 | struct net *net; | 826 | struct net *net; |
@@ -812,6 +850,52 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) | |||
812 | return 0; | 850 | return 0; |
813 | } | 851 | } |
814 | 852 | ||
853 | static int do_setvfinfo(struct net_device *dev, struct nlattr *attr) | ||
854 | { | ||
855 | int rem, err = -EINVAL; | ||
856 | struct nlattr *vf; | ||
857 | const struct net_device_ops *ops = dev->netdev_ops; | ||
858 | |||
859 | nla_for_each_nested(vf, attr, rem) { | ||
860 | switch (nla_type(vf)) { | ||
861 | case IFLA_VF_MAC: { | ||
862 | struct ifla_vf_mac *ivm; | ||
863 | ivm = nla_data(vf); | ||
864 | err = -EOPNOTSUPP; | ||
865 | if (ops->ndo_set_vf_mac) | ||
866 | err = ops->ndo_set_vf_mac(dev, ivm->vf, | ||
867 | ivm->mac); | ||
868 | break; | ||
869 | } | ||
870 | case IFLA_VF_VLAN: { | ||
871 | struct ifla_vf_vlan *ivv; | ||
872 | ivv = nla_data(vf); | ||
873 | err = -EOPNOTSUPP; | ||
874 | if (ops->ndo_set_vf_vlan) | ||
875 | err = ops->ndo_set_vf_vlan(dev, ivv->vf, | ||
876 | ivv->vlan, | ||
877 | ivv->qos); | ||
878 | break; | ||
879 | } | ||
880 | case IFLA_VF_TX_RATE: { | ||
881 | struct ifla_vf_tx_rate *ivt; | ||
882 | ivt = nla_data(vf); | ||
883 | err = -EOPNOTSUPP; | ||
884 | if (ops->ndo_set_vf_tx_rate) | ||
885 | err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, | ||
886 | ivt->rate); | ||
887 | break; | ||
888 | } | ||
889 | default: | ||
890 | err = -EINVAL; | ||
891 | break; | ||
892 | } | ||
893 | if (err) | ||
894 | break; | ||
895 | } | ||
896 | return err; | ||
897 | } | ||
898 | |||
815 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | 899 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, |
816 | struct nlattr **tb, char *ifname, int modified) | 900 | struct nlattr **tb, char *ifname, int modified) |
817 | { | 901 | { |
@@ -942,40 +1026,17 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
942 | write_unlock_bh(&dev_base_lock); | 1026 | write_unlock_bh(&dev_base_lock); |
943 | } | 1027 | } |
944 | 1028 | ||
945 | if (tb[IFLA_VF_MAC]) { | 1029 | if (tb[IFLA_VFINFO_LIST]) { |
946 | struct ifla_vf_mac *ivm; | 1030 | struct nlattr *attr; |
947 | ivm = nla_data(tb[IFLA_VF_MAC]); | 1031 | int rem; |
948 | err = -EOPNOTSUPP; | 1032 | nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) { |
949 | if (ops->ndo_set_vf_mac) | 1033 | if (nla_type(attr) != IFLA_VF_INFO) |
950 | err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac); | 1034 | goto errout; |
951 | if (err < 0) | 1035 | err = do_setvfinfo(dev, attr); |
952 | goto errout; | 1036 | if (err < 0) |
953 | modified = 1; | 1037 | goto errout; |
954 | } | 1038 | modified = 1; |
955 | 1039 | } | |
956 | if (tb[IFLA_VF_VLAN]) { | ||
957 | struct ifla_vf_vlan *ivv; | ||
958 | ivv = nla_data(tb[IFLA_VF_VLAN]); | ||
959 | err = -EOPNOTSUPP; | ||
960 | if (ops->ndo_set_vf_vlan) | ||
961 | err = ops->ndo_set_vf_vlan(dev, ivv->vf, | ||
962 | ivv->vlan, | ||
963 | ivv->qos); | ||
964 | if (err < 0) | ||
965 | goto errout; | ||
966 | modified = 1; | ||
967 | } | ||
968 | err = 0; | ||
969 | |||
970 | if (tb[IFLA_VF_TX_RATE]) { | ||
971 | struct ifla_vf_tx_rate *ivt; | ||
972 | ivt = nla_data(tb[IFLA_VF_TX_RATE]); | ||
973 | err = -EOPNOTSUPP; | ||
974 | if (ops->ndo_set_vf_tx_rate) | ||
975 | err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, ivt->rate); | ||
976 | if (err < 0) | ||
977 | goto errout; | ||
978 | modified = 1; | ||
979 | } | 1040 | } |
980 | err = 0; | 1041 | err = 0; |
981 | 1042 | ||
@@ -1270,10 +1331,11 @@ replay: | |||
1270 | err = ops->newlink(net, dev, tb, data); | 1331 | err = ops->newlink(net, dev, tb, data); |
1271 | else | 1332 | else |
1272 | err = register_netdevice(dev); | 1333 | err = register_netdevice(dev); |
1273 | if (err < 0 && !IS_ERR(dev)) { | 1334 | |
1335 | if (err < 0 && !IS_ERR(dev)) | ||
1274 | free_netdev(dev); | 1336 | free_netdev(dev); |
1337 | if (err < 0) | ||
1275 | goto out; | 1338 | goto out; |
1276 | } | ||
1277 | 1339 | ||
1278 | err = rtnl_configure_link(dev, ifm); | 1340 | err = rtnl_configure_link(dev, ifm); |
1279 | if (err < 0) | 1341 | if (err < 0) |
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c index c7da600750bb..93c91b633a56 100644 --- a/net/ieee802154/af_ieee802154.c +++ b/net/ieee802154/af_ieee802154.c | |||
@@ -151,6 +151,9 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg, | |||
151 | dev_load(sock_net(sk), ifr.ifr_name); | 151 | dev_load(sock_net(sk), ifr.ifr_name); |
152 | dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); | 152 | dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); |
153 | 153 | ||
154 | if (!dev) | ||
155 | return -ENODEV; | ||
156 | |||
154 | if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl) | 157 | if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl) |
155 | ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); | 158 | ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); |
156 | 159 | ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 6e747065c202..80769f1f9fab 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -661,13 +661,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, | |||
661 | #endif | 661 | #endif |
662 | #endif | 662 | #endif |
663 | 663 | ||
664 | #ifdef CONFIG_FDDI | 664 | #if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE) |
665 | case ARPHRD_FDDI: | 665 | case ARPHRD_FDDI: |
666 | arp->ar_hrd = htons(ARPHRD_ETHER); | 666 | arp->ar_hrd = htons(ARPHRD_ETHER); |
667 | arp->ar_pro = htons(ETH_P_IP); | 667 | arp->ar_pro = htons(ETH_P_IP); |
668 | break; | 668 | break; |
669 | #endif | 669 | #endif |
670 | #ifdef CONFIG_TR | 670 | #if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE) |
671 | case ARPHRD_IEEE802_TR: | 671 | case ARPHRD_IEEE802_TR: |
672 | arp->ar_hrd = htons(ARPHRD_IEEE802); | 672 | arp->ar_hrd = htons(ARPHRD_IEEE802); |
673 | arp->ar_pro = htons(ETH_P_IP); | 673 | arp->ar_pro = htons(ETH_P_IP); |
@@ -1051,7 +1051,7 @@ static int arp_req_set(struct net *net, struct arpreq *r, | |||
1051 | return -EINVAL; | 1051 | return -EINVAL; |
1052 | } | 1052 | } |
1053 | switch (dev->type) { | 1053 | switch (dev->type) { |
1054 | #ifdef CONFIG_FDDI | 1054 | #if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE) |
1055 | case ARPHRD_FDDI: | 1055 | case ARPHRD_FDDI: |
1056 | /* | 1056 | /* |
1057 | * According to RFC 1390, FDDI devices should accept ARP | 1057 | * According to RFC 1390, FDDI devices should accept ARP |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 59a838795e3e..c98f115fb0fd 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -209,7 +209,9 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i) | |||
209 | { | 209 | { |
210 | struct node *ret = tnode_get_child(tn, i); | 210 | struct node *ret = tnode_get_child(tn, i); |
211 | 211 | ||
212 | return rcu_dereference(ret); | 212 | return rcu_dereference_check(ret, |
213 | rcu_read_lock_held() || | ||
214 | lockdep_rtnl_is_held()); | ||
213 | } | 215 | } |
214 | 216 | ||
215 | static inline int tnode_child_length(const struct tnode *tn) | 217 | static inline int tnode_child_length(const struct tnode *tn) |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index c65f18e0936e..d1bcc9f21d4f 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -120,7 +120,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
120 | newskb->pkt_type = PACKET_LOOPBACK; | 120 | newskb->pkt_type = PACKET_LOOPBACK; |
121 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 121 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
122 | WARN_ON(!skb_dst(newskb)); | 122 | WARN_ON(!skb_dst(newskb)); |
123 | netif_rx(newskb); | 123 | netif_rx_ni(newskb); |
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | 126 | ||
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 9d4f6d1340a4..ec19a890c9a0 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -754,7 +754,8 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb) | |||
754 | c->next = mfc_unres_queue; | 754 | c->next = mfc_unres_queue; |
755 | mfc_unres_queue = c; | 755 | mfc_unres_queue = c; |
756 | 756 | ||
757 | mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires); | 757 | if (atomic_read(&net->ipv4.cache_resolve_queue_len) == 1) |
758 | mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires); | ||
758 | } | 759 | } |
759 | 760 | ||
760 | /* | 761 | /* |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0f8caf64caa3..296150b2a62f 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2839,7 +2839,6 @@ static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool * __percpu *pool) | |||
2839 | if (p->md5_desc.tfm) | 2839 | if (p->md5_desc.tfm) |
2840 | crypto_free_hash(p->md5_desc.tfm); | 2840 | crypto_free_hash(p->md5_desc.tfm); |
2841 | kfree(p); | 2841 | kfree(p); |
2842 | p = NULL; | ||
2843 | } | 2842 | } |
2844 | } | 2843 | } |
2845 | free_percpu(pool); | 2844 | free_percpu(pool); |
@@ -2937,25 +2936,40 @@ retry: | |||
2937 | 2936 | ||
2938 | EXPORT_SYMBOL(tcp_alloc_md5sig_pool); | 2937 | EXPORT_SYMBOL(tcp_alloc_md5sig_pool); |
2939 | 2938 | ||
2940 | struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu) | 2939 | |
2940 | /** | ||
2941 | * tcp_get_md5sig_pool - get md5sig_pool for this user | ||
2942 | * | ||
2943 | * We use percpu structure, so if we succeed, we exit with preemption | ||
2944 | * and BH disabled, to make sure another thread or softirq handling | ||
2945 | * wont try to get same context. | ||
2946 | */ | ||
2947 | struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) | ||
2941 | { | 2948 | { |
2942 | struct tcp_md5sig_pool * __percpu *p; | 2949 | struct tcp_md5sig_pool * __percpu *p; |
2943 | spin_lock_bh(&tcp_md5sig_pool_lock); | 2950 | |
2951 | local_bh_disable(); | ||
2952 | |||
2953 | spin_lock(&tcp_md5sig_pool_lock); | ||
2944 | p = tcp_md5sig_pool; | 2954 | p = tcp_md5sig_pool; |
2945 | if (p) | 2955 | if (p) |
2946 | tcp_md5sig_users++; | 2956 | tcp_md5sig_users++; |
2947 | spin_unlock_bh(&tcp_md5sig_pool_lock); | 2957 | spin_unlock(&tcp_md5sig_pool_lock); |
2948 | return (p ? *per_cpu_ptr(p, cpu) : NULL); | 2958 | |
2949 | } | 2959 | if (p) |
2960 | return *per_cpu_ptr(p, smp_processor_id()); | ||
2950 | 2961 | ||
2951 | EXPORT_SYMBOL(__tcp_get_md5sig_pool); | 2962 | local_bh_enable(); |
2963 | return NULL; | ||
2964 | } | ||
2965 | EXPORT_SYMBOL(tcp_get_md5sig_pool); | ||
2952 | 2966 | ||
2953 | void __tcp_put_md5sig_pool(void) | 2967 | void tcp_put_md5sig_pool(void) |
2954 | { | 2968 | { |
2969 | local_bh_enable(); | ||
2955 | tcp_free_md5sig_pool(); | 2970 | tcp_free_md5sig_pool(); |
2956 | } | 2971 | } |
2957 | 2972 | EXPORT_SYMBOL(tcp_put_md5sig_pool); | |
2958 | EXPORT_SYMBOL(__tcp_put_md5sig_pool); | ||
2959 | 2973 | ||
2960 | int tcp_md5_hash_header(struct tcp_md5sig_pool *hp, | 2974 | int tcp_md5_hash_header(struct tcp_md5sig_pool *hp, |
2961 | struct tcphdr *th) | 2975 | struct tcphdr *th) |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 954bbfb39dff..c36522a0f113 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -472,8 +472,8 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
472 | if (hslot->count < hslot2->count) | 472 | if (hslot->count < hslot2->count) |
473 | goto begin; | 473 | goto begin; |
474 | 474 | ||
475 | result = udp4_lib_lookup2(net, INADDR_ANY, sport, | 475 | result = udp4_lib_lookup2(net, saddr, sport, |
476 | daddr, hnum, dif, | 476 | INADDR_ANY, hnum, dif, |
477 | hslot2, slot2); | 477 | hslot2, slot2); |
478 | } | 478 | } |
479 | rcu_read_unlock(); | 479 | rcu_read_unlock(); |
@@ -1527,6 +1527,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
1527 | 1527 | ||
1528 | uh = udp_hdr(skb); | 1528 | uh = udp_hdr(skb); |
1529 | ulen = ntohs(uh->len); | 1529 | ulen = ntohs(uh->len); |
1530 | saddr = ip_hdr(skb)->saddr; | ||
1531 | daddr = ip_hdr(skb)->daddr; | ||
1532 | |||
1530 | if (ulen > skb->len) | 1533 | if (ulen > skb->len) |
1531 | goto short_packet; | 1534 | goto short_packet; |
1532 | 1535 | ||
@@ -1540,9 +1543,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
1540 | if (udp4_csum_init(skb, uh, proto)) | 1543 | if (udp4_csum_init(skb, uh, proto)) |
1541 | goto csum_error; | 1544 | goto csum_error; |
1542 | 1545 | ||
1543 | saddr = ip_hdr(skb)->saddr; | ||
1544 | daddr = ip_hdr(skb)->daddr; | ||
1545 | |||
1546 | if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) | 1546 | if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) |
1547 | return __udp4_lib_mcast_deliver(net, skb, uh, | 1547 | return __udp4_lib_mcast_deliver(net, skb, uh, |
1548 | saddr, daddr, udptable); | 1548 | saddr, daddr, udptable); |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3192aa02ba5d..3f9e86b15e0d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -200,7 +200,7 @@ lookup_protocol: | |||
200 | 200 | ||
201 | inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk); | 201 | inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk); |
202 | np->hop_limit = -1; | 202 | np->hop_limit = -1; |
203 | np->mcast_hops = -1; | 203 | np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; |
204 | np->mc_loop = 1; | 204 | np->mc_loop = 1; |
205 | np->pmtudisc = IPV6_PMTUDISC_WANT; | 205 | np->pmtudisc = IPV6_PMTUDISC_WANT; |
206 | np->ipv6only = net->ipv6.sysctl.bindv6only; | 206 | np->ipv6only = net->ipv6.sysctl.bindv6only; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 622dc7939a1b..61573885e451 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -222,6 +222,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, | |||
222 | if (!skb) | 222 | if (!skb) |
223 | return; | 223 | return; |
224 | 224 | ||
225 | skb->protocol = htons(ETH_P_IPV6); | ||
226 | |||
225 | serr = SKB_EXT_ERR(skb); | 227 | serr = SKB_EXT_ERR(skb); |
226 | serr->ee.ee_errno = err; | 228 | serr->ee.ee_errno = err; |
227 | serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6; | 229 | serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6; |
@@ -255,6 +257,8 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info) | |||
255 | if (!skb) | 257 | if (!skb) |
256 | return; | 258 | return; |
257 | 259 | ||
260 | skb->protocol = htons(ETH_P_IPV6); | ||
261 | |||
258 | skb_put(skb, sizeof(struct ipv6hdr)); | 262 | skb_put(skb, sizeof(struct ipv6hdr)); |
259 | skb_reset_network_header(skb); | 263 | skb_reset_network_header(skb); |
260 | iph = ipv6_hdr(skb); | 264 | iph = ipv6_hdr(skb); |
@@ -319,7 +323,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
319 | sin->sin6_flowinfo = 0; | 323 | sin->sin6_flowinfo = 0; |
320 | sin->sin6_port = serr->port; | 324 | sin->sin6_port = serr->port; |
321 | sin->sin6_scope_id = 0; | 325 | sin->sin6_scope_id = 0; |
322 | if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) { | 326 | if (skb->protocol == htons(ETH_P_IPV6)) { |
323 | ipv6_addr_copy(&sin->sin6_addr, | 327 | ipv6_addr_copy(&sin->sin6_addr, |
324 | (struct in6_addr *)(nh + serr->addr_offset)); | 328 | (struct in6_addr *)(nh + serr->addr_offset)); |
325 | if (np->sndflow) | 329 | if (np->sndflow) |
@@ -341,7 +345,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
341 | sin->sin6_family = AF_INET6; | 345 | sin->sin6_family = AF_INET6; |
342 | sin->sin6_flowinfo = 0; | 346 | sin->sin6_flowinfo = 0; |
343 | sin->sin6_scope_id = 0; | 347 | sin->sin6_scope_id = 0; |
344 | if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) { | 348 | if (skb->protocol == htons(ETH_P_IPV6)) { |
345 | ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr); | 349 | ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr); |
346 | if (np->rxopt.all) | 350 | if (np->rxopt.all) |
347 | datagram_recv_ctl(sk, msg, skb); | 351 | datagram_recv_ctl(sk, msg, skb); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 16c4391f952b..75d5ef830097 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -108,7 +108,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | |||
108 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 108 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
109 | WARN_ON(!skb_dst(newskb)); | 109 | WARN_ON(!skb_dst(newskb)); |
110 | 110 | ||
111 | netif_rx(newskb); | 111 | netif_rx_ni(newskb); |
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | 114 | ||
@@ -629,7 +629,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
629 | /* We must not fragment if the socket is set to force MTU discovery | 629 | /* We must not fragment if the socket is set to force MTU discovery |
630 | * or if the skb it not generated by a local socket. | 630 | * or if the skb it not generated by a local socket. |
631 | */ | 631 | */ |
632 | if (!skb->local_df) { | 632 | if (!skb->local_df && skb->len > mtu) { |
633 | skb->dev = skb_dst(skb)->dev; | 633 | skb->dev = skb_dst(skb)->dev; |
634 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 634 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
635 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 635 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c2438e8cb9d0..05ebd7833043 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -815,7 +815,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, | |||
815 | { | 815 | { |
816 | int flags = 0; | 816 | int flags = 0; |
817 | 817 | ||
818 | if (rt6_need_strict(&fl->fl6_dst)) | 818 | if (fl->oif || rt6_need_strict(&fl->fl6_dst)) |
819 | flags |= RT6_LOOKUP_F_IFACE; | 819 | flags |= RT6_LOOKUP_F_IFACE; |
820 | 820 | ||
821 | if (!ipv6_addr_any(&fl->fl6_src)) | 821 | if (!ipv6_addr_any(&fl->fl6_src)) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c92ebe8f80d5..075f540ec197 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1015,7 +1015,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1015 | skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); | 1015 | skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); |
1016 | 1016 | ||
1017 | t1 = (struct tcphdr *) skb_push(buff, tot_len); | 1017 | t1 = (struct tcphdr *) skb_push(buff, tot_len); |
1018 | skb_reset_transport_header(skb); | 1018 | skb_reset_transport_header(buff); |
1019 | 1019 | ||
1020 | /* Swap the send and the receive. */ | 1020 | /* Swap the send and the receive. */ |
1021 | memset(t1, 0, sizeof(*t1)); | 1021 | memset(t1, 0, sizeof(*t1)); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c177aea88c0b..90824852f598 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -259,8 +259,8 @@ static struct sock *__udp6_lib_lookup(struct net *net, | |||
259 | if (hslot->count < hslot2->count) | 259 | if (hslot->count < hslot2->count) |
260 | goto begin; | 260 | goto begin; |
261 | 261 | ||
262 | result = udp6_lib_lookup2(net, &in6addr_any, sport, | 262 | result = udp6_lib_lookup2(net, saddr, sport, |
263 | daddr, hnum, dif, | 263 | &in6addr_any, hnum, dif, |
264 | hslot2, slot2); | 264 | hslot2, slot2); |
265 | } | 265 | } |
266 | rcu_read_unlock(); | 266 | rcu_read_unlock(); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index ae181651c75a..00bf7c962b7e 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -124,7 +124,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
124 | xdst->u.dst.dev = dev; | 124 | xdst->u.dst.dev = dev; |
125 | dev_hold(dev); | 125 | dev_hold(dev); |
126 | 126 | ||
127 | xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev); | 127 | xdst->u.rt6.rt6i_idev = in6_dev_get(dev); |
128 | if (!xdst->u.rt6.rt6i_idev) | 128 | if (!xdst->u.rt6.rt6i_idev) |
129 | return -ENODEV; | 129 | return -ENODEV; |
130 | 130 | ||
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index a432f0ec051c..94e7fca75b85 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c | |||
@@ -31,7 +31,7 @@ static int llc_mac_header_len(unsigned short devtype) | |||
31 | case ARPHRD_ETHER: | 31 | case ARPHRD_ETHER: |
32 | case ARPHRD_LOOPBACK: | 32 | case ARPHRD_LOOPBACK: |
33 | return sizeof(struct ethhdr); | 33 | return sizeof(struct ethhdr); |
34 | #ifdef CONFIG_TR | 34 | #if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE) |
35 | case ARPHRD_IEEE802_TR: | 35 | case ARPHRD_IEEE802_TR: |
36 | return sizeof(struct trh_hdr); | 36 | return sizeof(struct trh_hdr); |
37 | #endif | 37 | #endif |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 96d25348aa59..87782a4bb541 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -184,7 +184,6 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
184 | HT_AGG_STATE_REQ_STOP_BA_MSK)) != | 184 | HT_AGG_STATE_REQ_STOP_BA_MSK)) != |
185 | HT_ADDBA_REQUESTED_MSK) { | 185 | HT_ADDBA_REQUESTED_MSK) { |
186 | spin_unlock_bh(&sta->lock); | 186 | spin_unlock_bh(&sta->lock); |
187 | *state = HT_AGG_STATE_IDLE; | ||
188 | #ifdef CONFIG_MAC80211_HT_DEBUG | 187 | #ifdef CONFIG_MAC80211_HT_DEBUG |
189 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 188 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
190 | "(or no longer) expecting addBA response there", | 189 | "(or no longer) expecting addBA response there", |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 06c33b68d8e5..b887e484ae04 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
225 | switch (sdata->vif.type) { | 225 | switch (sdata->vif.type) { |
226 | case NL80211_IFTYPE_AP: | 226 | case NL80211_IFTYPE_AP: |
227 | sdata->vif.bss_conf.enable_beacon = | 227 | sdata->vif.bss_conf.enable_beacon = |
228 | !!rcu_dereference(sdata->u.ap.beacon); | 228 | !!sdata->u.ap.beacon; |
229 | break; | 229 | break; |
230 | case NL80211_IFTYPE_ADHOC: | 230 | case NL80211_IFTYPE_ADHOC: |
231 | sdata->vif.bss_conf.enable_beacon = | 231 | sdata->vif.bss_conf.enable_beacon = |
232 | !!rcu_dereference(sdata->u.ibss.presp); | 232 | !!sdata->u.ibss.presp; |
233 | break; | 233 | break; |
234 | case NL80211_IFTYPE_MESH_POINT: | 234 | case NL80211_IFTYPE_MESH_POINT: |
235 | sdata->vif.bss_conf.enable_beacon = true; | 235 | sdata->vif.bss_conf.enable_beacon = true; |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 58e3e3a61d99..859ee5f3d941 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -750,9 +750,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
750 | 750 | ||
751 | switch (fc & IEEE80211_FCTL_STYPE) { | 751 | switch (fc & IEEE80211_FCTL_STYPE) { |
752 | case IEEE80211_STYPE_ACTION: | 752 | case IEEE80211_STYPE_ACTION: |
753 | if (skb->len < IEEE80211_MIN_ACTION_SIZE) | ||
754 | return RX_DROP_MONITOR; | ||
755 | /* fall through */ | ||
756 | case IEEE80211_STYPE_PROBE_RESP: | 753 | case IEEE80211_STYPE_PROBE_RESP: |
757 | case IEEE80211_STYPE_BEACON: | 754 | case IEEE80211_STYPE_BEACON: |
758 | skb_queue_tail(&ifmsh->skb_queue, skb); | 755 | skb_queue_tail(&ifmsh->skb_queue, skb); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c8cd169fc10e..875c8dec940a 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -168,6 +168,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
168 | ht_changed = conf_is_ht(&local->hw.conf) != enable_ht || | 168 | ht_changed = conf_is_ht(&local->hw.conf) != enable_ht || |
169 | channel_type != local->hw.conf.channel_type; | 169 | channel_type != local->hw.conf.channel_type; |
170 | 170 | ||
171 | if (local->tmp_channel) | ||
172 | local->tmp_channel_type = channel_type; | ||
171 | local->oper_channel_type = channel_type; | 173 | local->oper_channel_type = channel_type; |
172 | 174 | ||
173 | if (ht_changed) { | 175 | if (ht_changed) { |
@@ -2028,7 +2030,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2028 | continue; | 2030 | continue; |
2029 | 2031 | ||
2030 | if (wk->type != IEEE80211_WORK_DIRECT_PROBE && | 2032 | if (wk->type != IEEE80211_WORK_DIRECT_PROBE && |
2031 | wk->type != IEEE80211_WORK_AUTH) | 2033 | wk->type != IEEE80211_WORK_AUTH && |
2034 | wk->type != IEEE80211_WORK_ASSOC) | ||
2032 | continue; | 2035 | continue; |
2033 | 2036 | ||
2034 | if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) | 2037 | if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f0accf622cd7..04ea07f0e78a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1974,6 +1974,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1974 | goto handled; | 1974 | goto handled; |
1975 | } | 1975 | } |
1976 | break; | 1976 | break; |
1977 | case MESH_PLINK_CATEGORY: | ||
1978 | case MESH_PATH_SEL_CATEGORY: | ||
1979 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
1980 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); | ||
1981 | break; | ||
1977 | } | 1982 | } |
1978 | 1983 | ||
1979 | /* | 1984 | /* |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 56422d894351..fb12cec4d333 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, | |||
93 | struct ieee80211_local *local = sdata->local; | 93 | struct ieee80211_local *local = sdata->local; |
94 | struct sta_info *sta; | 94 | struct sta_info *sta; |
95 | 95 | ||
96 | sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); | 96 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], |
97 | rcu_read_lock_held() || | ||
98 | lockdep_is_held(&local->sta_lock) || | ||
99 | lockdep_is_held(&local->sta_mtx)); | ||
97 | while (sta) { | 100 | while (sta) { |
98 | if (sta->sdata == sdata && | 101 | if (sta->sdata == sdata && |
99 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 102 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
100 | break; | 103 | break; |
101 | sta = rcu_dereference(sta->hnext); | 104 | sta = rcu_dereference_check(sta->hnext, |
105 | rcu_read_lock_held() || | ||
106 | lockdep_is_held(&local->sta_lock) || | ||
107 | lockdep_is_held(&local->sta_mtx)); | ||
102 | } | 108 | } |
103 | return sta; | 109 | return sta; |
104 | } | 110 | } |
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | |||
113 | struct ieee80211_local *local = sdata->local; | 119 | struct ieee80211_local *local = sdata->local; |
114 | struct sta_info *sta; | 120 | struct sta_info *sta; |
115 | 121 | ||
116 | sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); | 122 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], |
123 | rcu_read_lock_held() || | ||
124 | lockdep_is_held(&local->sta_lock) || | ||
125 | lockdep_is_held(&local->sta_mtx)); | ||
117 | while (sta) { | 126 | while (sta) { |
118 | if ((sta->sdata == sdata || | 127 | if ((sta->sdata == sdata || |
119 | sta->sdata->bss == sdata->bss) && | 128 | sta->sdata->bss == sdata->bss) && |
120 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 129 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
121 | break; | 130 | break; |
122 | sta = rcu_dereference(sta->hnext); | 131 | sta = rcu_dereference_check(sta->hnext, |
132 | rcu_read_lock_held() || | ||
133 | lockdep_is_held(&local->sta_lock) || | ||
134 | lockdep_is_held(&local->sta_mtx)); | ||
123 | } | 135 | } |
124 | return sta; | 136 | return sta; |
125 | } | 137 | } |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index cc90363d7e7a..243946d4809d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2169,8 +2169,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, | |||
2169 | case SIOCGIFDSTADDR: | 2169 | case SIOCGIFDSTADDR: |
2170 | case SIOCSIFDSTADDR: | 2170 | case SIOCSIFDSTADDR: |
2171 | case SIOCSIFFLAGS: | 2171 | case SIOCSIFFLAGS: |
2172 | if (!net_eq(sock_net(sk), &init_net)) | ||
2173 | return -ENOIOCTLCMD; | ||
2174 | return inet_dgram_ops.ioctl(sock, cmd, arg); | 2172 | return inet_dgram_ops.ioctl(sock, cmd, arg); |
2175 | #endif | 2173 | #endif |
2176 | 2174 | ||
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index 9ece910ea394..7b155081b4dc 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c | |||
@@ -134,7 +134,7 @@ static int __init rds_rdma_listen_init(void) | |||
134 | ret = PTR_ERR(cm_id); | 134 | ret = PTR_ERR(cm_id); |
135 | printk(KERN_ERR "RDS/RDMA: failed to setup listener, " | 135 | printk(KERN_ERR "RDS/RDMA: failed to setup listener, " |
136 | "rdma_create_id() returned %d\n", ret); | 136 | "rdma_create_id() returned %d\n", ret); |
137 | goto out; | 137 | return ret; |
138 | } | 138 | } |
139 | 139 | ||
140 | sin.sin_family = AF_INET, | 140 | sin.sin_family = AF_INET, |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index df5abbff63e2..99c93ee98ad9 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -1194,8 +1194,10 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
1194 | /* Remove any peer addresses not present in the new association. */ | 1194 | /* Remove any peer addresses not present in the new association. */ |
1195 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { | 1195 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { |
1196 | trans = list_entry(pos, struct sctp_transport, transports); | 1196 | trans = list_entry(pos, struct sctp_transport, transports); |
1197 | if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) | 1197 | if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) { |
1198 | sctp_assoc_del_peer(asoc, &trans->ipaddr); | 1198 | sctp_assoc_rm_peer(asoc, trans); |
1199 | continue; | ||
1200 | } | ||
1199 | 1201 | ||
1200 | if (asoc->state >= SCTP_STATE_ESTABLISHED) | 1202 | if (asoc->state >= SCTP_STATE_ESTABLISHED) |
1201 | sctp_transport_reset(trans); | 1203 | sctp_transport_reset(trans); |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 905fda582b92..7ec09ba03a1c 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -144,6 +144,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
144 | /* Use SCTP specific send buffer space queues. */ | 144 | /* Use SCTP specific send buffer space queues. */ |
145 | ep->sndbuf_policy = sctp_sndbuf_policy; | 145 | ep->sndbuf_policy = sctp_sndbuf_policy; |
146 | 146 | ||
147 | sk->sk_data_ready = sctp_data_ready; | ||
147 | sk->sk_write_space = sctp_write_space; | 148 | sk->sk_write_space = sctp_write_space; |
148 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 149 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
149 | 150 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index 2a570184e5a9..ea2192444ce6 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -440,11 +440,25 @@ void sctp_icmp_proto_unreachable(struct sock *sk, | |||
440 | { | 440 | { |
441 | SCTP_DEBUG_PRINTK("%s\n", __func__); | 441 | SCTP_DEBUG_PRINTK("%s\n", __func__); |
442 | 442 | ||
443 | sctp_do_sm(SCTP_EVENT_T_OTHER, | 443 | if (sock_owned_by_user(sk)) { |
444 | SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), | 444 | if (timer_pending(&t->proto_unreach_timer)) |
445 | asoc->state, asoc->ep, asoc, t, | 445 | return; |
446 | GFP_ATOMIC); | 446 | else { |
447 | if (!mod_timer(&t->proto_unreach_timer, | ||
448 | jiffies + (HZ/20))) | ||
449 | sctp_association_hold(asoc); | ||
450 | } | ||
451 | |||
452 | } else { | ||
453 | if (timer_pending(&t->proto_unreach_timer) && | ||
454 | del_timer(&t->proto_unreach_timer)) | ||
455 | sctp_association_put(asoc); | ||
447 | 456 | ||
457 | sctp_do_sm(SCTP_EVENT_T_OTHER, | ||
458 | SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), | ||
459 | asoc->state, asoc->ep, asoc, t, | ||
460 | GFP_ATOMIC); | ||
461 | } | ||
448 | } | 462 | } |
449 | 463 | ||
450 | /* Common lookup code for icmp/icmpv6 error handler. */ | 464 | /* Common lookup code for icmp/icmpv6 error handler. */ |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 17cb400ecd6a..30c1767186b8 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -108,7 +108,7 @@ static const struct sctp_paramhdr prsctp_param = { | |||
108 | cpu_to_be16(sizeof(struct sctp_paramhdr)), | 108 | cpu_to_be16(sizeof(struct sctp_paramhdr)), |
109 | }; | 109 | }; |
110 | 110 | ||
111 | /* A helper to initialize to initialize an op error inside a | 111 | /* A helper to initialize an op error inside a |
112 | * provided chunk, as most cause codes will be embedded inside an | 112 | * provided chunk, as most cause codes will be embedded inside an |
113 | * abort chunk. | 113 | * abort chunk. |
114 | */ | 114 | */ |
@@ -125,6 +125,29 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, | |||
125 | chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); | 125 | chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); |
126 | } | 126 | } |
127 | 127 | ||
128 | /* A helper to initialize an op error inside a | ||
129 | * provided chunk, as most cause codes will be embedded inside an | ||
130 | * abort chunk. Differs from sctp_init_cause in that it won't oops | ||
131 | * if there isn't enough space in the op error chunk | ||
132 | */ | ||
133 | int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code, | ||
134 | size_t paylen) | ||
135 | { | ||
136 | sctp_errhdr_t err; | ||
137 | __u16 len; | ||
138 | |||
139 | /* Cause code constants are now defined in network order. */ | ||
140 | err.cause = cause_code; | ||
141 | len = sizeof(sctp_errhdr_t) + paylen; | ||
142 | err.length = htons(len); | ||
143 | |||
144 | if (skb_tailroom(chunk->skb) > len) | ||
145 | return -ENOSPC; | ||
146 | chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk, | ||
147 | sizeof(sctp_errhdr_t), | ||
148 | &err); | ||
149 | return 0; | ||
150 | } | ||
128 | /* 3.3.2 Initiation (INIT) (1) | 151 | /* 3.3.2 Initiation (INIT) (1) |
129 | * | 152 | * |
130 | * This chunk is used to initiate a SCTP association between two | 153 | * This chunk is used to initiate a SCTP association between two |
@@ -208,7 +231,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
208 | sp = sctp_sk(asoc->base.sk); | 231 | sp = sctp_sk(asoc->base.sk); |
209 | num_types = sp->pf->supported_addrs(sp, types); | 232 | num_types = sp->pf->supported_addrs(sp, types); |
210 | 233 | ||
211 | chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); | 234 | chunksize = sizeof(init) + addrs_len; |
235 | chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types)); | ||
212 | chunksize += sizeof(ecap_param); | 236 | chunksize += sizeof(ecap_param); |
213 | 237 | ||
214 | if (sctp_prsctp_enable) | 238 | if (sctp_prsctp_enable) |
@@ -238,14 +262,14 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
238 | /* Add HMACS parameter length if any were defined */ | 262 | /* Add HMACS parameter length if any were defined */ |
239 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; | 263 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; |
240 | if (auth_hmacs->length) | 264 | if (auth_hmacs->length) |
241 | chunksize += ntohs(auth_hmacs->length); | 265 | chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); |
242 | else | 266 | else |
243 | auth_hmacs = NULL; | 267 | auth_hmacs = NULL; |
244 | 268 | ||
245 | /* Add CHUNKS parameter length */ | 269 | /* Add CHUNKS parameter length */ |
246 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; | 270 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; |
247 | if (auth_chunks->length) | 271 | if (auth_chunks->length) |
248 | chunksize += ntohs(auth_chunks->length); | 272 | chunksize += WORD_ROUND(ntohs(auth_chunks->length)); |
249 | else | 273 | else |
250 | auth_chunks = NULL; | 274 | auth_chunks = NULL; |
251 | 275 | ||
@@ -255,7 +279,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
255 | 279 | ||
256 | /* If we have any extensions to report, account for that */ | 280 | /* If we have any extensions to report, account for that */ |
257 | if (num_ext) | 281 | if (num_ext) |
258 | chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; | 282 | chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + |
283 | num_ext); | ||
259 | 284 | ||
260 | /* RFC 2960 3.3.2 Initiation (INIT) (1) | 285 | /* RFC 2960 3.3.2 Initiation (INIT) (1) |
261 | * | 286 | * |
@@ -397,13 +422,13 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
397 | 422 | ||
398 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; | 423 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; |
399 | if (auth_hmacs->length) | 424 | if (auth_hmacs->length) |
400 | chunksize += ntohs(auth_hmacs->length); | 425 | chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); |
401 | else | 426 | else |
402 | auth_hmacs = NULL; | 427 | auth_hmacs = NULL; |
403 | 428 | ||
404 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; | 429 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; |
405 | if (auth_chunks->length) | 430 | if (auth_chunks->length) |
406 | chunksize += ntohs(auth_chunks->length); | 431 | chunksize += WORD_ROUND(ntohs(auth_chunks->length)); |
407 | else | 432 | else |
408 | auth_chunks = NULL; | 433 | auth_chunks = NULL; |
409 | 434 | ||
@@ -412,7 +437,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
412 | } | 437 | } |
413 | 438 | ||
414 | if (num_ext) | 439 | if (num_ext) |
415 | chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; | 440 | chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + |
441 | num_ext); | ||
416 | 442 | ||
417 | /* Now allocate and fill out the chunk. */ | 443 | /* Now allocate and fill out the chunk. */ |
418 | retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); | 444 | retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); |
@@ -1129,6 +1155,24 @@ nodata: | |||
1129 | return retval; | 1155 | return retval; |
1130 | } | 1156 | } |
1131 | 1157 | ||
1158 | /* Create an Operation Error chunk of a fixed size, | ||
1159 | * specifically, max(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) | ||
1160 | * This is a helper function to allocate an error chunk for | ||
1161 | * for those invalid parameter codes in which we may not want | ||
1162 | * to report all the errors, if the incomming chunk is large | ||
1163 | */ | ||
1164 | static inline struct sctp_chunk *sctp_make_op_error_fixed( | ||
1165 | const struct sctp_association *asoc, | ||
1166 | const struct sctp_chunk *chunk) | ||
1167 | { | ||
1168 | size_t size = asoc ? asoc->pathmtu : 0; | ||
1169 | |||
1170 | if (!size) | ||
1171 | size = SCTP_DEFAULT_MAXSEGMENT; | ||
1172 | |||
1173 | return sctp_make_op_error_space(asoc, chunk, size); | ||
1174 | } | ||
1175 | |||
1132 | /* Create an Operation Error chunk. */ | 1176 | /* Create an Operation Error chunk. */ |
1133 | struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, | 1177 | struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, |
1134 | const struct sctp_chunk *chunk, | 1178 | const struct sctp_chunk *chunk, |
@@ -1371,6 +1415,18 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data) | |||
1371 | return target; | 1415 | return target; |
1372 | } | 1416 | } |
1373 | 1417 | ||
1418 | /* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient | ||
1419 | * space in the chunk | ||
1420 | */ | ||
1421 | void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, | ||
1422 | int len, const void *data) | ||
1423 | { | ||
1424 | if (skb_tailroom(chunk->skb) > len) | ||
1425 | return sctp_addto_chunk(chunk, len, data); | ||
1426 | else | ||
1427 | return NULL; | ||
1428 | } | ||
1429 | |||
1374 | /* Append bytes from user space to the end of a chunk. Will panic if | 1430 | /* Append bytes from user space to the end of a chunk. Will panic if |
1375 | * chunk is not big enough. | 1431 | * chunk is not big enough. |
1376 | * Returns a kernel err value. | 1432 | * Returns a kernel err value. |
@@ -1974,13 +2030,12 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, | |||
1974 | * returning multiple unknown parameters. | 2030 | * returning multiple unknown parameters. |
1975 | */ | 2031 | */ |
1976 | if (NULL == *errp) | 2032 | if (NULL == *errp) |
1977 | *errp = sctp_make_op_error_space(asoc, chunk, | 2033 | *errp = sctp_make_op_error_fixed(asoc, chunk); |
1978 | ntohs(chunk->chunk_hdr->length)); | ||
1979 | 2034 | ||
1980 | if (*errp) { | 2035 | if (*errp) { |
1981 | sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM, | 2036 | sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM, |
1982 | WORD_ROUND(ntohs(param.p->length))); | 2037 | WORD_ROUND(ntohs(param.p->length))); |
1983 | sctp_addto_chunk(*errp, | 2038 | sctp_addto_chunk_fixed(*errp, |
1984 | WORD_ROUND(ntohs(param.p->length)), | 2039 | WORD_ROUND(ntohs(param.p->length)), |
1985 | param.v); | 2040 | param.v); |
1986 | } else { | 2041 | } else { |
@@ -3315,21 +3370,6 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, | |||
3315 | sctp_chunk_free(asconf); | 3370 | sctp_chunk_free(asconf); |
3316 | asoc->addip_last_asconf = NULL; | 3371 | asoc->addip_last_asconf = NULL; |
3317 | 3372 | ||
3318 | /* Send the next asconf chunk from the addip chunk queue. */ | ||
3319 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
3320 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
3321 | asconf = list_entry(entry, struct sctp_chunk, list); | ||
3322 | |||
3323 | list_del_init(entry); | ||
3324 | |||
3325 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
3326 | sctp_chunk_hold(asconf); | ||
3327 | if (sctp_primitive_ASCONF(asoc, asconf)) | ||
3328 | sctp_chunk_free(asconf); | ||
3329 | else | ||
3330 | asoc->addip_last_asconf = asconf; | ||
3331 | } | ||
3332 | |||
3333 | return retval; | 3373 | return retval; |
3334 | } | 3374 | } |
3335 | 3375 | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 4c5bed9af4e3..eb1f42f45fdd 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -397,6 +397,41 @@ out_unlock: | |||
397 | sctp_transport_put(transport); | 397 | sctp_transport_put(transport); |
398 | } | 398 | } |
399 | 399 | ||
400 | /* Handle the timeout of the ICMP protocol unreachable timer. Trigger | ||
401 | * the correct state machine transition that will close the association. | ||
402 | */ | ||
403 | void sctp_generate_proto_unreach_event(unsigned long data) | ||
404 | { | ||
405 | struct sctp_transport *transport = (struct sctp_transport *) data; | ||
406 | struct sctp_association *asoc = transport->asoc; | ||
407 | |||
408 | sctp_bh_lock_sock(asoc->base.sk); | ||
409 | if (sock_owned_by_user(asoc->base.sk)) { | ||
410 | SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__); | ||
411 | |||
412 | /* Try again later. */ | ||
413 | if (!mod_timer(&transport->proto_unreach_timer, | ||
414 | jiffies + (HZ/20))) | ||
415 | sctp_association_hold(asoc); | ||
416 | goto out_unlock; | ||
417 | } | ||
418 | |||
419 | /* Is this structure just waiting around for us to actually | ||
420 | * get destroyed? | ||
421 | */ | ||
422 | if (asoc->base.dead) | ||
423 | goto out_unlock; | ||
424 | |||
425 | sctp_do_sm(SCTP_EVENT_T_OTHER, | ||
426 | SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), | ||
427 | asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC); | ||
428 | |||
429 | out_unlock: | ||
430 | sctp_bh_unlock_sock(asoc->base.sk); | ||
431 | sctp_association_put(asoc); | ||
432 | } | ||
433 | |||
434 | |||
400 | /* Inject a SACK Timeout event into the state machine. */ | 435 | /* Inject a SACK Timeout event into the state machine. */ |
401 | static void sctp_generate_sack_event(unsigned long data) | 436 | static void sctp_generate_sack_event(unsigned long data) |
402 | { | 437 | { |
@@ -962,6 +997,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc, | |||
962 | } | 997 | } |
963 | 998 | ||
964 | 999 | ||
1000 | /* Sent the next ASCONF packet currently stored in the association. | ||
1001 | * This happens after the ASCONF_ACK was succeffully processed. | ||
1002 | */ | ||
1003 | static void sctp_cmd_send_asconf(struct sctp_association *asoc) | ||
1004 | { | ||
1005 | /* Send the next asconf chunk from the addip chunk | ||
1006 | * queue. | ||
1007 | */ | ||
1008 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
1009 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
1010 | struct sctp_chunk *asconf = list_entry(entry, | ||
1011 | struct sctp_chunk, list); | ||
1012 | list_del_init(entry); | ||
1013 | |||
1014 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
1015 | sctp_chunk_hold(asconf); | ||
1016 | if (sctp_primitive_ASCONF(asoc, asconf)) | ||
1017 | sctp_chunk_free(asconf); | ||
1018 | else | ||
1019 | asoc->addip_last_asconf = asconf; | ||
1020 | } | ||
1021 | } | ||
1022 | |||
965 | 1023 | ||
966 | /* These three macros allow us to pull the debugging code out of the | 1024 | /* These three macros allow us to pull the debugging code out of the |
967 | * main flow of sctp_do_sm() to keep attention focused on the real | 1025 | * main flow of sctp_do_sm() to keep attention focused on the real |
@@ -1617,6 +1675,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1617 | } | 1675 | } |
1618 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); | 1676 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); |
1619 | break; | 1677 | break; |
1678 | case SCTP_CMD_SEND_NEXT_ASCONF: | ||
1679 | sctp_cmd_send_asconf(asoc); | ||
1680 | break; | ||
1620 | default: | 1681 | default: |
1621 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1682 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
1622 | cmd->verb, cmd->obj.ptr); | 1683 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index abf601a1b847..24b2cd555637 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -3676,8 +3676,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
3676 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | 3676 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); |
3677 | 3677 | ||
3678 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, | 3678 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, |
3679 | asconf_ack)) | 3679 | asconf_ack)) { |
3680 | /* Successfully processed ASCONF_ACK. We can | ||
3681 | * release the next asconf if we have one. | ||
3682 | */ | ||
3683 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, | ||
3684 | SCTP_NULL()); | ||
3680 | return SCTP_DISPOSITION_CONSUME; | 3685 | return SCTP_DISPOSITION_CONSUME; |
3686 | } | ||
3681 | 3687 | ||
3682 | abort = sctp_make_abort(asoc, asconf_ack, | 3688 | abort = sctp_make_abort(asoc, asconf_ack, |
3683 | sizeof(sctp_errhdr_t)); | 3689 | sizeof(sctp_errhdr_t)); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 007e8baba089..44a1ab03a3f0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -3719,12 +3719,12 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3719 | sp->hmac = NULL; | 3719 | sp->hmac = NULL; |
3720 | 3720 | ||
3721 | SCTP_DBG_OBJCNT_INC(sock); | 3721 | SCTP_DBG_OBJCNT_INC(sock); |
3722 | percpu_counter_inc(&sctp_sockets_allocated); | ||
3723 | 3722 | ||
3724 | /* Set socket backlog limit. */ | 3723 | /* Set socket backlog limit. */ |
3725 | sk->sk_backlog.limit = sysctl_sctp_rmem[1]; | 3724 | sk->sk_backlog.limit = sysctl_sctp_rmem[1]; |
3726 | 3725 | ||
3727 | local_bh_disable(); | 3726 | local_bh_disable(); |
3727 | percpu_counter_inc(&sctp_sockets_allocated); | ||
3728 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 3728 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
3729 | local_bh_enable(); | 3729 | local_bh_enable(); |
3730 | 3730 | ||
@@ -3741,8 +3741,8 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) | |||
3741 | /* Release our hold on the endpoint. */ | 3741 | /* Release our hold on the endpoint. */ |
3742 | ep = sctp_sk(sk)->ep; | 3742 | ep = sctp_sk(sk)->ep; |
3743 | sctp_endpoint_free(ep); | 3743 | sctp_endpoint_free(ep); |
3744 | percpu_counter_dec(&sctp_sockets_allocated); | ||
3745 | local_bh_disable(); | 3744 | local_bh_disable(); |
3745 | percpu_counter_dec(&sctp_sockets_allocated); | ||
3746 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | 3746 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); |
3747 | local_bh_enable(); | 3747 | local_bh_enable(); |
3748 | } | 3748 | } |
@@ -6189,6 +6189,16 @@ do_nonblock: | |||
6189 | goto out; | 6189 | goto out; |
6190 | } | 6190 | } |
6191 | 6191 | ||
6192 | void sctp_data_ready(struct sock *sk, int len) | ||
6193 | { | ||
6194 | read_lock_bh(&sk->sk_callback_lock); | ||
6195 | if (sk_has_sleeper(sk)) | ||
6196 | wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN | | ||
6197 | POLLRDNORM | POLLRDBAND); | ||
6198 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); | ||
6199 | read_unlock_bh(&sk->sk_callback_lock); | ||
6200 | } | ||
6201 | |||
6192 | /* If socket sndbuf has changed, wake up all per association waiters. */ | 6202 | /* If socket sndbuf has changed, wake up all per association waiters. */ |
6193 | void sctp_write_space(struct sock *sk) | 6203 | void sctp_write_space(struct sock *sk) |
6194 | { | 6204 | { |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index be4d63d5a5cc..165d54e07fcd 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -108,6 +108,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
108 | (unsigned long)peer); | 108 | (unsigned long)peer); |
109 | setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event, | 109 | setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event, |
110 | (unsigned long)peer); | 110 | (unsigned long)peer); |
111 | setup_timer(&peer->proto_unreach_timer, | ||
112 | sctp_generate_proto_unreach_event, (unsigned long)peer); | ||
111 | 113 | ||
112 | /* Initialize the 64-bit random nonce sent with heartbeat. */ | 114 | /* Initialize the 64-bit random nonce sent with heartbeat. */ |
113 | get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); | 115 | get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); |
@@ -171,6 +173,10 @@ void sctp_transport_free(struct sctp_transport *transport) | |||
171 | del_timer(&transport->T3_rtx_timer)) | 173 | del_timer(&transport->T3_rtx_timer)) |
172 | sctp_transport_put(transport); | 174 | sctp_transport_put(transport); |
173 | 175 | ||
176 | /* Delete the ICMP proto unreachable timer if it's active. */ | ||
177 | if (timer_pending(&transport->proto_unreach_timer) && | ||
178 | del_timer(&transport->proto_unreach_timer)) | ||
179 | sctp_association_put(transport->asoc); | ||
174 | 180 | ||
175 | sctp_transport_put(transport); | 181 | sctp_transport_put(transport); |
176 | } | 182 | } |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index f394fc190a49..95afe79dd9d7 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -237,7 +237,7 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan) | |||
237 | list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) { | 237 | list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) { |
238 | 238 | ||
239 | /* Enforce a 60 second garbage collection moratorium */ | 239 | /* Enforce a 60 second garbage collection moratorium */ |
240 | if (time_in_range_open(cred->cr_expire, expired, jiffies) && | 240 | if (time_in_range(cred->cr_expire, expired, jiffies) && |
241 | test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) | 241 | test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) |
242 | continue; | 242 | continue; |
243 | 243 | ||
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index e56f711baccc..36e84e13c6aa 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -83,6 +83,41 @@ struct compat_x25_subscrip_struct { | |||
83 | }; | 83 | }; |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | |||
87 | int x25_parse_address_block(struct sk_buff *skb, | ||
88 | struct x25_address *called_addr, | ||
89 | struct x25_address *calling_addr) | ||
90 | { | ||
91 | unsigned char len; | ||
92 | int needed; | ||
93 | int rc; | ||
94 | |||
95 | if (skb->len < 1) { | ||
96 | /* packet has no address block */ | ||
97 | rc = 0; | ||
98 | goto empty; | ||
99 | } | ||
100 | |||
101 | len = *skb->data; | ||
102 | needed = 1 + (len >> 4) + (len & 0x0f); | ||
103 | |||
104 | if (skb->len < needed) { | ||
105 | /* packet is too short to hold the addresses it claims | ||
106 | to hold */ | ||
107 | rc = -1; | ||
108 | goto empty; | ||
109 | } | ||
110 | |||
111 | return x25_addr_ntoa(skb->data, called_addr, calling_addr); | ||
112 | |||
113 | empty: | ||
114 | *called_addr->x25_addr = 0; | ||
115 | *calling_addr->x25_addr = 0; | ||
116 | |||
117 | return rc; | ||
118 | } | ||
119 | |||
120 | |||
86 | int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, | 121 | int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, |
87 | struct x25_address *calling_addr) | 122 | struct x25_address *calling_addr) |
88 | { | 123 | { |
@@ -367,6 +402,7 @@ static void __x25_destroy_socket(struct sock *sk) | |||
367 | /* | 402 | /* |
368 | * Queue the unaccepted socket for death | 403 | * Queue the unaccepted socket for death |
369 | */ | 404 | */ |
405 | skb->sk->sk_state = TCP_LISTEN; | ||
370 | sock_set_flag(skb->sk, SOCK_DEAD); | 406 | sock_set_flag(skb->sk, SOCK_DEAD); |
371 | x25_start_heartbeat(skb->sk); | 407 | x25_start_heartbeat(skb->sk); |
372 | x25_sk(skb->sk)->state = X25_STATE_0; | 408 | x25_sk(skb->sk)->state = X25_STATE_0; |
@@ -554,7 +590,8 @@ static int x25_create(struct net *net, struct socket *sock, int protocol, | |||
554 | x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE; | 590 | x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE; |
555 | x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE; | 591 | x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE; |
556 | x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; | 592 | x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; |
557 | x25->facilities.throughput = X25_DEFAULT_THROUGHPUT; | 593 | x25->facilities.throughput = 0; /* by default don't negotiate |
594 | throughput */ | ||
558 | x25->facilities.reverse = X25_DEFAULT_REVERSE; | 595 | x25->facilities.reverse = X25_DEFAULT_REVERSE; |
559 | x25->dte_facilities.calling_len = 0; | 596 | x25->dte_facilities.calling_len = 0; |
560 | x25->dte_facilities.called_len = 0; | 597 | x25->dte_facilities.called_len = 0; |
@@ -922,16 +959,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, | |||
922 | /* | 959 | /* |
923 | * Extract the X.25 addresses and convert them to ASCII strings, | 960 | * Extract the X.25 addresses and convert them to ASCII strings, |
924 | * and remove them. | 961 | * and remove them. |
962 | * | ||
963 | * Address block is mandatory in call request packets | ||
925 | */ | 964 | */ |
926 | addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr); | 965 | addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr); |
966 | if (addr_len <= 0) | ||
967 | goto out_clear_request; | ||
927 | skb_pull(skb, addr_len); | 968 | skb_pull(skb, addr_len); |
928 | 969 | ||
929 | /* | 970 | /* |
930 | * Get the length of the facilities, skip past them for the moment | 971 | * Get the length of the facilities, skip past them for the moment |
931 | * get the call user data because this is needed to determine | 972 | * get the call user data because this is needed to determine |
932 | * the correct listener | 973 | * the correct listener |
974 | * | ||
975 | * Facilities length is mandatory in call request packets | ||
933 | */ | 976 | */ |
977 | if (skb->len < 1) | ||
978 | goto out_clear_request; | ||
934 | len = skb->data[0] + 1; | 979 | len = skb->data[0] + 1; |
980 | if (skb->len < len) | ||
981 | goto out_clear_request; | ||
935 | skb_pull(skb,len); | 982 | skb_pull(skb,len); |
936 | 983 | ||
937 | /* | 984 | /* |
@@ -1415,9 +1462,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1415 | if (facilities.winsize_in < 1 || | 1462 | if (facilities.winsize_in < 1 || |
1416 | facilities.winsize_in > 127) | 1463 | facilities.winsize_in > 127) |
1417 | break; | 1464 | break; |
1418 | if (facilities.throughput < 0x03 || | 1465 | if (facilities.throughput) { |
1419 | facilities.throughput > 0xDD) | 1466 | int out = facilities.throughput & 0xf0; |
1420 | break; | 1467 | int in = facilities.throughput & 0x0f; |
1468 | if (!out) | ||
1469 | facilities.throughput |= | ||
1470 | X25_DEFAULT_THROUGHPUT << 4; | ||
1471 | else if (out < 0x30 || out > 0xD0) | ||
1472 | break; | ||
1473 | if (!in) | ||
1474 | facilities.throughput |= | ||
1475 | X25_DEFAULT_THROUGHPUT; | ||
1476 | else if (in < 0x03 || in > 0x0D) | ||
1477 | break; | ||
1478 | } | ||
1421 | if (facilities.reverse && | 1479 | if (facilities.reverse && |
1422 | (facilities.reverse & 0x81) != 0x81) | 1480 | (facilities.reverse & 0x81) != 0x81) |
1423 | break; | 1481 | break; |
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index a21f6646eb3a..771bab00754b 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
@@ -35,7 +35,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) | 35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) |
36 | { | 36 | { |
37 | unsigned char *p = skb->data; | 37 | unsigned char *p = skb->data; |
38 | unsigned int len = *p++; | 38 | unsigned int len; |
39 | 39 | ||
40 | *vc_fac_mask = 0; | 40 | *vc_fac_mask = 0; |
41 | 41 | ||
@@ -50,6 +50,14 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
50 | memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); | 50 | memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); |
51 | memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); | 51 | memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); |
52 | 52 | ||
53 | if (skb->len < 1) | ||
54 | return 0; | ||
55 | |||
56 | len = *p++; | ||
57 | |||
58 | if (len >= skb->len) | ||
59 | return -1; | ||
60 | |||
53 | while (len > 0) { | 61 | while (len > 0) { |
54 | switch (*p & X25_FAC_CLASS_MASK) { | 62 | switch (*p & X25_FAC_CLASS_MASK) { |
55 | case X25_FAC_CLASS_A: | 63 | case X25_FAC_CLASS_A: |
@@ -247,6 +255,8 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, | |||
247 | memcpy(new, ours, sizeof(*new)); | 255 | memcpy(new, ours, sizeof(*new)); |
248 | 256 | ||
249 | len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask); | 257 | len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask); |
258 | if (len < 0) | ||
259 | return len; | ||
250 | 260 | ||
251 | /* | 261 | /* |
252 | * They want reverse charging, we won't accept it. | 262 | * They want reverse charging, we won't accept it. |
@@ -259,9 +269,18 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, | |||
259 | new->reverse = theirs.reverse; | 269 | new->reverse = theirs.reverse; |
260 | 270 | ||
261 | if (theirs.throughput) { | 271 | if (theirs.throughput) { |
262 | if (theirs.throughput < ours->throughput) { | 272 | int theirs_in = theirs.throughput & 0x0f; |
263 | SOCK_DEBUG(sk, "X.25: throughput negotiated down\n"); | 273 | int theirs_out = theirs.throughput & 0xf0; |
264 | new->throughput = theirs.throughput; | 274 | int ours_in = ours->throughput & 0x0f; |
275 | int ours_out = ours->throughput & 0xf0; | ||
276 | if (!ours_in || theirs_in < ours_in) { | ||
277 | SOCK_DEBUG(sk, "X.25: inbound throughput negotiated\n"); | ||
278 | new->throughput = (new->throughput & 0xf0) | theirs_in; | ||
279 | } | ||
280 | if (!ours_out || theirs_out < ours_out) { | ||
281 | SOCK_DEBUG(sk, | ||
282 | "X.25: outbound throughput negotiated\n"); | ||
283 | new->throughput = (new->throughput & 0x0f) | theirs_out; | ||
265 | } | 284 | } |
266 | } | 285 | } |
267 | 286 | ||
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index a31b3b9e5966..372ac226e648 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
@@ -90,6 +90,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more) | |||
90 | static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) | 90 | static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) |
91 | { | 91 | { |
92 | struct x25_address source_addr, dest_addr; | 92 | struct x25_address source_addr, dest_addr; |
93 | int len; | ||
93 | 94 | ||
94 | switch (frametype) { | 95 | switch (frametype) { |
95 | case X25_CALL_ACCEPTED: { | 96 | case X25_CALL_ACCEPTED: { |
@@ -107,11 +108,17 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
107 | * Parse the data in the frame. | 108 | * Parse the data in the frame. |
108 | */ | 109 | */ |
109 | skb_pull(skb, X25_STD_MIN_LEN); | 110 | skb_pull(skb, X25_STD_MIN_LEN); |
110 | skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); | 111 | |
111 | skb_pull(skb, | 112 | len = x25_parse_address_block(skb, &source_addr, |
112 | x25_parse_facilities(skb, &x25->facilities, | 113 | &dest_addr); |
114 | if (len > 0) | ||
115 | skb_pull(skb, len); | ||
116 | |||
117 | len = x25_parse_facilities(skb, &x25->facilities, | ||
113 | &x25->dte_facilities, | 118 | &x25->dte_facilities, |
114 | &x25->vc_facil_mask)); | 119 | &x25->vc_facil_mask); |
120 | if (len > 0) | ||
121 | skb_pull(skb, len); | ||
115 | /* | 122 | /* |
116 | * Copy any Call User Data. | 123 | * Copy any Call User Data. |
117 | */ | 124 | */ |