[kernel] r6944 - in dists/trunk/linux-2.6/debian: . patches/series

maximilian attems maks-guest at costa.debian.org
Tue Jul 4 07:47:14 UTC 2006


Author: maks-guest
Date: Tue Jul  4 07:47:09 2006
New Revision: 6944

Added:
   dists/trunk/linux-2.6/debian/patches/2.6.17.2
   dists/trunk/linux-2.6/debian/patches/2.6.17.3
   dists/trunk/linux-2.6/debian/patches/series/3
Modified:
   dists/trunk/linux-2.6/debian/changelog

Log:
add 2.6.17.2, 2.6.17.3 aka sctp is fun


Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	(original)
+++ dists/trunk/linux-2.6/debian/changelog	Tue Jul  4 07:47:09 2006
@@ -1,3 +1,37 @@
+linux-2.6 (2.6.17-3) UNRELEASED; urgency=low
+
+  * Add stable release 2.6.17.2:
+    - ide-io: increase timeout value to allow for slave wakeup
+    - NTFS: Critical bug fix (affects MIPS and possibly others)
+    - Link error when futexes are disabled on 64bit architectures
+    - SCTP: Reset rtt_in_progress for the chunk when processing its sack.
+    - SPARC32: Fix iommu_flush_iotlb end address
+    - ETHTOOL: Fix UFO typo
+    - UML: fix uptime
+    - x86: compile fix for asm-i386/alternatives.h
+    - bcm43xx: init fix for possible Machine Check
+    - SCTP: Fix persistent slowdown in sctp when a gap ack consumes rx buffer.
+    - kbuild: bugfix with initramfs
+    - Input: return correct size when reading modalias attribute
+    - ohci1394: Fix broken suspend/resume in ohci1394
+    - idr: fix race in idr code
+    - USB: Whiteheat: fix firmware spurious errors
+    - libata: minor patch for ATA_DFLAG_PIO
+    - SCTP: Send only 1 window update SACK per message.
+    - PFKEYV2: Fix inconsistent typing in struct sadb_x_kmprivate.
+    - SCTP: Limit association max_retrans setting in setsockopt.
+    - SCTP: Reject sctp packets with broadcast addresses.
+    - IPV6: Sum real space for RTAs.
+    - IPV6 ADDRCONF: Fix default source address selection without
+      CONFIG_IPV6_PRIVACY
+    - IPV6: Fix source address selection.
+  * Add stable release 2.6.17.3:
+    - NETFILTER: SCTP conntrack: fix crash triggered by packet without chunks
+    [CVE-2006-2934]
+  * Deapply merged sparc32-iotlb.patch.
+
+ -- maximilian attems <maks at sternwelten.at>  Tue,  4 Jul 2006 09:28:29 +0200
+
 linux-2.6 (2.6.17-2) unstable; urgency=low
 
   [ Jurij Smakov ]

