Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
bd86acf1
Commit
bd86acf1
authored
Feb 17, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge nuts.davemloft.net:/disk1/BK/network-2.6
into nuts.davemloft.net:/disk1/BK/net-2.6
parents
015510a7
4d99775f
Changes
43
Hide whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
2143 additions
and
513 deletions
+2143
-513
Documentation/networking/ip-sysctl.txt
Documentation/networking/ip-sysctl.txt
+49
-0
drivers/net/Kconfig
drivers/net/Kconfig
+2
-1
drivers/net/hamradio/Kconfig
drivers/net/hamradio/Kconfig
+8
-5
drivers/net/irda/Kconfig
drivers/net/irda/Kconfig
+17
-1
drivers/net/irda/Makefile
drivers/net/irda/Makefile
+1
-0
drivers/net/irda/stir4200.c
drivers/net/irda/stir4200.c
+1283
-0
drivers/net/sungem.c
drivers/net/sungem.c
+0
-1
drivers/net/wan/Kconfig
drivers/net/wan/Kconfig
+296
-270
drivers/scsi/libata-core.c
drivers/scsi/libata-core.c
+38
-2
drivers/serial/8250.c
drivers/serial/8250.c
+10
-0
drivers/serial/serial_core.c
drivers/serial/serial_core.c
+0
-3
include/linux/inetdevice.h
include/linux/inetdevice.h
+5
-0
include/linux/ipv6.h
include/linux/ipv6.h
+2
-0
include/linux/ipv6_route.h
include/linux/ipv6_route.h
+0
-1
include/linux/skbuff.h
include/linux/skbuff.h
+3
-0
include/linux/sysctl.h
include/linux/sysctl.h
+4
-1
include/net/addrconf.h
include/net/addrconf.h
+1
-0
include/net/ip6_route.h
include/net/ip6_route.h
+1
-0
include/net/ip_vs.h
include/net/ip_vs.h
+1
-1
include/net/ipv6.h
include/net/ipv6.h
+1
-0
net/core/dev.c
net/core/dev.c
+1
-0
net/core/ethtool.c
net/core/ethtool.c
+1
-1
net/core/neighbour.c
net/core/neighbour.c
+1
-2
net/core/pktgen.c
net/core/pktgen.c
+12
-6
net/decnet/dn_rules.c
net/decnet/dn_rules.c
+1
-1
net/ipv4/arp.c
net/ipv4/arp.c
+70
-5
net/ipv4/devinet.c
net/ipv4/devinet.c
+95
-1
net/ipv4/fib_rules.c
net/ipv4/fib_rules.c
+1
-1
net/ipv4/ipvs/ip_vs_sync.c
net/ipv4/ipvs/ip_vs_sync.c
+20
-16
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_input.c
+13
-5
net/ipv6/addrconf.c
net/ipv6/addrconf.c
+13
-3
net/ipv6/exthdrs.c
net/ipv6/exthdrs.c
+1
-1
net/ipv6/ip6_fib.c
net/ipv6/ip6_fib.c
+1
-1
net/ipv6/ip6_input.c
net/ipv6/ip6_input.c
+19
-14
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_tunnel.c
+1
-1
net/ipv6/mcast.c
net/ipv6/mcast.c
+32
-3
net/ipv6/ndisc.c
net/ipv6/ndisc.c
+110
-138
net/ipv6/netfilter/ip6t_eui64.c
net/ipv6/netfilter/ip6t_eui64.c
+1
-1
net/ipv6/raw.c
net/ipv6/raw.c
+3
-3
net/ipv6/route.c
net/ipv6/route.c
+6
-5
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_input.c
+17
-8
net/ipv6/xfrm6_policy.c
net/ipv6/xfrm6_policy.c
+1
-11
net/sched/sch_sfq.c
net/sched/sch_sfq.c
+1
-0
No files found.
Documentation/networking/ip-sysctl.txt
View file @
bd86acf1
...
...
@@ -499,6 +499,55 @@ arp_filter - BOOLEAN
conf/{all,interface}/arp_filter is set to TRUE,
it will be disabled otherwise
arp_announce - INTEGER
Define different restriction levels for announcing the local
source IP address from IP packets in ARP requests sent on
interface:
0 - (default) Use any local address, configured on any interface
1 - Try to avoid local addresses that are not in the target's
subnet for this interface. This mode is useful when target
hosts reachable via this interface require the source IP
address in ARP requests to be part of their logical network
configured on the receiving interface. When we generate the
request we will check all our subnets that include the
target IP and will preserve the source address if it is from
such subnet. If there is no such subnet we select source
address according to the rules for level 2.
2 - Always use the best local address for this target.
In this mode we ignore the source address in the IP packet
and try to select local address that we prefer for talks with
the target host. Such local address is selected by looking
for primary IP addresses on all our subnets on the outgoing
interface that include the target IP address. If no suitable
local address is found we select the first local address
we have on the outgoing interface or on all other interfaces,
with the hope we will receive reply for our request and
even sometimes no matter the source IP address we announce.
The max value from conf/{all,interface}/arp_announce is used.
Increasing the restriction level gives more chance for
receiving answer from the resolved target while decreasing
the level announces more valid sender's information.
arp_ignore - INTEGER
Define different modes for sending replies in response to
received ARP requests that resolve local target IP addresses:
0 - (default): reply for any local target IP address, configured
on any interface
1 - reply only if the target IP address is local address
configured on the incoming interface
2 - reply only if the target IP address is local address
configured on the incoming interface and both with the
sender's IP address are part from same subnet on this interface
3 - do not reply for local addresses configured with scope host,
only resolutions for global and link addresses are replied
4-7 - reserved
8 - do not reply for all local addresses
The max value from conf/{all,interface}/arp_ignore is used
when ARP request is received on the {interface}
tag - INTEGER
Allows you to write a number, which can be used as required.
Default value is 0.
...
...
drivers/net/Kconfig
View file @
bd86acf1
...
...
@@ -1715,7 +1715,8 @@ config NET_POCKET
<file:Documentation/Changes>) and you can say N here.
Laptop users should read the Linux Laptop home page at
<http://www.linux-on-laptops.com/>.
<http://www.linux-on-laptops.com/> or
Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>.
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all
...
...
drivers/net/hamradio/Kconfig
View file @
bd86acf1
...
...
@@ -72,8 +72,8 @@ config DMASCC
certain parameters, such as channel access timing, clock mode, and
DMA channel. This is accomplished with a small utility program,
dmascc_cfg, available at
<http://
www.nt.tuwien.ac.at/~kkudielk/Linux/>. Please be sure to get
at least version 1.27 of dmascc_cfg, as older versions will not
<http://
cacofonix.nt.tuwien.ac.at/~oe1kib/Linux/>. Please be sure to
get
at least version 1.27 of dmascc_cfg, as older versions will not
work with the current driver.
config SCC
...
...
@@ -96,8 +96,9 @@ config SCC_DELAY
help
Say Y here if you experience problems with the SCC driver not
working properly; please read
<file:Documentation/networking/z8530drv.txt> for details. If unsure,
say N.
<file:Documentation/networking/z8530drv.txt> for details.
If unsure, say N.
config SCC_TRXECHO
bool "support for TRX that feedback the tx signal to rx"
...
...
@@ -105,7 +106,9 @@ config SCC_TRXECHO
help
Some transmitters feed the transmitted signal back to the receive
line. Say Y here to foil this by explicitly disabling the receiver
during data transmission. If in doubt, say Y.
during data transmission.
If in doubt, say Y.
config BAYCOM_SER_FDX
tristate "BAYCOM ser12 fullduplex driver for AX.25"
...
...
drivers/net/irda/Kconfig
View file @
bd86acf1
...
...
@@ -269,7 +269,7 @@ config MA600_DONGLE_OLD
information, download the following tar gzip file.
There is a pre-compiled module on
<http://engsvr.ust.hk/~eetwl95/
download/ma600-2.4.x.tar.gz
>
<http://engsvr.ust.hk/~eetwl95/
ma600.html
>
config EP7211_IR
tristate "EP7211 I/R support"
...
...
@@ -292,6 +292,22 @@ config USB_IRDA
Please note that the driver is still experimental. And of course,
you will need both USB and IrDA support in your kernel...
config SIGMATEL_FIR
tristate "SigmaTel STIr4200 bridge (EXPERIMENTAL)"
depends on IRDA && USB && EXPERIMENTAL
select CRC32
---help---
Say Y here if you want to build support for the SigmaTel STIr4200
USB IrDA FIR bridge device driver.
USB bridge based on the SigmaTel STIr4200 don't conform to the
IrDA-USB device class specification, and therefore need their
own specific driver. Those dongles support SIR and FIR (4Mbps)
speeds.
To compile it as a module, choose M here: the module will be called
stir4200.
config NSC_FIR
tristate "NSC PC87108/PC87338"
depends on IRDA && ISA
...
...
drivers/net/irda/Makefile
View file @
bd86acf1
...
...
@@ -9,6 +9,7 @@
obj-$(CONFIG_IRPORT_SIR)
+=
irport.o
# FIR drivers
obj-$(CONFIG_USB_IRDA)
+=
irda-usb.o
obj-$(CONFIG_SIGMATEL_FIR)
+=
stir4200.o
obj-$(CONFIG_NSC_FIR)
+=
nsc-ircc.o
obj-$(CONFIG_WINBOND_FIR)
+=
w83977af_ir.o
obj-$(CONFIG_SA1100_FIR)
+=
sa1100_ir.o
...
...
drivers/net/irda/stir4200.c
0 → 100644
View file @
bd86acf1
/*****************************************************************************
*
* Filename: stir4200.c
* Version: 0.4
* Description: Irda SigmaTel USB Dongle
* Status: Experimental
* Author: Stephen Hemminger <shemminger@osdl.org>
*
* Based on earlier driver by Paul Stewart <stewart@parc.com>
*
* Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at>
* Copyright (C) 2001, Dag Brattli <dag@brattli.net>
* Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com>
* Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****************************************************************************/
/*
* This dongle does no framing, and requires polling to receive the
* data. The STIr4200 has bulk in and out endpoints just like
* usr-irda devices, but the data it sends and receives is raw; like
* irtty, it needs to call the wrap and unwrap functions to add and
* remove SOF/BOF and escape characters to/from the frame.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/suspend.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <net/irda/irda.h>
#include <net/irda/irlap.h>
#include <net/irda/irda_device.h>
#include <net/irda/wrapper.h>
#include <net/irda/crc.h>
#include <linux/crc32.h>
MODULE_AUTHOR
(
"Stephen Hemminger <shemminger@osdl.org>"
);
MODULE_DESCRIPTION
(
"IrDA-USB Dongle Driver for SigmaTel STIr4200"
);
MODULE_LICENSE
(
"GPL"
);
static
int
qos_mtt_bits
=
0x07
;
/* 1 ms or more */
module_param
(
qos_mtt_bits
,
int
,
0
);
MODULE_PARM_DESC
(
qos_mtt_bits
,
"Minimum Turn Time"
);
static
int
rx_sensitivity
=
1
;
/* FIR 0..4, SIR 0..6 */
module_param
(
rx_sensitivity
,
int
,
0
);
MODULE_PARM_DESC
(
rx_sensitivity
,
"Set Receiver sensitivity (0-6, 0 is most sensitive)"
);
static
int
tx_power
=
0
;
/* 0 = highest ... 3 = lowest */
module_param
(
tx_power
,
int
,
0
);
MODULE_PARM_DESC
(
tx_power
,
"Set Transmitter power (0-3, 0 is highest power)"
);
static
int
rx_interval
=
5
;
/* milliseconds */
module_param
(
rx_interval
,
int
,
0
);
MODULE_PARM_DESC
(
rx_interval
,
"Receive polling interval (ms)"
);
#define STIR_IRDA_HEADER 4
#define CTRL_TIMEOUT 100
/* milliseconds */
#define TRANSMIT_TIMEOUT 200
/* milliseconds */
#define STIR_FIFO_SIZE 4096
#define NUM_RX_URBS 2
enum
FirChars
{
FIR_CE
=
0x7d
,
FIR_XBOF
=
0x7f
,
FIR_EOF
=
0x7e
,
};
enum
StirRequests
{
REQ_WRITE_REG
=
0x00
,
REQ_READ_REG
=
0x01
,
REQ_READ_ROM
=
0x02
,
REQ_WRITE_SINGLE
=
0x03
,
};
/* Register offsets */
enum
StirRegs
{
REG_RSVD
=
0
,
REG_MODE
,
REG_PDCLK
,
REG_CTRL1
,
REG_CTRL2
,
REG_FIFOCTL
,
REG_FIFOLSB
,
REG_FIFOMSB
,
REG_DPLL
,
REG_IRDIG
,
REG_TEST
=
15
,
};
enum
StirModeMask
{
MODE_FIR
=
0x80
,
MODE_SIR
=
0x20
,
MODE_ASK
=
0x10
,
MODE_FASTRX
=
0x08
,
MODE_FFRSTEN
=
0x04
,
MODE_NRESET
=
0x02
,
MODE_2400
=
0x01
,
};
enum
StirPdclkMask
{
PDCLK_4000000
=
0x02
,
PDCLK_115200
=
0x09
,
PDCLK_57600
=
0x13
,
PDCLK_38400
=
0x1D
,
PDCLK_19200
=
0x3B
,
PDCLK_9600
=
0x77
,
PDCLK_2400
=
0xDF
,
};
enum
StirCtrl1Mask
{
CTRL1_SDMODE
=
0x80
,
CTRL1_RXSLOW
=
0x40
,
CTRL1_TXPWD
=
0x10
,
CTRL1_RXPWD
=
0x08
,
CTRL1_SRESET
=
0x01
,
};
enum
StirCtrl2Mask
{
CTRL2_SPWIDTH
=
0x08
,
CTRL2_REVID
=
0x03
,
};
enum
StirFifoCtlMask
{
FIFOCTL_EOF
=
0x80
,
FIFOCTL_UNDER
=
0x40
,
FIFOCTL_OVER
=
0x20
,
FIFOCTL_DIR
=
0x10
,
FIFOCTL_CLR
=
0x08
,
FIFOCTL_EMPTY
=
0x04
,
FIFOCTL_RXERR
=
0x02
,
FIFOCTL_TXERR
=
0x01
,
};
enum
StirDiagMask
{
IRDIG_RXHIGH
=
0x80
,
IRDIG_RXLOW
=
0x40
,
};
enum
StirTestMask
{
TEST_PLLDOWN
=
0x80
,
TEST_LOOPIR
=
0x40
,
TEST_LOOPUSB
=
0x20
,
TEST_TSTENA
=
0x10
,
TEST_TSTOSC
=
0x0F
,
};
enum
StirState
{
STIR_STATE_RECEIVING
=
0
,
STIR_STATE_TXREADY
,
};
struct
stir_cb
{
struct
usb_device
*
usbdev
;
/* init: probe_irda */
struct
net_device
*
netdev
;
/* network layer */
struct
irlap_cb
*
irlap
;
/* The link layer we are binded to */
struct
net_device_stats
stats
;
/* network statistics */
struct
qos_info
qos
;
unsigned
long
state
;
unsigned
speed
;
/* Current speed */
wait_queue_head_t
thr_wait
;
/* transmit thread wakeup */
struct
completion
thr_exited
;
pid_t
thr_pid
;
unsigned
int
tx_bulkpipe
;
void
*
tx_data
;
/* wrapped data out */
unsigned
tx_len
;
unsigned
tx_newspeed
;
unsigned
tx_mtt
;
unsigned
int
rx_intpipe
;
iobuff_t
rx_buff
;
/* receive unwrap state machine */
struct
timespec
rx_time
;
struct
urb
*
rx_urbs
[
NUM_RX_URBS
];
void
*
rx_data
[
NUM_RX_URBS
];
};
/* These are the currently known USB ids */
static
struct
usb_device_id
dongles
[]
=
{
/* SigmaTel, Inc, STIr4200 IrDA/USB Bridge */
{
USB_DEVICE
(
0x066f
,
0x4200
)
},
{
}
};
MODULE_DEVICE_TABLE
(
usb
,
dongles
);
static
int
fifo_txwait
(
struct
stir_cb
*
stir
,
unsigned
space
);
static
void
stir_usb_receive
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
);
/* Send control message to set dongle register */
static
int
write_reg
(
struct
stir_cb
*
stir
,
__u16
reg
,
__u8
value
)
{
struct
usb_device
*
dev
=
stir
->
usbdev
;
pr_debug
(
"%s: write reg %d = 0x%x
\n
"
,
stir
->
netdev
->
name
,
reg
,
value
);
return
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
REQ_WRITE_SINGLE
,
USB_DIR_OUT
|
USB_TYPE_VENDOR
|
USB_RECIP_DEVICE
,
value
,
reg
,
NULL
,
0
,
MSECS_TO_JIFFIES
(
CTRL_TIMEOUT
));
}
/* Send control message to read multiple registers */
static
inline
int
read_reg
(
struct
stir_cb
*
stir
,
__u16
reg
,
__u8
*
data
,
__u16
count
)
{
struct
usb_device
*
dev
=
stir
->
usbdev
;
return
usb_control_msg
(
dev
,
usb_rcvctrlpipe
(
dev
,
0
),
REQ_READ_REG
,
USB_DIR_IN
|
USB_TYPE_VENDOR
|
USB_RECIP_DEVICE
,
0
,
reg
,
data
,
count
,
MSECS_TO_JIFFIES
(
CTRL_TIMEOUT
));
}
/*
* Prepare a FIR IrDA frame for transmission to the USB dongle. The
* FIR transmit frame is documented in the datasheet. It consists of
* a two byte 0x55 0xAA sequence, two little-endian length bytes, a
* sequence of exactly 16 XBOF bytes of 0x7E, two BOF bytes of 0x7E,
* then the data escaped as follows:
*
* 0x7D -> 0x7D 0x5D
* 0x7E -> 0x7D 0x5E
* 0x7F -> 0x7D 0x5F
*
* Then, 4 bytes of little endian (stuffed) FCS follow, then two
* trailing EOF bytes of 0x7E.
*/
static
inline
__u8
*
stuff_fir
(
__u8
*
p
,
__u8
c
)
{
switch
(
c
)
{
case
0x7d
:
case
0x7e
:
case
0x7f
:
*
p
++
=
0x7d
;
c
^=
IRDA_TRANS
;
/* fall through */
default:
*
p
++
=
c
;
}
return
p
;
}
/* Take raw data in skb and put it wrapped into buf */
static
unsigned
wrap_fir_skb
(
const
struct
sk_buff
*
skb
,
__u8
*
buf
)
{
__u8
*
ptr
=
buf
;
__u32
fcs
=
~
(
crc32_le
(
~
0
,
skb
->
data
,
skb
->
len
));
__u16
wraplen
;
int
i
;
/* Header */
buf
[
0
]
=
0x55
;
buf
[
1
]
=
0xAA
;
ptr
=
buf
+
STIR_IRDA_HEADER
;
memset
(
ptr
,
0x7f
,
16
);
ptr
+=
16
;
/* BOF */
*
ptr
++
=
0x7e
;
*
ptr
++
=
0x7e
;
/* Address / Control / Information */
for
(
i
=
0
;
i
<
skb
->
len
;
i
++
)
ptr
=
stuff_fir
(
ptr
,
skb
->
data
[
i
]);
/* FCS */
ptr
=
stuff_fir
(
ptr
,
fcs
&
0xff
);
ptr
=
stuff_fir
(
ptr
,
(
fcs
>>
8
)
&
0xff
);
ptr
=
stuff_fir
(
ptr
,
(
fcs
>>
16
)
&
0xff
);
ptr
=
stuff_fir
(
ptr
,
(
fcs
>>
24
)
&
0xff
);
/* EOFs */
*
ptr
++
=
0x7e
;
*
ptr
++
=
0x7e
;
/* Total length, minus the header */
wraplen
=
(
ptr
-
buf
)
-
STIR_IRDA_HEADER
;
buf
[
2
]
=
wraplen
&
0xff
;
buf
[
3
]
=
(
wraplen
>>
8
)
&
0xff
;
return
wraplen
+
STIR_IRDA_HEADER
;
}
static
unsigned
wrap_sir_skb
(
struct
sk_buff
*
skb
,
__u8
*
buf
)
{
__u16
wraplen
;
wraplen
=
async_wrap_skb
(
skb
,
buf
+
STIR_IRDA_HEADER
,
STIR_FIFO_SIZE
-
STIR_IRDA_HEADER
);
buf
[
0
]
=
0x55
;
buf
[
1
]
=
0xAA
;
buf
[
2
]
=
wraplen
&
0xff
;
buf
[
3
]
=
(
wraplen
>>
8
)
&
0xff
;
return
wraplen
+
STIR_IRDA_HEADER
;
}
/*
* Frame is fully formed in the rx_buff so check crc
* and pass up to irlap
* setup for next receive
*/
static
void
fir_eof
(
struct
stir_cb
*
stir
)
{
iobuff_t
*
rx_buff
=
&
stir
->
rx_buff
;
int
len
=
rx_buff
->
len
-
4
;
__u32
fcs
;
struct
sk_buff
*
nskb
;
if
(
unlikely
(
len
<=
0
))
{
pr_debug
(
"%s: short frame len %d
\n
"
,
stir
->
netdev
->
name
,
len
);
++
stir
->
stats
.
rx_errors
;
++
stir
->
stats
.
rx_length_errors
;
return
;
}
fcs
=
rx_buff
->
data
[
len
]
|
rx_buff
->
data
[
len
+
1
]
<<
8
|
rx_buff
->
data
[
len
+
2
]
<<
16
|
rx_buff
->
data
[
len
+
3
]
<<
24
;
if
(
unlikely
(
fcs
!=
~
(
crc32_le
(
~
0
,
rx_buff
->
data
,
len
))))
{
pr_debug
(
"%s: crc error
\n
"
,
stir
->
netdev
->
name
);
irda_device_set_media_busy
(
stir
->
netdev
,
TRUE
);
stir
->
stats
.
rx_errors
++
;
stir
->
stats
.
rx_crc_errors
++
;
return
;
}
/* If can't get new buffer, just drop and reuse */
nskb
=
dev_alloc_skb
(
IRDA_SKB_MAX_MTU
);
if
(
unlikely
(
!
nskb
))
++
stir
->
stats
.
rx_dropped
;
else
{
struct
sk_buff
*
oskb
=
rx_buff
->
skb
;
skb_reserve
(
nskb
,
1
);
/* Set correct length in socket buffer */
skb_put
(
oskb
,
len
);
oskb
->
mac
.
raw
=
oskb
->
data
;
oskb
->
protocol
=
htons
(
ETH_P_IRDA
);
oskb
->
dev
=
stir
->
netdev
;
netif_rx
(
oskb
);
stir
->
stats
.
rx_packets
++
;
stir
->
stats
.
rx_bytes
+=
len
;
rx_buff
->
skb
=
nskb
;
rx_buff
->
head
=
nskb
->
data
;
}
rx_buff
->
data
=
rx_buff
->
head
;
rx_buff
->
len
=
0
;
}
/* Unwrap FIR stuffed data and bump it to IrLAP */
static
void
stir_fir_chars
(
struct
stir_cb
*
stir
,
const
__u8
*
bytes
,
int
len
)
{
iobuff_t
*
rx_buff
=
&
stir
->
rx_buff
;
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
__u8
byte
=
bytes
[
i
];
switch
(
rx_buff
->
state
)
{
case
OUTSIDE_FRAME
:
/* ignore garbage till start of frame */
if
(
unlikely
(
byte
!=
FIR_EOF
))
continue
;
/* Now receiving frame */
rx_buff
->
state
=
BEGIN_FRAME
;
rx_buff
->
in_frame
=
TRUE
;
/* Time to initialize receive buffer */
rx_buff
->
data
=
rx_buff
->
head
;
rx_buff
->
len
=
0
;
continue
;
case
LINK_ESCAPE
:
if
(
byte
==
FIR_EOF
)
{
pr_debug
(
"%s: got EOF after escape
\n
"
,
stir
->
netdev
->
name
);
goto
frame_error
;
}
rx_buff
->
state
=
INSIDE_FRAME
;
byte
^=
IRDA_TRANS
;
break
;
case
BEGIN_FRAME
:
/* ignore multiple BOF/EOF */
if
(
byte
==
FIR_EOF
)
continue
;
rx_buff
->
state
=
INSIDE_FRAME
;
/* fall through */
case
INSIDE_FRAME
:
switch
(
byte
)
{
case
FIR_CE
:
rx_buff
->
state
=
LINK_ESCAPE
;
continue
;
case
FIR_XBOF
:
/* 0x7f is not used in this framing */
pr_debug
(
"%s: got XBOF without escape
\n
"
,
stir
->
netdev
->
name
);
goto
frame_error
;
case
FIR_EOF
:
rx_buff
->
state
=
OUTSIDE_FRAME
;
rx_buff
->
in_frame
=
FALSE
;
fir_eof
(
stir
);
continue
;
}
break
;
}
/* add byte to rx buffer */
if
(
unlikely
(
rx_buff
->
len
>=
rx_buff
->
truesize
))
{
pr_debug
(
"%s: fir frame exceeds %d
\n
"
,
stir
->
netdev
->
name
,
rx_buff
->
truesize
);
++
stir
->
stats
.
rx_over_errors
;
goto
error_recovery
;
}
rx_buff
->
data
[
rx_buff
->
len
++
]
=
byte
;
continue
;
frame_error:
++
stir
->
stats
.
rx_frame_errors
;
error_recovery:
++
stir
->
stats
.
rx_errors
;
irda_device_set_media_busy
(
stir
->
netdev
,
TRUE
);
rx_buff
->
state
=
OUTSIDE_FRAME
;
rx_buff
->
in_frame
=
FALSE
;
}
}
/* Unwrap SIR stuffed data and bump it up to IrLAP */
static
void
stir_sir_chars
(
struct
stir_cb
*
stir
,
const
__u8
*
bytes
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
async_unwrap_char
(
stir
->
netdev
,
&
stir
->
stats
,
&
stir
->
rx_buff
,
bytes
[
i
]);
}
static
inline
int
isfir
(
u32
speed
)
{
return
(
speed
==
4000000
);
}
static
inline
void
unwrap_chars
(
struct
stir_cb
*
stir
,
const
__u8
*
bytes
,
int
length
)
{
if
(
isfir
(
stir
->
speed
))
stir_fir_chars
(
stir
,
bytes
,
length
);
else
stir_sir_chars
(
stir
,
bytes
,
length
);
}
/* Mode parameters for each speed */
static
const
struct
{
unsigned
speed
;
__u8
pdclk
;
}
stir_modes
[]
=
{
{
2400
,
PDCLK_2400
},
{
9600
,
PDCLK_9600
},
{
19200
,
PDCLK_19200
},
{
38400
,
PDCLK_38400
},
{
57600
,
PDCLK_57600
},
{
115200
,
PDCLK_115200
},
{
4000000
,
PDCLK_4000000
},
};
/*
* Setup chip for speed.
* Called at startup to initialize the chip
* and on speed changes.
*
* Note: Write multiple registers doesn't appear to work
*/
static
int
change_speed
(
struct
stir_cb
*
stir
,
unsigned
speed
)
{
int
i
,
err
;
__u8
mode
;
pr_debug
(
"%s: change speed %d
\n
"
,
stir
->
netdev
->
name
,
speed
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
stir_modes
);
++
i
)
{
if
(
speed
==
stir_modes
[
i
].
speed
)
goto
found
;
}
ERROR
(
"%s: invalid speed %d
\n
"
,
stir
->
netdev
->
name
,
speed
);
return
-
EINVAL
;
found:
pr_debug
(
"%s: speed change from %d to %d
\n
"
,
stir
->
netdev
->
name
,
stir
->
speed
,
speed
);
/* Make sure any previous Tx is really finished. This happens
* when we answer an incomming request ; the ua:rsp and the
* speed change are bundled together, so we need to wait until
* the packet we just submitted has been sent. Jean II */
if
(
fifo_txwait
(
stir
,
0
))
return
-
EIO
;
/* Set clock */
err
=
write_reg
(
stir
,
REG_PDCLK
,
stir_modes
[
i
].
pdclk
);
if
(
err
)
goto
out
;
mode
=
MODE_NRESET
|
MODE_FASTRX
;
if
(
isfir
(
speed
))
mode
|=
MODE_FIR
|
MODE_FFRSTEN
;
else
mode
|=
MODE_SIR
;
if
(
speed
==
2400
)
mode
|=
MODE_2400
;
err
=
write_reg
(
stir
,
REG_MODE
,
mode
);
if
(
err
)
goto
out
;
/* This resets TEMIC style transceiver if any. */
err
=
write_reg
(
stir
,
REG_CTRL1
,
CTRL1_SDMODE
|
(
tx_power
&
3
)
<<
1
);
if
(
err
)
goto
out
;
err
=
write_reg
(
stir
,
REG_CTRL1
,
(
tx_power
&
3
)
<<
1
);
out:
stir
->
speed
=
speed
;
return
err
;
}
static
int
stir_reset
(
struct
stir_cb
*
stir
)
{
int
err
;
/* reset state */
stir
->
rx_buff
.
in_frame
=
FALSE
;
stir
->
rx_buff
.
state
=
OUTSIDE_FRAME
;
stir
->
speed
=
-
1
;
/* Undocumented magic to tweak the DPLL */
err
=
write_reg
(
stir
,
REG_DPLL
,
0x15
);
if
(
err
)
goto
out
;
/* Reset sensitivity */
err
=
write_reg
(
stir
,
REG_CTRL2
,
(
rx_sensitivity
&
7
)
<<
5
);
if
(
err
)
goto
out
;
err
=
change_speed
(
stir
,
9600
);
out:
return
err
;
}
/*
* Called from net/core when new frame is available.
*/
static
int
stir_hard_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
netdev
)
{
struct
stir_cb
*
stir
=
netdev
->
priv
;
netif_stop_queue
(
netdev
);
/* the IRDA wrapping routines don't deal with non linear skb */
SKB_LINEAR_ASSERT
(
skb
);
if
(
unlikely
(
skb
->
len
)
==
0
)
/* speed change only */
stir
->
tx_len
=
0
;
else
if
(
isfir
(
stir
->
speed
))
stir
->
tx_len
=
wrap_fir_skb
(
skb
,
stir
->
tx_data
);
else
stir
->
tx_len
=
wrap_sir_skb
(
skb
,
stir
->
tx_data
);
stir
->
stats
.
tx_packets
++
;
stir
->
stats
.
tx_bytes
+=
skb
->
len
;
stir
->
tx_mtt
=
irda_get_mtt
(
skb
);
stir
->
tx_newspeed
=
irda_get_next_speed
(
skb
);
if
(
!
test_and_set_bit
(
STIR_STATE_TXREADY
,
&
stir
->
state
))
wake_up
(
&
stir
->
thr_wait
);
dev_kfree_skb
(
skb
);
return
0
;
}
/*
* Wait for the transmit FIFO to have space for next data
*/
static
int
fifo_txwait
(
struct
stir_cb
*
stir
,
unsigned
space
)
{
int
err
;
unsigned
count
;
__u8
regs
[
3
];
unsigned
long
timeout
=
jiffies
+
HZ
/
10
;
for
(;;)
{
/* Read FIFO status and count */
err
=
read_reg
(
stir
,
REG_FIFOCTL
,
regs
,
3
);
if
(
unlikely
(
err
!=
3
))
{
WARNING
(
"%s: FIFO register read error: %d
\n
"
,
stir
->
netdev
->
name
,
err
);
return
err
;
}
/* is fifo receiving already, or empty */
if
(
!
(
regs
[
0
]
&
FIFOCTL_DIR
)
||
(
regs
[
0
]
&
FIFOCTL_EMPTY
))
return
0
;
if
(
signal_pending
(
current
))
return
-
EINTR
;
/* shutting down? */
if
(
!
netif_running
(
stir
->
netdev
)
||
!
netif_device_present
(
stir
->
netdev
))
return
-
ESHUTDOWN
;
count
=
(
unsigned
)(
regs
[
2
]
&
0x1f
)
<<
8
|
regs
[
1
];
pr_debug
(
"%s: fifo status 0x%x count %u
\n
"
,
stir
->
netdev
->
name
,
regs
[
0
],
count
);
/* only waiting for some space */
if
(
space
&&
STIR_FIFO_SIZE
-
4
>
space
+
count
)
return
0
;
if
(
time_after
(
jiffies
,
timeout
))
{
WARNING
(
"%s: transmit fifo timeout status=0x%x count=%d
\n
"
,
stir
->
netdev
->
name
,
regs
[
0
],
count
);
++
stir
->
stats
.
tx_errors
;
irda_device_set_media_busy
(
stir
->
netdev
,
TRUE
);
return
-
ETIMEDOUT
;
}
/* estimate transfer time for remaining chars */
wait_ms
((
count
*
8000
)
/
stir
->
speed
);
}
}
/* Wait for turnaround delay before starting transmit. */
static
void
turnaround_delay
(
long
us
,
const
struct
timespec
*
last
)
{
long
ticks
;
struct
timespec
now
=
CURRENT_TIME
;
if
(
us
<=
0
)
return
;
us
-=
(
now
.
tv_sec
-
last
->
tv_sec
)
*
USEC_PER_SEC
;
us
-=
(
now
.
tv_nsec
-
last
->
tv_nsec
)
/
NSEC_PER_USEC
;
if
(
us
<
10
)
return
;
ticks
=
us
/
(
1000000
/
HZ
);
if
(
ticks
>
0
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
1
+
ticks
);
}
else
udelay
(
us
);
}
/*
* Start receiver by submitting a request to the receive pipe.
* If nothing is available it will return after rx_interval.
*/
static
void
receive_start
(
struct
stir_cb
*
stir
)
{
int
i
;
if
(
test_and_set_bit
(
STIR_STATE_RECEIVING
,
&
stir
->
state
))
return
;
if
(
fifo_txwait
(
stir
,
0
))
return
;
for
(
i
=
0
;
i
<
NUM_RX_URBS
;
i
++
)
{
struct
urb
*
urb
=
stir
->
rx_urbs
[
i
];
usb_fill_int_urb
(
urb
,
stir
->
usbdev
,
stir
->
rx_intpipe
,
stir
->
rx_data
[
i
],
STIR_FIFO_SIZE
,
stir_usb_receive
,
stir
,
rx_interval
);
if
(
usb_submit_urb
(
urb
,
GFP_KERNEL
))
urb
->
status
=
-
EINVAL
;
}
if
(
i
==
0
)
{
/* if nothing got queued, then just retry next time */
if
(
net_ratelimit
())
WARNING
(
"%s: no receive buffers avaiable
\n
"
,
stir
->
netdev
->
name
);
clear_bit
(
STIR_STATE_RECEIVING
,
&
stir
->
state
);
}
}
/* Stop all pending receive Urb's */
static
void
receive_stop
(
struct
stir_cb
*
stir
)
{
int
i
;
for
(
i
=
0
;
i
<
NUM_RX_URBS
;
i
++
)
{
struct
urb
*
urb
=
stir
->
rx_urbs
[
i
];
usb_unlink_urb
(
urb
);
}
}
/* Send wrapped data (in tx_data) to device */
static
void
stir_send
(
struct
stir_cb
*
stir
)
{
int
rc
;
if
(
test_and_clear_bit
(
STIR_STATE_RECEIVING
,
&
stir
->
state
))
{
receive_stop
(
stir
);
turnaround_delay
(
stir
->
tx_mtt
,
&
stir
->
rx_time
);
if
(
stir
->
rx_buff
.
in_frame
)
++
stir
->
stats
.
collisions
;
}
else
if
(
fifo_txwait
(
stir
,
stir
->
tx_len
))
return
;
/* shutdown or major errors */
stir
->
netdev
->
trans_start
=
jiffies
;
pr_debug
(
"%s: send %d
\n
"
,
stir
->
netdev
->
name
,
stir
->
tx_len
);
rc
=
usb_bulk_msg
(
stir
->
usbdev
,
stir
->
tx_bulkpipe
,
stir
->
tx_data
,
stir
->
tx_len
,
NULL
,
MSECS_TO_JIFFIES
(
TRANSMIT_TIMEOUT
));
if
(
unlikely
(
rc
))
{
WARNING
(
"%s: usb bulk message failed %d
\n
"
,
stir
->
netdev
->
name
,
rc
);
stir
->
stats
.
tx_errors
++
;
}
}
/*
* Transmit state machine thread
*/
static
int
stir_transmit_thread
(
void
*
arg
)
{
struct
stir_cb
*
stir
=
arg
;
struct
net_device
*
dev
=
stir
->
netdev
;
DECLARE_WAITQUEUE
(
wait
,
current
);
daemonize
(
"%s"
,
dev
->
name
);
allow_signal
(
SIGTERM
);
while
(
netif_running
(
dev
)
&&
netif_device_present
(
dev
)
&&
!
signal_pending
(
current
))
{
/* make swsusp happy with our thread */
if
(
current
->
flags
&
PF_FREEZE
)
{
receive_stop
(
stir
);
write_reg
(
stir
,
REG_CTRL1
,
CTRL1_TXPWD
|
CTRL1_RXPWD
);
refrigerator
(
PF_IOTHREAD
);
stir_reset
(
stir
);
}
/* if something to send? */
if
(
test_and_clear_bit
(
STIR_STATE_TXREADY
,
&
stir
->
state
))
{
unsigned
new_speed
=
stir
->
tx_newspeed
;
/* Note that we may both send a packet and
* change speed in some cases. Jean II */
if
(
stir
->
tx_len
!=
0
)
stir_send
(
stir
);
if
(
stir
->
speed
!=
new_speed
)
change_speed
(
stir
,
new_speed
);
netif_wake_queue
(
stir
->
netdev
);
continue
;
}
if
(
irda_device_txqueue_empty
(
dev
))
receive_start
(
stir
);
set_task_state
(
current
,
TASK_INTERRUPTIBLE
);
add_wait_queue
(
&
stir
->
thr_wait
,
&
wait
);
if
(
test_bit
(
STIR_STATE_TXREADY
,
&
stir
->
state
))
__set_task_state
(
current
,
TASK_RUNNING
);
else
schedule_timeout
(
HZ
/
10
);
remove_wait_queue
(
&
stir
->
thr_wait
,
&
wait
);
}
complete_and_exit
(
&
stir
->
thr_exited
,
0
);
}
/*
* Receive wrapped data into rx_data buffer.
* This chip doesn't block until data is available, we just have
* to read the FIFO perodically (ugh).
*/
static
void
stir_usb_receive
(
struct
urb
*
urb
,
struct
pt_regs
*
regs
)
{
struct
stir_cb
*
stir
=
urb
->
context
;
int
err
;
if
(
!
netif_running
(
stir
->
netdev
))
return
;
switch
(
urb
->
status
)
{
case
0
:
if
(
urb
->
actual_length
>
0
)
{
pr_debug
(
"%s: receive %d
\n
"
,
stir
->
netdev
->
name
,
urb
->
actual_length
);
unwrap_chars
(
stir
,
urb
->
transfer_buffer
,
urb
->
actual_length
);
stir
->
netdev
->
last_rx
=
jiffies
;
stir
->
rx_time
=
CURRENT_TIME
;
}
break
;
case
-
ECONNRESET
:
/* killed but pending */
case
-
ENOENT
:
/* killed but not in use */
case
-
ESHUTDOWN
:
/* These are normal errors when URB is cancelled */
stir
->
rx_buff
.
in_frame
=
FALSE
;
stir
->
rx_buff
.
state
=
OUTSIDE_FRAME
;
return
;
default:
WARNING
(
"%s: received status %d
\n
"
,
stir
->
netdev
->
name
,
urb
->
status
);
stir
->
stats
.
rx_errors
++
;
urb
->
status
=
0
;
}
/* kernel thread is stopping receiver don't resubmit */
if
(
!
test_bit
(
STIR_STATE_RECEIVING
,
&
stir
->
state
))
return
;
/* resubmit existing urb */
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
/* in case of error, the kernel thread will restart us */
if
(
err
)
{
WARNING
(
"%s: usb receive submit error: %d
\n
"
,
stir
->
netdev
->
name
,
err
);
urb
->
status
=
-
ENOENT
;
wake_up
(
&
stir
->
thr_wait
);
}
}
/*
* Function stir_net_open (dev)
*
* Network device is taken up. Usually this is done by "ifconfig irda0 up"
*/
static
int
stir_net_open
(
struct
net_device
*
netdev
)
{
struct
stir_cb
*
stir
=
netdev
->
priv
;
int
i
,
err
;
char
hwname
[
16
];
err
=
stir_reset
(
stir
);
if
(
err
)
goto
err_out1
;
err
=
-
ENOMEM
;
/* Note: Max SIR frame possible is 4273 */
stir
->
tx_data
=
kmalloc
(
STIR_FIFO_SIZE
,
GFP_KERNEL
);
if
(
!
stir
->
tx_data
)
{
ERROR
(
"%s(), alloc failed for rxbuf!
\n
"
,
__FUNCTION__
);
goto
err_out1
;
}
/* Initialize for SIR/FIR to copy data directly into skb. */
stir
->
rx_buff
.
truesize
=
IRDA_SKB_MAX_MTU
;
stir
->
rx_buff
.
skb
=
dev_alloc_skb
(
IRDA_SKB_MAX_MTU
);
if
(
!
stir
->
rx_buff
.
skb
)
{
ERROR
(
"%s(), dev_alloc_skb() failed for rxbuf!
\n
"
,
__FUNCTION__
);
goto
err_out2
;
}
skb_reserve
(
stir
->
rx_buff
.
skb
,
1
);
stir
->
rx_buff
.
head
=
stir
->
rx_buff
.
skb
->
data
;
stir
->
rx_time
=
CURRENT_TIME
;
/* Allocate N receive buffer's and urbs */
for
(
i
=
0
;
i
<
NUM_RX_URBS
;
i
++
)
{
stir
->
rx_urbs
[
i
]
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
stir
->
rx_urbs
[
i
]){
ERROR
(
"%s(), usb_alloc_urb failed
\n
"
,
__FUNCTION__
);
goto
err_out3
;
}
stir
->
rx_data
[
i
]
=
kmalloc
(
STIR_FIFO_SIZE
,
GFP_KERNEL
);
if
(
!
stir
->
rx_data
)
{
usb_free_urb
(
stir
->
rx_urbs
[
i
]);
ERROR
(
"%s(), alloc failed for rxbuf!
\n
"
,
__FUNCTION__
);
goto
err_out3
;
}
}
/*
* Now that everything should be initialized properly,
* Open new IrLAP layer instance to take care of us...
* Note : will send immediately a speed change...
*/
sprintf
(
hwname
,
"usb#%d"
,
stir
->
usbdev
->
devnum
);
stir
->
irlap
=
irlap_open
(
netdev
,
&
stir
->
qos
,
hwname
);
if
(
!
stir
->
irlap
)
{
ERROR
(
"%s(): irlap_open failed
\n
"
,
__FUNCTION__
);
goto
err_out3
;
}
/** Start kernel thread for transmit. */
stir
->
thr_pid
=
kernel_thread
(
stir_transmit_thread
,
stir
,
CLONE_FS
|
CLONE_FILES
);
if
(
stir
->
thr_pid
<
0
)
{
err
=
stir
->
thr_pid
;
WARNING
(
"%s: unable to start kernel thread
\n
"
,
stir
->
netdev
->
name
);
goto
err_out4
;
}
netif_start_queue
(
netdev
);
return
0
;
err_out4:
irlap_close
(
stir
->
irlap
);
err_out3:
while
(
--
i
>=
0
)
{
usb_free_urb
(
stir
->
rx_urbs
[
i
]);
kfree
(
stir
->
rx_data
[
i
]);
}
kfree_skb
(
stir
->
rx_buff
.
skb
);
err_out2:
kfree
(
stir
->
tx_data
);
err_out1:
return
err
;
}
/*
* Function stir_net_close (stir)
*
* Network device is taken down. Usually this is done by
* "ifconfig irda0 down"
*/
static
int
stir_net_close
(
struct
net_device
*
netdev
)
{
struct
stir_cb
*
stir
=
netdev
->
priv
;
int
i
;
/* Stop transmit processing */
netif_stop_queue
(
netdev
);
/* Kill transmit thread */
kill_proc
(
stir
->
thr_pid
,
SIGTERM
,
1
);
wait_for_completion
(
&
stir
->
thr_exited
);
kfree
(
stir
->
tx_data
);
clear_bit
(
STIR_STATE_RECEIVING
,
&
stir
->
state
);
receive_stop
(
stir
);
for
(
i
=
0
;
i
<
NUM_RX_URBS
;
i
++
)
{
usb_free_urb
(
stir
->
rx_urbs
[
i
]);
kfree
(
stir
->
rx_data
[
i
]);
}
kfree_skb
(
stir
->
rx_buff
.
skb
);
/* Stop and remove instance of IrLAP */
if
(
stir
->
irlap
)
irlap_close
(
stir
->
irlap
);
stir
->
irlap
=
NULL
;
return
0
;
}
/*
* IOCTLs : Extra out-of-band network commands...
*/
static
int
stir_net_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
)
{
struct
if_irda_req
*
irq
=
(
struct
if_irda_req
*
)
rq
;
struct
stir_cb
*
stir
=
dev
->
priv
;
int
ret
=
0
;
switch
(
cmd
)
{
case
SIOCSBANDWIDTH
:
/* Set bandwidth */
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
/* Check if the device is still there */
if
(
netif_device_present
(
stir
->
netdev
))
ret
=
change_speed
(
stir
,
irq
->
ifr_baudrate
);
break
;
case
SIOCSMEDIABUSY
:
/* Set media busy */
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
/* Check if the IrDA stack is still there */
if
(
netif_running
(
stir
->
netdev
))
irda_device_set_media_busy
(
stir
->
netdev
,
TRUE
);
break
;
case
SIOCGRECEIVING
:
/* Only approximately true */
irq
->
ifr_receiving
=
test_bit
(
STIR_STATE_RECEIVING
,
&
stir
->
state
);
break
;
default:
ret
=
-
EOPNOTSUPP
;
}
return
ret
;
}
/*
* Get device stats (for /proc/net/dev and ifconfig)
*/
static
struct
net_device_stats
*
stir_net_get_stats
(
struct
net_device
*
dev
)
{
struct
stir_cb
*
stir
=
dev
->
priv
;
return
&
stir
->
stats
;
}
/*
* Parse the various endpoints and find the one we need.
*
* The endpoint are the pipes used to communicate with the USB device.
* The spec defines 2 endpoints of type bulk transfer, one in, and one out.
* These are used to pass frames back and forth with the dongle.
*/
static
int
stir_setup_usb
(
struct
stir_cb
*
stir
,
struct
usb_interface
*
intf
)
{
struct
usb_device
*
usbdev
=
interface_to_usbdev
(
intf
);
const
struct
usb_host_interface
*
interface
=
&
intf
->
altsetting
[
intf
->
act_altsetting
];
const
struct
usb_endpoint_descriptor
*
ep_in
=
NULL
;
const
struct
usb_endpoint_descriptor
*
ep_out
=
NULL
;
int
i
;
if
(
interface
->
desc
.
bNumEndpoints
!=
2
)
{
WARNING
(
"%s: expected two endpoints
\n
"
,
__FUNCTION__
);
return
-
ENODEV
;
}
for
(
i
=
0
;
i
<
interface
->
desc
.
bNumEndpoints
;
i
++
)
{
const
struct
usb_endpoint_descriptor
*
ep
=
&
interface
->
endpoint
[
i
].
desc
;
if
((
ep
->
bmAttributes
&
USB_ENDPOINT_XFERTYPE_MASK
)
==
USB_ENDPOINT_XFER_BULK
)
{
/* We need to find an IN and an OUT */
if
((
ep
->
bEndpointAddress
&
USB_ENDPOINT_DIR_MASK
)
==
USB_DIR_IN
)
ep_in
=
ep
;
else
ep_out
=
ep
;
}
else
WARNING
(
"%s: unknown endpoint type 0x%x
\n
"
,
__FUNCTION__
,
ep
->
bmAttributes
);
}
if
(
!
ep_in
||
!
ep_out
)
return
-
EIO
;
stir
->
tx_bulkpipe
=
usb_sndbulkpipe
(
usbdev
,
ep_out
->
bEndpointAddress
&
USB_ENDPOINT_NUMBER_MASK
);
stir
->
rx_intpipe
=
usb_rcvintpipe
(
usbdev
,
ep_in
->
bEndpointAddress
&
USB_ENDPOINT_NUMBER_MASK
);
return
0
;
}
/*
* This routine is called by the USB subsystem for each new device
* in the system. We need to check if the device is ours, and in
* this case start handling it.
* Note : it might be worth protecting this function by a global
* spinlock... Or not, because maybe USB already deal with that...
*/
static
int
stir_probe
(
struct
usb_interface
*
intf
,
const
struct
usb_device_id
*
id
)
{
struct
usb_device
*
dev
=
interface_to_usbdev
(
intf
);
struct
stir_cb
*
stir
=
NULL
;
struct
net_device
*
net
;
int
ret
=
-
ENOMEM
;
/* Allocate network device container. */
net
=
alloc_irdadev
(
sizeof
(
*
stir
));
if
(
!
net
)
goto
err_out1
;
SET_MODULE_OWNER
(
net
);
SET_NETDEV_DEV
(
net
,
&
intf
->
dev
);
stir
=
net
->
priv
;
stir
->
netdev
=
net
;
stir
->
usbdev
=
dev
;
ret
=
stir_setup_usb
(
stir
,
intf
);
if
(
ret
!=
0
)
{
ERROR
(
"%s(), Bogus endpoints...
\n
"
,
__FUNCTION__
);
goto
err_out2
;
}
printk
(
KERN_INFO
"SigmaTel STIr4200 IRDA/USB found at address %d, "
"Vendor: %x, Product: %x
\n
"
,
dev
->
devnum
,
dev
->
descriptor
.
idVendor
,
dev
->
descriptor
.
idProduct
);
/* Initialize QoS for this device */
irda_init_max_qos_capabilies
(
&
stir
->
qos
);
/* That's the Rx capability. */
stir
->
qos
.
baud_rate
.
bits
&=
IR_2400
|
IR_9600
|
IR_19200
|
IR_38400
|
IR_57600
|
IR_115200
|
(
IR_4000000
<<
8
);
stir
->
qos
.
min_turn_time
.
bits
&=
qos_mtt_bits
;
irda_qos_bits_to_value
(
&
stir
->
qos
);
init_completion
(
&
stir
->
thr_exited
);
init_waitqueue_head
(
&
stir
->
thr_wait
);
/* Override the network functions we need to use */
net
->
hard_start_xmit
=
stir_hard_xmit
;
net
->
open
=
stir_net_open
;
net
->
stop
=
stir_net_close
;
net
->
get_stats
=
stir_net_get_stats
;
net
->
do_ioctl
=
stir_net_ioctl
;
ret
=
stir_reset
(
stir
);
if
(
ret
)
goto
err_out2
;
ret
=
register_netdev
(
net
);
if
(
ret
!=
0
)
goto
err_out2
;
MESSAGE
(
"IrDA: Registered SigmaTel device %s
\n
"
,
net
->
name
);
usb_set_intfdata
(
intf
,
stir
);
return
0
;
err_out2:
free_netdev
(
net
);
err_out1:
return
ret
;
}
/*
* The current device is removed, the USB layer tell us to shut it down...
*/
static
void
stir_disconnect
(
struct
usb_interface
*
intf
)
{
struct
stir_cb
*
stir
=
usb_get_intfdata
(
intf
);
struct
net_device
*
net
;
usb_set_intfdata
(
intf
,
NULL
);
if
(
!
stir
)
return
;
/* Stop transmitter */
net
=
stir
->
netdev
;
netif_device_detach
(
net
);
/* Remove netdevice */
unregister_netdev
(
net
);
/* No longer attached to USB bus */
stir
->
usbdev
=
NULL
;
free_netdev
(
net
);
}
/* Power management suspend, so power off the transmitter/receiver */
static
int
stir_suspend
(
struct
usb_interface
*
intf
,
u32
state
)
{
struct
stir_cb
*
stir
=
usb_get_intfdata
(
intf
);
netif_device_detach
(
stir
->
netdev
);
return
0
;
}
/* Coming out of suspend, so reset hardware */
static
int
stir_resume
(
struct
usb_interface
*
intf
)
{
struct
stir_cb
*
stir
=
usb_get_intfdata
(
intf
);
netif_device_attach
(
stir
->
netdev
);
/* receiver restarted when send thread wakes up */
return
0
;
}
/*
* USB device callbacks
*/
static
struct
usb_driver
irda_driver
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"stir4200"
,
.
probe
=
stir_probe
,
.
disconnect
=
stir_disconnect
,
.
id_table
=
dongles
,
.
suspend
=
stir_suspend
,
.
resume
=
stir_resume
,
};
/*
* Module insertion
*/
static
int
__init
stir_init
(
void
)
{
if
(
usb_register
(
&
irda_driver
)
<
0
)
return
-
1
;
MESSAGE
(
"SigmaTel support registered
\n
"
);
return
0
;
}
module_init
(
stir_init
);
/*
* Module removal
*/
static
void
__exit
stir_cleanup
(
void
)
{
/* Deregister the driver and remove all pending instances */
usb_deregister
(
&
irda_driver
);
}
module_exit
(
stir_cleanup
);
drivers/net/sungem.c
View file @
bd86acf1
...
...
@@ -1961,7 +1961,6 @@ static void gem_init_hw(struct gem *gp, int restart_link)
*/
static
void
gem_apple_powerup
(
struct
gem
*
gp
)
{
u16
cmd
;
u32
mif_cfg
;
mb
();
...
...
drivers/net/wan/Kconfig
View file @
bd86acf1
...
...
@@ -8,17 +8,18 @@ menu "Wan interfaces"
config WAN
bool "Wan interfaces support"
---help---
Wide Area Networks (WANs), such as X.25,
frame r
elay and leased
Wide Area Networks (WANs), such as X.25,
Frame R
elay and leased
lines, are used to interconnect Local Area Networks (LANs) over vast
distances with data transfer rates significantly higher than those
achievable with commonly used asynchronous modem connections.
Usually, a quite expensive external device called a `WAN router' is
needed to connect to a WAN.
needed to connect to a WAN. As an alternative, a relatively
inexpensive WAN interface card can allow your Linux box to directly
connect to a WAN.
As an alternative, a relatively inexpensive WAN interface card can
allow your Linux box to directly connect to a WAN. If you have one
of those cards and wish to use it under Linux, say Y here and also
to the WAN driver for your card, below.
If you have one of those cards and wish to use it under Linux,
say Y here and also to the WAN driver for your card.
If unsure, say N.
...
...
@@ -27,32 +28,34 @@ config HOSTESS_SV11
tristate "Comtrol Hostess SV-11 support"
depends on WAN && ISA && m
help
This is a network card for low speed synchronous serial links, at
up to 256Kbps. It supports both PPP and Cisco HDLC.
Driver for Comtrol Hostess SV-11 network card which
operates on low speed synchronous serial links at up to
256Kbps, supporting PPP and Cisco HDLC.
At this point, the driver can only be compiled as a module.
The driver will be compiled as a module: the
module will be called hostess_sv11.
# The COSA/SRP driver has not been tested as non-modular yet.
config COSA
tristate "COSA/SRP sync serial boards support"
depends on WAN && ISA && m
---help---
This is a driver for COSA and SRP synchronous serial boards. These
boards allow to connect synchronous serial devices (for example
Driver for COSA and SRP synchronous serial boards.
These boards allow to connect synchronous serial devices (for example
base-band modems, or any other device with the X.21, V.24, V.35 or
V.36 interface) to your Linux box. The cards can work as the
character device, synchronous PPP network device, or the Cisco HDLC
network device.
To actually use the COSA or SRP board, you will need user-space
utilities for downloading the firmware to the cards and to set them
up. Look at the <http://www.fi.muni.cz/~kas/cosa/> for more
information about the cards (including the pointer to the user-space
utilities). You can also read the comment at the top of the
<file:drivers/net/wan/cosa.c> for details about the cards and the driver
itself.
You will need user-space utilities COSA or SRP boards for downloading
the firmware to the cards and to set them up. Look at the
<http://www.fi.muni.cz/~kas/cosa/> for more information. You can also
read the comment at the top of the <file:drivers/net/wan/cosa.c> for
details about the cards and the driver itself.
The driver will be compiled as a module: the module will be called cosa.
The driver will be compiled as a module: the
module will be called cosa.
#
# COMX drivers
...
...
@@ -62,16 +65,16 @@ config COMX
tristate "MultiGate (COMX) synchronous serial boards support"
depends on WAN && (ISA || PCI) && BROKEN
---help---
Say Y if you want to use any board from the MultiGate (COMX) family.
These boards are synchronous serial adapters for the PC,
manufactured by ITConsult-Pro Co, Hungary.
Drivers for the PC synchronous serial adapters by
ITConsult-Pro Co, Hungary.
Read <file:Documentation/networking/comx.txt> for help on
configuring and using COMX interfaces. Further info on these cards
can be found
at <http://www.itc.hu/> or <info@itc.hu>.
Read <file:Documentation/networking/comx.txt> for help on
configuring
and using COMX interfaces. Further info on these cards can be found
at <http://www.itc.hu/> or <info@itc.hu>.
You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
use this driver.
Say Y if you want to use any board from the MultiGate (COMX)
family, you must also say Y to "/proc file system support"
(CONFIG_PROC_FS) in order to use these drivers.
To compile this driver as a module, choose M here: the
module will be called comx.
...
...
@@ -80,12 +83,13 @@ config COMX_HW_COMX
tristate "Support for COMX/CMX/HiCOMX boards"
depends on COMX
help
Hardware driver for the 'CMX', 'COMX' and 'HiCOMX' boards from the
MultiGate family. Say Y if you have one of these.
Driver for the 'CMX', 'COMX' and 'HiCOMX' boards.
You will need additional firmware to use these cards, which are
downloadable from <ftp://ftp.itc.hu/>.
Say Y if you have a board like this.
To compile this driver as a module, choose M here: the
module will be called comx-hw-comx.
...
...
@@ -93,7 +97,8 @@ config COMX_HW_LOCOMX
tristate "Support for LoCOMX board"
depends on COMX
help
Hardware driver for the 'LoCOMX' board from the MultiGate family.
Driver for the 'LoCOMX' board.
Say Y if you have a board like this.
To compile this driver as a module, choose M here: the
...
...
@@ -103,8 +108,7 @@ config COMX_HW_MIXCOM
tristate "Support for MixCOM board"
depends on COMX
---help---
Hardware driver for the 'MixCOM' board from the MultiGate family.
Say Y if you have a board like this.
Driver for the 'MixCOM' board.
If you want to use the watchdog device on this card, you should
select it in the Watchdog Cards section of the Character Devices
...
...
@@ -113,6 +117,8 @@ config COMX_HW_MIXCOM
driver for the flash ROM of this card is available separately on
<ftp://ftp.itc.hu/>.
Say Y if you have a board like this.
To compile this driver as a module, choose M here: the
module will be called comx-hw-mixcom.
...
...
@@ -120,58 +126,63 @@ config COMX_HW_MUNICH
tristate "Support for MUNICH based boards: SliceCOM, PCICOM (WelCOM)"
depends on COMX
---help---
Hardware driver for the 'SliceCOM' (channelized E1) and 'PciCOM'
boards (X21) from the MultiGate family.
Driver for the 'SliceCOM' (channelized E1) and 'PciCOM' (X21) boards.
Read <file:Documentation/networking/slicecom.txt> for help on
configuring and using SliceCOM interfaces. Further info on these
cards can be found at <http://www.itc.hu> or <info@itc.hu>.
Say Y if you have a board like this.
To compile this driver as a module, choose M here: the
module will be called comx-hw-munich.
Read linux/Documentation/networking/slicecom.txt for help on
configuring and using SliceCOM interfaces. Further info on these cards
can be found at http://www.itc.hu or <info@itc.hu>.
config COMX_PROTO_PPP
tristate "Support for HDLC and syncPPP protocols on MultiGate boards"
depends on COMX
help
Cisco-HDLC and synchronous PPP protocol driver for all MultiGate
boards. Say Y if you want to use either protocol on your MultiGate
boards.
Cisco-HDLC and synchronous PPP protocol driver.
To compile this as a module, choose M here: the module will be called
comx-proto-ppp.
Say Y if you want to use either protocol.
To compile this as a module, choose M here: the
module will be called comx-proto-ppp.
config COMX_PROTO_LAPB
tristate "Support for LAPB protocol on MultiGate boards"
depends on WAN && (COMX!=n && LAPB=m && LAPB || LAPB=y && COMX)
help
LAPB protocol driver for all MultiGate boards. Say Y if you
want to use this protocol on your MultiGate boards.
LAPB protocol driver.
Say Y if you want to use this protocol.
To compile this as a module, choose M here: the
module will be called
comx-proto-lapb.
To compile this as a module, choose M here: the
module will be called
comx-proto-lapb.
config COMX_PROTO_FR
tristate "Support for Frame Relay on MultiGate boards"
depends on COMX
help
Frame Relay protocol driver for all MultiGate boards. Say Y if you
want to use this protocol on your MultiGate boards.
Frame Relay protocol driver.
Say Y if you want to use this protocol.
To compile this as a module, choose M here: the
module will be called
comx-proto-fr.
To compile this as a module, choose M here: the
module will be called
comx-proto-fr.
config DSCC4
tristate "Etinc PCISYNC serial board support"
depends on WAN && PCI && m
help
This is a driver for Etinc PCISYNC boards based on the Infineon
(ex. Siemens) DSCC4 chipset. It is supposed to work with the four
ports card. Take a look at <http://www.cogenit.fr/dscc4/>
for further informations about the driver and his configuration.
Driver for Etinc PCISYNC boards based on the Infineon (ex. Siemens)
DSCC4 chipset.
To compile this driver as a module, choose M here: the module
will be called dscc4.
This is supposed to work with the four port card. Take a look at
<http://www.cogenit.fr/dscc4/> for further information about the
driver.
To compile this driver as a module, choose M here: the
module will be called dscc4.
config DSCC4_PCISYNC
bool "Etinc PCISYNC features"
...
...
@@ -188,13 +199,12 @@ config DSCC4_PCI_RST
bool "Hard reset support"
depends on DSCC4
help
Various DSCC4 bugs forbid any reliable software reset of the
asic
.
Various DSCC4 bugs forbid any reliable software reset of the
ASIC
.
As a replacement, some vendors provide a way to assert the PCI #RST
pin of DSCC4 through the GPIO port of the card. If you choose Y,
the driver will make use of this feature before module removal
(i.e. rmmod).
The feature is known to be available on Commtech's cards.
Contact your manufacturer for details.
(i.e. rmmod). The feature is known to be available on Commtech's
cards. Contact your manufacturer for details.
Say Y if your card supports this feature.
...
...
@@ -205,27 +215,27 @@ config LANMEDIA
tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards"
depends on WAN && PCI
---help---
This is a driver for the following Lan Media family of serial
boards.
Driver for the following Lan Media family of serial boards:
LMC 1000 board allows you to connect synchronous serial devices (for
example base-band modems, or any other device with the X.21, V.24
,
V.35 or V.36 interface) to your Linux box.
- LMC 1000 board allows you to connect synchronous serial devices
(for example base-band modems, or any other device with the X.21
,
V.
24, V.
35 or V.36 interface) to your Linux box.
LMC 1200 with on board DSU board allows you to connect your Linux
-
LMC 1200 with on board DSU board allows you to connect your Linux
box dirrectly to a T1 or E1 circuit.
LMC 5200 board provides a HSSI interface capable of running up to
52
m
bits per second.
-
LMC 5200 board provides a HSSI interface capable of running up to
52
M
bits per second.
LMC 5245 board connects directly to a T3 circuit saving the
-
LMC 5245 board connects directly to a T3 circuit saving the
additional external hardware.
To change setting such as syncPPP vs cisco HDLC or clock source you
will need lmcctl. It is available at <ftp://ftp.lanmedia.com/>.
To change setting such as syncPPP vs Cisco HDLC or clock source you
will need lmcctl. It is available at <ftp://ftp.lanmedia.com/>
(broken link).
To compile this driver as a module, choose M here: the
module
will be called lmc.
To compile this driver as a module, choose M here: the
module
will be called lmc.
# There is no way to detect a Sealevel board. Force it modular
config SEALEVEL_4021
...
...
@@ -234,93 +244,89 @@ config SEALEVEL_4021
help
This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
This driver can only be compiled as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
If you want to do that, say M here. The module will be called
sealevel.
The driver will be compiled as a module: the
module will be called sealevel.
config SYNCLINK_SYNCPPP
tristate "SyncLink HDLC/SYNCPPP support"
depends on WAN
help
Enables HDLC/SYNCPPP support for the SyncLink WAN driver.
Normally the SyncLink WAN driver works with the main PPP
driver (ppp.c) and pppd program. HDLC/SYNCPPP support allows use
of the Cisco HDLC/PPP driver (syncppp.c).
The SyncLink WAN driver (in character devices) must also be enabled.
Normally the SyncLink WAN driver works with the main PPP driver
<file:drivers/net/ppp_generic.c> and pppd program.
HDLC/SYNCPPP support allows use of the Cisco HDLC/PPP driver
<file:drivers/net/wan/syncppp.c>. The SyncLink WAN driver (in
character devices) must also be enabled.
# Generic HDLC
config HDLC
tristate "Generic HDLC layer"
depends on WAN
help
Say Y to this option if your Linux box contains a WAN card supported
by this driver and you are planning to connect the box to a WAN
( = Wide Area Network). You will need supporting software from
<http://hq.pm.waw.pl/hdlc/>.
Say Y to this option if your Linux box contains a WAN (Wide Area
Network) card supported by this driver and you are planning to
connect the box to a WAN.
You will need supporting software from <http://hq.pm.waw.pl/hdlc/>.
Generic HDLC driver currently supports raw HDLC, Cisco HDLC, Frame
Relay, synchronous Point-to-Point Protocol (PPP) and X.25.
To compile this driver as a module, choose M here: the
module
will be called hdlc.
To compile this driver as a module, choose M here: the
module
will be called hdlc.
If unsure, say N
here
.
If unsure, say N.
config HDLC_RAW
bool "Raw HDLC support"
depends on HDLC
help
Say Y to this option if you want generic HDLC driver to support
raw HDLC over WAN (Wide Area Network) connections.
Generic HDLC driver supporting raw HDLC over WAN connections.
If unsure, say N
here
.
If unsure, say N.
config HDLC_RAW_ETH
bool "Raw HDLC Ethernet device support"
depends on HDLC
help
Say Y to this option if you want generic HDLC driver to support
raw HDLC Ethernet device emulation over WAN (Wide Area Network)
connections.
Generic HDLC driver supporting raw HDLC Ethernet device emulation
over WAN connections.
You will need it for Ethernet over HDLC bridges.
If unsure, say N
here
.
If unsure, say N.
config HDLC_CISCO
bool "Cisco HDLC support"
depends on HDLC
help
Say Y to this option if you want generic HDLC driver to support
Cisco HDLC over WAN (Wide Area Network) connections.
Generic HDLC driver supporting Cisco HDLC over WAN connections.
If unsure, say N
here
.
If unsure, say N.
config HDLC_FR
bool "Frame Relay support"
depends on HDLC
help
Say Y to this option if you want generic HDLC driver to support
Frame-Relay protocol over WAN (Wide Area Network) connections.
Generic HDLC driver supporting Frame Relay over WAN connections.
If unsure, say N
here
.
If unsure, say N.
config HDLC_PPP
bool "Synchronous Point-to-Point Protocol (PPP) support"
depends on HDLC
help
Say Y to this option if you want generic HDLC driver to support
PPP over WAN (Wide Area Network) connections.
Generic HDLC driver supporting PPP over WAN connections.
If unsure, say N
here
.
If unsure, say N.
config HDLC_X25
bool "X.25 protocol support"
depends on HDLC && (LAPB=m && HDLC=m || LAPB=y)
help
Say Y to this option if you want generic HDLC driver to support
X.25 protocol over WAN (Wide Area Network) connections.
Generic HDLC driver supporting X.25 over WAN connections.
If unsure, say N
here
.
If unsure, say N.
comment "X.25/LAPB support is disabled"
depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
...
...
@@ -329,63 +335,61 @@ config PCI200SYN
tristate "Goramo PCI200SYN support"
depends on HDLC && PCI
help
This driver is for PCI200SYN cards made by Goramo sp. j.
Driver for PCI200SYN cards by Goramo sp. j.
If you have such a card, say Y here and see
<http://hq.pm.waw.pl/
pub/hdlc/>
<http://hq.pm.waw.pl/
hdlc/>.
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called pci200syn.
To compile this as a module, choose M here: the
module will be called pci200syn.
If unsure, say N
here
.
If unsure, say N.
config WANXL
tristate "SBE Inc. wanXL support"
depends on HDLC && PCI
help
This driver is for wanXL PCI cards made by SBE Inc. If you have
such a card, say Y here and see <http://hq.pm.waw.pl/pub/hdlc/>.
Driver for wanXL PCI cards by SBE Inc.
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The module
will be called wanxl.
If you have such a card, say Y here and see
<http://hq.pm.waw.pl/hdlc/>.
To compile this as a module, choose M here: the
module will be called wanxl.
If unsure, say N
here
.
If unsure, say N.
config WANXL_BUILD_FIRMWARE
bool "rebuild wanXL firmware"
depends on WANXL
help
This option allows you to rebuild firmware run by the QUICC
processor. It requires as68k, ld68k and hexdump programs.
You should never need this option.
Allows you to rebuild firmware run by the QUICC processor.
It requires as68k, ld68k and hexdump programs.
If unsure, say N here
.
You should never need this option, say N
.
config PC300
tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)"
depends on HDLC && PCI
---help---
This is a driver for the Cyclades-PC300 synchronous communication
boards. These boards provide synchronous serial interfaces to your
Driver for the Cyclades-PC300 synchronous communication boards.
These boards provide synchronous serial interfaces to your
Linux box (interfaces currently available are RS-232/V.35, X.21 and
T1/E1). If you wish to support Multilink PPP, please select the
option
below this one
and read the file README.mlppp provided by PC300
option
later
and read the file README.mlppp provided by PC300
package.
To compile this as a module, choose M here: the module
will be
called pc300.
To compile this as a module, choose M here: the module
will be
called pc300.
If
you haven't heard about it, it's safe to
say N.
If
unsure,
say N.
config PC300_MLPPP
bool "Cyclades-PC300 MLPPP support"
depends on PC300 && PPP_MULTILINK && PPP_SYNC_TTY && HDLC_PPP
help
Say 'Y' to this option if you are planning to use Multilink PPP over the
PC300 synchronous communication boards.
Multilink PPP over the PC300 synchronous communication boards.
comment "Cyclades-PC300 MLPPP support is disabled."
depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
...
...
@@ -397,129 +401,140 @@ config N2
tristate "SDL RISCom/N2 support"
depends on HDLC && ISA
help
This driver is for RISCom/N2 single or dual channel ISA cards
made by SDL Communications Inc. If you have such a card,
say Y here and see <http://hq.pm.waw.pl/pub/hdlc/>.
Driver for RISCom/N2 single or dual channel ISA cards by
SDL Communications Inc.
If you have such a card, say Y here and see
<http://hq.pm.waw.pl/hdlc/>.
Note that N2csu and N2dds cards are not supported by this driver.
To compile this driver as a module, choose M here: the module
will be called n2.
If unsure, say N
here
.
If unsure, say N.
config C101
tristate "Moxa C101 support"
depends on HDLC && ISA
help
This driver is for C101 SuperSync ISA cards made by Moxa
Technologies Co., Ltd. If you have such a card,
say Y here and see <http://hq.pm.waw.pl/pub/hdlc/>
Driver for C101 SuperSync ISA cards by Moxa Technologies Co., Ltd.
To compile this driver as a module, choose M here: the module
will be called c101.
If you have such a card, say Y here and see
<http://hq.pm.waw.pl/pub/hdlc/>
To compile this driver as a module, choose M here: the
module will be called c101.
If unsure, say N
here
.
If unsure, say N.
config FARSYNC
tristate "FarSync T-Series support"
depends on HDLC && PCI
---help---
This driver supports the FarSync T-Series X.21 (and V.35/V.24) cards
from FarSite Communications Ltd.
Support for the FarSync T-Series X.21 (and V.35/V.24) cards by
FarSite Communications Ltd.
Synchronous communication is supported on all ports at speeds up to
8Mb/s (128K on V.24) using synchronous PPP, Cisco HDLC, raw HDLC,
Frame Relay or X.25/LAPB.
To compile this driver as a module, choose M here: the module will be
called farsync. If you want the module to be automatically loaded
when the interface is referenced then you should add
"alias hdlcX farsync" to /etc/modules.conf for each interface, where
X is 0, 1, 2, ...
If you want the module to be automatically loaded when the interface
is referenced then you should add "alias hdlcX farsync" to
/etc/modules.conf for each interface, where X is 0, 1, 2, ...
To compile this driver as a module, choose M here: the
module will be called farsync.
config DLCI
tristate "Frame
r
elay DLCI support"
tristate "Frame
R
elay DLCI support"
depends on WAN
---help---
This is support for the frame relay protocol; frame relay is a fast
low-cost way to connect to a remote Internet access provider or to
form a private wide area network. The one physical line from your
box to the local "switch" (i.e. the entry point to the frame relay
network, usually at the phone company) can carry several logical
point-to-point connections to other computers connected to the frame
relay network. For a general explanation of the protocol, check out
<http://www.frforum.com/> on the WWW. To use frame relay, you need
supporting hardware (called FRAD) and certain programs from the
net-tools package as explained in
Support for the Frame Relay protocol.
Frame Relay is a fast low-cost way to connect to a remote Internet
access provider or to form a private wide area network. The one
physical line from your box to the local "switch" (i.e. the entry
point to the Frame Relay network, usually at the phone company) can
carry several logical point-to-point connections to other computers
connected to the Frame Relay network. For a general explanation of
the protocol, check out <http://www.mplsforum.org/>.
To use frame relay, you need supporting hardware (called FRAD) and
certain programs from the net-tools package as explained in
<file:Documentation/networking/framerelay.txt>.
To compile this driver as a module, choose M here: the
module will be
called dlci.
To compile this driver as a module, choose M here: the
module will be
called dlci.
config DLCI_COUNT
int "Max open DLCI"
depends on DLCI
default "24"
help
This is the maximal number of logical point-to-point frame relay
connections (the identifiers of which are called DCLIs) that
the driver can handle. The default is probably fine.
Maximal number of logical point-to-point frame relay connections
(the identifiers of which are called DCLIs) that the driver can
handle.
The default is probably fine.
config DLCI_MAX
int "Max DLCI per device"
depends on DLCI
default "8"
help
You can specify here how many logical point-to-point frame relay
connections (the identifiers of which are called DCLIs) should be
handled by each of your hardware frame relay access devices. Go with
the default.
How many logical point-to-point frame relay connections (the
identifiers of which are called DCLIs) should be handled by each
of your hardware frame relay access devices.
Go with the default.
config SDLA
tristate "SDLA (Sangoma S502/S508) support"
depends on DLCI && ISA
help
Say Y here if you need a driver for the Sangoma S502A, S502E, and
S508 Frame Relay Access Devices. These are multi-protocol cards, but
only frame relay is supported by the driver at this time. Please
read <file:Documentation/networking/framerelay.txt>.
Driver for the Sangoma S502A, S502E, and S508 Frame Relay Access
Devices.
To compile this driver as a module, choose M here: the module will be
called sdla.
These are multi-protocol cards, but only Frame Relay is supported
by the driver at this time. Please read
<file:Documentation/networking/framerelay.txt>.
To compile this driver as a module, choose M here: the
module will be called sdla.
# Wan router core.
config WAN_ROUTER_DRIVERS
bool "WAN router drivers"
depends on WAN && WAN_ROUTER
---help---
If you have a WAN interface card and you want your Linux box to act
as a WAN router, thereby connecting you Local Area Network to the
outside world over the WAN connection, say Y here and then to the
driver for your card below. In addition, you need to say Y to "Wan
Router".
Connect LAN to WAN via Linux box.
Select driver your card and remember to say Y to "Wan Router."
You will need the wan-tools package which is available from
<ftp://ftp.sangoma.com/>.
Read
<file:Documentation/networking/wan-router.txt>
for more information
.
<ftp://ftp.sangoma.com/>.
For more information read:
<file:Documentation/networking/wan-router.txt>.
Note that the answer to this question won't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about WAN router drivers. If unsure, say N.
the questions about WAN router drivers.
If unsure, say N.
config VENDOR_SANGOMA
tristate "Sangoma WANPIPE(tm) multiprotocol cards"
depends on WAN_ROUTER_DRIVERS && WAN_ROUTER && (PCI || ISA) && BROKEN
---help---
WANPIPE from Sangoma Technologies Inc. (<http://www.sangoma.com/>)
Driver for S514-PCI/ISA Synchronous Data Link Adapters (SDLA).
WANPIPE from Sangoma Technologies Inc. <http://www.sangoma.com/>
is a family of intelligent multiprotocol WAN adapters with data
transfer rates up to 4Mbps. They are also known as Synchronous
Data Link Adapters (SDLA) and are designated as S514-PCI or
S508-ISA. These cards support
transfer rates up to 4Mbps. Cards support:
- X.25, Frame Relay, PPP, Cisco HDLC protocols.
- API
support for protocols like HDLC (LAPB)
,
HDLC Streaming, X.25,
Frame Relay and BiSync.
- API
for protocols like HDLC (LAPB), HDLC Streaming, X.25
,
Frame Relay and BiSync.
- Ethernet Bridging over Frame Relay protocol.
...
...
@@ -527,88 +542,89 @@ config VENDOR_SANGOMA
- Async PPP (Modem Dialup)
If you have one or more of these cards, say M to this option; you
may then also want to read the file
<file:Documentation/networking/wanpipe.txt>. The next questions
will ask you about the protocols you want the driver to support.
The next questions will ask you about the protocols you want
the driver to support.
To compile this driver as a module, choose M here: the module will
be called wanpipe.
If you have one or more of these cards, say M to this option;
and read <file:Documentation/networking/wanpipe.txt>.
To compile this driver as a module, choose M here: the
module will be called wanpipe.
config WANPIPE_CHDLC
bool "WANPIPE Cisco HDLC support"
depends on VENDOR_SANGOMA
---help---
Say Y to this option if you are planning to connect a WANPIPE card
to a leased line using the Cisco HDLC protocol. This now supports
Dual Port Cisco HDLC on the S514-PCI/S508-ISA cards.
This support also allows user to build applications using the
HDLC streaming API.
Connect a WANPIPE card to a leased line using the Cisco HDLC.
- Supports Dual Port Cisco HDLC on the S514-PCI/S508-ISA cards
which allows user to build applications using the HDLC streaming API.
CHDLC Streaming driver also supports MULTILINK PPP
support that can bind multiple WANPIPE T1 cards into
a single logical channel.
- CHDLC Streaming MULTILINK PPP that can bind multiple WANPIPE T1
cards into a single logical channel.
If you say N, the Cisco HDLC support and
HDLC streaming API and MULTILINK PPP will not be
included in the driver.
Say Y and the Cisco HDLC support, HDLC streaming API and
MULTILINK PPP will be included in the driver.
config WANPIPE_FR
bool "WANPIPE Frame Relay support"
depends on VENDOR_SANGOMA
help
Say Y to this option if you are planning to connect a WANPIPE card
to a frame relay network, or use frame relay API to develope
custom applications over the Frame Relay protocol.
This feature also contains the Ethernet Bridging over Frame Relay,
where a WANPIPE frame relay link can be directly connected to the
Linux kernel bridge. If you say N, the frame relay support will
not be included in the driver. The Frame Relay option is
supported on S514-PCI and S508-ISA cards.
Connect a WANPIPE card to a Frame Relay network, or use Frame Felay
API to develope custom applications.
Contains the Ethernet Bridging over Frame Relay feature, where
a WANPIPE frame relay link can be directly connected to the Linux
kernel bridge. The Frame Relay option is supported on S514-PCI
and S508-ISA cards.
Say Y and the Frame Relay support will be included in the driver.
config WANPIPE_X25
bool "WANPIPE X.25 support"
depends on VENDOR_SANGOMA
help
Say Y to this option if you are planning to connect a WANPIPE card
to an X.25 network. Note, this feature also includes the X.25 API
support used to develope custom applications over the X.25 protocol.
If you say N, the X.25 support will not be included in the driver.
The X.25 option is supported on S514-PCI and S508-ISA cards.
Connect a WANPIPE card to an X.25 network.
Includes the X.25 API support for custom applications over the
X.25 protocol. The X.25 option is supported on S514-PCI and
S508-ISA cards.
Say Y and the X.25 support will be included in the driver.
config WANPIPE_PPP
bool "WANPIPE PPP support"
depends on VENDOR_SANGOMA
help
Say Y to this option if you are planning to connect a WANPIPE card
to a leased line using Point-to-Point protocol (PPP). If you say N,
the PPP support will not be included in the driver. The PPP option
is supported on S514-PCI/S508-ISA cards.
Connect a WANPIPE card to a leased line using Point-to-Point
Protocol (PPP).
The PPP option is supported on S514-PCI/S508-ISA cards.
Say Y and the PPP support will be included in the driver.
config WANPIPE_MULTPPP
bool "WANPIPE Multi-Port PPP support"
depends on VENDOR_SANGOMA
help
Say Y to this option if you are planning to connect a WANPIPE card
to a leased line using Point-to-Point protocol (PPP). Note, the
MultiPort PPP uses the Linux Kernel SyncPPP protocol over the
Sangoma HDLC Streaming adapter. In this case each Sangoma adapter
port can support an independent PPP connection. For example, a
single Quad-Port PCI adapter can support up to four independent
PPP links. If you say N,the PPP support will not be included in the
driver. The PPP option is supported on S514-PCI/S508-ISA cards.
Connect a WANPIPE card to a leased line using Point-to-Point
Protocol (PPP).
Uses in-kernel SyncPPP protocol over the Sangoma HDLC Streaming
adapter. In this case each Sangoma adapter port can support an
independent PPP connection. For example, a single Quad-Port PCI
adapter can support up to four independent PPP links. The PPP
option is supported on S514-PCI/S508-ISA cards.
Say Y and the Multi-Port PPP support will be included in the driver.
config CYCLADES_SYNC
tristate "Cyclom 2X(tm) cards (EXPERIMENTAL)"
depends on WAN_ROUTER_DRIVERS && (PCI || ISA)
---help---
Cyclom 2X from Cyclades Corporation (<http://www.cyclades.com/> and
<http://www.cyclades.com.br/>) is an intelligent multiprotocol WAN
adapter with data transfer rates up to 512 Kbps. These cards support
the X.25 and SNA related protocols. If you have one or more of these
cards, say Y to this option. The next questions will ask you about
the protocols you want the driver to support (for now only X.25 is
supported).
Cyclom 2X from Cyclades Corporation <http://www.cyclades.com/> is an
intelligent multiprotocol WAN adapter with data transfer rates up to
512 Kbps. These cards support the X.25 and SNA related protocols.
While no documentation is available at this time please grab the
wanconfig tarball in
...
...
@@ -618,75 +634,85 @@ config CYCLADES_SYNC
<ftp://ftp.sangoma.com/>).
Feel free to contact me or the cycsyn-devel mailing list at
acme@conectiva.com.br and cycsyn-devel@bazar.conectiva.com.br for
additional details, I hope to have documentation available as soon
as possible. (Cyclades Brazil is writing the Documentation).
<acme@conectiva.com.br> and <cycsyn-devel@bazar.conectiva.com.br> for
additional details, I hope to have documentation available as soon as
possible. (Cyclades Brazil is writing the Documentation).
The next questions will ask you about the protocols you want the
driver to support (for now only X.25 is supported).
To compile this driver as a module, choose M here: the module will be
called cyclomx.
If you have one or more of these cards, say Y to this option.
To compile this driver as a module, choose M here: the
module will be called cyclomx.
config CYCLOMX_X25
bool "Cyclom 2X X.25 support (EXPERIMENTAL)"
depends on CYCLADES_SYNC
help
Say Y to this option if you are planning to connect a Cyclom 2X card
to an X.25 network.
Connect a Cyclom 2X card to an X.25 network.
If you say N, the X.25 support will not be included in the driver
(saves about 11 KB of kernel memory).
Enabling X.25 support will enlarge your kernel by about 11 kB.
# X.25 network drivers
config LAPBETHER
tristate "LAPB over Ethernet driver (EXPERIMENTAL)"
depends on WAN && LAPB && X25
---help---
This is a driver for a pseudo device (typically called /dev/lapb0)
which allows you to open an LAPB point-to-point connection to some
other computer on your Ethernet network. In order to do this, you
need to say Y or M to the driver for your Ethernet card as well as
to "LAPB Data Link Driver".
Driver for a pseudo device (typically called /dev/lapb0) which allows
you to open an LAPB point-to-point connection to some other computer
on your Ethernet network.
To compile this driver as a module, choose M here: the module
will be called lapbether. If unsure, say N.
In order to do this, you need to say Y or M to the driver for your
Ethernet card as well as to "LAPB Data Link Driver".
To compile this driver as a module, choose M here: the
module will be called lapbether.
If unsure, say N.
config X25_ASY
tristate "X.25 async driver (EXPERIMENTAL)"
depends on WAN && LAPB && X25
---help---
This is a driver for sending and receiving X.25 frames over regular
asynchronous serial lines such as telephone lines equipped with
ordinary modems. Experts should note that this driver doesn't
currently comply with the asynchronous HDLS framing protocols in
CCITT recommendation X.25.
Send and receive X.25 frames over regular asynchronous serial
lines such as telephone lines equipped with ordinary modems.
To compile this driver as a module, choose M here: the module
will be called x25_asy. If unsure, say N.
Experts should note that this driver doesn't currently comply with
the asynchronous HDLS framing protocols in CCITT recommendation X.25.
To compile this driver as a module, choose M here: the
module will be called x25_asy.
If unsure, say N.
config SBNI
tristate "Granch SBNI12 Leased Line adapter support"
depends on WAN && X86
---help---
This is a driver for ISA SBNI12-xx cards which are low cost
alternatives to leased line modems. Say Y if you want to insert
the driver into the kernel or say M to compile it as a module (the
module will be called sbni).
Driver for ISA SBNI12-xx cards which are low cost alternatives to
leased line modems.
You can find more information and last versions of drivers and
utilities at <http://www.granch.ru/>. If you have any question you
can send email to
sbni@granch.ru
.
can send email to
<sbni@granch.ru>
.
Say N if unsure.
To compile this driver as a module, choose M here: the
module will be called sbni.
If unsure, say N.
config SBNI_MULTILINE
bool "Multiple line feature support"
depends on SBNI
help
Schedule traffic for some parallel lines, via SBNI12 adapters.
If you have two computers connected with two parallel lines it's
possible to increase transfer rate nearly twice. You should have
a program named 'sbniconfig' to configure adapters.
Say N if unsure
.
If unsure, say N
.
endmenu
drivers/scsi/libata-core.c
View file @
bd86acf1
/*
libata-core.c - helper library for ATA
Copyright 2003
-2004
Red Hat, Inc. All rights reserved.
Copyright 2003
-2004
Jeff Garzik
Copyright 2003 Red Hat, Inc. All rights reserved.
Copyright 2003 Jeff Garzik
The contents of this file are subject to the Open
Software License version 1.1 that can be found at
...
...
@@ -2385,6 +2385,41 @@ static inline unsigned int ata_host_intr (struct ata_port *ap,
return
handled
;
}
/**
* ata_chk_spurious_int - Check for spurious interrupts
* @ap: port to which command is being issued
*
* Examines the DMA status registers and clears
* unexpected interrupts. Created to work around
* hardware bug on Intel ICH5, but is applied to all
* chipsets using the standard irq handler, just for safety.
* If the bug is not present, this is simply a single
* PIO or MMIO read addition to the irq handler.
*
* LOCKING:
*/
static
inline
void
ata_chk_spurious_int
(
struct
ata_port
*
ap
)
{
int
host_stat
;
if
(
ap
->
flags
&
ATA_FLAG_MMIO
)
{
void
*
mmio
=
(
void
*
)
ap
->
ioaddr
.
bmdma_addr
;
host_stat
=
readb
(
mmio
+
ATA_DMA_STATUS
);
}
else
host_stat
=
inb
(
ap
->
ioaddr
.
bmdma_addr
+
ATA_DMA_STATUS
);
if
((
host_stat
&
(
ATA_DMA_INTR
|
ATA_DMA_ERR
|
ATA_DMA_ACTIVE
))
==
ATA_DMA_INTR
)
{
if
(
ap
->
flags
&
ATA_FLAG_MMIO
)
{
void
*
mmio
=
(
void
*
)
ap
->
ioaddr
.
bmdma_addr
;
writeb
(
host_stat
&
~
ATA_DMA_ERR
,
mmio
+
ATA_DMA_STATUS
);
}
else
outb
(
host_stat
&
~
ATA_DMA_ERR
,
ap
->
ioaddr
.
bmdma_addr
+
ATA_DMA_STATUS
);
DPRINTK
(
"ata%u: Caught spurious interrupt, status 0x%X
\n
"
,
ap
->
id
,
host_stat
);
udelay
(
1
);
}
}
/**
* ata_interrupt -
* @irq:
...
...
@@ -2417,6 +2452,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
qc
=
ata_qc_from_tag
(
ap
,
ap
->
active_tag
);
if
(
qc
&&
((
qc
->
flags
&
ATA_QCFLAG_POLL
)
==
0
))
handled
+=
ata_host_intr
(
ap
,
qc
);
ata_chk_spurious_int
(
ap
);
}
}
...
...
drivers/serial/8250.c
View file @
bd86acf1
...
...
@@ -1976,6 +1976,8 @@ static int __init serial8250_console_setup(struct console *co, char *options)
if
(
co
->
index
>=
UART_NR
)
co
->
index
=
0
;
port
=
&
serial8250_ports
[
co
->
index
].
port
;
if
(
port
->
type
==
PORT_UNKNOWN
)
return
-
ENODEV
;
/*
* Temporary fix.
...
...
@@ -2007,6 +2009,14 @@ static int __init serial8250_console_init(void)
}
console_initcall
(
serial8250_console_init
);
static
int
__init
serial8250_late_console_init
(
void
)
{
if
(
!
(
serial8250_console
.
flags
&
CON_ENABLED
))
register_console
(
&
serial8250_console
);
return
0
;
}
late_initcall
(
serial8250_late_console_init
);
#define SERIAL8250_CONSOLE &serial8250_console
#else
#define SERIAL8250_CONSOLE NULL
...
...
drivers/serial/serial_core.c
View file @
bd86acf1
...
...
@@ -1871,9 +1871,6 @@ uart_set_options(struct uart_port *port, struct console *co,
if
(
flow
==
'r'
)
termios
.
c_cflag
|=
CRTSCTS
;
if
(
!
port
->
ops
)
return
0
;
/* "console=" on ia64 */
port
->
ops
->
set_termios
(
port
,
&
termios
,
NULL
);
co
->
cflag
=
termios
.
c_cflag
;
...
...
include/linux/inetdevice.h
View file @
bd86acf1
...
...
@@ -18,6 +18,8 @@ struct ipv4_devconf
int
mc_forwarding
;
int
tag
;
int
arp_filter
;
int
arp_announce
;
int
arp_ignore
;
int
medium_id
;
int
no_xfrm
;
int
no_policy
;
...
...
@@ -71,6 +73,8 @@ struct in_device
(ipv4_devconf.accept_redirects || (in_dev)->cnf.accept_redirects)))
#define IN_DEV_ARPFILTER(in_dev) (ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter)
#define IN_DEV_ARP_ANNOUNCE(in_dev) (max(ipv4_devconf.arp_announce, (in_dev)->cnf.arp_announce))
#define IN_DEV_ARP_IGNORE(in_dev) (max(ipv4_devconf.arp_ignore, (in_dev)->cnf.arp_ignore))
struct
in_ifaddr
{
...
...
@@ -97,6 +101,7 @@ extern void devinet_init(void);
extern
struct
in_device
*
inetdev_init
(
struct
net_device
*
dev
);
extern
struct
in_device
*
inetdev_by_index
(
int
);
extern
u32
inet_select_addr
(
const
struct
net_device
*
dev
,
u32
dst
,
int
scope
);
extern
u32
inet_confirm_addr
(
const
struct
net_device
*
dev
,
u32
dst
,
u32
local
,
int
scope
);
extern
struct
in_ifaddr
*
inet_ifa_byprefix
(
struct
in_device
*
in_dev
,
u32
prefix
,
u32
mask
);
extern
void
inet_forward_change
(
void
);
...
...
include/linux/ipv6.h
View file @
bd86acf1
...
...
@@ -136,6 +136,7 @@ struct ipv6_devconf {
__s32
rtr_solicits
;
__s32
rtr_solicit_interval
;
__s32
rtr_solicit_delay
;
__s32
force_mld_version
;
#ifdef CONFIG_IPV6_PRIVACY
__s32
use_tempaddr
;
__s32
temp_valid_lft
;
...
...
@@ -165,6 +166,7 @@ enum {
DEVCONF_REGEN_MAX_RETRY
,
DEVCONF_MAX_DESYNC_FACTOR
,
DEVCONF_MAX_ADDRESSES
,
DEVCONF_FORCE_MLD_VERSION
,
DEVCONF_MAX
};
...
...
include/linux/ipv6_route.h
View file @
bd86acf1
...
...
@@ -24,7 +24,6 @@
#define RTF_CACHE 0x01000000
/* cache entry */
#define RTF_FLOW 0x02000000
/* flow significant route */
#define RTF_POLICY 0x04000000
/* policy route */
#define RTF_NDISC 0x08000000
/* ndisc route */
#define RTF_LOCAL 0x80000000
...
...
include/linux/skbuff.h
View file @
bd86acf1
...
...
@@ -163,6 +163,7 @@ struct skb_shared_info {
* @cb: Control buffer. Free for use by every layer. Put private vars here
* @len: Length of actual data
* @data_len: Data length
* @mac_len: Length of link layer header
* @csum: Checksum
* @__unused: Dead field, may be reused
* @cloned: Head may be cloned (check refcnt to be sure)
...
...
@@ -204,6 +205,7 @@ struct sk_buff {
struct
icmphdr
*
icmph
;
struct
igmphdr
*
igmph
;
struct
iphdr
*
ipiph
;
struct
ipv6hdr
*
ipv6h
;
unsigned
char
*
raw
;
}
h
;
...
...
@@ -232,6 +234,7 @@ struct sk_buff {
unsigned
int
len
,
data_len
,
mac_len
,
csum
;
unsigned
char
local_df
,
cloned
,
...
...
include/linux/sysctl.h
View file @
bd86acf1
...
...
@@ -362,6 +362,8 @@ enum
NET_IPV4_CONF_NOXFRM
=
15
,
NET_IPV4_CONF_NOPOLICY
=
16
,
NET_IPV4_CONF_FORCE_IGMP_VERSION
=
17
,
NET_IPV4_CONF_ARP_ANNOUNCE
=
18
,
NET_IPV4_CONF_ARP_IGNORE
=
19
,
};
/* /proc/sys/net/ipv4/netfilter */
...
...
@@ -423,7 +425,8 @@ enum {
NET_IPV6_TEMP_PREFERED_LFT
=
13
,
NET_IPV6_REGEN_MAX_RETRY
=
14
,
NET_IPV6_MAX_DESYNC_FACTOR
=
15
,
NET_IPV6_MAX_ADDRESSES
=
16
NET_IPV6_MAX_ADDRESSES
=
16
,
NET_IPV6_FORCE_MLD_VERSION
=
17
};
/* /proc/sys/net/ipv6/icmp */
...
...
include/net/addrconf.h
View file @
bd86acf1
...
...
@@ -98,6 +98,7 @@ extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
extern
int
ipv6_chk_mcast_addr
(
struct
net_device
*
dev
,
struct
in6_addr
*
group
,
struct
in6_addr
*
src_addr
);
extern
int
ipv6_is_mld
(
struct
sk_buff
*
skb
,
int
nexthdr
);
extern
void
addrconf_prefix_rcv
(
struct
net_device
*
dev
,
u8
*
opt
,
int
len
);
...
...
include/net/ip6_route.h
View file @
bd86acf1
...
...
@@ -64,6 +64,7 @@ extern struct rt6_info *rt6_lookup(struct in6_addr *daddr,
extern
struct
dst_entry
*
ndisc_dst_alloc
(
struct
net_device
*
dev
,
struct
neighbour
*
neigh
,
struct
in6_addr
*
addr
,
int
(
*
output
)(
struct
sk_buff
*
));
extern
int
ndisc_dst_gc
(
int
*
more
);
extern
void
fib6_force_start_gc
(
void
);
...
...
include/net/ip_vs.h
View file @
bd86acf1
...
...
@@ -8,7 +8,7 @@
#include <asm/types.h>
/* For __uXX types */
#define IP_VS_VERSION_CODE 0x010
108
#define IP_VS_VERSION_CODE 0x010
200
#define NVERSION(version) \
(version >> 16) & 0xFF, \
(version >> 8) & 0xFF, \
...
...
include/net/ipv6.h
View file @
bd86acf1
...
...
@@ -355,6 +355,7 @@ extern int ip6_dst_lookup(struct sock *sk,
*/
extern
int
ip6_output
(
struct
sk_buff
*
skb
);
extern
int
ip6_output2
(
struct
sk_buff
*
skb
);
extern
int
ip6_forward
(
struct
sk_buff
*
skb
);
extern
int
ip6_input
(
struct
sk_buff
*
skb
);
extern
int
ip6_mc_input
(
struct
sk_buff
*
skb
);
...
...
net/core/dev.c
View file @
bd86acf1
...
...
@@ -1742,6 +1742,7 @@ int netif_receive_skb(struct sk_buff *skb)
#endif
skb
->
h
.
raw
=
skb
->
nh
.
raw
=
skb
->
data
;
skb
->
mac_len
=
skb
->
nh
.
raw
-
skb
->
mac
.
raw
;
pt_prev
=
NULL
;
rcu_read_lock
();
...
...
net/core/ethtool.c
View file @
bd86acf1
...
...
@@ -374,7 +374,7 @@ static int ethtool_set_ringparam(struct net_device *dev, void *useraddr)
{
struct
ethtool_ringparam
ringparam
;
if
(
!
dev
->
ethtool_ops
->
g
et_ringparam
)
if
(
!
dev
->
ethtool_ops
->
s
et_ringparam
)
return
-
EOPNOTSUPP
;
if
(
copy_from_user
(
&
ringparam
,
useraddr
,
sizeof
(
ringparam
)))
...
...
net/core/neighbour.c
View file @
bd86acf1
...
...
@@ -1164,8 +1164,7 @@ void neigh_table_init(struct neigh_table *tbl)
if
(
!
tbl
->
kmem_cachep
)
tbl
->
kmem_cachep
=
kmem_cache_create
(
tbl
->
id
,
(
tbl
->
entry_size
+
15
)
&
~
15
,
tbl
->
entry_size
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
tbl
->
lock
=
RW_LOCK_UNLOCKED
;
...
...
net/core/pktgen.c
View file @
bd86acf1
...
...
@@ -50,6 +50,8 @@
* Fix refcount off by one if first packet fails, potential null deref,
* memleak 030710- KJP
*
* Fixed unaligned access on IA-64 Grant Grundler <grundler@parisc-linux.org>
*
* See Documentation/networking/pktgen.txt for how to use this.
*/
...
...
@@ -88,7 +90,7 @@
#define cycles() ((u32)get_cycles())
#define VERSION "pktgen version 1.3
1
"
#define VERSION "pktgen version 1.3
2
"
static
char
version
[]
__initdata
=
"pktgen.c: v1.3: Packet Generator for packet performance testing.
\n
"
;
...
...
@@ -193,7 +195,8 @@ struct pktgen_info {
struct
pktgen_hdr
{
__u32
pgh_magic
;
__u32
seq_num
;
struct
timeval
timestamp
;
__u32
tv_sec
;
__u32
tv_usec
;
};
static
int
cpu_speed
;
...
...
@@ -563,11 +566,14 @@ static struct sk_buff *fill_packet(struct net_device *odev, struct pktgen_info*
/* Stamp the time, and sequence number, convert them to network byte order */
if
(
pgh
)
{
struct
timeval
timestamp
;
pgh
->
pgh_magic
=
htonl
(
PKTGEN_MAGIC
);
do_gettimeofday
(
&
(
pgh
->
timestamp
));
pgh
->
timestamp
.
tv_usec
=
htonl
(
pgh
->
timestamp
.
tv_usec
);
pgh
->
timestamp
.
tv_sec
=
htonl
(
pgh
->
timestamp
.
tv_sec
);
pgh
->
seq_num
=
htonl
(
info
->
seq_num
);
pgh
->
seq_num
=
htonl
(
info
->
seq_num
);
do_gettimeofday
(
&
timestamp
);
pgh
->
tv_sec
=
htonl
(
timestamp
.
tv_sec
);
pgh
->
tv_usec
=
htonl
(
timestamp
.
tv_usec
);
}
return
skb
;
...
...
net/decnet/dn_rules.c
View file @
bd86acf1
...
...
@@ -381,7 +381,7 @@ static int dn_fib_fill_rule(struct sk_buff *skb, struct dn_fib_rule *r, struct n
nlmsg_failure:
rtattr_failure:
skb_
put
(
skb
,
b
-
skb
->
tail
);
skb_
trim
(
skb
,
b
-
skb
->
data
);
return
-
1
;
}
...
...
net/ipv4/arp.c
View file @
bd86acf1
...
...
@@ -325,15 +325,40 @@ static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb)
static
void
arp_solicit
(
struct
neighbour
*
neigh
,
struct
sk_buff
*
skb
)
{
u32
saddr
;
u32
saddr
=
0
;
u8
*
dst_ha
=
NULL
;
struct
net_device
*
dev
=
neigh
->
dev
;
u32
target
=
*
(
u32
*
)
neigh
->
primary_key
;
int
probes
=
atomic_read
(
&
neigh
->
probes
);
struct
in_device
*
in_dev
=
in_dev_get
(
dev
);
if
(
!
in_dev
)
return
;
if
(
skb
&&
inet_addr_type
(
skb
->
nh
.
iph
->
saddr
)
==
RTN_LOCAL
)
switch
(
IN_DEV_ARP_ANNOUNCE
(
in_dev
))
{
default:
case
0
:
/* By default announce any local IP */
if
(
skb
&&
inet_addr_type
(
skb
->
nh
.
iph
->
saddr
)
==
RTN_LOCAL
)
saddr
=
skb
->
nh
.
iph
->
saddr
;
break
;
case
1
:
/* Restrict announcements of saddr in same subnet */
if
(
!
skb
)
break
;
saddr
=
skb
->
nh
.
iph
->
saddr
;
else
if
(
inet_addr_type
(
saddr
)
==
RTN_LOCAL
)
{
/* saddr should be known to target */
if
(
inet_addr_onlink
(
in_dev
,
target
,
saddr
))
break
;
}
saddr
=
0
;
break
;
case
2
:
/* Avoid secondary IPs, get a primary/preferred one */
break
;
}
if
(
in_dev
)
in_dev_put
(
in_dev
);
if
(
!
saddr
)
saddr
=
inet_select_addr
(
dev
,
target
,
RT_SCOPE_LINK
);
if
((
probes
-=
neigh
->
parms
->
ucast_probes
)
<
0
)
{
...
...
@@ -354,6 +379,42 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
read_unlock_bh
(
&
neigh
->
lock
);
}
static
int
arp_ignore
(
struct
in_device
*
in_dev
,
struct
net_device
*
dev
,
u32
sip
,
u32
tip
)
{
int
scope
;
switch
(
IN_DEV_ARP_IGNORE
(
in_dev
))
{
case
0
:
/* Reply, the tip is already validated */
return
0
;
case
1
:
/* Reply only if tip is configured on the incoming interface */
sip
=
0
;
scope
=
RT_SCOPE_HOST
;
break
;
case
2
:
/*
* Reply only if tip is configured on the incoming interface
* and is in same subnet as sip
*/
scope
=
RT_SCOPE_HOST
;
break
;
case
3
:
/* Do not reply for scope host addresses */
sip
=
0
;
scope
=
RT_SCOPE_LINK
;
dev
=
NULL
;
break
;
case
4
:
/* Reserved */
case
5
:
case
6
:
case
7
:
return
0
;
case
8
:
/* Do not reply */
return
1
;
default:
return
0
;
}
return
!
inet_confirm_addr
(
dev
,
sip
,
tip
,
scope
);
}
static
int
arp_filter
(
__u32
sip
,
__u32
tip
,
struct
net_device
*
dev
)
{
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
sip
,
...
...
@@ -764,7 +825,8 @@ int arp_process(struct sk_buff *skb)
/* Special case: IPv4 duplicate address detection packet (RFC2131) */
if
(
sip
==
0
)
{
if
(
arp
->
ar_op
==
htons
(
ARPOP_REQUEST
)
&&
inet_addr_type
(
tip
)
==
RTN_LOCAL
)
inet_addr_type
(
tip
)
==
RTN_LOCAL
&&
!
arp_ignore
(
in_dev
,
dev
,
sip
,
tip
))
arp_send
(
ARPOP_REPLY
,
ETH_P_ARP
,
tip
,
dev
,
tip
,
sha
,
dev
->
dev_addr
,
dev
->
dev_addr
);
goto
out
;
}
...
...
@@ -779,7 +841,10 @@ int arp_process(struct sk_buff *skb)
n
=
neigh_event_ns
(
&
arp_tbl
,
sha
,
&
sip
,
dev
);
if
(
n
)
{
int
dont_send
=
0
;
if
(
IN_DEV_ARPFILTER
(
in_dev
))
if
(
!
dont_send
)
dont_send
|=
arp_ignore
(
in_dev
,
dev
,
sip
,
tip
);
if
(
!
dont_send
&&
IN_DEV_ARPFILTER
(
in_dev
))
dont_send
|=
arp_filter
(
sip
,
tip
,
dev
);
if
(
!
dont_send
)
arp_send
(
ARPOP_REPLY
,
ETH_P_ARP
,
sip
,
dev
,
tip
,
sha
,
dev
->
dev_addr
,
sha
);
...
...
net/ipv4/devinet.c
View file @
bd86acf1
...
...
@@ -809,6 +809,84 @@ u32 inet_select_addr(const struct net_device *dev, u32 dst, int scope)
goto
out
;
}
static
u32
confirm_addr_indev
(
struct
in_device
*
in_dev
,
u32
dst
,
u32
local
,
int
scope
)
{
int
same
=
0
;
u32
addr
=
0
;
for_ifa
(
in_dev
)
{
if
(
!
addr
&&
(
local
==
ifa
->
ifa_local
||
!
local
)
&&
ifa
->
ifa_scope
<=
scope
)
{
addr
=
ifa
->
ifa_local
;
if
(
same
)
break
;
}
if
(
!
same
)
{
same
=
(
!
local
||
inet_ifa_match
(
local
,
ifa
))
&&
(
!
dst
||
inet_ifa_match
(
dst
,
ifa
));
if
(
same
&&
addr
)
{
if
(
local
||
!
dst
)
break
;
/* Is the selected addr into dst subnet? */
if
(
inet_ifa_match
(
addr
,
ifa
))
break
;
/* No, then can we use new local src? */
if
(
ifa
->
ifa_scope
<=
scope
)
{
addr
=
ifa
->
ifa_local
;
break
;
}
/* search for large dst subnet for addr */
same
=
0
;
}
}
}
endfor_ifa
(
in_dev
);
return
same
?
addr
:
0
;
}
/*
* Confirm that local IP address exists using wildcards:
* - dev: only on this interface, 0=any interface
* - dst: only in the same subnet as dst, 0=any dst
* - local: address, 0=autoselect the local address
* - scope: maximum allowed scope value for the local address
*/
u32
inet_confirm_addr
(
const
struct
net_device
*
dev
,
u32
dst
,
u32
local
,
int
scope
)
{
u32
addr
=
0
;
struct
in_device
*
in_dev
;
if
(
dev
)
{
read_lock
(
&
inetdev_lock
);
if
((
in_dev
=
__in_dev_get
(
dev
)))
{
read_lock
(
&
in_dev
->
lock
);
addr
=
confirm_addr_indev
(
in_dev
,
dst
,
local
,
scope
);
read_unlock
(
&
in_dev
->
lock
);
}
read_unlock
(
&
inetdev_lock
);
return
addr
;
}
read_lock
(
&
dev_base_lock
);
read_lock
(
&
inetdev_lock
);
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
{
if
((
in_dev
=
__in_dev_get
(
dev
)))
{
read_lock
(
&
in_dev
->
lock
);
addr
=
confirm_addr_indev
(
in_dev
,
dst
,
local
,
scope
);
read_unlock
(
&
in_dev
->
lock
);
if
(
addr
)
break
;
}
}
read_unlock
(
&
inetdev_lock
);
read_unlock
(
&
dev_base_lock
);
return
addr
;
}
/*
* Device notifier
*/
...
...
@@ -1132,7 +1210,7 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int *name, int nlen,
static
struct
devinet_sysctl_table
{
struct
ctl_table_header
*
sysctl_header
;
ctl_table
devinet_vars
[
18
];
ctl_table
devinet_vars
[
20
];
ctl_table
devinet_dev
[
2
];
ctl_table
devinet_conf_dir
[
2
];
ctl_table
devinet_proto_dir
[
2
];
...
...
@@ -1251,6 +1329,22 @@ static struct devinet_sysctl_table {
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
,
},
{
.
ctl_name
=
NET_IPV4_CONF_ARP_ANNOUNCE
,
.
procname
=
"arp_announce"
,
.
data
=
&
ipv4_devconf
.
arp_announce
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
,
},
{
.
ctl_name
=
NET_IPV4_CONF_ARP_IGNORE
,
.
procname
=
"arp_ignore"
,
.
data
=
&
ipv4_devconf
.
arp_ignore
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
,
},
{
.
ctl_name
=
NET_IPV4_CONF_NOXFRM
,
.
procname
=
"disable_xfrm"
,
...
...
net/ipv4/fib_rules.c
View file @
bd86acf1
...
...
@@ -438,7 +438,7 @@ static __inline__ int inet_fill_rule(struct sk_buff *skb,
nlmsg_failure:
rtattr_failure:
skb_
put
(
skb
,
b
-
skb
->
tail
);
skb_
trim
(
skb
,
b
-
skb
->
data
);
return
-
1
;
}
...
...
net/ipv4/ipvs/ip_vs_sync.c
View file @
bd86acf1
...
...
@@ -18,8 +18,6 @@
* messages filtering.
*/
#define __KERNEL_SYSCALLS__
/* for waitpid */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
...
...
@@ -27,7 +25,6 @@
#include <linux/slab.h>
#include <linux/net.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/unistd.h>
#include <linux/completion.h>
...
...
@@ -621,8 +618,6 @@ ip_vs_receive(struct socket *sock, char *buffer, const size_t buflen)
}
static
int
errno
;
static
DECLARE_WAIT_QUEUE_HEAD
(
sync_wait
);
static
pid_t
sync_master_pid
=
0
;
static
pid_t
sync_backup_pid
=
0
;
...
...
@@ -769,10 +764,10 @@ static int sync_thread(void *startup)
if
(
ip_vs_sync_state
&
IP_VS_STATE_MASTER
&&
!
sync_master_pid
)
{
state
=
IP_VS_STATE_MASTER
;
name
=
"ipvs
syncmaster"
;
name
=
"ipvs
_
syncmaster"
;
}
else
if
(
ip_vs_sync_state
&
IP_VS_STATE_BACKUP
&&
!
sync_backup_pid
)
{
state
=
IP_VS_STATE_BACKUP
;
name
=
"ipvs
syncbackup"
;
name
=
"ipvs
_
syncbackup"
;
}
else
{
IP_VS_BUG
();
ip_vs_use_count_dec
();
...
...
@@ -830,10 +825,19 @@ static int sync_thread(void *startup)
static
int
fork_sync_thread
(
void
*
startup
)
{
pid_t
pid
;
/* fork the sync thread here, then the parent process of the
sync thread is the init process after this thread exits. */
if
(
kernel_thread
(
sync_thread
,
startup
,
0
)
<
0
)
IP_VS_BUG
();
repeat:
if
((
pid
=
kernel_thread
(
sync_thread
,
startup
,
0
))
<
0
)
{
IP_VS_ERR
(
"could not create sync_thread due to %d... "
"retrying.
\n
"
,
pid
);
current
->
state
=
TASK_UNINTERRUPTIBLE
;
schedule_timeout
(
HZ
);
goto
repeat
;
}
return
0
;
}
...
...
@@ -842,7 +846,6 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
{
DECLARE_COMPLETION
(
startup
);
pid_t
pid
;
int
waitpid_result
;
if
((
state
==
IP_VS_STATE_MASTER
&&
sync_master_pid
)
||
(
state
==
IP_VS_STATE_BACKUP
&&
sync_backup_pid
))
...
...
@@ -861,12 +864,13 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
ip_vs_backup_syncid
=
syncid
;
}
if
((
pid
=
kernel_thread
(
fork_sync_thread
,
&
startup
,
0
))
<
0
)
IP_VS_BUG
();
if
((
waitpid_result
=
waitpid
(
pid
,
NULL
,
__WCLONE
))
!=
pid
)
{
IP_VS_ERR
(
"%s: waitpid(%d,...) failed, errno %d
\n
"
,
__FUNCTION__
,
pid
,
-
waitpid_result
);
repeat:
if
((
pid
=
kernel_thread
(
fork_sync_thread
,
&
startup
,
0
))
<
0
)
{
IP_VS_ERR
(
"could not create fork_sync_thread due to %d... "
"retrying.
\n
"
,
pid
);
current
->
state
=
TASK_UNINTERRUPTIBLE
;
schedule_timeout
(
HZ
);
goto
repeat
;
}
wait_for_completion
(
&
startup
);
...
...
net/ipv4/xfrm4_input.c
View file @
bd86acf1
...
...
@@ -9,6 +9,7 @@
*
*/
#include <linux/string.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
#include <net/xfrm.h>
...
...
@@ -18,9 +19,10 @@ int xfrm4_rcv(struct sk_buff *skb)
return
xfrm4_rcv_encap
(
skb
,
0
);
}
static
inline
void
ipip_ecn_decapsulate
(
struct
iphdr
*
outer_iph
,
struct
sk_buff
*
skb
)
static
inline
void
ipip_ecn_decapsulate
(
struct
sk_buff
*
skb
)
{
struct
iphdr
*
inner_iph
=
skb
->
nh
.
iph
;
struct
iphdr
*
outer_iph
=
skb
->
nh
.
iph
;
struct
iphdr
*
inner_iph
=
skb
->
h
.
ipiph
;
if
(
INET_ECN_is_ce
(
outer_iph
->
tos
)
&&
INET_ECN_is_not_ce
(
inner_iph
->
tos
))
...
...
@@ -95,10 +97,16 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if
(
x
->
props
.
mode
)
{
if
(
iph
->
protocol
!=
IPPROTO_IPIP
)
goto
drop
;
skb
->
nh
.
raw
=
skb
->
data
;
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
struct
iphdr
)))
goto
drop
;
if
(
skb_cloned
(
skb
)
&&
pskb_expand_head
(
skb
,
0
,
0
,
GFP_ATOMIC
))
goto
drop
;
if
(
!
(
x
->
props
.
flags
&
XFRM_STATE_NOECN
))
ipip_ecn_decapsulate
(
iph
,
skb
);
iph
=
skb
->
nh
.
iph
;
ipip_ecn_decapsulate
(
skb
);
skb
->
mac
.
raw
=
memmove
(
skb
->
data
-
skb
->
mac_len
,
skb
->
mac
.
raw
,
skb
->
mac_len
);
skb
->
nh
.
raw
=
skb
->
data
;
memset
(
&
(
IPCB
(
skb
)
->
opt
),
0
,
sizeof
(
struct
ip_options
));
decaps
=
1
;
break
;
...
...
net/ipv6/addrconf.c
View file @
bd86acf1
...
...
@@ -149,6 +149,7 @@ struct ipv6_devconf ipv6_devconf = {
.
accept_ra
=
1
,
.
accept_redirects
=
1
,
.
autoconf
=
1
,
.
force_mld_version
=
0
,
.
dad_transmits
=
1
,
.
rtr_solicits
=
MAX_RTR_SOLICITATIONS
,
.
rtr_solicit_interval
=
RTR_SOLICITATION_INTERVAL
,
...
...
@@ -231,7 +232,7 @@ int ipv6_addr_type(const struct in6_addr *addr)
if
((
addr
->
s6_addr32
[
0
]
|
addr
->
s6_addr32
[
1
])
==
0
)
{
if
(
addr
->
s6_addr32
[
2
]
==
0
)
{
if
(
addr
->
in6_u
.
u
6_addr32
[
3
]
==
0
)
if
(
addr
->
s
6_addr32
[
3
]
==
0
)
return
IPV6_ADDR_ANY
;
if
(
addr
->
s6_addr32
[
3
]
==
htonl
(
0x00000001
))
...
...
@@ -1071,7 +1072,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
eui
[
0
]
^=
2
;
return
0
;
case
ARPHRD_ARCNET
:
/* XXX: inherit EUI-64 fro
m
other interface -- yoshfuji */
/* XXX: inherit EUI-64 fro
m
other interface -- yoshfuji */
if
(
dev
->
addr_len
!=
ARCNET_ALEN
)
return
-
1
;
memset
(
eui
,
0
,
7
);
...
...
@@ -2739,6 +2740,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
array
[
DEVCONF_RTR_SOLICITS
]
=
cnf
->
rtr_solicits
;
array
[
DEVCONF_RTR_SOLICIT_INTERVAL
]
=
cnf
->
rtr_solicit_interval
;
array
[
DEVCONF_RTR_SOLICIT_DELAY
]
=
cnf
->
rtr_solicit_delay
;
array
[
DEVCONF_FORCE_MLD_VERSION
]
=
cnf
->
force_mld_version
;
#ifdef CONFIG_IPV6_PRIVACY
array
[
DEVCONF_USE_TEMPADDR
]
=
cnf
->
use_tempaddr
;
array
[
DEVCONF_TEMP_VALID_LFT
]
=
cnf
->
temp_valid_lft
;
...
...
@@ -3042,7 +3044,7 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table,
static
struct
addrconf_sysctl_table
{
struct
ctl_table_header
*
sysctl_header
;
ctl_table
addrconf_vars
[
1
7
];
ctl_table
addrconf_vars
[
1
8
];
ctl_table
addrconf_dev
[
2
];
ctl_table
addrconf_conf_dir
[
2
];
ctl_table
addrconf_proto_dir
[
2
];
...
...
@@ -3133,6 +3135,14 @@ static struct addrconf_sysctl_table
.
proc_handler
=
&
proc_dointvec_jiffies
,
.
strategy
=
&
sysctl_jiffies
,
},
{
.
ctl_name
=
NET_IPV6_FORCE_MLD_VERSION
,
.
procname
=
"force_mld_version"
,
.
data
=
&
ipv6_devconf
.
force_mld_version
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
,
},
#ifdef CONFIG_IPV6_PRIVACY
{
.
ctl_name
=
NET_IPV6_USE_TEMPADDR
,
...
...
net/ipv6/exthdrs.c
View file @
bd86acf1
...
...
@@ -120,7 +120,7 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb)
for
(
curr
=
procs
;
curr
->
type
>=
0
;
curr
++
)
{
if
(
curr
->
type
==
skb
->
nh
.
raw
[
off
])
{
/* type specific length/alignment
checks will be perfomed in the
checks will be perfo
r
med in the
func(). */
if
(
curr
->
func
(
skb
,
off
)
==
0
)
return
0
;
...
...
net/ipv6/ip6_fib.c
View file @
bd86acf1
...
...
@@ -85,7 +85,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
/*
* A routing update causes an increase of the serial number on the
* afected subtree. This allows for cached routes to be asynchronously
* af
f
ected subtree. This allows for cached routes to be asynchronously
* tested when modifications are made to the destination cache as a
* result of redirects, path MTU changes, etc.
*/
...
...
net/ipv6/ip6_input.c
View file @
bd86acf1
...
...
@@ -168,11 +168,19 @@ static inline int ip6_input_finish(struct sk_buff *skb)
smp_read_barrier_depends
();
if
(
ipprot
->
flags
&
INET6_PROTO_FINAL
)
{
struct
ipv6hdr
*
hdr
;
if
(
!
cksum_sub
&&
skb
->
ip_summed
==
CHECKSUM_HW
)
{
skb
->
csum
=
csum_sub
(
skb
->
csum
,
csum_partial
(
skb
->
nh
.
raw
,
skb
->
h
.
raw
-
skb
->
nh
.
raw
,
0
));
cksum_sub
++
;
}
hdr
=
skb
->
nh
.
ipv6h
;
if
(
ipv6_addr_is_multicast
(
&
hdr
->
daddr
)
&&
!
ipv6_chk_mcast_addr
(
skb
->
dev
,
&
hdr
->
daddr
,
&
hdr
->
saddr
)
&&
!
ipv6_is_mld
(
skb
,
nexthdr
))
goto
discard
;
}
if
(
!
(
ipprot
->
flags
&
INET6_PROTO_NOPOLICY
)
&&
!
xfrm6_policy_check
(
NULL
,
XFRM_POLICY_IN
,
skb
))
...
...
@@ -211,15 +219,14 @@ int ip6_input(struct sk_buff *skb)
int
ip6_mc_input
(
struct
sk_buff
*
skb
)
{
struct
ipv6hdr
*
hdr
;
int
deliver
=
0
;
int
discard
=
1
;
struct
ipv6hdr
*
hdr
;
int
deliver
;
IP6_INC_STATS_BH
(
Ip6InMcastPkts
);
hdr
=
skb
->
nh
.
ipv6h
;
if
(
ipv6_chk_mcast_addr
(
skb
->
dev
,
&
hdr
->
daddr
,
&
hdr
->
saddr
))
deliver
=
1
;
deliver
=
likely
(
!
(
skb
->
dev
->
flags
&
(
IFF_PROMISC
|
IFF_ALLMULTI
)))
||
ipv6_chk_mcast_addr
(
skb
->
dev
,
&
hdr
->
daddr
,
NULL
)
;
/*
* IPv6 multicast router mode isnt currently supported.
...
...
@@ -238,23 +245,21 @@ int ip6_mc_input(struct sk_buff *skb)
if (deliver) {
skb2 = skb_clone(skb, GFP_ATOMIC);
dst_output(skb2);
} else {
d
iscard = 0
;
skb2 = skb
;
d
st_output(skb)
;
return 0
;
}
dst_output(skb2);
}
}
#endif
if
(
deliver
)
{
discard
=
0
;
if
(
likely
(
deliver
))
{
ip6_input
(
skb
);
return
0
;
}
if
(
discard
)
kfree_skb
(
skb
);
/* discard */
kfree_skb
(
skb
);
return
0
;
}
net/ipv6/ip6_tunnel.c
View file @
bd86acf1
...
...
@@ -399,7 +399,7 @@ void ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
__u16
len
;
/* If the packet doesn't contain the original IPv6 header we are
in trouble since we might need the source address for furter
in trouble since we might need the source address for furt
h
er
processing of the error. */
read_lock
(
&
ip6ip6_lock
);
...
...
net/ipv6/mcast.c
View file @
bd86acf1
...
...
@@ -152,8 +152,10 @@ int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
#define IGMP6_UNSOLICITED_IVAL (10*HZ)
#define MLD_QRV_DEFAULT 2
#define MLD_V1_SEEN(idev) ((idev)->mc_v1_seen && \
time_before(jiffies, (idev)->mc_v1_seen))
#define MLD_V1_SEEN(idev) (ipv6_devconf.force_mld_version == 1 || \
(idev)->cnf.force_mld_version == 1 || \
((idev)->mc_v1_seen && \
time_before(jiffies, (idev)->mc_v1_seen)))
#define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
#define MLDV2_EXP(thresh, nbmant, nbexp, value) \
...
...
@@ -900,6 +902,33 @@ int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr)
return
err
;
}
/*
* identify MLD packets for MLD filter exceptions
*/
int
ipv6_is_mld
(
struct
sk_buff
*
skb
,
int
nexthdr
)
{
struct
icmp6hdr
*
pic
;
if
(
nexthdr
!=
IPPROTO_ICMPV6
)
return
0
;
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
struct
icmp6hdr
)))
return
0
;
pic
=
(
struct
icmp6hdr
*
)
skb
->
h
.
raw
;
switch
(
pic
->
icmp6_type
)
{
case
ICMPV6_MGM_QUERY
:
case
ICMPV6_MGM_REPORT
:
case
ICMPV6_MGM_REDUCTION
:
case
ICMPV6_MLD2_REPORT
:
return
1
;
default:
break
;
}
return
0
;
}
/*
* check if the interface/address pair is valid
*/
...
...
@@ -918,7 +947,7 @@ int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group,
break
;
}
if
(
mc
)
{
if
(
!
ipv6_addr_any
(
src_addr
))
{
if
(
src_addr
&&
!
ipv6_addr_any
(
src_addr
))
{
struct
ip6_sf_list
*
psf
;
spin_lock_bh
(
&
mc
->
mca_lock
);
...
...
net/ipv6/ndisc.c
View file @
bd86acf1
...
...
@@ -28,11 +28,12 @@
/* Set to 3 to get tracing... */
#define ND_DEBUG 1
#define ND_PRINTK(
x...) printk(KERN_DEBUG x
)
#define ND_PRINTK(
fmt, args...) do { if (net_ratelimit()) { printk(fmt, ## args); } } while(0
)
#define ND_NOPRINTK(x...) do { ; } while(0)
#define ND_PRINTK0 ND_PRINTK
#define ND_PRINTK1 ND_NOPRINTK
#define ND_PRINTK2 ND_NOPRINTK
#define ND_PRINTK3 ND_NOPRINTK
#if ND_DEBUG >= 1
#undef ND_PRINTK1
#define ND_PRINTK1 ND_PRINTK
...
...
@@ -41,6 +42,10 @@
#undef ND_PRINTK2
#define ND_PRINTK2 ND_PRINTK
#endif
#if ND_DEBUG >= 3
#undef ND_PRINTK3
#define ND_PRINTK3 ND_PRINTK
#endif
#include <linux/module.h>
#include <linux/config.h>
...
...
@@ -210,8 +215,10 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
case
ND_OPT_MTU
:
case
ND_OPT_REDIRECT_HDR
:
if
(
ndopts
->
nd_opt_array
[
nd_opt
->
nd_opt_type
])
{
ND_PRINTK2
(
"ndisc_parse_options(): duplicated ND6 option found: type=%d
\n
"
,
nd_opt
->
nd_opt_type
);
ND_PRINTK2
(
KERN_WARNING
"%s(): duplicated ND6 option found: type=%d
\n
"
,
__FUNCTION__
,
nd_opt
->
nd_opt_type
);
}
else
{
ndopts
->
nd_opt_array
[
nd_opt
->
nd_opt_type
]
=
nd_opt
;
}
...
...
@@ -226,8 +233,9 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
* Unknown options must be silently ignored,
* to accommodate future extension to the protocol.
*/
ND_PRINTK2
(
KERN_WARNING
"ndisc_parse_options(): ignored unsupported option; type=%d, len=%d
\n
"
,
ND_PRINTK2
(
KERN_NOTICE
"%s(): ignored unsupported option; type=%d, len=%d
\n
"
,
__FUNCTION__
,
nd_opt
->
nd_opt_type
,
nd_opt
->
nd_opt_len
);
}
opt_len
-=
l
;
...
...
@@ -341,65 +349,10 @@ static void pndisc_destructor(struct pneigh_entry *n)
ipv6_dev_mc_dec
(
dev
,
&
maddr
);
}
static
int
ndisc_build_ll_hdr
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
in6_addr
*
daddr
,
struct
neighbour
*
neigh
,
int
len
)
{
unsigned
char
ha
[
MAX_ADDR_LEN
];
unsigned
char
*
h_dest
=
NULL
;
if
(
dev
->
hard_header
)
{
if
(
ipv6_addr_is_multicast
(
daddr
))
{
ndisc_mc_map
(
daddr
,
ha
,
dev
,
1
);
h_dest
=
ha
;
}
else
if
(
neigh
)
{
read_lock_bh
(
&
neigh
->
lock
);
if
(
neigh
->
nud_state
&
NUD_VALID
)
{
memcpy
(
ha
,
neigh
->
ha
,
dev
->
addr_len
);
h_dest
=
ha
;
}
read_unlock_bh
(
&
neigh
->
lock
);
}
else
{
neigh
=
neigh_lookup
(
&
nd_tbl
,
daddr
,
dev
);
if
(
neigh
)
{
read_lock_bh
(
&
neigh
->
lock
);
if
(
neigh
->
nud_state
&
NUD_VALID
)
{
memcpy
(
ha
,
neigh
->
ha
,
dev
->
addr_len
);
h_dest
=
ha
;
}
read_unlock_bh
(
&
neigh
->
lock
);
neigh_release
(
neigh
);
}
}
if
(
dev
->
hard_header
(
skb
,
dev
,
ETH_P_IPV6
,
h_dest
,
NULL
,
len
)
<
0
)
return
0
;
}
return
1
;
}
/*
* Send a Neighbour Advertisement
*/
static
int
ndisc_output
(
struct
sk_buff
*
skb
)
{
if
(
skb
)
{
struct
neighbour
*
neigh
=
(
skb
->
dst
?
skb
->
dst
->
neighbour
:
NULL
);
if
(
ndisc_build_ll_hdr
(
skb
,
skb
->
dev
,
&
skb
->
nh
.
ipv6h
->
daddr
,
neigh
,
skb
->
len
)
==
0
)
{
kfree_skb
(
skb
);
return
-
EINVAL
;
}
dev_queue_xmit
(
skb
);
return
0
;
}
return
-
EINVAL
;
}
static
inline
void
ndisc_flow_init
(
struct
flowi
*
fl
,
u8
type
,
struct
in6_addr
*
saddr
,
struct
in6_addr
*
daddr
)
{
...
...
@@ -442,7 +395,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
ndisc_flow_init
(
&
fl
,
NDISC_NEIGHBOUR_ADVERTISEMENT
,
src_addr
,
daddr
);
dst
=
ndisc_dst_alloc
(
dev
,
neigh
,
ndisc_output
);
dst
=
ndisc_dst_alloc
(
dev
,
neigh
,
daddr
,
ip6_output2
);
if
(
!
dst
)
return
;
...
...
@@ -463,7 +416,9 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
1
,
&
err
);
if
(
skb
==
NULL
)
{
ND_PRINTK1
(
"send_na: alloc skb failed
\n
"
);
ND_PRINTK0
(
KERN_ERR
"ICMPv6 NA: %s() failed to allocate an skb.
\n
"
,
__FUNCTION__
);
dst_release
(
dst
);
return
;
}
...
...
@@ -530,7 +485,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
ndisc_flow_init
(
&
fl
,
NDISC_NEIGHBOUR_SOLICITATION
,
saddr
,
daddr
);
dst
=
ndisc_dst_alloc
(
dev
,
neigh
,
ndisc_output
);
dst
=
ndisc_dst_alloc
(
dev
,
neigh
,
daddr
,
ip6_output2
);
if
(
!
dst
)
return
;
...
...
@@ -548,7 +503,9 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
skb
=
sock_alloc_send_skb
(
sk
,
MAX_HEADER
+
len
+
LL_RESERVED_SPACE
(
dev
),
1
,
&
err
);
if
(
skb
==
NULL
)
{
ND_PRINTK1
(
"send_ns: alloc skb failed
\n
"
);
ND_PRINTK0
(
KERN_ERR
"ICMPv6 NA: %s() failed to allocate an skb.
\n
"
,
__FUNCTION__
);
dst_release
(
dst
);
return
;
}
...
...
@@ -603,7 +560,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
ndisc_flow_init
(
&
fl
,
NDISC_ROUTER_SOLICITATION
,
saddr
,
daddr
);
dst
=
ndisc_dst_alloc
(
dev
,
NULL
,
ndisc_output
);
dst
=
ndisc_dst_alloc
(
dev
,
NULL
,
daddr
,
ip6_output2
);
if
(
!
dst
)
return
;
...
...
@@ -620,7 +577,9 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
skb
=
sock_alloc_send_skb
(
sk
,
MAX_HEADER
+
len
+
LL_RESERVED_SPACE
(
dev
),
1
,
&
err
);
if
(
skb
==
NULL
)
{
ND_PRINTK1
(
"send_ns: alloc skb failed
\n
"
);
ND_PRINTK0
(
KERN_ERR
"ICMPv6 RS: %s() failed to allocate an skb.
\n
"
,
__FUNCTION__
);
dst_release
(
dst
);
return
;
}
...
...
@@ -683,8 +642,13 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
saddr
=
&
skb
->
nh
.
ipv6h
->
saddr
;
if
((
probes
-=
neigh
->
parms
->
ucast_probes
)
<
0
)
{
if
(
!
(
neigh
->
nud_state
&
NUD_VALID
))
ND_PRINTK1
(
"trying to ucast probe in NUD_INVALID
\n
"
);
if
(
!
(
neigh
->
nud_state
&
NUD_VALID
))
{
ND_PRINTK1
(
KERN_DEBUG
"%s(): trying to ucast probe in NUD_INVALID: "
"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x
\n
"
,
__FUNCTION__
,
NIP6
(
*
target
));
}
ndisc_send_ns
(
dev
,
neigh
,
target
,
target
,
saddr
);
}
else
if
((
probes
-=
neigh
->
parms
->
app_probes
)
<
0
)
{
#ifdef CONFIG_ARPD
...
...
@@ -713,8 +677,8 @@ static void ndisc_recv_ns(struct sk_buff *skb)
int
inc
;
if
(
ipv6_addr_is_multicast
(
&
msg
->
target
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NS: target address is multicast
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NS: multicast target address
"
);
return
;
}
...
...
@@ -727,14 +691,14 @@ static void ndisc_recv_ns(struct sk_buff *skb)
daddr
->
s6_addr32
[
1
]
==
htonl
(
0x00000000
)
&&
daddr
->
s6_addr32
[
2
]
==
htonl
(
0x00000001
)
&&
daddr
->
s6_addr
[
12
]
==
0xff
))
{
if
(
net_ratelimit
())
printk
(
KERN_DEBUG
"ICMP
6 NS: bad DAD packet (wrong destination)
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv
6 NS: bad DAD packet (wrong destination)
\n
"
);
return
;
}
if
(
!
ndisc_parse_options
(
msg
->
opt
,
ndoptlen
,
&
ndopts
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NS: invalid ND option, ignored.
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NS: invalid ND options
\n
"
);
return
;
}
...
...
@@ -742,19 +706,19 @@ static void ndisc_recv_ns(struct sk_buff *skb)
lladdr
=
(
u8
*
)(
ndopts
.
nd_opts_src_lladdr
+
1
);
lladdrlen
=
ndopts
.
nd_opts_src_lladdr
->
nd_opt_len
<<
3
;
if
(
lladdrlen
!=
NDISC_OPT_SPACE
(
dev
->
addr_len
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NS: bad lladdr length.
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NS: invalid link-layer address length
\n
"
);
return
;
}
/*
XXX:
RFC2461 7.1.1:
/* RFC2461 7.1.1:
* If the IP source address is the unspecified address,
* there MUST NOT be source link-layer address option
* in the message.
*/
if
(
dad
)
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP
6 NS: bad DAD packet (link-layer address option)
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv
6 NS: bad DAD packet (link-layer address option)
\n
"
);
return
;
}
}
...
...
@@ -868,34 +832,35 @@ static void ndisc_recv_na(struct sk_buff *skb)
struct
neighbour
*
neigh
;
if
(
skb
->
len
<
sizeof
(
struct
nd_msg
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP
NA: packet too short
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6
NA: packet too short
\n
"
);
return
;
}
if
(
ipv6_addr_is_multicast
(
&
msg
->
target
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"NDISC NA: target address is multicast
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NA: target address is multicast.
\n
"
);
return
;
}
if
(
ipv6_addr_is_multicast
(
daddr
)
&&
msg
->
icmph
.
icmp6_solicited
)
{
ND_PRINTK0
(
"NDISC: solicited NA is multicasted
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NA: solicited NA is multicasted.
\n
"
);
return
;
}
if
(
!
ndisc_parse_options
(
msg
->
opt
,
ndoptlen
,
&
ndopts
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NS: invalid ND option, ignored.
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NS: invalid ND option
\n
"
);
return
;
}
if
(
ndopts
.
nd_opts_tgt_lladdr
)
{
lladdr
=
(
u8
*
)(
ndopts
.
nd_opts_tgt_lladdr
+
1
);
lladdrlen
=
ndopts
.
nd_opts_tgt_lladdr
->
nd_opt_len
<<
3
;
if
(
lladdrlen
!=
NDISC_OPT_SPACE
(
dev
->
addr_len
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"NDISC NA: invalid lladdr length.
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NA: invalid link-layer address length
\n
"
);
return
;
}
}
...
...
@@ -909,7 +874,8 @@ static void ndisc_recv_na(struct sk_buff *skb)
about it. It could be misconfiguration, or
an smart proxy agent tries to help us :-)
*/
ND_PRINTK0
(
"%s: someone advertises our address!
\n
"
,
ND_PRINTK1
(
KERN_WARNING
"ICMPv6 NA: someone advertises our address on %s!
\n
"
,
ifp
->
idev
->
dev
->
name
);
in6_ifa_put
(
ifp
);
return
;
...
...
@@ -954,13 +920,13 @@ static void ndisc_router_discovery(struct sk_buff *skb)
optlen
=
(
skb
->
tail
-
skb
->
h
.
raw
)
-
sizeof
(
struct
ra_msg
);
if
(
!
(
ipv6_addr_type
(
&
skb
->
nh
.
ipv6h
->
saddr
)
&
IPV6_ADDR_LINKLOCAL
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP RA: source address is not linklocal
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 RA: source address is not link-local.
\n
"
);
return
;
}
if
(
optlen
<
0
)
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP
RA: packet too short
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6
RA: packet too short
\n
"
);
return
;
}
...
...
@@ -970,7 +936,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
in6_dev
=
in6_dev_get
(
skb
->
dev
);
if
(
in6_dev
==
NULL
)
{
ND_PRINTK1
(
"RA: can't find in6 device
\n
"
);
ND_PRINTK0
(
KERN_ERR
"ICMPv6 RA: can't find inet6 device for %s.
\n
"
,
skb
->
dev
->
name
);
return
;
}
if
(
in6_dev
->
cnf
.
forwarding
||
!
in6_dev
->
cnf
.
accept_ra
)
{
...
...
@@ -980,9 +948,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
if
(
!
ndisc_parse_options
(
opt
,
optlen
,
&
ndopts
))
{
in6_dev_put
(
in6_dev
);
if
(
net_ratelimit
())
ND_PRINTK2
(
KERN_WARNING
"ICMP6 RA: invalid ND option, ignored.
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMP6 RA: invalid ND options
\n
"
);
return
;
}
...
...
@@ -1015,18 +982,23 @@ static void ndisc_router_discovery(struct sk_buff *skb)
}
if
(
rt
==
NULL
&&
lifetime
)
{
ND_PRINTK2
(
"ndisc_rdisc: adding default router
\n
"
);
ND_PRINTK3
(
KERN_DEBUG
"ICMPv6 RA: adding default router.
\n
"
);
rt
=
rt6_add_dflt_router
(
&
skb
->
nh
.
ipv6h
->
saddr
,
skb
->
dev
);
if
(
rt
==
NULL
)
{
ND_PRINTK1
(
"route_add failed
\n
"
);
ND_PRINTK0
(
KERN_ERR
"ICMPv6 RA: %s() failed to add default route.
\n
"
,
__FUNCTION__
);
in6_dev_put
(
in6_dev
);
return
;
}
neigh
=
rt
->
rt6i_nexthop
;
if
(
neigh
==
NULL
)
{
ND_PRINTK1
(
"nd: add default router: null neighbour
\n
"
);
ND_PRINTK0
(
KERN_ERR
"ICMPv6 RA: %s() got default router without neighbour.
\n
"
,
__FUNCTION__
);
dst_release
(
&
rt
->
u
.
dst
);
in6_dev_put
(
in6_dev
);
return
;
...
...
@@ -1052,7 +1024,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
*/
if
(
in6_dev
->
nd_parms
)
{
__u32
rtime
=
ntohl
(
ra_msg
->
retrans_timer
);
unsigned
long
rtime
=
ntohl
(
ra_msg
->
retrans_timer
);
if
(
rtime
&&
rtime
/
1000
<
MAX_SCHEDULE_TIMEOUT
/
HZ
)
{
rtime
=
(
rtime
*
HZ
)
/
1000
;
...
...
@@ -1091,9 +1063,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
lladdr
=
(
u8
*
)((
ndopts
.
nd_opts_src_lladdr
)
+
1
);
lladdrlen
=
ndopts
.
nd_opts_src_lladdr
->
nd_opt_len
<<
3
;
if
(
lladdrlen
!=
NDISC_OPT_SPACE
(
skb
->
dev
->
addr_len
))
{
if
(
net_ratelimit
())
ND_PRINTK2
(
KERN_WARNING
"ICMP6 RA: Invalid lladdr length.
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 RA: invalid link-layer address length
\n
"
);
goto
out
;
}
}
...
...
@@ -1116,10 +1087,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
mtu
=
ntohl
(
mtu
);
if
(
mtu
<
IPV6_MIN_MTU
||
mtu
>
skb
->
dev
->
mtu
)
{
if
(
net_ratelimit
())
{
ND_PRINTK0
(
"NDISC: router announcement with mtu = %d
\n
"
,
mtu
);
}
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 RA: invalid mtu: %d
\n
"
,
mtu
);
}
else
if
(
in6_dev
->
cnf
.
mtu6
!=
mtu
)
{
in6_dev
->
cnf
.
mtu6
=
mtu
;
...
...
@@ -1131,9 +1101,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
}
if
(
ndopts
.
nd_opts_tgt_lladdr
||
ndopts
.
nd_opts_rh
)
{
if
(
net_ratelimit
())
ND_PRINTK0
(
KERN_WARNING
"ICMP6 RA: got invalid option with RA"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 RA: invalid RA options"
);
}
out:
if
(
rt
)
...
...
@@ -1155,8 +1124,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
int
lladdrlen
;
if
(
!
(
ipv6_addr_type
(
&
skb
->
nh
.
ipv6h
->
saddr
)
&
IPV6_ADDR_LINKLOCAL
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP redirect: source address is not linklocal
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 Redirect: source address is not link-local.
\n
"
);
return
;
}
...
...
@@ -1164,8 +1133,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
optlen
-=
sizeof
(
struct
icmp6hdr
)
+
2
*
sizeof
(
struct
in6_addr
);
if
(
optlen
<
0
)
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP redirect: packet too small
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 Redirect: packet too short
\n
"
);
return
;
}
...
...
@@ -1174,16 +1143,16 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
dest
=
target
+
1
;
if
(
ipv6_addr_is_multicast
(
dest
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP redirect for multicast addr
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 Redirect: destination address is multicast.
\n
"
);
return
;
}
if
(
ipv6_addr_cmp
(
dest
,
target
)
==
0
)
{
on_link
=
1
;
}
else
if
(
!
(
ipv6_addr_type
(
target
)
&
IPV6_ADDR_LINKLOCAL
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP redirect: target address is not linklocal
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 Redirect: target address is not link-local.
\n
"
);
return
;
}
...
...
@@ -1195,15 +1164,14 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
return
;
}
/*
XXX:
RFC2461 8.1:
/* RFC2461 8.1:
* The IP source address of the Redirect MUST be the same as the current
* first-hop router for the specified ICMP Destination Address.
*/
if
(
!
ndisc_parse_options
((
u8
*
)(
dest
+
1
),
optlen
,
&
ndopts
))
{
if
(
net_ratelimit
())
ND_PRINTK2
(
KERN_WARNING
"ICMP6 Redirect: invalid ND options, rejected.
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 Redirect: invalid ND options
\n
"
);
in6_dev_put
(
in6_dev
);
return
;
}
...
...
@@ -1211,9 +1179,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
lladdr
=
(
u8
*
)(
ndopts
.
nd_opts_tgt_lladdr
+
1
);
lladdrlen
=
ndopts
.
nd_opts_tgt_lladdr
->
nd_opt_len
<<
3
;
if
(
lladdrlen
!=
NDISC_OPT_SPACE
(
skb
->
dev
->
addr_len
))
{
if
(
net_ratelimit
())
ND_PRINTK2
(
KERN_WARNING
"ICMP6 Redirect: invalid lladdr length.
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 Redirect: invalid link-layer address length
\n
"
);
in6_dev_put
(
in6_dev
);
return
;
}
...
...
@@ -1258,7 +1225,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
dev
=
skb
->
dev
;
if
(
ipv6_get_lladdr
(
dev
,
&
saddr_buf
))
{
ND_PRINTK1
(
"redirect: no link_local addr for dev
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 Redirect: no link-local address on %s
\n
"
,
dev
->
name
);
return
;
}
...
...
@@ -1278,7 +1247,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
rt
=
(
struct
rt6_info
*
)
dst
;
if
(
rt
->
rt6i_flags
&
RTF_GATEWAY
)
{
ND_PRINTK1
(
"ndisc_send_redirect: not a neighbour
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 Redirect: destination is not a neighbour.
\n
"
);
dst_release
(
dst
);
return
;
}
...
...
@@ -1308,7 +1278,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
buff
=
sock_alloc_send_skb
(
sk
,
MAX_HEADER
+
len
+
LL_RESERVED_SPACE
(
dev
),
1
,
&
err
);
if
(
buff
==
NULL
)
{
ND_PRINTK1
(
"ndisc_send_redirect: alloc_skb failed
\n
"
);
ND_PRINTK0
(
KERN_ERR
"ICMPv6 Redirect: %s() failed to allocate an skb.
\n
"
,
__FUNCTION__
);
dst_release
(
dst
);
return
;
}
...
...
@@ -1388,16 +1360,16 @@ int ndisc_rcv(struct sk_buff *skb)
__skb_push
(
skb
,
skb
->
data
-
skb
->
h
.
raw
);
if
(
skb
->
nh
.
ipv6h
->
hop_limit
!=
255
)
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NDISC: fake message with non-255 Hop Limit received: %d
\n
"
,
skb
->
nh
.
ipv6h
->
hop_limit
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NDISC: invalid hop-limit: %d
\n
"
,
skb
->
nh
.
ipv6h
->
hop_limit
);
return
0
;
}
if
(
msg
->
icmph
.
icmp6_code
!=
0
)
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NDISC: code is not zero
\n
"
);
ND_PRINTK2
(
KERN_WARNING
"ICMPv6 NDISC: invalid ICMPv6 code: %d
\n
"
,
msg
->
icmph
.
icmp6_code
);
return
0
;
}
...
...
@@ -1465,9 +1437,9 @@ int __init ndisc_init(struct net_proto_family *ops)
err
=
sock_create
(
PF_INET6
,
SOCK_RAW
,
IPPROTO_ICMPV6
,
&
ndisc_socket
);
if
(
err
<
0
)
{
printk
(
KERN_ERR
"Failed to initialize the NDISC control socket (err %d).
\n
"
,
err
);
ND_PRINTK0
(
KERN_ERR
"ICMPv6 NDISC: Failed to initialize the control socket (err %d).
\n
"
,
err
);
ndisc_socket
=
NULL
;
/* For safety. */
return
err
;
}
...
...
net/ipv6/netfilter/ip6t_eui64.c
View file @
bd86acf1
...
...
@@ -50,7 +50,7 @@ match(const struct sk_buff *skb,
eui64
[
0
]
|=
0x02
;
i
=
0
;
while
((
skb
->
nh
.
ipv6h
->
saddr
.
in6_u
.
u6_addr8
[
8
+
i
]
==
while
((
skb
->
nh
.
ipv6h
->
saddr
.
s6_addr
[
8
+
i
]
==
eui64
[
i
])
&&
(
i
<
8
))
i
++
;
if
(
i
==
8
)
...
...
net/ipv6/raw.c
View file @
bd86acf1
...
...
@@ -222,7 +222,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
}
/* ipv4 addr of the socket is invalid. Only the
* unpecified and mapped address have a v4 equivalent.
* un
s
pecified and mapped address have a v4 equivalent.
*/
v4addr
=
LOOPBACK4_IPV6
;
if
(
!
(
addr_type
&
IPV6_ADDR_MULTICAST
))
{
...
...
@@ -306,7 +306,7 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
* This is next to useless...
* if we demultiplex in network layer we don't need the extra call
* just to queue the skb...
* maybe we could have the network decide up
p
on a hint if it
* maybe we could have the network decide upon a hint if it
* should call raw_rcv for demultiplexing
*/
int
rawv6_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
...
...
@@ -627,7 +627,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
if
(
ipv6_addr_any
(
daddr
))
{
/*
* unspecfied destination address
* unspec
i
fied destination address
* treated as error... is this correct ?
*/
fl6_sock_release
(
flowlabel
);
...
...
net/ipv6/route.c
View file @
bd86acf1
...
...
@@ -223,7 +223,7 @@ static struct rt6_info *rt6_best_dflt(struct rt6_info *rt, int oif)
match
=
sprt
;
mpri
=
m
;
if
(
m
>=
12
)
{
/* we choose the last
est
default router if it
/* we choose the last default router if it
* is in (probably) reachable state.
* If route changed, we should do pmtu
* discovery. --yoshfuji
...
...
@@ -563,6 +563,7 @@ static struct dst_entry *ndisc_dst_gc_list;
struct
dst_entry
*
ndisc_dst_alloc
(
struct
net_device
*
dev
,
struct
neighbour
*
neigh
,
struct
in6_addr
*
addr
,
int
(
*
output
)(
struct
sk_buff
*
))
{
struct
rt6_info
*
rt
=
ip6_dst_alloc
();
...
...
@@ -574,11 +575,13 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
dev_hold
(
dev
);
if
(
neigh
)
neigh_hold
(
neigh
);
else
neigh
=
ndisc_get_neigh
(
dev
,
addr
);
rt
->
rt6i_dev
=
dev
;
rt
->
rt6i_nexthop
=
neigh
;
rt
->
rt6i_expires
=
0
;
rt
->
rt6i_flags
=
RTF_LOCAL
|
RTF_NDISC
;
rt
->
rt6i_flags
=
RTF_LOCAL
;
rt
->
rt6i_metric
=
0
;
atomic_set
(
&
rt
->
u
.
dst
.
__refcnt
,
1
);
rt
->
u
.
dst
.
metrics
[
RTAX_HOPLIMIT
-
1
]
=
255
;
...
...
@@ -832,7 +835,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
}
}
rt
->
rt6i_flags
=
rtmsg
->
rtmsg_flags
&
~
RTF_NDISC
;
rt
->
rt6i_flags
=
rtmsg
->
rtmsg_flags
;
install_route:
if
(
rta
&&
rta
[
RTA_METRICS
-
1
])
{
...
...
@@ -1125,8 +1128,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
{
struct
rt6_info
*
rt
=
ip6_dst_alloc
();
BUG_ON
(
ort
->
rt6i_flags
&
RTF_NDISC
);
if
(
rt
)
{
rt
->
u
.
dst
.
input
=
ort
->
u
.
dst
.
input
;
rt
->
u
.
dst
.
output
=
ort
->
u
.
dst
.
output
;
...
...
net/ipv6/xfrm6_input.c
View file @
bd86acf1
...
...
@@ -9,17 +9,20 @@
* IPv6 support
*/
#include <linux/string.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/xfrm.h>
static
inline
void
ipip6_ecn_decapsulate
(
struct
ipv6hdr
*
iph
,
struct
sk_buff
*
skb
)
static
inline
void
ipip6_ecn_decapsulate
(
struct
sk_buff
*
skb
)
{
if
(
INET_ECN_is_ce
(
ip6_get_dsfield
(
iph
))
&&
INET_ECN_is_not_ce
(
ip6_get_dsfield
(
skb
->
nh
.
ipv6h
)))
IP6_ECN_set_ce
(
skb
->
nh
.
ipv6h
);
struct
ipv6hdr
*
outer_iph
=
skb
->
nh
.
ipv6h
;
struct
ipv6hdr
*
inner_iph
=
skb
->
h
.
ipv6h
;
if
(
INET_ECN_is_ce
(
ip6_get_dsfield
(
outer_iph
))
&&
INET_ECN_is_not_ce
(
ip6_get_dsfield
(
inner_iph
)))
IP6_ECN_set_ce
(
inner_iph
);
}
int
xfrm6_rcv
(
struct
sk_buff
**
pskb
,
unsigned
int
*
nhoffp
)
...
...
@@ -77,10 +80,16 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
if
(
x
->
props
.
mode
)
{
/* XXX */
if
(
nexthdr
!=
IPPROTO_IPV6
)
goto
drop
;
skb
->
nh
.
raw
=
skb
->
data
;
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
struct
ipv6hdr
)))
goto
drop
;
if
(
skb_cloned
(
skb
)
&&
pskb_expand_head
(
skb
,
0
,
0
,
GFP_ATOMIC
))
goto
drop
;
if
(
!
(
x
->
props
.
flags
&
XFRM_STATE_NOECN
))
ipip6_ecn_decapsulate
(
iph
,
skb
);
iph
=
skb
->
nh
.
ipv6h
;
ipip6_ecn_decapsulate
(
skb
);
skb
->
mac
.
raw
=
memmove
(
skb
->
data
-
skb
->
mac_len
,
skb
->
mac
.
raw
,
skb
->
mac_len
);
skb
->
nh
.
raw
=
skb
->
data
;
decaps
=
1
;
break
;
}
...
...
net/ipv6/xfrm6_policy.c
View file @
bd86acf1
...
...
@@ -55,13 +55,6 @@ static struct dst_entry *
__xfrm6_find_bundle
(
struct
flowi
*
fl
,
struct
rtable
*
rt
,
struct
xfrm_policy
*
policy
)
{
struct
dst_entry
*
dst
;
u32
ndisc_bit
=
0
;
if
(
fl
->
proto
==
IPPROTO_ICMPV6
&&
(
fl
->
fl_icmp_type
==
NDISC_NEIGHBOUR_ADVERTISEMENT
||
fl
->
fl_icmp_type
==
NDISC_NEIGHBOUR_SOLICITATION
||
fl
->
fl_icmp_type
==
NDISC_ROUTER_SOLICITATION
))
ndisc_bit
=
RTF_NDISC
;
/* Still not clear if we should set fl->fl6_{src,dst}... */
read_lock_bh
(
&
policy
->
lock
);
...
...
@@ -69,9 +62,6 @@ __xfrm6_find_bundle(struct flowi *fl, struct rtable *rt, struct xfrm_policy *pol
struct
xfrm_dst
*
xdst
=
(
struct
xfrm_dst
*
)
dst
;
struct
in6_addr
fl_dst_prefix
,
fl_src_prefix
;
if
((
xdst
->
u
.
rt6
.
rt6i_flags
&
RTF_NDISC
)
!=
ndisc_bit
)
continue
;
ipv6_addr_prefix
(
&
fl_dst_prefix
,
&
fl
->
fl6_dst
,
xdst
->
u
.
rt6
.
rt6i_dst
.
plen
);
...
...
@@ -169,7 +159,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
dst_prev
->
output
=
dst_prev
->
xfrm
->
type
->
output
;
/* Sheit... I remember I did this right. Apparently,
* it was magically lost, so this code needs audit */
x
->
u
.
rt6
.
rt6i_flags
=
rt0
->
rt6i_flags
&
(
RTCF_BROADCAST
|
RTCF_MULTICAST
|
RTCF_LOCAL
|
RTF_NDISC
);
x
->
u
.
rt6
.
rt6i_flags
=
rt0
->
rt6i_flags
&
(
RTCF_BROADCAST
|
RTCF_MULTICAST
|
RTCF_LOCAL
);
x
->
u
.
rt6
.
rt6i_metric
=
rt0
->
rt6i_metric
;
x
->
u
.
rt6
.
rt6i_node
=
rt0
->
rt6i_node
;
x
->
u
.
rt6
.
rt6i_gateway
=
rt0
->
rt6i_gateway
;
...
...
net/sched/sch_sfq.c
View file @
bd86acf1
...
...
@@ -341,6 +341,7 @@ sfq_dequeue(struct Qdisc* sch)
/* Is the slot empty? */
if
(
q
->
qs
[
a
].
qlen
==
0
)
{
q
->
ht
[
q
->
hash
[
a
]]
=
SFQ_DEPTH
;
a
=
q
->
next
[
a
];
if
(
a
==
old_a
)
{
q
->
tail
=
SFQ_DEPTH
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment