Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [IPSEC]: Fix the address family to refer encap_family
  [IPSEC]: changing API of xfrm6_tunnel_register
  [IPSEC]: make sit use the xfrm4_tunnel_register
  [IPSEC]: Changing API of xfrm4_tunnel_register.
  [TCP]: Prevent pseudo garbage in SYN's advertized window
  [NET_SCHED]: sch_hfsc: replace ASSERT macro by WARN_ON
  [BRIDGE] br_if: Fix oops in port_carrier_check
  [NETFILTER]: Clear GSO bits for TCP reset packet
  [TG3]: Update copyright, version, and reldate.
  [TG3]: Add some tx timeout debug messages.
  [TG3]: Use constant for PHY register 0x1e.
  [TG3]: Power down 5704 serdes transceiver when shutting down.
  [TG3]: 5906 doesn't need to switch to slower clock.
  [TG3]: 5722/5756 don't need PHY jitter workaround.
  [TG3]: Use lower DMA watermark for 5703.
  [TG3]: Save MSI state before suspend.
  [XFRM]: Fix IPv4 tunnel mode decapsulation with IPV6=n
  [IPV6] HASHTABLES: Use appropriate seed for caluculating ehash index.
This commit is contained in:
Linus Torvalds 2007-02-13 18:17:26 -08:00
commit 551a10c7fc
21 changed files with 226 additions and 72 deletions

View File

@ -4,7 +4,7 @@
* Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
* Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
* Copyright (C) 2004 Sun Microsystems Inc. * Copyright (C) 2004 Sun Microsystems Inc.
* Copyright (C) 2005 Broadcom Corporation. * Copyright (C) 2005-2007 Broadcom Corporation.
* *
* Firmware is: * Firmware is:
* Derived from proprietary unpublished source code, * Derived from proprietary unpublished source code,
@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3" #define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.72" #define DRV_MODULE_VERSION "3.73"
#define DRV_MODULE_RELDATE "January 8, 2007" #define DRV_MODULE_RELDATE "February 12, 2007"
#define TG3_DEF_MAC_MODE 0 #define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0 #define TG3_DEF_RX_MODE 0
@ -1175,8 +1175,18 @@ static void tg3_nvram_unlock(struct tg3 *);
static void tg3_power_down_phy(struct tg3 *tp) static void tg3_power_down_phy(struct tg3 *tp)
{ {
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
u32 sg_dig_ctrl = tr32(SG_DIG_CTRL);
u32 serdes_cfg = tr32(MAC_SERDES_CFG);
sg_dig_ctrl |=
SG_DIG_USING_HW_AUTONEG | SG_DIG_SOFT_RESET;
tw32(SG_DIG_CTRL, sg_dig_ctrl);
tw32(MAC_SERDES_CFG, serdes_cfg | (1 << 15));
}
return; return;
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
u32 val; u32 val;
@ -1340,7 +1350,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK | tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
CLOCK_CTRL_PWRDOWN_PLL133, 40); CLOCK_CTRL_PWRDOWN_PLL133, 40);
} else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { } else if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)) {
/* do nothing */ /* do nothing */
} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) { (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
@ -3724,13 +3735,23 @@ out:
tg3_full_unlock(tp); tg3_full_unlock(tp);
} }
static void tg3_dump_short_state(struct tg3 *tp)
{
printk(KERN_ERR PFX "DEBUG: MAC_TX_STATUS[%08x] MAC_RX_STATUS[%08x]\n",
tr32(MAC_TX_STATUS), tr32(MAC_RX_STATUS));
printk(KERN_ERR PFX "DEBUG: RDMAC_STATUS[%08x] WDMAC_STATUS[%08x]\n",
tr32(RDMAC_STATUS), tr32(WDMAC_STATUS));
}
static void tg3_tx_timeout(struct net_device *dev) static void tg3_tx_timeout(struct net_device *dev)
{ {
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
if (netif_msg_tx_err(tp)) if (netif_msg_tx_err(tp)) {
printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
dev->name); dev->name);
tg3_dump_short_state(tp);
}
schedule_work(&tp->reset_task); schedule_work(&tp->reset_task);
} }
@ -6583,8 +6604,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
u32 tmp; u32 tmp;
/* Clear CRC stats. */ /* Clear CRC stats. */
if (!tg3_readphy(tp, 0x1e, &tmp)) { if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
tg3_writephy(tp, 0x1e, tmp | 0x8000); tg3_writephy(tp, MII_TG3_TEST1,
tmp | MII_TG3_TEST1_CRC_EN);
tg3_readphy(tp, 0x14, &tmp); tg3_readphy(tp, 0x14, &tmp);
} }
} }
@ -7408,8 +7430,9 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
u32 val; u32 val;
spin_lock_bh(&tp->lock); spin_lock_bh(&tp->lock);
if (!tg3_readphy(tp, 0x1e, &val)) { if (!tg3_readphy(tp, MII_TG3_TEST1, &val)) {
tg3_writephy(tp, 0x1e, val | 0x8000); tg3_writephy(tp, MII_TG3_TEST1,
val | MII_TG3_TEST1_CRC_EN);
tg3_readphy(tp, 0x14, &val); tg3_readphy(tp, 0x14, &val);
} else } else
val = 0; val = 0;
@ -10779,6 +10802,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) { GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) {
if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 &&
tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722)
tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M) if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M)
tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM; tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM;
@ -11314,6 +11339,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f);
u32 read_water = 0x7;
/* If the 5704 is behind the EPB bridge, we can /* If the 5704 is behind the EPB bridge, we can
* do the less restrictive ONE_DMA workaround for * do the less restrictive ONE_DMA workaround for
@ -11325,8 +11351,13 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
else if (ccval == 0x6 || ccval == 0x7) else if (ccval == 0x6 || ccval == 0x7)
tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703)
read_water = 4;
/* Set bit 23 to enable PCIX hw bug fix */ /* Set bit 23 to enable PCIX hw bug fix */
tp->dma_rwctrl |= 0x009f0000; tp->dma_rwctrl |=
(read_water << DMA_RWCTRL_READ_WATER_SHIFT) |
(0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
(1 << 23);
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) { } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
/* 5780 always in PCIX mode */ /* 5780 always in PCIX mode */
tp->dma_rwctrl |= 0x00144000; tp->dma_rwctrl |= 0x00144000;
@ -12016,6 +12047,9 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
tg3_full_unlock(tp); tg3_full_unlock(tp);
/* Save MSI address and data for resume. */
pci_save_state(pdev);
err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
if (err) { if (err) {
tg3_full_lock(tp, 0); tg3_full_lock(tp, 0);

View File

@ -1660,6 +1660,7 @@
#define MII_TG3_TEST1 0x1e #define MII_TG3_TEST1 0x1e
#define MII_TG3_TEST1_TRIM_EN 0x0010 #define MII_TG3_TEST1_TRIM_EN 0x0010
#define MII_TG3_TEST1_CRC_EN 0x8000
/* There are two ways to manage the TX descriptors on the tigon3. /* There are two ways to manage the TX descriptors on the tigon3.
* Either the descriptors are in host DMA'able memory, or they * Either the descriptors are in host DMA'able memory, or they

View File

@ -946,14 +946,14 @@ extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
extern int xfrm_init_state(struct xfrm_state *x); extern int xfrm_init_state(struct xfrm_state *x);
extern int xfrm4_rcv(struct sk_buff *skb); extern int xfrm4_rcv(struct sk_buff *skb);
extern int xfrm4_output(struct sk_buff *skb); extern int xfrm4_output(struct sk_buff *skb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi); extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
extern int xfrm6_rcv(struct sk_buff **pskb); extern int xfrm6_rcv(struct sk_buff **pskb);
extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
xfrm_address_t *saddr, u8 proto); xfrm_address_t *saddr, u8 proto);
extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);

View File

@ -108,6 +108,7 @@ static void port_carrier_check(struct work_struct *work)
spin_unlock_bh(&br->lock); spin_unlock_bh(&br->lock);
} }
done: done:
dev_put(dev);
rtnl_unlock(); rtnl_unlock();
} }
@ -161,7 +162,8 @@ static void del_nbp(struct net_bridge_port *p)
dev_set_promiscuity(dev, -1); dev_set_promiscuity(dev, -1);
cancel_delayed_work(&p->carrier_check); if (cancel_delayed_work(&p->carrier_check))
dev_put(dev);
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
br_stp_disable_port(p); br_stp_disable_port(p);
@ -444,7 +446,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
br_stp_recalculate_bridge_id(br); br_stp_recalculate_bridge_id(br);
br_features_recompute(br); br_features_recompute(br);
schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE); if (schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE))
dev_hold(dev);
spin_unlock_bh(&br->lock); spin_unlock_bh(&br->lock);
dev_set_mtu(br->dev, br_min_mtu(br)); dev_set_mtu(br->dev, br_min_mtu(br));

View File

@ -56,7 +56,9 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
case NETDEV_CHANGE: case NETDEV_CHANGE:
if (br->dev->flags & IFF_UP) if (br->dev->flags & IFF_UP)
schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE); if (schedule_delayed_work(&p->carrier_check,
BR_PORT_DEBOUNCE))
dev_hold(dev);
break; break;
case NETDEV_FEAT_CHANGE: case NETDEV_FEAT_CHANGE:

View File

@ -871,7 +871,7 @@ static int __init ipip_init(void)
printk(banner); printk(banner);
if (xfrm4_tunnel_register(&ipip_handler)) { if (xfrm4_tunnel_register(&ipip_handler, AF_INET)) {
printk(KERN_INFO "ipip init: can't register tunnel\n"); printk(KERN_INFO "ipip init: can't register tunnel\n");
return -EAGAIN; return -EAGAIN;
} }
@ -893,7 +893,7 @@ static int __init ipip_init(void)
err2: err2:
free_netdev(ipip_fb_tunnel_dev); free_netdev(ipip_fb_tunnel_dev);
err1: err1:
xfrm4_tunnel_deregister(&ipip_handler); xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
goto out; goto out;
} }
@ -913,7 +913,7 @@ static void __exit ipip_destroy_tunnels(void)
static void __exit ipip_fini(void) static void __exit ipip_fini(void)
{ {
if (xfrm4_tunnel_deregister(&ipip_handler)) if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET))
printk(KERN_INFO "ipip close: can't deregister tunnel\n"); printk(KERN_INFO "ipip close: can't deregister tunnel\n");
rtnl_lock(); rtnl_lock();

View File

@ -80,6 +80,10 @@ static void send_reset(struct sk_buff *oldskb, int hook)
nskb->mark = 0; nskb->mark = 0;
skb_init_secmark(nskb); skb_init_secmark(nskb);
skb_shinfo(nskb)->gso_size = 0;
skb_shinfo(nskb)->gso_segs = 0;
skb_shinfo(nskb)->gso_type = 0;
tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl); tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
/* Swap source and dest */ /* Swap source and dest */

View File

@ -481,7 +481,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
/* RFC1323: The window in SYN & SYN/ACK segments /* RFC1323: The window in SYN & SYN/ACK segments
* is never scaled. * is never scaled.
*/ */
th->window = htons(tp->rcv_wnd); th->window = htons(min(tp->rcv_wnd, 65535U));
} else { } else {
th->window = htons(tcp_select_window(sk)); th->window = htons(tcp_select_window(sk));
} }
@ -2160,7 +2160,7 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
} }
/* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
th->window = htons(req->rcv_wnd); th->window = htons(min(req->rcv_wnd, 65535U));
TCP_SKB_CB(skb)->when = tcp_time_stamp; TCP_SKB_CB(skb)->when = tcp_time_stamp;
tcp_syn_build_options((__be32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok, tcp_syn_build_options((__be32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok,

View File

@ -14,9 +14,10 @@
#include <net/xfrm.h> #include <net/xfrm.h>
static struct xfrm_tunnel *tunnel4_handlers; static struct xfrm_tunnel *tunnel4_handlers;
static struct xfrm_tunnel *tunnel64_handlers;
static DEFINE_MUTEX(tunnel4_mutex); static DEFINE_MUTEX(tunnel4_mutex);
int xfrm4_tunnel_register(struct xfrm_tunnel *handler) int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family)
{ {
struct xfrm_tunnel **pprev; struct xfrm_tunnel **pprev;
int ret = -EEXIST; int ret = -EEXIST;
@ -24,7 +25,8 @@ int xfrm4_tunnel_register(struct xfrm_tunnel *handler)
mutex_lock(&tunnel4_mutex); mutex_lock(&tunnel4_mutex);
for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) { for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
*pprev; pprev = &(*pprev)->next) {
if ((*pprev)->priority > priority) if ((*pprev)->priority > priority)
break; break;
if ((*pprev)->priority == priority) if ((*pprev)->priority == priority)
@ -44,14 +46,15 @@ err:
EXPORT_SYMBOL(xfrm4_tunnel_register); EXPORT_SYMBOL(xfrm4_tunnel_register);
int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler) int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family)
{ {
struct xfrm_tunnel **pprev; struct xfrm_tunnel **pprev;
int ret = -ENOENT; int ret = -ENOENT;
mutex_lock(&tunnel4_mutex); mutex_lock(&tunnel4_mutex);
for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) { for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
*pprev; pprev = &(*pprev)->next) {
if (*pprev == handler) { if (*pprev == handler) {
*pprev = handler->next; *pprev = handler->next;
ret = 0; ret = 0;
@ -86,6 +89,26 @@ drop:
return 0; return 0;
} }
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static int tunnel64_rcv(struct sk_buff *skb)
{
struct xfrm_tunnel *handler;
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
goto drop;
for (handler = tunnel64_handlers; handler; handler = handler->next)
if (!handler->handler(skb))
return 0;
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
drop:
kfree_skb(skb);
return 0;
}
#endif
static void tunnel4_err(struct sk_buff *skb, u32 info) static void tunnel4_err(struct sk_buff *skb, u32 info)
{ {
struct xfrm_tunnel *handler; struct xfrm_tunnel *handler;
@ -101,17 +124,36 @@ static struct net_protocol tunnel4_protocol = {
.no_policy = 1, .no_policy = 1,
}; };
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static struct net_protocol tunnel64_protocol = {
.handler = tunnel64_rcv,
.err_handler = tunnel4_err,
.no_policy = 1,
};
#endif
static int __init tunnel4_init(void) static int __init tunnel4_init(void)
{ {
if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) { if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) {
printk(KERN_ERR "tunnel4 init: can't add protocol\n"); printk(KERN_ERR "tunnel4 init: can't add protocol\n");
return -EAGAIN; return -EAGAIN;
} }
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
if (inet_add_protocol(&tunnel64_protocol, IPPROTO_IPV6)) {
printk(KERN_ERR "tunnel64 init: can't add protocol\n");
inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP);
return -EAGAIN;
}
#endif
return 0; return 0;
} }
static void __exit tunnel4_fini(void) static void __exit tunnel4_fini(void)
{ {
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
if (inet_del_protocol(&tunnel64_protocol, IPPROTO_IPV6))
printk(KERN_ERR "tunnel64 close: can't remove protocol\n");
#endif
if (inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP)) if (inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP))
printk(KERN_ERR "tunnel4 close: can't remove protocol\n"); printk(KERN_ERR "tunnel4 close: can't remove protocol\n");
} }

View File

@ -27,6 +27,7 @@ static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32
{ {
switch (nexthdr) { switch (nexthdr) {
case IPPROTO_IPIP: case IPPROTO_IPIP:
case IPPROTO_IPV6:
*spi = skb->nh.iph->saddr; *spi = skb->nh.iph->saddr;
*seq = 0; *seq = 0;
return 0; return 0;
@ -70,7 +71,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if (xfrm_nr == XFRM_MAX_DEPTH) if (xfrm_nr == XFRM_MAX_DEPTH)
goto drop; goto drop;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, iph->protocol, AF_INET); x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
iph->protocol != IPPROTO_IPV6 ? iph->protocol : IPPROTO_IPIP, AF_INET);
if (x == NULL) if (x == NULL)
goto drop; goto drop;

View File

@ -95,6 +95,7 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
switch(iph->protocol){ switch(iph->protocol){
case IPPROTO_IPIP: case IPPROTO_IPIP:
break;
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
case IPPROTO_IPV6: case IPPROTO_IPV6:
break; break;

View File

@ -64,24 +64,45 @@ static struct xfrm_tunnel xfrm_tunnel_handler = {
.priority = 2, .priority = 2,
}; };
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static struct xfrm_tunnel xfrm64_tunnel_handler = {
.handler = xfrm4_rcv,
.err_handler = xfrm_tunnel_err,
.priority = 2,
};
#endif
static int __init ipip_init(void) static int __init ipip_init(void)
{ {
if (xfrm_register_type(&ipip_type, AF_INET) < 0) { if (xfrm_register_type(&ipip_type, AF_INET) < 0) {
printk(KERN_INFO "ipip init: can't add xfrm type\n"); printk(KERN_INFO "ipip init: can't add xfrm type\n");
return -EAGAIN; return -EAGAIN;
} }
if (xfrm4_tunnel_register(&xfrm_tunnel_handler)) {
printk(KERN_INFO "ipip init: can't add xfrm handler\n"); if (xfrm4_tunnel_register(&xfrm_tunnel_handler, AF_INET)) {
printk(KERN_INFO "ipip init: can't add xfrm handler for AF_INET\n");
xfrm_unregister_type(&ipip_type, AF_INET); xfrm_unregister_type(&ipip_type, AF_INET);
return -EAGAIN; return -EAGAIN;
} }
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
if (xfrm4_tunnel_register(&xfrm64_tunnel_handler, AF_INET6)) {
printk(KERN_INFO "ipip init: can't add xfrm handler for AF_INET6\n");
xfrm4_tunnel_deregister(&xfrm_tunnel_handler, AF_INET);
xfrm_unregister_type(&ipip_type, AF_INET);
return -EAGAIN;
}
#endif
return 0; return 0;
} }
static void __exit ipip_fini(void) static void __exit ipip_fini(void)
{ {
if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler)) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
printk(KERN_INFO "ipip close: can't remove xfrm handler\n"); if (xfrm4_tunnel_deregister(&xfrm64_tunnel_handler, AF_INET6))
printk(KERN_INFO "ipip close: can't remove xfrm handler for AF_INET6\n");
#endif
if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler, AF_INET))
printk(KERN_INFO "ipip close: can't remove xfrm handler for AF_INET\n");
if (xfrm_unregister_type(&ipip_type, AF_INET) < 0) if (xfrm_unregister_type(&ipip_type, AF_INET) < 0)
printk(KERN_INFO "ipip close: can't remove xfrm type\n"); printk(KERN_INFO "ipip close: can't remove xfrm type\n");
} }

View File

@ -156,6 +156,7 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION
config IPV6_SIT config IPV6_SIT
tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)" tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
depends on IPV6 depends on IPV6
select INET_TUNNEL
default y default y
---help--- ---help---
Tunneling means encapsulating data of one protocol type within Tunneling means encapsulating data of one protocol type within

View File

@ -172,7 +172,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
const struct in6_addr *saddr = &np->daddr; const struct in6_addr *saddr = &np->daddr;
const int dif = sk->sk_bound_dev_if; const int dif = sk->sk_bound_dev_if;
const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, const unsigned int hash = inet6_ehashfn(daddr, lport, saddr,
inet->dport); inet->dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
struct sock *sk2; struct sock *sk2;

View File

@ -1128,7 +1128,7 @@ static int __init ip6_tunnel_init(void)
{ {
int err; int err;
if (xfrm6_tunnel_register(&ip6ip6_handler)) { if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) {
printk(KERN_ERR "ip6ip6 init: can't register tunnel\n"); printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
return -EAGAIN; return -EAGAIN;
} }
@ -1147,7 +1147,7 @@ static int __init ip6_tunnel_init(void)
} }
return 0; return 0;
fail: fail:
xfrm6_tunnel_deregister(&ip6ip6_handler); xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
return err; return err;
} }
@ -1171,7 +1171,7 @@ static void __exit ip6ip6_destroy_tunnels(void)
static void __exit ip6_tunnel_cleanup(void) static void __exit ip6_tunnel_cleanup(void)
{ {
if (xfrm6_tunnel_deregister(&ip6ip6_handler)) if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6))
printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
rtnl_lock(); rtnl_lock();

View File

@ -216,7 +216,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
} }
static void ipip6_err(struct sk_buff *skb, u32 info) static int ipip6_err(struct sk_buff *skb, u32 info)
{ {
#ifndef I_WISH_WORLD_WERE_PERFECT #ifndef I_WISH_WORLD_WERE_PERFECT
@ -228,21 +228,22 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
int type = skb->h.icmph->type; int type = skb->h.icmph->type;
int code = skb->h.icmph->code; int code = skb->h.icmph->code;
struct ip_tunnel *t; struct ip_tunnel *t;
int err;
switch (type) { switch (type) {
default: default:
case ICMP_PARAMETERPROB: case ICMP_PARAMETERPROB:
return; return 0;
case ICMP_DEST_UNREACH: case ICMP_DEST_UNREACH:
switch (code) { switch (code) {
case ICMP_SR_FAILED: case ICMP_SR_FAILED:
case ICMP_PORT_UNREACH: case ICMP_PORT_UNREACH:
/* Impossible event. */ /* Impossible event. */
return; return 0;
case ICMP_FRAG_NEEDED: case ICMP_FRAG_NEEDED:
/* Soft state for pmtu is maintained by IP core. */ /* Soft state for pmtu is maintained by IP core. */
return; return 0;
default: default:
/* All others are translated to HOST_UNREACH. /* All others are translated to HOST_UNREACH.
rfc2003 contains "deep thoughts" about NET_UNREACH, rfc2003 contains "deep thoughts" about NET_UNREACH,
@ -253,14 +254,18 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
break; break;
case ICMP_TIME_EXCEEDED: case ICMP_TIME_EXCEEDED:
if (code != ICMP_EXC_TTL) if (code != ICMP_EXC_TTL)
return; return 0;
break; break;
} }
err = -ENOENT;
read_lock(&ipip6_lock); read_lock(&ipip6_lock);
t = ipip6_tunnel_lookup(iph->daddr, iph->saddr); t = ipip6_tunnel_lookup(iph->daddr, iph->saddr);
if (t == NULL || t->parms.iph.daddr == 0) if (t == NULL || t->parms.iph.daddr == 0)
goto out; goto out;
err = 0;
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
goto out; goto out;
@ -271,7 +276,7 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
t->err_time = jiffies; t->err_time = jiffies;
out: out:
read_unlock(&ipip6_lock); read_unlock(&ipip6_lock);
return; return err;
#else #else
struct iphdr *iph = (struct iphdr*)dp; struct iphdr *iph = (struct iphdr*)dp;
int hlen = iph->ihl<<2; int hlen = iph->ihl<<2;
@ -332,7 +337,7 @@ out:
/* Prepare fake skb to feed it to icmpv6_send */ /* Prepare fake skb to feed it to icmpv6_send */
skb2 = skb_clone(skb, GFP_ATOMIC); skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2 == NULL) if (skb2 == NULL)
return; return 0;
dst_release(skb2->dst); dst_release(skb2->dst);
skb2->dst = NULL; skb2->dst = NULL;
skb_pull(skb2, skb->data - (u8*)iph6); skb_pull(skb2, skb->data - (u8*)iph6);
@ -355,7 +360,7 @@ out:
} }
} }
kfree_skb(skb2); kfree_skb(skb2);
return; return 0;
#endif #endif
} }
@ -791,9 +796,10 @@ static int __init ipip6_fb_tunnel_init(struct net_device *dev)
return 0; return 0;
} }
static struct net_protocol sit_protocol = { static struct xfrm_tunnel sit_handler = {
.handler = ipip6_rcv, .handler = ipip6_rcv,
.err_handler = ipip6_err, .err_handler = ipip6_err,
.priority = 1,
}; };
static void __exit sit_destroy_tunnels(void) static void __exit sit_destroy_tunnels(void)
@ -812,7 +818,7 @@ static void __exit sit_destroy_tunnels(void)
static void __exit sit_cleanup(void) static void __exit sit_cleanup(void)
{ {
inet_del_protocol(&sit_protocol, IPPROTO_IPV6); xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
rtnl_lock(); rtnl_lock();
sit_destroy_tunnels(); sit_destroy_tunnels();
@ -826,7 +832,7 @@ static int __init sit_init(void)
printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
if (inet_add_protocol(&sit_protocol, IPPROTO_IPV6) < 0) { if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) {
printk(KERN_INFO "sit init: Can't add protocol\n"); printk(KERN_INFO "sit init: Can't add protocol\n");
return -EAGAIN; return -EAGAIN;
} }
@ -848,7 +854,7 @@ static int __init sit_init(void)
err2: err2:
free_netdev(ipip6_fb_tunnel_dev); free_netdev(ipip6_fb_tunnel_dev);
err1: err1:
inet_del_protocol(&sit_protocol, IPPROTO_IPV6); xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
goto out; goto out;
} }

View File

@ -30,9 +30,10 @@
#include <net/xfrm.h> #include <net/xfrm.h>
static struct xfrm6_tunnel *tunnel6_handlers; static struct xfrm6_tunnel *tunnel6_handlers;
static struct xfrm6_tunnel *tunnel46_handlers;
static DEFINE_MUTEX(tunnel6_mutex); static DEFINE_MUTEX(tunnel6_mutex);
int xfrm6_tunnel_register(struct xfrm6_tunnel *handler) int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
{ {
struct xfrm6_tunnel **pprev; struct xfrm6_tunnel **pprev;
int ret = -EEXIST; int ret = -EEXIST;
@ -40,7 +41,8 @@ int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
mutex_lock(&tunnel6_mutex); mutex_lock(&tunnel6_mutex);
for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) { for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
*pprev; pprev = &(*pprev)->next) {
if ((*pprev)->priority > priority) if ((*pprev)->priority > priority)
break; break;
if ((*pprev)->priority == priority) if ((*pprev)->priority == priority)
@ -60,14 +62,15 @@ err:
EXPORT_SYMBOL(xfrm6_tunnel_register); EXPORT_SYMBOL(xfrm6_tunnel_register);
int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler) int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
{ {
struct xfrm6_tunnel **pprev; struct xfrm6_tunnel **pprev;
int ret = -ENOENT; int ret = -ENOENT;
mutex_lock(&tunnel6_mutex); mutex_lock(&tunnel6_mutex);
for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) { for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
*pprev; pprev = &(*pprev)->next) {
if (*pprev == handler) { if (*pprev == handler) {
*pprev = handler->next; *pprev = handler->next;
ret = 0; ret = 0;
@ -103,6 +106,25 @@ drop:
return 0; return 0;
} }
static int tunnel46_rcv(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;
struct xfrm6_tunnel *handler;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
goto drop;
for (handler = tunnel46_handlers; handler; handler = handler->next)
if (!handler->handler(skb))
return 0;
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev);
drop:
kfree_skb(skb);
return 0;
}
static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
int type, int code, int offset, __be32 info) int type, int code, int offset, __be32 info)
{ {
@ -119,17 +141,30 @@ static struct inet6_protocol tunnel6_protocol = {
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
}; };
static struct inet6_protocol tunnel46_protocol = {
.handler = tunnel46_rcv,
.err_handler = tunnel6_err,
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};
static int __init tunnel6_init(void) static int __init tunnel6_init(void)
{ {
if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) { if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) {
printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
return -EAGAIN; return -EAGAIN;
} }
if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) {
printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);
return -EAGAIN;
}
return 0; return 0;
} }
static void __exit tunnel6_fini(void) static void __exit tunnel6_fini(void)
{ {
if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP))
printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6)) if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6))
printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
} }