Added: dists/trunk/linux-2.6/debian/patches/2.6.17.2
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/2.6.17.2	Tue Jul  4 07:47:09 2006
@@ -0,0 +1,661 @@
+diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
+index 77840c8..7215849 100644
+--- a/arch/sparc/mm/iommu.c
++++ b/arch/sparc/mm/iommu.c
+@@ -144,8 +144,9 @@ static void iommu_flush_iotlb(iopte_t *i
+ 	unsigned long start;
+ 	unsigned long end;
+ 
+-	start = (unsigned long)iopte & PAGE_MASK;
++	start = (unsigned long)iopte;
+ 	end = PAGE_ALIGN(start + niopte*sizeof(iopte_t));
++	start &= PAGE_MASK;
+ 	if (viking_mxcc_present) {
+ 		while(start < end) {
+ 			viking_mxcc_flush_page(start);
+diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
+index 86f51d0..87cdbc5 100644
+--- a/arch/um/kernel/time_kern.c
++++ b/arch/um/kernel/time_kern.c
+@@ -87,7 +87,7 @@ #endif
+ 
+ void time_init_kern(void)
+ {
+-	unsigned long long nsecs;
++	long long nsecs;
+ 
+ 	nsecs = os_nsecs();
+ 	set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
+diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
+index c01615d..5748554 100644
+--- a/drivers/ide/ide-io.c
++++ b/drivers/ide/ide-io.c
+@@ -932,7 +932,7 @@ #endif
+ 			printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
+ 		SELECT_DRIVE(drive);
+ 		HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]);
+-		rc = ide_wait_not_busy(HWIF(drive), 10000);
++		rc = ide_wait_not_busy(HWIF(drive), 100000);
+ 		if (rc)
+ 			printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
+ 	}
+diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
+index 11f1377..8f1292c 100644
+--- a/drivers/ieee1394/ohci1394.c
++++ b/drivers/ieee1394/ohci1394.c
+@@ -3539,6 +3539,7 @@ #ifdef CONFIG_PPC_PMAC
+ 	}
+ #endif /* CONFIG_PPC_PMAC */
+ 
++	pci_restore_state(pdev);
+ 	pci_enable_device(pdev);
+ 
+ 	return 0;
+@@ -3558,6 +3559,8 @@ #ifdef CONFIG_PPC_PMAC
+ 	}
+ #endif
+ 
++	pci_save_state(pdev);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/input/input.c b/drivers/input/input.c
+index 3038c26..b149c94 100644
+--- a/drivers/input/input.c
++++ b/drivers/input/input.c
+@@ -629,7 +629,7 @@ static ssize_t input_dev_show_modalias(s
+ 
+ 	len = input_print_modalias(buf, PAGE_SIZE, id, 1);
+ 
+-	return max_t(int, len, PAGE_SIZE);
++	return min_t(int, len, PAGE_SIZE);
+ }
+ static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
+ 
+diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+index 7ed18ca..513fc75 100644
+--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
++++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+@@ -1870,6 +1870,15 @@ static irqreturn_t bcm43xx_interrupt_han
+ 
+ 	spin_lock(&bcm->_lock);
+ 
++	/* Only accept IRQs, if we are initialized properly.
++	 * This avoids an RX race while initializing.
++	 * We should probably not enable IRQs before we are initialized
++	 * completely, but some careful work is needed to fix this. I think it
++	 * is best to stay with this cheap workaround for now... .
++	 */
++	if (unlikely(!bcm->initialized))
++		goto out;
++
+ 	reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
+ 	if (reason == 0xffffffff) {
+ 		/* irq not for us (shared irq) */
+@@ -1891,20 +1900,11 @@ static irqreturn_t bcm43xx_interrupt_han
+ 
+ 	bcm43xx_interrupt_ack(bcm, reason);
+ 
+-	/* Only accept IRQs, if we are initialized properly.
+-	 * This avoids an RX race while initializing.
+-	 * We should probably not enable IRQs before we are initialized
+-	 * completely, but some careful work is needed to fix this. I think it
+-	 * is best to stay with this cheap workaround for now... .
+-	 */
+-	if (likely(bcm->initialized)) {
+-		/* disable all IRQs. They are enabled again in the bottom half. */
+-		bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
+-		/* save the reason code and call our bottom half. */
+-		bcm->irq_reason = reason;
+-		tasklet_schedule(&bcm->isr_tasklet);
+-	}
+-
++	/* disable all IRQs. They are enabled again in the bottom half. */
++	bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
++	/* save the reason code and call our bottom half. */
++	bcm->irq_reason = reason;
++	tasklet_schedule(&bcm->isr_tasklet);
+ out:
+ 	mmiowb();
+ 	spin_unlock(&bcm->_lock);
+diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
+index f63c387..6c8452e 100644
+--- a/drivers/parport/Kconfig
++++ b/drivers/parport/Kconfig
+@@ -48,7 +48,7 @@ config PARPORT_PC
+ 
+ config PARPORT_SERIAL
+ 	tristate "Multi-IO cards (parallel and serial)"
+-	depends on SERIAL_8250 && PARPORT_PC && PCI
++	depends on SERIAL_8250_PCI && PARPORT_PC && PCI
+ 	help
+ 	  This adds support for multi-IO PCI cards that have parallel and
+ 	  serial ports.  You should say Y or M here.  If you say M, the module
+diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
+index b046ffa..6cd197d 100644
+--- a/drivers/scsi/libata-core.c
++++ b/drivers/scsi/libata-core.c
+@@ -1229,7 +1229,7 @@ static int ata_dev_configure(struct ata_
+ 		       id[84], id[85], id[86], id[87], id[88]);
+ 
+ 	/* initialize to-be-configured parameters */
+-	dev->flags = 0;
++	dev->flags &= ~ATA_DFLAG_CFG_MASK;
+ 	dev->max_sectors = 0;
+ 	dev->cdb_len = 0;
+ 	dev->n_sectors = 0;
+diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
+index f806553..3ced09c 100644
+--- a/drivers/usb/serial/whiteheat.c
++++ b/drivers/usb/serial/whiteheat.c
+@@ -388,7 +388,7 @@ static int whiteheat_attach (struct usb_
+ 	if (ret) {
+ 		err("%s: Couldn't send command [%d]", serial->type->description, ret);
+ 		goto no_firmware;
+-	} else if (alen != sizeof(command)) {
++	} else if (alen != 2) {
+ 		err("%s: Send command incomplete [%d]", serial->type->description, alen);
+ 		goto no_firmware;
+ 	}
+@@ -400,7 +400,7 @@ static int whiteheat_attach (struct usb_
+ 	if (ret) {
+ 		err("%s: Couldn't get results [%d]", serial->type->description, ret);
+ 		goto no_firmware;
+-	} else if (alen != sizeof(result)) {
++	} else if (alen != sizeof(*hw_info) + 1) {
+ 		err("%s: Get results incomplete [%d]", serial->type->description, alen);
+ 		goto no_firmware;
+ 	} else if (result[0] != command[0]) {
+diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
+index c63a83e..36e1e13 100644
+--- a/fs/ntfs/file.c
++++ b/fs/ntfs/file.c
+@@ -1484,14 +1484,15 @@ static inline void ntfs_flush_dcache_pag
+ 		unsigned nr_pages)
+ {
+ 	BUG_ON(!nr_pages);
++	/*
++	 * Warning: Do not do the decrement at the same time as the call to
++	 * flush_dcache_page() because it is a NULL macro on i386 and hence the
++	 * decrement never happens so the loop never terminates.
++	 */
+ 	do {
+-		/*
+-		 * Warning: Do not do the decrement at the same time as the
+-		 * call because flush_dcache_page() is a NULL macro on i386
+-		 * and hence the decrement never happens.
+-		 */
++		--nr_pages;
+ 		flush_dcache_page(pages[nr_pages]);
+-	} while (--nr_pages > 0);
++	} while (nr_pages > 0);
+ }
+ 
+ /**
+diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h
+index e201dec..d79e9ee 100644
+--- a/include/asm-i386/alternative.h
++++ b/include/asm-i386/alternative.h
+@@ -3,6 +3,8 @@ #define _I386_ALTERNATIVE_H
+ 
+ #ifdef __KERNEL__
+ 
++#include <asm/types.h>
++
+ struct alt_instr {
+ 	u8 *instr; 		/* original instruction */
+ 	u8 *replacement;
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index b80d2e7..05d3fb3 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -120,9 +120,12 @@ enum {
+ 	ATA_SHT_USE_CLUSTERING	= 1,
+ 
+ 	/* struct ata_device stuff */
+-	ATA_DFLAG_LBA48		= (1 << 0), /* device supports LBA48 */
+-	ATA_DFLAG_PIO		= (1 << 1), /* device currently in PIO mode */
+-	ATA_DFLAG_LBA		= (1 << 2), /* device supports LBA */
++	ATA_DFLAG_LBA		= (1 << 0), /* device supports LBA */
++	ATA_DFLAG_LBA48		= (1 << 1), /* device supports LBA48 */
++
++	ATA_DFLAG_CFG_MASK	= (1 << 8) - 1,
++
++	ATA_DFLAG_PIO		= (1 << 8), /* device currently in PIO mode */
+ 
+ 	ATA_DEV_UNKNOWN		= 0,	/* unknown device */
+ 	ATA_DEV_ATA		= 1,	/* ATA device */
+diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
+index bac0fb3..d5dd471 100644
+--- a/include/linux/pfkeyv2.h
++++ b/include/linux/pfkeyv2.h
+@@ -159,7 +159,7 @@ struct sadb_spirange {
+ struct sadb_x_kmprivate {
+ 	uint16_t	sadb_x_kmprivate_len;
+ 	uint16_t	sadb_x_kmprivate_exttype;
+-	u_int32_t	sadb_x_kmprivate_reserved;
++	uint32_t	sadb_x_kmprivate_reserved;
+ } __attribute__((packed));
+ /* sizeof(struct sadb_x_kmprivate) == 8 */
+ 
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index 7f4fea1..5f69158 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -555,7 +555,8 @@ struct sctp_af {
+ 	int		(*to_addr_param) (const union sctp_addr *,
+ 					  union sctp_addr_param *); 
+ 	int		(*addr_valid)	(union sctp_addr *,
+-					 struct sctp_sock *);
++					 struct sctp_sock *,
++					 const struct sk_buff *);
+ 	sctp_scope_t	(*scope) (union sctp_addr *);
+ 	void		(*inaddr_any)	(union sctp_addr *, unsigned short);
+ 	int		(*is_any)	(const union sctp_addr *);
+diff --git a/kernel/exit.c b/kernel/exit.c
+index e06d0c1..ccf791b 100644
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -899,7 +899,7 @@ fastcall NORET_TYPE void do_exit(long co
+ 	}
+ 	if (unlikely(tsk->robust_list))
+ 		exit_robust_list(tsk);
+-#ifdef CONFIG_COMPAT
++#if defined(CONFIG_FUTEX) && defined(CONFIG_COMPAT)
+ 	if (unlikely(tsk->compat_robust_list))
+ 		compat_exit_robust_list(tsk);
+ #endif
+diff --git a/lib/idr.c b/lib/idr.c
+index d226259..de19030 100644
+--- a/lib/idr.c
++++ b/lib/idr.c
+@@ -48,15 +48,21 @@ static struct idr_layer *alloc_layer(str
+ 	return(p);
+ }
+ 
++/* only called when idp->lock is held */
++static void __free_layer(struct idr *idp, struct idr_layer *p)
++{
++	p->ary[0] = idp->id_free;
++	idp->id_free = p;
++	idp->id_free_cnt++;
++}
++
+ static void free_layer(struct idr *idp, struct idr_layer *p)
+ {
+ 	/*
+ 	 * Depends on the return element being zeroed.
+ 	 */
+ 	spin_lock(&idp->lock);
+-	p->ary[0] = idp->id_free;
+-	idp->id_free = p;
+-	idp->id_free_cnt++;
++	__free_layer(idp, p);
+ 	spin_unlock(&idp->lock);
+ }
+ 
+@@ -184,12 +190,14 @@ build_up:
+ 			 * The allocation failed.  If we built part of
+ 			 * the structure tear it down.
+ 			 */
++			spin_lock(&idp->lock);
+ 			for (new = p; p && p != idp->top; new = p) {
+ 				p = p->ary[0];
+ 				new->ary[0] = NULL;
+ 				new->bitmap = new->count = 0;
+-				free_layer(idp, new);
++				__free_layer(idp, new);
+ 			}
++			spin_unlock(&idp->lock);
+ 			return -1;
+ 		}
+ 		new->ary[0] = p;
+diff --git a/net/core/ethtool.c b/net/core/ethtool.c
+index e6f7610..c680b7e 100644
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -591,7 +591,7 @@ static int ethtool_set_tso(struct net_de
+ 
+ static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
+ {
+-	struct ethtool_value edata = { ETHTOOL_GTSO };
++	struct ethtool_value edata = { ETHTOOL_GUFO };
+ 
+ 	if (!dev->ethtool_ops->get_ufo)
+ 		return -EOPNOTSUPP;
+@@ -600,6 +600,7 @@ static int ethtool_get_ufo(struct net_de
+ 		 return -EFAULT;
+ 	return 0;
+ }
++
+ static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
+ {
+ 	struct ethtool_value edata;
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 445006e..4da6645 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -862,6 +862,8 @@ static int inline ipv6_saddr_label(const
+   * 	2002::/16		2
+   * 	::/96			3
+   * 	::ffff:0:0/96		4
++  *	fc00::/7		5
++  * 	2001::/32		6
+   */
+ 	if (type & IPV6_ADDR_LOOPBACK)
+ 		return 0;
+@@ -869,8 +871,12 @@ static int inline ipv6_saddr_label(const
+ 		return 3;
+ 	else if (type & IPV6_ADDR_MAPPED)
+ 		return 4;
++	else if (addr->s6_addr32[0] == htonl(0x20010000))
++		return 6;
+ 	else if (addr->s6_addr16[0] == htons(0x2002))
+ 		return 2;
++	else if ((addr->s6_addr[0] & 0xfe) == 0xfc)
++		return 5;
+ 	return 1;
+ }
+ 
+@@ -1069,6 +1075,9 @@ #ifdef CONFIG_IPV6_PRIVACY
+ 				if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
+ 					continue;
+ 			}
++#else
++			if (hiscore.rule < 7)
++				hiscore.rule++;
+ #endif
+ 			/* Rule 8: Use longest matching prefix */
+ 			if (hiscore.rule < 8) {
+@@ -2860,6 +2869,11 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
+ 	return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen);
+ }
+ 
++/* Maximum length of ifa_cacheinfo attributes */
++#define INET6_IFADDR_RTA_SPACE \
++		RTA_SPACE(16) /* IFA_ADDRESS */ + \
++		RTA_SPACE(sizeof(struct ifa_cacheinfo)) /* CACHEINFO */
++
+ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
+ 			     u32 pid, u32 seq, int event, unsigned int flags)
+ {
+@@ -3092,7 +3106,7 @@ static int inet6_dump_ifacaddr(struct sk
+ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
+ {
+ 	struct sk_buff *skb;
+-	int size = NLMSG_SPACE(sizeof(struct ifaddrmsg)+128);
++	int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE);
+ 
+ 	skb = alloc_skb(size, GFP_ATOMIC);
+ 	if (!skb) {
+@@ -3142,6 +3156,17 @@ #endif
+ #endif
+ }
+ 
++/* Maximum length of ifinfomsg attributes */
++#define INET6_IFINFO_RTA_SPACE \
++		RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \
++		RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ +	\
++		RTA_SPACE(sizeof(u32)) /* MTU */ + \
++		RTA_SPACE(sizeof(int)) /* LINK */ + \
++		RTA_SPACE(0) /* PROTINFO */ + \
++		RTA_SPACE(sizeof(u32)) /* FLAGS */ + \
++		RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \
++		RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */
++
+ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 
+ 			     u32 pid, u32 seq, int event, unsigned int flags)
+ {
+@@ -3235,8 +3260,7 @@ static int inet6_dump_ifinfo(struct sk_b
+ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
+ {
+ 	struct sk_buff *skb;
+-	/* 128 bytes ?? */
+-	int size = NLMSG_SPACE(sizeof(struct ifinfomsg)+128);
++	int size = NLMSG_SPACE(sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE);
+ 	
+ 	skb = alloc_skb(size, GFP_ATOMIC);
+ 	if (!skb) {
+@@ -3252,6 +3276,11 @@ void inet6_ifinfo_notify(int event, stru
+ 	netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFINFO, GFP_ATOMIC);
+ }
+ 
++/* Maximum length of prefix_cacheinfo attributes */
++#define INET6_PREFIX_RTA_SPACE \
++		RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \
++		RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */
++
+ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
+ 			struct prefix_info *pinfo, u32 pid, u32 seq, 
+ 			int event, unsigned int flags)
+@@ -3296,7 +3325,7 @@ static void inet6_prefix_notify(int even
+ 			 struct prefix_info *pinfo)
+ {
+ 	struct sk_buff *skb;
+-	int size = NLMSG_SPACE(sizeof(struct prefixmsg)+128);
++	int size = NLMSG_SPACE(sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE);
+ 
+ 	skb = alloc_skb(size, GFP_ATOMIC);
+ 	if (!skb) {
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 1662f9c..70d6606 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -170,7 +170,8 @@ int sctp_rcv(struct sk_buff *skb)
+ 	 * IP broadcast addresses cannot be used in an SCTP transport
+ 	 * address."
+ 	 */
+-	if (!af->addr_valid(&src, NULL) || !af->addr_valid(&dest, NULL))
++	if (!af->addr_valid(&src, NULL, skb) ||
++	    !af->addr_valid(&dest, NULL, skb))
+ 		goto discard_it;
+ 
+ 	asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index c20d282..8ef0807 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -523,7 +523,9 @@ static int sctp_v6_available(union sctp_
+  * Return 0 - If the address is a non-unicast or an illegal address.
+  * Return 1 - If the address is a unicast.
+  */
+-static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
++static int sctp_v6_addr_valid(union sctp_addr *addr,
++			      struct sctp_sock *sp,
++			      const struct sk_buff *skb)
+ {
+ 	int ret = ipv6_addr_type(&addr->v6.sin6_addr);
+ 
+@@ -537,7 +539,7 @@ static int sctp_v6_addr_valid(union sctp
+ 		if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
+ 			return 0;
+ 		sctp_v6_map_v4(addr);
+-		return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp);
++		return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp, skb);
+ 	}
+ 
+ 	/* Is this a non-unicast address */
+diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
+index f148f95..e5faa35 100644
+--- a/net/sctp/outqueue.c
++++ b/net/sctp/outqueue.c
+@@ -1262,6 +1262,7 @@ #endif /* SCTP_DEBUG */
+ 			   	if (!tchunk->tsn_gap_acked &&
+ 				    !tchunk->resent &&
+ 				    tchunk->rtt_in_progress) {
++					tchunk->rtt_in_progress = 0;
+ 					rtt = jiffies - tchunk->sent_at;
+ 					sctp_transport_update_rto(transport,
+ 								  rtt);
+diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
+index 2088aa9..816c033 100644
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -365,12 +365,18 @@ static int sctp_v4_is_any(const union sc
+  * Return 0 - If the address is a non-unicast or an illegal address.
+  * Return 1 - If the address is a unicast.
+  */
+-static int sctp_v4_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
++static int sctp_v4_addr_valid(union sctp_addr *addr,
++			      struct sctp_sock *sp,
++			      const struct sk_buff *skb)
+ {
+ 	/* Is this a non-unicast address or a unusable SCTP address? */
+ 	if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr))
+ 		return 0;
+ 
++ 	/* Is this a broadcast address? */
++ 	if (skb && ((struct rtable *)skb->dst)->rt_flags & RTCF_BROADCAST)
++ 		return 0;
++
+ 	return 1;
+ }
+ 
+diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
+index 8bc2792..9e58144 100644
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -5293,10 +5293,18 @@ static int sctp_eat_data(const struct sc
+ 	 * seems a bit troublesome in that frag_point varies based on
+ 	 * PMTU.  In cases, such as loopback, this might be a rather
+ 	 * large spill over.
++	 * NOTE: If we have a full receive buffer here, we only renege if
++	 * our receiver can still make progress without the tsn being
++	 * received. We do this because in the event that the associations
++	 * receive queue is empty we are filling a leading gap, and since
++	 * reneging moves the gap to the end of the tsn stream, we are likely
++	 * to stall again very shortly. Avoiding the renege when we fill a
++	 * leading gap is a good heuristic for avoiding such steady state
++	 * stalls.
+ 	 */
+ 	if (!asoc->rwnd || asoc->rwnd_over ||
+ 	    (datalen > asoc->rwnd + asoc->frag_point) ||
+-	    rcvbuf_over) {
++	    (rcvbuf_over && (!skb_queue_len(&sk->sk_receive_queue)))) {
+ 
+ 		/* If this is the next TSN, consider reneging to make
+ 		 * room.   Note: Playing nice with a confused sender.  A
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 174d4d3..b811691 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -172,7 +172,7 @@ static inline int sctp_verify_addr(struc
+ 		return -EINVAL;
+ 
+ 	/* Is this a valid SCTP address?  */
+-	if (!af->addr_valid(addr, sctp_sk(sk)))
++	if (!af->addr_valid(addr, sctp_sk(sk), NULL))
+ 		return -EINVAL;
+ 
+ 	if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr)))
+@@ -2530,8 +2530,32 @@ static int sctp_setsockopt_associnfo(str
+ 
+ 	/* Set the values to the specific association */
+ 	if (asoc) {
+-		if (assocparams.sasoc_asocmaxrxt != 0)
++		if (assocparams.sasoc_asocmaxrxt != 0) {
++			__u32 path_sum = 0;
++			int   paths = 0;
++			struct list_head *pos;
++			struct sctp_transport *peer_addr;
++
++			list_for_each(pos, &asoc->peer.transport_addr_list) {
++				peer_addr = list_entry(pos,
++						struct sctp_transport,
++						transports);
++				path_sum += peer_addr->pathmaxrxt;
++				paths++;
++			}
++
++			/* Only validate asocmaxrxt if we have more then
++			 * one path/transport.  We do this because path
++			 * retransmissions are only counted when we have more
++			 * then one path.
++			 */
++			if (paths > 1 &&
++			    assocparams.sasoc_asocmaxrxt > path_sum)
++				return -EINVAL;
++
+ 			asoc->max_retrans = assocparams.sasoc_asocmaxrxt;
++		}
++
+ 		if (assocparams.sasoc_cookie_life != 0) {
+ 			asoc->cookie_life.tv_sec =
+ 					assocparams.sasoc_cookie_life / 1000;
+diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
+index ba97f97..ee23678 100644
+--- a/net/sctp/ulpevent.c
++++ b/net/sctp/ulpevent.c
+@@ -51,6 +51,8 @@ #include <net/sctp/sm.h>
+ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event,
+ 				       struct sctp_association *asoc);
+ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event);
++static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event);
++
+ 
+ /* Initialize an ULP event from an given skb.  */
+ SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
+@@ -883,6 +885,7 @@ static void sctp_ulpevent_receive_data(s
+ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event)
+ {
+ 	struct sk_buff *skb, *frag;
++	unsigned int	len;
+ 
+ 	/* Current stack structures assume that the rcv buffer is
+ 	 * per socket.   For UDP style sockets this is not true as
+@@ -892,7 +895,30 @@ static void sctp_ulpevent_release_data(s
+ 	 */
+ 
+ 	skb = sctp_event2skb(event);
+-	sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb));
++	len = skb->len;
++
++	if (!skb->data_len)
++		goto done;
++
++	/* Don't forget the fragments. */
++	for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
++		/* NOTE:  skb_shinfos are recursive. Although IP returns
++		 * skb's with only 1 level of fragments, SCTP reassembly can
++		 * increase the levels.
++		 */
++		sctp_ulpevent_release_frag_data(sctp_skb2event(frag));
++	}
++
++done:
++	sctp_assoc_rwnd_increase(event->asoc, len);
++	sctp_ulpevent_release_owner(event);
++}
++
++static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event)
++{
++	struct sk_buff *skb, *frag;
++
++	skb = sctp_event2skb(event);
+ 
+ 	if (!skb->data_len)
+ 		goto done;
+@@ -903,7 +929,7 @@ static void sctp_ulpevent_release_data(s
+ 		 * skb's with only 1 level of fragments, SCTP reassembly can
+ 		 * increase the levels.
+ 		 */
+-		sctp_ulpevent_release_data(sctp_skb2event(frag));
++		sctp_ulpevent_release_frag_data(sctp_skb2event(frag));
+ 	}
+ 
+ done:
+diff --git a/usr/Makefile b/usr/Makefile
+index 19d74e6..e938242 100644
+--- a/usr/Makefile
++++ b/usr/Makefile
+@@ -21,8 +21,7 @@ ramfs-input := $(if $(filter-out "",$(CO
+                     $(CONFIG_INITRAMFS_SOURCE),-d)
+ ramfs-args  := \
+         $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
+-        $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID)) \
+-        $(ramfs-input)
++        $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))
+ 
+ # .initramfs_data.cpio.gz.d is used to identify all files included
+ # in initramfs and to detect if any files are added/removed.

Added: dists/trunk/linux-2.6/debian/patches/2.6.17.3
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/2.6.17.3	Tue Jul  4 07:47:09 2006
@@ -0,0 +1,26 @@
+diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+index 0416073..2d3612c 100644
+--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
++++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+@@ -254,7 +254,7 @@ static int do_basic_checks(struct ip_con
+ 	}
+ 
+ 	DEBUGP("Basic checks passed\n");
+-	return 0;
++	return count == 0;
+ }
+ 
+ static int new_state(enum ip_conntrack_dir dir,
+diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
+index 0c6da49..9dab81d 100644
+--- a/net/netfilter/nf_conntrack_proto_sctp.c
++++ b/net/netfilter/nf_conntrack_proto_sctp.c
+@@ -259,7 +259,7 @@ static int do_basic_checks(struct nf_con
+ 	}
+ 
+ 	DEBUGP("Basic checks passed\n");
+-	return 0;
++	return count == 0;
+ }
+ 
+ static int new_state(enum ip_conntrack_dir dir,

Added: dists/trunk/linux-2.6/debian/patches/series/3
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/series/3	Tue Jul  4 07:47:09 2006
@@ -0,0 +1,3 @@
+- sparc32-iotlb.patch
++ 2.6.17.2
++ 2.6.17.3



More information about the Kernel-svn-changes mailing list