Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: net: Fix FDDI and TR config checks in ipv4 arp and LLC. IPv4: unresolved multicast route cleanup mac80211: remove association work when processing deauth request ar9170: wait for asynchronous firmware loading ipv4: udp: fix short packet and bad checksum logging phy: Fix initialization in micrel driver. sctp: Fix a race between ICMP protocol unreachable and connect() veth: Dont kfree_skb() after dev_forward_skb() IPv6: fix IPV6_RECVERR handling of locally-generated errors net/gianfar: drop recycled skbs on MTU change iwlwifi: work around passive scan issue
This commit is contained in:
commit
9fc282baa8
20 changed files with 118 additions and 30 deletions
|
@ -1649,6 +1649,7 @@ static void free_skb_resources(struct gfar_private *priv)
|
||||||
sizeof(struct rxbd8) * priv->total_rx_ring_size,
|
sizeof(struct rxbd8) * priv->total_rx_ring_size,
|
||||||
priv->tx_queue[0]->tx_bd_base,
|
priv->tx_queue[0]->tx_bd_base,
|
||||||
priv->tx_queue[0]->tx_bd_dma_base);
|
priv->tx_queue[0]->tx_bd_dma_base);
|
||||||
|
skb_queue_purge(&priv->rx_recycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfar_start(struct net_device *dev)
|
void gfar_start(struct net_device *dev)
|
||||||
|
@ -2088,7 +2089,6 @@ static int gfar_close(struct net_device *dev)
|
||||||
|
|
||||||
disable_napi(priv);
|
disable_napi(priv);
|
||||||
|
|
||||||
skb_queue_purge(&priv->rx_recycle);
|
|
||||||
cancel_work_sync(&priv->reset_task);
|
cancel_work_sync(&priv->reset_task);
|
||||||
stop_gfar(dev);
|
stop_gfar(dev);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ static int kszphy_config_init(struct phy_device *phydev)
|
||||||
|
|
||||||
static struct phy_driver ks8001_driver = {
|
static struct phy_driver ks8001_driver = {
|
||||||
.phy_id = PHY_ID_KS8001,
|
.phy_id = PHY_ID_KS8001,
|
||||||
|
.name = "Micrel KS8001",
|
||||||
.phy_id_mask = 0x00fffff0,
|
.phy_id_mask = 0x00fffff0,
|
||||||
.features = PHY_BASIC_FEATURES,
|
.features = PHY_BASIC_FEATURES,
|
||||||
.flags = PHY_POLL,
|
.flags = PHY_POLL,
|
||||||
|
|
|
@ -187,7 +187,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
rx_drop:
|
rx_drop:
|
||||||
kfree_skb(skb);
|
|
||||||
rcv_stats->rx_dropped++;
|
rcv_stats->rx_dropped++;
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -727,12 +727,16 @@ static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
|
||||||
{
|
{
|
||||||
struct device *parent = aru->udev->dev.parent;
|
struct device *parent = aru->udev->dev.parent;
|
||||||
|
|
||||||
|
complete(&aru->firmware_loading_complete);
|
||||||
|
|
||||||
/* unbind anything failed */
|
/* unbind anything failed */
|
||||||
if (parent)
|
if (parent)
|
||||||
down(&parent->sem);
|
down(&parent->sem);
|
||||||
device_release_driver(&aru->udev->dev);
|
device_release_driver(&aru->udev->dev);
|
||||||
if (parent)
|
if (parent)
|
||||||
up(&parent->sem);
|
up(&parent->sem);
|
||||||
|
|
||||||
|
usb_put_dev(aru->udev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
|
static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
|
||||||
|
@ -761,6 +765,8 @@ static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
|
||||||
if (err)
|
if (err)
|
||||||
goto err_unrx;
|
goto err_unrx;
|
||||||
|
|
||||||
|
complete(&aru->firmware_loading_complete);
|
||||||
|
usb_put_dev(aru->udev);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err_unrx:
|
err_unrx:
|
||||||
|
@ -858,6 +864,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
|
||||||
init_usb_anchor(&aru->tx_pending);
|
init_usb_anchor(&aru->tx_pending);
|
||||||
init_usb_anchor(&aru->tx_submitted);
|
init_usb_anchor(&aru->tx_submitted);
|
||||||
init_completion(&aru->cmd_wait);
|
init_completion(&aru->cmd_wait);
|
||||||
|
init_completion(&aru->firmware_loading_complete);
|
||||||
spin_lock_init(&aru->tx_urb_lock);
|
spin_lock_init(&aru->tx_urb_lock);
|
||||||
|
|
||||||
aru->tx_pending_urbs = 0;
|
aru->tx_pending_urbs = 0;
|
||||||
|
@ -877,6 +884,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
|
||||||
if (err)
|
if (err)
|
||||||
goto err_freehw;
|
goto err_freehw;
|
||||||
|
|
||||||
|
usb_get_dev(aru->udev);
|
||||||
return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
|
return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
|
||||||
&aru->udev->dev, GFP_KERNEL, aru,
|
&aru->udev->dev, GFP_KERNEL, aru,
|
||||||
ar9170_usb_firmware_step2);
|
ar9170_usb_firmware_step2);
|
||||||
|
@ -896,6 +904,9 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
aru->common.state = AR9170_IDLE;
|
aru->common.state = AR9170_IDLE;
|
||||||
|
|
||||||
|
wait_for_completion(&aru->firmware_loading_complete);
|
||||||
|
|
||||||
ar9170_unregister(&aru->common);
|
ar9170_unregister(&aru->common);
|
||||||
ar9170_usb_cancel_urbs(aru);
|
ar9170_usb_cancel_urbs(aru);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ struct ar9170_usb {
|
||||||
unsigned int tx_pending_urbs;
|
unsigned int tx_pending_urbs;
|
||||||
|
|
||||||
struct completion cmd_wait;
|
struct completion cmd_wait;
|
||||||
|
struct completion firmware_loading_complete;
|
||||||
int readlen;
|
int readlen;
|
||||||
u8 *readbuf;
|
u8 *readbuf;
|
||||||
|
|
||||||
|
|
|
@ -2621,7 +2621,9 @@ struct iwl_ssid_ie {
|
||||||
#define PROBE_OPTION_MAX_3945 4
|
#define PROBE_OPTION_MAX_3945 4
|
||||||
#define PROBE_OPTION_MAX 20
|
#define PROBE_OPTION_MAX 20
|
||||||
#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
|
#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
|
||||||
#define IWL_GOOD_CRC_TH cpu_to_le16(1)
|
#define IWL_GOOD_CRC_TH_DISABLED 0
|
||||||
|
#define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1)
|
||||||
|
#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff)
|
||||||
#define IWL_MAX_SCAN_SIZE 1024
|
#define IWL_MAX_SCAN_SIZE 1024
|
||||||
#define IWL_MAX_CMD_SIZE 4096
|
#define IWL_MAX_CMD_SIZE 4096
|
||||||
#define IWL_MAX_PROBE_REQUEST 200
|
#define IWL_MAX_PROBE_REQUEST 200
|
||||||
|
|
|
@ -813,16 +813,29 @@ static void iwl_bg_request_scan(struct work_struct *data)
|
||||||
rate = IWL_RATE_1M_PLCP;
|
rate = IWL_RATE_1M_PLCP;
|
||||||
rate_flags = RATE_MCS_CCK_MSK;
|
rate_flags = RATE_MCS_CCK_MSK;
|
||||||
}
|
}
|
||||||
scan->good_CRC_th = 0;
|
scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
|
||||||
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
|
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
|
||||||
band = IEEE80211_BAND_5GHZ;
|
band = IEEE80211_BAND_5GHZ;
|
||||||
rate = IWL_RATE_6M_PLCP;
|
rate = IWL_RATE_6M_PLCP;
|
||||||
/*
|
/*
|
||||||
* If active scaning is requested but a certain channel
|
* If active scanning is requested but a certain channel is
|
||||||
* is marked passive, we can do active scanning if we
|
* marked passive, we can do active scanning if we detect
|
||||||
* detect transmissions.
|
* transmissions.
|
||||||
|
*
|
||||||
|
* There is an issue with some firmware versions that triggers
|
||||||
|
* a sysassert on a "good CRC threshold" of zero (== disabled),
|
||||||
|
* on a radar channel even though this means that we should NOT
|
||||||
|
* send probes.
|
||||||
|
*
|
||||||
|
* The "good CRC threshold" is the number of frames that we
|
||||||
|
* need to receive during our dwell time on a channel before
|
||||||
|
* sending out probes -- setting this to a huge value will
|
||||||
|
* mean we never reach it, but at the same time work around
|
||||||
|
* the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
|
||||||
|
* here instead of IWL_GOOD_CRC_TH_DISABLED.
|
||||||
*/
|
*/
|
||||||
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
|
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
|
||||||
|
IWL_GOOD_CRC_TH_NEVER;
|
||||||
|
|
||||||
/* Force use of chains B and C (0x6) for scan Rx for 4965
|
/* Force use of chains B and C (0x6) for scan Rx for 4965
|
||||||
* Avoid A (0x1) because of its off-channel reception on A-band.
|
* Avoid A (0x1) because of its off-channel reception on A-band.
|
||||||
|
|
|
@ -2967,7 +2967,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||||
* is marked passive, we can do active scanning if we
|
* is marked passive, we can do active scanning if we
|
||||||
* detect transmissions.
|
* detect transmissions.
|
||||||
*/
|
*/
|
||||||
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
|
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
|
||||||
|
IWL_GOOD_CRC_TH_DISABLED;
|
||||||
band = IEEE80211_BAND_5GHZ;
|
band = IEEE80211_BAND_5GHZ;
|
||||||
} else {
|
} else {
|
||||||
IWL_WARN(priv, "Invalid scan band count\n");
|
IWL_WARN(priv, "Invalid scan band count\n");
|
||||||
|
|
|
@ -279,6 +279,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
|
||||||
/* 2nd level prototypes */
|
/* 2nd level prototypes */
|
||||||
void sctp_generate_t3_rtx_event(unsigned long peer);
|
void sctp_generate_t3_rtx_event(unsigned long peer);
|
||||||
void sctp_generate_heartbeat_event(unsigned long peer);
|
void sctp_generate_heartbeat_event(unsigned long peer);
|
||||||
|
void sctp_generate_proto_unreach_event(unsigned long peer);
|
||||||
|
|
||||||
void sctp_ootb_pkt_free(struct sctp_packet *);
|
void sctp_ootb_pkt_free(struct sctp_packet *);
|
||||||
|
|
||||||
|
|
|
@ -1010,6 +1010,9 @@ struct sctp_transport {
|
||||||
/* Heartbeat timer is per destination. */
|
/* Heartbeat timer is per destination. */
|
||||||
struct timer_list hb_timer;
|
struct timer_list hb_timer;
|
||||||
|
|
||||||
|
/* Timer to handle ICMP proto unreachable envets */
|
||||||
|
struct timer_list proto_unreach_timer;
|
||||||
|
|
||||||
/* Since we're using per-destination retransmission timers
|
/* Since we're using per-destination retransmission timers
|
||||||
* (see above), we're also using per-destination "transmitted"
|
* (see above), we're also using per-destination "transmitted"
|
||||||
* queues. This probably ought to be a private struct
|
* queues. This probably ought to be a private struct
|
||||||
|
|
|
@ -1451,7 +1451,7 @@ static inline void net_timestamp(struct sk_buff *skb)
|
||||||
*
|
*
|
||||||
* return values:
|
* return values:
|
||||||
* NET_RX_SUCCESS (no congestion)
|
* NET_RX_SUCCESS (no congestion)
|
||||||
* NET_RX_DROP (packet was dropped)
|
* NET_RX_DROP (packet was dropped, but freed)
|
||||||
*
|
*
|
||||||
* dev_forward_skb can be used for injecting an skb from the
|
* dev_forward_skb can be used for injecting an skb from the
|
||||||
* start_xmit function of one device into the receive queue
|
* 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)
|
||||||
{
|
{
|
||||||
skb_orphan(skb);
|
skb_orphan(skb);
|
||||||
|
|
||||||
if (!(dev->flags & IFF_UP))
|
if (!(dev->flags & IFF_UP) ||
|
||||||
|
(skb->len > (dev->mtu + dev->hard_header_len))) {
|
||||||
|
kfree_skb(skb);
|
||||||
return NET_RX_DROP;
|
return NET_RX_DROP;
|
||||||
|
}
|
||||||
if (skb->len > (dev->mtu + dev->hard_header_len))
|
|
||||||
return NET_RX_DROP;
|
|
||||||
|
|
||||||
skb_set_dev(skb, dev);
|
skb_set_dev(skb, dev);
|
||||||
skb->tstamp.tv64 = 0;
|
skb->tstamp.tv64 = 0;
|
||||||
skb->pkt_type = PACKET_HOST;
|
skb->pkt_type = PACKET_HOST;
|
||||||
|
|
|
@ -661,13 +661,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_FDDI
|
#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
|
||||||
case ARPHRD_FDDI:
|
case ARPHRD_FDDI:
|
||||||
arp->ar_hrd = htons(ARPHRD_ETHER);
|
arp->ar_hrd = htons(ARPHRD_ETHER);
|
||||||
arp->ar_pro = htons(ETH_P_IP);
|
arp->ar_pro = htons(ETH_P_IP);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_TR
|
#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
|
||||||
case ARPHRD_IEEE802_TR:
|
case ARPHRD_IEEE802_TR:
|
||||||
arp->ar_hrd = htons(ARPHRD_IEEE802);
|
arp->ar_hrd = htons(ARPHRD_IEEE802);
|
||||||
arp->ar_pro = htons(ETH_P_IP);
|
arp->ar_pro = htons(ETH_P_IP);
|
||||||
|
@ -1051,7 +1051,7 @@ static int arp_req_set(struct net *net, struct arpreq *r,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
switch (dev->type) {
|
switch (dev->type) {
|
||||||
#ifdef CONFIG_FDDI
|
#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
|
||||||
case ARPHRD_FDDI:
|
case ARPHRD_FDDI:
|
||||||
/*
|
/*
|
||||||
* According to RFC 1390, FDDI devices should accept ARP
|
* According to RFC 1390, FDDI devices should accept ARP
|
||||||
|
|
|
@ -754,7 +754,8 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb)
|
||||||
c->next = mfc_unres_queue;
|
c->next = mfc_unres_queue;
|
||||||
mfc_unres_queue = c;
|
mfc_unres_queue = c;
|
||||||
|
|
||||||
mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires);
|
if (atomic_read(&net->ipv4.cache_resolve_queue_len) == 1)
|
||||||
|
mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1527,6 +1527,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
|
||||||
|
|
||||||
uh = udp_hdr(skb);
|
uh = udp_hdr(skb);
|
||||||
ulen = ntohs(uh->len);
|
ulen = ntohs(uh->len);
|
||||||
|
saddr = ip_hdr(skb)->saddr;
|
||||||
|
daddr = ip_hdr(skb)->daddr;
|
||||||
|
|
||||||
if (ulen > skb->len)
|
if (ulen > skb->len)
|
||||||
goto short_packet;
|
goto short_packet;
|
||||||
|
|
||||||
|
@ -1540,9 +1543,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
|
||||||
if (udp4_csum_init(skb, uh, proto))
|
if (udp4_csum_init(skb, uh, proto))
|
||||||
goto csum_error;
|
goto csum_error;
|
||||||
|
|
||||||
saddr = ip_hdr(skb)->saddr;
|
|
||||||
daddr = ip_hdr(skb)->daddr;
|
|
||||||
|
|
||||||
if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
|
if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
|
||||||
return __udp4_lib_mcast_deliver(net, skb, uh,
|
return __udp4_lib_mcast_deliver(net, skb, uh,
|
||||||
saddr, daddr, udptable);
|
saddr, daddr, udptable);
|
||||||
|
|
|
@ -222,6 +222,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
skb->protocol = htons(ETH_P_IPV6);
|
||||||
|
|
||||||
serr = SKB_EXT_ERR(skb);
|
serr = SKB_EXT_ERR(skb);
|
||||||
serr->ee.ee_errno = err;
|
serr->ee.ee_errno = err;
|
||||||
serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6;
|
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)
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
skb->protocol = htons(ETH_P_IPV6);
|
||||||
|
|
||||||
skb_put(skb, sizeof(struct ipv6hdr));
|
skb_put(skb, sizeof(struct ipv6hdr));
|
||||||
skb_reset_network_header(skb);
|
skb_reset_network_header(skb);
|
||||||
iph = ipv6_hdr(skb);
|
iph = ipv6_hdr(skb);
|
||||||
|
@ -319,7 +323,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
|
||||||
sin->sin6_flowinfo = 0;
|
sin->sin6_flowinfo = 0;
|
||||||
sin->sin6_port = serr->port;
|
sin->sin6_port = serr->port;
|
||||||
sin->sin6_scope_id = 0;
|
sin->sin6_scope_id = 0;
|
||||||
if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
|
if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||||
ipv6_addr_copy(&sin->sin6_addr,
|
ipv6_addr_copy(&sin->sin6_addr,
|
||||||
(struct in6_addr *)(nh + serr->addr_offset));
|
(struct in6_addr *)(nh + serr->addr_offset));
|
||||||
if (np->sndflow)
|
if (np->sndflow)
|
||||||
|
@ -341,7 +345,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
|
||||||
sin->sin6_family = AF_INET6;
|
sin->sin6_family = AF_INET6;
|
||||||
sin->sin6_flowinfo = 0;
|
sin->sin6_flowinfo = 0;
|
||||||
sin->sin6_scope_id = 0;
|
sin->sin6_scope_id = 0;
|
||||||
if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
|
if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||||
ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr);
|
ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr);
|
||||||
if (np->rxopt.all)
|
if (np->rxopt.all)
|
||||||
datagram_recv_ctl(sk, msg, skb);
|
datagram_recv_ctl(sk, msg, skb);
|
||||||
|
|
|
@ -31,7 +31,7 @@ static int llc_mac_header_len(unsigned short devtype)
|
||||||
case ARPHRD_ETHER:
|
case ARPHRD_ETHER:
|
||||||
case ARPHRD_LOOPBACK:
|
case ARPHRD_LOOPBACK:
|
||||||
return sizeof(struct ethhdr);
|
return sizeof(struct ethhdr);
|
||||||
#ifdef CONFIG_TR
|
#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
|
||||||
case ARPHRD_IEEE802_TR:
|
case ARPHRD_IEEE802_TR:
|
||||||
return sizeof(struct trh_hdr);
|
return sizeof(struct trh_hdr);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2030,7 +2030,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
|
if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
|
||||||
wk->type != IEEE80211_WORK_AUTH)
|
wk->type != IEEE80211_WORK_AUTH &&
|
||||||
|
wk->type != IEEE80211_WORK_ASSOC)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
|
if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
|
||||||
|
|
|
@ -440,11 +440,25 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
|
||||||
{
|
{
|
||||||
SCTP_DEBUG_PRINTK("%s\n", __func__);
|
SCTP_DEBUG_PRINTK("%s\n", __func__);
|
||||||
|
|
||||||
sctp_do_sm(SCTP_EVENT_T_OTHER,
|
if (sock_owned_by_user(sk)) {
|
||||||
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
|
if (timer_pending(&t->proto_unreach_timer))
|
||||||
asoc->state, asoc->ep, asoc, t,
|
return;
|
||||||
GFP_ATOMIC);
|
else {
|
||||||
|
if (!mod_timer(&t->proto_unreach_timer,
|
||||||
|
jiffies + (HZ/20)))
|
||||||
|
sctp_association_hold(asoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (timer_pending(&t->proto_unreach_timer) &&
|
||||||
|
del_timer(&t->proto_unreach_timer))
|
||||||
|
sctp_association_put(asoc);
|
||||||
|
|
||||||
|
sctp_do_sm(SCTP_EVENT_T_OTHER,
|
||||||
|
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
|
||||||
|
asoc->state, asoc->ep, asoc, t,
|
||||||
|
GFP_ATOMIC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Common lookup code for icmp/icmpv6 error handler. */
|
/* Common lookup code for icmp/icmpv6 error handler. */
|
||||||
|
|
|
@ -397,6 +397,41 @@ void sctp_generate_heartbeat_event(unsigned long data)
|
||||||
sctp_transport_put(transport);
|
sctp_transport_put(transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle the timeout of the ICMP protocol unreachable timer. Trigger
|
||||||
|
* the correct state machine transition that will close the association.
|
||||||
|
*/
|
||||||
|
void sctp_generate_proto_unreach_event(unsigned long data)
|
||||||
|
{
|
||||||
|
struct sctp_transport *transport = (struct sctp_transport *) data;
|
||||||
|
struct sctp_association *asoc = transport->asoc;
|
||||||
|
|
||||||
|
sctp_bh_lock_sock(asoc->base.sk);
|
||||||
|
if (sock_owned_by_user(asoc->base.sk)) {
|
||||||
|
SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);
|
||||||
|
|
||||||
|
/* Try again later. */
|
||||||
|
if (!mod_timer(&transport->proto_unreach_timer,
|
||||||
|
jiffies + (HZ/20)))
|
||||||
|
sctp_association_hold(asoc);
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is this structure just waiting around for us to actually
|
||||||
|
* get destroyed?
|
||||||
|
*/
|
||||||
|
if (asoc->base.dead)
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
|
sctp_do_sm(SCTP_EVENT_T_OTHER,
|
||||||
|
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
|
||||||
|
asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
sctp_bh_unlock_sock(asoc->base.sk);
|
||||||
|
sctp_association_put(asoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Inject a SACK Timeout event into the state machine. */
|
/* Inject a SACK Timeout event into the state machine. */
|
||||||
static void sctp_generate_sack_event(unsigned long data)
|
static void sctp_generate_sack_event(unsigned long data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -108,6 +108,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
|
||||||
(unsigned long)peer);
|
(unsigned long)peer);
|
||||||
setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
|
setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
|
||||||
(unsigned long)peer);
|
(unsigned long)peer);
|
||||||
|
setup_timer(&peer->proto_unreach_timer,
|
||||||
|
sctp_generate_proto_unreach_event, (unsigned long)peer);
|
||||||
|
|
||||||
/* Initialize the 64-bit random nonce sent with heartbeat. */
|
/* Initialize the 64-bit random nonce sent with heartbeat. */
|
||||||
get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
|
get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
|
||||||
|
|
Loading…
Reference in a new issue