View File

@ -40,7 +40,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
if (xfrm_nr == XFRM_MAX_DEPTH) if (xfrm_nr == XFRM_MAX_DEPTH)
goto drop; goto drop;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, nexthdr, AF_INET6); x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6);
if (x == NULL) if (x == NULL)
goto drop; goto drop;
spin_lock(&x->lock); spin_lock(&x->lock);

View File

@ -339,17 +339,29 @@ static struct xfrm6_tunnel xfrm6_tunnel_handler = {
.priority = 2, .priority = 2,
}; };
static struct xfrm6_tunnel xfrm46_tunnel_handler = {
.handler = xfrm6_tunnel_rcv,
.err_handler = xfrm6_tunnel_err,
.priority = 2,
};
static int __init xfrm6_tunnel_init(void) static int __init xfrm6_tunnel_init(void)
{ {
if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
return -EAGAIN; return -EAGAIN;
if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) { if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) {
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
return -EAGAIN;
}
if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) {
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
return -EAGAIN; return -EAGAIN;
} }
if (xfrm6_tunnel_spi_init() < 0) { if (xfrm6_tunnel_spi_init() < 0) {
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
return -EAGAIN; return -EAGAIN;
} }
@ -359,7 +371,8 @@ static int __init xfrm6_tunnel_init(void)
static void __exit xfrm6_tunnel_fini(void) static void __exit xfrm6_tunnel_fini(void)
{ {
xfrm6_tunnel_spi_fini(); xfrm6_tunnel_spi_fini();
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
} }

