diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 11 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 159 | ||||
-rw-r--r-- | net/ipv4/arp.c | 6 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 34 | ||||
-rw-r--r-- | net/ipv4/udp.c | 6 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 8 | ||||
-rw-r--r-- | net/llc/llc_sap.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 3 | ||||
-rw-r--r-- | net/sctp/input.c | 22 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 35 | ||||
-rw-r--r-- | net/sctp/transport.c | 6 |
12 files changed, 215 insertions, 80 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index f769098774b7..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; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index fe776c9ddeca..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 | ||
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/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 8fef859db35d..c36522a0f113 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -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/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/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/mlme.c b/net/mac80211/mlme.c index 4aefa6dc3091..875c8dec940a 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2030,7 +2030,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2030 | continue; | 2030 | continue; |
2031 | 2031 | ||
2032 | if (wk->type != IEEE80211_WORK_DIRECT_PROBE && | 2032 | if (wk->type != IEEE80211_WORK_DIRECT_PROBE && |
2033 | wk->type != IEEE80211_WORK_AUTH) | 2033 | wk->type != IEEE80211_WORK_AUTH && |
2034 | wk->type != IEEE80211_WORK_ASSOC) | ||
2034 | continue; | 2035 | continue; |
2035 | 2036 | ||
2036 | 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/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_sideeffect.c b/net/sctp/sm_sideeffect.c index d5ae450b6f02..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 | { |
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 | } |