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: [SUNGEM]: Fix MAC address setting when interface is up. [IPV4] fib_trie: Document locking. [NET]: Correct accept(2) recovery after sock_attach_fd() [PPP]: Don't leak an sk_buff on interface destruction. [NET_SCHED]: Fix ingress locking [NET_SCHED]: cls_basic: fix NULL pointer dereference [DCCP]: make dccp_write_xmit_timer() static again [TG3]: Update version and reldate. [TG3]: Exit irq handler during chip reset. [TG3]: Eliminate the unused TG3_FLAG_SPLIT_MODE flag. [IPV6]: Fix routing round-robin locking. [DECNet] fib: Fix out of bound access of dn_fib_props[] [IPv4] fib: Fix out of bound access of fib_props[] [NET] AX.25 Kconfig and docs updates and fixes [NET]: Fix neighbour destructor handling. [NET]: Fix fib_rules compatibility breakage [SCTP]: Update SCTP Maintainers entry [NET]: remove unused header file: drivers/net/wan/lmc/lmc_media.h
This commit is contained in:
commit
703071b5b9
|
@ -1,16 +1,10 @@
|
||||||
To use the amateur radio protocols within Linux you will need to get a
|
To use the amateur radio protocols within Linux you will need to get a
|
||||||
suitable copy of the AX.25 Utilities. More detailed information about these
|
suitable copy of the AX.25 Utilities. More detailed information about
|
||||||
and associated programs can be found on http://zone.pspt.fi/~jsn/.
|
AX.25, NET/ROM and ROSE, associated programs and and utilities can be
|
||||||
|
found on http://www.linux-ax25.org.
|
||||||
For more information about the AX.25, NET/ROM and ROSE protocol stacks, see
|
|
||||||
the AX25-HOWTO written by Terry Dawson <terry@perf.no.itg.telstra.com.au>
|
|
||||||
who is also the AX.25 Utilities maintainer.
|
|
||||||
|
|
||||||
There is an active mailing list for discussing Linux amateur radio matters
|
There is an active mailing list for discussing Linux amateur radio matters
|
||||||
called linux-hams. To subscribe to it, send a message to
|
called linux-hams@vger.kernel.org. To subscribe to it, send a message to
|
||||||
majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body
|
majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body
|
||||||
of the message, the subject field is ignored.
|
of the message, the subject field is ignored. You don't need to be
|
||||||
|
subscribed to post but of course that means you might miss an answer.
|
||||||
Jonathan G4KLX
|
|
||||||
|
|
||||||
g4klx@g4klx.demon.co.uk
|
|
||||||
|
|
|
@ -2928,9 +2928,12 @@ L: linux-scsi@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
SCTP PROTOCOL
|
SCTP PROTOCOL
|
||||||
|
P: Vlad Yasevich
|
||||||
|
M: vladislav.yasevich@hp.com
|
||||||
P: Sridhar Samudrala
|
P: Sridhar Samudrala
|
||||||
M: sri@us.ibm.com
|
M: sri@us.ibm.com
|
||||||
L: lksctp-developers@lists.sourceforge.net
|
L: lksctp-developers@lists.sourceforge.net
|
||||||
|
W: http://lksctp.sourceforge.net
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
SCx200 CPU SUPPORT
|
SCx200 CPU SUPPORT
|
||||||
|
|
|
@ -814,7 +814,7 @@ static void ipoib_set_mcast_list(struct net_device *dev)
|
||||||
queue_work(ipoib_workqueue, &priv->restart_task);
|
queue_work(ipoib_workqueue, &priv->restart_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ipoib_neigh_destructor(struct neighbour *n)
|
static void ipoib_neigh_cleanup(struct neighbour *n)
|
||||||
{
|
{
|
||||||
struct ipoib_neigh *neigh;
|
struct ipoib_neigh *neigh;
|
||||||
struct ipoib_dev_priv *priv = netdev_priv(n->dev);
|
struct ipoib_dev_priv *priv = netdev_priv(n->dev);
|
||||||
|
@ -822,7 +822,7 @@ static void ipoib_neigh_destructor(struct neighbour *n)
|
||||||
struct ipoib_ah *ah = NULL;
|
struct ipoib_ah *ah = NULL;
|
||||||
|
|
||||||
ipoib_dbg(priv,
|
ipoib_dbg(priv,
|
||||||
"neigh_destructor for %06x " IPOIB_GID_FMT "\n",
|
"neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
|
||||||
IPOIB_QPN(n->ha),
|
IPOIB_QPN(n->ha),
|
||||||
IPOIB_GID_RAW_ARG(n->ha + 4));
|
IPOIB_GID_RAW_ARG(n->ha + 4));
|
||||||
|
|
||||||
|
@ -874,7 +874,7 @@ void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh)
|
||||||
|
|
||||||
static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
|
static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
|
||||||
{
|
{
|
||||||
parms->neigh_destructor = ipoib_neigh_destructor;
|
parms->neigh_cleanup = ipoib_neigh_cleanup;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2544,6 +2544,9 @@ static void ppp_destroy_interface(struct ppp *ppp)
|
||||||
ppp->active_filter = NULL;
|
ppp->active_filter = NULL;
|
||||||
#endif /* CONFIG_PPP_FILTER */
|
#endif /* CONFIG_PPP_FILTER */
|
||||||
|
|
||||||
|
if (ppp->xmit_pending)
|
||||||
|
kfree_skb(ppp->xmit_pending);
|
||||||
|
|
||||||
kfree(ppp);
|
kfree(ppp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2530,6 +2530,35 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
|
||||||
return &gp->net_stats;
|
return &gp->net_stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gem_set_mac_address(struct net_device *dev, void *addr)
|
||||||
|
{
|
||||||
|
struct sockaddr *macaddr = (struct sockaddr *) addr;
|
||||||
|
struct gem *gp = dev->priv;
|
||||||
|
unsigned char *e = &dev->dev_addr[0];
|
||||||
|
|
||||||
|
if (!is_valid_ether_addr(macaddr->sa_data))
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
if (!netif_running(dev) || !netif_device_present(dev)) {
|
||||||
|
/* We'll just catch it later when the
|
||||||
|
* device is up'd or resumed.
|
||||||
|
*/
|
||||||
|
memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&gp->pm_mutex);
|
||||||
|
memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
|
||||||
|
if (gp->running) {
|
||||||
|
writel((e[4] << 8) | e[5], gp->regs + MAC_ADDR0);
|
||||||
|
writel((e[2] << 8) | e[3], gp->regs + MAC_ADDR1);
|
||||||
|
writel((e[0] << 8) | e[1], gp->regs + MAC_ADDR2);
|
||||||
|
}
|
||||||
|
mutex_unlock(&gp->pm_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void gem_set_multicast(struct net_device *dev)
|
static void gem_set_multicast(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct gem *gp = dev->priv;
|
struct gem *gp = dev->priv;
|
||||||
|
@ -3122,6 +3151,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
|
||||||
dev->change_mtu = gem_change_mtu;
|
dev->change_mtu = gem_change_mtu;
|
||||||
dev->irq = pdev->irq;
|
dev->irq = pdev->irq;
|
||||||
dev->dma = 0;
|
dev->dma = 0;
|
||||||
|
dev->set_mac_address = gem_set_mac_address;
|
||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
dev->poll_controller = gem_poll_controller;
|
dev->poll_controller = gem_poll_controller;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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.74"
|
#define DRV_MODULE_VERSION "3.75"
|
||||||
#define DRV_MODULE_RELDATE "February 20, 2007"
|
#define DRV_MODULE_RELDATE "March 23, 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
|
||||||
|
@ -3568,32 +3568,34 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
|
||||||
* Reading the PCI State register will confirm whether the
|
* Reading the PCI State register will confirm whether the
|
||||||
* interrupt is ours and will flush the status block.
|
* interrupt is ours and will flush the status block.
|
||||||
*/
|
*/
|
||||||
if ((sblk->status & SD_STATUS_UPDATED) ||
|
if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) {
|
||||||
!(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
|
if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
|
||||||
/*
|
(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
|
||||||
* Writing any value to intr-mbox-0 clears PCI INTA# and
|
handled = 0;
|
||||||
* chip-internal interrupt pending events.
|
|
||||||
* Writing non-zero to intr-mbox-0 additional tells the
|
|
||||||
* NIC to stop sending us irqs, engaging "in-intr-handler"
|
|
||||||
* event coalescing.
|
|
||||||
*/
|
|
||||||
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
|
||||||
0x00000001);
|
|
||||||
if (tg3_irq_sync(tp))
|
|
||||||
goto out;
|
goto out;
|
||||||
sblk->status &= ~SD_STATUS_UPDATED;
|
|
||||||
if (likely(tg3_has_work(tp))) {
|
|
||||||
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
|
|
||||||
netif_rx_schedule(dev); /* schedule NAPI poll */
|
|
||||||
} else {
|
|
||||||
/* No work, shared interrupt perhaps? re-enable
|
|
||||||
* interrupts, and flush that PCI write
|
|
||||||
*/
|
|
||||||
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
|
||||||
0x00000000);
|
|
||||||
}
|
}
|
||||||
} else { /* shared interrupt */
|
}
|
||||||
handled = 0;
|
|
||||||
|
/*
|
||||||
|
* Writing any value to intr-mbox-0 clears PCI INTA# and
|
||||||
|
* chip-internal interrupt pending events.
|
||||||
|
* Writing non-zero to intr-mbox-0 additional tells the
|
||||||
|
* NIC to stop sending us irqs, engaging "in-intr-handler"
|
||||||
|
* event coalescing.
|
||||||
|
*/
|
||||||
|
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
|
||||||
|
if (tg3_irq_sync(tp))
|
||||||
|
goto out;
|
||||||
|
sblk->status &= ~SD_STATUS_UPDATED;
|
||||||
|
if (likely(tg3_has_work(tp))) {
|
||||||
|
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
|
||||||
|
netif_rx_schedule(dev); /* schedule NAPI poll */
|
||||||
|
} else {
|
||||||
|
/* No work, shared interrupt perhaps? re-enable
|
||||||
|
* interrupts, and flush that PCI write
|
||||||
|
*/
|
||||||
|
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
||||||
|
0x00000000);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return IRQ_RETVAL(handled);
|
return IRQ_RETVAL(handled);
|
||||||
|
@ -3611,31 +3613,33 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
|
||||||
* Reading the PCI State register will confirm whether the
|
* Reading the PCI State register will confirm whether the
|
||||||
* interrupt is ours and will flush the status block.
|
* interrupt is ours and will flush the status block.
|
||||||
*/
|
*/
|
||||||
if ((sblk->status_tag != tp->last_tag) ||
|
if (unlikely(sblk->status_tag == tp->last_tag)) {
|
||||||
!(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
|
if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
|
||||||
/*
|
(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
|
||||||
* writing any value to intr-mbox-0 clears PCI INTA# and
|
handled = 0;
|
||||||
* chip-internal interrupt pending events.
|
|
||||||
* writing non-zero to intr-mbox-0 additional tells the
|
|
||||||
* NIC to stop sending us irqs, engaging "in-intr-handler"
|
|
||||||
* event coalescing.
|
|
||||||
*/
|
|
||||||
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
|
||||||
0x00000001);
|
|
||||||
if (tg3_irq_sync(tp))
|
|
||||||
goto out;
|
goto out;
|
||||||
if (netif_rx_schedule_prep(dev)) {
|
|
||||||
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
|
|
||||||
/* Update last_tag to mark that this status has been
|
|
||||||
* seen. Because interrupt may be shared, we may be
|
|
||||||
* racing with tg3_poll(), so only update last_tag
|
|
||||||
* if tg3_poll() is not scheduled.
|
|
||||||
*/
|
|
||||||
tp->last_tag = sblk->status_tag;
|
|
||||||
__netif_rx_schedule(dev);
|
|
||||||
}
|
}
|
||||||
} else { /* shared interrupt */
|
}
|
||||||
handled = 0;
|
|
||||||
|
/*
|
||||||
|
* writing any value to intr-mbox-0 clears PCI INTA# and
|
||||||
|
* chip-internal interrupt pending events.
|
||||||
|
* writing non-zero to intr-mbox-0 additional tells the
|
||||||
|
* NIC to stop sending us irqs, engaging "in-intr-handler"
|
||||||
|
* event coalescing.
|
||||||
|
*/
|
||||||
|
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
|
||||||
|
if (tg3_irq_sync(tp))
|
||||||
|
goto out;
|
||||||
|
if (netif_rx_schedule_prep(dev)) {
|
||||||
|
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
|
||||||
|
/* Update last_tag to mark that this status has been
|
||||||
|
* seen. Because interrupt may be shared, we may be
|
||||||
|
* racing with tg3_poll(), so only update last_tag
|
||||||
|
* if tg3_poll() is not scheduled.
|
||||||
|
*/
|
||||||
|
tp->last_tag = sblk->status_tag;
|
||||||
|
__netif_rx_schedule(dev);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return IRQ_RETVAL(handled);
|
return IRQ_RETVAL(handled);
|
||||||
|
@ -4823,6 +4827,19 @@ static int tg3_chip_reset(struct tg3 *tp)
|
||||||
if (write_op == tg3_write_flush_reg32)
|
if (write_op == tg3_write_flush_reg32)
|
||||||
tp->write32 = tg3_write32;
|
tp->write32 = tg3_write32;
|
||||||
|
|
||||||
|
/* Prevent the irq handler from reading or writing PCI registers
|
||||||
|
* during chip reset when the memory enable bit in the PCI command
|
||||||
|
* register may be cleared. The chip does not generate interrupt
|
||||||
|
* at this time, but the irq handler may still be called due to irq
|
||||||
|
* sharing or irqpoll.
|
||||||
|
*/
|
||||||
|
tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
|
||||||
|
tp->hw_status->status = 0;
|
||||||
|
tp->hw_status->status_tag = 0;
|
||||||
|
tp->last_tag = 0;
|
||||||
|
smp_mb();
|
||||||
|
synchronize_irq(tp->pdev->irq);
|
||||||
|
|
||||||
/* do the reset */
|
/* do the reset */
|
||||||
val = GRC_MISC_CFG_CORECLK_RESET;
|
val = GRC_MISC_CFG_CORECLK_RESET;
|
||||||
|
|
||||||
|
@ -4904,6 +4921,8 @@ static int tg3_chip_reset(struct tg3 *tp)
|
||||||
|
|
||||||
pci_restore_state(tp->pdev);
|
pci_restore_state(tp->pdev);
|
||||||
|
|
||||||
|
tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING;
|
||||||
|
|
||||||
/* Make sure PCI-X relaxed ordering bit is clear. */
|
/* Make sure PCI-X relaxed ordering bit is clear. */
|
||||||
pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
|
pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
|
||||||
val &= ~PCIX_CAPS_RELAXED_ORDERING;
|
val &= ~PCIX_CAPS_RELAXED_ORDERING;
|
||||||
|
@ -6321,8 +6340,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
|
||||||
RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
|
RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
|
||||||
RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
|
RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
|
||||||
RDMAC_MODE_LNGREAD_ENAB);
|
RDMAC_MODE_LNGREAD_ENAB);
|
||||||
if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
|
|
||||||
rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE;
|
|
||||||
|
|
||||||
/* If statement applies to 5705 and 5750 PCI devices only */
|
/* If statement applies to 5705 and 5750 PCI devices only */
|
||||||
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
|
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
|
||||||
|
@ -6495,9 +6512,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
|
||||||
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
|
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
|
||||||
val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
|
val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
|
||||||
val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
|
val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
|
||||||
if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
|
|
||||||
val |= (tp->split_mode_max_reqs <<
|
|
||||||
PCIX_CAPS_SPLIT_SHIFT);
|
|
||||||
}
|
}
|
||||||
tw32(TG3PCI_X_CAPS, val);
|
tw32(TG3PCI_X_CAPS, val);
|
||||||
}
|
}
|
||||||
|
@ -10863,14 +10877,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||||
grc_misc_cfg = tr32(GRC_MISC_CFG);
|
grc_misc_cfg = tr32(GRC_MISC_CFG);
|
||||||
grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
|
grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
|
||||||
|
|
||||||
/* Broadcom's driver says that CIOBE multisplit has a bug */
|
|
||||||
#if 0
|
|
||||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
|
|
||||||
grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
|
|
||||||
tp->tg3_flags |= TG3_FLAG_SPLIT_MODE;
|
|
||||||
tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
|
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
|
||||||
(grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
|
(grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
|
||||||
grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
|
grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
|
||||||
|
@ -11968,14 +11974,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
||||||
i == 5 ? '\n' : ':');
|
i == 5 ? '\n' : ':');
|
||||||
|
|
||||||
printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] "
|
printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] "
|
||||||
"MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] "
|
"MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n",
|
||||||
"TSOcap[%d] \n",
|
|
||||||
dev->name,
|
dev->name,
|
||||||
(tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
|
(tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
|
||||||
(tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
|
(tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
|
||||||
(tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
|
(tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
|
||||||
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
|
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
|
||||||
(tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0,
|
|
||||||
(tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
|
(tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
|
||||||
(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
|
(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
|
||||||
printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
|
printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
|
||||||
|
|
|
@ -2223,7 +2223,7 @@ struct tg3 {
|
||||||
#define TG3_FLAG_40BIT_DMA_BUG 0x08000000
|
#define TG3_FLAG_40BIT_DMA_BUG 0x08000000
|
||||||
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
|
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
|
||||||
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
|
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
|
||||||
#define TG3_FLAG_SPLIT_MODE 0x40000000
|
#define TG3_FLAG_CHIP_RESETTING 0x40000000
|
||||||
#define TG3_FLAG_INIT_COMPLETE 0x80000000
|
#define TG3_FLAG_INIT_COMPLETE 0x80000000
|
||||||
u32 tg3_flags2;
|
u32 tg3_flags2;
|
||||||
#define TG3_FLG2_RESTART_TIMER 0x00000001
|
#define TG3_FLG2_RESTART_TIMER 0x00000001
|
||||||
|
@ -2262,9 +2262,6 @@ struct tg3 {
|
||||||
#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000
|
#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000
|
||||||
#define TG3_FLG2_PHY_ADJUST_TRIM 0x80000000
|
#define TG3_FLG2_PHY_ADJUST_TRIM 0x80000000
|
||||||
|
|
||||||
u32 split_mode_max_reqs;
|
|
||||||
#define SPLIT_MODE_5704_MAX_REQ 3
|
|
||||||
|
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
u16 timer_counter;
|
u16 timer_counter;
|
||||||
u16 timer_multiplier;
|
u16 timer_multiplier;
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
#ifndef _LMC_MEDIA_H_
|
|
||||||
#define _LMC_MEDIA_H_
|
|
||||||
|
|
||||||
lmc_media_t lmc_ds3_media = {
|
|
||||||
lmc_ds3_init, /* special media init stuff */
|
|
||||||
lmc_ds3_default, /* reset to default state */
|
|
||||||
lmc_ds3_set_status, /* reset status to state provided */
|
|
||||||
lmc_dummy_set_1, /* set clock source */
|
|
||||||
lmc_dummy_set2_1, /* set line speed */
|
|
||||||
lmc_ds3_set_100ft, /* set cable length */
|
|
||||||
lmc_ds3_set_scram, /* set scrambler */
|
|
||||||
lmc_ds3_get_link_status, /* get link status */
|
|
||||||
lmc_dummy_set_1, /* set link status */
|
|
||||||
lmc_ds3_set_crc_length, /* set CRC length */
|
|
||||||
lmc_dummy_set_1, /* set T1 or E1 circuit type */
|
|
||||||
lmc_ds3_watchdog
|
|
||||||
};
|
|
||||||
|
|
||||||
lmc_media_t lmc_hssi_media = {
|
|
||||||
lmc_hssi_init, /* special media init stuff */
|
|
||||||
lmc_hssi_default, /* reset to default state */
|
|
||||||
lmc_hssi_set_status, /* reset status to state provided */
|
|
||||||
lmc_hssi_set_clock, /* set clock source */
|
|
||||||
lmc_dummy_set2_1, /* set line speed */
|
|
||||||
lmc_dummy_set_1, /* set cable length */
|
|
||||||
lmc_dummy_set_1, /* set scrambler */
|
|
||||||
lmc_hssi_get_link_status, /* get link status */
|
|
||||||
lmc_hssi_set_link_status, /* set link status */
|
|
||||||
lmc_hssi_set_crc_length, /* set CRC length */
|
|
||||||
lmc_dummy_set_1, /* set T1 or E1 circuit type */
|
|
||||||
lmc_hssi_watchdog
|
|
||||||
};
|
|
||||||
|
|
||||||
lmc_media_t lmc_ssi_media = { lmc_ssi_init, /* special media init stuff */
|
|
||||||
lmc_ssi_default, /* reset to default state */
|
|
||||||
lmc_ssi_set_status, /* reset status to state provided */
|
|
||||||
lmc_ssi_set_clock, /* set clock source */
|
|
||||||
lmc_ssi_set_speed, /* set line speed */
|
|
||||||
lmc_dummy_set_1, /* set cable length */
|
|
||||||
lmc_dummy_set_1, /* set scrambler */
|
|
||||||
lmc_ssi_get_link_status, /* get link status */
|
|
||||||
lmc_ssi_set_link_status, /* set link status */
|
|
||||||
lmc_ssi_set_crc_length, /* set CRC length */
|
|
||||||
lmc_dummy_set_1, /* set T1 or E1 circuit type */
|
|
||||||
lmc_ssi_watchdog
|
|
||||||
};
|
|
||||||
|
|
||||||
lmc_media_t lmc_t1_media = {
|
|
||||||
lmc_t1_init, /* special media init stuff */
|
|
||||||
lmc_t1_default, /* reset to default state */
|
|
||||||
lmc_t1_set_status, /* reset status to state provided */
|
|
||||||
lmc_t1_set_clock, /* set clock source */
|
|
||||||
lmc_dummy_set2_1, /* set line speed */
|
|
||||||
lmc_dummy_set_1, /* set cable length */
|
|
||||||
lmc_dummy_set_1, /* set scrambler */
|
|
||||||
lmc_t1_get_link_status, /* get link status */
|
|
||||||
lmc_dummy_set_1, /* set link status */
|
|
||||||
lmc_t1_set_crc_length, /* set CRC length */
|
|
||||||
lmc_t1_set_circuit_type, /* set T1 or E1 circuit type */
|
|
||||||
lmc_t1_watchdog
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct fib_rules_ops
|
||||||
int family;
|
int family;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
int rule_size;
|
int rule_size;
|
||||||
|
int addr_size;
|
||||||
|
|
||||||
int (*action)(struct fib_rule *,
|
int (*action)(struct fib_rule *,
|
||||||
struct flowi *, int,
|
struct flowi *, int,
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct fib6_node
|
||||||
__u16 fn_bit; /* bit key */
|
__u16 fn_bit; /* bit key */
|
||||||
__u16 fn_flags;
|
__u16 fn_flags;
|
||||||
__u32 fn_sernum;
|
__u32 fn_sernum;
|
||||||
|
struct rt6_info *rr_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef CONFIG_IPV6_SUBTREES
|
#ifndef CONFIG_IPV6_SUBTREES
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct neigh_parms
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct neigh_parms *next;
|
struct neigh_parms *next;
|
||||||
int (*neigh_setup)(struct neighbour *);
|
int (*neigh_setup)(struct neighbour *);
|
||||||
void (*neigh_destructor)(struct neighbour *);
|
void (*neigh_cleanup)(struct neighbour *);
|
||||||
struct neigh_table *tbl;
|
struct neigh_table *tbl;
|
||||||
|
|
||||||
void *sysctl_table;
|
void *sysctl_table;
|
||||||
|
|
|
@ -261,14 +261,6 @@ static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||||
spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
|
spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clip_neigh_destroy(struct neighbour *neigh)
|
|
||||||
{
|
|
||||||
DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh);
|
|
||||||
if (NEIGH2ENTRY(neigh)->vccs)
|
|
||||||
printk(KERN_CRIT "clip_neigh_destroy: vccs != NULL !!!\n");
|
|
||||||
NEIGH2ENTRY(neigh)->vccs = (void *) NEIGHBOR_DEAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
|
static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb);
|
DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb);
|
||||||
|
@ -342,7 +334,6 @@ static struct neigh_table clip_tbl = {
|
||||||
/* parameters are copied from ARP ... */
|
/* parameters are copied from ARP ... */
|
||||||
.parms = {
|
.parms = {
|
||||||
.tbl = &clip_tbl,
|
.tbl = &clip_tbl,
|
||||||
.neigh_destructor = clip_neigh_destroy,
|
|
||||||
.base_reachable_time = 30 * HZ,
|
.base_reachable_time = 30 * HZ,
|
||||||
.retrans_time = 1 * HZ,
|
.retrans_time = 1 * HZ,
|
||||||
.gc_staletime = 60 * HZ,
|
.gc_staletime = 60 * HZ,
|
||||||
|
|
|
@ -1,30 +1,27 @@
|
||||||
#
|
#
|
||||||
# Amateur Radio protocols and AX.25 device configuration
|
# Amateur Radio protocols and AX.25 device configuration
|
||||||
#
|
#
|
||||||
# 19971130 Now in an own category to make correct compilation of the
|
|
||||||
# AX.25 stuff easier...
|
|
||||||
# Joerg Reuter DL1BKE <jreuter@yaina.de>
|
|
||||||
# 19980129 Moved to net/ax25/Config.in, sourcing device drivers.
|
|
||||||
|
|
||||||
menuconfig HAMRADIO
|
menuconfig HAMRADIO
|
||||||
depends on NET
|
depends on NET
|
||||||
bool "Amateur Radio support"
|
bool "Amateur Radio support"
|
||||||
help
|
help
|
||||||
If you want to connect your Linux box to an amateur radio, answer Y
|
If you want to connect your Linux box to an amateur radio, answer Y
|
||||||
here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> and
|
here. You want to read <http://www.tapr.org/tapr/html/pkthome.html>
|
||||||
the AX25-HOWTO, available from <http://www.tldp.org/docs.html#howto>.
|
and more specifically about AX.25 on Linux
|
||||||
|
<http://www.linux-ax25.org/>.
|
||||||
|
|
||||||
Note that the answer to this question won't directly affect the
|
Note that the answer to this question won't directly affect the
|
||||||
kernel: saying N will just cause the configurator to skip all
|
kernel: saying N will just cause the configurator to skip all
|
||||||
the questions about amateur radio.
|
the questions about amateur radio.
|
||||||
|
|
||||||
comment "Packet Radio protocols"
|
comment "Packet Radio protocols"
|
||||||
depends on HAMRADIO && NET
|
depends on HAMRADIO
|
||||||
|
|
||||||
config AX25
|
config AX25
|
||||||
tristate "Amateur Radio AX.25 Level 2 protocol"
|
tristate "Amateur Radio AX.25 Level 2 protocol"
|
||||||
depends on HAMRADIO && NET
|
depends on HAMRADIO
|
||||||
---help---
|
help
|
||||||
This is the protocol used for computer communication over amateur
|
This is the protocol used for computer communication over amateur
|
||||||
radio. It is either used by itself for point-to-point links, or to
|
radio. It is either used by itself for point-to-point links, or to
|
||||||
carry other protocols such as tcp/ip. To use it, you need a device
|
carry other protocols such as tcp/ip. To use it, you need a device
|
||||||
|
@ -52,6 +49,7 @@ config AX25
|
||||||
|
|
||||||
config AX25_DAMA_SLAVE
|
config AX25_DAMA_SLAVE
|
||||||
bool "AX.25 DAMA Slave support"
|
bool "AX.25 DAMA Slave support"
|
||||||
|
default y
|
||||||
depends on AX25
|
depends on AX25
|
||||||
help
|
help
|
||||||
DAMA is a mechanism to prevent collisions when doing AX.25
|
DAMA is a mechanism to prevent collisions when doing AX.25
|
||||||
|
@ -59,23 +57,38 @@ config AX25_DAMA_SLAVE
|
||||||
from clients (called "slaves") and redistributes it to other slaves.
|
from clients (called "slaves") and redistributes it to other slaves.
|
||||||
If you say Y here, your Linux box will act as a DAMA slave; this is
|
If you say Y here, your Linux box will act as a DAMA slave; this is
|
||||||
transparent in that you don't have to do any special DAMA
|
transparent in that you don't have to do any special DAMA
|
||||||
configuration. (Linux cannot yet act as a DAMA server.) If unsure,
|
configuration. Linux cannot yet act as a DAMA server. This option
|
||||||
say N.
|
only compiles DAMA slave support into the kernel. It still needs to
|
||||||
|
be enabled at runtime. For more about DAMA see
|
||||||
|
<http://www.linux-ax25.org>. If unsure, say Y.
|
||||||
|
|
||||||
|
# placeholder until implemented
|
||||||
|
config AX25_DAMA_MASTER
|
||||||
|
bool 'AX.25 DAMA Master support'
|
||||||
|
depends on AX25_DAMA_SLAVE && BROKEN
|
||||||
|
help
|
||||||
|
DAMA is a mechanism to prevent collisions when doing AX.25
|
||||||
|
networking. A DAMA server (called "master") accepts incoming traffic
|
||||||
|
from clients (called "slaves") and redistributes it to other slaves.
|
||||||
|
If you say Y here, your Linux box will act as a DAMA master; this is
|
||||||
|
transparent in that you don't have to do any special DAMA
|
||||||
|
configuration. Linux cannot yet act as a DAMA server. This option
|
||||||
|
only compiles DAMA slave support into the kernel. It still needs to
|
||||||
|
be explicitly enabled, so if unsure, say Y.
|
||||||
|
|
||||||
# bool ' AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER
|
|
||||||
config NETROM
|
config NETROM
|
||||||
tristate "Amateur Radio NET/ROM protocol"
|
tristate "Amateur Radio NET/ROM protocol"
|
||||||
depends on AX25
|
depends on AX25
|
||||||
---help---
|
help
|
||||||
NET/ROM is a network layer protocol on top of AX.25 useful for
|
NET/ROM is a network layer protocol on top of AX.25 useful for
|
||||||
routing.
|
routing.
|
||||||
|
|
||||||
A comprehensive listing of all the software for Linux amateur radio
|
A comprehensive listing of all the software for Linux amateur radio
|
||||||
users as well as information about how to configure an AX.25 port is
|
users as well as information about how to configure an AX.25 port is
|
||||||
contained in the AX25-HOWTO, available from
|
contained in the Linux Ham Wiki, available from
|
||||||
<http://www.tldp.org/docs.html#howto>. You also might want to
|
<http://www.linux-ax25.org>. You also might want to check out the
|
||||||
check out the file <file:Documentation/networking/ax25.txt>. More
|
file <file:Documentation/networking/ax25.txt>. More information about
|
||||||
information about digital amateur radio in general is on the WWW at
|
digital amateur radio in general is on the WWW at
|
||||||
<http://www.tapr.org/tapr/html/pkthome.html>.
|
<http://www.tapr.org/tapr/html/pkthome.html>.
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
|
@ -84,27 +97,25 @@ config NETROM
|
||||||
config ROSE
|
config ROSE
|
||||||
tristate "Amateur Radio X.25 PLP (Rose)"
|
tristate "Amateur Radio X.25 PLP (Rose)"
|
||||||
depends on AX25
|
depends on AX25
|
||||||
---help---
|
help
|
||||||
The Packet Layer Protocol (PLP) is a way to route packets over X.25
|
The Packet Layer Protocol (PLP) is a way to route packets over X.25
|
||||||
connections in general and amateur radio AX.25 connections in
|
connections in general and amateur radio AX.25 connections in
|
||||||
particular, essentially an alternative to NET/ROM.
|
particular, essentially an alternative to NET/ROM.
|
||||||
|
|
||||||
A comprehensive listing of all the software for Linux amateur radio
|
A comprehensive listing of all the software for Linux amateur radio
|
||||||
users as well as information about how to configure an AX.25 port is
|
users as well as information about how to configure an AX.25 port is
|
||||||
contained in the AX25-HOWTO, available from
|
contained in the Linux Ham Wiki, available from
|
||||||
<http://www.tldp.org/docs.html#howto>. You also might want to
|
<http://www.linux-ax25.org>. You also might want to check out the
|
||||||
check out the file <file:Documentation/networking/ax25.txt>. More
|
file <file:Documentation/networking/ax25.txt>. More information about
|
||||||
information about digital amateur radio in general is on the WWW at
|
digital amateur radio in general is on the WWW at
|
||||||
<http://www.tapr.org/tapr/html/pkthome.html>.
|
<http://www.tapr.org/tapr/html/pkthome.html>.
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called rose.
|
module will be called rose.
|
||||||
|
|
||||||
|
|
||||||
menu "AX.25 network device drivers"
|
menu "AX.25 network device drivers"
|
||||||
depends on HAMRADIO && NET && AX25!=n
|
depends on HAMRADIO && AX25
|
||||||
|
|
||||||
source "drivers/net/hamradio/Kconfig"
|
source "drivers/net/hamradio/Kconfig"
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
|
|
@ -1750,10 +1750,10 @@ static int ing_filter(struct sk_buff *skb)
|
||||||
|
|
||||||
skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS);
|
skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS);
|
||||||
|
|
||||||
spin_lock(&dev->ingress_lock);
|
spin_lock(&dev->queue_lock);
|
||||||
if ((q = dev->qdisc_ingress) != NULL)
|
if ((q = dev->qdisc_ingress) != NULL)
|
||||||
result = q->enqueue(skb, q);
|
result = q->enqueue(skb, q);
|
||||||
spin_unlock(&dev->ingress_lock);
|
spin_unlock(&dev->queue_lock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,28 @@ out:
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(fib_rules_lookup);
|
EXPORT_SYMBOL_GPL(fib_rules_lookup);
|
||||||
|
|
||||||
|
static int validate_rulemsg(struct fib_rule_hdr *frh, struct nlattr **tb,
|
||||||
|
struct fib_rules_ops *ops)
|
||||||
|
{
|
||||||
|
int err = -EINVAL;
|
||||||
|
|
||||||
|
if (frh->src_len)
|
||||||
|
if (tb[FRA_SRC] == NULL ||
|
||||||
|
frh->src_len > (ops->addr_size * 8) ||
|
||||||
|
nla_len(tb[FRA_SRC]) != ops->addr_size)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
|
if (frh->dst_len)
|
||||||
|
if (tb[FRA_DST] == NULL ||
|
||||||
|
frh->dst_len > (ops->addr_size * 8) ||
|
||||||
|
nla_len(tb[FRA_DST]) != ops->addr_size)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
errout:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||||
{
|
{
|
||||||
struct fib_rule_hdr *frh = nlmsg_data(nlh);
|
struct fib_rule_hdr *frh = nlmsg_data(nlh);
|
||||||
|
@ -173,6 +195,10 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
|
err = validate_rulemsg(frh, tb, ops);
|
||||||
|
if (err < 0)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
rule = kzalloc(ops->rule_size, GFP_KERNEL);
|
rule = kzalloc(ops->rule_size, GFP_KERNEL);
|
||||||
if (rule == NULL) {
|
if (rule == NULL) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
@ -260,6 +286,10 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
|
err = validate_rulemsg(frh, tb, ops);
|
||||||
|
if (err < 0)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
list_for_each_entry(rule, ops->rules_list, list) {
|
list_for_each_entry(rule, ops->rules_list, list) {
|
||||||
if (frh->action && (frh->action != rule->action))
|
if (frh->action && (frh->action != rule->action))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -140,6 +140,8 @@ static int neigh_forced_gc(struct neigh_table *tbl)
|
||||||
n->dead = 1;
|
n->dead = 1;
|
||||||
shrunk = 1;
|
shrunk = 1;
|
||||||
write_unlock(&n->lock);
|
write_unlock(&n->lock);
|
||||||
|
if (n->parms->neigh_cleanup)
|
||||||
|
n->parms->neigh_cleanup(n);
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -211,6 +213,8 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
|
||||||
NEIGH_PRINTK2("neigh %p is stray.\n", n);
|
NEIGH_PRINTK2("neigh %p is stray.\n", n);
|
||||||
}
|
}
|
||||||
write_unlock(&n->lock);
|
write_unlock(&n->lock);
|
||||||
|
if (n->parms->neigh_cleanup)
|
||||||
|
n->parms->neigh_cleanup(n);
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,9 +586,6 @@ void neigh_destroy(struct neighbour *neigh)
|
||||||
kfree(hh);
|
kfree(hh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neigh->parms->neigh_destructor)
|
|
||||||
(neigh->parms->neigh_destructor)(neigh);
|
|
||||||
|
|
||||||
skb_queue_purge(&neigh->arp_queue);
|
skb_queue_purge(&neigh->arp_queue);
|
||||||
|
|
||||||
dev_put(neigh->dev);
|
dev_put(neigh->dev);
|
||||||
|
@ -675,6 +676,8 @@ static void neigh_periodic_timer(unsigned long arg)
|
||||||
*np = n->next;
|
*np = n->next;
|
||||||
n->dead = 1;
|
n->dead = 1;
|
||||||
write_unlock(&n->lock);
|
write_unlock(&n->lock);
|
||||||
|
if (n->parms->neigh_cleanup)
|
||||||
|
n->parms->neigh_cleanup(n);
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2088,8 +2091,11 @@ void __neigh_for_each_release(struct neigh_table *tbl,
|
||||||
} else
|
} else
|
||||||
np = &n->next;
|
np = &n->next;
|
||||||
write_unlock(&n->lock);
|
write_unlock(&n->lock);
|
||||||
if (release)
|
if (release) {
|
||||||
|
if (n->parms->neigh_cleanup)
|
||||||
|
n->parms->neigh_cleanup(n);
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,6 @@ extern void dccp_send_sync(struct sock *sk, const u64 seq,
|
||||||
const enum dccp_pkt_type pkt_type);
|
const enum dccp_pkt_type pkt_type);
|
||||||
|
|
||||||
extern void dccp_write_xmit(struct sock *sk, int block);
|
extern void dccp_write_xmit(struct sock *sk, int block);
|
||||||
extern void dccp_write_xmit_timer(unsigned long data);
|
|
||||||
extern void dccp_write_space(struct sock *sk);
|
extern void dccp_write_space(struct sock *sk);
|
||||||
|
|
||||||
extern void dccp_init_xmit_timers(struct sock *sk);
|
extern void dccp_init_xmit_timers(struct sock *sk);
|
||||||
|
|
|
@ -262,7 +262,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transmit-delay timer: used by the CCIDs to delay actual send time */
|
/* Transmit-delay timer: used by the CCIDs to delay actual send time */
|
||||||
void dccp_write_xmit_timer(unsigned long data)
|
static void dccp_write_xmit_timer(unsigned long data)
|
||||||
{
|
{
|
||||||
struct sock *sk = (struct sock *)data;
|
struct sock *sk = (struct sock *)data;
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
struct dccp_sock *dp = dccp_sk(sk);
|
||||||
|
|
|
@ -63,7 +63,7 @@ static struct
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 scope;
|
u8 scope;
|
||||||
} dn_fib_props[RTA_MAX+1] = {
|
} dn_fib_props[RTN_MAX+1] = {
|
||||||
[RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE },
|
[RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE },
|
||||||
[RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE },
|
[RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE },
|
||||||
[RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST },
|
[RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST },
|
||||||
|
@ -276,6 +276,9 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta
|
||||||
struct dn_fib_info *ofi;
|
struct dn_fib_info *ofi;
|
||||||
int nhs = 1;
|
int nhs = 1;
|
||||||
|
|
||||||
|
if (r->rtm_type > RTN_MAX)
|
||||||
|
goto err_inval;
|
||||||
|
|
||||||
if (dn_fib_props[r->rtm_type].scope > r->rtm_scope)
|
if (dn_fib_props[r->rtm_type].scope > r->rtm_scope)
|
||||||
goto err_inval;
|
goto err_inval;
|
||||||
|
|
||||||
|
|
|
@ -109,8 +109,6 @@ errout:
|
||||||
|
|
||||||
static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = {
|
static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = {
|
||||||
FRA_GENERIC_POLICY,
|
FRA_GENERIC_POLICY,
|
||||||
[FRA_SRC] = { .type = NLA_U16 },
|
|
||||||
[FRA_DST] = { .type = NLA_U16 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
|
static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
|
||||||
|
@ -133,7 +131,7 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
|
||||||
int err = -EINVAL;
|
int err = -EINVAL;
|
||||||
struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
|
struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
|
||||||
|
|
||||||
if (frh->src_len > 16 || frh->dst_len > 16 || frh->tos)
|
if (frh->tos)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
if (rule->table == RT_TABLE_UNSPEC) {
|
if (rule->table == RT_TABLE_UNSPEC) {
|
||||||
|
@ -150,10 +148,10 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb[FRA_SRC])
|
if (frh->src_len)
|
||||||
r->src = nla_get_le16(tb[FRA_SRC]);
|
r->src = nla_get_le16(tb[FRA_SRC]);
|
||||||
|
|
||||||
if (tb[FRA_DST])
|
if (frh->dst_len)
|
||||||
r->dst = nla_get_le16(tb[FRA_DST]);
|
r->dst = nla_get_le16(tb[FRA_DST]);
|
||||||
|
|
||||||
r->src_len = frh->src_len;
|
r->src_len = frh->src_len;
|
||||||
|
@ -176,10 +174,10 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
|
||||||
if (frh->dst_len && (r->dst_len != frh->dst_len))
|
if (frh->dst_len && (r->dst_len != frh->dst_len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (tb[FRA_SRC] && (r->src != nla_get_le16(tb[FRA_SRC])))
|
if (frh->src_len && (r->src != nla_get_le16(tb[FRA_SRC])))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (tb[FRA_DST] && (r->dst != nla_get_le16(tb[FRA_DST])))
|
if (frh->dst_len && (r->dst != nla_get_le16(tb[FRA_DST])))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -249,6 +247,7 @@ int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
static struct fib_rules_ops dn_fib_rules_ops = {
|
static struct fib_rules_ops dn_fib_rules_ops = {
|
||||||
.family = AF_DECnet,
|
.family = AF_DECnet,
|
||||||
.rule_size = sizeof(struct dn_fib_rule),
|
.rule_size = sizeof(struct dn_fib_rule),
|
||||||
|
.addr_size = sizeof(u16),
|
||||||
.action = dn_fib_rule_action,
|
.action = dn_fib_rule_action,
|
||||||
.match = dn_fib_rule_match,
|
.match = dn_fib_rule_match,
|
||||||
.configure = dn_fib_rule_configure,
|
.configure = dn_fib_rule_configure,
|
||||||
|
|
|
@ -493,6 +493,11 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
|
cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
|
||||||
cfg->fc_nlinfo.nlh = nlh;
|
cfg->fc_nlinfo.nlh = nlh;
|
||||||
|
|
||||||
|
if (cfg->fc_type > RTN_MAX) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {
|
nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {
|
||||||
switch (attr->nla_type) {
|
switch (attr->nla_type) {
|
||||||
case RTA_DST:
|
case RTA_DST:
|
||||||
|
|
|
@ -171,8 +171,6 @@ static struct fib_table *fib_empty_table(void)
|
||||||
|
|
||||||
static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = {
|
static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = {
|
||||||
FRA_GENERIC_POLICY,
|
FRA_GENERIC_POLICY,
|
||||||
[FRA_SRC] = { .type = NLA_U32 },
|
|
||||||
[FRA_DST] = { .type = NLA_U32 },
|
|
||||||
[FRA_FLOW] = { .type = NLA_U32 },
|
[FRA_FLOW] = { .type = NLA_U32 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,8 +181,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
|
||||||
int err = -EINVAL;
|
int err = -EINVAL;
|
||||||
struct fib4_rule *rule4 = (struct fib4_rule *) rule;
|
struct fib4_rule *rule4 = (struct fib4_rule *) rule;
|
||||||
|
|
||||||
if (frh->src_len > 32 || frh->dst_len > 32 ||
|
if (frh->tos & ~IPTOS_TOS_MASK)
|
||||||
(frh->tos & ~IPTOS_TOS_MASK))
|
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
if (rule->table == RT_TABLE_UNSPEC) {
|
if (rule->table == RT_TABLE_UNSPEC) {
|
||||||
|
@ -201,10 +198,10 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb[FRA_SRC])
|
if (frh->src_len)
|
||||||
rule4->src = nla_get_be32(tb[FRA_SRC]);
|
rule4->src = nla_get_be32(tb[FRA_SRC]);
|
||||||
|
|
||||||
if (tb[FRA_DST])
|
if (frh->dst_len)
|
||||||
rule4->dst = nla_get_be32(tb[FRA_DST]);
|
rule4->dst = nla_get_be32(tb[FRA_DST]);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_CLS_ROUTE
|
#ifdef CONFIG_NET_CLS_ROUTE
|
||||||
|
@ -242,10 +239,10 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (tb[FRA_SRC] && (rule4->src != nla_get_be32(tb[FRA_SRC])))
|
if (frh->src_len && (rule4->src != nla_get_be32(tb[FRA_SRC])))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (tb[FRA_DST] && (rule4->dst != nla_get_be32(tb[FRA_DST])))
|
if (frh->dst_len && (rule4->dst != nla_get_be32(tb[FRA_DST])))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -309,6 +306,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
|
||||||
static struct fib_rules_ops fib4_rules_ops = {
|
static struct fib_rules_ops fib4_rules_ops = {
|
||||||
.family = AF_INET,
|
.family = AF_INET,
|
||||||
.rule_size = sizeof(struct fib4_rule),
|
.rule_size = sizeof(struct fib4_rule),
|
||||||
|
.addr_size = sizeof(u32),
|
||||||
.action = fib4_rule_action,
|
.action = fib4_rule_action,
|
||||||
.match = fib4_rule_match,
|
.match = fib4_rule_match,
|
||||||
.configure = fib4_rule_configure,
|
.configure = fib4_rule_configure,
|
||||||
|
|
|
@ -89,7 +89,7 @@ static const struct
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 scope;
|
u8 scope;
|
||||||
} fib_props[RTA_MAX + 1] = {
|
} fib_props[RTN_MAX + 1] = {
|
||||||
{
|
{
|
||||||
.error = 0,
|
.error = 0,
|
||||||
.scope = RT_SCOPE_NOWHERE,
|
.scope = RT_SCOPE_NOWHERE,
|
||||||
|
|
|
@ -1123,6 +1123,9 @@ err:
|
||||||
return fa_head;
|
return fa_head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Caller must hold RTNL.
|
||||||
|
*/
|
||||||
static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
|
static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
|
||||||
{
|
{
|
||||||
struct trie *t = (struct trie *) tb->tb_data;
|
struct trie *t = (struct trie *) tb->tb_data;
|
||||||
|
@ -1540,6 +1543,9 @@ static int trie_leaf_remove(struct trie *t, t_key key)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Caller must hold RTNL.
|
||||||
|
*/
|
||||||
static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
|
static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
|
||||||
{
|
{
|
||||||
struct trie *t = (struct trie *) tb->tb_data;
|
struct trie *t = (struct trie *) tb->tb_data;
|
||||||
|
@ -1718,6 +1724,9 @@ up:
|
||||||
return NULL; /* Ready. Root of trie */
|
return NULL; /* Ready. Root of trie */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Caller must hold RTNL.
|
||||||
|
*/
|
||||||
static int fn_trie_flush(struct fib_table *tb)
|
static int fn_trie_flush(struct fib_table *tb)
|
||||||
{
|
{
|
||||||
struct trie *t = (struct trie *) tb->tb_data;
|
struct trie *t = (struct trie *) tb->tb_data;
|
||||||
|
|
|
@ -131,8 +131,6 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
|
||||||
|
|
||||||
static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
|
static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
|
||||||
FRA_GENERIC_POLICY,
|
FRA_GENERIC_POLICY,
|
||||||
[FRA_SRC] = { .len = sizeof(struct in6_addr) },
|
|
||||||
[FRA_DST] = { .len = sizeof(struct in6_addr) },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
|
static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
|
||||||
|
@ -142,9 +140,6 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
|
||||||
int err = -EINVAL;
|
int err = -EINVAL;
|
||||||
struct fib6_rule *rule6 = (struct fib6_rule *) rule;
|
struct fib6_rule *rule6 = (struct fib6_rule *) rule;
|
||||||
|
|
||||||
if (frh->src_len > 128 || frh->dst_len > 128)
|
|
||||||
goto errout;
|
|
||||||
|
|
||||||
if (rule->action == FR_ACT_TO_TBL) {
|
if (rule->action == FR_ACT_TO_TBL) {
|
||||||
if (rule->table == RT6_TABLE_UNSPEC)
|
if (rule->table == RT6_TABLE_UNSPEC)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
@ -155,11 +150,11 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb[FRA_SRC])
|
if (frh->src_len)
|
||||||
nla_memcpy(&rule6->src.addr, tb[FRA_SRC],
|
nla_memcpy(&rule6->src.addr, tb[FRA_SRC],
|
||||||
sizeof(struct in6_addr));
|
sizeof(struct in6_addr));
|
||||||
|
|
||||||
if (tb[FRA_DST])
|
if (frh->dst_len)
|
||||||
nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
|
nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
|
||||||
sizeof(struct in6_addr));
|
sizeof(struct in6_addr));
|
||||||
|
|
||||||
|
@ -186,11 +181,11 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
|
||||||
if (frh->tos && (rule6->tclass != frh->tos))
|
if (frh->tos && (rule6->tclass != frh->tos))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (tb[FRA_SRC] &&
|
if (frh->src_len &&
|
||||||
nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr)))
|
nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (tb[FRA_DST] &&
|
if (frh->dst_len &&
|
||||||
nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
|
nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -240,6 +235,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
|
||||||
static struct fib_rules_ops fib6_rules_ops = {
|
static struct fib_rules_ops fib6_rules_ops = {
|
||||||
.family = AF_INET6,
|
.family = AF_INET6,
|
||||||
.rule_size = sizeof(struct fib6_rule),
|
.rule_size = sizeof(struct fib6_rule),
|
||||||
|
.addr_size = sizeof(struct in6_addr),
|
||||||
.action = fib6_rule_action,
|
.action = fib6_rule_action,
|
||||||
.match = fib6_rule_match,
|
.match = fib6_rule_match,
|
||||||
.configure = fib6_rule_configure,
|
.configure = fib6_rule_configure,
|
||||||
|
|
|
@ -658,6 +658,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
||||||
ins = &iter->u.dst.rt6_next;
|
ins = &iter->u.dst.rt6_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset round-robin state, if necessary */
|
||||||
|
if (ins == &fn->leaf)
|
||||||
|
fn->rr_ptr = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* insert node
|
* insert node
|
||||||
*/
|
*/
|
||||||
|
@ -1109,6 +1113,10 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
|
||||||
rt6_stats.fib_rt_entries--;
|
rt6_stats.fib_rt_entries--;
|
||||||
rt6_stats.fib_discarded_routes++;
|
rt6_stats.fib_discarded_routes++;
|
||||||
|
|
||||||
|
/* Reset round-robin state, if necessary */
|
||||||
|
if (fn->rr_ptr == rt)
|
||||||
|
fn->rr_ptr = NULL;
|
||||||
|
|
||||||
/* Adjust walkers */
|
/* Adjust walkers */
|
||||||
read_lock(&fib6_walker_lock);
|
read_lock(&fib6_walker_lock);
|
||||||
FOR_WALKERS(w) {
|
FOR_WALKERS(w) {
|
||||||
|
|
|
@ -363,55 +363,76 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rt6_info *rt6_select(struct rt6_info **head, int oif,
|
static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict,
|
||||||
int strict)
|
int *mpri, struct rt6_info *match)
|
||||||
{
|
{
|
||||||
struct rt6_info *match = NULL, *last = NULL;
|
int m;
|
||||||
struct rt6_info *rt, *rt0 = *head;
|
|
||||||
u32 metric;
|
if (rt6_check_expired(rt))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
m = rt6_score_route(rt, oif, strict);
|
||||||
|
if (m < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (m > *mpri) {
|
||||||
|
if (strict & RT6_LOOKUP_F_REACHABLE)
|
||||||
|
rt6_probe(match);
|
||||||
|
*mpri = m;
|
||||||
|
match = rt;
|
||||||
|
} else if (strict & RT6_LOOKUP_F_REACHABLE) {
|
||||||
|
rt6_probe(rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
|
||||||
|
struct rt6_info *rr_head,
|
||||||
|
u32 metric, int oif, int strict)
|
||||||
|
{
|
||||||
|
struct rt6_info *rt, *match;
|
||||||
int mpri = -1;
|
int mpri = -1;
|
||||||
|
|
||||||
RT6_TRACE("%s(head=%p(*head=%p), oif=%d)\n",
|
match = NULL;
|
||||||
__FUNCTION__, head, head ? *head : NULL, oif);
|
for (rt = rr_head; rt && rt->rt6i_metric == metric;
|
||||||
|
rt = rt->u.dst.rt6_next)
|
||||||
|
match = find_match(rt, oif, strict, &mpri, match);
|
||||||
|
for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric;
|
||||||
|
rt = rt->u.dst.rt6_next)
|
||||||
|
match = find_match(rt, oif, strict, &mpri, match);
|
||||||
|
|
||||||
for (rt = rt0, metric = rt0->rt6i_metric;
|
return match;
|
||||||
rt && rt->rt6i_metric == metric && (!last || rt != rt0);
|
}
|
||||||
rt = rt->u.dst.rt6_next) {
|
|
||||||
int m;
|
|
||||||
|
|
||||||
if (rt6_check_expired(rt))
|
static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
|
||||||
continue;
|
{
|
||||||
|
struct rt6_info *match, *rt0;
|
||||||
|
|
||||||
last = rt;
|
RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n",
|
||||||
|
__FUNCTION__, fn->leaf, oif);
|
||||||
|
|
||||||
m = rt6_score_route(rt, oif, strict);
|
rt0 = fn->rr_ptr;
|
||||||
if (m < 0)
|
if (!rt0)
|
||||||
continue;
|
fn->rr_ptr = rt0 = fn->leaf;
|
||||||
|
|
||||||
if (m > mpri) {
|
match = find_rr_leaf(fn, rt0, rt0->rt6i_metric, oif, strict);
|
||||||
if (strict & RT6_LOOKUP_F_REACHABLE)
|
|
||||||
rt6_probe(match);
|
|
||||||
match = rt;
|
|
||||||
mpri = m;
|
|
||||||
} else if (strict & RT6_LOOKUP_F_REACHABLE) {
|
|
||||||
rt6_probe(rt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!match &&
|
if (!match &&
|
||||||
(strict & RT6_LOOKUP_F_REACHABLE) &&
|
(strict & RT6_LOOKUP_F_REACHABLE)) {
|
||||||
last && last != rt0) {
|
struct rt6_info *next = rt0->u.dst.rt6_next;
|
||||||
|
|
||||||
/* no entries matched; do round-robin */
|
/* no entries matched; do round-robin */
|
||||||
static DEFINE_SPINLOCK(lock);
|
if (!next || next->rt6i_metric != rt0->rt6i_metric)
|
||||||
spin_lock(&lock);
|
next = fn->leaf;
|
||||||
*head = rt0->u.dst.rt6_next;
|
|
||||||
rt0->u.dst.rt6_next = last->u.dst.rt6_next;
|
if (next != rt0)
|
||||||
last->u.dst.rt6_next = rt0;
|
fn->rr_ptr = next;
|
||||||
spin_unlock(&lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RT6_TRACE("%s() => %p, score=%d\n",
|
RT6_TRACE("%s() => %p\n",
|
||||||
__FUNCTION__, match, mpri);
|
__FUNCTION__, match);
|
||||||
|
|
||||||
return (match ? match : &ip6_null_entry);
|
return (match ? match : &ip6_null_entry);
|
||||||
}
|
}
|
||||||
|
@ -657,7 +678,7 @@ restart_2:
|
||||||
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
|
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
rt = rt6_select(&fn->leaf, fl->iif, strict | reachable);
|
rt = rt6_select(fn, fl->iif, strict | reachable);
|
||||||
BACKTRACK(&fl->fl6_src);
|
BACKTRACK(&fl->fl6_src);
|
||||||
if (rt == &ip6_null_entry ||
|
if (rt == &ip6_null_entry ||
|
||||||
rt->rt6i_flags & RTF_CACHE)
|
rt->rt6i_flags & RTF_CACHE)
|
||||||
|
@ -752,7 +773,7 @@ restart_2:
|
||||||
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
|
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
rt = rt6_select(&fn->leaf, fl->oif, strict | reachable);
|
rt = rt6_select(fn, fl->oif, strict | reachable);
|
||||||
BACKTRACK(&fl->fl6_src);
|
BACKTRACK(&fl->fl6_src);
|
||||||
if (rt == &ip6_null_entry ||
|
if (rt == &ip6_null_entry ||
|
||||||
rt->rt6i_flags & RTF_CACHE)
|
rt->rt6i_flags & RTF_CACHE)
|
||||||
|
|
|
@ -81,6 +81,13 @@ static void basic_put(struct tcf_proto *tp, unsigned long f)
|
||||||
|
|
||||||
static int basic_init(struct tcf_proto *tp)
|
static int basic_init(struct tcf_proto *tp)
|
||||||
{
|
{
|
||||||
|
struct basic_head *head;
|
||||||
|
|
||||||
|
head = kzalloc(sizeof(*head), GFP_KERNEL);
|
||||||
|
if (head == NULL)
|
||||||
|
return -ENOBUFS;
|
||||||
|
INIT_LIST_HEAD(&head->flist);
|
||||||
|
tp->root = head;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,15 +183,6 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = -ENOBUFS;
|
err = -ENOBUFS;
|
||||||
if (head == NULL) {
|
|
||||||
head = kzalloc(sizeof(*head), GFP_KERNEL);
|
|
||||||
if (head == NULL)
|
|
||||||
goto errout;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&head->flist);
|
|
||||||
tp->root = head;
|
|
||||||
}
|
|
||||||
|
|
||||||
f = kzalloc(sizeof(*f), GFP_KERNEL);
|
f = kzalloc(sizeof(*f), GFP_KERNEL);
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
|
@ -1381,7 +1381,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
|
||||||
|
|
||||||
err = sock_attach_fd(newsock, newfile);
|
err = sock_attach_fd(newsock, newfile);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_fd;
|
goto out_fd_simple;
|
||||||
|
|
||||||
err = security_socket_accept(sock, newsock);
|
err = security_socket_accept(sock, newsock);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -1414,6 +1414,11 @@ out_put:
|
||||||
fput_light(sock->file, fput_needed);
|
fput_light(sock->file, fput_needed);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
out_fd_simple:
|
||||||
|
sock_release(newsock);
|
||||||
|
put_filp(newfile);
|
||||||
|
put_unused_fd(newfd);
|
||||||
|
goto out_put;
|
||||||
out_fd:
|
out_fd:
|
||||||
fput(newfile);
|
fput(newfile);
|
||||||
put_unused_fd(newfd);
|
put_unused_fd(newfd);
|
||||||
|
|
Loading…
Reference in New Issue