View File

@ -71,8 +71,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/div64.h> #include <asm/div64.h>
#define HFSC_DEBUG 1
/* /*
* kernel internal service curve representation: * kernel internal service curve representation:
* coordinates are given by 64 bit unsigned integers. * coordinates are given by 64 bit unsigned integers.
@ -211,17 +209,6 @@ do { \
} while (0) } while (0)
#endif #endif
#if HFSC_DEBUG
#define ASSERT(cond) \
do { \
if (unlikely(!(cond))) \
printk("assertion %s failed at %s:%i (%s)\n", \
#cond, __FILE__, __LINE__, __FUNCTION__); \
} while (0)
#else
#define ASSERT(cond)
#endif /* HFSC_DEBUG */
#define HT_INFINITY 0xffffffffffffffffULL /* infinite time value */ #define HT_INFINITY 0xffffffffffffffffULL /* infinite time value */
@ -1492,7 +1479,7 @@ hfsc_schedule_watchdog(struct Qdisc *sch, u64 cur_time)
if (next_time == 0 || next_time > q->root.cl_cfmin) if (next_time == 0 || next_time > q->root.cl_cfmin)
next_time = q->root.cl_cfmin; next_time = q->root.cl_cfmin;
} }
ASSERT(next_time != 0); WARN_ON(next_time == 0);
delay = next_time - cur_time; delay = next_time - cur_time;
delay = PSCHED_US2JIFFIE(delay); delay = PSCHED_US2JIFFIE(delay);

View File

@ -1550,7 +1550,7 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
unsigned short family) unsigned short family)
{ {
if (xfrm_state_kern(x)) if (xfrm_state_kern(x))
return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, family); return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, tmpl->encap_family);
return x->id.proto == tmpl->id.proto && return x->id.proto == tmpl->id.proto &&
(x->id.spi == tmpl->id.spi || !tmpl->id.spi) && (x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
(x->props.reqid == tmpl->reqid || !tmpl->reqid) && (x->props.reqid == tmpl->reqid || !tmpl->reqid) &&